mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 18:18:06 +02:00
pvr, pco: add multiview compiler support, advertise extension
- Pass view index to fragment shader via linked flat varying. - Use view index instead of layer id for input attachments when required. Signed-off-by: Simon Perretta <simon.perretta@imgtec.com> Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37512>
This commit is contained in:
parent
9d48088428
commit
cb6c921502
10 changed files with 167 additions and 8 deletions
|
|
@ -452,7 +452,7 @@ Vulkan 1.1 -- all DONE: anv, hk, lvp, nvk, panvk/v10+, radv, tu, vn
|
|||
VK_KHR_maintenance1 DONE (anv, dzn, hasvk, lvp, nvk, panvk, pvr, radv, tu, v3dv, vn)
|
||||
VK_KHR_maintenance2 DONE (anv, dzn, hasvk, lvp, nvk, panvk, pvr, radv, tu, v3dv, vn)
|
||||
VK_KHR_maintenance3 DONE (anv, dzn, hasvk, lvp, nvk, panvk, pvr, radv, tu, v3dv, vn)
|
||||
VK_KHR_multiview DONE (anv, dzn, hasvk, lvp, nvk, panvk/v10+, radv, tu, v3dv, vn)
|
||||
VK_KHR_multiview DONE (anv, dzn, hasvk, lvp, nvk, panvk/v10+, pvr, radv, tu, v3dv, vn)
|
||||
VK_KHR_relaxed_block_layout DONE (anv, dzn, hasvk, lvp, nvk, panvk, radv, tu, v3dv, vn)
|
||||
VK_KHR_sampler_ycbcr_conversion DONE (anv, hasvk, lvp, nvk, panvk/v10+, radv, tu, v3dv, vn)
|
||||
VK_KHR_shader_draw_parameters DONE (anv, dzn, hasvk, lvp, nvk, panvk, radv, tu, vn)
|
||||
|
|
|
|||
|
|
@ -34,7 +34,11 @@ const struct spirv_to_nir_options *pco_spirv_options(void);
|
|||
const nir_shader_compiler_options *pco_nir_options(void);
|
||||
|
||||
void pco_preprocess_nir(pco_ctx *ctx, nir_shader *nir);
|
||||
void pco_link_nir(pco_ctx *ctx, nir_shader *producer, nir_shader *consumer);
|
||||
void pco_link_nir(pco_ctx *ctx,
|
||||
nir_shader *producer,
|
||||
nir_shader *consumer,
|
||||
pco_data *producer_data,
|
||||
pco_data *consumer_data);
|
||||
void pco_rev_link_nir(pco_ctx *ctx, nir_shader *producer, nir_shader *consumer);
|
||||
void pco_lower_nir(pco_ctx *ctx, nir_shader *nir, pco_data *data);
|
||||
void pco_postprocess_nir(pco_ctx *ctx, nir_shader *nir, pco_data *data);
|
||||
|
|
|
|||
|
|
@ -106,6 +106,8 @@ typedef struct _pco_fs_data {
|
|||
|
||||
pco_range sample_locations;
|
||||
|
||||
gl_varying_slot view_index_slot;
|
||||
|
||||
struct {
|
||||
bool w; /** Whether the shader uses pos.w. */
|
||||
bool z; /** Whether the shader uses pos.z */
|
||||
|
|
@ -224,6 +226,7 @@ typedef struct _pco_common_data {
|
|||
|
||||
bool robust_buffer_access;
|
||||
bool image_2d_view_of_3d;
|
||||
bool multiview;
|
||||
} pco_common_data;
|
||||
|
||||
/** PCO shader data. */
|
||||
|
|
|
|||
|
|
@ -1756,6 +1756,9 @@ bool pco_legalize(pco_shader *shader);
|
|||
bool pco_opt_comp_only_vecs(pco_shader *shader);
|
||||
bool pco_nir_compute_instance_check(nir_shader *shader);
|
||||
bool pco_nir_link_clip_cull_vars(nir_shader *producer, nir_shader *consumer);
|
||||
bool pco_nir_link_multiview(nir_shader *producer,
|
||||
nir_shader *consumer,
|
||||
pco_data *consumer_data);
|
||||
bool pco_nir_lower_algebraic(nir_shader *shader);
|
||||
bool pco_nir_lower_algebraic_late(nir_shader *shader);
|
||||
bool pco_nir_lower_atomics(nir_shader *shader, pco_data *data);
|
||||
|
|
|
|||
|
|
@ -636,15 +636,27 @@ void pco_preprocess_nir(pco_ctx *ctx, nir_shader *nir)
|
|||
}
|
||||
}
|
||||
|
||||
static bool can_remove_var(nir_variable *var, UNUSED void *data)
|
||||
{
|
||||
return !var->data.always_active_io;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Performs linking optimizations on consecutive NIR shader stages.
|
||||
*
|
||||
* \param[in] ctx PCO compiler context.
|
||||
* \param[in,out] producer NIR producer shader.
|
||||
* \param[in,out] consumer NIR consumer shader.
|
||||
* \param[in,out] producer_data Producer shader data.
|
||||
* \param[in,out] consumer_data Consumer shader data.
|
||||
*/
|
||||
void pco_link_nir(pco_ctx *ctx, nir_shader *producer, nir_shader *consumer)
|
||||
void pco_link_nir(pco_ctx *ctx,
|
||||
nir_shader *producer,
|
||||
nir_shader *consumer,
|
||||
pco_data *producer_data,
|
||||
pco_data *consumer_data)
|
||||
{
|
||||
pco_nir_link_multiview(producer, consumer, consumer_data);
|
||||
pco_nir_link_clip_cull_vars(producer, consumer);
|
||||
|
||||
nir_lower_io_array_vars_to_elements(producer, consumer);
|
||||
|
|
@ -660,8 +672,12 @@ void pco_link_nir(pco_ctx *ctx, nir_shader *producer, nir_shader *consumer)
|
|||
if (nir_link_opt_varyings(producer, consumer))
|
||||
pco_nir_opt(ctx, consumer);
|
||||
|
||||
NIR_PASS(_, producer, nir_remove_dead_variables, nir_var_shader_out, NULL);
|
||||
NIR_PASS(_, consumer, nir_remove_dead_variables, nir_var_shader_in, NULL);
|
||||
nir_remove_dead_variables_options rdv = {
|
||||
.can_remove_var = can_remove_var,
|
||||
};
|
||||
|
||||
NIR_PASS(_, producer, nir_remove_dead_variables, nir_var_shader_out, &rdv);
|
||||
NIR_PASS(_, consumer, nir_remove_dead_variables, nir_var_shader_in, &rdv);
|
||||
|
||||
bool progress = nir_remove_unused_varyings(producer, consumer);
|
||||
nir_compact_varyings(producer, consumer, true);
|
||||
|
|
|
|||
|
|
@ -1549,3 +1549,68 @@ bool pco_nir_lower_interpolation(nir_shader *shader, pco_fs_data *fs)
|
|||
|
||||
return progress;
|
||||
}
|
||||
|
||||
static bool lower_load_view_index_fs(struct nir_builder *b,
|
||||
nir_intrinsic_instr *intr,
|
||||
void *cb_data)
|
||||
{
|
||||
if (intr->intrinsic != nir_intrinsic_load_view_index)
|
||||
return false;
|
||||
|
||||
nir_variable *view_index_var = cb_data;
|
||||
b->cursor = nir_before_instr(&intr->instr);
|
||||
nir_def_replace(&intr->def, nir_load_var(b, view_index_var));
|
||||
nir_instr_free(&intr->instr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pco_nir_link_multiview(nir_shader *producer,
|
||||
nir_shader *consumer,
|
||||
pco_data *consumer_data)
|
||||
{
|
||||
if (producer->info.stage != MESA_SHADER_VERTEX ||
|
||||
consumer->info.stage != MESA_SHADER_FRAGMENT ||
|
||||
!consumer_data->common.multiview) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Find unused varying slot for the view index. */
|
||||
gl_varying_slot view_index_slot = VARYING_SLOT_VAR0;
|
||||
nir_foreach_shader_out_variable (var, producer) {
|
||||
view_index_slot = MAX2(view_index_slot, var->data.location + 1);
|
||||
}
|
||||
assert(view_index_slot < VARYING_SLOT_MAX);
|
||||
consumer_data->fs.view_index_slot = view_index_slot;
|
||||
|
||||
/* Create output variable in the producer. */
|
||||
nir_variable *view_index_var = nir_variable_create(producer,
|
||||
nir_var_shader_out,
|
||||
glsl_uint_type(),
|
||||
"view_index");
|
||||
view_index_var->data.location = view_index_slot;
|
||||
view_index_var->data.interpolation = INTERP_MODE_FLAT;
|
||||
view_index_var->data.always_active_io = true;
|
||||
|
||||
/* Store view index in the producer. */
|
||||
nir_builder b = nir_builder_at(nir_after_block(
|
||||
nir_impl_last_block(nir_shader_get_entrypoint(producer))));
|
||||
nir_store_var(&b, view_index_var, nir_load_view_index(&b), 1);
|
||||
|
||||
/* Create input variable in the consumer. */
|
||||
view_index_var = nir_variable_create(consumer,
|
||||
nir_var_shader_in,
|
||||
glsl_uint_type(),
|
||||
"view_index");
|
||||
view_index_var->data.location = view_index_slot;
|
||||
view_index_var->data.interpolation = INTERP_MODE_FLAT;
|
||||
view_index_var->data.always_active_io = true;
|
||||
|
||||
/* Lower view index loads in the consumer. */
|
||||
nir_shader_intrinsics_pass(consumer,
|
||||
lower_load_view_index_fs,
|
||||
nir_metadata_all,
|
||||
view_index_var);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1226,7 +1226,22 @@ static nir_def *lower_image(nir_builder *b, nir_instr *instr, void *cb_data)
|
|||
frag_coords = nir_f2i32(b, frag_coords);
|
||||
coords = nir_iadd(b, frag_coords, coords);
|
||||
|
||||
nir_def *layer = nir_load_layer_id(b); /* TODO: view id for multiview? */
|
||||
nir_def *layer = nir_load_layer_id(b);
|
||||
|
||||
/* Use the view index instead if we're in multiview. */
|
||||
if (data->common.multiview) {
|
||||
assert(data->fs.view_index_slot >= VARYING_SLOT_VAR0 &&
|
||||
data->fs.view_index_slot < VARYING_SLOT_MAX);
|
||||
layer = nir_load_input(b,
|
||||
1,
|
||||
32,
|
||||
nir_imm_int(b, 0),
|
||||
.dest_type = nir_type_uint32,
|
||||
.io_semantics = (nir_io_semantics){
|
||||
.location = data->fs.view_index_slot,
|
||||
.num_slots = 1,
|
||||
});
|
||||
}
|
||||
|
||||
coords = nir_pad_vector(b, coords, 3);
|
||||
coords = nir_vector_insert_imm(b, coords, layer, 2);
|
||||
|
|
|
|||
|
|
@ -2113,6 +2113,7 @@ static pco_instr *trans_intr(trans_ctx *tctx, nir_intrinsic_instr *intr)
|
|||
case nir_intrinsic_load_base_instance:
|
||||
case nir_intrinsic_load_base_vertex:
|
||||
case nir_intrinsic_load_draw_id:
|
||||
case nir_intrinsic_load_view_index:
|
||||
|
||||
/* Compute sysvals. */
|
||||
case nir_intrinsic_load_local_invocation_index:
|
||||
|
|
|
|||
|
|
@ -189,6 +189,7 @@ static void pvr_physical_device_get_supported_extensions(
|
|||
.KHR_maintenance1 = true,
|
||||
.KHR_maintenance2 = true,
|
||||
.KHR_maintenance3 = true,
|
||||
.KHR_multiview = true,
|
||||
.KHR_present_id2 = PVR_USE_WSI_PLATFORM,
|
||||
.KHR_present_wait2 = PVR_USE_WSI_PLATFORM,
|
||||
.KHR_separate_depth_stencil_layouts = true,
|
||||
|
|
@ -293,6 +294,11 @@ static void pvr_physical_device_get_supported_features(
|
|||
/* Vulkan 1.2 / VK_KHR_imageless_framebuffer */
|
||||
.imagelessFramebuffer = true,
|
||||
|
||||
/* Vulkan 1.1 / VK_KHR_multiview */
|
||||
.multiview = true,
|
||||
.multiviewGeometryShader = false,
|
||||
.multiviewTessellationShader = false,
|
||||
|
||||
/* Vulkan 1.2 / VK_KHR_timeline_semaphore */
|
||||
.timelineSemaphore = true,
|
||||
|
||||
|
|
@ -586,6 +592,10 @@ static bool pvr_physical_device_get_properties(
|
|||
.maxPerSetDescriptors = PVR_MAX_DESCRIPTORS_PER_SET,
|
||||
.maxMemoryAllocationSize = max_memory_alloc_size,
|
||||
|
||||
/* Vulkan 1.1 / VK_KHR_multiview */
|
||||
.maxMultiviewViewCount = PVR_MAX_MULTIVIEW,
|
||||
.maxMultiviewInstanceIndex = (1 << 27) - 1,
|
||||
|
||||
/* Vulkan 1.2 / VK_KHR_driver_properties */
|
||||
.driverID = VK_DRIVER_ID_IMAGINATION_OPEN_SOURCE_MESA,
|
||||
.driverName = "Imagination open-source Mesa driver",
|
||||
|
|
|
|||
|
|
@ -400,6 +400,11 @@ static VkResult pvr_pds_vertex_attrib_programs_create_and_upload(
|
|||
input.draw_index_register = sys_vals[SYSTEM_VALUE_DRAW_ID].start;
|
||||
}
|
||||
|
||||
if (sys_vals[SYSTEM_VALUE_VIEW_INDEX].count > 0) {
|
||||
input.flags |= PVR_PDS_VERTEX_FLAGS_VIEW_INDEX_REQUIRED;
|
||||
input.view_index_register = sys_vals[SYSTEM_VALUE_VIEW_INDEX].start;
|
||||
}
|
||||
|
||||
pvr_pds_setup_doutu(&input.usc_task_control,
|
||||
0,
|
||||
usc_temp_count,
|
||||
|
|
@ -930,6 +935,10 @@ static void pvr_pipeline_finish(struct pvr_device *device,
|
|||
vk_object_base_finish(&pipeline->base);
|
||||
}
|
||||
|
||||
static void pvr_early_init_shader_data(pco_data *data,
|
||||
nir_shader *nir,
|
||||
const void *pCreateInfo);
|
||||
|
||||
static void
|
||||
pvr_preprocess_shader_data(pco_data *data,
|
||||
nir_shader *nir,
|
||||
|
|
@ -987,6 +996,7 @@ static VkResult pvr_compute_pipeline_compile(
|
|||
if (result != VK_SUCCESS)
|
||||
goto err_free_build_context;
|
||||
|
||||
pvr_early_init_shader_data(&shader_data, nir, pCreateInfo);
|
||||
pco_preprocess_nir(pco_ctx, nir);
|
||||
pvr_preprocess_shader_data(&shader_data, nir, pCreateInfo, layout, NULL);
|
||||
pco_lower_nir(pco_ctx, nir, &shader_data);
|
||||
|
|
@ -1651,7 +1661,7 @@ static void pvr_alloc_vs_sysvals(pco_data *data, nir_shader *nir)
|
|||
gl_system_value sys_vals[] = {
|
||||
SYSTEM_VALUE_VERTEX_ID, SYSTEM_VALUE_INSTANCE_ID,
|
||||
SYSTEM_VALUE_BASE_INSTANCE, SYSTEM_VALUE_BASE_VERTEX,
|
||||
SYSTEM_VALUE_DRAW_ID,
|
||||
SYSTEM_VALUE_DRAW_ID, SYSTEM_VALUE_VIEW_INDEX,
|
||||
};
|
||||
|
||||
for (unsigned u = 0; u < ARRAY_SIZE(sys_vals); ++u) {
|
||||
|
|
@ -2570,6 +2580,29 @@ static void pvr_postprocess_shader_data(pco_data *data,
|
|||
/* TODO: common things, like large constants being put into shareds. */
|
||||
}
|
||||
|
||||
static void pvr_early_init_shader_data(pco_data *data,
|
||||
nir_shader *nir,
|
||||
const void *pCreateInfo)
|
||||
{
|
||||
const VkGraphicsPipelineCreateInfo *pGraphicsCreateInfo = pCreateInfo;
|
||||
|
||||
switch (nir->info.stage) {
|
||||
case MESA_SHADER_VERTEX:
|
||||
case MESA_SHADER_FRAGMENT: {
|
||||
VK_FROM_HANDLE(pvr_render_pass, pass, pGraphicsCreateInfo->renderPass);
|
||||
data->common.multiview = pass->multiview_enabled;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case MESA_SHADER_COMPUTE:
|
||||
break;
|
||||
|
||||
default:
|
||||
UNREACHABLE("Unsupported stage.");
|
||||
}
|
||||
}
|
||||
|
||||
/* Compiles and uploads shaders and PDS programs. */
|
||||
static VkResult
|
||||
pvr_graphics_pipeline_compile(struct pvr_device *const device,
|
||||
|
|
@ -2594,6 +2627,7 @@ pvr_graphics_pipeline_compile(struct pvr_device *const device,
|
|||
nir_shader *producer = NULL;
|
||||
nir_shader *consumer = NULL;
|
||||
pco_data shader_data[MESA_SHADER_STAGES] = { 0 };
|
||||
pco_data *producer_data = NULL;
|
||||
nir_shader *nir_shaders[MESA_SHADER_STAGES] = { 0 };
|
||||
pco_shader *pco_shaders[MESA_SHADER_STAGES] = { 0 };
|
||||
pco_shader **vs = &pco_shaders[MESA_SHADER_VERTEX];
|
||||
|
|
@ -2621,6 +2655,9 @@ pvr_graphics_pipeline_compile(struct pvr_device *const device,
|
|||
if (result != VK_SUCCESS)
|
||||
goto err_free_build_context;
|
||||
|
||||
pvr_early_init_shader_data(&shader_data[stage],
|
||||
nir_shaders[stage],
|
||||
pCreateInfo);
|
||||
pco_preprocess_nir(pco_ctx, nir_shaders[stage]);
|
||||
}
|
||||
|
||||
|
|
@ -2629,9 +2666,14 @@ pvr_graphics_pipeline_compile(struct pvr_device *const device,
|
|||
continue;
|
||||
|
||||
if (producer)
|
||||
pco_link_nir(pco_ctx, producer, nir_shaders[stage]);
|
||||
pco_link_nir(pco_ctx,
|
||||
producer,
|
||||
nir_shaders[stage],
|
||||
producer_data,
|
||||
&shader_data[stage]);
|
||||
|
||||
producer = nir_shaders[stage];
|
||||
producer_data = &shader_data[stage];
|
||||
}
|
||||
|
||||
for (mesa_shader_stage stage = MESA_SHADER_STAGES; stage-- > 0;) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue