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:

committed by
Marge Bot

parent
f12f5ae2f8
commit
18e628135d
@@ -137,6 +137,12 @@ brw_shader_stage_is_bindless(gl_shader_stage stage)
|
||||
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.
|
||||
*
|
||||
|
@@ -925,7 +925,10 @@ anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
|
||||
|
||||
switch (bind_point) {
|
||||
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;
|
||||
break;
|
||||
|
||||
@@ -957,11 +960,20 @@ anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
|
||||
anv_descriptor_set_is_push(set)) {
|
||||
pipe_state->descriptors[set_index] = set;
|
||||
|
||||
/* Ray-tracing shaders are entirely bindless and so they don't have
|
||||
* access to HW binding tables. This means that we have to upload the
|
||||
* descriptor set as an 64-bit address in the push constants.
|
||||
/* Those stages don't have access to HW binding tables.
|
||||
* This means that we have to upload the descriptor set
|
||||
* 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_address addr = anv_descriptor_set_address(set);
|
||||
@@ -1239,7 +1251,9 @@ void anv_CmdPushConstants(
|
||||
{
|
||||
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 =
|
||||
&cmd_buffer->state.gfx.base;
|
||||
|
||||
|
@@ -1404,7 +1404,8 @@ anv_nir_apply_pipeline_layout(const struct anv_physical_device *pdevice,
|
||||
.pdevice = pdevice,
|
||||
.layout = layout,
|
||||
.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_32bit_index_offset,
|
||||
.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 (map->surface_count + array_size > MAX_BINDING_TABLE_SIZE ||
|
||||
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
|
||||
* 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 (map->sampler_count + array_size > MAX_SAMPLER_TABLE_SIZE ||
|
||||
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
|
||||
* requires bindless for some reason, flag it as bindless.
|
||||
*
|
||||
|
@@ -86,7 +86,7 @@ anv_nir_compute_push_layout(const struct anv_physical_device *pdevice,
|
||||
const bool push_ubo_ranges =
|
||||
pdevice->info.verx10 >= 75 &&
|
||||
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) {
|
||||
/* We can't on-the-fly adjust our push ranges because doing so would
|
||||
|
@@ -3531,6 +3531,56 @@ cmd_buffer_flush_push_constants(struct anv_cmd_buffer *cmd_buffer,
|
||||
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
|
||||
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;
|
||||
cmd_buffer_flush_push_constants(cmd_buffer,
|
||||
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) {
|
||||
|
@@ -2633,9 +2633,13 @@ emit_task_state(struct anv_graphics_pipeline *pipeline)
|
||||
task.NumberofBarriers = task_prog_data->base.uses_barrier;
|
||||
task.SharedLocalMemorySize =
|
||||
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". */
|
||||
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.SharedLocalMemorySize =
|
||||
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". */
|
||||
anv_batch_emit(&pipeline->base.batch, GENX(3DSTATE_MESH_DISTRIB), distrib) {
|
||||
|
Reference in New Issue
Block a user