summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/iris/iris_batch.c3
-rw-r--r--src/gallium/drivers/iris/iris_batch.h2
-rw-r--r--src/gallium/drivers/iris/iris_context.c16
-rw-r--r--src/gallium/drivers/iris/iris_context.h46
-rw-r--r--src/gallium/drivers/iris/iris_draw.c2
-rw-r--r--src/gallium/drivers/iris/iris_program_cache.c4
-rw-r--r--src/gallium/drivers/iris/iris_state.c559
7 files changed, 322 insertions, 310 deletions
diff --git a/src/gallium/drivers/iris/iris_batch.c b/src/gallium/drivers/iris/iris_batch.c
index 23cff418960..5d3d6698a37 100644
--- a/src/gallium/drivers/iris/iris_batch.c
+++ b/src/gallium/drivers/iris/iris_batch.c
@@ -201,6 +201,9 @@ iris_batch_reset(struct iris_batch *batch)
if (batch->state_sizes)
_mesa_hash_table_clear(batch->state_sizes, NULL);
+
+ if (batch->ring == I915_EXEC_RENDER)
+ batch->emit_state_base_address(batch);
}
static void
diff --git a/src/gallium/drivers/iris/iris_batch.h b/src/gallium/drivers/iris/iris_batch.h
index 47da23baeb1..6b67737f614 100644
--- a/src/gallium/drivers/iris/iris_batch.h
+++ b/src/gallium/drivers/iris/iris_batch.h
@@ -89,6 +89,8 @@ struct iris_batch {
/** Map from batch offset to iris_alloc_state data (with DEBUG_BATCH) */
struct hash_table *state_sizes;
+
+ void (*emit_state_base_address)(struct iris_batch *batch);
};
void iris_init_batch(struct iris_batch *batch,
diff --git a/src/gallium/drivers/iris/iris_context.c b/src/gallium/drivers/iris/iris_context.c
index ffebaf3c0a0..ca2aeeb4942 100644
--- a/src/gallium/drivers/iris/iris_context.c
+++ b/src/gallium/drivers/iris/iris_context.c
@@ -84,10 +84,23 @@ iris_destroy_context(struct pipe_context *ctx)
ralloc_free(ice);
}
+#define genX_call(devinfo, func, ...) \
+ switch (devinfo->gen) { \
+ case 10: \
+ gen10_##func(__VA_ARGS__); \
+ break; \
+ case 9: \
+ gen9_##func(__VA_ARGS__); \
+ break; \
+ default: \
+ unreachable("Unknown hardware generation"); \
+ }
+
struct pipe_context *
iris_create_context(struct pipe_screen *pscreen, void *priv, unsigned flags)
{
struct iris_screen *screen = (struct iris_screen*)pscreen;
+ const struct gen_device_info *devinfo = &screen->devinfo;
struct iris_context *ice = rzalloc(NULL, struct iris_context);
if (!ice)
@@ -115,11 +128,10 @@ iris_create_context(struct pipe_screen *pscreen, void *priv, unsigned flags)
iris_init_resource_functions(ctx);
iris_init_query_functions(ctx);
- iris_init_state(ice);
iris_init_program_cache(ice);
iris_init_batch(&ice->render_batch, screen, &ice->dbg, I915_EXEC_RENDER);
- iris_upload_initial_gpu_state(&ice->render_batch);
+ genX_call(devinfo, init_state, ice);
return ctx;
}
diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h
index 46ef2d17269..b85c63729d2 100644
--- a/src/gallium/drivers/iris/iris_context.h
+++ b/src/gallium/drivers/iris/iris_context.h
@@ -75,6 +75,16 @@ struct iris_batch;
struct iris_depth_stencil_alpha_state;
+enum iris_program_cache_id {
+ IRIS_CACHE_VS = MESA_SHADER_VERTEX,
+ IRIS_CACHE_TCS = MESA_SHADER_TESS_CTRL,
+ IRIS_CACHE_TES = MESA_SHADER_TESS_EVAL,
+ IRIS_CACHE_GS = MESA_SHADER_GEOMETRY,
+ IRIS_CACHE_FS = MESA_SHADER_FRAGMENT,
+ IRIS_CACHE_CS = MESA_SHADER_COMPUTE,
+ IRIS_CACHE_BLORP_BLIT,
+};
+
struct iris_program_cache {
struct hash_table *table;
struct iris_bo *bo;
@@ -131,6 +141,15 @@ struct iris_context {
struct pipe_framebuffer_state framebuffer;
struct iris_sampler_state *samplers[MESA_SHADER_STAGES][IRIS_MAX_TEXTURE_SAMPLERS];
+
+ void (*upload_render_state)(struct iris_context *ice,
+ struct iris_batch *batch,
+ const struct pipe_draw_info *draw);
+ unsigned (*derived_program_state_size)(enum iris_program_cache_id id);
+ void (*set_derived_program_state)(const struct gen_device_info *devinfo,
+ enum iris_program_cache_id cache_id,
+ struct iris_compiled_shader *shader);
+ void (*destroy_state)(struct iris_context *ice);
} state;
};
@@ -151,38 +170,15 @@ void iris_init_clear_functions(struct pipe_context *ctx);
void iris_init_program_functions(struct pipe_context *ctx);
void iris_init_resource_functions(struct pipe_context *ctx);
void iris_init_query_functions(struct pipe_context *ctx);
-
-void iris_setup_state_base_address(struct iris_context *ice,
- struct iris_batch *batch,
- struct iris_bo *instruction_bo);
-void iris_upload_initial_gpu_state(struct iris_batch *batch);
-void iris_upload_render_state(struct iris_context *ice,
- struct iris_batch *batch,
- const struct pipe_draw_info *draw);
-void iris_destroy_state(struct iris_context *ice);
-
void iris_update_compiled_shaders(struct iris_context *ice);
void iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info);
-enum iris_program_cache_id {
- IRIS_CACHE_VS = MESA_SHADER_VERTEX,
- IRIS_CACHE_TCS = MESA_SHADER_TESS_CTRL,
- IRIS_CACHE_TES = MESA_SHADER_TESS_EVAL,
- IRIS_CACHE_GS = MESA_SHADER_GEOMETRY,
- IRIS_CACHE_FS = MESA_SHADER_FRAGMENT,
- IRIS_CACHE_CS = MESA_SHADER_COMPUTE,
- IRIS_CACHE_BLORP_BLIT,
-};
-
-void iris_init_state(struct iris_context *ice);
+void gen9_init_state(struct iris_context *ice);
+void gen10_init_state(struct iris_context *ice);
void iris_init_program_cache(struct iris_context *ice);
void iris_destroy_program_cache(struct iris_context *ice);
void iris_print_program_cache(struct iris_context *ice);
-unsigned iris_derived_program_state_size(enum iris_program_cache_id cache_id);
-void iris_set_derived_program_state(const struct gen_device_info *devinfo,
- enum iris_program_cache_id cache_id,
- struct iris_compiled_shader *shader);
bool iris_bind_cached_shader(struct iris_context *ice,
enum iris_program_cache_id cache_id,
const void *key);
diff --git a/src/gallium/drivers/iris/iris_draw.c b/src/gallium/drivers/iris/iris_draw.c
index 72537ccb262..96e05fa5f24 100644
--- a/src/gallium/drivers/iris/iris_draw.c
+++ b/src/gallium/drivers/iris/iris_draw.c
@@ -37,5 +37,5 @@ iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
struct iris_context *ice = (struct iris_context *) ctx;
iris_update_compiled_shaders(ice);
- iris_upload_render_state(ice, &ice->render_batch, info);
+ ice->state.upload_render_state(ice, &ice->render_batch, info);
}
diff --git a/src/gallium/drivers/iris/iris_program_cache.c b/src/gallium/drivers/iris/iris_program_cache.c
index acbfba0681a..c1d7f5fbe05 100644
--- a/src/gallium/drivers/iris/iris_program_cache.c
+++ b/src/gallium/drivers/iris/iris_program_cache.c
@@ -259,7 +259,7 @@ iris_upload_and_bind_shader(struct iris_context *ice,
struct iris_program_cache *cache = &ice->shaders.cache;
struct iris_compiled_shader *shader =
ralloc_size(cache->table, sizeof(struct iris_compiled_shader) +
- iris_derived_program_state_size(cache_id));
+ ice->state.derived_program_state_size(cache_id));
const struct iris_compiled_shader *existing =
find_existing_assembly(cache, assembly, prog_data->program_size);
@@ -283,7 +283,7 @@ iris_upload_and_bind_shader(struct iris_context *ice,
ralloc_steal(shader->prog_data, prog_data->pull_param);
/* Store the 3DSTATE shader packets and other derived state. */
- iris_set_derived_program_state(devinfo, cache_id, shader);
+ ice->state.set_derived_program_state(devinfo, cache_id, shader);
struct keybox *keybox = make_keybox(cache, cache_id, key);
_mesa_hash_table_insert(cache->table, keybox, shader);
diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c
index 058bcea07eb..0a05b55fdf3 100644
--- a/src/gallium/drivers/iris/iris_state.c
+++ b/src/gallium/drivers/iris/iris_state.c
@@ -282,7 +282,7 @@ ro_bo(struct iris_bo *bo, uint32_t offset)
return (struct iris_address) { .bo = bo, .offset = offset };
}
-void
+static void
iris_upload_initial_gpu_state(struct iris_batch *batch)
{
iris_emit_cmd(batch, GENX(3DSTATE_DRAWING_RECTANGLE), rect) {
@@ -1312,18 +1312,9 @@ iris_set_stream_output_targets(struct pipe_context *ctx,
{
}
-void
-iris_setup_state_base_address(struct iris_context *ice,
- struct iris_batch *batch,
- struct iris_bo *instruction_bo)
+static void
+iris_emit_state_base_address(struct iris_batch *batch)
{
- if (!(ice->state.dirty & IRIS_DIRTY_STATE_BASE_ADDRESS))
- return;
-
- //iris_batchbuffer_flush(...)
-
- ice->state.dirty &= ~IRIS_DIRTY_STATE_BASE_ADDRESS;
-
/* XXX: PIPE_CONTROLs */
iris_emit_cmd(batch, GENX(STATE_BASE_ADDRESS), sba) {
@@ -1351,17 +1342,277 @@ iris_setup_state_base_address(struct iris_context *ice,
sba.SurfaceStateBaseAddress = ro_bo(batch->statebuf.bo, 0);
sba.DynamicStateBaseAddress = ro_bo(batch->statebuf.bo, 0);
- sba.InstructionBaseAddress = ro_bo(instruction_bo, 0);
sba.GeneralStateBufferSize = 0xfffff000;
- sba.DynamicStateBufferSize = ALIGN(MAX_STATE_SIZE, 4096);
sba.IndirectObjectBufferSize = 0xfffff000;
- sba.InstructionBufferSize = ALIGN(ice->shaders.cache.bo->size, 4096);
- sba.BindlessSurfaceStateSize = 0;
+ sba.InstructionBufferSize = 0xfffff000;
+ sba.DynamicStateBufferSize = ALIGN(MAX_STATE_SIZE, 4096);
}
}
-void
+static void
+iris_bind_compute_state(struct pipe_context *ctx, void *state)
+{
+}
+
+ //pkt.SamplerCount = \
+ //DIV_ROUND_UP(CLAMP(stage_state->sampler_count, 0, 16), 4); \
+ //pkt.PerThreadScratchSpace = prog_data->total_scratch == 0 ? 0 : \
+ //ffs(stage_state->per_thread_scratch) - 11; \
+
+#define INIT_THREAD_DISPATCH_FIELDS(pkt, prefix) \
+ pkt.KernelStartPointer = shader->prog_offset; \
+ pkt.BindingTableEntryCount = prog_data->binding_table.size_bytes / 4; \
+ pkt.FloatingPointMode = prog_data->use_alt_mode; \
+ \
+ pkt.DispatchGRFStartRegisterForURBData = \
+ prog_data->dispatch_grf_start_reg; \
+ pkt.prefix##URBEntryReadLength = vue_prog_data->urb_read_length; \
+ pkt.prefix##URBEntryReadOffset = 0; \
+ \
+ pkt.StatisticsEnable = true; \
+ pkt.Enable = true;
+
+static void
+iris_set_vs_state(const struct gen_device_info *devinfo,
+ struct iris_compiled_shader *shader)
+{
+ struct brw_stage_prog_data *prog_data = shader->prog_data;
+ struct brw_vue_prog_data *vue_prog_data = (void *) prog_data;
+
+ iris_pack_command(GENX(3DSTATE_VS), shader->derived_data, vs) {
+ INIT_THREAD_DISPATCH_FIELDS(vs, Vertex);
+ vs.MaximumNumberofThreads = devinfo->max_vs_threads - 1;
+ vs.SIMD8DispatchEnable = true;
+ vs.UserClipDistanceCullTestEnableBitmask =
+ vue_prog_data->cull_distance_mask;
+ }
+}
+
+static void
+iris_set_tcs_state(const struct gen_device_info *devinfo,
+ struct iris_compiled_shader *shader)
+{
+ struct brw_stage_prog_data *prog_data = shader->prog_data;
+ struct brw_vue_prog_data *vue_prog_data = (void *) prog_data;
+ struct brw_tcs_prog_data *tcs_prog_data = (void *) prog_data;
+
+ iris_pack_command(GENX(3DSTATE_HS), shader->derived_data, hs) {
+ INIT_THREAD_DISPATCH_FIELDS(hs, Vertex);
+
+ hs.InstanceCount = tcs_prog_data->instances - 1;
+ hs.MaximumNumberofThreads = devinfo->max_tcs_threads - 1;
+ hs.IncludeVertexHandles = true;
+ }
+}
+
+static void
+iris_set_tes_state(const struct gen_device_info *devinfo,
+ struct iris_compiled_shader *shader)
+{
+ struct brw_stage_prog_data *prog_data = shader->prog_data;
+ struct brw_vue_prog_data *vue_prog_data = (void *) prog_data;
+ struct brw_tes_prog_data *tes_prog_data = (void *) prog_data;
+
+ uint32_t *te_state = (void *) shader->derived_data;
+ uint32_t *ds_state = te_state + GENX(3DSTATE_TE_length);
+
+ iris_pack_command(GENX(3DSTATE_TE), te_state, te) {
+ te.Partitioning = tes_prog_data->partitioning;
+ te.OutputTopology = tes_prog_data->output_topology;
+ te.TEDomain = tes_prog_data->domain;
+ te.TEEnable = true;
+ te.MaximumTessellationFactorOdd = 63.0;
+ te.MaximumTessellationFactorNotOdd = 64.0;
+ }
+
+ iris_pack_command(GENX(3DSTATE_DS), ds_state, ds) {
+ INIT_THREAD_DISPATCH_FIELDS(ds, Patch);
+
+ ds.DispatchMode = DISPATCH_MODE_SIMD8_SINGLE_PATCH;
+ ds.MaximumNumberofThreads = devinfo->max_tes_threads - 1;
+ ds.ComputeWCoordinateEnable =
+ tes_prog_data->domain == BRW_TESS_DOMAIN_TRI;
+
+ ds.UserClipDistanceCullTestEnableBitmask =
+ vue_prog_data->cull_distance_mask;
+ }
+
+}
+
+static void
+iris_set_gs_state(const struct gen_device_info *devinfo,
+ struct iris_compiled_shader *shader)
+{
+ struct brw_stage_prog_data *prog_data = shader->prog_data;
+ struct brw_vue_prog_data *vue_prog_data = (void *) prog_data;
+ struct brw_gs_prog_data *gs_prog_data = (void *) prog_data;
+
+ iris_pack_command(GENX(3DSTATE_GS), shader->derived_data, gs) {
+ INIT_THREAD_DISPATCH_FIELDS(gs, Vertex);
+
+ gs.OutputVertexSize = gs_prog_data->output_vertex_size_hwords * 2 - 1;
+ gs.OutputTopology = gs_prog_data->output_topology;
+ gs.ControlDataHeaderSize =
+ gs_prog_data->control_data_header_size_hwords;
+ gs.InstanceControl = gs_prog_data->invocations - 1;
+ gs.DispatchMode = SIMD8;
+ gs.IncludePrimitiveID = gs_prog_data->include_primitive_id;
+ gs.ControlDataFormat = gs_prog_data->control_data_format;
+ gs.ReorderMode = TRAILING;
+ gs.ExpectedVertexCount = gs_prog_data->vertices_in;
+ gs.MaximumNumberofThreads =
+ GEN_GEN == 8 ? (devinfo->max_gs_threads / 2 - 1)
+ : (devinfo->max_gs_threads - 1);
+
+ if (gs_prog_data->static_vertex_count != -1) {
+ gs.StaticOutput = true;
+ gs.StaticOutputVertexCount = gs_prog_data->static_vertex_count;
+ }
+ gs.IncludeVertexHandles = vue_prog_data->include_vue_handles;
+
+ gs.UserClipDistanceCullTestEnableBitmask =
+ vue_prog_data->cull_distance_mask;
+
+ const int urb_entry_write_offset = 1;
+ const uint32_t urb_entry_output_length =
+ DIV_ROUND_UP(vue_prog_data->vue_map.num_slots, 2) -
+ urb_entry_write_offset;
+
+ gs.VertexURBEntryOutputReadOffset = urb_entry_write_offset;
+ gs.VertexURBEntryOutputLength = MAX2(urb_entry_output_length, 1);
+ }
+}
+
+static void
+iris_set_fs_state(const struct gen_device_info *devinfo,
+ struct iris_compiled_shader *shader)
+{
+ struct brw_stage_prog_data *prog_data = shader->prog_data;
+ struct brw_wm_prog_data *wm_prog_data = (void *) shader->prog_data;
+
+ uint32_t *ps_state = (void *) shader->derived_data;
+ uint32_t *psx_state = ps_state + GENX(3DSTATE_PS_length);
+
+ iris_pack_command(GENX(3DSTATE_PS), ps_state, ps) {
+ ps.VectorMaskEnable = true;
+ //ps.SamplerCount = ...
+ ps.BindingTableEntryCount = prog_data->binding_table.size_bytes / 4;
+ ps.FloatingPointMode = prog_data->use_alt_mode;
+ ps.MaximumNumberofThreadsPerPSD = 64 - (GEN_GEN == 8 ? 2 : 1);
+
+ ps.PushConstantEnable = prog_data->nr_params > 0 ||
+ prog_data->ubo_ranges[0].length > 0;
+
+ /* From the documentation for this packet:
+ * "If the PS kernel does not need the Position XY Offsets to
+ * compute a Position Value, then this field should be programmed
+ * to POSOFFSET_NONE."
+ *
+ * "SW Recommendation: If the PS kernel needs the Position Offsets
+ * to compute a Position XY value, this field should match Position
+ * ZW Interpolation Mode to ensure a consistent position.xyzw
+ * computation."
+ *
+ * We only require XY sample offsets. So, this recommendation doesn't
+ * look useful at the moment. We might need this in future.
+ */
+ ps.PositionXYOffsetSelect =
+ wm_prog_data->uses_pos_offset ? POSOFFSET_SAMPLE : POSOFFSET_NONE;
+ ps._8PixelDispatchEnable = wm_prog_data->dispatch_8;
+ ps._16PixelDispatchEnable = wm_prog_data->dispatch_16;
+ ps._32PixelDispatchEnable = wm_prog_data->dispatch_32;
+
+ // XXX: Disable SIMD32 with 16x MSAA
+
+ ps.DispatchGRFStartRegisterForConstantSetupData0 =
+ brw_wm_prog_data_dispatch_grf_start_reg(wm_prog_data, ps, 0);
+ ps.DispatchGRFStartRegisterForConstantSetupData1 =
+ brw_wm_prog_data_dispatch_grf_start_reg(wm_prog_data, ps, 1);
+ ps.DispatchGRFStartRegisterForConstantSetupData2 =
+ brw_wm_prog_data_dispatch_grf_start_reg(wm_prog_data, ps, 2);
+
+ ps.KernelStartPointer0 =
+ shader->prog_offset + brw_wm_prog_data_prog_offset(wm_prog_data, ps, 0);
+ ps.KernelStartPointer1 =
+ shader->prog_offset + brw_wm_prog_data_prog_offset(wm_prog_data, ps, 1);
+ ps.KernelStartPointer2 =
+ shader->prog_offset + brw_wm_prog_data_prog_offset(wm_prog_data, ps, 2);
+ }
+
+ iris_pack_command(GENX(3DSTATE_PS_EXTRA), psx_state, psx) {
+ psx.PixelShaderValid = true;
+ psx.PixelShaderComputedDepthMode = wm_prog_data->computed_depth_mode;
+ psx.PixelShaderKillsPixel = wm_prog_data->uses_kill;
+ psx.AttributeEnable = wm_prog_data->num_varying_inputs != 0;
+ psx.PixelShaderUsesSourceDepth = wm_prog_data->uses_src_depth;
+ psx.PixelShaderUsesSourceW = wm_prog_data->uses_src_w;
+ psx.PixelShaderIsPerSample = wm_prog_data->persample_dispatch;
+
+ if (wm_prog_data->uses_sample_mask) {
+ /* TODO: conservative rasterization */
+ if (wm_prog_data->post_depth_coverage)
+ psx.InputCoverageMaskState = ICMS_DEPTH_COVERAGE;
+ else
+ psx.InputCoverageMaskState = ICMS_NORMAL;
+ }
+
+ psx.oMaskPresenttoRenderTarget = wm_prog_data->uses_omask;
+ psx.PixelShaderPullsBary = wm_prog_data->pulls_bary;
+ psx.PixelShaderComputesStencil = wm_prog_data->computed_stencil;
+
+ // XXX: UAV bit
+ }
+}
+
+static unsigned
+iris_derived_program_state_size(enum iris_program_cache_id cache_id)
+{
+ assert(cache_id <= IRIS_CACHE_CS);
+
+ static const unsigned dwords[] = {
+ [IRIS_CACHE_VS] = GENX(3DSTATE_VS_length),
+ [IRIS_CACHE_TCS] = GENX(3DSTATE_HS_length),
+ [IRIS_CACHE_TES] = GENX(3DSTATE_TE_length) + GENX(3DSTATE_DS_length),
+ [IRIS_CACHE_GS] = GENX(3DSTATE_GS_length),
+ [IRIS_CACHE_FS] =
+ GENX(3DSTATE_PS_length) + GENX(3DSTATE_PS_EXTRA_length),
+ [IRIS_CACHE_CS] = 0,
+ [IRIS_CACHE_BLORP_BLIT] = 0,
+ };
+
+ return sizeof(uint32_t) * dwords[cache_id];
+}
+
+static void
+iris_set_derived_program_state(const struct gen_device_info *devinfo,
+ enum iris_program_cache_id cache_id,
+ struct iris_compiled_shader *shader)
+{
+ switch (cache_id) {
+ case IRIS_CACHE_VS:
+ iris_set_vs_state(devinfo, shader);
+ break;
+ case IRIS_CACHE_TCS:
+ iris_set_tcs_state(devinfo, shader);
+ break;
+ case IRIS_CACHE_TES:
+ iris_set_tes_state(devinfo, shader);
+ break;
+ case IRIS_CACHE_GS:
+ iris_set_gs_state(devinfo, shader);
+ break;
+ case IRIS_CACHE_FS:
+ iris_set_fs_state(devinfo, shader);
+ break;
+ case IRIS_CACHE_CS:
+ break;
+ default:
+ break;
+ }
+}
+
+static void
iris_upload_render_state(struct iris_context *ice,
struct iris_batch *batch,
const struct pipe_draw_info *draw)
@@ -1693,269 +1944,9 @@ iris_upload_render_state(struct iris_context *ice,
#endif
}
-static void
-iris_bind_compute_state(struct pipe_context *ctx, void *state)
-{
-}
-
- //pkt.SamplerCount = \
- //DIV_ROUND_UP(CLAMP(stage_state->sampler_count, 0, 16), 4); \
- //pkt.PerThreadScratchSpace = prog_data->total_scratch == 0 ? 0 : \
- //ffs(stage_state->per_thread_scratch) - 11; \
-
-#define INIT_THREAD_DISPATCH_FIELDS(pkt, prefix) \
- pkt.KernelStartPointer = shader->prog_offset; \
- pkt.BindingTableEntryCount = prog_data->binding_table.size_bytes / 4; \
- pkt.FloatingPointMode = prog_data->use_alt_mode; \
- \
- pkt.DispatchGRFStartRegisterForURBData = \
- prog_data->dispatch_grf_start_reg; \
- pkt.prefix##URBEntryReadLength = vue_prog_data->urb_read_length; \
- pkt.prefix##URBEntryReadOffset = 0; \
- \
- pkt.StatisticsEnable = true; \
- pkt.Enable = true;
-
-static void
-iris_set_vs_state(const struct gen_device_info *devinfo,
- struct iris_compiled_shader *shader)
-{
- struct brw_stage_prog_data *prog_data = shader->prog_data;
- struct brw_vue_prog_data *vue_prog_data = (void *) prog_data;
-
- iris_pack_command(GENX(3DSTATE_VS), shader->derived_data, vs) {
- INIT_THREAD_DISPATCH_FIELDS(vs, Vertex);
- vs.MaximumNumberofThreads = devinfo->max_vs_threads - 1;
- vs.SIMD8DispatchEnable = true;
- vs.UserClipDistanceCullTestEnableBitmask =
- vue_prog_data->cull_distance_mask;
- }
-}
-
-static void
-iris_set_tcs_state(const struct gen_device_info *devinfo,
- struct iris_compiled_shader *shader)
-{
- struct brw_stage_prog_data *prog_data = shader->prog_data;
- struct brw_vue_prog_data *vue_prog_data = (void *) prog_data;
- struct brw_tcs_prog_data *tcs_prog_data = (void *) prog_data;
-
- iris_pack_command(GENX(3DSTATE_HS), shader->derived_data, hs) {
- INIT_THREAD_DISPATCH_FIELDS(hs, Vertex);
- hs.InstanceCount = tcs_prog_data->instances - 1;
- hs.MaximumNumberofThreads = devinfo->max_tcs_threads - 1;
- hs.IncludeVertexHandles = true;
- }
-}
static void
-iris_set_tes_state(const struct gen_device_info *devinfo,
- struct iris_compiled_shader *shader)
-{
- struct brw_stage_prog_data *prog_data = shader->prog_data;
- struct brw_vue_prog_data *vue_prog_data = (void *) prog_data;
- struct brw_tes_prog_data *tes_prog_data = (void *) prog_data;
-
- uint32_t *te_state = (void *) shader->derived_data;
- uint32_t *ds_state = te_state + GENX(3DSTATE_TE_length);
-
- iris_pack_command(GENX(3DSTATE_TE), te_state, te) {
- te.Partitioning = tes_prog_data->partitioning;
- te.OutputTopology = tes_prog_data->output_topology;
- te.TEDomain = tes_prog_data->domain;
- te.TEEnable = true;
- te.MaximumTessellationFactorOdd = 63.0;
- te.MaximumTessellationFactorNotOdd = 64.0;
- }
-
- iris_pack_command(GENX(3DSTATE_DS), ds_state, ds) {
- INIT_THREAD_DISPATCH_FIELDS(ds, Patch);
-
- ds.DispatchMode = DISPATCH_MODE_SIMD8_SINGLE_PATCH;
- ds.MaximumNumberofThreads = devinfo->max_tes_threads - 1;
- ds.ComputeWCoordinateEnable =
- tes_prog_data->domain == BRW_TESS_DOMAIN_TRI;
-
- ds.UserClipDistanceCullTestEnableBitmask =
- vue_prog_data->cull_distance_mask;
- }
-
-}
-
-static void
-iris_set_gs_state(const struct gen_device_info *devinfo,
- struct iris_compiled_shader *shader)
-{
- struct brw_stage_prog_data *prog_data = shader->prog_data;
- struct brw_vue_prog_data *vue_prog_data = (void *) prog_data;
- struct brw_gs_prog_data *gs_prog_data = (void *) prog_data;
-
- iris_pack_command(GENX(3DSTATE_GS), shader->derived_data, gs) {
- INIT_THREAD_DISPATCH_FIELDS(gs, Vertex);
-
- gs.OutputVertexSize = gs_prog_data->output_vertex_size_hwords * 2 - 1;
- gs.OutputTopology = gs_prog_data->output_topology;
- gs.ControlDataHeaderSize =
- gs_prog_data->control_data_header_size_hwords;
- gs.InstanceControl = gs_prog_data->invocations - 1;
- gs.DispatchMode = SIMD8;
- gs.IncludePrimitiveID = gs_prog_data->include_primitive_id;
- gs.ControlDataFormat = gs_prog_data->control_data_format;
- gs.ReorderMode = TRAILING;
- gs.ExpectedVertexCount = gs_prog_data->vertices_in;
- gs.MaximumNumberofThreads =
- GEN_GEN == 8 ? (devinfo->max_gs_threads / 2 - 1)
- : (devinfo->max_gs_threads - 1);
-
- if (gs_prog_data->static_vertex_count != -1) {
- gs.StaticOutput = true;
- gs.StaticOutputVertexCount = gs_prog_data->static_vertex_count;
- }
- gs.IncludeVertexHandles = vue_prog_data->include_vue_handles;
-
- gs.UserClipDistanceCullTestEnableBitmask =
- vue_prog_data->cull_distance_mask;
-
- const int urb_entry_write_offset = 1;
- const uint32_t urb_entry_output_length =
- DIV_ROUND_UP(vue_prog_data->vue_map.num_slots, 2) -
- urb_entry_write_offset;
-
- gs.VertexURBEntryOutputReadOffset = urb_entry_write_offset;
- gs.VertexURBEntryOutputLength = MAX2(urb_entry_output_length, 1);
- }
-}
-
-static void
-iris_set_fs_state(const struct gen_device_info *devinfo,
- struct iris_compiled_shader *shader)
-{
- struct brw_stage_prog_data *prog_data = shader->prog_data;
- struct brw_wm_prog_data *wm_prog_data = (void *) shader->prog_data;
-
- uint32_t *ps_state = (void *) shader->derived_data;
- uint32_t *psx_state = ps_state + GENX(3DSTATE_PS_length);
-
- iris_pack_command(GENX(3DSTATE_PS), ps_state, ps) {
- ps.VectorMaskEnable = true;
- //ps.SamplerCount = ...
- ps.BindingTableEntryCount = prog_data->binding_table.size_bytes / 4;
- ps.FloatingPointMode = prog_data->use_alt_mode;
- ps.MaximumNumberofThreadsPerPSD = 64 - (GEN_GEN == 8 ? 2 : 1);
-
- ps.PushConstantEnable = prog_data->nr_params > 0 ||
- prog_data->ubo_ranges[0].length > 0;
-
- /* From the documentation for this packet:
- * "If the PS kernel does not need the Position XY Offsets to
- * compute a Position Value, then this field should be programmed
- * to POSOFFSET_NONE."
- *
- * "SW Recommendation: If the PS kernel needs the Position Offsets
- * to compute a Position XY value, this field should match Position
- * ZW Interpolation Mode to ensure a consistent position.xyzw
- * computation."
- *
- * We only require XY sample offsets. So, this recommendation doesn't
- * look useful at the moment. We might need this in future.
- */
- ps.PositionXYOffsetSelect =
- wm_prog_data->uses_pos_offset ? POSOFFSET_SAMPLE : POSOFFSET_NONE;
- ps._8PixelDispatchEnable = wm_prog_data->dispatch_8;
- ps._16PixelDispatchEnable = wm_prog_data->dispatch_16;
- ps._32PixelDispatchEnable = wm_prog_data->dispatch_32;
-
- // XXX: Disable SIMD32 with 16x MSAA
-
- ps.DispatchGRFStartRegisterForConstantSetupData0 =
- brw_wm_prog_data_dispatch_grf_start_reg(wm_prog_data, ps, 0);
- ps.DispatchGRFStartRegisterForConstantSetupData1 =
- brw_wm_prog_data_dispatch_grf_start_reg(wm_prog_data, ps, 1);
- ps.DispatchGRFStartRegisterForConstantSetupData2 =
- brw_wm_prog_data_dispatch_grf_start_reg(wm_prog_data, ps, 2);
-
- ps.KernelStartPointer0 =
- shader->prog_offset + brw_wm_prog_data_prog_offset(wm_prog_data, ps, 0);
- ps.KernelStartPointer1 =
- shader->prog_offset + brw_wm_prog_data_prog_offset(wm_prog_data, ps, 1);
- ps.KernelStartPointer2 =
- shader->prog_offset + brw_wm_prog_data_prog_offset(wm_prog_data, ps, 2);
- }
-
- iris_pack_command(GENX(3DSTATE_PS_EXTRA), psx_state, psx) {
- psx.PixelShaderValid = true;
- psx.PixelShaderComputedDepthMode = wm_prog_data->computed_depth_mode;
- psx.PixelShaderKillsPixel = wm_prog_data->uses_kill;
- psx.AttributeEnable = wm_prog_data->num_varying_inputs != 0;
- psx.PixelShaderUsesSourceDepth = wm_prog_data->uses_src_depth;
- psx.PixelShaderUsesSourceW = wm_prog_data->uses_src_w;
- psx.PixelShaderIsPerSample = wm_prog_data->persample_dispatch;
-
- if (wm_prog_data->uses_sample_mask) {
- /* TODO: conservative rasterization */
- if (wm_prog_data->post_depth_coverage)
- psx.InputCoverageMaskState = ICMS_DEPTH_COVERAGE;
- else
- psx.InputCoverageMaskState = ICMS_NORMAL;
- }
-
- psx.oMaskPresenttoRenderTarget = wm_prog_data->uses_omask;
- psx.PixelShaderPullsBary = wm_prog_data->pulls_bary;
- psx.PixelShaderComputesStencil = wm_prog_data->computed_stencil;
-
- // XXX: UAV bit
- }
-}
-
-unsigned
-iris_derived_program_state_size(enum iris_program_cache_id cache_id)
-{
- assert(cache_id <= IRIS_CACHE_CS);
-
- static const unsigned dwords[] = {
- [IRIS_CACHE_VS] = GENX(3DSTATE_VS_length),
- [IRIS_CACHE_TCS] = GENX(3DSTATE_HS_length),
- [IRIS_CACHE_TES] = GENX(3DSTATE_TE_length) + GENX(3DSTATE_DS_length),
- [IRIS_CACHE_GS] = GENX(3DSTATE_GS_length),
- [IRIS_CACHE_FS] =
- GENX(3DSTATE_PS_length) + GENX(3DSTATE_PS_EXTRA_length),
- [IRIS_CACHE_CS] = 0,
- [IRIS_CACHE_BLORP_BLIT] = 0,
- };
-
- return sizeof(uint32_t) * dwords[cache_id];
-}
-
-void
-iris_set_derived_program_state(const struct gen_device_info *devinfo,
- enum iris_program_cache_id cache_id,
- struct iris_compiled_shader *shader)
-{
- switch (cache_id) {
- case IRIS_CACHE_VS:
- iris_set_vs_state(devinfo, shader);
- break;
- case IRIS_CACHE_TCS:
- iris_set_tcs_state(devinfo, shader);
- break;
- case IRIS_CACHE_TES:
- iris_set_tes_state(devinfo, shader);
- break;
- case IRIS_CACHE_GS:
- iris_set_gs_state(devinfo, shader);
- break;
- case IRIS_CACHE_FS:
- iris_set_fs_state(devinfo, shader);
- break;
- case IRIS_CACHE_CS:
- break;
- default:
- break;
- }
-}
-
-void
iris_destroy_state(struct iris_context *ice)
{
// XXX: unreference resources/surfaces.
@@ -1966,12 +1957,10 @@ iris_destroy_state(struct iris_context *ice)
}
void
-iris_init_state(struct iris_context *ice)
+genX(init_state)(struct iris_context *ice)
{
struct pipe_context *ctx = &ice->ctx;
- ice->state.dirty = ~0ull;
-
ctx->create_blend_state = iris_create_blend_state;
ctx->create_depth_stencil_alpha_state = iris_create_zsa_state;
ctx->create_rasterizer_state = iris_create_rasterizer_state;
@@ -2015,4 +2004,14 @@ iris_init_state(struct iris_context *ice)
ctx->create_stream_output_target = iris_create_stream_output_target;
ctx->stream_output_target_destroy = iris_stream_output_target_destroy;
ctx->set_stream_output_targets = iris_set_stream_output_targets;
+
+ ice->render_batch.emit_state_base_address = iris_emit_state_base_address;
+ ice->state.upload_render_state = iris_upload_render_state;
+ ice->state.derived_program_state_size = iris_derived_program_state_size;
+ ice->state.set_derived_program_state = iris_set_derived_program_state;
+ ice->state.destroy_state = iris_destroy_state;
+
+ ice->state.dirty = ~0ull;
+
+ iris_upload_initial_gpu_state(&ice->render_batch);
}