*/
stages |= VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_VERTEX_BIT;
- if (stages == cmd_buffer->state.push_constant_stages)
+ if (stages == cmd_buffer->state.gfx.push_constant_stages)
return;
#if GEN_GEN >= 8
alloc.ConstantBufferSize = push_constant_kb - kb_used;
}
- cmd_buffer->state.push_constant_stages = stages;
+ cmd_buffer->state.gfx.push_constant_stages = stages;
/* From the BDW PRM for 3DSTATE_PUSH_CONSTANT_ALLOC_VS:
*
*/
const bool need_client_mem_relocs =
!cmd_buffer->device->physical->use_softpin;
+ struct anv_push_constants *push = &pipe_state->push_constants;
for (uint32_t s = 0; s < map->surface_count; s++) {
struct anv_pipeline_binding *binding = &map->surface_to_descriptor[s];
anv_cmd_buffer_alloc_surface_state(cmd_buffer);
struct anv_address constant_data = {
- .bo = cmd_buffer->device->dynamic_state_pool.block_pool.bo,
- .offset = shader->constant_data.offset,
+ .bo = cmd_buffer->device->instruction_state_pool.block_pool.bo,
+ .offset = shader->kernel.offset +
+ shader->prog_data->const_data_offset,
};
- unsigned constant_data_size = shader->constant_data_size;
+ unsigned constant_data_size = shader->prog_data->const_data_size;
const enum isl_format format =
anv_isl_format_for_descriptor_type(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
if (desc->buffer) {
/* Compute the offset within the buffer */
- struct anv_push_constants *push =
- &cmd_buffer->state.push_constants[shader->stage];
-
uint32_t dynamic_offset =
push->dynamic_offsets[binding->dynamic_offset_index];
uint64_t offset = desc->offset + dynamic_offset;
gl_shader_stage stage,
const struct anv_push_range *range)
{
- const struct anv_cmd_graphics_state *gfx_state = &cmd_buffer->state.gfx;
+ struct anv_cmd_graphics_state *gfx_state = &cmd_buffer->state.gfx;
switch (range->set) {
case ANV_DESCRIPTOR_SET_DESCRIPTORS: {
/* This is a descriptor set buffer so the set index is
}
case ANV_DESCRIPTOR_SET_PUSH_CONSTANTS: {
- struct anv_state state =
- anv_cmd_buffer_push_constants(cmd_buffer, stage);
+ if (gfx_state->base.push_constants_state.alloc_size == 0) {
+ gfx_state->base.push_constants_state =
+ anv_cmd_buffer_gfx_push_constants(cmd_buffer);
+ }
return (struct anv_address) {
.bo = cmd_buffer->device->dynamic_state_pool.block_pool.bo,
- .offset = state.offset,
+ .offset = gfx_state->base.push_constants_state.offset,
};
}
} else {
assert(desc->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC);
if (desc->buffer) {
- struct anv_push_constants *push =
- &cmd_buffer->state.push_constants[stage];
+ const struct anv_push_constants *push =
+ &gfx_state->base.push_constants;
uint32_t dynamic_offset =
push->dynamic_offsets[range->dynamic_offset_index];
return anv_address_add(desc->buffer->address,
assert(desc->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC);
/* Compute the offset within the buffer */
- struct anv_push_constants *push =
- &cmd_buffer->state.push_constants[stage];
+ const struct anv_push_constants *push =
+ &gfx_state->base.push_constants;
uint32_t dynamic_offset =
push->dynamic_offsets[range->dynamic_offset_index];
uint64_t offset = desc->offset + dynamic_offset;
VkShaderStageFlags dirty_stages)
{
VkShaderStageFlags flushed = 0;
- const struct anv_cmd_graphics_state *gfx_state = &cmd_buffer->state.gfx;
+ struct anv_cmd_graphics_state *gfx_state = &cmd_buffer->state.gfx;
const struct anv_graphics_pipeline *pipeline = gfx_state->pipeline;
#if GEN_GEN >= 12
uint32_t nobuffer_stages = 0;
#endif
+ /* Compute robust pushed register access mask for each stage. */
+ if (cmd_buffer->device->robust_buffer_access) {
+ anv_foreach_stage(stage, dirty_stages) {
+ if (!anv_pipeline_has_stage(pipeline, stage))
+ continue;
+
+ const struct anv_pipeline_bind_map *bind_map =
+ &pipeline->shaders[stage]->bind_map;
+ struct anv_push_constants *push = &gfx_state->base.push_constants;
+
+ push->push_reg_mask[stage] = 0;
+ /* Start of the current range in the shader, relative to the start of
+ * push constants in the shader.
+ */
+ unsigned range_start_reg = 0;
+ for (unsigned i = 0; i < 4; i++) {
+ const struct anv_push_range *range = &bind_map->push_ranges[i];
+ if (range->length == 0)
+ continue;
+
+ unsigned bound_size =
+ get_push_range_bound_size(cmd_buffer, stage, range);
+ if (bound_size >= range->start * 32) {
+ unsigned bound_regs =
+ MIN2(DIV_ROUND_UP(bound_size, 32) - range->start,
+ range->length);
+ assert(range_start_reg + bound_regs <= 64);
+ push->push_reg_mask[stage] |= BITFIELD64_RANGE(range_start_reg,
+ bound_regs);
+ }
+
+ cmd_buffer->state.push_constants_dirty |=
+ mesa_to_vk_shader_stage(stage);
+
+ range_start_reg += range->length;
+ }
+ }
+ }
+
+ /* Resets the push constant state so that we allocate a new one if
+ * needed.
+ */
+ gfx_state->base.push_constants_state = ANV_STATE_NULL;
+
anv_foreach_stage(stage, dirty_stages) {
unsigned buffer_count = 0;
flushed |= mesa_to_vk_shader_stage(stage);
if (anv_pipeline_has_stage(pipeline, stage)) {
const struct anv_pipeline_bind_map *bind_map =
&pipeline->shaders[stage]->bind_map;
- struct anv_push_constants *push =
- &cmd_buffer->state.push_constants[stage];
-
- if (cmd_buffer->device->robust_buffer_access) {
- push->push_reg_mask = 0;
- /* Start of the current range in the shader, relative to the start
- * of push constants in the shader.
- */
- unsigned range_start_reg = 0;
- for (unsigned i = 0; i < 4; i++) {
- const struct anv_push_range *range = &bind_map->push_ranges[i];
- if (range->length == 0)
- continue;
-
- unsigned bound_size =
- get_push_range_bound_size(cmd_buffer, stage, range);
- if (bound_size >= range->start * 32) {
- unsigned bound_regs =
- MIN2(DIV_ROUND_UP(bound_size, 32) - range->start,
- range->length);
- assert(range_start_reg + bound_regs <= 64);
- push->push_reg_mask |= BITFIELD64_RANGE(range_start_reg,
- bound_regs);
- }
-
- cmd_buffer->state.push_constants_dirty |=
- mesa_to_vk_shader_stage(stage);
-
- range_start_reg += range->length;
- }
- }
/* We have to gather buffer addresses as a second step because the
* loop above puts data into the push constant area and the call to
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;
+
struct GENX(VERTEX_BUFFER_STATE) state;
if (buffer) {
+ 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;
+
state = (struct GENX(VERTEX_BUFFER_STATE)) {
.VertexBufferIndex = vb,
.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 {
sob.SurfaceBaseAddress = anv_address_add(xfb->buffer->address,
xfb->offset);
/* Size is in DWords - 1 */
- sob.SurfaceSize = xfb->size / 4 - 1;
+ sob.SurfaceSize = DIV_ROUND_UP(xfb->size, 4) - 1;
}
}
}
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) {
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);
return;
struct anv_push_constants *push =
- &cmd_buffer->state.push_constants[MESA_SHADER_COMPUTE];
+ &cmd_buffer->state.compute.base.push_constants;
if (push->cs.base_work_group_id[0] != baseGroupX ||
push->cs.base_work_group_id[1] != baseGroupY ||
push->cs.base_work_group_id[2] != baseGroupZ) {