#include "genxml/gen_macros.h"
#include "genxml/genX_pack.h"
-/* We reserve GPR 15 for conditional rendering */
-#define GEN_MI_BUILDER_NUM_ALLOC_GPRS 15
+/* We reserve :
+ * - GPR 14 for secondary command buffer returns
+ * - GPR 15 for conditional rendering
+ */
+#define GEN_MI_BUILDER_NUM_ALLOC_GPRS 14
#define __gen_get_batch_dwords anv_batch_emit_dwords
#define __gen_address_offset anv_address_add
#include "common/gen_mi_builder.h"
* ensured that we have the table even if this command buffer doesn't
* initialize any images.
*/
- cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_AUX_TABLE_INVALIDATE_BIT;
+ if (cmd_buffer->device->info.has_aux_map)
+ cmd_buffer->state.pending_pipe_bits |= ANV_PIPE_AUX_TABLE_INVALIDATE_BIT;
/* We send an "Indirect State Pointers Disable" packet at
* EndCommandBuffer, so all push contant packets are ignored during a
}
anv_cmd_buffer_add_secondary(primary, secondary);
+
+ assert(secondary->perf_query_pool == NULL || primary->perf_query_pool == NULL ||
+ secondary->perf_query_pool == primary->perf_query_pool);
+ if (secondary->perf_query_pool)
+ primary->perf_query_pool = secondary->perf_query_pool;
}
/* The secondary isn't counted in our VF cache tracking so we need to
genX(cmd_buffer_config_l3)(struct anv_cmd_buffer *cmd_buffer,
const struct gen_l3_config *cfg)
{
- assert(cfg);
+ assert(cfg || GEN_GEN >= 12);
if (cfg == cmd_buffer->state.current_l3_config)
return;
if (bits & ANV_PIPE_END_OF_PIPE_SYNC_BIT) {
pipe.CommandStreamerStallEnable = true;
pipe.PostSyncOperation = WriteImmediateData;
- pipe.Address = (struct anv_address) {
- .bo = cmd_buffer->device->workaround_bo,
- .offset = 0
- };
+ pipe.Address = cmd_buffer->device->workaround_address;
}
/*
*/
anv_batch_emit(&cmd_buffer->batch, GENX(MI_LOAD_REGISTER_MEM), lrm) {
lrm.RegisterAddress = 0x243C; /* GEN7_3DPRIM_START_INSTANCE */
- lrm.MemoryAddress = (struct anv_address) {
- .bo = cmd_buffer->device->workaround_bo,
- .offset = 0
- };
+ lrm.MemoryAddress = cmd_buffer->device->workaround_address;
}
}
*/
if (GEN_GEN == 9 && pipe.VFCacheInvalidationEnable) {
pipe.PostSyncOperation = WriteImmediateData;
- pipe.Address =
- (struct anv_address) { cmd_buffer->device->workaround_bo, 0 };
+ pipe.Address = cmd_buffer->device->workaround_address;
}
}
cmd_buffer->state.push_constants_dirty &= ~flushed;
}
+static void
+cmd_buffer_emit_clip(struct anv_cmd_buffer *cmd_buffer)
+{
+ const uint32_t clip_states =
+#if GEN_GEN <= 7
+ ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE |
+ ANV_CMD_DIRTY_DYNAMIC_CULL_MODE |
+#endif
+ ANV_CMD_DIRTY_DYNAMIC_VIEWPORT |
+ ANV_CMD_DIRTY_PIPELINE;
+
+ if ((cmd_buffer->state.gfx.dirty & clip_states) == 0)
+ return;
+
+#if GEN_GEN <= 7
+ const struct anv_dynamic_state *d = &cmd_buffer->state.gfx.dynamic;
+#endif
+ struct GENX(3DSTATE_CLIP) clip = {
+ GENX(3DSTATE_CLIP_header),
+#if GEN_GEN <= 7
+ .FrontWinding = genX(vk_to_gen_front_face)[d->front_face],
+ .CullMode = genX(vk_to_gen_cullmode)[d->cull_mode],
+#endif
+ };
+ uint32_t dwords[GENX(3DSTATE_CLIP_length)];
+
+ struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
+ const struct brw_vue_prog_data *last =
+ anv_pipeline_get_last_vue_prog_data(pipeline);
+ if (last->vue_map.slots_valid & VARYING_BIT_VIEWPORT) {
+ clip.MaximumVPIndex =
+ cmd_buffer->state.gfx.dynamic.viewport.count > 0 ?
+ cmd_buffer->state.gfx.dynamic.viewport.count - 1 : 0;
+ }
+
+ GENX(3DSTATE_CLIP_pack)(NULL, dwords, &clip);
+ anv_batch_emit_merge(&cmd_buffer->batch, dwords,
+ pipeline->gen7.clip);
+}
+
void
genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer)
{
struct anv_buffer *buffer = cmd_buffer->state.vertex_bindings[vb].buffer;
uint32_t offset = cmd_buffer->state.vertex_bindings[vb].offset;
+ /* If dynamic, use stride/size from vertex binding, otherwise use
+ * stride/size that was setup in the pipeline object.
+ */
+ bool dynamic_stride = cmd_buffer->state.gfx.dynamic.dyn_vbo_stride;
+ bool dynamic_size = cmd_buffer->state.gfx.dynamic.dyn_vbo_size;
+
+ uint32_t stride = dynamic_stride ?
+ cmd_buffer->state.vertex_bindings[vb].stride : pipeline->vb[vb].stride;
+ uint32_t size = dynamic_size ?
+ cmd_buffer->state.vertex_bindings[vb].size : buffer->size;
+
struct GENX(VERTEX_BUFFER_STATE) state;
if (buffer) {
state = (struct GENX(VERTEX_BUFFER_STATE)) {
.BufferAccessType = pipeline->vb[vb].instanced ? INSTANCEDATA : VERTEXDATA,
.InstanceDataStepRate = pipeline->vb[vb].instance_divisor,
#endif
-
.AddressModifyEnable = true,
- .BufferPitch = pipeline->vb[vb].stride,
+ .BufferPitch = stride,
.BufferStartingAddress = anv_address_add(buffer->address, offset),
.NullVertexBuffer = offset >= buffer->size,
#if GEN_GEN >= 8
- .BufferSize = buffer->size - offset
+ .BufferSize = size - offset
#else
- .EndAddress = anv_address_add(buffer->address, buffer->size - 1),
+ .EndAddress = anv_address_add(buffer->address, size - 1),
#endif
};
} else {
cmd_buffer_alloc_push_constants(cmd_buffer);
}
+ if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE)
+ cmd_buffer->state.gfx.primitive_topology = pipeline->topology;
+
#if GEN_GEN <= 7
if (cmd_buffer->state.descriptors_dirty & VK_SHADER_STAGE_VERTEX_BIT ||
cmd_buffer->state.push_constants_dirty & VK_SHADER_STAGE_VERTEX_BIT) {
anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
pc.DepthStallEnable = true;
pc.PostSyncOperation = WriteImmediateData;
- pc.Address =
- (struct anv_address) { cmd_buffer->device->workaround_bo, 0 };
+ pc.Address = cmd_buffer->device->workaround_address;
}
}
#endif
if (dirty)
cmd_buffer_emit_descriptor_pointers(cmd_buffer, dirty);
+ cmd_buffer_emit_clip(cmd_buffer);
+
if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_VIEWPORT)
gen8_cmd_buffer_emit_viewport(cmd_buffer);
anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) {
prim.PredicateEnable = cmd_buffer->state.conditional_render_enabled;
prim.VertexAccessType = SEQUENTIAL;
- prim.PrimitiveTopologyType = pipeline->topology;
+ prim.PrimitiveTopologyType = cmd_buffer->state.gfx.primitive_topology;
prim.VertexCountPerInstance = vertexCount;
prim.StartVertexLocation = firstVertex;
prim.InstanceCount = instanceCount;
anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) {
prim.PredicateEnable = cmd_buffer->state.conditional_render_enabled;
prim.VertexAccessType = RANDOM;
- prim.PrimitiveTopologyType = pipeline->topology;
+ prim.PrimitiveTopologyType = cmd_buffer->state.gfx.primitive_topology;
prim.VertexCountPerInstance = indexCount;
prim.StartVertexLocation = firstIndex;
prim.InstanceCount = instanceCount;
anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) {
prim.IndirectParameterEnable = true;
prim.VertexAccessType = SEQUENTIAL;
- prim.PrimitiveTopologyType = pipeline->topology;
+ prim.PrimitiveTopologyType = cmd_buffer->state.gfx.primitive_topology;
}
update_dirty_vbs_for_gen8_vb_flush(cmd_buffer, SEQUENTIAL);
prim.IndirectParameterEnable = true;
prim.PredicateEnable = cmd_buffer->state.conditional_render_enabled;
prim.VertexAccessType = SEQUENTIAL;
- prim.PrimitiveTopologyType = pipeline->topology;
+ prim.PrimitiveTopologyType = cmd_buffer->state.gfx.primitive_topology;
}
update_dirty_vbs_for_gen8_vb_flush(cmd_buffer, SEQUENTIAL);
prim.IndirectParameterEnable = true;
prim.PredicateEnable = cmd_buffer->state.conditional_render_enabled;
prim.VertexAccessType = RANDOM;
- prim.PrimitiveTopologyType = pipeline->topology;
+ prim.PrimitiveTopologyType = cmd_buffer->state.gfx.primitive_topology;
}
update_dirty_vbs_for_gen8_vb_flush(cmd_buffer, RANDOM);
prim.IndirectParameterEnable = true;
prim.PredicateEnable = true;
prim.VertexAccessType = SEQUENTIAL;
- prim.PrimitiveTopologyType = pipeline->topology;
+ prim.PrimitiveTopologyType = cmd_buffer->state.gfx.primitive_topology;
}
update_dirty_vbs_for_gen8_vb_flush(cmd_buffer, SEQUENTIAL);
prim.IndirectParameterEnable = true;
prim.PredicateEnable = true;
prim.VertexAccessType = RANDOM;
- prim.PrimitiveTopologyType = pipeline->topology;
+ prim.PrimitiveTopologyType = cmd_buffer->state.gfx.primitive_topology;
}
update_dirty_vbs_for_gen8_vb_flush(cmd_buffer, RANDOM);
genX(CmdDispatchBase)(commandBuffer, 0, 0, 0, x, y, z);
}
+static inline void
+emit_gpgpu_walker(struct anv_cmd_buffer *cmd_buffer,
+ const struct anv_compute_pipeline *pipeline, bool indirect,
+ const struct brw_cs_prog_data *prog_data,
+ uint32_t groupCountX, uint32_t groupCountY,
+ uint32_t groupCountZ)
+{
+ bool predicate = (GEN_GEN <= 7 && indirect) ||
+ cmd_buffer->state.conditional_render_enabled;
+ const struct anv_cs_parameters cs_params = anv_cs_parameters(pipeline);
+
+ anv_batch_emit(&cmd_buffer->batch, GENX(GPGPU_WALKER), ggw) {
+ ggw.IndirectParameterEnable = indirect;
+ ggw.PredicateEnable = predicate;
+ ggw.SIMDSize = cs_params.simd_size / 16;
+ ggw.ThreadDepthCounterMaximum = 0;
+ ggw.ThreadHeightCounterMaximum = 0;
+ ggw.ThreadWidthCounterMaximum = cs_params.threads - 1;
+ ggw.ThreadGroupIDXDimension = groupCountX;
+ ggw.ThreadGroupIDYDimension = groupCountY;
+ ggw.ThreadGroupIDZDimension = groupCountZ;
+ ggw.RightExecutionMask = pipeline->cs_right_mask;
+ ggw.BottomExecutionMask = 0xffffffff;
+ }
+
+ anv_batch_emit(&cmd_buffer->batch, GENX(MEDIA_STATE_FLUSH), msf);
+}
+
void genX(CmdDispatchBase)(
VkCommandBuffer commandBuffer,
uint32_t baseGroupX,
if (cmd_buffer->state.conditional_render_enabled)
genX(cmd_emit_conditional_render_predicate)(cmd_buffer);
- anv_batch_emit(&cmd_buffer->batch, GENX(GPGPU_WALKER), ggw) {
- ggw.PredicateEnable = cmd_buffer->state.conditional_render_enabled;
- ggw.SIMDSize = prog_data->simd_size / 16;
- ggw.ThreadDepthCounterMaximum = 0;
- ggw.ThreadHeightCounterMaximum = 0;
- ggw.ThreadWidthCounterMaximum = anv_cs_threads(pipeline) - 1;
- ggw.ThreadGroupIDXDimension = groupCountX;
- ggw.ThreadGroupIDYDimension = groupCountY;
- ggw.ThreadGroupIDZDimension = groupCountZ;
- ggw.RightExecutionMask = pipeline->cs_right_mask;
- ggw.BottomExecutionMask = 0xffffffff;
- }
-
- anv_batch_emit(&cmd_buffer->batch, GENX(MEDIA_STATE_FLUSH), msf);
+ emit_gpgpu_walker(cmd_buffer, pipeline, false, prog_data, groupCountX,
+ groupCountY, groupCountZ);
}
#define GPGPU_DISPATCHDIMX 0x2500
struct anv_compute_pipeline *pipeline = cmd_buffer->state.compute.pipeline;
const struct brw_cs_prog_data *prog_data = get_cs_prog_data(pipeline);
struct anv_address addr = anv_address_add(buffer->address, offset);
- struct anv_batch *batch = &cmd_buffer->batch;
+ UNUSED struct anv_batch *batch = &cmd_buffer->batch;
anv_cmd_buffer_push_base_group_id(cmd_buffer, 0, 0, 0);
genX(cmd_emit_conditional_render_predicate)(cmd_buffer);
#endif
- anv_batch_emit(batch, GENX(GPGPU_WALKER), ggw) {
- ggw.IndirectParameterEnable = true;
- ggw.PredicateEnable = GEN_GEN <= 7 ||
- cmd_buffer->state.conditional_render_enabled;
- ggw.SIMDSize = prog_data->simd_size / 16;
- ggw.ThreadDepthCounterMaximum = 0;
- ggw.ThreadHeightCounterMaximum = 0;
- ggw.ThreadWidthCounterMaximum = anv_cs_threads(pipeline) - 1;
- ggw.RightExecutionMask = pipeline->cs_right_mask;
- ggw.BottomExecutionMask = 0xffffffff;
- }
-
- anv_batch_emit(batch, GENX(MEDIA_STATE_FLUSH), msf);
+ emit_gpgpu_walker(cmd_buffer, pipeline, true, prog_data, 0, 0, 0);
}
static void
*/
anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
pc.PostSyncOperation = WriteImmediateData;
- pc.Address =
- (struct anv_address) { cmd_buffer->device->workaround_bo, 0 };
+ pc.Address = cmd_buffer->device->workaround_address;
}
}
cmd_buffer->state.hiz_enabled = isl_aux_usage_has_hiz(info.hiz_usage);