From 279403d1746ef3a983cc343a19ea32cee373a5c2 Mon Sep 17 00:00:00 2001 From: Emma Anholt Date: Tue, 16 May 2023 15:03:44 -0700 Subject: [PATCH] mesa: Move ARB_vp position invariant option handling to NIR. Reviewed-by: Alyssa Rosenzweig Reviewed-by: Erik Faye-Lund Part-of: --- src/mesa/main/tests/disable_windows_include.c | 1 - src/mesa/meson.build | 3 +- src/mesa/program/arbprogparse.c | 1 - src/mesa/program/prog_to_nir.c | 7 + src/mesa/program/programopt.c | 223 ------------------ src/mesa/program/programopt.h | 47 ---- src/mesa/state_tracker/st_nir.h | 2 + .../st_nir_lower_position_invariant.c | 58 +++++ src/mesa/state_tracker/st_program.c | 5 - 9 files changed, 68 insertions(+), 279 deletions(-) delete mode 100644 src/mesa/program/programopt.c delete mode 100644 src/mesa/program/programopt.h create mode 100644 src/mesa/state_tracker/st_nir_lower_position_invariant.c diff --git a/src/mesa/main/tests/disable_windows_include.c b/src/mesa/main/tests/disable_windows_include.c index 46415e70049..e90a63eea32 100644 --- a/src/mesa/main/tests/disable_windows_include.c +++ b/src/mesa/main/tests/disable_windows_include.c @@ -140,7 +140,6 @@ #include #include #include -#include #include #include #include diff --git a/src/mesa/meson.build b/src/mesa/meson.build index 8633b8cfb42..b864f53414e 100644 --- a/src/mesa/meson.build +++ b/src/mesa/meson.build @@ -282,8 +282,6 @@ files_libmesa = files( 'program/program.h', 'program/program_parse_extra.c', 'program/program_parser.h', - 'program/programopt.c', - 'program/programopt.h', 'program/symbol_table.c', 'program/symbol_table.h', 'state_tracker/st_atifs_to_nir.c', @@ -359,6 +357,7 @@ files_libmesa = files( 'state_tracker/st_nir_builtins.c', 'state_tracker/st_nir_lower_builtin.c', 'state_tracker/st_nir_lower_fog.c', + 'state_tracker/st_nir_lower_position_invariant.c', 'state_tracker/st_nir_lower_tex_src_plane.c', 'state_tracker/st_pbo.c', 'state_tracker/st_pbo_compute.c', diff --git a/src/mesa/program/arbprogparse.c b/src/mesa/program/arbprogparse.c index 26c3ec69ad7..30f940c7641 100644 --- a/src/mesa/program/arbprogparse.c +++ b/src/mesa/program/arbprogparse.c @@ -56,7 +56,6 @@ having three separate program parameter arrays. #include "main/context.h" #include "arbprogparse.h" -#include "programopt.h" #include "prog_parameter.h" #include "prog_statevars.h" #include "prog_instruction.h" diff --git a/src/mesa/program/prog_to_nir.c b/src/mesa/program/prog_to_nir.c index 14d9995dcc8..a254ef58a45 100644 --- a/src/mesa/program/prog_to_nir.c +++ b/src/mesa/program/prog_to_nir.c @@ -1032,6 +1032,13 @@ prog_to_nir(const struct gl_context *ctx, const struct gl_program *prog, s->info.io_lowered = false; s->info.internal = false; + /* ARB_vp: */ + if (prog->arb.IsPositionInvariant) { + NIR_PASS_V(s, st_nir_lower_position_invariant, + ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS, + prog->Parameters); + } + /* Add OPTION ARB_fog_exp code */ if (prog->arb.Fog) NIR_PASS_V(s, st_nir_lower_fog, prog->arb.Fog, prog->Parameters); diff --git a/src/mesa/program/programopt.c b/src/mesa/program/programopt.c deleted file mode 100644 index ba390d5c282..00000000000 --- a/src/mesa/program/programopt.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * \file programopt.c - * Vertex/Fragment program optimizations and transformations for program - * options, etc. - * - * \author Brian Paul - */ - - -#include "util/glheader.h" -#include "main/context.h" -#include "prog_parameter.h" -#include "prog_statevars.h" -#include "program.h" -#include "programopt.h" -#include "prog_instruction.h" - - -/** - * This function inserts instructions for coordinate modelview * projection - * into a vertex program. - * May be used to implement the position_invariant option. - */ -static void -insert_mvp_dp4_code(struct gl_context *ctx, struct gl_program *vprog) -{ - struct prog_instruction *newInst; - const GLuint origLen = vprog->arb.NumInstructions; - const GLuint newLen = origLen + 4; - GLuint i; - - /* - * Setup state references for the modelview/projection matrix. - * XXX we should check if these state vars are already declared. - */ - static const gl_state_index16 mvpState[4][STATE_LENGTH] = { - { STATE_MVP_MATRIX, 0, 0, 0 }, /* state.matrix.mvp.row[0] */ - { STATE_MVP_MATRIX, 0, 1, 1 }, /* state.matrix.mvp.row[1] */ - { STATE_MVP_MATRIX, 0, 2, 2 }, /* state.matrix.mvp.row[2] */ - { STATE_MVP_MATRIX, 0, 3, 3 }, /* state.matrix.mvp.row[3] */ - }; - GLint mvpRef[4]; - - for (i = 0; i < 4; i++) { - mvpRef[i] = _mesa_add_state_reference(vprog->Parameters, mvpState[i]); - } - - /* Alloc storage for new instructions */ - newInst = rzalloc_array(vprog, struct prog_instruction, newLen); - if (!newInst) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, - "glProgramString(inserting position_invariant code)"); - return; - } - - /* - * Generated instructions: - * newInst[0] = DP4 result.position.x, mvp.row[0], vertex.position; - * newInst[1] = DP4 result.position.y, mvp.row[1], vertex.position; - * newInst[2] = DP4 result.position.z, mvp.row[2], vertex.position; - * newInst[3] = DP4 result.position.w, mvp.row[3], vertex.position; - */ - _mesa_init_instructions(newInst, 4); - for (i = 0; i < 4; i++) { - newInst[i].Opcode = OPCODE_DP4; - newInst[i].DstReg.File = PROGRAM_OUTPUT; - newInst[i].DstReg.Index = VARYING_SLOT_POS; - newInst[i].DstReg.WriteMask = (WRITEMASK_X << i); - newInst[i].SrcReg[0].File = PROGRAM_STATE_VAR; - newInst[i].SrcReg[0].Index = mvpRef[i]; - newInst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP; - newInst[i].SrcReg[1].File = PROGRAM_INPUT; - newInst[i].SrcReg[1].Index = VERT_ATTRIB_POS; - newInst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP; - } - - /* Append original instructions after new instructions */ - _mesa_copy_instructions (newInst + 4, vprog->arb.Instructions, origLen); - - /* free old instructions */ - ralloc_free(vprog->arb.Instructions); - - /* install new instructions */ - vprog->arb.Instructions = newInst; - vprog->arb.NumInstructions = newLen; - vprog->info.inputs_read |= VERT_BIT_POS; - vprog->info.outputs_written |= BITFIELD64_BIT(VARYING_SLOT_POS); -} - - -static void -insert_mvp_mad_code(struct gl_context *ctx, struct gl_program *vprog) -{ - struct prog_instruction *newInst; - const GLuint origLen = vprog->arb.NumInstructions; - const GLuint newLen = origLen + 4; - GLuint hposTemp; - GLuint i; - - /* - * Setup state references for the modelview/projection matrix. - * XXX we should check if these state vars are already declared. - */ - static const gl_state_index16 mvpState[4][STATE_LENGTH] = { - { STATE_MVP_MATRIX_TRANSPOSE, 0, 0, 0 }, - { STATE_MVP_MATRIX_TRANSPOSE, 0, 1, 1 }, - { STATE_MVP_MATRIX_TRANSPOSE, 0, 2, 2 }, - { STATE_MVP_MATRIX_TRANSPOSE, 0, 3, 3 }, - }; - GLint mvpRef[4]; - - for (i = 0; i < 4; i++) { - mvpRef[i] = _mesa_add_state_reference(vprog->Parameters, mvpState[i]); - } - - /* Alloc storage for new instructions */ - newInst = rzalloc_array(vprog, struct prog_instruction, newLen); - if (!newInst) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, - "glProgramString(inserting position_invariant code)"); - return; - } - - /* TEMP hposTemp; */ - hposTemp = vprog->arb.NumTemporaries++; - - /* - * Generated instructions: - * emit_op2(p, OPCODE_MUL, tmp, 0, swizzle1(src,X), mat[0]); - * emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Y), mat[1], tmp); - * emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Z), mat[2], tmp); - * emit_op3(p, OPCODE_MAD, dest, 0, swizzle1(src,W), mat[3], tmp); - */ - _mesa_init_instructions(newInst, 4); - - newInst[0].Opcode = OPCODE_MUL; - newInst[0].DstReg.File = PROGRAM_TEMPORARY; - newInst[0].DstReg.Index = hposTemp; - newInst[0].DstReg.WriteMask = WRITEMASK_XYZW; - newInst[0].SrcReg[0].File = PROGRAM_INPUT; - newInst[0].SrcReg[0].Index = VERT_ATTRIB_POS; - newInst[0].SrcReg[0].Swizzle = SWIZZLE_XXXX; - newInst[0].SrcReg[1].File = PROGRAM_STATE_VAR; - newInst[0].SrcReg[1].Index = mvpRef[0]; - newInst[0].SrcReg[1].Swizzle = SWIZZLE_NOOP; - - for (i = 1; i <= 2; i++) { - newInst[i].Opcode = OPCODE_MAD; - newInst[i].DstReg.File = PROGRAM_TEMPORARY; - newInst[i].DstReg.Index = hposTemp; - newInst[i].DstReg.WriteMask = WRITEMASK_XYZW; - newInst[i].SrcReg[0].File = PROGRAM_INPUT; - newInst[i].SrcReg[0].Index = VERT_ATTRIB_POS; - newInst[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(i,i,i,i); - newInst[i].SrcReg[1].File = PROGRAM_STATE_VAR; - newInst[i].SrcReg[1].Index = mvpRef[i]; - newInst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP; - newInst[i].SrcReg[2].File = PROGRAM_TEMPORARY; - newInst[i].SrcReg[2].Index = hposTemp; - newInst[1].SrcReg[2].Swizzle = SWIZZLE_NOOP; - } - - newInst[3].Opcode = OPCODE_MAD; - newInst[3].DstReg.File = PROGRAM_OUTPUT; - newInst[3].DstReg.Index = VARYING_SLOT_POS; - newInst[3].DstReg.WriteMask = WRITEMASK_XYZW; - newInst[3].SrcReg[0].File = PROGRAM_INPUT; - newInst[3].SrcReg[0].Index = VERT_ATTRIB_POS; - newInst[3].SrcReg[0].Swizzle = SWIZZLE_WWWW; - newInst[3].SrcReg[1].File = PROGRAM_STATE_VAR; - newInst[3].SrcReg[1].Index = mvpRef[3]; - newInst[3].SrcReg[1].Swizzle = SWIZZLE_NOOP; - newInst[3].SrcReg[2].File = PROGRAM_TEMPORARY; - newInst[3].SrcReg[2].Index = hposTemp; - newInst[3].SrcReg[2].Swizzle = SWIZZLE_NOOP; - - - /* Append original instructions after new instructions */ - _mesa_copy_instructions (newInst + 4, vprog->arb.Instructions, origLen); - - /* free old instructions */ - ralloc_free(vprog->arb.Instructions); - - /* install new instructions */ - vprog->arb.Instructions = newInst; - vprog->arb.NumInstructions = newLen; - vprog->info.inputs_read |= VERT_BIT_POS; - vprog->info.outputs_written |= BITFIELD64_BIT(VARYING_SLOT_POS); -} - - -void -_mesa_insert_mvp_code(struct gl_context *ctx, struct gl_program *vprog) -{ - if (ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS) - insert_mvp_dp4_code( ctx, vprog ); - else - insert_mvp_mad_code( ctx, vprog ); -} diff --git a/src/mesa/program/programopt.h b/src/mesa/program/programopt.h deleted file mode 100644 index cfd08a593fa..00000000000 --- a/src/mesa/program/programopt.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef PROGRAMOPT_H -#define PROGRAMOPT_H 1 - -#include "util/glheader.h" -#include "prog_parameter.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -struct gl_context; -struct gl_program; - -extern void -_mesa_insert_mvp_code(struct gl_context *ctx, struct gl_program *vprog); - -#ifdef __cplusplus -} -#endif - -#endif /* PROGRAMOPT_H */ diff --git a/src/mesa/state_tracker/st_nir.h b/src/mesa/state_tracker/st_nir.h index f1e3e52a255..4d590732b07 100644 --- a/src/mesa/state_tracker/st_nir.h +++ b/src/mesa/state_tracker/st_nir.h @@ -89,6 +89,8 @@ st_nir_state_variable_create(struct nir_shader *shader, bool st_nir_lower_fog(struct nir_shader *s, enum gl_fog_mode fog_mode, struct gl_program_parameter_list *paramList); +bool st_nir_lower_position_invariant(struct nir_shader *s, bool aos, + struct gl_program_parameter_list *paramList); #ifdef __cplusplus } diff --git a/src/mesa/state_tracker/st_nir_lower_position_invariant.c b/src/mesa/state_tracker/st_nir_lower_position_invariant.c new file mode 100644 index 00000000000..dd8568f90bb --- /dev/null +++ b/src/mesa/state_tracker/st_nir_lower_position_invariant.c @@ -0,0 +1,58 @@ +/* + * Copyright © 2023 Google LLC + * SPDX-License-Identifier: MIT + */ + +#include "nir_builder.h" +#include "nir_builtin_builder.h" +#include "st_nir.h" + +/** + * Emits the implicit "gl_Position = gl_ModelViewProjection * gl_Vertex" for + * ARB_vertex_program's ARB_position_invariant option, which must match the + * behavior of the fixed function vertex shader. + * + * The "aos" flag is + * ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS, used by + * both FF VS and ARB_vp. + */ +bool +st_nir_lower_position_invariant(struct nir_shader *s, bool aos, + struct gl_program_parameter_list *paramList) +{ + nir_builder b; + nir_builder_init(&b, nir_shader_get_entrypoint(s)); + b.cursor = nir_before_block(nir_start_block(b.impl)); + + nir_ssa_def *mvp[4]; + for (int i = 0; i < 4; i++) { + gl_state_index16 tokens[STATE_LENGTH] = { + aos ? STATE_MVP_MATRIX : STATE_MVP_MATRIX_TRANSPOSE, 0, i, i}; + nir_variable *var = st_nir_state_variable_create(s, glsl_vec4_type(), tokens); + _mesa_add_state_reference(paramList, tokens); + mvp[i] = nir_load_var(&b, var); + } + + nir_ssa_def *result; + nir_ssa_def *in_pos = nir_load_var(&b, nir_get_variable_with_location(s, nir_var_shader_in, + VERT_ATTRIB_POS, glsl_vec4_type())); + s->info.inputs_read |= VERT_BIT_POS; + if (aos) { + nir_ssa_def *chans[4]; + for (int i = 0; i < 4; i++) + chans[i] = nir_fdot4(&b, mvp[i], in_pos); + result = nir_vec4(&b, chans[0], chans[1], chans[2], chans[3]); + } else { + result = nir_fmul(&b, mvp[0], nir_channel(&b, in_pos, 0)); + for (int i = 1; i < 4; i++) + result = nir_fmad(&b, mvp[i], nir_channel(&b, in_pos, i), result); + } + nir_store_var(&b, nir_get_variable_with_location(s, nir_var_shader_out, + VARYING_SLOT_POS, glsl_vec4_type()), result, 0xf); + s->info.outputs_written |= VARYING_BIT_POS; + + nir_metadata_preserve(b.impl, nir_metadata_block_index | + nir_metadata_dominance); + + return true; +} diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 079b57b3a25..5a6d4cced53 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -38,7 +38,6 @@ #include "program/prog_parameter.h" #include "program/prog_print.h" #include "program/prog_to_nir.h" -#include "program/programopt.h" #include "compiler/glsl/gl_nir.h" #include "compiler/glsl/gl_nir_linker.h" @@ -585,10 +584,6 @@ static bool st_translate_vertex_program(struct st_context *st, struct gl_program *prog) { - /* ARB_vp: */ - if (prog->arb.IsPositionInvariant) - _mesa_insert_mvp_code(st->ctx, prog); - /* This determines which states will be updated when the assembly * shader is bound. */