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;
|
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.
|
||||||
*
|
*
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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.
|
||||||
*
|
*
|
||||||
|
@@ -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
|
||||||
|
@@ -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) {
|
||||||
|
@@ -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) {
|
||||||
|
Reference in New Issue
Block a user