#include "intel/compiler/brw_compiler.h"
#include "iris_context.h"
-#define __gen_address_type unsigned
-#define __gen_user_data void
-
-static uint64_t
-__gen_combine_address(void *user_data, void *location,
- unsigned address, uint32_t delta)
-{
- return delta;
-}
-
-#define __genxml_cmd_length(cmd) cmd ## _length
-#define __genxml_cmd_length_bias(cmd) cmd ## _length_bias
-#define __genxml_cmd_header(cmd) cmd ## _header
-#define __genxml_cmd_pack(cmd) cmd ## _pack
-
-#define iris_pack_command(cmd, dst, name) \
- for (struct cmd name = { __genxml_cmd_header(cmd) }, \
- *_dst = (void *)(dst); __builtin_expect(_dst != NULL, 1); \
- __genxml_cmd_pack(cmd)(NULL, (void *)dst, &name), \
- _dst = NULL)
-
-#define iris_pack_state(cmd, dst, name) \
- for (struct cmd name = {}, \
- *_dst = (void *)(dst); __builtin_expect(_dst != NULL, 1); \
- __genxml_cmd_pack(cmd)(NULL, (void *)_dst, &name), \
- _dst = NULL)
-
-#include "genxml/genX_pack.h"
-#include "genxml/gen_macros.h"
-
-static void
+void
iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
{
struct iris_context *ice = (struct iris_context *) ctx;
- iris_upload_render_state(ice, draw);
-
-#if 0
- l3 configuration
-
- 3DSTATE_VIEWPORT_STATE_POINTERS_CC - CC_VIEWPORT
- -> from iris_depth_stencil_alpha_state
-
- 3DSTATE_VIEWPORT_STATE_POINTERS_SF_CL - SF_CLIP_VIEWPORT
- -> pipe_viewport_state for matrix elements, guardband is calculated
- from those. can calculate screen space from matrix apparently...
-
- 3DSTATE_SCISSOR_STATE_POINTERS - SCISSOR_RECT
- -> from ice->state.scissors
-
- 3DSTATE_PUSH_CONSTANT_ALLOC_*
- 3DSTATE_URB_*
- -> TODO
-
- 3DSTATE_PS_BLEND
- 3DSTATE_BLEND_STATE_POINTERS - BLEND_STATE
- -> from iris_blend_state (most) + iris_depth_stencil_alpha_state
- (alpha test function/enable) + has writeable RT from ???????
-
- 3DSTATE_CC_STATE_POINTERS - COLOR_CALC_STATE
- -> from ice->state.blend_color + iris_depth_stencil_alpha_state
- (ref_value)
-
- 3DSTATE_CONSTANT_* - push constants
- -> TODO
-
- Surfaces:
- - pull constants
- - ubos/ssbos/abos
- - images
- - textures
- - render targets - write and read
- 3DSTATE_BINDING_TABLE_POINTERS_*
- -> TODO
-
- 3DSTATE_SAMPLER_STATE_POINTERS_*
- -> TODO
-
- 3DSTATE_MULTISAMPLE
- 3DSTATE_SAMPLE_MASK
-
- 3DSTATE_VS
- 3DSTATE_HS
- 3DSTATE_TE
- 3DSTATE_DS
- 3DSTATE_GS
- 3DSTATE_PS_EXTRA
- 3DSTATE_PS
- 3DSTATE_STREAMOUT
- 3DSTATE_SO_BUFFER
- 3DSTATE_SO_DECL_LIST
-
- 3DSTATE_CLIP
- -> iris_raster_state + ??? (Non-perspective Bary, ForceZeroRTAIndex)
-
- 3DSTATE_RASTER
- 3DSTATE_SF
- -> iris_raster_state
-
- 3DSTATE_WM
- -> iris_raster_state + FS state (barycentric, EDSC)
- 3DSTATE_SBE
- -> iris_raster_state (point sprite texture coordinate origin)
- -> bunch of shader state...
- 3DSTATE_SBE_SWIZ
- -> FS state
-
- 3DSTATE_DEPTH_BUFFER
- 3DSTATE_HIER_DEPTH_BUFFER
- 3DSTATE_STENCIL_BUFFER
- 3DSTATE_CLEAR_PARAMS
- -> iris_framebuffer_state?
-
- 3DSTATE_VF_TOPOLOGY
- -> pipe_draw_info (prim_mode)
- 3DSTATE_VF
- -> pipe_draw_info (restart_index, primitive_restart)
-
- 3DSTATE_INDEX_BUFFER
- -> pipe_draw_info (index)
- 3DSTATE_VERTEX_BUFFERS
- -> pipe_vertex_buffer (set_vertex_buffer hook)
- 3DSTATE_VERTEX_ELEMENTS
- -> iris_vertex_element
- 3DSTATE_VF_INSTANCING
- -> iris_vertex_element
- 3DSTATE_VF_SGVS
- -> TODO ???
- 3DSTATE_VF_COMPONENT_PACKING
- -> TODO ???
-
- 3DPRIMITIVE
- -> pipe_draw_info
-
- rare:
- 3DSTATE_POLY_STIPPLE_OFFSET
- 3DSTATE_POLY_STIPPLE_PATTERN
- -> ice->state.poly_stipple
- 3DSTATE_LINE_STIPPLE
- -> iris_raster_state
-
- once:
- 3DSTATE_AA_LINE_PARAMETERS
- 3DSTATE_WM_CHROMAKEY
- 3DSTATE_SAMPLE_PATTERN
- 3DSTATE_DRAWING_RECTANGLE
- 3DSTATE_WM_HZ_OP
-#endif
+ iris_update_compiled_shaders(ice);
+ //iris_upload_render_state(ice, &ice->batch, info);
+ iris_upload_render_state(ice, NULL, info);
}
unsigned program_id;
};
+// XXX: need unify_interfaces() at link time...
+
static void *
iris_create_shader_state(struct pipe_context *ctx,
const struct pipe_shader_state *state)
nir_shader *nir = state->ir.nir;
- struct iris_uncompiled_shader *cso =
+ struct iris_uncompiled_shader *ish =
calloc(1, sizeof(struct iris_uncompiled_shader));
- if (!cso)
+ if (!ish)
return NULL;
nir = brw_preprocess_nir(screen->compiler, nir);
+ //NIR_PASS_V(nir, brw_nir_lower_uniforms, true);
- cso->program_id = get_new_program_id(screen);
- cso->base.type = PIPE_SHADER_IR_NIR;
- cso->base.ir.nir = nir;
+ ish->program_id = get_new_program_id(screen);
+ ish->base.type = PIPE_SHADER_IR_NIR;
+ ish->base.ir.nir = nir;
- return cso;
+ return ish;
}
static void
iris_delete_shader_state(struct pipe_context *ctx, void *hwcso)
{
- struct iris_uncompiled_shader *cso = hwcso;
+ struct iris_uncompiled_shader *ish = hwcso;
+
+ ralloc_free(ish->base.ir.nir);
+ free(ish);
+}
+
+static void
+iris_bind_vs_state(struct pipe_context *ctx, void *hwcso)
+{
+ struct iris_context *ice = (struct iris_context *)ctx;
+
+ ice->progs[MESA_SHADER_VERTEX] = hwcso;
+ ice->state.dirty |= IRIS_DIRTY_UNCOMPILED_VS;
+}
+
+static void
+iris_bind_tcs_state(struct pipe_context *ctx, void *hwcso)
+{
+ struct iris_context *ice = (struct iris_context *)ctx;
+
+ ice->progs[MESA_SHADER_TESS_CTRL] = hwcso;
+ ice->state.dirty |= IRIS_DIRTY_UNCOMPILED_TCS;
+}
+
+static void
+iris_bind_tes_state(struct pipe_context *ctx, void *hwcso)
+{
+ struct iris_context *ice = (struct iris_context *)ctx;
+
+ ice->progs[MESA_SHADER_TESS_EVAL] = hwcso;
+ ice->state.dirty |= IRIS_DIRTY_UNCOMPILED_TES;
+}
+
+static void
+iris_bind_gs_state(struct pipe_context *ctx, void *hwcso)
+{
+ struct iris_context *ice = (struct iris_context *)ctx;
+
+ ice->progs[MESA_SHADER_GEOMETRY] = hwcso;
+ ice->state.dirty |= IRIS_DIRTY_UNCOMPILED_GS;
+}
+
+static void
+iris_bind_fs_state(struct pipe_context *ctx, void *hwcso)
+{
+ struct iris_context *ice = (struct iris_context *)ctx;
+
+ ice->progs[MESA_SHADER_FRAGMENT] = hwcso;
+ ice->state.dirty |= IRIS_DIRTY_UNCOMPILED_FS;
+}
+
+/**
+ * Sets up the starting offsets for the groups of binding table entries
+ * common to all pipeline stages.
+ *
+ * Unused groups are initialized to 0xd0d0d0d0 to make it obvious that they're
+ * unused but also make sure that addition of small offsets to them will
+ * trigger some of our asserts that surface indices are < BRW_MAX_SURFACES.
+ */
+static uint32_t
+assign_common_binding_table_offsets(const struct gen_device_info *devinfo,
+ const struct shader_info *info,
+ struct brw_stage_prog_data *prog_data,
+ uint32_t next_binding_table_offset)
+{
+ prog_data->binding_table.texture_start = next_binding_table_offset;
+ prog_data->binding_table.gather_texture_start = next_binding_table_offset;
+ next_binding_table_offset += info->num_textures;
+
+ if (info->num_ubos) {
+ //assert(info->num_ubos <= BRW_MAX_UBO);
+ prog_data->binding_table.ubo_start = next_binding_table_offset;
+ next_binding_table_offset += info->num_ubos;
+ } else {
+ prog_data->binding_table.ubo_start = 0xd0d0d0d0;
+ }
+
+ if (info->num_ssbos || info->num_abos) {
+ //assert(info->num_abos <= BRW_MAX_ABO);
+ //assert(info->num_ssbos <= BRW_MAX_SSBO);
+ prog_data->binding_table.ssbo_start = next_binding_table_offset;
+ next_binding_table_offset += info->num_abos + info->num_ssbos;
+ } else {
+ prog_data->binding_table.ssbo_start = 0xd0d0d0d0;
+ }
+
+ prog_data->binding_table.shader_time_start = 0xd0d0d0d0;
+
+ if (info->num_images) {
+ prog_data->binding_table.image_start = next_binding_table_offset;
+ next_binding_table_offset += info->num_images;
+ } else {
+ prog_data->binding_table.image_start = 0xd0d0d0d0;
+ }
+
+ /* This may or may not be used depending on how the compile goes. */
+ prog_data->binding_table.pull_constants_start = next_binding_table_offset;
+ next_binding_table_offset++;
+
+ /* Plane 0 is just the regular texture section */
+ prog_data->binding_table.plane_start[0] = prog_data->binding_table.texture_start;
+
+ prog_data->binding_table.plane_start[1] = next_binding_table_offset;
+ next_binding_table_offset += info->num_textures;
+
+ prog_data->binding_table.plane_start[2] = next_binding_table_offset;
+ next_binding_table_offset += info->num_textures;
+
+ /* prog_data->base.binding_table.size will be set by brw_mark_surface_used. */
+
+ //assert(next_binding_table_offset <= BRW_MAX_SURFACES);
+ return next_binding_table_offset;
+}
+
+static bool
+iris_compile_vs(struct iris_context *ice,
+ struct iris_uncompiled_shader *ish,
+ const struct brw_vs_prog_key *key)
+{
+ struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
+ const struct brw_compiler *compiler = screen->compiler;
+ const struct gen_device_info *devinfo = &screen->devinfo;
+ const unsigned *program;
+ struct brw_vs_prog_data prog_data;
+ struct brw_stage_prog_data *stage_prog_data = &prog_data.base.base;
+ void *mem_ctx = ralloc_context(NULL);
+
+ assert(ish->base.type == PIPE_SHADER_IR_NIR);
+
+ nir_shader *nir = ish->base.ir.nir;
+
+ memset(&prog_data, 0, sizeof(prog_data));
+
+ // XXX: alt mode
+ assign_common_binding_table_offsets(devinfo, &nir->info,
+ &prog_data.base.base, 0);
+ brw_compute_vue_map(devinfo,
+ &prog_data.base.vue_map, nir->info.outputs_written,
+ nir->info.separate_shader);
+
+ char *error_str;
+ program = brw_compile_vs(compiler, ice, mem_ctx, key, &prog_data,
+ nir, -1, &error_str);
+ if (program == NULL) {
+ fprintf(stderr, "Failed to compile vertex shader: %s\n", error_str);
- ralloc_free(cso->base.ir.nir);
- free(cso);
+ ralloc_free(mem_ctx);
+ return false;
+ }
+
+ /* The param and pull_param arrays will be freed by the shader cache. */
+ ralloc_steal(NULL, prog_data.base.base.param);
+ ralloc_steal(NULL, prog_data.base.base.pull_param);
+ //brw_upload_cache(&brw->cache, BRW_CACHE_VS_PROG,
+ //key, sizeof(struct brw_vs_prog_key),
+ //program, prog_data.base.base.program_size,
+ //&prog_data, sizeof(prog_data),
+ //&brw->vs.base.prog_offset, &brw->vs.base.prog_data);
+ ralloc_free(mem_ctx);
+
+ return true;
+}
+
+static void
+iris_populate_vs_key(struct iris_context *ice, struct brw_vs_prog_key *key)
+{
+ memset(key, 0, sizeof(*key));
+}
+
+static void
+iris_update_compiled_vs(struct iris_context *ice)
+{
+ struct brw_vs_prog_key key;
+ iris_populate_vs_key(ice, &key);
+
+ UNUSED bool success =
+ iris_compile_vs(ice, ice->progs[MESA_SHADER_VERTEX], &key);
+}
+
+void
+iris_update_compiled_shaders(struct iris_context *ice)
+{
+ iris_update_compiled_vs(ice);
+ // ...
}
void
iris_init_program_functions(struct pipe_context *ctx)
{
- ctx->create_vs_state = iris_create_shader_state;
+ ctx->create_vs_state = iris_create_shader_state;
ctx->create_tcs_state = iris_create_shader_state;
ctx->create_tes_state = iris_create_shader_state;
- ctx->create_gs_state = iris_create_shader_state;
- ctx->create_fs_state = iris_create_shader_state;
+ ctx->create_gs_state = iris_create_shader_state;
+ ctx->create_fs_state = iris_create_shader_state;
- ctx->delete_vs_state = iris_delete_shader_state;
+ ctx->delete_vs_state = iris_delete_shader_state;
ctx->delete_tcs_state = iris_delete_shader_state;
ctx->delete_tes_state = iris_delete_shader_state;
- ctx->delete_gs_state = iris_delete_shader_state;
- ctx->delete_fs_state = iris_delete_shader_state;
+ ctx->delete_gs_state = iris_delete_shader_state;
+ ctx->delete_fs_state = iris_delete_shader_state;
+
+ ctx->bind_vs_state = iris_bind_vs_state;
+ ctx->bind_tcs_state = iris_bind_tcs_state;
+ ctx->bind_tes_state = iris_bind_tes_state;
+ ctx->bind_gs_state = iris_bind_gs_state;
+ ctx->bind_fs_state = iris_bind_fs_state;
}