anv: Add support for UBOs, SSBOs and push constants in Mesh pipeline

Signed-off-by: Marcin Ślusarz <marcin.slusarz@intel.com>
Reviewed-by: Caio Oliveira <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13662>
This commit is contained in:
Marcin Ślusarz
2021-07-12 13:46:31 +02:00
committed by Marge Bot
parent f12f5ae2f8
commit 18e628135d
6 changed files with 98 additions and 14 deletions

View File

@@ -137,6 +137,12 @@ brw_shader_stage_is_bindless(gl_shader_stage stage)
stage <= MESA_SHADER_CALLABLE; stage <= MESA_SHADER_CALLABLE;
} }
static inline bool
brw_shader_stage_requires_bindless_resources(gl_shader_stage stage)
{
return brw_shader_stage_is_bindless(stage) || gl_shader_stage_is_mesh(stage);
}
/** /**
* Program key structures. * Program key structures.
* *

View File

@@ -925,7 +925,10 @@ anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
switch (bind_point) { switch (bind_point) {
case VK_PIPELINE_BIND_POINT_GRAPHICS: case VK_PIPELINE_BIND_POINT_GRAPHICS:
stages &= VK_SHADER_STAGE_ALL_GRAPHICS; stages &= VK_SHADER_STAGE_ALL_GRAPHICS |
(cmd_buffer->device->vk.enabled_extensions.NV_mesh_shader ?
(VK_SHADER_STAGE_TASK_BIT_NV |
VK_SHADER_STAGE_MESH_BIT_NV) : 0);
pipe_state = &cmd_buffer->state.gfx.base; pipe_state = &cmd_buffer->state.gfx.base;
break; break;
@@ -957,11 +960,20 @@ anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
anv_descriptor_set_is_push(set)) { anv_descriptor_set_is_push(set)) {
pipe_state->descriptors[set_index] = set; pipe_state->descriptors[set_index] = set;
/* Ray-tracing shaders are entirely bindless and so they don't have /* Those stages don't have access to HW binding tables.
* access to HW binding tables. This means that we have to upload the * This means that we have to upload the descriptor set
* descriptor set as an 64-bit address in the push constants. * as an 64-bit address in the push constants.
*/ */
if (bind_point == VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR) { bool update_desc_sets = stages & (VK_SHADER_STAGE_TASK_BIT_NV |
VK_SHADER_STAGE_MESH_BIT_NV |
VK_SHADER_STAGE_RAYGEN_BIT_KHR |
VK_SHADER_STAGE_ANY_HIT_BIT_KHR |
VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR |
VK_SHADER_STAGE_MISS_BIT_KHR |
VK_SHADER_STAGE_INTERSECTION_BIT_KHR |
VK_SHADER_STAGE_CALLABLE_BIT_KHR);
if (update_desc_sets) {
struct anv_push_constants *push = &pipe_state->push_constants; struct anv_push_constants *push = &pipe_state->push_constants;
struct anv_address addr = anv_descriptor_set_address(set); struct anv_address addr = anv_descriptor_set_address(set);
@@ -1239,7 +1251,9 @@ void anv_CmdPushConstants(
{ {
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
if (stageFlags & VK_SHADER_STAGE_ALL_GRAPHICS) { if (stageFlags & (VK_SHADER_STAGE_ALL_GRAPHICS |
VK_SHADER_STAGE_TASK_BIT_NV |
VK_SHADER_STAGE_MESH_BIT_NV)) {
struct anv_cmd_pipeline_state *pipe_state = struct anv_cmd_pipeline_state *pipe_state =
&cmd_buffer->state.gfx.base; &cmd_buffer->state.gfx.base;

View File

@@ -1404,7 +1404,8 @@ anv_nir_apply_pipeline_layout(const struct anv_physical_device *pdevice,
.pdevice = pdevice, .pdevice = pdevice,
.layout = layout, .layout = layout,
.add_bounds_checks = robust_buffer_access, .add_bounds_checks = robust_buffer_access,
.desc_addr_format = brw_shader_stage_is_bindless(shader->info.stage) ? .desc_addr_format =
brw_shader_stage_requires_bindless_resources(shader->info.stage) ?
nir_address_format_64bit_global_32bit_offset : nir_address_format_64bit_global_32bit_offset :
nir_address_format_32bit_index_offset, nir_address_format_32bit_index_offset,
.ssbo_addr_format = anv_nir_ssbo_addr_format(pdevice, robust_buffer_access), .ssbo_addr_format = anv_nir_ssbo_addr_format(pdevice, robust_buffer_access),
@@ -1509,7 +1510,7 @@ anv_nir_apply_pipeline_layout(const struct anv_physical_device *pdevice,
if (binding->data & ANV_DESCRIPTOR_SURFACE_STATE) { if (binding->data & ANV_DESCRIPTOR_SURFACE_STATE) {
if (map->surface_count + array_size > MAX_BINDING_TABLE_SIZE || if (map->surface_count + array_size > MAX_BINDING_TABLE_SIZE ||
anv_descriptor_requires_bindless(pdevice, binding, false) || anv_descriptor_requires_bindless(pdevice, binding, false) ||
brw_shader_stage_is_bindless(shader->info.stage)) { brw_shader_stage_requires_bindless_resources(shader->info.stage)) {
/* If this descriptor doesn't fit in the binding table or if it /* If this descriptor doesn't fit in the binding table or if it
* requires bindless for some reason, flag it as bindless. * requires bindless for some reason, flag it as bindless.
*/ */
@@ -1549,7 +1550,7 @@ anv_nir_apply_pipeline_layout(const struct anv_physical_device *pdevice,
if (binding->data & ANV_DESCRIPTOR_SAMPLER_STATE) { if (binding->data & ANV_DESCRIPTOR_SAMPLER_STATE) {
if (map->sampler_count + array_size > MAX_SAMPLER_TABLE_SIZE || if (map->sampler_count + array_size > MAX_SAMPLER_TABLE_SIZE ||
anv_descriptor_requires_bindless(pdevice, binding, true) || anv_descriptor_requires_bindless(pdevice, binding, true) ||
brw_shader_stage_is_bindless(shader->info.stage)) { brw_shader_stage_requires_bindless_resources(shader->info.stage)) {
/* If this descriptor doesn't fit in the binding table or if it /* If this descriptor doesn't fit in the binding table or if it
* requires bindless for some reason, flag it as bindless. * requires bindless for some reason, flag it as bindless.
* *

View File

@@ -86,7 +86,7 @@ anv_nir_compute_push_layout(const struct anv_physical_device *pdevice,
const bool push_ubo_ranges = const bool push_ubo_ranges =
pdevice->info.verx10 >= 75 && pdevice->info.verx10 >= 75 &&
has_const_ubo && nir->info.stage != MESA_SHADER_COMPUTE && has_const_ubo && nir->info.stage != MESA_SHADER_COMPUTE &&
!brw_shader_stage_is_bindless(nir->info.stage); !brw_shader_stage_requires_bindless_resources(nir->info.stage);
if (push_ubo_ranges && robust_buffer_access) { if (push_ubo_ranges && robust_buffer_access) {
/* We can't on-the-fly adjust our push ranges because doing so would /* We can't on-the-fly adjust our push ranges because doing so would

View File

@@ -3531,6 +3531,56 @@ cmd_buffer_flush_push_constants(struct anv_cmd_buffer *cmd_buffer,
cmd_buffer->state.push_constants_dirty &= ~flushed; cmd_buffer->state.push_constants_dirty &= ~flushed;
} }
#if GFX_VERx10 >= 125
static void
cmd_buffer_flush_mesh_inline_data(struct anv_cmd_buffer *cmd_buffer,
VkShaderStageFlags dirty_stages)
{
struct anv_cmd_graphics_state *gfx_state = &cmd_buffer->state.gfx;
const struct anv_graphics_pipeline *pipeline = gfx_state->pipeline;
if (dirty_stages & VK_SHADER_STAGE_TASK_BIT_NV &&
anv_pipeline_has_stage(pipeline, MESA_SHADER_TASK)) {
const struct anv_shader_bin *shader = pipeline->shaders[MESA_SHADER_TASK];
const struct anv_pipeline_bind_map *bind_map = &shader->bind_map;
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_TASK_SHADER_DATA), data) {
const struct anv_push_range *range = &bind_map->push_ranges[0];
if (range->length > 0) {
struct anv_address buffer =
get_push_range_address(cmd_buffer, shader, range);
uint64_t addr = anv_address_physical(buffer);
data.InlineData[0] = addr & 0xffffffff;
data.InlineData[1] = addr >> 32;
}
}
}
if (dirty_stages & VK_SHADER_STAGE_MESH_BIT_NV &&
anv_pipeline_has_stage(pipeline, MESA_SHADER_MESH)) {
const struct anv_shader_bin *shader = pipeline->shaders[MESA_SHADER_MESH];
const struct anv_pipeline_bind_map *bind_map = &shader->bind_map;
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_MESH_SHADER_DATA), data) {
const struct anv_push_range *range = &bind_map->push_ranges[0];
if (range->length > 0) {
struct anv_address buffer =
get_push_range_address(cmd_buffer, shader, range);
uint64_t addr = anv_address_physical(buffer);
data.InlineData[0] = addr & 0xffffffff;
data.InlineData[1] = addr >> 32;
}
}
}
cmd_buffer->state.push_constants_dirty &= ~dirty_stages;
}
#endif
static void static void
cmd_buffer_emit_clip(struct anv_cmd_buffer *cmd_buffer) cmd_buffer_emit_clip(struct anv_cmd_buffer *cmd_buffer)
{ {
@@ -3840,6 +3890,11 @@ genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer)
dirty |= cmd_buffer->state.push_constants_dirty; dirty |= cmd_buffer->state.push_constants_dirty;
cmd_buffer_flush_push_constants(cmd_buffer, cmd_buffer_flush_push_constants(cmd_buffer,
dirty & VK_SHADER_STAGE_ALL_GRAPHICS); dirty & VK_SHADER_STAGE_ALL_GRAPHICS);
#if GFX_VERx10 >= 125
cmd_buffer_flush_mesh_inline_data(
cmd_buffer, dirty & (VK_SHADER_STAGE_TASK_BIT_NV |
VK_SHADER_STAGE_MESH_BIT_NV));
#endif
} }
if (dirty & VK_SHADER_STAGE_ALL_GRAPHICS) { if (dirty & VK_SHADER_STAGE_ALL_GRAPHICS) {

View File

@@ -2633,9 +2633,13 @@ emit_task_state(struct anv_graphics_pipeline *pipeline)
task.NumberofBarriers = task_prog_data->base.uses_barrier; task.NumberofBarriers = task_prog_data->base.uses_barrier;
task.SharedLocalMemorySize = task.SharedLocalMemorySize =
encode_slm_size(GFX_VER, task_prog_data->base.base.total_shared); encode_slm_size(GFX_VER, task_prog_data->base.base.total_shared);
}
anv_batch_emit(&pipeline->base.batch, GENX(3DSTATE_TASK_SHADER_DATA), zero); /*
* 3DSTATE_TASK_SHADER_DATA.InlineData[0:1] will be used for an address
* of a buffer with push constants and descriptor set table.
*/
task.EmitInlineParameter = true;
}
/* Recommended values from "Task and Mesh Distribution Programming". */ /* Recommended values from "Task and Mesh Distribution Programming". */
anv_batch_emit(&pipeline->base.batch, GENX(3DSTATE_TASK_REDISTRIB), redistrib) { anv_batch_emit(&pipeline->base.batch, GENX(3DSTATE_TASK_REDISTRIB), redistrib) {
@@ -2700,9 +2704,13 @@ emit_mesh_state(struct anv_graphics_pipeline *pipeline)
mesh.NumberofBarriers = mesh_prog_data->base.uses_barrier; mesh.NumberofBarriers = mesh_prog_data->base.uses_barrier;
mesh.SharedLocalMemorySize = mesh.SharedLocalMemorySize =
encode_slm_size(GFX_VER, mesh_prog_data->base.base.total_shared); encode_slm_size(GFX_VER, mesh_prog_data->base.base.total_shared);
}
anv_batch_emit(&pipeline->base.batch, GENX(3DSTATE_MESH_SHADER_DATA), zero); /*
* 3DSTATE_MESH_SHADER_DATA.InlineData[0:1] will be used for an address
* of a buffer with push constants and descriptor set table.
*/
mesh.EmitInlineParameter = true;
}
/* Recommended values from "Task and Mesh Distribution Programming". */ /* Recommended values from "Task and Mesh Distribution Programming". */
anv_batch_emit(&pipeline->base.batch, GENX(3DSTATE_MESH_DISTRIB), distrib) { anv_batch_emit(&pipeline->base.batch, GENX(3DSTATE_MESH_DISTRIB), distrib) {