X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=blobdiff_plain;f=src%2Fintel%2Fvulkan%2FgenX_cmd_buffer.c;h=8bcb4f4affdc9e04b3586dafb27cbc0608aa8cfc;hp=34afcf7a505ea26c33ce72d2ae3ebb16317573a8;hb=HEAD;hpb=ecf3335eef889f1c04b928a1a6371c6bd7b67fa5 diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 34afcf7a505..8bcb4f4affd 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -2362,7 +2362,7 @@ cmd_buffer_alloc_push_constants(struct anv_cmd_buffer *cmd_buffer) */ 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 @@ -2402,7 +2402,7 @@ cmd_buffer_alloc_push_constants(struct anv_cmd_buffer *cmd_buffer) 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: * @@ -2469,6 +2469,7 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer, */ 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]; @@ -2511,10 +2512,11 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer, 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); @@ -2653,9 +2655,6 @@ emit_binding_table(struct anv_cmd_buffer *cmd_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; @@ -2880,7 +2879,7 @@ get_push_range_address(struct anv_cmd_buffer *cmd_buffer, 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 @@ -2893,11 +2892,13 @@ get_push_range_address(struct anv_cmd_buffer *cmd_buffer, } 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, }; } @@ -2914,8 +2915,8 @@ get_push_range_address(struct anv_cmd_buffer *cmd_buffer, } 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, @@ -2984,8 +2985,8 @@ get_push_range_bound_size(struct anv_cmd_buffer *cmd_buffer, 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; @@ -3162,13 +3163,57 @@ cmd_buffer_flush_push_constants(struct anv_cmd_buffer *cmd_buffer, 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); @@ -3178,37 +3223,6 @@ cmd_buffer_flush_push_constants(struct anv_cmd_buffer *cmd_buffer, 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 @@ -3263,6 +3277,46 @@ cmd_buffer_flush_push_constants(struct anv_cmd_buffer *cmd_buffer, 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) { @@ -3298,8 +3352,19 @@ 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, @@ -3308,16 +3373,15 @@ genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer) .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 { @@ -3362,7 +3426,7 @@ genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer) 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; } } } @@ -3382,6 +3446,9 @@ genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer) 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) { @@ -3434,6 +3501,8 @@ genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer) 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); @@ -3581,7 +3650,7 @@ void genX(CmdDraw)( 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; @@ -3632,7 +3701,7 @@ void genX(CmdDrawIndexed)( 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; @@ -3712,7 +3781,7 @@ void genX(CmdDrawIndirectByteCountEXT)( 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); @@ -3797,7 +3866,7 @@ void genX(CmdDrawIndirect)( 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); @@ -3847,7 +3916,7 @@ void genX(CmdDrawIndexedIndirect)( 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); @@ -4002,7 +4071,7 @@ void genX(CmdDrawIndirectCount)( 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); @@ -4074,7 +4143,7 @@ void genX(CmdDrawIndexedIndirectCount)( 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); @@ -4300,7 +4369,7 @@ anv_cmd_buffer_push_base_group_id(struct anv_cmd_buffer *cmd_buffer, 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) {