#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)
- continue;
-
- 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),
- });
-
- flushed |= mesa_to_vk_shader_stage(stage);
- }
-
- cmd_buffer->state.push_constants_dirty &= ~flushed;
-
- return flushed;
-}
-
-GENX_FUNC(GEN7, GEN7) void
-genX(cmd_buffer_emit_descriptor_pointers)(struct anv_cmd_buffer *cmd_buffer,
- uint32_t stages)
+#if GEN_GEN == 7 && !GEN_IS_HASWELL
+void
+gen7_cmd_buffer_emit_descriptor_pointers(struct anv_cmd_buffer *cmd_buffer,
+ uint32_t stages)
{
static const uint32_t sampler_state_opcodes[] = {
[MESA_SHADER_VERTEX] = 43,
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;
+ }
}
}
-GENX_FUNC(GEN7, GEN7) uint32_t
-genX(cmd_buffer_flush_descriptor_sets)(struct anv_cmd_buffer *cmd_buffer)
+uint32_t
+gen7_cmd_buffer_flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
{
VkShaderStageFlags dirty = cmd_buffer->state.descriptors_dirty &
cmd_buffer->state.pipeline->active_stages;
return dirty;
}
+#endif /* GEN_GEN == 7 && !GEN_IS_HASWELL */
static inline int64_t
clamp_int64(int64_t x, int64_t min, int64_t max)
}
#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;
}
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);
- 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(cmd_buffer_config_l3)(cmd_buffer, pipeline);
+
+ 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);
- }
-
- 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 uint32_t depth_format = image ?
+ 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
if (cmd_buffer->state.dirty & (ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS |
ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE)) {
+ struct anv_dynamic_state *d = &cmd_buffer->state.dynamic;
struct anv_state cc_state =
anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
GENX(COLOR_CALC_STATE_length) * 4,
.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 =
- cmd_buffer->state.dynamic.stencil_reference.front,
- .BackFaceStencilReferenceValue =
- cmd_buffer->state.dynamic.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 |
ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK |
ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK)) {
uint32_t depth_stencil_dw[GENX(DEPTH_STENCIL_STATE_length)];
-
- const struct anv_image_view *iview =
- anv_cmd_buffer_get_depth_stencil_view(cmd_buffer);
+ struct anv_dynamic_state *d = &cmd_buffer->state.dynamic;
struct GENX(DEPTH_STENCIL_STATE) depth_stencil = {
- .StencilBufferWriteEnable = iview && (iview->aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT),
-
- .StencilTestMask =
- cmd_buffer->state.dynamic.stencil_compare_mask.front & 0xff,
- .StencilWriteMask =
- cmd_buffer->state.dynamic.stencil_write_mask.front & 0xff,
+ .StencilTestMask = d->stencil_compare_mask.front & 0xff,
+ .StencilWriteMask = d->stencil_write_mask.front & 0xff,
- .BackfaceStencilTestMask =
- cmd_buffer->state.dynamic.stencil_compare_mask.back & 0xff,
- .BackfaceStencilWriteMask =
- cmd_buffer->state.dynamic.stencil_write_mask.back & 0xff,
+ .BackfaceStencilTestMask = d->stencil_compare_mask.back & 0xff,
+ .BackfaceStencilWriteMask = d->stencil_write_mask.back & 0xff,
};
GENX(DEPTH_STENCIL_STATE_pack)(NULL, depth_stencil_dw, &depth_stencil);
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);
}