mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-26 13:30:39 +01:00
tu: Implement multiview pipeline state
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5720>
This commit is contained in:
parent
c884afc6f7
commit
c0c7dbd103
4 changed files with 70 additions and 18 deletions
|
|
@ -860,7 +860,6 @@ tu6_init_hw(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
|
||||||
tu_cs_emit_write_reg(cs, REG_A6XX_PC_UNKNOWN_9980, 0);
|
tu_cs_emit_write_reg(cs, REG_A6XX_PC_UNKNOWN_9980, 0);
|
||||||
|
|
||||||
tu_cs_emit_write_reg(cs, REG_A6XX_PC_PRIMITIVE_CNTL_6, 0);
|
tu_cs_emit_write_reg(cs, REG_A6XX_PC_PRIMITIVE_CNTL_6, 0);
|
||||||
tu_cs_emit_write_reg(cs, REG_A6XX_PC_MULTIVIEW_CNTL, 0);
|
|
||||||
|
|
||||||
tu_cs_emit_write_reg(cs, REG_A6XX_SP_UNKNOWN_A81B, 0);
|
tu_cs_emit_write_reg(cs, REG_A6XX_SP_UNKNOWN_A81B, 0);
|
||||||
|
|
||||||
|
|
@ -878,8 +877,6 @@ tu6_init_hw(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
|
||||||
|
|
||||||
tu_cs_emit_write_reg(cs, REG_A6XX_VFD_MODE_CNTL, 0x00000000);
|
tu_cs_emit_write_reg(cs, REG_A6XX_VFD_MODE_CNTL, 0x00000000);
|
||||||
|
|
||||||
tu_cs_emit_write_reg(cs, REG_A6XX_VFD_MULTIVIEW_CNTL, 0);
|
|
||||||
|
|
||||||
tu_cs_emit_write_reg(cs, REG_A6XX_PC_MODE_CNTL, 0x0000001f);
|
tu_cs_emit_write_reg(cs, REG_A6XX_PC_MODE_CNTL, 0x0000001f);
|
||||||
|
|
||||||
/* we don't use this yet.. probably best to disable.. */
|
/* we don't use this yet.. probably best to disable.. */
|
||||||
|
|
|
||||||
|
|
@ -264,6 +264,7 @@ struct tu_pipeline_builder
|
||||||
VkFormat color_attachment_formats[MAX_RTS];
|
VkFormat color_attachment_formats[MAX_RTS];
|
||||||
VkFormat depth_attachment_format;
|
VkFormat depth_attachment_format;
|
||||||
uint32_t render_components;
|
uint32_t render_components;
|
||||||
|
uint32_t multiview_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
@ -529,11 +530,18 @@ tu6_emit_vs_system_values(struct tu_cs *cs,
|
||||||
ir3_find_sysval_regid(gs, SYSTEM_VALUE_GS_HEADER_IR3) :
|
ir3_find_sysval_regid(gs, SYSTEM_VALUE_GS_HEADER_IR3) :
|
||||||
regid(63, 0);
|
regid(63, 0);
|
||||||
|
|
||||||
|
/* Note: we currently don't support multiview with tess or GS. If we did,
|
||||||
|
* and the HW actually works, then we'd have to somehow share this across
|
||||||
|
* stages. Note that the blob doesn't support this either.
|
||||||
|
*/
|
||||||
|
const uint32_t viewid_regid =
|
||||||
|
ir3_find_sysval_regid(vs, SYSTEM_VALUE_VIEW_INDEX);
|
||||||
|
|
||||||
tu_cs_emit_pkt4(cs, REG_A6XX_VFD_CONTROL_1, 6);
|
tu_cs_emit_pkt4(cs, REG_A6XX_VFD_CONTROL_1, 6);
|
||||||
tu_cs_emit(cs, A6XX_VFD_CONTROL_1_REGID4VTX(vertexid_regid) |
|
tu_cs_emit(cs, A6XX_VFD_CONTROL_1_REGID4VTX(vertexid_regid) |
|
||||||
A6XX_VFD_CONTROL_1_REGID4INST(instanceid_regid) |
|
A6XX_VFD_CONTROL_1_REGID4INST(instanceid_regid) |
|
||||||
A6XX_VFD_CONTROL_1_REGID4PRIMID(primitiveid_regid) |
|
A6XX_VFD_CONTROL_1_REGID4PRIMID(primitiveid_regid) |
|
||||||
0xfc000000);
|
A6XX_VFD_CONTROL_1_REGID4VIEWID(viewid_regid));
|
||||||
tu_cs_emit(cs, A6XX_VFD_CONTROL_2_REGID_HSPATCHID(hs_patch_regid) |
|
tu_cs_emit(cs, A6XX_VFD_CONTROL_2_REGID_HSPATCHID(hs_patch_regid) |
|
||||||
A6XX_VFD_CONTROL_2_REGID_INVOCATIONID(hs_invocation_regid));
|
A6XX_VFD_CONTROL_2_REGID_INVOCATIONID(hs_invocation_regid));
|
||||||
tu_cs_emit(cs, A6XX_VFD_CONTROL_3_REGID_DSPATCHID(ds_patch_regid) |
|
tu_cs_emit(cs, A6XX_VFD_CONTROL_3_REGID_DSPATCHID(ds_patch_regid) |
|
||||||
|
|
@ -905,7 +913,7 @@ tu6_emit_vpc(struct tu_cs *cs,
|
||||||
tu_cs_emit(cs, A6XX_VPC_CNTL_0_NUMNONPOSVAR(fs ? fs->total_in : 0) |
|
tu_cs_emit(cs, A6XX_VPC_CNTL_0_NUMNONPOSVAR(fs ? fs->total_in : 0) |
|
||||||
COND(fs && fs->total_in, A6XX_VPC_CNTL_0_VARYING) |
|
COND(fs && fs->total_in, A6XX_VPC_CNTL_0_VARYING) |
|
||||||
A6XX_VPC_CNTL_0_PRIMIDLOC(linkage.primid_loc) |
|
A6XX_VPC_CNTL_0_PRIMIDLOC(linkage.primid_loc) |
|
||||||
A6XX_VPC_CNTL_0_VIEWIDLOC(0xff));
|
A6XX_VPC_CNTL_0_VIEWIDLOC(linkage.viewid_loc));
|
||||||
|
|
||||||
if (hs) {
|
if (hs) {
|
||||||
shader_info *hs_info = &hs->shader->nir->info;
|
shader_info *hs_info = &hs->shader->nir->info;
|
||||||
|
|
@ -1010,9 +1018,6 @@ tu6_emit_vpc(struct tu_cs *cs,
|
||||||
tu_cs_emit_pkt4(cs, REG_A6XX_PC_PRIMITIVE_CNTL_6, 1);
|
tu_cs_emit_pkt4(cs, REG_A6XX_PC_PRIMITIVE_CNTL_6, 1);
|
||||||
tu_cs_emit(cs, A6XX_PC_PRIMITIVE_CNTL_6_STRIDE_IN_VPC(vec4_size));
|
tu_cs_emit(cs, A6XX_PC_PRIMITIVE_CNTL_6_STRIDE_IN_VPC(vec4_size));
|
||||||
|
|
||||||
tu_cs_emit_pkt4(cs, REG_A6XX_PC_MULTIVIEW_CNTL, 1);
|
|
||||||
tu_cs_emit(cs, 0);
|
|
||||||
|
|
||||||
tu_cs_emit_pkt4(cs, REG_A6XX_SP_GS_PRIM_SIZE, 1);
|
tu_cs_emit_pkt4(cs, REG_A6XX_SP_GS_PRIM_SIZE, 1);
|
||||||
tu_cs_emit(cs, vs->output_size);
|
tu_cs_emit(cs, vs->output_size);
|
||||||
}
|
}
|
||||||
|
|
@ -1413,6 +1418,33 @@ tu6_emit_program(struct tu_cs *cs,
|
||||||
tu6_emit_xs_config(cs, stage, xs, builder->shader_iova[stage]);
|
tu6_emit_xs_config(cs, stage, xs, builder->shader_iova[stage]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!binning_pass) {
|
||||||
|
uint32_t multiview_views = util_logbase2(builder->multiview_mask) + 1;
|
||||||
|
uint32_t multiview_cntl = builder->multiview_mask ?
|
||||||
|
A6XX_PC_MULTIVIEW_CNTL_ENABLE |
|
||||||
|
A6XX_PC_MULTIVIEW_CNTL_VIEWS(multiview_views) |
|
||||||
|
A6XX_PC_MULTIVIEW_CNTL_DISABLEMULTIPOS /* TODO multi-pos output */
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
/* Copy what the blob does here. This will emit an extra 0x3f
|
||||||
|
* CP_EVENT_WRITE when multiview is disabled. I'm not exactly sure what
|
||||||
|
* this is working around yet.
|
||||||
|
*/
|
||||||
|
tu_cs_emit_pkt7(cs, CP_REG_WRITE, 3);
|
||||||
|
tu_cs_emit(cs, CP_REG_WRITE_0_TRACKER(UNK_EVENT_WRITE));
|
||||||
|
tu_cs_emit(cs, REG_A6XX_PC_MULTIVIEW_CNTL);
|
||||||
|
tu_cs_emit(cs, multiview_cntl);
|
||||||
|
|
||||||
|
tu_cs_emit_pkt4(cs, REG_A6XX_VFD_MULTIVIEW_CNTL, 1);
|
||||||
|
tu_cs_emit(cs, multiview_cntl);
|
||||||
|
|
||||||
|
if (multiview_cntl &&
|
||||||
|
builder->device->physical_device->supports_multiview_mask) {
|
||||||
|
tu_cs_emit_pkt4(cs, REG_A6XX_PC_MULTIVIEW_MASK, 1);
|
||||||
|
tu_cs_emit(cs, builder->multiview_mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tu_cs_emit_pkt4(cs, REG_A6XX_SP_HS_UNKNOWN_A831, 1);
|
tu_cs_emit_pkt4(cs, REG_A6XX_SP_HS_UNKNOWN_A831, 1);
|
||||||
tu_cs_emit(cs, 0);
|
tu_cs_emit(cs, 0);
|
||||||
|
|
||||||
|
|
@ -1655,7 +1687,8 @@ tu6_emit_sample_locations(struct tu_cs *cs, const VkSampleLocationsInfoEXT *samp
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
tu6_gras_su_cntl(const VkPipelineRasterizationStateCreateInfo *rast_info,
|
tu6_gras_su_cntl(const VkPipelineRasterizationStateCreateInfo *rast_info,
|
||||||
VkSampleCountFlagBits samples)
|
VkSampleCountFlagBits samples,
|
||||||
|
bool multiview)
|
||||||
{
|
{
|
||||||
uint32_t gras_su_cntl = 0;
|
uint32_t gras_su_cntl = 0;
|
||||||
|
|
||||||
|
|
@ -1675,6 +1708,12 @@ tu6_gras_su_cntl(const VkPipelineRasterizationStateCreateInfo *rast_info,
|
||||||
if (samples > VK_SAMPLE_COUNT_1_BIT)
|
if (samples > VK_SAMPLE_COUNT_1_BIT)
|
||||||
gras_su_cntl |= A6XX_GRAS_SU_CNTL_MSAA_ENABLE;
|
gras_su_cntl |= A6XX_GRAS_SU_CNTL_MSAA_ENABLE;
|
||||||
|
|
||||||
|
if (multiview) {
|
||||||
|
gras_su_cntl |=
|
||||||
|
A6XX_GRAS_SU_CNTL_UNK17 |
|
||||||
|
A6XX_GRAS_SU_CNTL_MULTIVIEW_ENABLE;
|
||||||
|
}
|
||||||
|
|
||||||
return gras_su_cntl;
|
return gras_su_cntl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1984,8 +2023,8 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
struct tu_shader *shader =
|
struct tu_shader *shader =
|
||||||
tu_shader_create(builder->device, stage, stage_info, builder->layout,
|
tu_shader_create(builder->device, stage, stage_info, builder->multiview_mask,
|
||||||
builder->alloc);
|
builder->layout, builder->alloc);
|
||||||
if (!shader)
|
if (!shader)
|
||||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||||
|
|
||||||
|
|
@ -2267,7 +2306,7 @@ tu_pipeline_builder_parse_rasterization(struct tu_pipeline_builder *builder,
|
||||||
A6XX_GRAS_SU_POINT_SIZE(1.0f));
|
A6XX_GRAS_SU_POINT_SIZE(1.0f));
|
||||||
|
|
||||||
pipeline->gras_su_cntl =
|
pipeline->gras_su_cntl =
|
||||||
tu6_gras_su_cntl(rast_info, builder->samples);
|
tu6_gras_su_cntl(rast_info, builder->samples, builder->multiview_mask != 0);
|
||||||
|
|
||||||
if (tu_pipeline_static_state(pipeline, &cs, VK_DYNAMIC_STATE_LINE_WIDTH, 2)) {
|
if (tu_pipeline_static_state(pipeline, &cs, VK_DYNAMIC_STATE_LINE_WIDTH, 2)) {
|
||||||
pipeline->gras_su_cntl |=
|
pipeline->gras_su_cntl |=
|
||||||
|
|
@ -2488,6 +2527,13 @@ tu_pipeline_builder_init_graphics(
|
||||||
.layout = layout,
|
.layout = layout,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const struct tu_render_pass *pass =
|
||||||
|
tu_render_pass_from_handle(create_info->renderPass);
|
||||||
|
const struct tu_subpass *subpass =
|
||||||
|
&pass->subpasses[create_info->subpass];
|
||||||
|
|
||||||
|
builder->multiview_mask = subpass->multiview_mask;
|
||||||
|
|
||||||
builder->rasterizer_discard =
|
builder->rasterizer_discard =
|
||||||
create_info->pRasterizationState->rasterizerDiscardEnable;
|
create_info->pRasterizationState->rasterizerDiscardEnable;
|
||||||
|
|
||||||
|
|
@ -2496,11 +2542,6 @@ tu_pipeline_builder_init_graphics(
|
||||||
} else {
|
} else {
|
||||||
builder->samples = create_info->pMultisampleState->rasterizationSamples;
|
builder->samples = create_info->pMultisampleState->rasterizationSamples;
|
||||||
|
|
||||||
const struct tu_render_pass *pass =
|
|
||||||
tu_render_pass_from_handle(create_info->renderPass);
|
|
||||||
const struct tu_subpass *subpass =
|
|
||||||
&pass->subpasses[create_info->subpass];
|
|
||||||
|
|
||||||
const uint32_t a = subpass->depth_stencil_attachment.attachment;
|
const uint32_t a = subpass->depth_stencil_attachment.attachment;
|
||||||
builder->depth_attachment_format = (a != VK_ATTACHMENT_UNUSED) ?
|
builder->depth_attachment_format = (a != VK_ATTACHMENT_UNUSED) ?
|
||||||
pass->attachments[a].format : VK_FORMAT_UNDEFINED;
|
pass->attachments[a].format : VK_FORMAT_UNDEFINED;
|
||||||
|
|
@ -2603,7 +2644,7 @@ tu_compute_pipeline_create(VkDevice device,
|
||||||
struct ir3_shader_key key = {};
|
struct ir3_shader_key key = {};
|
||||||
|
|
||||||
struct tu_shader *shader =
|
struct tu_shader *shader =
|
||||||
tu_shader_create(dev, MESA_SHADER_COMPUTE, stage_info, layout, pAllocator);
|
tu_shader_create(dev, MESA_SHADER_COMPUTE, stage_info, 0, layout, pAllocator);
|
||||||
if (!shader) {
|
if (!shader) {
|
||||||
result = VK_ERROR_OUT_OF_HOST_MEMORY;
|
result = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
||||||
|
|
@ -1086,6 +1086,7 @@ struct tu_shader *
|
||||||
tu_shader_create(struct tu_device *dev,
|
tu_shader_create(struct tu_device *dev,
|
||||||
gl_shader_stage stage,
|
gl_shader_stage stage,
|
||||||
const VkPipelineShaderStageCreateInfo *stage_info,
|
const VkPipelineShaderStageCreateInfo *stage_info,
|
||||||
|
unsigned multiview_mask,
|
||||||
struct tu_pipeline_layout *layout,
|
struct tu_pipeline_layout *layout,
|
||||||
const VkAllocationCallbacks *alloc);
|
const VkAllocationCallbacks *alloc);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,8 @@ tu_spirv_to_nir(struct ir3_compiler *compiler,
|
||||||
/* Accessed via stg/ldg (not used with Vulkan?) */
|
/* Accessed via stg/ldg (not used with Vulkan?) */
|
||||||
.global_addr_format = nir_address_format_64bit_global,
|
.global_addr_format = nir_address_format_64bit_global,
|
||||||
|
|
||||||
|
/* ViewID is a sysval in geometry stages and an input in the FS */
|
||||||
|
.view_index_is_input = stage == MESA_SHADER_FRAGMENT,
|
||||||
.caps = {
|
.caps = {
|
||||||
.transform_feedback = true,
|
.transform_feedback = true,
|
||||||
.tessellation = true,
|
.tessellation = true,
|
||||||
|
|
@ -661,6 +663,7 @@ struct tu_shader *
|
||||||
tu_shader_create(struct tu_device *dev,
|
tu_shader_create(struct tu_device *dev,
|
||||||
gl_shader_stage stage,
|
gl_shader_stage stage,
|
||||||
const VkPipelineShaderStageCreateInfo *stage_info,
|
const VkPipelineShaderStageCreateInfo *stage_info,
|
||||||
|
unsigned multiview_mask,
|
||||||
struct tu_pipeline_layout *layout,
|
struct tu_pipeline_layout *layout,
|
||||||
const VkAllocationCallbacks *alloc)
|
const VkAllocationCallbacks *alloc)
|
||||||
{
|
{
|
||||||
|
|
@ -768,9 +771,19 @@ tu_shader_create(struct tu_device *dev,
|
||||||
&(nir_input_attachment_options) {
|
&(nir_input_attachment_options) {
|
||||||
.use_fragcoord_sysval = true,
|
.use_fragcoord_sysval = true,
|
||||||
.use_layer_id_sysval = false,
|
.use_layer_id_sysval = false,
|
||||||
|
/* When using multiview rendering, we must use
|
||||||
|
* gl_ViewIndex as the layer id to pass to the texture
|
||||||
|
* sampling function. gl_Layer doesn't work when
|
||||||
|
* multiview is enabled.
|
||||||
|
*/
|
||||||
|
.use_view_id_for_layer = multiview_mask != 0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stage == MESA_SHADER_VERTEX && multiview_mask) {
|
||||||
|
NIR_PASS_V(nir, tu_nir_lower_multiview, multiview_mask, dev);
|
||||||
|
}
|
||||||
|
|
||||||
NIR_PASS_V(nir, nir_lower_explicit_io,
|
NIR_PASS_V(nir, nir_lower_explicit_io,
|
||||||
nir_var_mem_ubo | nir_var_mem_ssbo,
|
nir_var_mem_ubo | nir_var_mem_ssbo,
|
||||||
nir_address_format_vec2_index_32bit_offset);
|
nir_address_format_vec2_index_32bit_offset);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue