Merge branch 'mesa'
This brings in the ir_to_mesa.cpp code I've been developing to codegen to the Mesa IR. It does not actually generate a complete Mesa fragment/vertex program yet.
This commit is contained in:
@@ -21,3 +21,5 @@ glsl_parser.output
|
||||
glsl_parser.cpp
|
||||
glsl_parser.h
|
||||
glsl
|
||||
mesa_codegen.cpp
|
||||
mesa_codegen.h
|
||||
|
||||
+8
-1
@@ -21,6 +21,7 @@
|
||||
# USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
AM_CPPFLAGS = -I mesa
|
||||
|
||||
SUBDIRS = glcpp
|
||||
|
||||
@@ -57,9 +58,15 @@ glsl_SOURCES = \
|
||||
ir_hierarchical_visitor.h \
|
||||
ir_hierarchical_visitor.cpp \
|
||||
ir_swizzle_swizzle.cpp \
|
||||
ir_to_mesa.cpp \
|
||||
ir_to_mesa.h \
|
||||
ir_validate.cpp \
|
||||
ir_vec_index_to_swizzle.cpp \
|
||||
linker.cpp
|
||||
linker.cpp \
|
||||
mesa/shader/prog_instruction.c \
|
||||
mesa/shader/prog_instruction.h \
|
||||
mesa/shader/prog_print.c \
|
||||
mesa/shader/prog_print.h
|
||||
|
||||
BUILT_SOURCES = glsl_parser.h glsl_parser.cpp glsl_lexer.cpp
|
||||
CLEANFILES = $(BUILT_SOURCES)
|
||||
|
||||
@@ -134,4 +134,6 @@ extern bool _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
|
||||
extern const char *
|
||||
_mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target);
|
||||
|
||||
void do_ir_to_mesa(exec_list *instructions);
|
||||
|
||||
#endif /* GLSL_PARSER_EXTRAS_H */
|
||||
|
||||
@@ -37,6 +37,10 @@ extern "C" {
|
||||
#include "ir_visitor.h"
|
||||
#include "ir_hierarchical_visitor.h"
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
||||
#endif
|
||||
|
||||
struct ir_program {
|
||||
void *bong_hits;
|
||||
};
|
||||
@@ -758,9 +762,9 @@ public:
|
||||
};
|
||||
|
||||
ir_loop_jump(jump_mode mode)
|
||||
: mode(mode)
|
||||
{
|
||||
/* empty */
|
||||
this->mode = mode;
|
||||
this->loop = loop;
|
||||
}
|
||||
|
||||
virtual ir_instruction *clone(struct hash_table *) const;
|
||||
@@ -782,9 +786,11 @@ public:
|
||||
return mode == jump_continue;
|
||||
}
|
||||
|
||||
private:
|
||||
/** Mode selector for the jump instruction. */
|
||||
enum jump_mode mode;
|
||||
private:
|
||||
/** Loop containing this break instruction. */
|
||||
ir_loop *loop;
|
||||
};
|
||||
/*@}*/
|
||||
|
||||
|
||||
+1211
File diff suppressed because it is too large
Load Diff
+50
-1
@@ -36,6 +36,8 @@
|
||||
#define MAX_DRAW_BUFFERS 8
|
||||
#define MAX_VARYING 16
|
||||
|
||||
#include <GL/gl.h>
|
||||
|
||||
/**
|
||||
* Indexes for vertex program attributes.
|
||||
* GL_NV_vertex_program aliases generic attributes over the conventional
|
||||
@@ -218,4 +220,51 @@ typedef enum
|
||||
FRAG_RESULT_MAX = (FRAG_RESULT_DATA0 + MAX_DRAW_BUFFERS)
|
||||
} gl_frag_result;
|
||||
|
||||
#endif
|
||||
/**
|
||||
* Names of the various vertex/fragment program register files, etc.
|
||||
*
|
||||
* NOTE: first four tokens must fit into 2 bits (see t_vb_arbprogram.c)
|
||||
* All values should fit in a 4-bit field.
|
||||
*
|
||||
* NOTE: PROGRAM_ENV_PARAM, PROGRAM_STATE_VAR, PROGRAM_NAMED_PARAM,
|
||||
* PROGRAM_CONSTANT, and PROGRAM_UNIFORM can all be considered to
|
||||
* be "uniform" variables since they can only be set outside glBegin/End.
|
||||
* They're also all stored in the same Parameters array.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
PROGRAM_TEMPORARY, /**< machine->Temporary[] */
|
||||
PROGRAM_INPUT, /**< machine->Inputs[] */
|
||||
PROGRAM_OUTPUT, /**< machine->Outputs[] */
|
||||
PROGRAM_VARYING, /**< machine->Inputs[]/Outputs[] */
|
||||
PROGRAM_LOCAL_PARAM, /**< gl_program->LocalParams[] */
|
||||
PROGRAM_ENV_PARAM, /**< gl_program->Parameters[] */
|
||||
PROGRAM_STATE_VAR, /**< gl_program->Parameters[] */
|
||||
PROGRAM_NAMED_PARAM, /**< gl_program->Parameters[] */
|
||||
PROGRAM_CONSTANT, /**< gl_program->Parameters[] */
|
||||
PROGRAM_UNIFORM, /**< gl_program->Parameters[] */
|
||||
PROGRAM_WRITE_ONLY, /**< A dummy, write-only register */
|
||||
PROGRAM_ADDRESS, /**< machine->AddressReg */
|
||||
PROGRAM_SAMPLER, /**< for shader samplers, compile-time only */
|
||||
PROGRAM_UNDEFINED, /**< Invalid/TBD value */
|
||||
PROGRAM_FILE_MAX
|
||||
} gl_register_file;
|
||||
|
||||
/**
|
||||
* An index for each type of texture object. These correspond to the GL
|
||||
* texture target enums, such as GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, etc.
|
||||
* Note: the order is from highest priority to lowest priority.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
TEXTURE_2D_ARRAY_INDEX,
|
||||
TEXTURE_1D_ARRAY_INDEX,
|
||||
TEXTURE_CUBE_INDEX,
|
||||
TEXTURE_3D_INDEX,
|
||||
TEXTURE_RECT_INDEX,
|
||||
TEXTURE_2D_INDEX,
|
||||
TEXTURE_1D_INDEX,
|
||||
NUM_TEXTURE_TARGETS
|
||||
} gl_texture_index;
|
||||
|
||||
#endif /* MTYPES_H */
|
||||
|
||||
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 7.3
|
||||
*
|
||||
* Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
|
||||
* Copyright (C) 1999-2009 VMware, Inc. 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.
|
||||
*/
|
||||
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if 0
|
||||
#include "main/glheader.h"
|
||||
#else
|
||||
#define _mesa_strdup strdup
|
||||
#define _mesa_snprintf snprintf
|
||||
#define ASSERT assert
|
||||
#endif
|
||||
#include "main/imports.h"
|
||||
#include "main/mtypes.h"
|
||||
#include "prog_instruction.h"
|
||||
|
||||
|
||||
/**
|
||||
* Initialize program instruction fields to defaults.
|
||||
* \param inst first instruction to initialize
|
||||
* \param count number of instructions to initialize
|
||||
*/
|
||||
void
|
||||
_mesa_init_instructions(struct prog_instruction *inst, GLuint count)
|
||||
{
|
||||
GLuint i;
|
||||
|
||||
memset(inst, 0, count * sizeof(struct prog_instruction));
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
inst[i].SrcReg[0].File = PROGRAM_UNDEFINED;
|
||||
inst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP;
|
||||
inst[i].SrcReg[1].File = PROGRAM_UNDEFINED;
|
||||
inst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP;
|
||||
inst[i].SrcReg[2].File = PROGRAM_UNDEFINED;
|
||||
inst[i].SrcReg[2].Swizzle = SWIZZLE_NOOP;
|
||||
|
||||
inst[i].DstReg.File = PROGRAM_UNDEFINED;
|
||||
inst[i].DstReg.WriteMask = WRITEMASK_XYZW;
|
||||
inst[i].DstReg.CondMask = COND_TR;
|
||||
inst[i].DstReg.CondSwizzle = SWIZZLE_NOOP;
|
||||
|
||||
inst[i].SaturateMode = SATURATE_OFF;
|
||||
inst[i].Precision = FLOAT32;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allocate an array of program instructions.
|
||||
* \param numInst number of instructions
|
||||
* \return pointer to instruction memory
|
||||
*/
|
||||
struct prog_instruction *
|
||||
_mesa_alloc_instructions(GLuint numInst)
|
||||
{
|
||||
return (struct prog_instruction *)
|
||||
calloc(1, numInst * sizeof(struct prog_instruction));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reallocate memory storing an array of program instructions.
|
||||
* This is used when we need to append additional instructions onto an
|
||||
* program.
|
||||
* \param oldInst pointer to first of old/src instructions
|
||||
* \param numOldInst number of instructions at <oldInst>
|
||||
* \param numNewInst desired size of new instruction array.
|
||||
* \return pointer to start of new instruction array.
|
||||
*/
|
||||
struct prog_instruction *
|
||||
_mesa_realloc_instructions(struct prog_instruction *oldInst,
|
||||
GLuint numOldInst, GLuint numNewInst)
|
||||
{
|
||||
struct prog_instruction *newInst;
|
||||
|
||||
(void)numOldInst;
|
||||
newInst = (struct prog_instruction *)
|
||||
realloc(oldInst,
|
||||
numNewInst * sizeof(struct prog_instruction));
|
||||
|
||||
return newInst;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy an array of program instructions.
|
||||
* \param dest pointer to destination.
|
||||
* \param src pointer to source.
|
||||
* \param n number of instructions to copy.
|
||||
* \return pointer to destination.
|
||||
*/
|
||||
struct prog_instruction *
|
||||
_mesa_copy_instructions(struct prog_instruction *dest,
|
||||
const struct prog_instruction *src, GLuint n)
|
||||
{
|
||||
GLuint i;
|
||||
memcpy(dest, src, n * sizeof(struct prog_instruction));
|
||||
for (i = 0; i < n; i++) {
|
||||
if (src[i].Comment)
|
||||
dest[i].Comment = _mesa_strdup(src[i].Comment);
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Free an array of instructions
|
||||
*/
|
||||
void
|
||||
_mesa_free_instructions(struct prog_instruction *inst, GLuint count)
|
||||
{
|
||||
GLuint i;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (inst[i].Data)
|
||||
free(inst[i].Data);
|
||||
if (inst[i].Comment)
|
||||
free((char *) inst[i].Comment);
|
||||
}
|
||||
free(inst);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Basic info about each instruction
|
||||
*/
|
||||
struct instruction_info
|
||||
{
|
||||
gl_inst_opcode Opcode;
|
||||
const char *Name;
|
||||
GLuint NumSrcRegs;
|
||||
GLuint NumDstRegs;
|
||||
};
|
||||
|
||||
/**
|
||||
* Instruction info
|
||||
* \note Opcode should equal array index!
|
||||
*/
|
||||
static const struct instruction_info InstInfo[MAX_OPCODE] = {
|
||||
{ OPCODE_NOP, "NOP", 0, 0 },
|
||||
{ OPCODE_ABS, "ABS", 1, 1 },
|
||||
{ OPCODE_ADD, "ADD", 2, 1 },
|
||||
{ OPCODE_AND, "AND", 2, 1 },
|
||||
{ OPCODE_ARA, "ARA", 1, 1 },
|
||||
{ OPCODE_ARL, "ARL", 1, 1 },
|
||||
{ OPCODE_ARL_NV, "ARL_NV", 1, 1 },
|
||||
{ OPCODE_ARR, "ARL", 1, 1 },
|
||||
{ OPCODE_BGNLOOP,"BGNLOOP", 0, 0 },
|
||||
{ OPCODE_BGNSUB, "BGNSUB", 0, 0 },
|
||||
{ OPCODE_BRA, "BRA", 0, 0 },
|
||||
{ OPCODE_BRK, "BRK", 0, 0 },
|
||||
{ OPCODE_CAL, "CAL", 0, 0 },
|
||||
{ OPCODE_CMP, "CMP", 3, 1 },
|
||||
{ OPCODE_CONT, "CONT", 0, 0 },
|
||||
{ OPCODE_COS, "COS", 1, 1 },
|
||||
{ OPCODE_DDX, "DDX", 1, 1 },
|
||||
{ OPCODE_DDY, "DDY", 1, 1 },
|
||||
{ OPCODE_DP2, "DP2", 2, 1 },
|
||||
{ OPCODE_DP2A, "DP2A", 3, 1 },
|
||||
{ OPCODE_DP3, "DP3", 2, 1 },
|
||||
{ OPCODE_DP4, "DP4", 2, 1 },
|
||||
{ OPCODE_DPH, "DPH", 2, 1 },
|
||||
{ OPCODE_DST, "DST", 2, 1 },
|
||||
{ OPCODE_ELSE, "ELSE", 0, 0 },
|
||||
{ OPCODE_END, "END", 0, 0 },
|
||||
{ OPCODE_ENDIF, "ENDIF", 0, 0 },
|
||||
{ OPCODE_ENDLOOP,"ENDLOOP", 0, 0 },
|
||||
{ OPCODE_ENDSUB, "ENDSUB", 0, 0 },
|
||||
{ OPCODE_EX2, "EX2", 1, 1 },
|
||||
{ OPCODE_EXP, "EXP", 1, 1 },
|
||||
{ OPCODE_FLR, "FLR", 1, 1 },
|
||||
{ OPCODE_FRC, "FRC", 1, 1 },
|
||||
{ OPCODE_IF, "IF", 1, 0 },
|
||||
{ OPCODE_KIL, "KIL", 1, 0 },
|
||||
{ OPCODE_KIL_NV, "KIL_NV", 0, 0 },
|
||||
{ OPCODE_LG2, "LG2", 1, 1 },
|
||||
{ OPCODE_LIT, "LIT", 1, 1 },
|
||||
{ OPCODE_LOG, "LOG", 1, 1 },
|
||||
{ OPCODE_LRP, "LRP", 3, 1 },
|
||||
{ OPCODE_MAD, "MAD", 3, 1 },
|
||||
{ OPCODE_MAX, "MAX", 2, 1 },
|
||||
{ OPCODE_MIN, "MIN", 2, 1 },
|
||||
{ OPCODE_MOV, "MOV", 1, 1 },
|
||||
{ OPCODE_MUL, "MUL", 2, 1 },
|
||||
{ OPCODE_NOISE1, "NOISE1", 1, 1 },
|
||||
{ OPCODE_NOISE2, "NOISE2", 1, 1 },
|
||||
{ OPCODE_NOISE3, "NOISE3", 1, 1 },
|
||||
{ OPCODE_NOISE4, "NOISE4", 1, 1 },
|
||||
{ OPCODE_NOT, "NOT", 1, 1 },
|
||||
{ OPCODE_NRM3, "NRM3", 1, 1 },
|
||||
{ OPCODE_NRM4, "NRM4", 1, 1 },
|
||||
{ OPCODE_OR, "OR", 2, 1 },
|
||||
{ OPCODE_PK2H, "PK2H", 1, 1 },
|
||||
{ OPCODE_PK2US, "PK2US", 1, 1 },
|
||||
{ OPCODE_PK4B, "PK4B", 1, 1 },
|
||||
{ OPCODE_PK4UB, "PK4UB", 1, 1 },
|
||||
{ OPCODE_POW, "POW", 2, 1 },
|
||||
{ OPCODE_POPA, "POPA", 0, 0 },
|
||||
{ OPCODE_PRINT, "PRINT", 1, 0 },
|
||||
{ OPCODE_PUSHA, "PUSHA", 0, 0 },
|
||||
{ OPCODE_RCC, "RCC", 1, 1 },
|
||||
{ OPCODE_RCP, "RCP", 1, 1 },
|
||||
{ OPCODE_RET, "RET", 0, 0 },
|
||||
{ OPCODE_RFL, "RFL", 1, 1 },
|
||||
{ OPCODE_RSQ, "RSQ", 1, 1 },
|
||||
{ OPCODE_SCS, "SCS", 1, 1 },
|
||||
{ OPCODE_SEQ, "SEQ", 2, 1 },
|
||||
{ OPCODE_SFL, "SFL", 0, 1 },
|
||||
{ OPCODE_SGE, "SGE", 2, 1 },
|
||||
{ OPCODE_SGT, "SGT", 2, 1 },
|
||||
{ OPCODE_SIN, "SIN", 1, 1 },
|
||||
{ OPCODE_SLE, "SLE", 2, 1 },
|
||||
{ OPCODE_SLT, "SLT", 2, 1 },
|
||||
{ OPCODE_SNE, "SNE", 2, 1 },
|
||||
{ OPCODE_SSG, "SSG", 1, 1 },
|
||||
{ OPCODE_STR, "STR", 0, 1 },
|
||||
{ OPCODE_SUB, "SUB", 2, 1 },
|
||||
{ OPCODE_SWZ, "SWZ", 1, 1 },
|
||||
{ OPCODE_TEX, "TEX", 1, 1 },
|
||||
{ OPCODE_TXB, "TXB", 1, 1 },
|
||||
{ OPCODE_TXD, "TXD", 3, 1 },
|
||||
{ OPCODE_TXL, "TXL", 1, 1 },
|
||||
{ OPCODE_TXP, "TXP", 1, 1 },
|
||||
{ OPCODE_TXP_NV, "TXP_NV", 1, 1 },
|
||||
{ OPCODE_TRUNC, "TRUNC", 1, 1 },
|
||||
{ OPCODE_UP2H, "UP2H", 1, 1 },
|
||||
{ OPCODE_UP2US, "UP2US", 1, 1 },
|
||||
{ OPCODE_UP4B, "UP4B", 1, 1 },
|
||||
{ OPCODE_UP4UB, "UP4UB", 1, 1 },
|
||||
{ OPCODE_X2D, "X2D", 3, 1 },
|
||||
{ OPCODE_XOR, "XOR", 2, 1 },
|
||||
{ OPCODE_XPD, "XPD", 2, 1 }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return the number of src registers for the given instruction/opcode.
|
||||
*/
|
||||
GLuint
|
||||
_mesa_num_inst_src_regs(gl_inst_opcode opcode)
|
||||
{
|
||||
ASSERT(opcode < MAX_OPCODE);
|
||||
ASSERT(opcode == InstInfo[opcode].Opcode);
|
||||
ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode);
|
||||
return InstInfo[opcode].NumSrcRegs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the number of dst registers for the given instruction/opcode.
|
||||
*/
|
||||
GLuint
|
||||
_mesa_num_inst_dst_regs(gl_inst_opcode opcode)
|
||||
{
|
||||
ASSERT(opcode < MAX_OPCODE);
|
||||
ASSERT(opcode == InstInfo[opcode].Opcode);
|
||||
ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode);
|
||||
return InstInfo[opcode].NumDstRegs;
|
||||
}
|
||||
|
||||
|
||||
GLboolean
|
||||
_mesa_is_tex_instruction(gl_inst_opcode opcode)
|
||||
{
|
||||
return (opcode == OPCODE_TEX ||
|
||||
opcode == OPCODE_TXB ||
|
||||
opcode == OPCODE_TXD ||
|
||||
opcode == OPCODE_TXL ||
|
||||
opcode == OPCODE_TXP);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if there's a potential src/dst register data dependency when
|
||||
* using SOA execution.
|
||||
* Example:
|
||||
* MOV T, T.yxwz;
|
||||
* This would expand into:
|
||||
* MOV t0, t1;
|
||||
* MOV t1, t0;
|
||||
* MOV t2, t3;
|
||||
* MOV t3, t2;
|
||||
* The second instruction will have the wrong value for t0 if executed as-is.
|
||||
*/
|
||||
GLboolean
|
||||
_mesa_check_soa_dependencies(const struct prog_instruction *inst)
|
||||
{
|
||||
GLuint i, chan;
|
||||
|
||||
if (inst->DstReg.WriteMask == WRITEMASK_X ||
|
||||
inst->DstReg.WriteMask == WRITEMASK_Y ||
|
||||
inst->DstReg.WriteMask == WRITEMASK_Z ||
|
||||
inst->DstReg.WriteMask == WRITEMASK_W ||
|
||||
inst->DstReg.WriteMask == 0x0) {
|
||||
/* no chance of data dependency */
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
/* loop over src regs */
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (inst->SrcReg[i].File == inst->DstReg.File &&
|
||||
inst->SrcReg[i].Index == inst->DstReg.Index) {
|
||||
/* loop over dest channels */
|
||||
GLuint channelsWritten = 0x0;
|
||||
for (chan = 0; chan < 4; chan++) {
|
||||
if (inst->DstReg.WriteMask & (1 << chan)) {
|
||||
/* check if we're reading a channel that's been written */
|
||||
GLuint swizzle = GET_SWZ(inst->SrcReg[i].Swizzle, chan);
|
||||
if (swizzle <= SWIZZLE_W &&
|
||||
(channelsWritten & (1 << swizzle))) {
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
channelsWritten |= (1 << chan);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return string name for given program opcode.
|
||||
*/
|
||||
const char *
|
||||
_mesa_opcode_string(gl_inst_opcode opcode)
|
||||
{
|
||||
if (opcode < MAX_OPCODE)
|
||||
return InstInfo[opcode].Name;
|
||||
else {
|
||||
static char s[20];
|
||||
_mesa_snprintf(s, sizeof(s), "OP%u", opcode);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,437 @@
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 7.3
|
||||
*
|
||||
* Copyright (C) 1999-2008 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_instruction.h
|
||||
*
|
||||
* Vertex/fragment program instruction datatypes and constants.
|
||||
*
|
||||
* \author Brian Paul
|
||||
* \author Keith Whitwell
|
||||
* \author Ian Romanick <idr@us.ibm.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PROG_INSTRUCTION_H
|
||||
#define PROG_INSTRUCTION_H
|
||||
|
||||
|
||||
#include "main/mtypes.h"
|
||||
|
||||
|
||||
/**
|
||||
* Swizzle indexes.
|
||||
* Do not change!
|
||||
*/
|
||||
/*@{*/
|
||||
#define SWIZZLE_X 0
|
||||
#define SWIZZLE_Y 1
|
||||
#define SWIZZLE_Z 2
|
||||
#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))
|
||||
#define SWIZZLE_NOOP MAKE_SWIZZLE4(0,1,2,3)
|
||||
#define GET_SWZ(swz, idx) (((swz) >> ((idx)*3)) & 0x7)
|
||||
#define GET_BIT(msk, idx) (((msk) >> (idx)) & 0x1)
|
||||
|
||||
#define SWIZZLE_XYZW MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W)
|
||||
#define SWIZZLE_XXXX MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X)
|
||||
#define SWIZZLE_YYYY MAKE_SWIZZLE4(SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y)
|
||||
#define SWIZZLE_ZZZZ MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z)
|
||||
#define SWIZZLE_WWWW MAKE_SWIZZLE4(SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W)
|
||||
|
||||
|
||||
/**
|
||||
* Writemask values, 1 bit per component.
|
||||
*/
|
||||
/*@{*/
|
||||
#define WRITEMASK_X 0x1
|
||||
#define WRITEMASK_Y 0x2
|
||||
#define WRITEMASK_XY 0x3
|
||||
#define WRITEMASK_Z 0x4
|
||||
#define WRITEMASK_XZ 0x5
|
||||
#define WRITEMASK_YZ 0x6
|
||||
#define WRITEMASK_XYZ 0x7
|
||||
#define WRITEMASK_W 0x8
|
||||
#define WRITEMASK_XW 0x9
|
||||
#define WRITEMASK_YW 0xa
|
||||
#define WRITEMASK_XYW 0xb
|
||||
#define WRITEMASK_ZW 0xc
|
||||
#define WRITEMASK_XZW 0xd
|
||||
#define WRITEMASK_YZW 0xe
|
||||
#define WRITEMASK_XYZW 0xf
|
||||
/*@}*/
|
||||
|
||||
|
||||
/**
|
||||
* Condition codes
|
||||
*/
|
||||
/*@{*/
|
||||
#define COND_GT 1 /**< greater than zero */
|
||||
#define COND_EQ 2 /**< equal to zero */
|
||||
#define COND_LT 3 /**< less than zero */
|
||||
#define COND_UN 4 /**< unordered (NaN) */
|
||||
#define COND_GE 5 /**< greater than or equal to zero */
|
||||
#define COND_LE 6 /**< less than or equal to zero */
|
||||
#define COND_NE 7 /**< not equal to zero */
|
||||
#define COND_TR 8 /**< always true */
|
||||
#define COND_FL 9 /**< always false */
|
||||
/*@}*/
|
||||
|
||||
|
||||
/**
|
||||
* Instruction precision for GL_NV_fragment_program
|
||||
*/
|
||||
/*@{*/
|
||||
#define FLOAT32 0x1
|
||||
#define FLOAT16 0x2
|
||||
#define FIXED12 0x4
|
||||
/*@}*/
|
||||
|
||||
|
||||
/**
|
||||
* Saturation modes when storing values.
|
||||
*/
|
||||
/*@{*/
|
||||
#define SATURATE_OFF 0
|
||||
#define SATURATE_ZERO_ONE 1
|
||||
/*@}*/
|
||||
|
||||
|
||||
/**
|
||||
* Per-component negation masks
|
||||
*/
|
||||
/*@{*/
|
||||
#define NEGATE_X 0x1
|
||||
#define NEGATE_Y 0x2
|
||||
#define NEGATE_Z 0x4
|
||||
#define NEGATE_W 0x8
|
||||
#define NEGATE_XYZ 0x7
|
||||
#define NEGATE_XYZW 0xf
|
||||
#define NEGATE_NONE 0x0
|
||||
/*@}*/
|
||||
|
||||
|
||||
/**
|
||||
* Program instruction opcodes, for both vertex and fragment programs.
|
||||
* \note changes to this opcode list must be reflected in t_vb_arbprogram.c
|
||||
*/
|
||||
typedef enum prog_opcode {
|
||||
/* ARB_vp ARB_fp NV_vp NV_fp GLSL */
|
||||
/*------------------------------------------*/
|
||||
OPCODE_NOP = 0, /* X */
|
||||
OPCODE_ABS, /* X X 1.1 X */
|
||||
OPCODE_ADD, /* X X X X X */
|
||||
OPCODE_AND, /* */
|
||||
OPCODE_ARA, /* 2 */
|
||||
OPCODE_ARL, /* X X */
|
||||
OPCODE_ARL_NV, /* 2 */
|
||||
OPCODE_ARR, /* 2 */
|
||||
OPCODE_BGNLOOP, /* opt */
|
||||
OPCODE_BGNSUB, /* opt */
|
||||
OPCODE_BRA, /* 2 X */
|
||||
OPCODE_BRK, /* 2 opt */
|
||||
OPCODE_CAL, /* 2 2 */
|
||||
OPCODE_CMP, /* X */
|
||||
OPCODE_CONT, /* opt */
|
||||
OPCODE_COS, /* X 2 X X */
|
||||
OPCODE_DDX, /* X X */
|
||||
OPCODE_DDY, /* X X */
|
||||
OPCODE_DP2, /* 2 */
|
||||
OPCODE_DP2A, /* 2 */
|
||||
OPCODE_DP3, /* X X X X X */
|
||||
OPCODE_DP4, /* X X X X X */
|
||||
OPCODE_DPH, /* X X 1.1 */
|
||||
OPCODE_DST, /* X X X X */
|
||||
OPCODE_ELSE, /* X */
|
||||
OPCODE_END, /* X X X X opt */
|
||||
OPCODE_ENDIF, /* opt */
|
||||
OPCODE_ENDLOOP, /* opt */
|
||||
OPCODE_ENDSUB, /* opt */
|
||||
OPCODE_EX2, /* X X 2 X X */
|
||||
OPCODE_EXP, /* X X X */
|
||||
OPCODE_FLR, /* X X 2 X X */
|
||||
OPCODE_FRC, /* X X 2 X X */
|
||||
OPCODE_IF, /* opt */
|
||||
OPCODE_KIL, /* X */
|
||||
OPCODE_KIL_NV, /* X X */
|
||||
OPCODE_LG2, /* X X 2 X X */
|
||||
OPCODE_LIT, /* X X X X */
|
||||
OPCODE_LOG, /* X X X */
|
||||
OPCODE_LRP, /* X X */
|
||||
OPCODE_MAD, /* X X X X X */
|
||||
OPCODE_MAX, /* X X X X X */
|
||||
OPCODE_MIN, /* X X X X X */
|
||||
OPCODE_MOV, /* X X X X X */
|
||||
OPCODE_MUL, /* X X X X X */
|
||||
OPCODE_NOISE1, /* X */
|
||||
OPCODE_NOISE2, /* X */
|
||||
OPCODE_NOISE3, /* X */
|
||||
OPCODE_NOISE4, /* X */
|
||||
OPCODE_NOT, /* */
|
||||
OPCODE_NRM3, /* */
|
||||
OPCODE_NRM4, /* */
|
||||
OPCODE_OR, /* */
|
||||
OPCODE_PK2H, /* X */
|
||||
OPCODE_PK2US, /* X */
|
||||
OPCODE_PK4B, /* X */
|
||||
OPCODE_PK4UB, /* X */
|
||||
OPCODE_POW, /* X X X X */
|
||||
OPCODE_POPA, /* 3 */
|
||||
OPCODE_PRINT, /* X X */
|
||||
OPCODE_PUSHA, /* 3 */
|
||||
OPCODE_RCC, /* 1.1 */
|
||||
OPCODE_RCP, /* X X X X X */
|
||||
OPCODE_RET, /* 2 2 */
|
||||
OPCODE_RFL, /* X X */
|
||||
OPCODE_RSQ, /* X X X X X */
|
||||
OPCODE_SCS, /* X */
|
||||
OPCODE_SEQ, /* 2 X X */
|
||||
OPCODE_SFL, /* 2 X */
|
||||
OPCODE_SGE, /* X X X X X */
|
||||
OPCODE_SGT, /* 2 X X */
|
||||
OPCODE_SIN, /* X 2 X X */
|
||||
OPCODE_SLE, /* 2 X X */
|
||||
OPCODE_SLT, /* X X X X X */
|
||||
OPCODE_SNE, /* 2 X X */
|
||||
OPCODE_SSG, /* 2 */
|
||||
OPCODE_STR, /* 2 X */
|
||||
OPCODE_SUB, /* X X 1.1 X X */
|
||||
OPCODE_SWZ, /* X X */
|
||||
OPCODE_TEX, /* X 3 X X */
|
||||
OPCODE_TXB, /* X 3 X */
|
||||
OPCODE_TXD, /* X X */
|
||||
OPCODE_TXL, /* 3 2 X */
|
||||
OPCODE_TXP, /* X X */
|
||||
OPCODE_TXP_NV, /* 3 X */
|
||||
OPCODE_TRUNC, /* X */
|
||||
OPCODE_UP2H, /* X */
|
||||
OPCODE_UP2US, /* X */
|
||||
OPCODE_UP4B, /* X */
|
||||
OPCODE_UP4UB, /* X */
|
||||
OPCODE_X2D, /* X */
|
||||
OPCODE_XOR, /* */
|
||||
OPCODE_XPD, /* X X X */
|
||||
MAX_OPCODE
|
||||
} gl_inst_opcode;
|
||||
|
||||
|
||||
/**
|
||||
* Number of bits for the src/dst register Index field.
|
||||
* This limits the size of temp/uniform register files.
|
||||
*/
|
||||
#define INST_INDEX_BITS 10
|
||||
|
||||
|
||||
/**
|
||||
* Instruction source register.
|
||||
*/
|
||||
struct prog_src_register
|
||||
{
|
||||
GLuint File:4; /**< One of the PROGRAM_* register file values. */
|
||||
GLint Index:(INST_INDEX_BITS+1); /**< Extra bit here for sign bit.
|
||||
* May be negative for relative addressing.
|
||||
*/
|
||||
GLuint Swizzle:12;
|
||||
GLuint RelAddr:1;
|
||||
|
||||
/** Take the component-wise absolute value */
|
||||
GLuint Abs:1;
|
||||
|
||||
/**
|
||||
* Post-Abs negation.
|
||||
* This will either be NEGATE_NONE or NEGATE_XYZW, except for the SWZ
|
||||
* instruction which allows per-component negation.
|
||||
*/
|
||||
GLuint Negate:4;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Instruction destination register.
|
||||
*/
|
||||
struct prog_dst_register
|
||||
{
|
||||
GLuint File:4; /**< One of the PROGRAM_* register file values */
|
||||
GLuint Index:INST_INDEX_BITS; /**< Unsigned, never negative */
|
||||
GLuint WriteMask:4;
|
||||
GLuint RelAddr:1;
|
||||
|
||||
/**
|
||||
* \name Conditional destination update control.
|
||||
*
|
||||
* \since
|
||||
* NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
|
||||
* NV_vertex_program2_option.
|
||||
*/
|
||||
/*@{*/
|
||||
/**
|
||||
* Takes one of the 9 possible condition values (EQ, FL, GT, GE, LE, LT,
|
||||
* NE, TR, or UN). Dest reg is only written to if the matching
|
||||
* (swizzled) condition code value passes. When a conditional update mask
|
||||
* is not specified, this will be \c COND_TR.
|
||||
*/
|
||||
GLuint CondMask:4;
|
||||
|
||||
/**
|
||||
* Condition code swizzle value.
|
||||
*/
|
||||
GLuint CondSwizzle:12;
|
||||
|
||||
/**
|
||||
* Selects the condition code register to use for conditional destination
|
||||
* update masking. In NV_fragmnet_program or NV_vertex_program2 mode, only
|
||||
* condition code register 0 is available. In NV_vertex_program3 mode,
|
||||
* condition code registers 0 and 1 are available.
|
||||
*/
|
||||
GLuint CondSrc:1;
|
||||
/*@}*/
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Vertex/fragment program instruction.
|
||||
*/
|
||||
struct prog_instruction
|
||||
{
|
||||
gl_inst_opcode Opcode;
|
||||
struct prog_src_register SrcReg[3];
|
||||
struct prog_dst_register DstReg;
|
||||
|
||||
/**
|
||||
* Indicates that the instruction should update the condition code
|
||||
* register.
|
||||
*
|
||||
* \since
|
||||
* NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
|
||||
* NV_vertex_program2_option.
|
||||
*/
|
||||
GLuint CondUpdate:1;
|
||||
|
||||
/**
|
||||
* If prog_instruction::CondUpdate is \c GL_TRUE, this value selects the
|
||||
* condition code register that is to be updated.
|
||||
*
|
||||
* In GL_NV_fragment_program or GL_NV_vertex_program2 mode, only condition
|
||||
* code register 0 is available. In GL_NV_vertex_program3 mode, condition
|
||||
* code registers 0 and 1 are available.
|
||||
*
|
||||
* \since
|
||||
* NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
|
||||
* NV_vertex_program2_option.
|
||||
*/
|
||||
GLuint CondDst:1;
|
||||
|
||||
/**
|
||||
* Saturate each value of the vectored result to the range [0,1] or the
|
||||
* range [-1,1]. \c SSAT mode (i.e., saturation to the range [-1,1]) is
|
||||
* only available in NV_fragment_program2 mode.
|
||||
* Value is one of the SATURATE_* tokens.
|
||||
*
|
||||
* \since
|
||||
* NV_fragment_program, NV_fragment_program_option, NV_vertex_program3.
|
||||
*/
|
||||
GLuint SaturateMode:2;
|
||||
|
||||
/**
|
||||
* Per-instruction selectable precision: FLOAT32, FLOAT16, FIXED12.
|
||||
*
|
||||
* \since
|
||||
* NV_fragment_program, NV_fragment_program_option.
|
||||
*/
|
||||
GLuint Precision:3;
|
||||
|
||||
/**
|
||||
* \name Extra fields for TEX, TXB, TXD, TXL, TXP instructions.
|
||||
*/
|
||||
/*@{*/
|
||||
/** Source texture unit. */
|
||||
GLuint TexSrcUnit:5;
|
||||
|
||||
/** Source texture target, one of TEXTURE_{1D,2D,3D,CUBE,RECT}_INDEX */
|
||||
GLuint TexSrcTarget:3;
|
||||
|
||||
/** True if tex instruction should do shadow comparison */
|
||||
GLuint TexShadow:1;
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
* For BRA and CAL instructions, the location to jump to.
|
||||
* For BGNLOOP, points to ENDLOOP (and vice-versa).
|
||||
* For BRK, points to BGNLOOP (which points to ENDLOOP).
|
||||
* For IF, points to ELSE or ENDIF.
|
||||
* For ELSE, points to ENDIF.
|
||||
*/
|
||||
GLint BranchTarget;
|
||||
|
||||
/** for debugging purposes */
|
||||
const char *Comment;
|
||||
|
||||
/** Arbitrary data. Used for OPCODE_PRINT and some drivers */
|
||||
void *Data;
|
||||
|
||||
/** for driver use (try to remove someday) */
|
||||
GLint Aux;
|
||||
};
|
||||
|
||||
|
||||
extern void
|
||||
_mesa_init_instructions(struct prog_instruction *inst, GLuint count);
|
||||
|
||||
extern struct prog_instruction *
|
||||
_mesa_alloc_instructions(GLuint numInst);
|
||||
|
||||
extern struct prog_instruction *
|
||||
_mesa_realloc_instructions(struct prog_instruction *oldInst,
|
||||
GLuint numOldInst, GLuint numNewInst);
|
||||
|
||||
extern struct prog_instruction *
|
||||
_mesa_copy_instructions(struct prog_instruction *dest,
|
||||
const struct prog_instruction *src, GLuint n);
|
||||
|
||||
extern void
|
||||
_mesa_free_instructions(struct prog_instruction *inst, GLuint count);
|
||||
|
||||
extern GLuint
|
||||
_mesa_num_inst_src_regs(gl_inst_opcode opcode);
|
||||
|
||||
extern GLuint
|
||||
_mesa_num_inst_dst_regs(gl_inst_opcode opcode);
|
||||
|
||||
extern GLboolean
|
||||
_mesa_is_tex_instruction(gl_inst_opcode opcode);
|
||||
|
||||
extern GLboolean
|
||||
_mesa_check_soa_dependencies(const struct prog_instruction *inst);
|
||||
|
||||
extern const char *
|
||||
_mesa_opcode_string(gl_inst_opcode opcode);
|
||||
|
||||
|
||||
#endif /* PROG_INSTRUCTION_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.5.3
|
||||
*
|
||||
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PROG_PRINT_H
|
||||
#define PROG_PRINT_H
|
||||
|
||||
|
||||
/**
|
||||
* 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_vp_inputs(GLbitfield inputs);
|
||||
|
||||
extern void
|
||||
_mesa_print_fp_inputs(GLbitfield inputs);
|
||||
|
||||
extern const char *
|
||||
_mesa_condcode_string(GLuint condcode);
|
||||
|
||||
extern const char *
|
||||
_mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended);
|
||||
|
||||
const char *
|
||||
_mesa_writemask_string(GLuint writeMask);
|
||||
|
||||
extern void
|
||||
_mesa_print_swizzle(GLuint swizzle);
|
||||
|
||||
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);
|
||||
|
||||
extern GLint
|
||||
_mesa_fprint_instruction_opt(FILE *f,
|
||||
const struct prog_instruction *inst,
|
||||
GLint indent,
|
||||
gl_prog_print_mode mode,
|
||||
const struct gl_program *prog);
|
||||
|
||||
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_fprint_program_opt(FILE *f,
|
||||
const struct gl_program *prog, gl_prog_print_mode mode,
|
||||
GLboolean lineNumbers);
|
||||
|
||||
#if 0
|
||||
extern void
|
||||
_mesa_print_parameter_list(const struct gl_program_parameter_list *list);
|
||||
|
||||
extern void
|
||||
_mesa_write_shader_to_file(const struct gl_shader *shader);
|
||||
|
||||
extern void
|
||||
_mesa_append_uniforms_to_file(const struct gl_shader *shader,
|
||||
const struct gl_program *prog);
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* PROG_PRINT_H */
|
||||
Reference in New Issue
Block a user