Mesa (master): ir3, tu: Link per-view position correctly
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Tue Sep 29 16:35:33 UTC 2020
Module: Mesa
Branch: master
Commit: 64ad5a1f7b3be382a9b6297a4a035dcaa1b36740
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=64ad5a1f7b3be382a9b6297a4a035dcaa1b36740
Author: Connor Abbott <cwabbott0 at gmail.com>
Date: Fri Aug 21 13:45:16 2020 +0200
ir3, tu: Link per-view position correctly
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6515>
---
src/freedreno/ir3/ir3_compiler_nir.c | 13 ++++++++++++-
src/freedreno/ir3/ir3_shader.h | 1 +
src/freedreno/vulkan/tu_pipeline.c | 27 ++++++++++++++++++++-------
src/freedreno/vulkan/tu_private.h | 1 +
4 files changed, 34 insertions(+), 8 deletions(-)
diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c
index 1fd4bf2b42a..b72f5bbcbe8 100644
--- a/src/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/freedreno/ir3/ir3_compiler_nir.c
@@ -3106,7 +3106,16 @@ setup_output(struct ir3_context *ctx, nir_intrinsic_instr *intr)
unsigned n = nir_intrinsic_base(intr) + offset;
unsigned frac = nir_intrinsic_component(intr);
unsigned ncomp = nir_intrinsic_src_components(intr, 0);
- unsigned slot = io.location + offset;
+
+ /* For per-view variables, each user-facing slot corresponds to multiple
+ * views, each with a corresponding driver_location, and the offset is for
+ * the driver_location. To properly figure out of the slot, we'd need to
+ * plumb through the number of views. However, for now we only use
+ * per-view with gl_Position, so we assume that the variable is not an
+ * array or matrix (so there are no indirect accesses to the variable
+ * itself) and the indirect offset corresponds to the view.
+ */
+ unsigned slot = io.location + (io.per_view ? 0 : offset);
if (ctx->so->type == MESA_SHADER_FRAGMENT) {
switch (slot) {
@@ -3172,6 +3181,8 @@ setup_output(struct ir3_context *ctx, nir_intrinsic_instr *intr)
compile_assert(ctx, so->outputs_count < ARRAY_SIZE(so->outputs));
so->outputs[n].slot = slot;
+ if (io.per_view)
+ so->outputs[n].view = offset;
for (int i = 0; i < ncomp; i++) {
unsigned idx = (n * 4) + i + frac;
diff --git a/src/freedreno/ir3/ir3_shader.h b/src/freedreno/ir3/ir3_shader.h
index 5b0ce85918b..39870066956 100644
--- a/src/freedreno/ir3/ir3_shader.h
+++ b/src/freedreno/ir3/ir3_shader.h
@@ -562,6 +562,7 @@ struct ir3_shader_variant {
struct {
uint8_t slot;
uint8_t regid;
+ uint8_t view;
bool half : 1;
} outputs[32 + 2]; /* +POSITION +PSIZE */
bool writes_pos, writes_smask, writes_psize, writes_stencilref;
diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c
index 5b6a41e6e6e..9f11c810086 100644
--- a/src/freedreno/vulkan/tu_pipeline.c
+++ b/src/freedreno/vulkan/tu_pipeline.c
@@ -825,8 +825,6 @@ tu6_emit_vpc(struct tu_cs *cs,
tu_cs_emit(cs, ~linkage.varmask[3]);
/* a6xx finds position/pointsize at the end */
- const uint32_t position_regid =
- ir3_find_output_regid(last_shader, VARYING_SLOT_POS);
const uint32_t pointsize_regid =
ir3_find_output_regid(last_shader, VARYING_SLOT_PSIZ);
const uint32_t layer_regid =
@@ -839,18 +837,31 @@ tu6_emit_vpc(struct tu_cs *cs,
ir3_find_output_regid(gs, VARYING_SLOT_GS_VERTEX_FLAGS_IR3) : 0;
uint32_t pointsize_loc = 0xff, position_loc = 0xff, layer_loc = 0xff, view_loc = 0xff;
+
if (layer_regid != regid(63, 0)) {
layer_loc = linkage.max_loc;
ir3_link_add(&linkage, layer_regid, 0x1, linkage.max_loc);
}
+
if (view_regid != regid(63, 0)) {
view_loc = linkage.max_loc;
ir3_link_add(&linkage, view_regid, 0x1, linkage.max_loc);
}
- if (position_regid != regid(63, 0)) {
- position_loc = linkage.max_loc;
- ir3_link_add(&linkage, position_regid, 0xf, linkage.max_loc);
+
+ unsigned extra_pos = 0;
+
+ for (unsigned i = 0; i < last_shader->outputs_count; i++) {
+ if (last_shader->outputs[i].slot != VARYING_SLOT_POS)
+ continue;
+
+ if (position_loc == 0xff)
+ position_loc = linkage.max_loc;
+
+ ir3_link_add(&linkage, last_shader->outputs[i].regid,
+ 0xf, position_loc + 4 * last_shader->outputs[i].view);
+ extra_pos = MAX2(extra_pos, last_shader->outputs[i].view);
}
+
if (pointsize_regid != regid(63, 0)) {
pointsize_loc = linkage.max_loc;
ir3_link_add(&linkage, pointsize_regid, 0x1, linkage.max_loc);
@@ -889,7 +900,8 @@ tu6_emit_vpc(struct tu_cs *cs,
tu_cs_emit_pkt4(cs, cfg->reg_vpc_xs_pack, 1);
tu_cs_emit(cs, A6XX_VPC_VS_PACK_POSITIONLOC(position_loc) |
A6XX_VPC_VS_PACK_PSIZELOC(pointsize_loc) |
- A6XX_VPC_VS_PACK_STRIDE_IN_VPC(linkage.max_loc));
+ A6XX_VPC_VS_PACK_STRIDE_IN_VPC(linkage.max_loc) |
+ A6XX_VPC_VS_PACK_EXTRAPOS(extra_pos));
tu_cs_emit_pkt4(cs, cfg->reg_vpc_xs_clip_cntl, 1);
tu_cs_emit(cs, 0xffff00);
@@ -1397,6 +1409,7 @@ tu6_emit_program(struct tu_cs *cs,
gl_shader_stage stage = MESA_SHADER_VERTEX;
uint32_t cps_per_patch = builder->create_info->pTessellationState ?
builder->create_info->pTessellationState->patchControlPoints : 0;
+ bool multi_pos_output = builder->shaders[MESA_SHADER_VERTEX]->multi_pos_output;
STATIC_ASSERT(MESA_SHADER_VERTEX == 0);
@@ -1430,7 +1443,7 @@ tu6_emit_program(struct tu_cs *cs,
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 */
+ COND(!multi_pos_output, A6XX_PC_MULTIVIEW_CNTL_DISABLEMULTIPOS)
: 0;
/* Copy what the blob does here. This will emit an extra 0x3f
diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h
index f018ed5abc7..37e75fc1eeb 100644
--- a/src/freedreno/vulkan/tu_private.h
+++ b/src/freedreno/vulkan/tu_private.h
@@ -1027,6 +1027,7 @@ struct tu_shader
struct tu_push_constant_range push_consts;
uint8_t active_desc_sets;
+ bool multi_pos_output;
};
bool
More information about the mesa-commit
mailing list