#include "genxml/gen_macros.h"
#include "genxml/genX_pack.h"
-static uint32_t
-cmd_buffer_flush_push_constants(struct anv_cmd_buffer *cmd_buffer)
-{
- static const uint32_t push_constant_opcodes[] = {
- [MESA_SHADER_VERTEX] = 21,
- [MESA_SHADER_TESS_CTRL] = 25, /* HS */
- [MESA_SHADER_TESS_EVAL] = 26, /* DS */
- [MESA_SHADER_GEOMETRY] = 22,
- [MESA_SHADER_FRAGMENT] = 23,
- [MESA_SHADER_COMPUTE] = 0,
- };
-
- VkShaderStageFlags flushed = 0;
-
- anv_foreach_stage(stage, cmd_buffer->state.push_constants_dirty) {
- if (stage == MESA_SHADER_COMPUTE)
- continue;
-
- struct anv_state state = anv_cmd_buffer_push_constants(cmd_buffer, stage);
-
- if (state.offset == 0) {
- anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_CONSTANT_VS),
- ._3DCommandSubOpcode = push_constant_opcodes[stage]);
- } else {
- anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_CONSTANT_VS),
- ._3DCommandSubOpcode = push_constant_opcodes[stage],
- .ConstantBody = {
- .PointerToConstantBuffer0 = { .offset = state.offset },
- .ConstantBuffer0ReadLength = DIV_ROUND_UP(state.alloc_size, 32),
- });
- }
- }
-
- cmd_buffer->state.push_constants_dirty &= ~VK_SHADER_STAGE_ALL_GRAPHICS;
-
- return flushed;
-}
-
#if GEN_GEN == 7 && !GEN_IS_HASWELL
void
gen7_cmd_buffer_emit_descriptor_pointers(struct anv_cmd_buffer *cmd_buffer,
anv_foreach_stage(s, stages) {
if (cmd_buffer->state.samplers[s].alloc_size > 0) {
anv_batch_emit(&cmd_buffer->batch,
- GENX(3DSTATE_SAMPLER_STATE_POINTERS_VS),
- ._3DCommandSubOpcode = sampler_state_opcodes[s],
- .PointertoVSSamplerState = cmd_buffer->state.samplers[s].offset);
+ GENX(3DSTATE_SAMPLER_STATE_POINTERS_VS), ssp) {
+ ssp._3DCommandSubOpcode = sampler_state_opcodes[s];
+ ssp.PointertoVSSamplerState = cmd_buffer->state.samplers[s].offset;
+ }
}
/* Always emit binding table pointers if we're asked to, since on SKL
* this is what flushes push constants. */
anv_batch_emit(&cmd_buffer->batch,
- GENX(3DSTATE_BINDING_TABLE_POINTERS_VS),
- ._3DCommandSubOpcode = binding_table_opcodes[s],
- .PointertoVSBindingTable = cmd_buffer->state.binding_tables[s].offset);
+ GENX(3DSTATE_BINDING_TABLE_POINTERS_VS), btp) {
+ btp._3DCommandSubOpcode = binding_table_opcodes[s];
+ btp.PointertoVSBindingTable = cmd_buffer->state.binding_tables[s].offset;
+ }
}
}
}
#if GEN_GEN == 7 && !GEN_IS_HASWELL
-static void
-emit_scissor_state(struct anv_cmd_buffer *cmd_buffer,
- uint32_t count, const VkRect2D *scissors)
+void
+gen7_cmd_buffer_emit_scissor(struct anv_cmd_buffer *cmd_buffer)
{
+ uint32_t count = cmd_buffer->state.dynamic.scissor.count;
+ const VkRect2D *scissors = cmd_buffer->state.dynamic.scissor.scissors;
struct anv_state scissor_state =
anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, count * 8, 32);
}
}
- anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_SCISSOR_STATE_POINTERS,
- .ScissorRectPointer = scissor_state.offset);
+ anv_batch_emit(&cmd_buffer->batch,
+ GEN7_3DSTATE_SCISSOR_STATE_POINTERS, ssp) {
+ ssp.ScissorRectPointer = scissor_state.offset;
+ }
if (!cmd_buffer->device->info.has_llc)
anv_state_clflush(scissor_state);
}
-
-void
-gen7_cmd_buffer_emit_scissor(struct anv_cmd_buffer *cmd_buffer)
-{
- if (cmd_buffer->state.dynamic.scissor.count > 0) {
- emit_scissor_state(cmd_buffer, cmd_buffer->state.dynamic.scissor.count,
- cmd_buffer->state.dynamic.scissor.scissors);
- } else {
- /* Emit a default scissor based on the currently bound framebuffer */
- emit_scissor_state(cmd_buffer, 1,
- &(VkRect2D) {
- .offset = { .x = 0, .y = 0, },
- .extent = {
- .width = cmd_buffer->state.framebuffer->width,
- .height = cmd_buffer->state.framebuffer->height,
- },
- });
- }
-}
#endif
static const uint32_t vk_to_gen_index_type[] = {
struct anv_state push_state = anv_cmd_buffer_cs_push_constants(cmd_buffer);
- const struct brw_cs_prog_data *cs_prog_data = &pipeline->cs_prog_data;
+ const struct brw_cs_prog_data *cs_prog_data = get_cs_prog_data(pipeline);
const struct brw_stage_prog_data *prog_data = &cs_prog_data->base;
unsigned local_id_dwords = cs_prog_data->local_invocation_id_regs * 8;
unsigned push_constant_regs = reg_aligned_constant_size / 32;
if (push_state.alloc_size) {
- anv_batch_emit(&cmd_buffer->batch, GENX(MEDIA_CURBE_LOAD),
- .CURBETotalDataLength = push_state.alloc_size,
- .CURBEDataStartAddress = push_state.offset);
+ anv_batch_emit(&cmd_buffer->batch, GENX(MEDIA_CURBE_LOAD), curbe) {
+ curbe.CURBETotalDataLength = push_state.alloc_size;
+ curbe.CURBEDataStartAddress = push_state.offset;
+ }
}
assert(prog_data->total_shared <= 64 * 1024);
pipeline->cs_thread_width_max);
const uint32_t size = GENX(INTERFACE_DESCRIPTOR_DATA_length) * sizeof(uint32_t);
- anv_batch_emit(&cmd_buffer->batch, GENX(MEDIA_INTERFACE_DESCRIPTOR_LOAD),
- .InterfaceDescriptorTotalLength = size,
- .InterfaceDescriptorDataStartAddress = state.offset);
+ anv_batch_emit(&cmd_buffer->batch,
+ GENX(MEDIA_INTERFACE_DESCRIPTOR_LOAD), idl) {
+ idl.InterfaceDescriptorTotalLength = size;
+ idl.InterfaceDescriptorDataStartAddress = state.offset;
+ }
return VK_SUCCESS;
}
-static void
-emit_lri(struct anv_batch *batch, uint32_t reg, uint32_t imm)
-{
- anv_batch_emit(batch, GENX(MI_LOAD_REGISTER_IMM),
- .RegisterOffset = reg,
- .DataDWord = imm);
-}
-
-#define GEN7_L3SQCREG1 0xb010
-#define GEN7_L3CNTLREG2 0xb020
-#define GEN7_L3CNTLREG3 0xb024
-
-static void
-config_l3(struct anv_cmd_buffer *cmd_buffer, bool enable_slm)
-{
- /* References for GL state:
- *
- * - commits e307cfa..228d5a3
- * - src/mesa/drivers/dri/i965/gen7_l3_state.c
- */
-
- uint32_t l3c2_val = enable_slm ?
- /* All = 0 ways; URB = 16 ways; DC and RO = 16; SLM = 1 */
- /*0x02040021*/0x010000a1 :
- /* All = 0 ways; URB = 32 ways; DC = 0; RO = 32; SLM = 0 */
- /*0x04080040*/0x02000030;
- bool changed = cmd_buffer->state.current_l3_config != l3c2_val;
-
- if (changed) {
- /* According to the hardware docs, the L3 partitioning can only be changed
- * while the pipeline is completely drained and the caches are flushed,
- * which involves a first PIPE_CONTROL flush which stalls the pipeline and
- * initiates invalidation of the relevant caches...
- */
- anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL),
- .TextureCacheInvalidationEnable = true,
- .ConstantCacheInvalidationEnable = true,
- .InstructionCacheInvalidateEnable = true,
- .DCFlushEnable = true,
- .PostSyncOperation = NoWrite,
- .CommandStreamerStallEnable = true);
-
- /* ...followed by a second stalling flush which guarantees that
- * invalidation is complete when the L3 configuration registers are
- * modified.
- */
- anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL),
- .DCFlushEnable = true,
- .PostSyncOperation = NoWrite,
- .CommandStreamerStallEnable = true);
-
- anv_finishme("write GEN7_L3SQCREG1");
- emit_lri(&cmd_buffer->batch, GEN7_L3CNTLREG2, l3c2_val);
- emit_lri(&cmd_buffer->batch, GEN7_L3CNTLREG3,
- enable_slm ? 0x00040810 : 0x00040410);
- cmd_buffer->state.current_l3_config = l3c2_val;
- }
-}
-
void
genX(cmd_buffer_flush_compute_state)(struct anv_cmd_buffer *cmd_buffer)
{
struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
- VkResult result;
+ MAYBE_UNUSED VkResult result;
assert(pipeline->active_stages == VK_SHADER_STAGE_COMPUTE_BIT);
- bool needs_slm = pipeline->cs_prog_data.base.total_shared > 0;
- config_l3(cmd_buffer, needs_slm);
+ genX(cmd_buffer_config_l3)(cmd_buffer, pipeline);
- if (cmd_buffer->state.current_pipeline != GPGPU) {
- anv_batch_emit(&cmd_buffer->batch, GENX(PIPELINE_SELECT),
- .PipelineSelection = GPGPU);
- cmd_buffer->state.current_pipeline = GPGPU;
- }
+ genX(flush_pipeline_select_gpgpu)(cmd_buffer);
if (cmd_buffer->state.compute_dirty & ANV_CMD_DIRTY_PIPELINE)
anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
}
void
-genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer)
+genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
{
struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
- uint32_t *p;
-
- uint32_t vb_emit = cmd_buffer->state.vb_dirty & pipeline->vb_used;
-
- assert((pipeline->active_stages & VK_SHADER_STAGE_COMPUTE_BIT) == 0);
-
- genX(flush_pipeline_select_3d)(cmd_buffer);
-
- if (vb_emit) {
- const uint32_t num_buffers = __builtin_popcount(vb_emit);
- const uint32_t num_dwords = 1 + num_buffers * 4;
-
- p = anv_batch_emitn(&cmd_buffer->batch, num_dwords,
- GENX(3DSTATE_VERTEX_BUFFERS));
- uint32_t vb, i = 0;
- for_each_bit(vb, vb_emit) {
- struct anv_buffer *buffer = cmd_buffer->state.vertex_bindings[vb].buffer;
- uint32_t offset = cmd_buffer->state.vertex_bindings[vb].offset;
-
- struct GENX(VERTEX_BUFFER_STATE) state = {
- .VertexBufferIndex = vb,
- .BufferAccessType = pipeline->instancing_enable[vb] ? INSTANCEDATA : VERTEXDATA,
- .VertexBufferMemoryObjectControlState = GENX(MOCS),
- .AddressModifyEnable = true,
- .BufferPitch = pipeline->binding_stride[vb],
- .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
- .EndAddress = { buffer->bo, buffer->offset + buffer->size - 1},
- .InstanceDataStepRate = 1
- };
-
- GENX(VERTEX_BUFFER_STATE_pack)(&cmd_buffer->batch, &p[1 + i * 4], &state);
- i++;
- }
- }
-
- if (cmd_buffer->state.dirty & ANV_CMD_DIRTY_PIPELINE) {
- /* If somebody compiled a pipeline after starting a command buffer the
- * scratch bo may have grown since we started this cmd buffer (and
- * emitted STATE_BASE_ADDRESS). If we're binding that pipeline now,
- * reemit STATE_BASE_ADDRESS so that we use the bigger scratch bo. */
- if (cmd_buffer->state.scratch_size < pipeline->total_scratch)
- gen7_cmd_buffer_emit_state_base_address(cmd_buffer);
-
- anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
-
- /* From the BDW PRM for 3DSTATE_PUSH_CONSTANT_ALLOC_VS:
- *
- * "The 3DSTATE_CONSTANT_VS must be reprogrammed prior to
- * the next 3DPRIMITIVE command after programming the
- * 3DSTATE_PUSH_CONSTANT_ALLOC_VS"
- *
- * Since 3DSTATE_PUSH_CONSTANT_ALLOC_VS is programmed as part of
- * pipeline setup, we need to dirty push constants.
- */
- cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_ALL_GRAPHICS;
- }
-
- if (cmd_buffer->state.descriptors_dirty & VK_SHADER_STAGE_VERTEX_BIT ||
- cmd_buffer->state.push_constants_dirty & VK_SHADER_STAGE_VERTEX_BIT) {
- /* From the IVB PRM Vol. 2, Part 1, Section 3.2.1:
- *
- * "A PIPE_CONTROL with Post-Sync Operation set to 1h and a depth
- * stall needs to be sent just prior to any 3DSTATE_VS,
- * 3DSTATE_URB_VS, 3DSTATE_CONSTANT_VS,
- * 3DSTATE_BINDING_TABLE_POINTER_VS,
- * 3DSTATE_SAMPLER_STATE_POINTER_VS command. Only one
- * PIPE_CONTROL needs to be sent before any combination of VS
- * associated 3DSTATE."
- */
- anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL),
- .DepthStallEnable = true,
- .PostSyncOperation = WriteImmediateData,
- .Address = { &cmd_buffer->device->workaround_bo, 0 });
- }
-
- uint32_t dirty = 0;
- if (cmd_buffer->state.descriptors_dirty) {
- dirty = gen7_cmd_buffer_flush_descriptor_sets(cmd_buffer);
- gen7_cmd_buffer_emit_descriptor_pointers(cmd_buffer, dirty);
- }
-
- if (cmd_buffer->state.push_constants_dirty)
- cmd_buffer_flush_push_constants(cmd_buffer);
-
- /* We use the gen8 state here because it only contains the additional
- * min/max fields and, since they occur at the end of the packet and
- * don't change the stride, they work on gen7 too.
- */
- if (cmd_buffer->state.dirty & ANV_CMD_DIRTY_DYNAMIC_VIEWPORT)
- gen8_cmd_buffer_emit_viewport(cmd_buffer);
-
- if (cmd_buffer->state.dirty & ANV_CMD_DIRTY_DYNAMIC_SCISSOR)
- gen7_cmd_buffer_emit_scissor(cmd_buffer);
if (cmd_buffer->state.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_RENDER_TARGETS |
ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH |
ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS)) {
- bool enable_bias = cmd_buffer->state.dynamic.depth_bias.bias != 0.0f ||
- cmd_buffer->state.dynamic.depth_bias.slope != 0.0f;
-
const struct anv_image_view *iview =
anv_cmd_buffer_get_depth_stencil_view(cmd_buffer);
const struct anv_image *image = iview ? iview->image : NULL;
- const struct anv_format *anv_format =
- iview ? anv_format_for_vk_format(iview->vk_format) : NULL;
- const bool has_depth = iview && anv_format->has_depth;
+ const bool has_depth =
+ image && (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT);
const uint32_t depth_format = has_depth ?
isl_surf_get_depth_format(&cmd_buffer->device->isl_dev,
&image->depth_surface.isl) : D16_UNORM;
GENX(3DSTATE_SF_header),
.DepthBufferSurfaceFormat = depth_format,
.LineWidth = cmd_buffer->state.dynamic.line_width,
- .GlobalDepthOffsetEnableSolid = enable_bias,
- .GlobalDepthOffsetEnableWireframe = enable_bias,
- .GlobalDepthOffsetEnablePoint = enable_bias,
.GlobalDepthOffsetConstant = cmd_buffer->state.dynamic.depth_bias.bias,
.GlobalDepthOffsetScale = cmd_buffer->state.dynamic.depth_bias.slope,
.GlobalDepthOffsetClamp = cmd_buffer->state.dynamic.depth_bias.clamp
.BlendConstantColorGreen = cmd_buffer->state.dynamic.blend_constants[1],
.BlendConstantColorBlue = cmd_buffer->state.dynamic.blend_constants[2],
.BlendConstantColorAlpha = cmd_buffer->state.dynamic.blend_constants[3],
- .StencilReferenceValue = d->stencil_reference.front,
- .BackFaceStencilReferenceValue = d->stencil_reference.back,
+ .StencilReferenceValue = d->stencil_reference.front & 0xff,
+ .BackFaceStencilReferenceValue = d->stencil_reference.back & 0xff,
};
GENX(COLOR_CALC_STATE_pack)(NULL, cc_state.map, &cc);
if (!cmd_buffer->device->info.has_llc)
anv_state_clflush(cc_state);
- anv_batch_emit(&cmd_buffer->batch,
- GENX(3DSTATE_CC_STATE_POINTERS),
- .ColorCalcStatePointer = cc_state.offset);
+ anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_CC_STATE_POINTERS), ccp) {
+ ccp.ColorCalcStatePointer = cc_state.offset;
+ }
}
if (cmd_buffer->state.dirty & (ANV_CMD_DIRTY_PIPELINE |
struct anv_dynamic_state *d = &cmd_buffer->state.dynamic;
struct GENX(DEPTH_STENCIL_STATE) depth_stencil = {
- .StencilBufferWriteEnable = d->stencil_write_mask.front != 0 ||
- d->stencil_write_mask.back != 0,
-
.StencilTestMask = d->stencil_compare_mask.front & 0xff,
.StencilWriteMask = d->stencil_write_mask.front & 0xff,
GENX(DEPTH_STENCIL_STATE_length), 64);
anv_batch_emit(&cmd_buffer->batch,
- GENX(3DSTATE_DEPTH_STENCIL_STATE_POINTERS),
- .PointertoDEPTH_STENCIL_STATE = ds_state.offset);
+ GENX(3DSTATE_DEPTH_STENCIL_STATE_POINTERS), dsp) {
+ dsp.PointertoDEPTH_STENCIL_STATE = ds_state.offset;
+ }
}
if (cmd_buffer->state.gen7.index_buffer &&
uint32_t offset = cmd_buffer->state.gen7.index_offset;
#if GEN_IS_HASWELL
- anv_batch_emit(&cmd_buffer->batch, GEN75_3DSTATE_VF,
- .IndexedDrawCutIndexEnable = pipeline->primitive_restart,
- .CutIndex = cmd_buffer->state.restart_index);
+ anv_batch_emit(&cmd_buffer->batch, GEN75_3DSTATE_VF, vf) {
+ vf.IndexedDrawCutIndexEnable = pipeline->primitive_restart;
+ vf.CutIndex = cmd_buffer->state.restart_index;
+ }
#endif
- anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_INDEX_BUFFER),
+ anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_INDEX_BUFFER), ib) {
#if !GEN_IS_HASWELL
- .CutIndexEnable = pipeline->primitive_restart,
+ ib.CutIndexEnable = pipeline->primitive_restart;
#endif
- .IndexFormat = cmd_buffer->state.gen7.index_type,
- .MemoryObjectControlState = GENX(MOCS),
- .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
- .BufferEndingAddress = { buffer->bo, buffer->offset + buffer->size });
+ ib.IndexFormat = cmd_buffer->state.gen7.index_type;
+ ib.MemoryObjectControlState = GENX(MOCS);
+
+ ib.BufferStartingAddress =
+ (struct anv_address) { buffer->bo, buffer->offset + offset };
+ ib.BufferEndingAddress =
+ (struct anv_address) { buffer->bo, buffer->offset + buffer->size };
+ }
}
- cmd_buffer->state.vb_dirty &= ~vb_emit;
cmd_buffer->state.dirty = 0;
}
const VkImageMemoryBarrier* pImageMemoryBarriers)
{
stub();
+
+ genX(CmdPipelineBarrier)(commandBuffer, srcStageMask, destStageMask,
+ false, /* byRegion */
+ memoryBarrierCount, pMemoryBarriers,
+ bufferMemoryBarrierCount, pBufferMemoryBarriers,
+ imageMemoryBarrierCount, pImageMemoryBarriers);
}