From beeb94402f9d33081147c88de2b9d4c4ea24e842 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 6 Jul 2018 15:48:46 -0700 Subject: [PATCH] v3d: Implement noperspective varyings on V3D 4.x. Fixes a bunch of piglit interpolation tests, and reduces my concern about some MSAA blit shaders with noperspective varyings. --- src/broadcom/cle/v3d_packet_v33.xml | 2 +- src/broadcom/compiler/nir_to_vir.c | 4 +--- src/broadcom/compiler/v3d_compiler.h | 4 ++++ src/broadcom/compiler/vir.c | 3 +++ src/gallium/drivers/v3d/v3d_context.h | 1 + src/gallium/drivers/v3d/v3d_program.c | 5 +++++ src/gallium/drivers/v3d/v3dx_emit.c | 25 +++++++++++++++++++++++++ 7 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/broadcom/cle/v3d_packet_v33.xml b/src/broadcom/cle/v3d_packet_v33.xml index f93b8245dce..eef29dab30d 100644 --- a/src/broadcom/cle/v3d_packet_v33.xml +++ b/src/broadcom/cle/v3d_packet_v33.xml @@ -668,7 +668,7 @@ - + diff --git a/src/broadcom/compiler/nir_to_vir.c b/src/broadcom/compiler/nir_to_vir.c index 89e4bc9fafa..426b41e2be8 100644 --- a/src/broadcom/compiler/nir_to_vir.c +++ b/src/broadcom/compiler/nir_to_vir.c @@ -443,9 +443,7 @@ emit_fragment_varying(struct v3d_compile *c, nir_variable *var, return vir_FADD(c, vir_FMUL(c, vary, c->payload_w), r5); } case INTERP_MODE_NOPERSPECTIVE: - /* C appears after the mov from the varying. - XXX: improve ldvary setup. - */ + BITSET_SET(c->noperspective_flags, i); return vir_FADD(c, vir_MOV(c, vary), r5); case INTERP_MODE_FLAT: BITSET_SET(c->flat_shade_flags, i); diff --git a/src/broadcom/compiler/v3d_compiler.h b/src/broadcom/compiler/v3d_compiler.h index 24af18e8f9e..f3e3875c87c 100644 --- a/src/broadcom/compiler/v3d_compiler.h +++ b/src/broadcom/compiler/v3d_compiler.h @@ -476,6 +476,8 @@ struct v3d_compile { */ uint32_t flat_shade_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)]; + uint32_t noperspective_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)]; + uint32_t centroid_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)]; bool uses_center_w; @@ -659,6 +661,8 @@ struct v3d_fs_prog_data { */ uint32_t flat_shade_flags[((V3D_MAX_FS_INPUTS - 1) / 24) + 1]; + uint32_t noperspective_flags[((V3D_MAX_FS_INPUTS - 1) / 24) + 1]; + uint32_t centroid_flags[((V3D_MAX_FS_INPUTS - 1) / 24) + 1]; bool writes_z; diff --git a/src/broadcom/compiler/vir.c b/src/broadcom/compiler/vir.c index 2754924e6c1..ee0f329040e 100644 --- a/src/broadcom/compiler/vir.c +++ b/src/broadcom/compiler/vir.c @@ -759,6 +759,9 @@ v3d_set_fs_prog_data_inputs(struct v3d_compile *c, if (BITSET_TEST(c->flat_shade_flags, i)) prog_data->flat_shade_flags[i / 24] |= 1 << (i % 24); + if (BITSET_TEST(c->noperspective_flags, i)) + prog_data->noperspective_flags[i / 24] |= 1 << (i % 24); + if (BITSET_TEST(c->centroid_flags, i)) prog_data->centroid_flags[i / 24] |= 1 << (i % 24); } diff --git a/src/gallium/drivers/v3d/v3d_context.h b/src/gallium/drivers/v3d/v3d_context.h index dea9f9f3d2c..5822ca9f7f8 100644 --- a/src/gallium/drivers/v3d/v3d_context.h +++ b/src/gallium/drivers/v3d/v3d_context.h @@ -81,6 +81,7 @@ void v3d_job_add_bo(struct v3d_job *job, struct v3d_bo *bo); #define VC5_DIRTY_STREAMOUT (1 << 27) #define VC5_DIRTY_OQ (1 << 28) #define VC5_DIRTY_CENTROID_FLAGS (1 << 29) +#define VC5_DIRTY_NOPERSPECTIVE_FLAGS (1 << 30) #define VC5_MAX_FS_INPUTS 64 diff --git a/src/gallium/drivers/v3d/v3d_program.c b/src/gallium/drivers/v3d/v3d_program.c index 93228b53c5c..85554586a6c 100644 --- a/src/gallium/drivers/v3d/v3d_program.c +++ b/src/gallium/drivers/v3d/v3d_program.c @@ -485,6 +485,11 @@ v3d_update_compiled_fs(struct v3d_context *v3d, uint8_t prim_mode) v3d->dirty |= VC5_DIRTY_FLAT_SHADE_FLAGS; } + if (v3d->prog.fs->prog_data.fs->noperspective_flags != + old_fs->prog_data.fs->noperspective_flags) { + v3d->dirty |= VC5_DIRTY_NOPERSPECTIVE_FLAGS; + } + if (v3d->prog.fs->prog_data.fs->centroid_flags != old_fs->prog_data.fs->centroid_flags) { v3d->dirty |= VC5_DIRTY_CENTROID_FLAGS; diff --git a/src/gallium/drivers/v3d/v3dx_emit.c b/src/gallium/drivers/v3d/v3dx_emit.c index 09965f68250..9c97bb6c25d 100644 --- a/src/gallium/drivers/v3d/v3dx_emit.c +++ b/src/gallium/drivers/v3d/v3dx_emit.c @@ -327,6 +327,23 @@ emit_flat_shade_flags(struct v3d_job *job, } #if V3D_VERSION >= 40 +static void +emit_noperspective_flags(struct v3d_job *job, + int varying_offset, + uint32_t varyings, + enum V3DX(Varying_Flags_Action) lower, + enum V3DX(Varying_Flags_Action) higher) +{ + cl_emit(&job->bcl, NON_PERSPECTIVE_FLAGS, flags) { + flags.varying_offset_v0 = varying_offset; + flags.non_perspective_flags_for_varyings_v024 = varyings; + flags.action_for_non_perspective_flags_of_lower_numbered_varyings = + lower; + flags.action_for_non_perspective_flags_of_higher_numbered_varyings = + higher; + } +} + static void emit_centroid_flags(struct v3d_job *job, int varying_offset, @@ -648,6 +665,14 @@ v3dX(emit_state)(struct pipe_context *pctx) } #if V3D_VERSION >= 40 + if (v3d->dirty & VC5_DIRTY_NOPERSPECTIVE_FLAGS) { + if (!emit_varying_flags(job, + v3d->prog.fs->prog_data.fs->noperspective_flags, + emit_noperspective_flags)) { + cl_emit(&job->bcl, ZERO_ALL_NON_PERSPECTIVE_FLAGS, flags); + } + } + if (v3d->dirty & VC5_DIRTY_CENTROID_FLAGS) { if (!emit_varying_flags(job, v3d->prog.fs->prog_data.fs->centroid_flags, -- 2.30.2