mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-06 06:40:08 +01:00
tu: Add multiview lowering pass
For now this only handles an a630 quirk where PC_MULTIVIEW_MASK doesn't exist. However in the future it will also handle multi-position output. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5720>
This commit is contained in:
parent
7b53ac1c1f
commit
c884afc6f7
4 changed files with 84 additions and 0 deletions
|
|
@ -51,6 +51,7 @@ libtu_files = files(
|
|||
'tu_fence.c',
|
||||
'tu_formats.c',
|
||||
'tu_image.c',
|
||||
'tu_nir_lower_multiview.c',
|
||||
'tu_pass.c',
|
||||
'tu_pipeline.c',
|
||||
'tu_pipeline_cache.c',
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ tu_physical_device_init(struct tu_physical_device *device,
|
|||
device->tile_align_w = 32;
|
||||
device->magic.PC_UNKNOWN_9805 = 0x0;
|
||||
device->magic.SP_UNKNOWN_A0F8 = 0x0;
|
||||
device->supports_multiview_mask = false; /* TODO */
|
||||
break;
|
||||
case 630:
|
||||
case 640:
|
||||
|
|
@ -86,6 +87,7 @@ tu_physical_device_init(struct tu_physical_device *device,
|
|||
device->tile_align_w = 32;
|
||||
device->magic.PC_UNKNOWN_9805 = 0x1;
|
||||
device->magic.SP_UNKNOWN_A0F8 = 0x1;
|
||||
device->supports_multiview_mask = device->gpu_id != 630;
|
||||
break;
|
||||
case 650:
|
||||
device->ccu_offset_gmem = 0x114000;
|
||||
|
|
@ -93,6 +95,7 @@ tu_physical_device_init(struct tu_physical_device *device,
|
|||
device->tile_align_w = 96;
|
||||
device->magic.PC_UNKNOWN_9805 = 0x2;
|
||||
device->magic.SP_UNKNOWN_A0F8 = 0x2;
|
||||
device->supports_multiview_mask = true;
|
||||
break;
|
||||
default:
|
||||
result = vk_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
|
||||
|
|
|
|||
76
src/freedreno/vulkan/tu_nir_lower_multiview.c
Normal file
76
src/freedreno/vulkan/tu_nir_lower_multiview.c
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright © 2020 Valve Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "tu_private.h"
|
||||
#include "nir_builder.h"
|
||||
|
||||
/* Some a6xx variants cannot support a non-contiguous multiview mask. Instead,
|
||||
* inside the shader something like this needs to be inserted:
|
||||
*
|
||||
* gl_Position = ((1ull << gl_ViewIndex) & view_mask) ? gl_Position : vec4(0.);
|
||||
*
|
||||
* Scan backwards until we find the gl_Position write (there should only be
|
||||
* one).
|
||||
*/
|
||||
static bool
|
||||
lower_multiview_mask(nir_function_impl *impl, uint32_t mask)
|
||||
{
|
||||
nir_builder b;
|
||||
nir_builder_init(&b, impl);
|
||||
|
||||
nir_foreach_block_reverse(block, impl) {
|
||||
nir_foreach_instr_reverse(instr, block) {
|
||||
if (instr->type != nir_instr_type_intrinsic)
|
||||
continue;
|
||||
|
||||
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
|
||||
if (intrin->intrinsic != nir_intrinsic_store_deref)
|
||||
continue;
|
||||
|
||||
nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
|
||||
if (deref->mode != nir_var_shader_out)
|
||||
continue;
|
||||
|
||||
nir_variable *var = nir_deref_instr_get_variable(deref);
|
||||
if (var->data.location != VARYING_SLOT_POS)
|
||||
continue;
|
||||
|
||||
assert(intrin->src[1].is_ssa);
|
||||
nir_ssa_def *orig_src = intrin->src[1].ssa;
|
||||
b.cursor = nir_before_instr(instr);
|
||||
|
||||
/* ((1ull << gl_ViewIndex) & mask) != 0 */
|
||||
nir_ssa_def *cmp =
|
||||
nir_i2b(&b, nir_iand(&b, nir_imm_int(&b, mask),
|
||||
nir_ishl(&b, nir_imm_int(&b, 1),
|
||||
nir_load_view_index(&b))));
|
||||
|
||||
nir_ssa_def *src = nir_bcsel(&b, cmp, orig_src, nir_imm_float(&b, 0.));
|
||||
nir_instr_rewrite_src(instr, &intrin->src[1], nir_src_for_ssa(src));
|
||||
|
||||
nir_metadata_preserve(impl, nir_metadata_block_index |
|
||||
nir_metadata_dominance);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
nir_metadata_preserve(impl, nir_metadata_all);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
tu_nir_lower_multiview(nir_shader *nir, uint32_t mask, struct tu_device *dev)
|
||||
{
|
||||
nir_function_impl *entrypoint = nir_shader_get_entrypoint(nir);
|
||||
|
||||
if (!dev->physical_device->supports_multiview_mask &&
|
||||
!util_is_power_of_two_or_zero(mask + 1)) {
|
||||
return lower_multiview_mask(entrypoint, mask);
|
||||
}
|
||||
|
||||
nir_metadata_preserve(entrypoint, nir_metadata_all);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -200,6 +200,7 @@ struct tu_physical_device
|
|||
/* gmem store/load granularity */
|
||||
#define GMEM_ALIGN_W 16
|
||||
#define GMEM_ALIGN_H 4
|
||||
bool supports_multiview_mask;
|
||||
|
||||
struct {
|
||||
uint32_t PC_UNKNOWN_9805;
|
||||
|
|
@ -1078,6 +1079,9 @@ struct tu_shader
|
|||
uint8_t active_desc_sets;
|
||||
};
|
||||
|
||||
bool
|
||||
tu_nir_lower_multiview(nir_shader *nir, uint32_t mask, struct tu_device *dev);
|
||||
|
||||
struct tu_shader *
|
||||
tu_shader_create(struct tu_device *dev,
|
||||
gl_shader_stage stage,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue