From 00cdc0a472c55330cbc58317f01b07f8f90be5a5 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 14 Dec 2006 15:01:06 -0700 Subject: Split the program.[ch] files into several new files. --- src/mesa/shader/prog_print.c | 464 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 464 insertions(+) create mode 100644 src/mesa/shader/prog_print.c (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c new file mode 100644 index 0000000000..eded71bbae --- /dev/null +++ b/src/mesa/shader/prog_print.c @@ -0,0 +1,464 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.3 + * + * Copyright (C) 1999-2006 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 + * BRIAN PAUL 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 prog_print.c + * Print vertex/fragment programs - for debugging. + * \author Brian Paul + */ + +#include "glheader.h" +#include "context.h" +#include "imports.h" +#include "macros.h" +#include "program.h" +#include "prog_instruction.h" +#include "prog_parameter.h" +#include "prog_print.h" +#include "prog_statevars.h" + + + +/** + * Basic info about each instruction + */ +struct instruction_info +{ + gl_inst_opcode Opcode; + const char *Name; + GLuint NumSrcRegs; +}; + +/** + * Instruction info + * \note Opcode should equal array index! + */ +static const struct instruction_info InstInfo[MAX_OPCODE] = { + { OPCODE_NOP, "NOP", 0 }, + { OPCODE_ABS, "ABS", 1 }, + { OPCODE_ADD, "ADD", 2 }, + { OPCODE_ARA, "ARA", 1 }, + { OPCODE_ARL, "ARL", 1 }, + { OPCODE_ARL_NV, "ARL", 1 }, + { OPCODE_ARR, "ARL", 1 }, + { OPCODE_BRA, "BRA", 0 }, + { OPCODE_CAL, "CAL", 0 }, + { OPCODE_CMP, "CMP", 3 }, + { OPCODE_COS, "COS", 1 }, + { OPCODE_DDX, "DDX", 1 }, + { OPCODE_DDY, "DDY", 1 }, + { OPCODE_DP3, "DP3", 2 }, + { OPCODE_DP4, "DP4", 2 }, + { OPCODE_DPH, "DPH", 2 }, + { OPCODE_DST, "DST", 2 }, + { OPCODE_END, "END", 0 }, + { OPCODE_EX2, "EX2", 1 }, + { OPCODE_EXP, "EXP", 1 }, + { OPCODE_FLR, "FLR", 1 }, + { OPCODE_FRC, "FRC", 1 }, + { OPCODE_KIL, "KIL", 1 }, + { OPCODE_KIL_NV, "KIL", 0 }, + { OPCODE_LG2, "LG2", 1 }, + { OPCODE_LIT, "LIT", 1 }, + { OPCODE_LOG, "LOG", 1 }, + { OPCODE_LRP, "LRP", 3 }, + { OPCODE_MAD, "MAD", 3 }, + { OPCODE_MAX, "MAX", 2 }, + { OPCODE_MIN, "MIN", 2 }, + { OPCODE_MOV, "MOV", 1 }, + { OPCODE_MUL, "MUL", 2 }, + { OPCODE_PK2H, "PK2H", 1 }, + { OPCODE_PK2US, "PK2US", 1 }, + { OPCODE_PK4B, "PK4B", 1 }, + { OPCODE_PK4UB, "PK4UB", 1 }, + { OPCODE_POW, "POW", 2 }, + { OPCODE_POPA, "POPA", 0 }, + { OPCODE_PRINT, "PRINT", 1 }, + { OPCODE_PUSHA, "PUSHA", 0 }, + { OPCODE_RCC, "RCC", 1 }, + { OPCODE_RCP, "RCP", 1 }, + { OPCODE_RET, "RET", 0 }, + { OPCODE_RFL, "RFL", 1 }, + { OPCODE_RSQ, "RSQ", 1 }, + { OPCODE_SCS, "SCS", 1 }, + { OPCODE_SEQ, "SEQ", 2 }, + { OPCODE_SFL, "SFL", 0 }, + { OPCODE_SGE, "SGE", 2 }, + { OPCODE_SGT, "SGT", 2 }, + { OPCODE_SIN, "SIN", 1 }, + { OPCODE_SLE, "SLE", 2 }, + { OPCODE_SLT, "SLT", 2 }, + { OPCODE_SNE, "SNE", 2 }, + { OPCODE_SSG, "SSG", 1 }, + { OPCODE_STR, "STR", 0 }, + { OPCODE_SUB, "SUB", 2 }, + { OPCODE_SWZ, "SWZ", 1 }, + { OPCODE_TEX, "TEX", 1 }, + { OPCODE_TXB, "TXB", 1 }, + { OPCODE_TXD, "TXD", 3 }, + { OPCODE_TXL, "TXL", 1 }, + { OPCODE_TXP, "TXP", 1 }, + { OPCODE_TXP_NV, "TXP", 1 }, + { OPCODE_UP2H, "UP2H", 1 }, + { OPCODE_UP2US, "UP2US", 1 }, + { OPCODE_UP4B, "UP4B", 1 }, + { OPCODE_UP4UB, "UP4UB", 1 }, + { OPCODE_X2D, "X2D", 3 }, + { OPCODE_XPD, "XPD", 2 } +}; + + +/** + * Return the number of src registers for the given instruction/opcode. + */ +GLuint +_mesa_num_inst_src_regs(gl_inst_opcode opcode) +{ + ASSERT(opcode == InstInfo[opcode].Opcode); + ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode); + return InstInfo[opcode].NumSrcRegs; +} + + +/** + * Return string name for given program opcode. + */ +const char * +_mesa_opcode_string(gl_inst_opcode opcode) +{ + ASSERT(opcode < MAX_OPCODE); + return InstInfo[opcode].Name; +} + +/** + * Return string name for given program/register file. + */ +static const char * +program_file_string(enum register_file f) +{ + switch (f) { + case PROGRAM_TEMPORARY: + return "TEMP"; + case PROGRAM_LOCAL_PARAM: + return "LOCAL"; + case PROGRAM_ENV_PARAM: + return "ENV"; + case PROGRAM_STATE_VAR: + return "STATE"; + case PROGRAM_INPUT: + return "INPUT"; + case PROGRAM_OUTPUT: + return "OUTPUT"; + case PROGRAM_NAMED_PARAM: + return "NAMED"; + case PROGRAM_CONSTANT: + return "CONST"; + case PROGRAM_UNIFORM: + return "UNIFORM"; + case PROGRAM_VARYING: + return "VARYING"; + case PROGRAM_WRITE_ONLY: + return "WRITE_ONLY"; + case PROGRAM_ADDRESS: + return "ADDR"; + default: + return "Unknown program file!"; + } +} + + +/** + * Return a string representation of the given swizzle word. + * If extended is true, use extended (comma-separated) format. + */ +static const char * +swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended) +{ + static const char swz[] = "xyzw01"; + static char s[20]; + GLuint i = 0; + + if (!extended && swizzle == SWIZZLE_NOOP && negateBase == 0) + return ""; /* no swizzle/negation */ + + if (!extended) + s[i++] = '.'; + + if (negateBase & 0x1) + s[i++] = '-'; + s[i++] = swz[GET_SWZ(swizzle, 0)]; + + if (extended) { + s[i++] = ','; + } + + if (negateBase & 0x2) + s[i++] = '-'; + s[i++] = swz[GET_SWZ(swizzle, 1)]; + + if (extended) { + s[i++] = ','; + } + + if (negateBase & 0x4) + s[i++] = '-'; + s[i++] = swz[GET_SWZ(swizzle, 2)]; + + if (extended) { + s[i++] = ','; + } + + if (negateBase & 0x8) + s[i++] = '-'; + s[i++] = swz[GET_SWZ(swizzle, 3)]; + + s[i] = 0; + return s; +} + + +static const char * +writemask_string(GLuint writeMask) +{ + static char s[10]; + GLuint i = 0; + + if (writeMask == WRITEMASK_XYZW) + return ""; + + s[i++] = '.'; + if (writeMask & WRITEMASK_X) + s[i++] = 'x'; + if (writeMask & WRITEMASK_Y) + s[i++] = 'y'; + if (writeMask & WRITEMASK_Z) + s[i++] = 'z'; + if (writeMask & WRITEMASK_W) + s[i++] = 'w'; + + s[i] = 0; + return s; +} + +static void +print_dst_reg(const struct prog_dst_register *dstReg) +{ + _mesa_printf(" %s[%d]%s", + program_file_string((enum register_file) dstReg->File), + dstReg->Index, + writemask_string(dstReg->WriteMask)); +} + +static void +print_src_reg(const struct prog_src_register *srcReg) +{ + _mesa_printf("%s[%d]%s", + program_file_string((enum register_file) srcReg->File), + srcReg->Index, + swizzle_string(srcReg->Swizzle, + srcReg->NegateBase, GL_FALSE)); +} + +static void +print_comment(const struct prog_instruction *inst) +{ + if (inst->Comment) + _mesa_printf("; # %s\n", inst->Comment); + else + _mesa_printf(";\n"); +} + + +void +_mesa_print_alu_instruction(const struct prog_instruction *inst, + const char *opcode_string, + GLuint numRegs) +{ + GLuint j; + + _mesa_printf("%s", opcode_string); + + /* frag prog only */ + if (inst->SaturateMode == SATURATE_ZERO_ONE) + _mesa_printf("_SAT"); + + if (inst->DstReg.File != PROGRAM_UNDEFINED) { + _mesa_printf(" %s[%d]%s", + program_file_string((enum register_file) inst->DstReg.File), + inst->DstReg.Index, + writemask_string(inst->DstReg.WriteMask)); + } + else { + _mesa_printf(" ???"); + } + + if (numRegs > 0) + _mesa_printf(", "); + + for (j = 0; j < numRegs; j++) { + print_src_reg(inst->SrcReg + j); + if (j + 1 < numRegs) + _mesa_printf(", "); + } + + if (inst->Comment) + _mesa_printf(" # %s", inst->Comment); + + print_comment(inst); +} + + +/** + * Print a single vertex/fragment program instruction. + */ +void +_mesa_print_instruction(const struct prog_instruction *inst) +{ + switch (inst->Opcode) { + case OPCODE_PRINT: + _mesa_printf("PRINT '%s'", inst->Data); + if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { + _mesa_printf(", "); + _mesa_printf("%s[%d]%s", + program_file_string((enum register_file) inst->SrcReg[0].File), + inst->SrcReg[0].Index, + swizzle_string(inst->SrcReg[0].Swizzle, + inst->SrcReg[0].NegateBase, GL_FALSE)); + } + if (inst->Comment) + _mesa_printf(" # %s", inst->Comment); + print_comment(inst); + break; + case OPCODE_SWZ: + _mesa_printf("SWZ"); + if (inst->SaturateMode == SATURATE_ZERO_ONE) + _mesa_printf("_SAT"); + print_dst_reg(&inst->DstReg); + _mesa_printf("%s[%d], %s", + program_file_string((enum register_file) inst->SrcReg[0].File), + inst->SrcReg[0].Index, + swizzle_string(inst->SrcReg[0].Swizzle, + inst->SrcReg[0].NegateBase, GL_TRUE)); + print_comment(inst); + break; + case OPCODE_TEX: + case OPCODE_TXP: + case OPCODE_TXB: + _mesa_printf("%s", _mesa_opcode_string(inst->Opcode)); + if (inst->SaturateMode == SATURATE_ZERO_ONE) + _mesa_printf("_SAT"); + _mesa_printf(" "); + print_dst_reg(&inst->DstReg); + _mesa_printf(", "); + print_src_reg(&inst->SrcReg[0]); + _mesa_printf(", texture[%d], ", inst->TexSrcUnit); + switch (inst->TexSrcTarget) { + case TEXTURE_1D_INDEX: _mesa_printf("1D"); break; + case TEXTURE_2D_INDEX: _mesa_printf("2D"); break; + case TEXTURE_3D_INDEX: _mesa_printf("3D"); break; + case TEXTURE_CUBE_INDEX: _mesa_printf("CUBE"); break; + case TEXTURE_RECT_INDEX: _mesa_printf("RECT"); break; + default: + ; + } + print_comment(inst); + break; + case OPCODE_ARL: + _mesa_printf("ARL addr.x, "); + print_src_reg(&inst->SrcReg[0]); + print_comment(inst); + break; + case OPCODE_BRA: + _mesa_printf("BRA %u", inst->BranchTarget); + print_comment(inst); + break; + case OPCODE_CAL: + _mesa_printf("CAL %u", inst->BranchTarget); + print_comment(inst); + break; + case OPCODE_END: + _mesa_printf("END"); + print_comment(inst); + break; + /* XXX may need other special-case instructions */ + default: + /* typical alu instruction */ + _mesa_print_alu_instruction(inst, + _mesa_opcode_string(inst->Opcode), + _mesa_num_inst_src_regs(inst->Opcode)); + break; + } +} + + +/** + * Print a vertx/fragment program to stdout. + * XXX this function could be greatly improved. + */ +void +_mesa_print_program(const struct gl_program *prog) +{ + GLuint i; + for (i = 0; i < prog->NumInstructions; i++) { + _mesa_printf("%3d: ", i); + _mesa_print_instruction(prog->Instructions + i); + } +} + + +/** + * Print all of a program's parameters. + */ +void +_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog) +{ + GLint i; + + _mesa_printf("InputsRead: 0x%x\n", prog->InputsRead); + _mesa_printf("OutputsWritten: 0x%x\n", prog->OutputsWritten); + _mesa_printf("NumInstructions=%d\n", prog->NumInstructions); + _mesa_printf("NumTemporaries=%d\n", prog->NumTemporaries); + _mesa_printf("NumParameters=%d\n", prog->NumParameters); + _mesa_printf("NumAttributes=%d\n", prog->NumAttributes); + _mesa_printf("NumAddressRegs=%d\n", prog->NumAddressRegs); + + _mesa_load_state_parameters(ctx, prog->Parameters); + +#if 0 + _mesa_printf("Local Params:\n"); + for (i = 0; i < MAX_PROGRAM_LOCAL_PARAMS; i++){ + const GLfloat *p = prog->LocalParams[i]; + _mesa_printf("%2d: %f, %f, %f, %f\n", i, p[0], p[1], p[2], p[3]); + } +#endif + + for (i = 0; i < prog->Parameters->NumParameters; i++){ + struct gl_program_parameter *param = prog->Parameters->Parameters + i; + const GLfloat *v = prog->Parameters->ParameterValues[i]; + _mesa_printf("param[%d] %s %s = {%.3f, %.3f, %.3f, %.3f};\n", + i, + program_file_string(prog->Parameters->Parameters[i].Type), + param->Name, v[0], v[1], v[2], v[3]); + } +} -- cgit v1.2.3 From 464b82b1e690b5ab690bd1673251e5b4edf69a62 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 14 Dec 2006 15:47:08 -0700 Subject: Move some code from prog_print.c to prog_instruction.c --- src/mesa/shader/prog_instruction.c | 112 +++++++++++++++++++++++++++++++++++++ src/mesa/shader/prog_print.c | 112 ------------------------------------- 2 files changed, 112 insertions(+), 112 deletions(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c index f4dae76de0..bebc3ecb69 100644 --- a/src/mesa/shader/prog_instruction.c +++ b/src/mesa/shader/prog_instruction.c @@ -97,3 +97,115 @@ _mesa_realloc_instructions(struct prog_instruction *oldInst, } + +/** + * Basic info about each instruction + */ +struct instruction_info +{ + gl_inst_opcode Opcode; + const char *Name; + GLuint NumSrcRegs; +}; + +/** + * Instruction info + * \note Opcode should equal array index! + */ +static const struct instruction_info InstInfo[MAX_OPCODE] = { + { OPCODE_NOP, "NOP", 0 }, + { OPCODE_ABS, "ABS", 1 }, + { OPCODE_ADD, "ADD", 2 }, + { OPCODE_ARA, "ARA", 1 }, + { OPCODE_ARL, "ARL", 1 }, + { OPCODE_ARL_NV, "ARL", 1 }, + { OPCODE_ARR, "ARL", 1 }, + { OPCODE_BRA, "BRA", 0 }, + { OPCODE_CAL, "CAL", 0 }, + { OPCODE_CMP, "CMP", 3 }, + { OPCODE_COS, "COS", 1 }, + { OPCODE_DDX, "DDX", 1 }, + { OPCODE_DDY, "DDY", 1 }, + { OPCODE_DP3, "DP3", 2 }, + { OPCODE_DP4, "DP4", 2 }, + { OPCODE_DPH, "DPH", 2 }, + { OPCODE_DST, "DST", 2 }, + { OPCODE_END, "END", 0 }, + { OPCODE_EX2, "EX2", 1 }, + { OPCODE_EXP, "EXP", 1 }, + { OPCODE_FLR, "FLR", 1 }, + { OPCODE_FRC, "FRC", 1 }, + { OPCODE_KIL, "KIL", 1 }, + { OPCODE_KIL_NV, "KIL", 0 }, + { OPCODE_LG2, "LG2", 1 }, + { OPCODE_LIT, "LIT", 1 }, + { OPCODE_LOG, "LOG", 1 }, + { OPCODE_LRP, "LRP", 3 }, + { OPCODE_MAD, "MAD", 3 }, + { OPCODE_MAX, "MAX", 2 }, + { OPCODE_MIN, "MIN", 2 }, + { OPCODE_MOV, "MOV", 1 }, + { OPCODE_MUL, "MUL", 2 }, + { OPCODE_PK2H, "PK2H", 1 }, + { OPCODE_PK2US, "PK2US", 1 }, + { OPCODE_PK4B, "PK4B", 1 }, + { OPCODE_PK4UB, "PK4UB", 1 }, + { OPCODE_POW, "POW", 2 }, + { OPCODE_POPA, "POPA", 0 }, + { OPCODE_PRINT, "PRINT", 1 }, + { OPCODE_PUSHA, "PUSHA", 0 }, + { OPCODE_RCC, "RCC", 1 }, + { OPCODE_RCP, "RCP", 1 }, + { OPCODE_RET, "RET", 0 }, + { OPCODE_RFL, "RFL", 1 }, + { OPCODE_RSQ, "RSQ", 1 }, + { OPCODE_SCS, "SCS", 1 }, + { OPCODE_SEQ, "SEQ", 2 }, + { OPCODE_SFL, "SFL", 0 }, + { OPCODE_SGE, "SGE", 2 }, + { OPCODE_SGT, "SGT", 2 }, + { OPCODE_SIN, "SIN", 1 }, + { OPCODE_SLE, "SLE", 2 }, + { OPCODE_SLT, "SLT", 2 }, + { OPCODE_SNE, "SNE", 2 }, + { OPCODE_SSG, "SSG", 1 }, + { OPCODE_STR, "STR", 0 }, + { OPCODE_SUB, "SUB", 2 }, + { OPCODE_SWZ, "SWZ", 1 }, + { OPCODE_TEX, "TEX", 1 }, + { OPCODE_TXB, "TXB", 1 }, + { OPCODE_TXD, "TXD", 3 }, + { OPCODE_TXL, "TXL", 1 }, + { OPCODE_TXP, "TXP", 1 }, + { OPCODE_TXP_NV, "TXP", 1 }, + { OPCODE_UP2H, "UP2H", 1 }, + { OPCODE_UP2US, "UP2US", 1 }, + { OPCODE_UP4B, "UP4B", 1 }, + { OPCODE_UP4UB, "UP4UB", 1 }, + { OPCODE_X2D, "X2D", 3 }, + { OPCODE_XPD, "XPD", 2 } +}; + + +/** + * Return the number of src registers for the given instruction/opcode. + */ +GLuint +_mesa_num_inst_src_regs(gl_inst_opcode opcode) +{ + ASSERT(opcode == InstInfo[opcode].Opcode); + ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode); + return InstInfo[opcode].NumSrcRegs; +} + + +/** + * Return string name for given program opcode. + */ +const char * +_mesa_opcode_string(gl_inst_opcode opcode) +{ + ASSERT(opcode < MAX_OPCODE); + return InstInfo[opcode].Name; +} + diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index eded71bbae..1453c3bb88 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -39,118 +39,6 @@ #include "prog_statevars.h" - -/** - * Basic info about each instruction - */ -struct instruction_info -{ - gl_inst_opcode Opcode; - const char *Name; - GLuint NumSrcRegs; -}; - -/** - * Instruction info - * \note Opcode should equal array index! - */ -static const struct instruction_info InstInfo[MAX_OPCODE] = { - { OPCODE_NOP, "NOP", 0 }, - { OPCODE_ABS, "ABS", 1 }, - { OPCODE_ADD, "ADD", 2 }, - { OPCODE_ARA, "ARA", 1 }, - { OPCODE_ARL, "ARL", 1 }, - { OPCODE_ARL_NV, "ARL", 1 }, - { OPCODE_ARR, "ARL", 1 }, - { OPCODE_BRA, "BRA", 0 }, - { OPCODE_CAL, "CAL", 0 }, - { OPCODE_CMP, "CMP", 3 }, - { OPCODE_COS, "COS", 1 }, - { OPCODE_DDX, "DDX", 1 }, - { OPCODE_DDY, "DDY", 1 }, - { OPCODE_DP3, "DP3", 2 }, - { OPCODE_DP4, "DP4", 2 }, - { OPCODE_DPH, "DPH", 2 }, - { OPCODE_DST, "DST", 2 }, - { OPCODE_END, "END", 0 }, - { OPCODE_EX2, "EX2", 1 }, - { OPCODE_EXP, "EXP", 1 }, - { OPCODE_FLR, "FLR", 1 }, - { OPCODE_FRC, "FRC", 1 }, - { OPCODE_KIL, "KIL", 1 }, - { OPCODE_KIL_NV, "KIL", 0 }, - { OPCODE_LG2, "LG2", 1 }, - { OPCODE_LIT, "LIT", 1 }, - { OPCODE_LOG, "LOG", 1 }, - { OPCODE_LRP, "LRP", 3 }, - { OPCODE_MAD, "MAD", 3 }, - { OPCODE_MAX, "MAX", 2 }, - { OPCODE_MIN, "MIN", 2 }, - { OPCODE_MOV, "MOV", 1 }, - { OPCODE_MUL, "MUL", 2 }, - { OPCODE_PK2H, "PK2H", 1 }, - { OPCODE_PK2US, "PK2US", 1 }, - { OPCODE_PK4B, "PK4B", 1 }, - { OPCODE_PK4UB, "PK4UB", 1 }, - { OPCODE_POW, "POW", 2 }, - { OPCODE_POPA, "POPA", 0 }, - { OPCODE_PRINT, "PRINT", 1 }, - { OPCODE_PUSHA, "PUSHA", 0 }, - { OPCODE_RCC, "RCC", 1 }, - { OPCODE_RCP, "RCP", 1 }, - { OPCODE_RET, "RET", 0 }, - { OPCODE_RFL, "RFL", 1 }, - { OPCODE_RSQ, "RSQ", 1 }, - { OPCODE_SCS, "SCS", 1 }, - { OPCODE_SEQ, "SEQ", 2 }, - { OPCODE_SFL, "SFL", 0 }, - { OPCODE_SGE, "SGE", 2 }, - { OPCODE_SGT, "SGT", 2 }, - { OPCODE_SIN, "SIN", 1 }, - { OPCODE_SLE, "SLE", 2 }, - { OPCODE_SLT, "SLT", 2 }, - { OPCODE_SNE, "SNE", 2 }, - { OPCODE_SSG, "SSG", 1 }, - { OPCODE_STR, "STR", 0 }, - { OPCODE_SUB, "SUB", 2 }, - { OPCODE_SWZ, "SWZ", 1 }, - { OPCODE_TEX, "TEX", 1 }, - { OPCODE_TXB, "TXB", 1 }, - { OPCODE_TXD, "TXD", 3 }, - { OPCODE_TXL, "TXL", 1 }, - { OPCODE_TXP, "TXP", 1 }, - { OPCODE_TXP_NV, "TXP", 1 }, - { OPCODE_UP2H, "UP2H", 1 }, - { OPCODE_UP2US, "UP2US", 1 }, - { OPCODE_UP4B, "UP4B", 1 }, - { OPCODE_UP4UB, "UP4UB", 1 }, - { OPCODE_X2D, "X2D", 3 }, - { OPCODE_XPD, "XPD", 2 } -}; - - -/** - * Return the number of src registers for the given instruction/opcode. - */ -GLuint -_mesa_num_inst_src_regs(gl_inst_opcode opcode) -{ - ASSERT(opcode == InstInfo[opcode].Opcode); - ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode); - return InstInfo[opcode].NumSrcRegs; -} - - -/** - * Return string name for given program opcode. - */ -const char * -_mesa_opcode_string(gl_inst_opcode opcode) -{ - ASSERT(opcode < MAX_OPCODE); - return InstInfo[opcode].Name; -} - /** * Return string name for given program/register file. */ -- cgit v1.2.3 From 2c1f9758525431d870b32986b6144c2921760bc0 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 14 Dec 2006 15:50:34 -0700 Subject: remove unneded includes --- src/mesa/shader/prog_parameter.c | 2 -- src/mesa/shader/prog_print.c | 2 -- 2 files changed, 4 deletions(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c index f634e38800..7094d6fc03 100644 --- a/src/mesa/shader/prog_parameter.c +++ b/src/mesa/shader/prog_parameter.c @@ -32,8 +32,6 @@ #include "glheader.h" #include "imports.h" #include "macros.h" -#include "mtypes.h" -#include "program.h" #include "prog_instruction.h" #include "prog_parameter.h" #include "prog_statevars.h" diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 1453c3bb88..7bc5016987 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -31,8 +31,6 @@ #include "glheader.h" #include "context.h" #include "imports.h" -#include "macros.h" -#include "program.h" #include "prog_instruction.h" #include "prog_parameter.h" #include "prog_print.h" -- cgit v1.2.3 From fa8059a89c91405615c0e0f73b2c469ccb27fb91 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 15 Dec 2006 15:36:29 -0700 Subject: fix double-printing of comment info --- src/mesa/shader/prog_print.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 7bc5016987..b34bbbd482 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -208,9 +208,6 @@ _mesa_print_alu_instruction(const struct prog_instruction *inst, _mesa_printf(", "); } - if (inst->Comment) - _mesa_printf(" # %s", inst->Comment); - print_comment(inst); } -- cgit v1.2.3 From 3a2815370d26012b41d742540237985a333b6ae4 Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 16 Dec 2006 12:51:34 -0700 Subject: print BRA instructions --- src/mesa/shader/prog_print.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index b34bbbd482..7e2e1b22c4 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -77,6 +77,9 @@ program_file_string(enum register_file f) /** * Return a string representation of the given swizzle word. * If extended is true, use extended (comma-separated) format. + * \param swizzle the swizzle field + * \param negateBase 4-bit negation vector + * \param extended if true, also allow 0, 1 values */ static const char * swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended) @@ -147,6 +150,25 @@ writemask_string(GLuint writeMask) return s; } + +static const char * +condcode_string(GLuint condcode) +{ + switch (condcode) { + case COND_GT: return "GT"; + case COND_EQ: return "EQ"; + case COND_LT: return "LT"; + case COND_UN: return "UN"; + case COND_GE: return "GE"; + case COND_LE: return "LE"; + case COND_NE: return "NE"; + case COND_TR: return "TR"; + case COND_FL: return "FL"; + default: return "cond???"; + } +} + + static void print_dst_reg(const struct prog_dst_register *dstReg) { @@ -273,7 +295,10 @@ _mesa_print_instruction(const struct prog_instruction *inst) print_comment(inst); break; case OPCODE_BRA: - _mesa_printf("BRA %u", inst->BranchTarget); + _mesa_printf("BRA %u (%s.%s)", + inst->BranchTarget, + condcode_string(inst->DstReg.CondMask), + swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE)); print_comment(inst); break; case OPCODE_CAL: @@ -284,6 +309,10 @@ _mesa_print_instruction(const struct prog_instruction *inst) _mesa_printf("END"); print_comment(inst); break; + case OPCODE_NOP: + _mesa_printf("NOP"); + print_comment(inst); + break; /* XXX may need other special-case instructions */ default: /* typical alu instruction */ -- cgit v1.2.3 From b50280e95f3c044f53c0705d3a5619ebb2db4513 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 18 Dec 2006 16:21:58 -0700 Subject: Check for inst->CondUpdate, print .C suffix. --- src/mesa/shader/prog_print.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 7e2e1b22c4..4cd55d0bca 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -206,16 +206,15 @@ _mesa_print_alu_instruction(const struct prog_instruction *inst, GLuint j; _mesa_printf("%s", opcode_string); + if (inst->CondUpdate) + _mesa_printf(".C"); /* frag prog only */ if (inst->SaturateMode == SATURATE_ZERO_ONE) _mesa_printf("_SAT"); if (inst->DstReg.File != PROGRAM_UNDEFINED) { - _mesa_printf(" %s[%d]%s", - program_file_string((enum register_file) inst->DstReg.File), - inst->DstReg.Index, - writemask_string(inst->DstReg.WriteMask)); + print_dst_reg(&inst->DstReg); } else { _mesa_printf(" ???"); -- cgit v1.2.3 From 83ca3ff384ac09524ff6946134cded4174590d92 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Dec 2006 17:17:38 -0700 Subject: added _mesa_print_parameter_list() --- src/mesa/shader/prog_print.c | 22 ++++++++++++++-------- src/mesa/shader/prog_print.h | 3 +++ 2 files changed, 17 insertions(+), 8 deletions(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 4cd55d0bca..07b383dc56 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -344,8 +344,6 @@ _mesa_print_program(const struct gl_program *prog) void _mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog) { - GLint i; - _mesa_printf("InputsRead: 0x%x\n", prog->InputsRead); _mesa_printf("OutputsWritten: 0x%x\n", prog->OutputsWritten); _mesa_printf("NumInstructions=%d\n", prog->NumInstructions); @@ -363,13 +361,21 @@ _mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog) _mesa_printf("%2d: %f, %f, %f, %f\n", i, p[0], p[1], p[2], p[3]); } #endif + _mesa_print_parameter_list(prog->Parameters); +} + - for (i = 0; i < prog->Parameters->NumParameters; i++){ - struct gl_program_parameter *param = prog->Parameters->Parameters + i; - const GLfloat *v = prog->Parameters->ParameterValues[i]; - _mesa_printf("param[%d] %s %s = {%.3f, %.3f, %.3f, %.3f};\n", - i, - program_file_string(prog->Parameters->Parameters[i].Type), +void +_mesa_print_parameter_list(const struct gl_program_parameter_list *list) +{ + GLuint i; + _mesa_printf("param list %p\n", (void *) list); + for (i = 0; i < list->NumParameters; i++){ + struct gl_program_parameter *param = list->Parameters + i; + const GLfloat *v = list->ParameterValues[i]; + _mesa_printf("param[%d] sz=%d %s %s = {%.3f, %.3f, %.3f, %.3f};\n", + i, param->Size, + program_file_string(list->Parameters[i].Type), param->Name, v[0], v[1], v[2], v[3]); } } diff --git a/src/mesa/shader/prog_print.h b/src/mesa/shader/prog_print.h index 595a0dcf37..8bc2c69c6f 100644 --- a/src/mesa/shader/prog_print.h +++ b/src/mesa/shader/prog_print.h @@ -41,5 +41,8 @@ _mesa_print_program(const struct gl_program *prog); extern void _mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog); +extern void +_mesa_print_parameter_list(const struct gl_program_parameter_list *list); + #endif /* PROG_PRINT_H */ -- cgit v1.2.3 From ff81f074fb4165122b4599f602f89ecff6f611ff Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 4 Jan 2007 15:25:29 -0700 Subject: minor formatting fix --- src/mesa/shader/prog_print.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 07b383dc56..416d7b4fa6 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -272,7 +272,6 @@ _mesa_print_instruction(const struct prog_instruction *inst) _mesa_printf("%s", _mesa_opcode_string(inst->Opcode)); if (inst->SaturateMode == SATURATE_ZERO_ONE) _mesa_printf("_SAT"); - _mesa_printf(" "); print_dst_reg(&inst->DstReg); _mesa_printf(", "); print_src_reg(&inst->SrcReg[0]); -- cgit v1.2.3 From b2ab693d68f2ba1358b9c3f8bab53b9ebfb586fe Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 5 Jan 2007 16:01:43 -0700 Subject: added PROGRAM_SAMPLER --- src/mesa/shader/prog_print.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 416d7b4fa6..04b7c7d22a 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -68,6 +68,8 @@ program_file_string(enum register_file f) return "WRITE_ONLY"; case PROGRAM_ADDRESS: return "ADDR"; + case PROGRAM_SAMPLER: + return "SAMPLER"; default: return "Unknown program file!"; } -- cgit v1.2.3 From 5ae49cf3ed53fda6a904d7e90feef78495ae6903 Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 20 Jan 2007 09:27:40 -0700 Subject: Initial implementation of OPCODE_IF/ELSE/ENDIF instructions. --- src/mesa/shader/prog_instruction.c | 3 ++ src/mesa/shader/prog_instruction.h | 3 ++ src/mesa/shader/prog_print.c | 14 +++++++- src/mesa/shader/slang/slang_codegen.c | 53 ++++++++++++++++++++++++++- src/mesa/shader/slang/slang_emit.c | 37 +++++++++++++++++++ src/mesa/shader/slang/slang_ir.h | 3 ++ src/mesa/swrast/s_fragprog.c | 67 +++++++++++++++++++++++++++++++++++ src/mesa/tnl/t_vb_arbprogram.c | 5 ++- 8 files changed, 182 insertions(+), 3 deletions(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c index 1379018d4a..3de71b8b5d 100644 --- a/src/mesa/shader/prog_instruction.c +++ b/src/mesa/shader/prog_instruction.c @@ -130,11 +130,14 @@ static const struct instruction_info InstInfo[MAX_OPCODE] = { { OPCODE_DP4, "DP4", 2 }, { OPCODE_DPH, "DPH", 2 }, { OPCODE_DST, "DST", 2 }, + { OPCODE_ELSE, "ELSE", 0 }, { OPCODE_END, "END", 0 }, + { OPCODE_ENDIF, "ENDIF", 0 }, { OPCODE_EX2, "EX2", 1 }, { OPCODE_EXP, "EXP", 1 }, { OPCODE_FLR, "FLR", 1 }, { OPCODE_FRC, "FRC", 1 }, + { OPCODE_IF, "IF", 0 }, { OPCODE_INT, "INT", 1 }, { OPCODE_KIL, "KIL", 1 }, { OPCODE_KIL_NV, "KIL", 0 }, diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h index b659879651..b1001885e0 100644 --- a/src/mesa/shader/prog_instruction.h +++ b/src/mesa/shader/prog_instruction.h @@ -143,11 +143,14 @@ typedef enum prog_opcode { OPCODE_DP4, /* X X X X */ OPCODE_DPH, /* X X 1.1 */ OPCODE_DST, /* X X X X */ + OPCODE_ELSE, OPCODE_END, /* X X X X */ + OPCODE_ENDIF, OPCODE_EX2, /* X X 2 X */ OPCODE_EXP, /* X X */ OPCODE_FLR, /* X X 2 X */ OPCODE_FRC, /* X X 2 X */ + OPCODE_IF, OPCODE_INT, /* */ OPCODE_KIL, /* X */ OPCODE_KIL_NV, /* X */ diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 04b7c7d22a..78ce752f2a 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -295,7 +295,7 @@ _mesa_print_instruction(const struct prog_instruction *inst) print_comment(inst); break; case OPCODE_BRA: - _mesa_printf("BRA %u (%s.%s)", + _mesa_printf("BRA %u (%s%s)", inst->BranchTarget, condcode_string(inst->DstReg.CondMask), swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE)); @@ -305,6 +305,18 @@ _mesa_print_instruction(const struct prog_instruction *inst) _mesa_printf("CAL %u", inst->BranchTarget); print_comment(inst); break; + case OPCODE_IF: + _mesa_printf(" IF (%s%s)", + condcode_string(inst->DstReg.CondMask), + swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE)); + print_comment(inst); + break; + case OPCODE_ELSE: + _mesa_printf(" ELSE;\n"); + break; + case OPCODE_ENDIF: + _mesa_printf(" ENDIF;\n"); + break; case OPCODE_END: _mesa_printf("END"); print_comment(inst); diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 6923c00562..aba6813a8b 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -1560,6 +1560,51 @@ _slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper) } +/** + * Use high-level IF/ELSE/ENDIF instructions + */ +static slang_ir_node * +_slang_gen_if2(slang_assemble_ctx * A, const slang_operation *oper) +{ + /* + * eval expr (child[0]), updating condcodes + * branch if false to _else or _endif + * "true" code block + * if haveElseClause clause: + * jump "__endif" + * label "__else" + * "false" code block + * label "__endif" + */ + const GLboolean haveElseClause = !_slang_is_noop(&oper->children[2]); + slang_ir_node *ifNode, *cond, *trueBody, *elseNode, *falseBody, *endifNode; + slang_ir_node *tree; + + cond = _slang_gen_operation(A, &oper->children[0]); + cond = _slang_gen_cond(cond); + /*assert(cond->Store);*/ + ifNode = new_node(IR_IF, cond, NULL); + + trueBody = _slang_gen_operation(A, &oper->children[1]); + tree = new_seq(ifNode, trueBody); + + if (haveElseClause) { + /* else clause */ + elseNode = new_node(IR_ELSE, NULL, NULL); + tree = new_seq(tree, elseNode); + + falseBody = _slang_gen_operation(A, &oper->children[2]); + tree = new_seq(tree, falseBody); + } + + endifNode = new_node(IR_ENDIF, NULL, NULL); + tree = new_seq(tree, endifNode); + + return tree; +} + + + /** * Generate IR node for storage of a temporary of given size. */ @@ -2314,7 +2359,13 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) case slang_oper_identifier: return _slang_gen_variable(A, oper); case slang_oper_if: - return _slang_gen_if(A, oper); + if (A->program->Target == GL_FRAGMENT_PROGRAM_ARB) { + return _slang_gen_if(A, oper); + } + else { + /* XXX update tnl executor */ + return _slang_gen_if(A, oper); + } case slang_oper_field: return _slang_gen_field(A, oper); case slang_oper_subscript: diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 6c31bfc677..44fd3752e2 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -91,6 +91,9 @@ static slang_ir_info IrInfo[] = { { IR_JUMP, "IR_JUMP", 0, 0, 0 }, { IR_CJUMP0, "IR_CJUMP0", 0, 0, 0 }, { IR_CJUMP1, "IR_CJUMP1", 0, 0, 0 }, + { IR_IF, "IR_IF", 0, 0, 0 }, + { IR_ELSE, "IR_ELSE", 0, 0, 0 }, + { IR_ENDIF, "IR_ENDIF", 0, 0, 0 }, { IR_KILL, "IR_KILL", 0, 0, 0 }, { IR_COND, "IR_COND", 0, 0, 0 }, { IR_CALL, "IR_CALL", 0, 0, 0 }, @@ -271,6 +274,18 @@ slang_print_ir(const slang_ir_node *n, int indent) printf("CJUMP1 %s\n", n->Target); slang_print_ir(n->Children[0], indent+3); break; + + case IR_IF: + printf("IF \n"); + slang_print_ir(n->Children[0], indent+3); + break; + case IR_ELSE: + printf("ELSE\n"); + break; + case IR_ENDIF: + printf("ENDIF\n"); + break; + case IR_VAR: printf("VAR %s%s at %s store %p\n", (char *) n->Var->a_name, swizzle_string(n->Store->Swizzle), @@ -862,6 +877,28 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) case IR_KILL: return emit_kill(prog); + case IR_IF: + { + struct prog_instruction *inst; + emit(vt, n->Children[0], prog); /* the condition */ + inst = new_instruction(prog, OPCODE_IF); + inst->DstReg.CondMask = COND_NE; /* if cond is non-zero */ + inst->DstReg.CondSwizzle = SWIZZLE_X; + return inst; + } + case IR_ELSE: + { + struct prog_instruction *inst; + inst = new_instruction(prog, OPCODE_ELSE); + return inst; + } + case IR_ENDIF: + { + struct prog_instruction *inst; + inst = new_instruction(prog, OPCODE_ENDIF); + return inst; + } + default: _mesa_problem(NULL, "Unexpected IR opcode in emit()\n"); abort(); diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h index 4072c70f90..e5a0fa8eb5 100644 --- a/src/mesa/shader/slang/slang_ir.h +++ b/src/mesa/shader/slang/slang_ir.h @@ -51,6 +51,9 @@ typedef enum IR_CJUMP0, /* conditional jump if zero */ IR_CJUMP1, /* conditional jump if one (or non-zero) */ IR_COND, /* conditional expression */ + IR_IF, /* high-level IF */ + IR_ELSE, /* high-level ELSE */ + IR_ENDIF, /* high-level ENDIF */ IR_CALL, /* call subroutine */ IR_MOVE, IR_ADD, diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index b842b49616..813345f4cd 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -888,6 +888,73 @@ execute_program( GLcontext *ctx, store_vector4( inst, machine, result ); } break; + case OPCODE_IF: + { + const GLuint swizzle = inst->DstReg.CondSwizzle; + const GLuint condMask = inst->DstReg.CondMask; + if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { + /* do if-clause (just continue execution) */ + } + else { + /* do else-clause, or go to endif */ + GLint ifDepth = 1; + do { + pc++; + inst = program->Base.Instructions + pc; + if (inst->Opcode == OPCODE_END) { + /* mal-formed program! */ + abort(); + } + else if (inst->Opcode == OPCODE_IF) { + ifDepth++; + } + else if (inst->Opcode == OPCODE_ELSE) { + if (ifDepth == 0) { + /* ok, continue normal execution */ + break; + } + } + else if (inst->Opcode == OPCODE_ENDIF) { + ifDepth--; + if (ifDepth == 0) { + /* ok, continue normal execution */ + break; + } + } + assert(ifDepth >= 0); + } while (pc < maxInst); + } + } + break; + case OPCODE_ELSE: + { + /* find/goto ENDIF */ + GLint ifDepth = 1; + do { + pc++; + inst = program->Base.Instructions + pc; + if (inst->Opcode == OPCODE_END) { + /* mal-formed program! */ + abort(); + } + else if (inst->Opcode == OPCODE_IF) { + ifDepth++; + } + else if (inst->Opcode == OPCODE_ENDIF) { + ifDepth--; + if (ifDepth == 0) + break; + } + assert(ifDepth >= 0); + } while (pc < maxInst); + } + break; + case OPCODE_ENDIF: + /* nothing */ + break; case OPCODE_INT: /* float to int */ { GLfloat a[4], result[4]; diff --git a/src/mesa/tnl/t_vb_arbprogram.c b/src/mesa/tnl/t_vb_arbprogram.c index 5773f0f627..5726a66c90 100644 --- a/src/mesa/tnl/t_vb_arbprogram.c +++ b/src/mesa/tnl/t_vb_arbprogram.c @@ -746,11 +746,14 @@ static void (* const opcode_func[MAX_OPCODE+3])(struct arb_vp_machine *, union i do_DP4, do_DPH, do_DST, - do_NOP, + do_NOP,/*ELSE*/ + do_NOP,/*END*/ + do_NOP,/*ENDIF*/ do_EX2, do_EXP, do_FLR, do_FRC, + do_NOP,/*IF*/ do_INT, do_NOP,/*KIL*/ do_NOP,/*KIL_NV*/ -- cgit v1.2.3 From b63c100677c76bb20a1871ea15298ca708acd04f Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 31 Jan 2007 16:34:54 -0700 Subject: Overhaul handling of writemasks/swizzling. This fixes two problem cases: vec2 v; v.x = v.y = 1.0; // chained assignment vec4 v; v.zx = vec2(a,b); // swizzled writemask --- src/mesa/shader/prog_instruction.h | 1 + src/mesa/shader/prog_print.c | 2 +- src/mesa/shader/slang/slang_assemble_constructor.c | 17 +- src/mesa/shader/slang/slang_codegen.c | 198 +++++++++++++-------- src/mesa/shader/slang/slang_emit.c | 69 +++++-- src/mesa/shader/slang/slang_ir.h | 6 +- 6 files changed, 197 insertions(+), 96 deletions(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h index 3e88b4e627..f018de82b3 100644 --- a/src/mesa/shader/prog_instruction.h +++ b/src/mesa/shader/prog_instruction.h @@ -49,6 +49,7 @@ #define SWIZZLE_W 3 #define SWIZZLE_ZERO 4 /**< For SWZ instruction only */ #define SWIZZLE_ONE 5 /**< For SWZ instruction only */ +#define SWIZZLE_NIL 7 /**< used during shader code gen (undefined value) */ /*@}*/ #define MAKE_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<3) | ((c)<<6) | ((d)<<9)) diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 78ce752f2a..63ff84e345 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -86,7 +86,7 @@ program_file_string(enum register_file f) static const char * swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended) { - static const char swz[] = "xyzw01"; + static const char swz[] = "xyzw01?!"; static char s[20]; GLuint i = 0; diff --git a/src/mesa/shader/slang/slang_assemble_constructor.c b/src/mesa/shader/slang/slang_assemble_constructor.c index a411597130..e045f2f6d2 100644 --- a/src/mesa/shader/slang/slang_assemble_constructor.c +++ b/src/mesa/shader/slang/slang_assemble_constructor.c @@ -31,7 +31,7 @@ #include "imports.h" #include "slang_assemble.h" #include "slang_storage.h" - +#include "prog_instruction.h" /** @@ -46,9 +46,14 @@ _slang_is_swizzle(const char *field, GLuint rows, slang_swizzle * swz) GLuint i; GLboolean xyzw = GL_FALSE, rgba = GL_FALSE, stpq = GL_FALSE; - /* init to default */ + /* init to undefined. + * We rely on undefined/nil values to distinguish between + * regular swizzles and writemasks. + * For example, the swizzle ".xNNN" is the writemask ".x". + * That's different than the swizzle ".xxxx". + */ for (i = 0; i < 4; i++) - swz->swizzle[i] = i; + swz->swizzle[i] = SWIZZLE_NIL; /* the swizzle can be at most 4-component long */ swz->num_components = slang_string_length(field); @@ -113,12 +118,6 @@ _slang_is_swizzle(const char *field, GLuint rows, slang_swizzle * swz) if ((xyzw && rgba) || (xyzw && stpq) || (rgba && stpq)) return GL_FALSE; - if (swz->num_components == 1) { - /* smear */ - swz->swizzle[3] = - swz->swizzle[2] = - swz->swizzle[1] = swz->swizzle[0]; - } return GL_TRUE; } diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index cc2a0b2738..d09883c664 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -609,42 +609,6 @@ new_var(slang_assemble_ctx *A, slang_operation *oper, slang_atom name) } -static GLboolean -slang_is_writemask(const char *field, GLuint *mask) -{ - const GLuint n = 4; - GLuint i, bit, c = 0; - - for (i = 0; i < n && field[i]; i++) { - switch (field[i]) { - case 'x': - case 'r': - bit = WRITEMASK_X; - break; - case 'y': - case 'g': - bit = WRITEMASK_Y; - break; - case 'z': - case 'b': - bit = WRITEMASK_Z; - break; - case 'w': - case 'a': - bit = WRITEMASK_W; - break; - default: - return GL_FALSE; - } - if (c & bit) - return GL_FALSE; - c |= bit; - } - *mask = c; - return GL_TRUE; -} - - /** * Check if the given function is really just a wrapper for a * basic assembly instruction. @@ -1960,6 +1924,111 @@ _slang_gen_variable(slang_assemble_ctx * A, slang_operation *oper) } +/** + * Some write-masked assignments are simple, but others are hard. + * Simple example: + * vec3 v; + * v.xy = vec2(a, b); + * Hard example: + * vec3 v; + * v.yz = vec2(a, b); + * this would have to be transformed/swizzled into: + * v.yz = vec2(a, b).*xy* (* = don't care) + * Instead, we'll effectively do this: + * v.y = vec2(a, b).xxxx; + * v.z = vec2(a, b).yyyy; + * + */ +static GLboolean +_slang_simple_writemask(GLuint writemask) +{ + switch (writemask) { + case WRITEMASK_X: + case WRITEMASK_Y: + case WRITEMASK_Z: + case WRITEMASK_W: + case WRITEMASK_XY: + case WRITEMASK_XYZ: + case WRITEMASK_XYZW: + return GL_TRUE; + default: + return GL_FALSE; + } +} + + +/** + * Convert the given swizzle into a writemask. In some cases this + * is trivial, in other cases, we'll need to also swizzle the right + * hand side to put components in the right places. + * \param swizzle the incoming swizzle + * \param writemaskOut returns the writemask + * \param swizzleOut swizzle to apply to the right-hand-side + * \return GL_FALSE for simple writemasks, GL_TRUE for non-simple + */ +static GLboolean +swizzle_to_writemask(GLuint swizzle, + GLuint *writemaskOut, GLuint *swizzleOut) +{ + GLuint mask = 0x0, newSwizzle[4]; + GLint i, size; + + /* make new dst writemask, compute size */ + for (i = 0; i < 4; i++) { + const GLuint swz = GET_SWZ(swizzle, i); + if (swz == SWIZZLE_NIL) { + /* end */ + break; + } + assert(swz >= 0 && swz <= 3); + mask |= (1 << swz); + } + assert(mask <= 0xf); + size = i; /* number of components in mask/swizzle */ + + *writemaskOut = mask; + + /* make new src swizzle, by inversion */ + for (i = 0; i < 4; i++) { + newSwizzle[i] = i; /*identity*/ + } + for (i = 0; i < size; i++) { + const GLuint swz = GET_SWZ(swizzle, i); + newSwizzle[swz] = i; + } + *swizzleOut = MAKE_SWIZZLE4(newSwizzle[0], + newSwizzle[1], + newSwizzle[2], + newSwizzle[3]); + + if (_slang_simple_writemask(mask)) { + if (size >= 1) + assert(GET_SWZ(*swizzleOut, 0) == SWIZZLE_X); + if (size >= 2) + assert(GET_SWZ(*swizzleOut, 1) == SWIZZLE_Y); + if (size >= 3) + assert(GET_SWZ(*swizzleOut, 2) == SWIZZLE_Z); + if (size >= 4) + assert(GET_SWZ(*swizzleOut, 3) == SWIZZLE_W); + return GL_TRUE; + } + else + return GL_FALSE; +} + + +static slang_ir_node * +_slang_gen_swizzle(slang_ir_node *child, GLuint swizzle) +{ + slang_ir_node *n = new_node(IR_SWIZZLE, child, NULL); + if (n) { + n->Store = _slang_new_ir_storage(PROGRAM_UNDEFINED, -1, -1); + n->Store->Swizzle = swizzle; + } + return n; +} + + /** * Generate IR tree for an assignment (=). */ @@ -1982,26 +2051,21 @@ _slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper) return n; } else { - slang_operation *lhs = &oper->children[0]; - slang_ir_node *n, *c0, *c1; - GLuint mask = WRITEMASK_XYZW; - if (lhs->type == slang_oper_field) { - /* XXXX this is a hack! */ - /* writemask */ - if (!slang_is_writemask((char *) lhs->a_id, &mask)) - mask = WRITEMASK_XYZW; - lhs = &lhs->children[0]; - } - c0 = _slang_gen_operation(A, lhs); - c1 = _slang_gen_operation(A, &oper->children[1]); - if (c0 && c1) { - n = new_node(IR_MOVE, c0, c1); - /*assert(c1->Opcode != IR_SEQ);*/ - if (c0->Writemask != WRITEMASK_XYZW) - /* XXX this is a hack! */ - n->Writemask = c0->Writemask; - else - n->Writemask = mask; + slang_ir_node *n, *lhs, *rhs; + lhs = _slang_gen_operation(A, &oper->children[0]); + rhs = _slang_gen_operation(A, &oper->children[1]); + if (lhs && rhs) { + /* convert lhs swizzle into writemask */ + GLuint writemask, newSwizzle; + if (!swizzle_to_writemask(lhs->Store->Swizzle, + &writemask, &newSwizzle)) { + /* Non-simple writemask, need to swizzle right hand side in + * order to put components into the right place. + */ + rhs = _slang_gen_swizzle(rhs, newSwizzle); + } + n = new_node(IR_MOVE, lhs, rhs); + n->Writemask = writemask; return n; } else { @@ -2011,20 +2075,6 @@ _slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper) } -static slang_ir_node * -_slang_gen_swizzle(slang_ir_node *child, GLuint swizzle) -{ - slang_ir_node *n = new_node(IR_SWIZZLE, child, NULL); - if (n) { - n->Store = _slang_new_ir_storage(child->Store->File, - child->Store->Index, - child->Store->Size); - n->Store->Swizzle = swizzle; - } - return n; -} - - /** * Generate IR tree for referencing a field in a struct (or basic vector type) */ @@ -2101,13 +2151,17 @@ _slang_gen_subscript(slang_assemble_ctx * A, slang_operation *oper) index = (GLint) oper->children[1].literal[0]; if (oper->children[1].type != slang_oper_literal_int || index >= max) { - RETURN_ERROR("Invalid array index", 0); + RETURN_ERROR("Invalid array index for vector type", 0); } n = _slang_gen_operation(A, &oper->children[0]); if (n) { /* use swizzle to access the element */ - n = _slang_gen_swizzle(n, SWIZZLE_X + index); + GLuint swizzle = MAKE_SWIZZLE4(SWIZZLE_X + index, + SWIZZLE_NIL, + SWIZZLE_NIL, + SWIZZLE_NIL); + n = _slang_gen_swizzle(n, swizzle); /*n->Store = _slang_clone_ir_storage_swz(n->Store, */ n->Writemask = WRITEMASK_X << index; } diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 1c945fa0ba..0626f7a643 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -424,7 +424,12 @@ storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st) if (st->Swizzle != SWIZZLE_NOOP) src->Swizzle = st->Swizzle; else - src->Swizzle = defaultSwizzle[st->Size - 1]; + src->Swizzle = defaultSwizzle[st->Size - 1]; /*XXX really need this?*/ + + assert(GET_SWZ(src->Swizzle, 0) != SWIZZLE_NIL); + assert(GET_SWZ(src->Swizzle, 1) != SWIZZLE_NIL); + assert(GET_SWZ(src->Swizzle, 2) != SWIZZLE_NIL); + assert(GET_SWZ(src->Swizzle, 3) != SWIZZLE_NIL); } @@ -975,6 +980,57 @@ emit_cond(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) } +/** + * Remove any SWIZZLE_NIL terms from given swizzle mask (smear prev term). + * Ex: fix_swizzle("zyNN") -> "zyyy" + */ +static GLuint +fix_swizzle(GLuint swizzle) +{ + GLuint swz[4], i; + for (i = 0; i < 4; i++) { + swz[i] = GET_SWZ(swizzle, i); + if (swz[i] == SWIZZLE_NIL) { + swz[i] = swz[i - 1]; + } + } + return MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]); +} + + +static struct prog_instruction * +emit_swizzle(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) +{ + GLuint swizzle; + + /* swizzled storage access */ + (void) emit(vt, n->Children[0], prog); + + /* "pull-up" the child's storage info, applying our swizzle info */ + n->Store->File = n->Children[0]->Store->File; + n->Store->Index = n->Children[0]->Store->Index; + n->Store->Size = n->Children[0]->Store->Size; + /*n->Var = n->Children[0]->Var; XXX for debug */ + assert(n->Store->Index >= 0); + + swizzle = fix_swizzle(n->Store->Swizzle); +#ifdef DEBUG + { + GLuint s = n->Children[0]->Store->Swizzle; + assert(GET_SWZ(s, 0) != SWIZZLE_NIL); + assert(GET_SWZ(s, 1) != SWIZZLE_NIL); + assert(GET_SWZ(s, 2) != SWIZZLE_NIL); + assert(GET_SWZ(s, 3) != SWIZZLE_NIL); + } +#endif + + /* apply this swizzle to child's swizzle to get composed swizzle */ + n->Store->Swizzle = swizzle_swizzle(n->Children[0]->Store->Swizzle, + swizzle); + return NULL; +} + + static struct prog_instruction * emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) { @@ -1060,16 +1116,7 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) return NULL; /* no instruction */ case IR_SWIZZLE: - /* swizzled storage access */ - (void) emit(vt, n->Children[0], prog); - /* "pull-up" the child's storage info, applying our swizzle info */ - n->Store->File = n->Children[0]->Store->File; - n->Store->Index = n->Children[0]->Store->Index; - n->Store->Size = n->Children[0]->Store->Size; - assert(n->Store->Index >= 0); - n->Store->Swizzle = swizzle_swizzle(n->Children[0]->Store->Swizzle, - n->Store->Swizzle); - return NULL; + return emit_swizzle(vt, n, prog); /* Simple arithmetic */ /* unary */ diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h index 4b696c5c13..5fd72be36a 100644 --- a/src/mesa/shader/slang/slang_ir.h +++ b/src/mesa/shader/slang/slang_ir.h @@ -121,17 +121,17 @@ typedef struct _slang_ir_storage slang_ir_storage; /** * Intermediate Representation (IR) tree node - * Basically a binary tree, but IR_LRP has three children. + * Basically a binary tree, but IR_LRP and IR_CLAMP have three children. */ typedef struct slang_ir_node_ { slang_ir_opcode Opcode; struct slang_ir_node_ *Children[3]; const char *Comment; - const char *Target; + const char *Target; /**< Branch target string */ GLuint Writemask; /**< If Opcode == IR_MOVE */ GLfloat Value[4]; /**< If Opcode == IR_FLOAT */ - slang_variable *Var; + slang_variable *Var; /**< If Opcode == IR_VAR or IR_VAR_DECL */ slang_ir_storage *Store; /**< location of result of this operation */ } slang_ir_node; -- cgit v1.2.3 From 5db088d70fbd14620c2fc7840096a05993f8e2b9 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 5 Feb 2007 14:58:15 -0700 Subject: indentation for program instructions (if/else, loops) --- src/mesa/shader/prog_print.c | 56 ++++++++++++++++++++++++++++++++++++-------- src/mesa/shader/prog_print.h | 6 ++--- 2 files changed, 49 insertions(+), 13 deletions(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 63ff84e345..9474fe995f 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -2,7 +2,7 @@ * Mesa 3-D graphics library * Version: 6.5.3 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * 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"), @@ -238,9 +238,22 @@ _mesa_print_alu_instruction(const struct prog_instruction *inst, /** * Print a single vertex/fragment program instruction. */ -void -_mesa_print_instruction(const struct prog_instruction *inst) +GLint +_mesa_print_instruction(const struct prog_instruction *inst, GLint indent) { + GLuint i; + + if (inst->Opcode == OPCODE_ELSE || + inst->Opcode == OPCODE_ENDIF || + inst->Opcode == OPCODE_ENDLOOP || + inst->Opcode == OPCODE_ENDSUB) { + indent -= 3; + } + assert(indent >= 0); + for (i = 0; i < indent; i++) { + _mesa_printf(" "); + } + switch (inst->Opcode) { case OPCODE_PRINT: _mesa_printf("PRINT '%s'", inst->Data); @@ -306,16 +319,38 @@ _mesa_print_instruction(const struct prog_instruction *inst) print_comment(inst); break; case OPCODE_IF: - _mesa_printf(" IF (%s%s)", + _mesa_printf("IF (%s%s)", condcode_string(inst->DstReg.CondMask), swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE)); print_comment(inst); - break; + return indent + 3; case OPCODE_ELSE: - _mesa_printf(" ELSE;\n"); - break; + _mesa_printf("ELSE;\n"); + return indent + 3; case OPCODE_ENDIF: - _mesa_printf(" ENDIF;\n"); + _mesa_printf("ENDIF;\n"); + break; + case OPCODE_BGNLOOP: + _mesa_printf("LOOP;\n"); + return indent + 3; + case OPCODE_ENDLOOP: + _mesa_printf("ENDLOOP;\n"); + break; + case OPCODE_BRK: + /* XXX just like BRA */ + _mesa_printf("BRK %u (%s%s)", + inst->BranchTarget, + condcode_string(inst->DstReg.CondMask), + swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE)); + print_comment(inst); + break; + case OPCODE_BGNSUB: + _mesa_printf("SUB;\n"); + print_comment(inst); + return indent + 3; + case OPCODE_ENDSUB: + _mesa_printf("ENDSUB;\n"); + print_comment(inst); break; case OPCODE_END: _mesa_printf("END"); @@ -333,6 +368,7 @@ _mesa_print_instruction(const struct prog_instruction *inst) _mesa_num_inst_src_regs(inst->Opcode)); break; } + return indent; } @@ -343,10 +379,10 @@ _mesa_print_instruction(const struct prog_instruction *inst) void _mesa_print_program(const struct gl_program *prog) { - GLuint i; + GLuint i, indent = 0; for (i = 0; i < prog->NumInstructions; i++) { _mesa_printf("%3d: ", i); - _mesa_print_instruction(prog->Instructions + i); + indent = _mesa_print_instruction(prog->Instructions + i, indent); } } diff --git a/src/mesa/shader/prog_print.h b/src/mesa/shader/prog_print.h index 8bc2c69c6f..19aaa53800 100644 --- a/src/mesa/shader/prog_print.h +++ b/src/mesa/shader/prog_print.h @@ -2,7 +2,7 @@ * Mesa 3-D graphics library * Version: 6.5.3 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * 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"), @@ -27,8 +27,8 @@ #define PROG_PRINT_H -extern void -_mesa_print_instruction(const struct prog_instruction *inst); +extern GLint +_mesa_print_instruction(const struct prog_instruction *inst, GLint indent); extern void _mesa_print_alu_instruction(const struct prog_instruction *inst, -- cgit v1.2.3 From d9731b26e759671d63e357eee2c921e90448ada2 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 5 Feb 2007 15:17:06 -0700 Subject: minor formatting changes --- src/mesa/shader/prog_print.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 9474fe995f..208c998661 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -325,16 +325,16 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) print_comment(inst); return indent + 3; case OPCODE_ELSE: - _mesa_printf("ELSE;\n"); + _mesa_printf("ELSE\n"); return indent + 3; case OPCODE_ENDIF: - _mesa_printf("ENDIF;\n"); + _mesa_printf("ENDIF\n"); break; case OPCODE_BGNLOOP: - _mesa_printf("LOOP;\n"); + _mesa_printf("BGNLOOP\n"); return indent + 3; case OPCODE_ENDLOOP: - _mesa_printf("ENDLOOP;\n"); + _mesa_printf("ENDLOOP (goto %d)\n", inst->BranchTarget); break; case OPCODE_BRK: /* XXX just like BRA */ -- cgit v1.2.3 From 86080796471df6a9e126fd536b21c3b10cb5310c Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 5 Feb 2007 17:18:10 -0700 Subject: Use IR node's BranchNode field for IF/ELSE/ENDIF instructions. This allows us to back-patch the IF/ELSE instruction's BranchTarget field to point to the location of the ELSE/ENDIF instructions. No longer have to search for ELSE/ENDIF in the interpreter. Also makes it trivial to translate IF/ELSE instructions into conditional/unconditional BRA instructions. --- src/mesa/shader/prog_print.c | 7 ++-- src/mesa/shader/slang/slang_codegen.c | 64 ++++++++++++++++++++++++++++------- src/mesa/shader/slang/slang_emit.c | 12 +++++++ src/mesa/swrast/s_fragprog.c | 57 ++++--------------------------- 4 files changed, 73 insertions(+), 67 deletions(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 208c998661..aea11da0db 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -319,13 +319,14 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) print_comment(inst); break; case OPCODE_IF: - _mesa_printf("IF (%s%s)", + _mesa_printf("IF (%s%s) (if false, goto %d)", condcode_string(inst->DstReg.CondMask), - swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE)); + swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), + inst->BranchTarget); print_comment(inst); return indent + 3; case OPCODE_ELSE: - _mesa_printf("ELSE\n"); + _mesa_printf("ELSE (goto %d)\n", inst->BranchTarget); return indent + 3; case OPCODE_ENDIF: _mesa_printf("ENDIF\n"); diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index c70f73f15a..7a1881c68e 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -590,6 +590,47 @@ new_end_loop(slang_ir_node *beginNode) } +/** + * Child[0] is the condition. + * XXX we might re-design IR_IF so Children[1] is the "then" body and + * Children[0] is the "else" body. + */ +static slang_ir_node * +new_if(slang_ir_node *cond) +{ + slang_ir_node *n = new_node(IR_IF, NULL, NULL); + assert(cond); + if (n) { + n->Children[0] = cond; + } + return n; +} + + +static slang_ir_node * +new_else(slang_ir_node *ifNode) +{ + slang_ir_node *n = new_node(IR_ELSE, NULL, NULL); + assert(ifNode); + if (n) { + n->BranchNode = ifNode; + } + return n; +} + + +static slang_ir_node * +new_endif(slang_ir_node *elseOrIfNode) +{ + slang_ir_node *n = new_node(IR_ENDIF, NULL, NULL); + assert(elseOrIfNode); + if (n) { + n->BranchNode = elseOrIfNode; + } + return n; +} + + /** * New IR_VAR node - a reference to a previously declared variable. */ @@ -1401,13 +1442,13 @@ _slang_gen_hl_while(slang_assemble_ctx * A, const slang_operation *oper) cond = new_node(IR_NOT, cond, NULL); cond = _slang_gen_cond(cond); - ifThen = new_node(IR_IF, cond, NULL); + ifThen = new_if(cond); tree = new_seq(beginLoop, ifThen); brk = new_node(IR_BREAK, NULL, NULL); tree = new_seq(tree, brk); - endif = new_node(IR_ENDIF, NULL, NULL); + endif = new_endif(ifThen); tree = new_seq(tree, endif); body = _slang_gen_operation(A, &oper->children[1]); @@ -1589,13 +1630,11 @@ _slang_gen_hl_if(slang_assemble_ctx * A, const slang_operation *oper) { /* * eval expr (child[0]), updating condcodes - * branch if false to _else or _endif - * "true" code block - * if haveElseClause clause: - * jump "__endif" - * label "__else" - * "false" code block - * label "__endif" + * IF expr THEN + * if-body code + * ELSE + * else-body code + * ENDIF */ /* XXX special cases to check for: * if body of conditiona is just a "break", emit a conditional break @@ -1608,21 +1647,20 @@ _slang_gen_hl_if(slang_assemble_ctx * A, const slang_operation *oper) cond = _slang_gen_operation(A, &oper->children[0]); cond = _slang_gen_cond(cond); /*assert(cond->Store);*/ - ifNode = new_node(IR_IF, cond, NULL); + ifNode = new_if(cond); trueBody = _slang_gen_operation(A, &oper->children[1]); tree = new_seq(ifNode, trueBody); if (haveElseClause) { - /* else clause */ - elseNode = new_node(IR_ELSE, NULL, NULL); + elseNode = new_else(ifNode); tree = new_seq(tree, elseNode); falseBody = _slang_gen_operation(A, &oper->children[2]); tree = new_seq(tree, falseBody); } - endifNode = new_node(IR_ENDIF, NULL, NULL); + endifNode = new_endif(haveElseClause ? elseNode : ifNode); tree = new_seq(tree, endifNode); return tree; diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 311eea1e6a..b890a6d93c 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -1036,6 +1036,7 @@ emit_not(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) free_temp_storage(vt, n->Children[0]); + inst->Comment = _mesa_strdup("NOT"); return inst; } @@ -1259,18 +1260,29 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) inst = new_instruction(prog, OPCODE_IF); inst->DstReg.CondMask = COND_NE; /* if cond is non-zero */ inst->DstReg.CondSwizzle = SWIZZLE_X; + n->InstLocation = prog->NumInstructions - 1; return inst; } case IR_ELSE: { struct prog_instruction *inst; + n->InstLocation = prog->NumInstructions; inst = new_instruction(prog, OPCODE_ELSE); + /* point IF's BranchTarget just after this instruction */ + assert(n->BranchNode); + assert(n->BranchNode->InstLocation >= 0); + prog->Instructions[n->BranchNode->InstLocation].BranchTarget = prog->NumInstructions; return inst; } case IR_ENDIF: { struct prog_instruction *inst; + n->InstLocation = prog->NumInstructions; inst = new_instruction(prog, OPCODE_ENDIF); + /* point ELSE's BranchTarget to just after this inst */ + assert(n->BranchNode); + assert(n->BranchNode->InstLocation >= 0); + prog->Instructions[n->BranchNode->InstLocation].BranchTarget = prog->NumInstructions; return inst; } diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 287dd9b1db..fbd25c0fbf 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -897,62 +897,17 @@ execute_program( GLcontext *ctx, /* do if-clause (just continue execution) */ } else { - /* search for else-clause or endif */ - /* XXX could encode location of the else/endif statement - * in the IF instruction to avoid searching... - */ - GLint ifDepth = 1; - do { - pc++; - inst = program->Base.Instructions + pc; - if (inst->Opcode == OPCODE_END) { - /* mal-formed program! */ - _mesa_problem(ctx, "END found before ELSE/ENDIF"); - return GL_FALSE; - } - else if (inst->Opcode == OPCODE_IF) { - /* nested if */ - ifDepth++; - } - else if (inst->Opcode == OPCODE_ELSE) { - if (ifDepth == 1) { - /* ok, continue normal execution */ - break; - } - } - else if (inst->Opcode == OPCODE_ENDIF) { - ifDepth--; - if (ifDepth == 0) { - /* ok, continue normal execution */ - break; - } - } - assert(ifDepth >= 0); - } while (pc < maxInst); + /* go to the instruction after ELSE or ENDIF */ + assert(inst->BranchTarget >= 0); + pc = inst->BranchTarget - 1; } } break; case OPCODE_ELSE: { - /* find/goto ENDIF */ - GLint ifDepth = 1; - do { - pc++; - inst = program->Base.Instructions + pc; - if (inst->Opcode == OPCODE_END) { - /* mal-formed program! */ - abort(); - } - else if (inst->Opcode == OPCODE_IF) { - ifDepth++; - } - else if (inst->Opcode == OPCODE_ENDIF) { - ifDepth--; - if (ifDepth == 0) - break; - } - assert(ifDepth >= 0); - } while (pc < maxInst); + /* goto ENDIF */ + assert(inst->BranchTarget >= 0); + pc = inst->BranchTarget - 1; } break; case OPCODE_ENDIF: -- cgit v1.2.3 From 2755c798f3cb89fcd4ece16cd740af1cd86a6b99 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 5 Feb 2007 18:01:02 -0700 Subject: BRK instruction's BranchTarget field now used for efficiently breaking out of loops. BRK's BranchTarget field actually points to the top of the loop, not the bottom, since we don't know the later's location yet. In the interpreter, basically do an indirect jump to update the PC. --- src/mesa/shader/prog_print.c | 8 ++-- src/mesa/shader/slang/slang_codegen.c | 90 +++++++++++++++++++++++++++++++++-- src/mesa/shader/slang/slang_emit.c | 24 ++++++++-- src/mesa/swrast/s_fragprog.c | 30 +++++------- 4 files changed, 123 insertions(+), 29 deletions(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index aea11da0db..3d4a474b05 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -332,17 +332,17 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) _mesa_printf("ENDIF\n"); break; case OPCODE_BGNLOOP: - _mesa_printf("BGNLOOP\n"); + _mesa_printf("BGNLOOP (end at %d)\n", inst->BranchTarget); return indent + 3; case OPCODE_ENDLOOP: _mesa_printf("ENDLOOP (goto %d)\n", inst->BranchTarget); break; case OPCODE_BRK: /* XXX just like BRA */ - _mesa_printf("BRK %u (%s%s)", - inst->BranchTarget, + _mesa_printf("BRK (%s%s) (for loop beginning at %d)", condcode_string(inst->DstReg.CondMask), - swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE)); + swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), + inst->BranchTarget); print_comment(inst); break; case OPCODE_BGNSUB: diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 7a1881c68e..a5f033d912 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -590,6 +590,18 @@ new_end_loop(slang_ir_node *beginNode) } +static slang_ir_node * +new_break(slang_ir_node *beginNode) +{ + slang_ir_node *n = new_node(IR_BREAK, NULL, NULL); + assert(beginNode); + if (n) { + n->BranchNode = beginNode; + } + return n; +} + + /** * Child[0] is the condition. * XXX we might re-design IR_IF so Children[1] is the "then" body and @@ -1430,7 +1442,7 @@ _slang_gen_hl_while(slang_assemble_ctx * A, const slang_operation *oper) * IF !expr THEN * BRK * ENDIF - * body code + * body code (child[1]) * ENDLOOP */ slang_ir_node *beginLoop, *endLoop, *ifThen, *endif; @@ -1445,7 +1457,7 @@ _slang_gen_hl_while(slang_assemble_ctx * A, const slang_operation *oper) ifThen = new_if(cond); tree = new_seq(beginLoop, ifThen); - brk = new_node(IR_BREAK, NULL, NULL); + brk = new_break(beginLoop); tree = new_seq(tree, brk); endif = new_endif(ifThen); @@ -1571,6 +1583,73 @@ _slang_gen_for(slang_assemble_ctx * A, const slang_operation *oper) } +/** + * Generate IR tree for a for-loop, using high-level BGNLOOP/ENDLOOP and + * IF/ENDIF instructions. + * + * XXX note done yet! + */ +static slang_ir_node * +_slang_gen_hl_for(slang_assemble_ctx * A, const slang_operation *oper) +{ + /* + * init code (child[0]) + * BGNLOOP + * eval expr (child[1]), updating condcodes + * IF !expr THEN + * BRK + * ENDIF + * code body (child[3]) + * label "__continueFor" // jump here for "continue" + * incr code (child[2]) + * ENDLOOP + */ + slang_atom startAtom = slang_atom_pool_gen(A->atoms, "__startFor"); + slang_atom contAtom = slang_atom_pool_gen(A->atoms, "__continueFor"); + slang_atom endAtom = slang_atom_pool_gen(A->atoms, "__endFor"); + slang_ir_node *init, *startLab, *cond, *bra, *body, *contLab; + slang_ir_node *incr, *jump, *endLab, *tree; + slang_atom prevLoopBreak = A->CurLoopBreak; + slang_atom prevLoopCont = A->CurLoopCont; + + /* Push this loop */ + A->CurLoopBreak = endAtom; + A->CurLoopCont = contAtom; + + init = _slang_gen_operation(A, &oper->children[0]); + startLab = new_label(startAtom); + tree = new_seq(init, startLab); + + cond = _slang_gen_operation(A, &oper->children[1]); + cond = _slang_gen_cond(cond); + tree = new_seq(tree, cond); + + bra = new_cjump(endAtom, 0); + tree = new_seq(tree, bra); + + body = _slang_gen_operation(A, &oper->children[3]); + tree = new_seq(tree, body); + + contLab = new_label(contAtom); + tree = new_seq(tree, contLab); + + incr = _slang_gen_operation(A, &oper->children[2]); + tree = new_seq(tree, incr); + + jump = new_jump(startAtom); + tree = new_seq(tree, jump); + + endLab = new_label(endAtom); + tree = new_seq(tree, endLab); + + /* Pop this loop */ + A->CurLoopBreak = prevLoopBreak; + A->CurLoopCont = prevLoopCont; + + return tree; +} + + /** * Generate IR tree for an if/then/else conditional using BRAnch instructions. */ @@ -2378,16 +2457,21 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) case slang_oper_do: return _slang_gen_do(A, oper); case slang_oper_for: - return _slang_gen_for(A, oper); + if (UseHighLevelInstructions) + return _slang_gen_hl_for(A, oper); + else + return _slang_gen_for(A, oper); case slang_oper_break: if (!A->CurLoopBreak) { RETURN_ERROR("'break' not in loop", 0); } + /* XXX emit IR_BREAK instruction */ return new_jump(A->CurLoopBreak); case slang_oper_continue: if (!A->CurLoopCont) { RETURN_ERROR("'continue' not in loop", 0); } + /* XXX emit IR_CONT instruction */ return new_jump(A->CurLoopCont); case slang_oper_discard: return new_node(IR_KILL, NULL, NULL); diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index b890a6d93c..3faacdd4cf 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -1265,24 +1265,29 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) } case IR_ELSE: { - struct prog_instruction *inst; + struct prog_instruction *inst, *ifInst; n->InstLocation = prog->NumInstructions; inst = new_instruction(prog, OPCODE_ELSE); /* point IF's BranchTarget just after this instruction */ assert(n->BranchNode); assert(n->BranchNode->InstLocation >= 0); - prog->Instructions[n->BranchNode->InstLocation].BranchTarget = prog->NumInstructions; + ifInst = prog->Instructions + n->BranchNode->InstLocation; + assert(ifInst->Opcode == OPCODE_IF); + ifInst->BranchTarget = prog->NumInstructions; return inst; } case IR_ENDIF: { - struct prog_instruction *inst; + struct prog_instruction *inst, *elseInst; n->InstLocation = prog->NumInstructions; inst = new_instruction(prog, OPCODE_ENDIF); /* point ELSE's BranchTarget to just after this inst */ assert(n->BranchNode); assert(n->BranchNode->InstLocation >= 0); - prog->Instructions[n->BranchNode->InstLocation].BranchTarget = prog->NumInstructions; + elseInst = prog->Instructions + n->BranchNode->InstLocation; + assert(elseInst->Opcode == OPCODE_ELSE || + elseInst->Opcode == OPCODE_IF); + elseInst->BranchTarget = prog->NumInstructions; return inst; } @@ -1295,12 +1300,15 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) break; case IR_END_LOOP: { - struct prog_instruction *inst; + struct prog_instruction *inst, *beginInst; inst = new_instruction(prog, OPCODE_ENDLOOP); assert(n->BranchNode); assert(n->BranchNode->InstLocation >= 0); /* The instruction BranchTarget points to top of loop */ inst->BranchTarget = n->BranchNode->InstLocation; + /* Update BEGIN_LOOP's BranchTarget to point to this instruction */ + beginInst = prog->Instructions + n->BranchNode->InstLocation; + beginInst->BranchTarget = prog->NumInstructions - 1; return inst; } case IR_CONT: @@ -1310,6 +1318,12 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) struct prog_instruction *inst; inst = new_instruction(prog, OPCODE_BRK); inst->DstReg.CondMask = COND_TR; /* always true */ + /* This instruction's branch target is top of loop, not bottom of + * loop because we don't know where it is yet! + */ + assert(n->BranchNode); + assert(n->BranchNode->InstLocation >= 0); + inst->BranchTarget = n->BranchNode->InstLocation; return inst; } case IR_BEGIN_SUB: diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index fbd25c0fbf..12c8aee6ea 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -625,7 +625,7 @@ execute_program( GLcontext *ctx, GLuint column ) { const GLuint MAX_EXEC = 10000; - GLint pc, total = 0, loopDepth = 0; + GLint pc, total = 0; if (DEBUG_FRAG) { printf("execute fragment program --------------------\n"); @@ -676,11 +676,8 @@ execute_program( GLcontext *ctx, } break; case OPCODE_BGNLOOP: /* begin loop */ - loopDepth++; break; case OPCODE_ENDLOOP: /* end loop */ - loopDepth--; - assert(loopDepth >= 0); /* subtract 1 here since pc is incremented by for(pc) loop */ pc = inst->BranchTarget - 1; /* go to matching BNGLOOP */ break; @@ -706,19 +703,18 @@ execute_program( GLcontext *ctx, } break; case OPCODE_BRK: /* break out of loop */ - if (loopDepth == 0) { - _mesa_problem(ctx, "BRK not inside a loop"); - } - /* search for OPCODE_ENDLOOP */ - do { - pc++; - inst = program->Base.Instructions + pc; - if (inst->Opcode == OPCODE_ENDLOOP) { - loopDepth--; - assert(loopDepth >= 0); - break; - } - } while (pc < maxInst); + { + /* The location of the ENDLOOP instruction is saved in the + * BGNLOOP instruction. Get that instruction and jump to + * its BranchTarget + 1. + */ + const struct prog_instruction *loopBeginInst + = program->Base.Instructions + inst->BranchTarget; + ASSERT(loopBeginInst->Opcode == OPCODE_BGNLOOP); + ASSERT(loopBeginInst->BranchTarget >= 0); + /* we'll add one at bottom of for-loop */ + pc = loopBeginInst->BranchTarget; + } break; case OPCODE_CAL: /* Call subroutine */ { -- cgit v1.2.3 From f22ed0986a743e033d827c78371612c7115ff913 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 6 Feb 2007 22:31:19 -0700 Subject: Implement CONT, improve BRK. IR_LOOP's BranchNode ptr is the head of a linked list of CONT and BRK nodes. After emitting loop, walk over the linked list, filling in the CONT/BRK instruction's BranchTarget field (location of the ENDLOOP instruction, or one past). --- src/mesa/shader/prog_print.c | 10 ++++++-- src/mesa/shader/slang/slang_codegen.c | 29 ++++++++++++++++++--- src/mesa/shader/slang/slang_emit.c | 47 ++++++++++++++++++++++++++--------- src/mesa/swrast/s_fragprog.c | 6 +++++ 4 files changed, 74 insertions(+), 18 deletions(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 3d4a474b05..6c303de9b5 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -338,8 +338,14 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) _mesa_printf("ENDLOOP (goto %d)\n", inst->BranchTarget); break; case OPCODE_BRK: - /* XXX just like BRA */ - _mesa_printf("BRK (%s%s) (for loop beginning at %d)", + _mesa_printf("BRK (%s%s) (goto %d)", + condcode_string(inst->DstReg.CondMask), + swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), + inst->BranchTarget); + print_comment(inst); + break; + case OPCODE_CONT: + _mesa_printf("CONT (%s%s) (goto %d)", condcode_string(inst->DstReg.CondMask), swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), inst->BranchTarget); diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index a4e2935ea8..42c1f0897e 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -608,7 +608,24 @@ new_break(slang_ir_node *loopNode) assert(loopNode); assert(loopNode->Opcode == IR_LOOP); if (n) { - n->BranchNode = loopNode; + /* insert this node at head of linked list */ + n->BranchNode = loopNode->BranchNode; + loopNode->BranchNode = n; + } + return n; +} + + +static slang_ir_node * +new_cont(slang_ir_node *loopNode) +{ + slang_ir_node *n = new_node0(IR_CONT); + assert(loopNode); + assert(loopNode->Opcode == IR_LOOP); + if (n) { + /* insert this node at head of linked list */ + n->BranchNode = loopNode->BranchNode; + loopNode->BranchNode = n; } return n; } @@ -2434,11 +2451,15 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) return new_jump(A->CurLoopBreak); } case slang_oper_continue: - if (!A->CurLoopCont) { + if (!A->CurLoop && !A->CurLoopCont) { RETURN_ERROR("'continue' not in loop", 0); } - /* XXX emit IR_CONT instruction */ - return new_jump(A->CurLoopCont); + if (UseHighLevelInstructions) { + return new_cont(A->CurLoop); + } + else { + return new_jump(A->CurLoopCont); + } case slang_oper_discard: return new_node0(IR_KILL); diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index c18f1e364c..2d5a7cf6f9 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -1303,7 +1303,9 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) case IR_LOOP: { - struct prog_instruction *beginInst; + struct prog_instruction *beginInst, *endInst; + GLuint endInstLoc; + slang_ir_node *p; /* save location of this instruction, used by OPCODE_ENDLOOP */ n->InstLocation = prog->NumInstructions; @@ -1312,27 +1314,48 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) /* body */ emit(vt, n->Children[0], prog); - inst = new_instruction(prog, OPCODE_ENDLOOP); - /* The instruction BranchTarget points to top of loop */ - inst->BranchTarget = n->InstLocation; + endInstLoc = prog->NumInstructions; + endInst = new_instruction(prog, OPCODE_ENDLOOP); + /* The ENDLOOP's BranchTarget points to top of loop */ + endInst->BranchTarget = n->InstLocation; /* Update BGNLOOP's BranchTarget to point to this instruction */ beginInst = prog->Instructions + n->InstLocation; beginInst->BranchTarget = prog->NumInstructions - 1; - return inst; + + /* Done emitting loop code. Now walk over the loop's linked list + * of BREAK and CONT nodes, filling in their BranchTarget fields. + */ + for (p = n->BranchNode; p; p = p->BranchNode) { + if (p->Opcode == IR_BREAK) { + struct prog_instruction *brkInst + = prog->Instructions + p->InstLocation; + assert(brkInst->Opcode == OPCODE_BRK); + brkInst->BranchTarget = endInstLoc + 1; + } + else { + assert(p->Opcode == IR_CONT); + struct prog_instruction *contInst + = prog->Instructions + p->InstLocation; + assert(contInst->Opcode == OPCODE_CONT); + contInst->BranchTarget = endInstLoc; + } + } + return NULL; } case IR_CONT: - return new_instruction(prog, OPCODE_CONT); + { + struct prog_instruction *inst; + n->InstLocation = prog->NumInstructions; + inst = new_instruction(prog, OPCODE_CONT); + inst->DstReg.CondMask = COND_TR; /* always true */ + return inst; + } case IR_BREAK: { struct prog_instruction *inst; + n->InstLocation = prog->NumInstructions; inst = new_instruction(prog, OPCODE_BRK); inst->DstReg.CondMask = COND_TR; /* always true */ - /* This instruction's branch target is top of loop, not bottom of - * loop because we don't know where it is yet! - */ - assert(n->BranchNode); - assert(n->BranchNode->InstLocation >= 0); - inst->BranchTarget = n->BranchNode->InstLocation; return inst; } diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 12c8aee6ea..63974b30f2 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -704,6 +704,7 @@ execute_program( GLcontext *ctx, break; case OPCODE_BRK: /* break out of loop */ { +#if 0 /* The location of the ENDLOOP instruction is saved in the * BGNLOOP instruction. Get that instruction and jump to * its BranchTarget + 1. @@ -714,6 +715,9 @@ execute_program( GLcontext *ctx, ASSERT(loopBeginInst->BranchTarget >= 0); /* we'll add one at bottom of for-loop */ pc = loopBeginInst->BranchTarget; +#else + pc = inst->BranchTarget - 1; +#endif } break; case OPCODE_CAL: /* Call subroutine */ @@ -747,6 +751,8 @@ execute_program( GLcontext *ctx, } break; case OPCODE_CONT: /* continue loop */ + /* Subtract 1 here since we'll do pc++ at end of for-loop */ + pc = inst->BranchTarget - 1; break; case OPCODE_COS: { -- cgit v1.2.3 From c5e6bf63e6f8256c9e10bbbe8fb7a38de9d22921 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 7 Feb 2007 16:09:13 -0700 Subject: s/%f/%g/ --- src/mesa/shader/prog_print.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 6c303de9b5..0adb589daa 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -429,7 +429,7 @@ _mesa_print_parameter_list(const struct gl_program_parameter_list *list) for (i = 0; i < list->NumParameters; i++){ struct gl_program_parameter *param = list->Parameters + i; const GLfloat *v = list->ParameterValues[i]; - _mesa_printf("param[%d] sz=%d %s %s = {%.3f, %.3f, %.3f, %.3f};\n", + _mesa_printf("param[%d] sz=%d %s %s = {%.3g, %.3g, %.3g, %.3g};\n", i, param->Size, program_file_string(list->Parameters[i].Type), param->Name, v[0], v[1], v[2], v[3]); -- cgit v1.2.3 From 501ee87180047dd04afc69103c31e1eae5374bf1 Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 17 Feb 2007 09:15:00 -0700 Subject: Lots of changes to prog_print.c code. Mainly, allow printing programs in either ARB, NV or "debug" formats. --- src/mesa/shader/prog_print.c | 352 ++++++++++++++++++++++++++++++++++++++----- src/mesa/shader/prog_print.h | 24 ++- src/mesa/swrast/s_fragprog.c | 3 +- src/mesa/tnl/t_vp_build.c | 2 +- 4 files changed, 336 insertions(+), 45 deletions(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 0adb589daa..647ade9505 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -37,11 +37,12 @@ #include "prog_statevars.h" + /** * Return string name for given program/register file. */ static const char * -program_file_string(enum register_file f) +file_string(enum register_file f, gl_prog_print_mode mode) { switch (f) { case PROGRAM_TEMPORARY: @@ -76,6 +77,213 @@ program_file_string(enum register_file f) } +/** + * Return ARB_v/f_prog-style input attrib string. + */ +static const char * +arb_input_attrib_string(GLint index, GLenum progType) +{ + const char *vertAttribs[] = { + "vertex.position", + "vertex.weight", + "vertex.normal", + "vertex.color.primary", + "vertex.color.secondary", + "vertex.fogcoord", + "vertex.(six)", + "vertex.(seven)", + "vertex.texcoord[0]", + "vertex.texcoord[1]", + "vertex.texcoord[2]", + "vertex.texcoord[3]", + "vertex.texcoord[4]", + "vertex.texcoord[5]", + "vertex.texcoord[6]", + "vertex.texcoord[7]" + }; + const char *fragAttribs[] = { + "fragment.position", + "fragment.color.primary", + "fragment.color.secondary", + "fragment.fogcoord", + "fragment.texcoord[0]", + "fragment.texcoord[1]", + "fragment.texcoord[2]", + "fragment.texcoord[3]", + "fragment.texcoord[4]", + "fragment.texcoord[5]", + "fragment.texcoord[6]", + "fragment.texcoord[7]", + "fragment.varying[0]", + "fragment.varying[1]", + "fragment.varying[2]", + "fragment.varying[3]", + "fragment.varying[4]", + "fragment.varying[5]", + "fragment.varying[6]", + "fragment.varying[7]" + }; + + if (progType == GL_VERTEX_PROGRAM_ARB) { + assert(index < sizeof(vertAttribs) / sizeof(vertAttribs[0])); + return vertAttribs[index]; + } + else { + assert(index < sizeof(fragAttribs) / sizeof(fragAttribs[0])); + return fragAttribs[index]; + } +} + + +/** + * Return ARB_v/f_prog-style output attrib string. + */ +static const char * +arb_output_attrib_string(GLint index, GLenum progType) +{ + const char *vertResults[] = { + "result.position", + "result.color.primary", + "result.color.secondary", + "result.fogcoord", + "result.texcoord[0]", + "result.texcoord[1]", + "result.texcoord[2]", + "result.texcoord[3]", + "result.texcoord[4]", + "result.texcoord[5]", + "result.texcoord[6]", + "result.texcoord[7]", + "result.varying[0]", + "result.varying[1]", + "result.varying[2]", + "result.varying[3]", + "result.varying[4]", + "result.varying[5]", + "result.varying[6]", + "result.varying[7]" + }; + const char *fragResults[] = { + "result.color", + "result.depth" + }; + + if (progType == GL_VERTEX_PROGRAM_ARB) { + assert(index < sizeof(vertResults) / sizeof(vertResults[0])); + return vertResults[index]; + } + else { + assert(index < sizeof(fragResults) / sizeof(fragResults[0])); + return fragResults[index]; + } +} + + +/** + * Return string representation of the given register. + * Note that some types of registers (like PROGRAM_UNIFORM) aren't defined + * by the ARB/NV program languages so we've taken some liberties here. + * \param file the register file (PROGRAM_INPUT, PROGRAM_TEMPORARY, etc) + * \param index number of the register in the register file + * \param mode the output format/mode/style + * \param prog pointer to containing program + */ +static const char * +reg_string(enum register_file f, GLint index, gl_prog_print_mode mode, + const struct gl_program *prog) +{ + static char str[100]; + + str[0] = 0; + + switch (mode) { + case PROG_PRINT_DEBUG: + sprintf(str, "%s[%d]", file_string(f, mode), index); + break; + + case PROG_PRINT_ARB: + switch (f) { + case PROGRAM_INPUT: + sprintf(str, "%s", arb_input_attrib_string(index, prog->Target)); + break; + case PROGRAM_OUTPUT: + sprintf(str, "%s", arb_output_attrib_string(index, prog->Target)); + break; + case PROGRAM_TEMPORARY: + sprintf(str, "temp%d", index); + break; + case PROGRAM_ENV_PARAM: + sprintf(str, "program.env[%d]", index); + break; + case PROGRAM_LOCAL_PARAM: + sprintf(str, "program.local[%d]", index); + break; + case PROGRAM_VARYING: /* extension */ + sprintf(str, "varying[%d]", index); + break; + case PROGRAM_CONSTANT: /* extension */ + sprintf(str, "constant[%d]", index); + break; + case PROGRAM_UNIFORM: /* extension */ + sprintf(str, "uniform[%d]", index); + break; + case PROGRAM_STATE_VAR: + { + struct gl_program_parameter *param + = prog->Parameters->Parameters + index; + sprintf(str, _mesa_program_state_string(param->StateIndexes)); + } + break; + case PROGRAM_ADDRESS: + sprintf(str, "A%d", index); + break; + default: + _mesa_problem(NULL, "bad file in reg_string()"); + } + break; + + case PROG_PRINT_NV: + switch (f) { + case PROGRAM_INPUT: + if (prog->Target == GL_VERTEX_PROGRAM_ARB) + sprintf(str, "v[%d]", index); + else + sprintf(str, "f[%d]", index); + break; + case PROGRAM_OUTPUT: + sprintf(str, "o[%d]", index); + break; + case PROGRAM_TEMPORARY: + sprintf(str, "R%d", index); + break; + case PROGRAM_ENV_PARAM: + sprintf(str, "c[%d]", index); + break; + case PROGRAM_VARYING: /* extension */ + sprintf(str, "varying[%d]", index); + break; + case PROGRAM_UNIFORM: /* extension */ + sprintf(str, "uniform[%d]", index); + break; + case PROGRAM_CONSTANT: /* extension */ + sprintf(str, "constant[%d]", index); + break; + case PROGRAM_STATE_VAR: /* extension */ + sprintf(str, "state[%d]", index); + break; + default: + _mesa_problem(NULL, "bad file in reg_string()"); + } + break; + + default: + _mesa_problem(NULL, "bad mode in reg_string()"); + } + + return str; +} + + /** * Return a string representation of the given swizzle word. * If extended is true, use extended (comma-separated) format. @@ -172,22 +380,38 @@ condcode_string(GLuint condcode) static void -print_dst_reg(const struct prog_dst_register *dstReg) +print_dst_reg(const struct prog_dst_register *dstReg, gl_prog_print_mode mode, + const struct gl_program *prog) { - _mesa_printf(" %s[%d]%s", - program_file_string((enum register_file) dstReg->File), + _mesa_printf("%s%s", + reg_string((enum register_file) dstReg->File, + dstReg->Index, mode, prog), + writemask_string(dstReg->WriteMask)); + +#if 0 + _mesa_printf("%s[%d]%s", + file_string((enum register_file) dstReg->File, mode), dstReg->Index, writemask_string(dstReg->WriteMask)); +#endif } static void -print_src_reg(const struct prog_src_register *srcReg) +print_src_reg(const struct prog_src_register *srcReg, gl_prog_print_mode mode, + const struct gl_program *prog) { + _mesa_printf("%s%s", + reg_string((enum register_file) srcReg->File, + srcReg->Index, mode, prog), + swizzle_string(srcReg->Swizzle, + srcReg->NegateBase, GL_FALSE)); +#if 0 _mesa_printf("%s[%d]%s", - program_file_string((enum register_file) srcReg->File), + file_string((enum register_file) srcReg->File, mode), srcReg->Index, swizzle_string(srcReg->Swizzle, srcReg->NegateBase, GL_FALSE)); +#endif } static void @@ -200,10 +424,11 @@ print_comment(const struct prog_instruction *inst) } -void -_mesa_print_alu_instruction(const struct prog_instruction *inst, - const char *opcode_string, - GLuint numRegs) +static void +print_alu_instruction(const struct prog_instruction *inst, + const char *opcode_string, GLuint numRegs, + gl_prog_print_mode mode, + const struct gl_program *prog) { GLuint j; @@ -215,8 +440,9 @@ _mesa_print_alu_instruction(const struct prog_instruction *inst, if (inst->SaturateMode == SATURATE_ZERO_ONE) _mesa_printf("_SAT"); + _mesa_printf(" "); if (inst->DstReg.File != PROGRAM_UNDEFINED) { - print_dst_reg(&inst->DstReg); + print_dst_reg(&inst->DstReg, mode, prog); } else { _mesa_printf(" ???"); @@ -226,7 +452,7 @@ _mesa_print_alu_instruction(const struct prog_instruction *inst, _mesa_printf(", "); for (j = 0; j < numRegs; j++) { - print_src_reg(inst->SrcReg + j); + print_src_reg(inst->SrcReg + j, mode, prog); if (j + 1 < numRegs) _mesa_printf(", "); } @@ -235,11 +461,21 @@ _mesa_print_alu_instruction(const struct prog_instruction *inst, } +void +_mesa_print_instruction(const struct prog_instruction *inst) +{ + /* note: 4th param should be ignored for PROG_PRINT_DEBUG */ + _mesa_print_instruction_opt(inst, 0, PROG_PRINT_DEBUG, NULL); +} + + /** * Print a single vertex/fragment program instruction. */ GLint -_mesa_print_instruction(const struct prog_instruction *inst, GLint indent) +_mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent, + gl_prog_print_mode mode, + const struct gl_program *prog) { GLuint i; @@ -260,7 +496,8 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { _mesa_printf(", "); _mesa_printf("%s[%d]%s", - program_file_string((enum register_file) inst->SrcReg[0].File), + file_string((enum register_file) inst->SrcReg[0].File, + mode), inst->SrcReg[0].Index, swizzle_string(inst->SrcReg[0].Swizzle, inst->SrcReg[0].NegateBase, GL_FALSE)); @@ -273,9 +510,11 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) _mesa_printf("SWZ"); if (inst->SaturateMode == SATURATE_ZERO_ONE) _mesa_printf("_SAT"); - print_dst_reg(&inst->DstReg); + _mesa_printf(" "); + print_dst_reg(&inst->DstReg, mode, prog); _mesa_printf("%s[%d], %s", - program_file_string((enum register_file) inst->SrcReg[0].File), + file_string((enum register_file) inst->SrcReg[0].File, + mode), inst->SrcReg[0].Index, swizzle_string(inst->SrcReg[0].Swizzle, inst->SrcReg[0].NegateBase, GL_TRUE)); @@ -287,9 +526,10 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) _mesa_printf("%s", _mesa_opcode_string(inst->Opcode)); if (inst->SaturateMode == SATURATE_ZERO_ONE) _mesa_printf("_SAT"); - print_dst_reg(&inst->DstReg); + _mesa_printf(" "); + print_dst_reg(&inst->DstReg, mode, prog); _mesa_printf(", "); - print_src_reg(&inst->SrcReg[0]); + print_src_reg(&inst->SrcReg[0], mode, prog); _mesa_printf(", texture[%d], ", inst->TexSrcUnit); switch (inst->TexSrcTarget) { case TEXTURE_1D_INDEX: _mesa_printf("1D"); break; @@ -304,7 +544,7 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) break; case OPCODE_ARL: _mesa_printf("ARL addr.x, "); - print_src_reg(&inst->SrcReg[0]); + print_src_reg(&inst->SrcReg[0], mode, prog); print_comment(inst); break; case OPCODE_BRA: @@ -319,49 +559,48 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) print_comment(inst); break; case OPCODE_IF: - _mesa_printf("IF (%s%s) (if false, goto %d)", + _mesa_printf("IF (%s%s); # (if false, goto %d)", condcode_string(inst->DstReg.CondMask), swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), inst->BranchTarget); print_comment(inst); return indent + 3; case OPCODE_ELSE: - _mesa_printf("ELSE (goto %d)\n", inst->BranchTarget); + _mesa_printf("ELSE; # (goto %d)\n", inst->BranchTarget); return indent + 3; case OPCODE_ENDIF: - _mesa_printf("ENDIF\n"); + _mesa_printf("ENDIF;\n"); break; case OPCODE_BGNLOOP: - _mesa_printf("BGNLOOP (end at %d)\n", inst->BranchTarget); + _mesa_printf("BGNLOOP; # (end at %d)\n", inst->BranchTarget); return indent + 3; case OPCODE_ENDLOOP: - _mesa_printf("ENDLOOP (goto %d)\n", inst->BranchTarget); + _mesa_printf("ENDLOOP; # (goto %d)\n", inst->BranchTarget); break; case OPCODE_BRK: - _mesa_printf("BRK (%s%s) (goto %d)", + _mesa_printf("BRK (%s%s); #(goto %d)", condcode_string(inst->DstReg.CondMask), swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), inst->BranchTarget); print_comment(inst); break; case OPCODE_CONT: - _mesa_printf("CONT (%s%s) (goto %d)", + _mesa_printf("CONT (%s%s); #(goto %d)", condcode_string(inst->DstReg.CondMask), swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), inst->BranchTarget); print_comment(inst); break; case OPCODE_BGNSUB: - _mesa_printf("SUB;\n"); + _mesa_printf("SUB"); print_comment(inst); return indent + 3; case OPCODE_ENDSUB: - _mesa_printf("ENDSUB;\n"); + _mesa_printf("ENDSUB"); print_comment(inst); break; case OPCODE_END: - _mesa_printf("END"); - print_comment(inst); + _mesa_printf("END\n"); break; case OPCODE_NOP: _mesa_printf("NOP"); @@ -370,9 +609,10 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) /* XXX may need other special-case instructions */ default: /* typical alu instruction */ - _mesa_print_alu_instruction(inst, - _mesa_opcode_string(inst->Opcode), - _mesa_num_inst_src_regs(inst->Opcode)); + print_alu_instruction(inst, + _mesa_opcode_string(inst->Opcode), + _mesa_num_inst_src_regs(inst->Opcode), + mode, prog); break; } return indent; @@ -380,16 +620,50 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) /** - * Print a vertx/fragment program to stdout. - * XXX this function could be greatly improved. + * Print program to stdout, default options. */ void _mesa_print_program(const struct gl_program *prog) +{ + _mesa_print_program_opt(prog, PROG_PRINT_ARB, GL_TRUE); +} + + +/** + * Print program, with options. + */ +void +_mesa_print_program_opt(const struct gl_program *prog, + gl_prog_print_mode mode, + GLboolean lineNumbers) { GLuint i, indent = 0; + + switch (prog->Target) { + case GL_VERTEX_PROGRAM_ARB: + if (mode == PROG_PRINT_ARB) + _mesa_printf("!!ARBvp1.0\n"); + else if (mode == PROG_PRINT_NV) + _mesa_printf("!!VP1.0\n"); + else + _mesa_printf("# Vertex Program/Shader\n"); + break; + case GL_FRAGMENT_PROGRAM_ARB: + case GL_FRAGMENT_PROGRAM_NV: + if (mode == PROG_PRINT_ARB) + _mesa_printf("!!ARBfp1.0\n"); + else if (mode == PROG_PRINT_NV) + _mesa_printf("!!FP1.0\n"); + else + _mesa_printf("# Fragment Program/Shader\n"); + break; + } + for (i = 0; i < prog->NumInstructions; i++) { - _mesa_printf("%3d: ", i); - indent = _mesa_print_instruction(prog->Instructions + i, indent); + if (lineNumbers) + _mesa_printf("%3d: ", i); + indent = _mesa_print_instruction_opt(prog->Instructions + i, + indent, mode, prog); } } @@ -424,14 +698,16 @@ _mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog) void _mesa_print_parameter_list(const struct gl_program_parameter_list *list) { + const gl_prog_print_mode mode = PROG_PRINT_DEBUG; GLuint i; + _mesa_printf("param list %p\n", (void *) list); for (i = 0; i < list->NumParameters; i++){ struct gl_program_parameter *param = list->Parameters + i; const GLfloat *v = list->ParameterValues[i]; _mesa_printf("param[%d] sz=%d %s %s = {%.3g, %.3g, %.3g, %.3g};\n", i, param->Size, - program_file_string(list->Parameters[i].Type), + file_string(list->Parameters[i].Type, mode), param->Name, v[0], v[1], v[2], v[3]); } } diff --git a/src/mesa/shader/prog_print.h b/src/mesa/shader/prog_print.h index 19aaa53800..79c599f5a7 100644 --- a/src/mesa/shader/prog_print.h +++ b/src/mesa/shader/prog_print.h @@ -27,17 +27,31 @@ #define PROG_PRINT_H -extern GLint -_mesa_print_instruction(const struct prog_instruction *inst, GLint indent); +/** + * The output style to use when printing programs. + */ +typedef enum { + PROG_PRINT_ARB, + PROG_PRINT_NV, + PROG_PRINT_DEBUG +} gl_prog_print_mode; + extern void -_mesa_print_alu_instruction(const struct prog_instruction *inst, - const char *opcode_string, - GLuint numRegs); +_mesa_print_instruction(const struct prog_instruction *inst); + +extern GLint +_mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent, + gl_prog_print_mode mode, + const struct gl_program *prog); extern void _mesa_print_program(const struct gl_program *prog); +extern void +_mesa_print_program_opt(const struct gl_program *prog, gl_prog_print_mode mode, + GLboolean lineNumbers); + extern void _mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog); diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index fe41c0b5f4..89907f73c6 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -554,6 +554,7 @@ init_machine_deriv( GLcontext *ctx, _mesa_memcpy(dMachine, machine, sizeof(struct fp_machine)); if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) { + /* XXX also need to do this when using valgrind */ /* Clear temporary registers (undefined for ARB_f_p) */ _mesa_bzero( (void*) machine->Temporaries, MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); @@ -665,7 +666,7 @@ execute_program( GLcontext *ctx, } if (DEBUG_FRAG) { - _mesa_print_instruction(inst, 0); + _mesa_print_instruction(inst); } switch (inst->Opcode) { diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c index 6fb14e7caa..47fed32904 100644 --- a/src/mesa/tnl/t_vp_build.c +++ b/src/mesa/tnl/t_vp_build.c @@ -497,7 +497,7 @@ static void debug_insn( struct prog_instruction *inst, const char *fn, } _mesa_printf("%d:\t", line); - _mesa_print_instruction(inst, 0); + _mesa_print_instruction(inst); } } -- cgit v1.2.3 From 9449a4d8945de684609663468b96b7ed3aa884b9 Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 17 Feb 2007 09:41:59 -0700 Subject: s/PROG_PRINT_ARB/PROG_PRINT_DEBUG/ --- src/mesa/shader/prog_print.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 647ade9505..9560ffad7d 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -625,7 +625,7 @@ _mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent, void _mesa_print_program(const struct gl_program *prog) { - _mesa_print_program_opt(prog, PROG_PRINT_ARB, GL_TRUE); + _mesa_print_program_opt(prog, PROG_PRINT_DEBUG, GL_TRUE); } -- cgit v1.2.3 From 7b30053b264726156a018c822657270e745320ce Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 22 Feb 2007 09:08:36 -0700 Subject: fix negative indentation problem --- src/mesa/shader/prog_print.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 9560ffad7d..95b62fcfb5 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -477,7 +477,7 @@ _mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent, gl_prog_print_mode mode, const struct gl_program *prog) { - GLuint i; + GLint i; if (inst->Opcode == OPCODE_ELSE || inst->Opcode == OPCODE_ENDIF || @@ -485,7 +485,6 @@ _mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent, inst->Opcode == OPCODE_ENDSUB) { indent -= 3; } - assert(indent >= 0); for (i = 0; i < indent; i++) { _mesa_printf(" "); } -- cgit v1.2.3 From 059376c855cbeb160e98f438a35edb8bd88b8bb2 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 22 Feb 2007 17:45:32 -0700 Subject: expose _mesa_swizzle_string() --- src/mesa/shader/prog_print.c | 34 ++++++++++++++++++++-------------- src/mesa/shader/prog_print.h | 3 +++ 2 files changed, 23 insertions(+), 14 deletions(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 95b62fcfb5..0d21912a0e 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -291,8 +291,8 @@ reg_string(enum register_file f, GLint index, gl_prog_print_mode mode, * \param negateBase 4-bit negation vector * \param extended if true, also allow 0, 1 values */ -static const char * -swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended) +const char * +_mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended) { static const char swz[] = "xyzw01?!"; static char s[20]; @@ -403,13 +403,13 @@ print_src_reg(const struct prog_src_register *srcReg, gl_prog_print_mode mode, _mesa_printf("%s%s", reg_string((enum register_file) srcReg->File, srcReg->Index, mode, prog), - swizzle_string(srcReg->Swizzle, + _mesa_swizzle_string(srcReg->Swizzle, srcReg->NegateBase, GL_FALSE)); #if 0 _mesa_printf("%s[%d]%s", file_string((enum register_file) srcReg->File, mode), srcReg->Index, - swizzle_string(srcReg->Swizzle, + _mesa_swizzle_string(srcReg->Swizzle, srcReg->NegateBase, GL_FALSE)); #endif } @@ -498,8 +498,8 @@ _mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent, file_string((enum register_file) inst->SrcReg[0].File, mode), inst->SrcReg[0].Index, - swizzle_string(inst->SrcReg[0].Swizzle, - inst->SrcReg[0].NegateBase, GL_FALSE)); + _mesa_swizzle_string(inst->SrcReg[0].Swizzle, + inst->SrcReg[0].NegateBase, GL_FALSE)); } if (inst->Comment) _mesa_printf(" # %s", inst->Comment); @@ -515,8 +515,8 @@ _mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent, file_string((enum register_file) inst->SrcReg[0].File, mode), inst->SrcReg[0].Index, - swizzle_string(inst->SrcReg[0].Swizzle, - inst->SrcReg[0].NegateBase, GL_TRUE)); + _mesa_swizzle_string(inst->SrcReg[0].Swizzle, + inst->SrcReg[0].NegateBase, GL_TRUE)); print_comment(inst); break; case OPCODE_TEX: @@ -550,7 +550,7 @@ _mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent, _mesa_printf("BRA %u (%s%s)", inst->BranchTarget, condcode_string(inst->DstReg.CondMask), - swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE)); + _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE)); print_comment(inst); break; case OPCODE_CAL: @@ -560,7 +560,7 @@ _mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent, case OPCODE_IF: _mesa_printf("IF (%s%s); # (if false, goto %d)", condcode_string(inst->DstReg.CondMask), - swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), + _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), inst->BranchTarget); print_comment(inst); return indent + 3; @@ -579,14 +579,14 @@ _mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent, case OPCODE_BRK: _mesa_printf("BRK (%s%s); #(goto %d)", condcode_string(inst->DstReg.CondMask), - swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), + _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), inst->BranchTarget); print_comment(inst); break; case OPCODE_CONT: _mesa_printf("CONT (%s%s); #(goto %d)", condcode_string(inst->DstReg.CondMask), - swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), + _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), inst->BranchTarget); print_comment(inst); break; @@ -602,8 +602,14 @@ _mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent, _mesa_printf("END\n"); break; case OPCODE_NOP: - _mesa_printf("NOP"); - print_comment(inst); + if (mode == PROG_PRINT_DEBUG) { + _mesa_printf("NOP"); + print_comment(inst); + } + else if (inst->Comment) { + /* ARB/NV extensions don't have NOP instruction */ + _mesa_printf("# %s\n", inst->Comment); + } break; /* XXX may need other special-case instructions */ default: diff --git a/src/mesa/shader/prog_print.h b/src/mesa/shader/prog_print.h index 79c599f5a7..c0101b6b0f 100644 --- a/src/mesa/shader/prog_print.h +++ b/src/mesa/shader/prog_print.h @@ -37,6 +37,9 @@ typedef enum { } gl_prog_print_mode; +extern const char * +_mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended); + extern void _mesa_print_instruction(const struct prog_instruction *inst); -- cgit v1.2.3 From 0020d1022f4b5befe4adf783bedc4cf83e09f01f Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 23 Feb 2007 11:43:44 -0700 Subject: re-expose _mesa_print_alu_instruction() --- src/mesa/shader/prog_print.c | 10 +++++++++- src/mesa/shader/prog_print.h | 4 ++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 0d21912a0e..4519f0c030 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -426,7 +426,7 @@ print_comment(const struct prog_instruction *inst) static void print_alu_instruction(const struct prog_instruction *inst, - const char *opcode_string, GLuint numRegs, + const char *opcode_string, GLuint numRegs, gl_prog_print_mode mode, const struct gl_program *prog) { @@ -461,6 +461,14 @@ print_alu_instruction(const struct prog_instruction *inst, } +void +_mesa_print_alu_instruction(const struct prog_instruction *inst, + const char *opcode_string, GLuint numRegs) +{ + print_alu_instruction(inst, opcode_string, numRegs, PROG_PRINT_DEBUG, NULL); +} + + void _mesa_print_instruction(const struct prog_instruction *inst) { diff --git a/src/mesa/shader/prog_print.h b/src/mesa/shader/prog_print.h index c0101b6b0f..9c7607f9d5 100644 --- a/src/mesa/shader/prog_print.h +++ b/src/mesa/shader/prog_print.h @@ -40,6 +40,10 @@ typedef enum { extern const char * _mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended); +extern void +_mesa_print_alu_instruction(const struct prog_instruction *inst, + const char *opcode_string, GLuint numRegs); + extern void _mesa_print_instruction(const struct prog_instruction *inst); -- cgit v1.2.3 From 1936b25ebd580c5ef9e8cb471a986da39ef46ca5 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 22 Mar 2007 09:04:18 -0600 Subject: print conditional writemask, if enabled --- src/mesa/shader/prog_print.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 4519f0c030..d290ce0a2a 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -388,6 +388,12 @@ print_dst_reg(const struct prog_dst_register *dstReg, gl_prog_print_mode mode, dstReg->Index, mode, prog), writemask_string(dstReg->WriteMask)); + if (dstReg->CondMask != COND_TR) { + _mesa_printf(" (%s.%s)", + condcode_string(dstReg->CondMask), + _mesa_swizzle_string(dstReg->CondSwizzle, GL_FALSE, GL_FALSE)); + } + #if 0 _mesa_printf("%s[%d]%s", file_string((enum register_file) dstReg->File, mode), -- cgit v1.2.3 From 63556fa9949f543a8134b6b5ff3d216acb71dd9f Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 23 Mar 2007 14:47:46 -0600 Subject: Add the ability to generate programs that doesn't use condition codes. ctx->Shader.EmitCondCodes determines if we use condition codes. If not, IF statement uses first operand's X component as the condition. Added OPCODE_BRK0, OPCODE_BRK1, OPCODE_CONT0, OPCODE_CONT1 to handle the common cases of conditional break/continue. --- src/mesa/main/mtypes.h | 6 +- src/mesa/shader/prog_execute.c | 53 +++++++++++++--- src/mesa/shader/prog_instruction.c | 6 +- src/mesa/shader/prog_instruction.h | 4 ++ src/mesa/shader/prog_print.c | 30 +++++++-- src/mesa/shader/shader_api.c | 1 + src/mesa/shader/slang/slang_emit.c | 123 ++++++++++++++++++++++++++----------- src/mesa/tnl/t_vb_arbprogram.c | 4 ++ 8 files changed, 176 insertions(+), 51 deletions(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 0c9bf200d8..828b0f2384 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2127,8 +2127,10 @@ struct gl_shader_program struct gl_shader_state { struct gl_shader_program *CurrentProgram; /**< The user-bound program */ - GLboolean EmitHighLevelInstructions; /**< Driver-selectable */ - GLboolean EmitComments; /**< Driver-selectable */ + /** Driver-selectable options: */ + GLboolean EmitHighLevelInstructions; /**< IF/ELSE/ENDIF vs. BRA, etc. */ + GLboolean EmitCondCodes; /**< Use condition codes? */ + GLboolean EmitComments; /**< Annotated instructions */ }; diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c index 092c07f7b6..f881d477ca 100644 --- a/src/mesa/shader/prog_execute.c +++ b/src/mesa/shader/prog_execute.c @@ -720,6 +720,32 @@ _mesa_execute_program(GLcontext * ctx, pc = inst->BranchTarget - 1; } break; + case OPCODE_BRK0: /* Break if zero */ + /* fall-through */ + case OPCODE_CONT0: /* Continue if zero */ + { + GLfloat a[4]; + fetch_vector1(&inst->SrcReg[0], machine, a); + if (a[0] == 0.0) { + /* take branch */ + /* Subtract 1 here since we'll do pc++ at end of for-loop */ + pc = inst->BranchTarget - 1; + } + } + break; + case OPCODE_BRK1: /* Break if non-zero */ + /* fall-through */ + case OPCODE_CONT1: /* Continue if non-zero */ + { + GLfloat a[4]; + fetch_vector1(&inst->SrcReg[0], machine, a); + if (a[0] != 0.0) { + /* take branch */ + /* Subtract 1 here since we'll do pc++ at end of for-loop */ + pc = inst->BranchTarget - 1; + } + } + break; case OPCODE_CAL: /* Call subroutine (conditional) */ if (eval_condition(machine, inst)) { /* call the subroutine */ @@ -914,13 +940,26 @@ _mesa_execute_program(GLcontext * ctx, } break; case OPCODE_IF: - if (eval_condition(machine, inst)) { - /* do if-clause (just continue execution) */ - } - else { - /* go to the instruction after ELSE or ENDIF */ - assert(inst->BranchTarget >= 0); - pc = inst->BranchTarget - 1; + { + GLboolean cond; + /* eval condition */ + if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { + GLfloat a[4]; + fetch_vector1(&inst->SrcReg[0], machine, a); + cond = (a[0] != 0.0); + } + else { + cond = eval_condition(machine, inst); + } + /* do if/else */ + if (cond) { + /* do if-clause (just continue execution) */ + } + else { + /* go to the instruction after ELSE or ENDIF */ + assert(inst->BranchTarget >= 0); + pc = inst->BranchTarget - 1; + } } break; case OPCODE_ELSE: diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c index ed479a7f61..272caf6c74 100644 --- a/src/mesa/shader/prog_instruction.c +++ b/src/mesa/shader/prog_instruction.c @@ -138,9 +138,13 @@ static const struct instruction_info InstInfo[MAX_OPCODE] = { { OPCODE_BGNSUB, "BGNSUB", 0 }, { OPCODE_BRA, "BRA", 0 }, { OPCODE_BRK, "BRK", 0 }, + { OPCODE_BRK0, "BRK0", 1 }, + { OPCODE_BRK1, "BRK1", 1 }, { OPCODE_CAL, "CAL", 0 }, { OPCODE_CMP, "CMP", 3 }, - { OPCODE_CONT, "CONT", 1 }, + { OPCODE_CONT, "CONT", 0 }, + { OPCODE_CONT0, "CONT0", 1 }, + { OPCODE_CONT1, "CONT1", 1 }, { OPCODE_COS, "COS", 1 }, { OPCODE_DDX, "DDX", 1 }, { OPCODE_DDY, "DDY", 1 }, diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h index c800757aa0..dc2d2dc29b 100644 --- a/src/mesa/shader/prog_instruction.h +++ b/src/mesa/shader/prog_instruction.h @@ -153,9 +153,13 @@ typedef enum prog_opcode { OPCODE_BGNSUB, /* opt */ OPCODE_BRA, /* 2 X */ OPCODE_BRK, /* 2 opt */ + OPCODE_BRK0, /* opt */ + OPCODE_BRK1, /* opt */ OPCODE_CAL, /* 2 2 */ OPCODE_CMP, /* X */ OPCODE_CONT, /* opt */ + OPCODE_CONT0, /* opt */ + OPCODE_CONT1, /* opt */ OPCODE_COS, /* X 2 X X */ OPCODE_DDX, /* X X */ OPCODE_DDY, /* X X */ diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index d290ce0a2a..39d2a07812 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -572,10 +572,20 @@ _mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent, print_comment(inst); break; case OPCODE_IF: - _mesa_printf("IF (%s%s); # (if false, goto %d)", - condcode_string(inst->DstReg.CondMask), - _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), - inst->BranchTarget); + if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { + /* Use ordinary register */ + _mesa_printf("IF "); + print_src_reg(&inst->SrcReg[0], mode, prog); + _mesa_printf("; "); + } + else { + /* Use cond codes */ + _mesa_printf("IF (%s%s);", + condcode_string(inst->DstReg.CondMask), + _mesa_swizzle_string(inst->DstReg.CondSwizzle, + 0, GL_FALSE)); + } + _mesa_printf(" # (if false, goto %d)", inst->BranchTarget); print_comment(inst); return indent + 3; case OPCODE_ELSE: @@ -604,6 +614,18 @@ _mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent, inst->BranchTarget); print_comment(inst); break; + + case OPCODE_BRK0: + case OPCODE_BRK1: + case OPCODE_CONT0: + case OPCODE_CONT1: + _mesa_printf("%s ", _mesa_opcode_string(inst->Opcode)); + print_src_reg(&inst->SrcReg[0], mode, prog); + _mesa_printf("; "); + _mesa_printf(" # (goto %d)", inst->BranchTarget); + print_comment(inst); + break; + case OPCODE_BGNSUB: _mesa_printf("SUB"); print_comment(inst); diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index aab522e292..88aa8c50f5 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -206,6 +206,7 @@ _mesa_init_shader_state(GLcontext * ctx) * are generated by the GLSL compiler. */ ctx->Shader.EmitHighLevelInstructions = GL_TRUE; + ctx->Shader.EmitCondCodes = GL_TRUE; /* XXX probably want GL_FALSE... */ ctx->Shader.EmitComments = GL_FALSE; } diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 16a054b35e..9e476b8a0f 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -61,6 +61,7 @@ typedef struct struct gl_program *prog; /* code-gen options */ GLboolean EmitHighLevelInstructions; + GLboolean EmitCondCodes; GLboolean EmitComments; } slang_emit_info; @@ -1155,10 +1156,6 @@ emit_move(slang_emit_info *emitInfo, slang_ir_node *n) static struct prog_instruction * emit_cond(slang_emit_info *emitInfo, slang_ir_node *n) { - /* Conditional expression (in if/while/for stmts). - * Need to update condition code register. - * Next instruction is typically an IR_IF. - */ struct prog_instruction *inst; if (!n->Children[0]) @@ -1166,28 +1163,39 @@ emit_cond(slang_emit_info *emitInfo, slang_ir_node *n) inst = emit(emitInfo, n->Children[0]); - if (inst) { - /* set inst's CondUpdate flag */ - inst->CondUpdate = GL_TRUE; - n->Store = n->Children[0]->Store; - return inst; /* XXX or null? */ + if (emitInfo->EmitCondCodes) { + /* Conditional expression (in if/while/for stmts). + * Need to update condition code register. + * Next instruction is typically an IR_IF. + */ + if (inst) { + /* set inst's CondUpdate flag */ + inst->CondUpdate = GL_TRUE; + n->Store = n->Children[0]->Store; + return inst; /* XXX or null? */ + } + else { + /* This'll happen for things like "if (i) ..." where no code + * is normally generated for the expression "i". + * Generate a move instruction just to set condition codes. + * Note: must use full 4-component vector since all four + * condition codes must be set identically. + */ + if (!alloc_temp_storage(emitInfo, n, 4)) + return NULL; + inst = new_instruction(emitInfo, OPCODE_MOV); + inst->CondUpdate = GL_TRUE; + storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); + storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); + _slang_free_temp(emitInfo->vt, n->Store); + inst->Comment = _mesa_strdup("COND expr"); + return inst; /* XXX or null? */ + } } else { - /* This'll happen for things like "if (i) ..." where no code - * is normally generated for the expression "i". - * Generate a move instruction just to set condition codes. - * Note: must use full 4-component vector since all four - * condition codes must be set identically. - */ - if (!alloc_temp_storage(emitInfo, n, 4)) - return NULL; - inst = new_instruction(emitInfo, OPCODE_MOV); - inst->CondUpdate = GL_TRUE; - storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); - storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); - _slang_free_temp(emitInfo->vt, n->Store); - inst->Comment = _mesa_strdup("COND expr"); - return inst; /* XXX or null? */ + /* No-op */ + n->Store = n->Children[0]->Store; + return NULL; } } @@ -1244,7 +1252,13 @@ emit_if(slang_emit_info *emitInfo, slang_ir_node *n) ifInstLoc = prog->NumInstructions; if (emitInfo->EmitHighLevelInstructions) { ifInst = new_instruction(emitInfo, OPCODE_IF); - ifInst->DstReg.CondMask = COND_NE; /* if cond is non-zero */ + if (emitInfo->EmitCondCodes) { + ifInst->DstReg.CondMask = COND_NE; /* if cond is non-zero */ + } + else { + /* test reg.x */ + storage_to_src_reg(&ifInst->SrcReg[0], n->Children[0]->Store); + } } else { /* conditional jump to else, or endif */ @@ -1252,8 +1266,10 @@ emit_if(slang_emit_info *emitInfo, slang_ir_node *n) ifInst->DstReg.CondMask = COND_EQ; /* BRA if cond is zero */ ifInst->Comment = _mesa_strdup("if zero"); } - /* which condition code to use: */ - ifInst->DstReg.CondSwizzle = n->Children[0]->Store->Swizzle; + if (emitInfo->EmitCondCodes) { + /* which condition code to use: */ + ifInst->DstReg.CondSwizzle = n->Children[0]->Store->Swizzle; + } /* if body */ emit(emitInfo, n->Children[1]); @@ -1342,6 +1358,8 @@ emit_loop(slang_emit_info *emitInfo, slang_ir_node *n) ir->Opcode == IR_BREAK_IF_FALSE || ir->Opcode == IR_BREAK_IF_TRUE) { assert(inst->Opcode == OPCODE_BRK || + inst->Opcode == OPCODE_BRK0 || + inst->Opcode == OPCODE_BRK1 || inst->Opcode == OPCODE_BRA); /* go to instruction after end of loop */ inst->BranchTarget = endInstLoc + 1; @@ -1351,6 +1369,8 @@ emit_loop(slang_emit_info *emitInfo, slang_ir_node *n) ir->Opcode == IR_CONT_IF_FALSE || ir->Opcode == IR_CONT_IF_TRUE); assert(inst->Opcode == OPCODE_CONT || + inst->Opcode == OPCODE_CONT0 || + inst->Opcode == OPCODE_CONT1 || inst->Opcode == OPCODE_BRA); /* to go instruction at top of loop */ inst->BranchTarget = beginInstLoc; @@ -1361,7 +1381,7 @@ emit_loop(slang_emit_info *emitInfo, slang_ir_node *n) /** - * "Continue" or "break" statement. + * Unconditional "continue" or "break" statement. * Either OPCODE_CONT, OPCODE_BRK or OPCODE_BRA will be emitted. */ static struct prog_instruction * @@ -1393,24 +1413,52 @@ emit_cont_break_if(slang_emit_info *emitInfo, slang_ir_node *n, gl_inst_opcode opcode; struct prog_instruction *inst; + assert(n->Opcode == IR_CONT_IF_TRUE || + n->Opcode == IR_CONT_IF_FALSE || + n->Opcode == IR_BREAK_IF_TRUE || + n->Opcode == IR_BREAK_IF_FALSE); + /* evaluate condition expr, setting cond codes */ inst = emit(emitInfo, n->Children[0]); - assert(inst); - inst->CondUpdate = GL_TRUE; + if (emitInfo->EmitCondCodes) { + assert(inst); + inst->CondUpdate = GL_TRUE; + } n->InstLocation = emitInfo->prog->NumInstructions; + + /* opcode selection */ if (emitInfo->EmitHighLevelInstructions) { - if (n->Opcode == IR_CONT_IF_TRUE || - n->Opcode == IR_CONT_IF_FALSE) - opcode = OPCODE_CONT; - else - opcode = OPCODE_BRK; + if (emitInfo->EmitCondCodes) { + if (n->Opcode == IR_CONT_IF_TRUE || + n->Opcode == IR_CONT_IF_FALSE) + opcode = OPCODE_CONT; + else + opcode = OPCODE_BRK; + } + else { + if (n->Opcode == IR_CONT_IF_TRUE) + opcode = OPCODE_CONT1; + else if (n->Opcode == IR_CONT_IF_FALSE) + opcode = OPCODE_CONT0; + else if (n->Opcode == IR_BREAK_IF_TRUE) + opcode = OPCODE_BRK1; + else if (n->Opcode == IR_BREAK_IF_FALSE) + opcode = OPCODE_BRK0; + } } else { opcode = OPCODE_BRA; } + inst = new_instruction(emitInfo, opcode); - inst->DstReg.CondMask = breakTrue ? COND_NE : COND_EQ; + if (emitInfo->EmitCondCodes) { + inst->DstReg.CondMask = breakTrue ? COND_NE : COND_EQ; + } + else { + /* BRK0, BRK1, CONT0, CONT1 */ + storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); + } return inst; } @@ -1779,7 +1827,8 @@ _slang_emit_code(slang_ir_node *n, slang_var_table *vt, emitInfo.prog = prog; emitInfo.EmitHighLevelInstructions = ctx->Shader.EmitHighLevelInstructions; - emitInfo.EmitComments = 1+ctx->Shader.EmitComments; + emitInfo.EmitCondCodes = 0; /* XXX temporary! */ + emitInfo.EmitComments = ctx->Shader.EmitComments; (void) emit(&emitInfo, n); diff --git a/src/mesa/tnl/t_vb_arbprogram.c b/src/mesa/tnl/t_vb_arbprogram.c index b322d48b23..425a866994 100644 --- a/src/mesa/tnl/t_vb_arbprogram.c +++ b/src/mesa/tnl/t_vb_arbprogram.c @@ -741,9 +741,13 @@ static gpu_function opcode_func[MAX_OPCODE+3] = do_NOP,/*BGNSUB*/ do_NOP,/*BRA*/ do_NOP,/*BRK*/ + do_NOP,/*BRK0*/ + do_NOP,/*BRK1*/ do_NOP,/*CAL*/ do_NOP,/*CMP*/ do_NOP,/*CONT*/ + do_NOP,/*CONT0*/ + do_NOP,/*CONT1*/ do_NOP,/*COS*/ do_NOP,/*DDX*/ do_NOP,/*DDY*/ -- cgit v1.2.3 From 81767eead9e1b1b5d5dfd274c0875fa1332a5983 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 23 Mar 2007 17:45:53 -0600 Subject: consolidate some code --- src/mesa/shader/prog_print.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'src/mesa/shader/prog_print.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 39d2a07812..3f7ad47e05 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -601,14 +601,9 @@ _mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent, _mesa_printf("ENDLOOP; # (goto %d)\n", inst->BranchTarget); break; case OPCODE_BRK: - _mesa_printf("BRK (%s%s); #(goto %d)", - condcode_string(inst->DstReg.CondMask), - _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), - inst->BranchTarget); - print_comment(inst); - break; case OPCODE_CONT: - _mesa_printf("CONT (%s%s); #(goto %d)", + _mesa_printf("%s (%s%s); # (goto %d)", + _mesa_opcode_string(inst->Opcode), condcode_string(inst->DstReg.CondMask), _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), inst->BranchTarget); -- cgit v1.2.3