summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/iris/iris_program.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/iris/iris_program.c')
-rw-r--r--src/gallium/drivers/iris/iris_program.c642
1 files changed, 312 insertions, 330 deletions
diff --git a/src/gallium/drivers/iris/iris_program.c b/src/gallium/drivers/iris/iris_program.c
index 8b1fa56659a..eb341e94fdd 100644
--- a/src/gallium/drivers/iris/iris_program.c
+++ b/src/gallium/drivers/iris/iris_program.c
@@ -45,26 +45,6 @@
#define ALL_SAMPLERS_XYZW .tex.swizzles[0 ... MAX_SAMPLERS - 1] = 0x688
#define KEY_INIT .program_string_id = ish->program_id, ALL_SAMPLERS_XYZW
-static struct iris_compiled_shader *
-iris_compile_vs(struct iris_context *, struct iris_uncompiled_shader *,
- const struct brw_vs_prog_key *);
-static struct iris_compiled_shader *
-iris_compile_tcs(struct iris_context *, struct iris_uncompiled_shader *,
- const struct brw_tcs_prog_key *);
-static struct iris_compiled_shader *
-iris_compile_tes(struct iris_context *, struct iris_uncompiled_shader *,
- const struct brw_tes_prog_key *);
-static struct iris_compiled_shader *
-iris_compile_gs(struct iris_context *, struct iris_uncompiled_shader *,
- const struct brw_gs_prog_key *);
-static struct iris_compiled_shader *
-iris_compile_fs(struct iris_context *, struct iris_uncompiled_shader *,
- const struct brw_wm_prog_key *, struct brw_vue_map *);
-static struct iris_compiled_shader *
-iris_compile_cs(struct iris_context *, struct iris_uncompiled_shader *,
- const struct brw_cs_prog_key *);
-
-
static unsigned
get_new_program_id(struct iris_screen *screen)
{
@@ -231,316 +211,6 @@ update_so_info(struct pipe_stream_output_info *so_info,
}
/**
- * The pipe->create_[stage]_state() driver hooks.
- *
- * Performs basic NIR preprocessing, records any state dependencies, and
- * returns an iris_uncompiled_shader as the Gallium CSO.
- *
- * Actual shader compilation to assembly happens later, at first use.
- */
-static void *
-iris_create_uncompiled_shader(struct pipe_context *ctx,
- nir_shader *nir,
- const struct pipe_stream_output_info *so_info)
-{
- struct iris_screen *screen = (struct iris_screen *)ctx->screen;
- const struct gen_device_info *devinfo = &screen->devinfo;
-
- struct iris_uncompiled_shader *ish =
- calloc(1, sizeof(struct iris_uncompiled_shader));
- if (!ish)
- return NULL;
-
- nir = brw_preprocess_nir(screen->compiler, nir);
-
- NIR_PASS_V(nir, brw_nir_lower_image_load_store, devinfo);
- NIR_PASS_V(nir, iris_lower_storage_image_derefs);
-
- ish->program_id = get_new_program_id(screen);
- ish->nir = nir;
- if (so_info) {
- memcpy(&ish->stream_output, so_info, sizeof(*so_info));
- update_so_info(&ish->stream_output, nir->info.outputs_written);
- }
-
- return ish;
-}
-
-static struct iris_uncompiled_shader *
-iris_create_shader_state(struct pipe_context *ctx,
- const struct pipe_shader_state *state)
-{
- assert(state->type == PIPE_SHADER_IR_NIR);
-
- return iris_create_uncompiled_shader(ctx, state->ir.nir,
- &state->stream_output);
-}
-
-static void *
-iris_create_vs_state(struct pipe_context *ctx,
- const struct pipe_shader_state *state)
-{
- struct iris_context *ice = (void *) ctx;
- struct iris_screen *screen = (void *) ctx->screen;
- struct iris_uncompiled_shader *ish = iris_create_shader_state(ctx, state);
-
- /* User clip planes */
- if (ish->nir->info.clip_distance_array_size == 0)
- ish->nos |= (1ull << IRIS_NOS_RASTERIZER);
-
- if (screen->precompile) {
- struct brw_vs_prog_key key = { KEY_INIT };
-
- iris_compile_vs(ice, ish, &key);
- }
-
- return ish;
-}
-
-static void *
-iris_create_tcs_state(struct pipe_context *ctx,
- const struct pipe_shader_state *state)
-{
- struct iris_context *ice = (void *) ctx;
- struct iris_screen *screen = (void *) ctx->screen;
- struct iris_uncompiled_shader *ish = iris_create_shader_state(ctx, state);
- struct shader_info *info = &ish->nir->info;
-
- // XXX: NOS?
-
- if (screen->precompile) {
- const unsigned _GL_TRIANGLES = 0x0004;
- struct brw_tcs_prog_key key = {
- KEY_INIT,
- // XXX: make sure the linker fills this out from the TES...
- .tes_primitive_mode =
- info->tess.primitive_mode ? info->tess.primitive_mode
- : _GL_TRIANGLES,
- .outputs_written = info->outputs_written,
- .patch_outputs_written = info->patch_outputs_written,
- };
-
- iris_compile_tcs(ice, ish, &key);
- }
-
- return ish;
-}
-
-static void *
-iris_create_tes_state(struct pipe_context *ctx,
- const struct pipe_shader_state *state)
-{
- struct iris_context *ice = (void *) ctx;
- struct iris_screen *screen = (void *) ctx->screen;
- struct iris_uncompiled_shader *ish = iris_create_shader_state(ctx, state);
- struct shader_info *info = &ish->nir->info;
-
- // XXX: NOS?
-
- if (screen->precompile) {
- struct brw_tes_prog_key key = {
- KEY_INIT,
- // XXX: not ideal, need TCS output/TES input unification
- .inputs_read = info->inputs_read,
- .patch_inputs_read = info->patch_inputs_read,
- };
-
- iris_compile_tes(ice, ish, &key);
- }
-
- return ish;
-}
-
-static void *
-iris_create_gs_state(struct pipe_context *ctx,
- const struct pipe_shader_state *state)
-{
- struct iris_context *ice = (void *) ctx;
- struct iris_screen *screen = (void *) ctx->screen;
- struct iris_uncompiled_shader *ish = iris_create_shader_state(ctx, state);
-
- // XXX: NOS?
-
- if (screen->precompile) {
- struct brw_gs_prog_key key = { KEY_INIT };
-
- iris_compile_gs(ice, ish, &key);
- }
-
- return ish;
-}
-
-static void *
-iris_create_fs_state(struct pipe_context *ctx,
- const struct pipe_shader_state *state)
-{
- struct iris_context *ice = (void *) ctx;
- struct iris_screen *screen = (void *) ctx->screen;
- struct iris_uncompiled_shader *ish = iris_create_shader_state(ctx, state);
- struct shader_info *info = &ish->nir->info;
-
- ish->nos |= (1ull << IRIS_NOS_FRAMEBUFFER) |
- (1ull << IRIS_NOS_DEPTH_STENCIL_ALPHA) |
- (1ull << IRIS_NOS_RASTERIZER) |
- (1ull << IRIS_NOS_BLEND);
-
- /* The program key needs the VUE map if there are > 16 inputs */
- if (util_bitcount64(ish->nir->info.inputs_read &
- BRW_FS_VARYING_INPUT_MASK) > 16) {
- ish->nos |= (1ull << IRIS_NOS_LAST_VUE_MAP);
- }
-
- if (screen->precompile) {
- const uint64_t color_outputs = info->outputs_written &
- ~(BITFIELD64_BIT(FRAG_RESULT_DEPTH) |
- BITFIELD64_BIT(FRAG_RESULT_STENCIL) |
- BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK));
-
- bool can_rearrange_varyings =
- util_bitcount64(info->inputs_read & BRW_FS_VARYING_INPUT_MASK) <= 16;
-
- struct brw_wm_prog_key key = {
- KEY_INIT,
- .nr_color_regions = util_bitcount(color_outputs),
- .coherent_fb_fetch = true,
- .input_slots_valid =
- can_rearrange_varyings ? 0 : info->inputs_read | VARYING_BIT_POS,
- };
-
- iris_compile_fs(ice, ish, &key, NULL);
- }
-
- return ish;
-}
-
-static void *
-iris_create_compute_state(struct pipe_context *ctx,
- const struct pipe_compute_state *state)
-{
- assert(state->ir_type == PIPE_SHADER_IR_NIR);
-
- struct iris_context *ice = (void *) ctx;
- struct iris_screen *screen = (void *) ctx->screen;
- struct iris_uncompiled_shader *ish =
- iris_create_uncompiled_shader(ctx, (void *) state->prog, NULL);
-
- // XXX: disallow more than 64KB of shared variables
-
- if (screen->precompile) {
- struct brw_cs_prog_key key = { KEY_INIT };
-
- iris_compile_cs(ice, ish, &key);
- }
-
- return ish;
-}
-
-/**
- * The pipe->delete_[stage]_state() driver hooks.
- *
- * Frees the iris_uncompiled_shader.
- */
-static void
-iris_delete_shader_state(struct pipe_context *ctx, void *state)
-{
- struct iris_uncompiled_shader *ish = state;
-
- ralloc_free(ish->nir);
- free(ish);
-}
-
-/**
- * The pipe->bind_[stage]_state() driver hook.
- *
- * Binds an uncompiled shader as the current one for a particular stage.
- * Updates dirty tracking to account for the shader's NOS.
- */
-static void
-bind_state(struct iris_context *ice,
- struct iris_uncompiled_shader *ish,
- gl_shader_stage stage)
-{
- uint64_t dirty_bit = IRIS_DIRTY_UNCOMPILED_VS << stage;
- const uint64_t nos = ish ? ish->nos : 0;
-
- ice->shaders.uncompiled[stage] = ish;
- ice->state.dirty |= dirty_bit;
-
- /* Record that CSOs need to mark IRIS_DIRTY_UNCOMPILED_XS when they change
- * (or that they no longer need to do so).
- */
- for (int i = 0; i < IRIS_NOS_COUNT; i++) {
- if (nos & (1 << i))
- ice->state.dirty_for_nos[i] |= dirty_bit;
- else
- ice->state.dirty_for_nos[i] &= ~dirty_bit;
- }
-}
-
-static void
-iris_bind_vs_state(struct pipe_context *ctx, void *state)
-{
- bind_state((void *) ctx, state, MESA_SHADER_VERTEX);
-}
-
-static void
-iris_bind_tcs_state(struct pipe_context *ctx, void *state)
-{
- bind_state((void *) ctx, state, MESA_SHADER_TESS_CTRL);
-}
-
-static void
-iris_bind_tes_state(struct pipe_context *ctx, void *state)
-{
- struct iris_context *ice = (struct iris_context *)ctx;
-
- /* Enabling/disabling optional stages requires a URB reconfiguration. */
- if (!!state != !!ice->shaders.uncompiled[MESA_SHADER_TESS_EVAL])
- ice->state.dirty |= IRIS_DIRTY_URB;
-
- bind_state((void *) ctx, state, MESA_SHADER_TESS_EVAL);
-}
-
-static void
-iris_bind_gs_state(struct pipe_context *ctx, void *state)
-{
- struct iris_context *ice = (struct iris_context *)ctx;
-
- /* Enabling/disabling optional stages requires a URB reconfiguration. */
- if (!!state != !!ice->shaders.uncompiled[MESA_SHADER_GEOMETRY])
- ice->state.dirty |= IRIS_DIRTY_URB;
-
- bind_state((void *) ctx, state, MESA_SHADER_GEOMETRY);
-}
-
-static void
-iris_bind_fs_state(struct pipe_context *ctx, void *state)
-{
- struct iris_context *ice = (struct iris_context *) ctx;
- struct iris_uncompiled_shader *old_ish =
- ice->shaders.uncompiled[MESA_SHADER_FRAGMENT];
- struct iris_uncompiled_shader *new_ish = state;
-
- const unsigned color_bits =
- BITFIELD64_BIT(FRAG_RESULT_COLOR) |
- BITFIELD64_RANGE(FRAG_RESULT_DATA0, BRW_MAX_DRAW_BUFFERS);
-
- /* Fragment shader outputs influence HasWriteableRT */
- if (!old_ish || !new_ish ||
- (old_ish->nir->info.outputs_written & color_bits) !=
- (new_ish->nir->info.outputs_written & color_bits))
- ice->state.dirty |= IRIS_DIRTY_PS_BLEND;
-
- bind_state((void *) ctx, state, MESA_SHADER_FRAGMENT);
-}
-
-static void
-iris_bind_cs_state(struct pipe_context *ctx, void *state)
-{
- bind_state((void *) ctx, state, MESA_SHADER_COMPUTE);
-}
-
-/**
* Sets up the starting offsets for the groups of binding table entries
* common to all pipeline stages.
*
@@ -1658,6 +1328,318 @@ iris_get_scratch_space(struct iris_context *ice,
return *bop;
}
+/* ------------------------------------------------------------------- */
+
+/**
+ * The pipe->create_[stage]_state() driver hooks.
+ *
+ * Performs basic NIR preprocessing, records any state dependencies, and
+ * returns an iris_uncompiled_shader as the Gallium CSO.
+ *
+ * Actual shader compilation to assembly happens later, at first use.
+ */
+static void *
+iris_create_uncompiled_shader(struct pipe_context *ctx,
+ nir_shader *nir,
+ const struct pipe_stream_output_info *so_info)
+{
+ struct iris_screen *screen = (struct iris_screen *)ctx->screen;
+ const struct gen_device_info *devinfo = &screen->devinfo;
+
+ struct iris_uncompiled_shader *ish =
+ calloc(1, sizeof(struct iris_uncompiled_shader));
+ if (!ish)
+ return NULL;
+
+ nir = brw_preprocess_nir(screen->compiler, nir);
+
+ NIR_PASS_V(nir, brw_nir_lower_image_load_store, devinfo);
+ NIR_PASS_V(nir, iris_lower_storage_image_derefs);
+
+ ish->program_id = get_new_program_id(screen);
+ ish->nir = nir;
+ if (so_info) {
+ memcpy(&ish->stream_output, so_info, sizeof(*so_info));
+ update_so_info(&ish->stream_output, nir->info.outputs_written);
+ }
+
+ return ish;
+}
+
+static struct iris_uncompiled_shader *
+iris_create_shader_state(struct pipe_context *ctx,
+ const struct pipe_shader_state *state)
+{
+ assert(state->type == PIPE_SHADER_IR_NIR);
+
+ return iris_create_uncompiled_shader(ctx, state->ir.nir,
+ &state->stream_output);
+}
+
+static void *
+iris_create_vs_state(struct pipe_context *ctx,
+ const struct pipe_shader_state *state)
+{
+ struct iris_context *ice = (void *) ctx;
+ struct iris_screen *screen = (void *) ctx->screen;
+ struct iris_uncompiled_shader *ish = iris_create_shader_state(ctx, state);
+
+ /* User clip planes */
+ if (ish->nir->info.clip_distance_array_size == 0)
+ ish->nos |= (1ull << IRIS_NOS_RASTERIZER);
+
+ if (screen->precompile) {
+ struct brw_vs_prog_key key = { KEY_INIT };
+
+ iris_compile_vs(ice, ish, &key);
+ }
+
+ return ish;
+}
+
+static void *
+iris_create_tcs_state(struct pipe_context *ctx,
+ const struct pipe_shader_state *state)
+{
+ struct iris_context *ice = (void *) ctx;
+ struct iris_screen *screen = (void *) ctx->screen;
+ struct iris_uncompiled_shader *ish = iris_create_shader_state(ctx, state);
+ struct shader_info *info = &ish->nir->info;
+
+ // XXX: NOS?
+
+ if (screen->precompile) {
+ const unsigned _GL_TRIANGLES = 0x0004;
+ struct brw_tcs_prog_key key = {
+ KEY_INIT,
+ // XXX: make sure the linker fills this out from the TES...
+ .tes_primitive_mode =
+ info->tess.primitive_mode ? info->tess.primitive_mode
+ : _GL_TRIANGLES,
+ .outputs_written = info->outputs_written,
+ .patch_outputs_written = info->patch_outputs_written,
+ };
+
+ iris_compile_tcs(ice, ish, &key);
+ }
+
+ return ish;
+}
+
+static void *
+iris_create_tes_state(struct pipe_context *ctx,
+ const struct pipe_shader_state *state)
+{
+ struct iris_context *ice = (void *) ctx;
+ struct iris_screen *screen = (void *) ctx->screen;
+ struct iris_uncompiled_shader *ish = iris_create_shader_state(ctx, state);
+ struct shader_info *info = &ish->nir->info;
+
+ // XXX: NOS?
+
+ if (screen->precompile) {
+ struct brw_tes_prog_key key = {
+ KEY_INIT,
+ // XXX: not ideal, need TCS output/TES input unification
+ .inputs_read = info->inputs_read,
+ .patch_inputs_read = info->patch_inputs_read,
+ };
+
+ iris_compile_tes(ice, ish, &key);
+ }
+
+ return ish;
+}
+
+static void *
+iris_create_gs_state(struct pipe_context *ctx,
+ const struct pipe_shader_state *state)
+{
+ struct iris_context *ice = (void *) ctx;
+ struct iris_screen *screen = (void *) ctx->screen;
+ struct iris_uncompiled_shader *ish = iris_create_shader_state(ctx, state);
+
+ // XXX: NOS?
+
+ if (screen->precompile) {
+ struct brw_gs_prog_key key = { KEY_INIT };
+
+ iris_compile_gs(ice, ish, &key);
+ }
+
+ return ish;
+}
+
+static void *
+iris_create_fs_state(struct pipe_context *ctx,
+ const struct pipe_shader_state *state)
+{
+ struct iris_context *ice = (void *) ctx;
+ struct iris_screen *screen = (void *) ctx->screen;
+ struct iris_uncompiled_shader *ish = iris_create_shader_state(ctx, state);
+ struct shader_info *info = &ish->nir->info;
+
+ ish->nos |= (1ull << IRIS_NOS_FRAMEBUFFER) |
+ (1ull << IRIS_NOS_DEPTH_STENCIL_ALPHA) |
+ (1ull << IRIS_NOS_RASTERIZER) |
+ (1ull << IRIS_NOS_BLEND);
+
+ /* The program key needs the VUE map if there are > 16 inputs */
+ if (util_bitcount64(ish->nir->info.inputs_read &
+ BRW_FS_VARYING_INPUT_MASK) > 16) {
+ ish->nos |= (1ull << IRIS_NOS_LAST_VUE_MAP);
+ }
+
+ if (screen->precompile) {
+ const uint64_t color_outputs = info->outputs_written &
+ ~(BITFIELD64_BIT(FRAG_RESULT_DEPTH) |
+ BITFIELD64_BIT(FRAG_RESULT_STENCIL) |
+ BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK));
+
+ bool can_rearrange_varyings =
+ util_bitcount64(info->inputs_read & BRW_FS_VARYING_INPUT_MASK) <= 16;
+
+ struct brw_wm_prog_key key = {
+ KEY_INIT,
+ .nr_color_regions = util_bitcount(color_outputs),
+ .coherent_fb_fetch = true,
+ .input_slots_valid =
+ can_rearrange_varyings ? 0 : info->inputs_read | VARYING_BIT_POS,
+ };
+
+ iris_compile_fs(ice, ish, &key, NULL);
+ }
+
+ return ish;
+}
+
+static void *
+iris_create_compute_state(struct pipe_context *ctx,
+ const struct pipe_compute_state *state)
+{
+ assert(state->ir_type == PIPE_SHADER_IR_NIR);
+
+ struct iris_context *ice = (void *) ctx;
+ struct iris_screen *screen = (void *) ctx->screen;
+ struct iris_uncompiled_shader *ish =
+ iris_create_uncompiled_shader(ctx, (void *) state->prog, NULL);
+
+ // XXX: disallow more than 64KB of shared variables
+
+ if (screen->precompile) {
+ struct brw_cs_prog_key key = { KEY_INIT };
+
+ iris_compile_cs(ice, ish, &key);
+ }
+
+ return ish;
+}
+
+/**
+ * The pipe->delete_[stage]_state() driver hooks.
+ *
+ * Frees the iris_uncompiled_shader.
+ */
+static void
+iris_delete_shader_state(struct pipe_context *ctx, void *state)
+{
+ struct iris_uncompiled_shader *ish = state;
+
+ ralloc_free(ish->nir);
+ free(ish);
+}
+
+/**
+ * The pipe->bind_[stage]_state() driver hook.
+ *
+ * Binds an uncompiled shader as the current one for a particular stage.
+ * Updates dirty tracking to account for the shader's NOS.
+ */
+static void
+bind_state(struct iris_context *ice,
+ struct iris_uncompiled_shader *ish,
+ gl_shader_stage stage)
+{
+ uint64_t dirty_bit = IRIS_DIRTY_UNCOMPILED_VS << stage;
+ const uint64_t nos = ish ? ish->nos : 0;
+
+ ice->shaders.uncompiled[stage] = ish;
+ ice->state.dirty |= dirty_bit;
+
+ /* Record that CSOs need to mark IRIS_DIRTY_UNCOMPILED_XS when they change
+ * (or that they no longer need to do so).
+ */
+ for (int i = 0; i < IRIS_NOS_COUNT; i++) {
+ if (nos & (1 << i))
+ ice->state.dirty_for_nos[i] |= dirty_bit;
+ else
+ ice->state.dirty_for_nos[i] &= ~dirty_bit;
+ }
+}
+
+static void
+iris_bind_vs_state(struct pipe_context *ctx, void *state)
+{
+ bind_state((void *) ctx, state, MESA_SHADER_VERTEX);
+}
+
+static void
+iris_bind_tcs_state(struct pipe_context *ctx, void *state)
+{
+ bind_state((void *) ctx, state, MESA_SHADER_TESS_CTRL);
+}
+
+static void
+iris_bind_tes_state(struct pipe_context *ctx, void *state)
+{
+ struct iris_context *ice = (struct iris_context *)ctx;
+
+ /* Enabling/disabling optional stages requires a URB reconfiguration. */
+ if (!!state != !!ice->shaders.uncompiled[MESA_SHADER_TESS_EVAL])
+ ice->state.dirty |= IRIS_DIRTY_URB;
+
+ bind_state((void *) ctx, state, MESA_SHADER_TESS_EVAL);
+}
+
+static void
+iris_bind_gs_state(struct pipe_context *ctx, void *state)
+{
+ struct iris_context *ice = (struct iris_context *)ctx;
+
+ /* Enabling/disabling optional stages requires a URB reconfiguration. */
+ if (!!state != !!ice->shaders.uncompiled[MESA_SHADER_GEOMETRY])
+ ice->state.dirty |= IRIS_DIRTY_URB;
+
+ bind_state((void *) ctx, state, MESA_SHADER_GEOMETRY);
+}
+
+static void
+iris_bind_fs_state(struct pipe_context *ctx, void *state)
+{
+ struct iris_context *ice = (struct iris_context *) ctx;
+ struct iris_uncompiled_shader *old_ish =
+ ice->shaders.uncompiled[MESA_SHADER_FRAGMENT];
+ struct iris_uncompiled_shader *new_ish = state;
+
+ const unsigned color_bits =
+ BITFIELD64_BIT(FRAG_RESULT_COLOR) |
+ BITFIELD64_RANGE(FRAG_RESULT_DATA0, BRW_MAX_DRAW_BUFFERS);
+
+ /* Fragment shader outputs influence HasWriteableRT */
+ if (!old_ish || !new_ish ||
+ (old_ish->nir->info.outputs_written & color_bits) !=
+ (new_ish->nir->info.outputs_written & color_bits))
+ ice->state.dirty |= IRIS_DIRTY_PS_BLEND;
+
+ bind_state((void *) ctx, state, MESA_SHADER_FRAGMENT);
+}
+
+static void
+iris_bind_cs_state(struct pipe_context *ctx, void *state)
+{
+ bind_state((void *) ctx, state, MESA_SHADER_COMPUTE);
+}
+
void
iris_init_program_functions(struct pipe_context *ctx)
{