Implement vertex attribute binding.
Users can set explicit binding with glBindAttribLocation(), otherwise the linker will allocate generic attribute slots.
This commit is contained in:
@@ -1844,16 +1844,16 @@ struct gl_program_parameter_list;
|
|||||||
struct gl_program
|
struct gl_program
|
||||||
{
|
{
|
||||||
GLuint Id;
|
GLuint Id;
|
||||||
GLubyte *String; /**< Null-terminated program text */
|
GLubyte *String; /**< Null-terminated program text */
|
||||||
GLint RefCount;
|
GLint RefCount;
|
||||||
GLenum Target;
|
GLenum Target; /**< GL_VERTEX/FRAGMENT_PROGRAM_ARB, GL_FRAGMENT_PROGRAM_NV */
|
||||||
GLenum Format; /**< String encoding format */
|
GLenum Format; /**< String encoding format */
|
||||||
GLboolean Resident;
|
GLboolean Resident;
|
||||||
|
|
||||||
struct prog_instruction *Instructions;
|
struct prog_instruction *Instructions;
|
||||||
|
|
||||||
GLbitfield InputsRead; /* Bitmask of which input regs are read */
|
GLbitfield InputsRead; /**< Bitmask of which input regs are read */
|
||||||
GLbitfield OutputsWritten; /* Bitmask of which output regs are written to */
|
GLbitfield OutputsWritten; /**< Bitmask of which output regs are written to */
|
||||||
GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS]; /**< TEXTURE_x_BIT bitmask */
|
GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS]; /**< TEXTURE_x_BIT bitmask */
|
||||||
|
|
||||||
/** Named parameters, constants, etc. from program text */
|
/** Named parameters, constants, etc. from program text */
|
||||||
@@ -1863,6 +1863,8 @@ struct gl_program
|
|||||||
|
|
||||||
/** Vertex/fragment shader varying vars */
|
/** Vertex/fragment shader varying vars */
|
||||||
struct gl_program_parameter_list *Varying;
|
struct gl_program_parameter_list *Varying;
|
||||||
|
/** Vertex program user-defined attributes */
|
||||||
|
struct gl_program_parameter_list *Attributes;
|
||||||
|
|
||||||
/** Logical counts */
|
/** Logical counts */
|
||||||
/*@{*/
|
/*@{*/
|
||||||
|
@@ -239,6 +239,9 @@ _mesa_add_sampler(struct gl_program_parameter_list *paramList,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add parameter representing a varying variable.
|
||||||
|
*/
|
||||||
GLint
|
GLint
|
||||||
_mesa_add_varying(struct gl_program_parameter_list *paramList,
|
_mesa_add_varying(struct gl_program_parameter_list *paramList,
|
||||||
const char *name, GLuint size)
|
const char *name, GLuint size)
|
||||||
@@ -256,6 +259,31 @@ _mesa_add_varying(struct gl_program_parameter_list *paramList,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add parameter representing a vertex program attribute.
|
||||||
|
*/
|
||||||
|
GLint
|
||||||
|
_mesa_add_attribute(struct gl_program_parameter_list *paramList,
|
||||||
|
const char *name, GLint attrib)
|
||||||
|
{
|
||||||
|
GLint size = 4; /* XXX ok? */
|
||||||
|
GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
|
||||||
|
if (i >= 0) {
|
||||||
|
/* replace */
|
||||||
|
ASSERT(paramList->Parameters[i].StateIndexes[0] == STATE_USER_ATTRIB);
|
||||||
|
paramList->Parameters[i].StateIndexes[1] = attrib;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* add */
|
||||||
|
i = _mesa_add_parameter(paramList, name, NULL, size, PROGRAM_INPUT);
|
||||||
|
if (i >= 0) {
|
||||||
|
paramList->Parameters[i].StateIndexes[0] = STATE_USER_ATTRIB;
|
||||||
|
paramList->Parameters[i].StateIndexes[1] = attrib;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if 0 /* not used yet */
|
#if 0 /* not used yet */
|
||||||
|
@@ -107,6 +107,10 @@ extern GLint
|
|||||||
_mesa_add_varying(struct gl_program_parameter_list *paramList,
|
_mesa_add_varying(struct gl_program_parameter_list *paramList,
|
||||||
const char *name, GLuint size);
|
const char *name, GLuint size);
|
||||||
|
|
||||||
|
extern GLint
|
||||||
|
_mesa_add_attribute(struct gl_program_parameter_list *paramList,
|
||||||
|
const char *name, GLint attrib);
|
||||||
|
|
||||||
extern GLint
|
extern GLint
|
||||||
_mesa_add_state_reference(struct gl_program_parameter_list *paramList,
|
_mesa_add_state_reference(struct gl_program_parameter_list *paramList,
|
||||||
const GLint *stateTokens);
|
const GLint *stateTokens);
|
||||||
|
@@ -96,6 +96,8 @@ typedef enum gl_state_index_ {
|
|||||||
STATE_NORMAL_SCALE,
|
STATE_NORMAL_SCALE,
|
||||||
STATE_TEXRECT_SCALE,
|
STATE_TEXRECT_SCALE,
|
||||||
STATE_POSITION_NORMALIZED, /* normalized light position */
|
STATE_POSITION_NORMALIZED, /* normalized light position */
|
||||||
|
STATE_USER_ATTRIB, /** shader vertex attrib: user-specified */
|
||||||
|
STATE_AUTO_ATTRIB, /** shader vertex attrib: linker-specified */
|
||||||
STATE_INTERNAL_DRIVER /* first available state index for drivers (must be last) */
|
STATE_INTERNAL_DRIVER /* first available state index for drivers (must be last) */
|
||||||
} gl_state_index;
|
} gl_state_index;
|
||||||
|
|
||||||
|
@@ -365,6 +365,8 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)
|
|||||||
memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams));
|
memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams));
|
||||||
if (prog->Varying)
|
if (prog->Varying)
|
||||||
clone->Varying = _mesa_clone_parameter_list(prog->Varying);
|
clone->Varying = _mesa_clone_parameter_list(prog->Varying);
|
||||||
|
if (prog->Attributes)
|
||||||
|
clone->Attributes = _mesa_clone_parameter_list(prog->Attributes);
|
||||||
memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams));
|
memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams));
|
||||||
clone->NumInstructions = prog->NumInstructions;
|
clone->NumInstructions = prog->NumInstructions;
|
||||||
clone->NumTemporaries = prog->NumTemporaries;
|
clone->NumTemporaries = prog->NumTemporaries;
|
||||||
|
@@ -40,6 +40,8 @@
|
|||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "program.h"
|
#include "program.h"
|
||||||
#include "prog_parameter.h"
|
#include "prog_parameter.h"
|
||||||
|
#include "prog_print.h"
|
||||||
|
#include "prog_statevars.h"
|
||||||
#include "shader_api.h"
|
#include "shader_api.h"
|
||||||
|
|
||||||
#include "slang_compile.h"
|
#include "slang_compile.h"
|
||||||
@@ -59,6 +61,7 @@ _mesa_new_shader_program(GLcontext *ctx, GLuint name)
|
|||||||
shProg->Type = GL_SHADER_PROGRAM;
|
shProg->Type = GL_SHADER_PROGRAM;
|
||||||
shProg->Name = name;
|
shProg->Name = name;
|
||||||
shProg->RefCount = 1;
|
shProg->RefCount = 1;
|
||||||
|
shProg->Attributes = _mesa_new_parameter_list();
|
||||||
}
|
}
|
||||||
return shProg;
|
return shProg;
|
||||||
}
|
}
|
||||||
@@ -275,6 +278,8 @@ _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,
|
|||||||
{
|
{
|
||||||
struct gl_shader_program *shProg
|
struct gl_shader_program *shProg
|
||||||
= _mesa_lookup_shader_program(ctx, program);
|
= _mesa_lookup_shader_program(ctx, program);
|
||||||
|
GLint i;
|
||||||
|
GLint oldIndex;
|
||||||
|
|
||||||
if (!shProg) {
|
if (!shProg) {
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(program)");
|
_mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(program)");
|
||||||
@@ -290,15 +295,21 @@ _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* XXXX */
|
oldIndex = _mesa_get_attrib_location(ctx, program, name);
|
||||||
if (name == NULL || index >= MAX_VERTEX_ATTRIBS)
|
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocationARB");
|
/* this will replace the current value if it's already in the list */
|
||||||
else if (IS_NAME_WITH_GL_PREFIX(name))
|
i = _mesa_add_attribute(shProg->Attributes, name, index);
|
||||||
_mesa_error(ctx, GL_INVALID_OPERATION, "glBindAttribLocationARB");
|
if (i < 0) {
|
||||||
else
|
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindAttribLocation");
|
||||||
(**pro).OverrideAttribBinding(pro, index, name);
|
}
|
||||||
RELEASE_PROGRAM(pro);
|
|
||||||
#endif
|
if (shProg->VertexProgram && oldIndex >= 0) {
|
||||||
|
_slang_remap_attribute(&shProg->VertexProgram->Base, oldIndex, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("===== post BindAttrib:\n");
|
||||||
|
_mesa_print_program(&shProg->VertexProgram->Base);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -541,11 +552,9 @@ _mesa_get_attrib_location(GLcontext *ctx, GLuint program,
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (shProg->Attributes) {
|
if (shProg->Attributes) {
|
||||||
GLuint i;
|
GLint i = _mesa_lookup_parameter_index(shProg->Attributes, -1, name);
|
||||||
for (i = 0; i < shProg->Attributes->NumParameters; i++) {
|
if (i >= 0) {
|
||||||
if (!strcmp(shProg->Attributes->Parameters[i].Name, name)) {
|
return shProg->Attributes->Parameters[i].StateIndexes[1];
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@@ -605,7 +614,7 @@ _mesa_get_programiv(GLcontext *ctx, GLuint program,
|
|||||||
*params = shProg->NumShaders;
|
*params = shProg->NumShaders;
|
||||||
break;
|
break;
|
||||||
case GL_ACTIVE_ATTRIBUTES:
|
case GL_ACTIVE_ATTRIBUTES:
|
||||||
*params = shProg->Uniforms ? shProg->Uniforms->NumParameters : 0;
|
*params = shProg->Attributes ? shProg->Attributes->NumParameters : 0;
|
||||||
break;
|
break;
|
||||||
case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
|
case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
|
||||||
*params = _mesa_parameter_longest_name(shProg->Attributes);
|
*params = _mesa_parameter_longest_name(shProg->Attributes);
|
||||||
|
@@ -540,7 +540,8 @@ _slang_codegen_global_variable(slang_variable *var, struct gl_program *prog,
|
|||||||
}
|
}
|
||||||
else if (var->type.qualifier == slang_qual_const) {
|
else if (var->type.qualifier == slang_qual_const) {
|
||||||
if (prog) {
|
if (prog) {
|
||||||
abort();
|
/* user-defined constant */
|
||||||
|
abort(); /* XXX fix */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* pre-defined global constant, like gl_MaxLights */
|
/* pre-defined global constant, like gl_MaxLights */
|
||||||
@@ -550,11 +551,22 @@ _slang_codegen_global_variable(slang_variable *var, struct gl_program *prog,
|
|||||||
if (dbg) printf("CONST ");
|
if (dbg) printf("CONST ");
|
||||||
}
|
}
|
||||||
else if (var->type.qualifier == slang_qual_attribute) {
|
else if (var->type.qualifier == slang_qual_attribute) {
|
||||||
/* Vertex attribute */
|
if (prog) {
|
||||||
GLint index = _slang_input_index(varName, GL_VERTEX_PROGRAM_ARB);
|
/* user-defined vertex attribute */
|
||||||
GLint size = 4; /* XXX? */
|
const GLint size = _slang_sizeof_type_specifier(&var->type.specifier);
|
||||||
assert(index >= 0);
|
GLint index = _mesa_add_parameter(prog->Attributes, varName,
|
||||||
store = _slang_new_ir_storage(PROGRAM_INPUT, index, size);
|
NULL, size, PROGRAM_INPUT);
|
||||||
|
assert(index >= 0);
|
||||||
|
store = _slang_new_ir_storage(PROGRAM_INPUT,
|
||||||
|
VERT_ATTRIB_GENERIC0 + index, size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* pre-defined vertex attrib */
|
||||||
|
GLint index = _slang_input_index(varName, GL_VERTEX_PROGRAM_ARB);
|
||||||
|
GLint size = 4; /* XXX? */
|
||||||
|
assert(index >= 0);
|
||||||
|
store = _slang_new_ir_storage(PROGRAM_INPUT, index, size);
|
||||||
|
}
|
||||||
if (dbg) printf("ATTRIB ");
|
if (dbg) printf("ATTRIB ");
|
||||||
}
|
}
|
||||||
else if (var->type.qualifier == slang_qual_fixedinput) {
|
else if (var->type.qualifier == slang_qual_fixedinput) {
|
||||||
|
@@ -2260,6 +2260,7 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader)
|
|||||||
|
|
||||||
shader->Programs[0]->Parameters = _mesa_new_parameter_list();
|
shader->Programs[0]->Parameters = _mesa_new_parameter_list();
|
||||||
shader->Programs[0]->Varying = _mesa_new_parameter_list();
|
shader->Programs[0]->Varying = _mesa_new_parameter_list();
|
||||||
|
shader->Programs[0]->Attributes = _mesa_new_parameter_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
slang_info_log_construct(&info_log);
|
slang_info_log_construct(&info_log);
|
||||||
|
@@ -357,6 +357,9 @@ extern void
|
|||||||
_slang_resolve_samplers(struct gl_shader_program *shProg,
|
_slang_resolve_samplers(struct gl_shader_program *shProg,
|
||||||
struct gl_program *prog);
|
struct gl_program *prog);
|
||||||
|
|
||||||
|
extern void
|
||||||
|
_slang_remap_attribute(struct gl_program *prog, GLuint oldAttrib, GLuint newAttrib);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@@ -36,6 +36,7 @@
|
|||||||
#include "prog_instruction.h"
|
#include "prog_instruction.h"
|
||||||
#include "prog_parameter.h"
|
#include "prog_parameter.h"
|
||||||
#include "prog_print.h"
|
#include "prog_print.h"
|
||||||
|
#include "prog_statevars.h"
|
||||||
#include "shader_api.h"
|
#include "shader_api.h"
|
||||||
#include "slang_link.h"
|
#include "slang_link.h"
|
||||||
|
|
||||||
@@ -311,31 +312,71 @@ _slang_resolve_branches(struct gl_program *prog)
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scan program for texture instructions, lookup sampler/uniform's value
|
* Resolve binding of generic vertex attributes.
|
||||||
* to determine which texture unit to use.
|
* For example, if the vertex shader declared "attribute vec4 foobar" we'll
|
||||||
* Also, update the program's TexturesUsed[] array.
|
* allocate a generic vertex attribute for "foobar" and plug that value into
|
||||||
|
* the vertex program instructions.
|
||||||
*/
|
*/
|
||||||
void
|
static GLboolean
|
||||||
_slang_resolve_samplers(struct gl_shader_program *shProg,
|
_slang_resolve_attributes(struct gl_shader_program *shProg,
|
||||||
struct gl_program *prog)
|
struct gl_program *prog)
|
||||||
{
|
{
|
||||||
GLuint i;
|
GLuint i, j;
|
||||||
|
GLbitfield usedAttributes;
|
||||||
|
|
||||||
for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
|
assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
|
||||||
prog->TexturesUsed[i] = 0;
|
|
||||||
|
|
||||||
|
/* Build a bitmask indicating which attribute indexes have been
|
||||||
|
* explicitly bound by the user with glBindAttributeLocation().
|
||||||
|
*/
|
||||||
|
usedAttributes = 0x0;
|
||||||
|
for (i = 0; i < shProg->Attributes->NumParameters; i++) {
|
||||||
|
GLint attr = shProg->Attributes->Parameters[i].StateIndexes[1];
|
||||||
|
usedAttributes |= attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!shProg->Attributes)
|
||||||
|
shProg->Attributes = _mesa_new_parameter_list();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scan program for generic attribute references
|
||||||
|
*/
|
||||||
for (i = 0; i < prog->NumInstructions; i++) {
|
for (i = 0; i < prog->NumInstructions; i++) {
|
||||||
struct prog_instruction *inst = prog->Instructions + i;
|
struct prog_instruction *inst = prog->Instructions + i;
|
||||||
if (inst->Opcode == OPCODE_TEX ||
|
for (j = 0; j < 3; j++) {
|
||||||
inst->Opcode == OPCODE_TXB ||
|
if (inst->SrcReg[j].File == PROGRAM_INPUT &&
|
||||||
inst->Opcode == OPCODE_TXP) {
|
inst->SrcReg[j].Index >= VERT_ATTRIB_GENERIC0) {
|
||||||
GLint sampleUnit = (GLint) shProg->Uniforms->ParameterValues[inst->Sampler][0];
|
/* this is a generic attrib */
|
||||||
assert(sampleUnit < MAX_TEXTURE_IMAGE_UNITS);
|
const GLint k = inst->SrcReg[j].Index - VERT_ATTRIB_GENERIC0;
|
||||||
inst->TexSrcUnit = sampleUnit;
|
const char *name = prog->Attributes->Parameters[k].Name;
|
||||||
|
/* See if this attrib name is in the program's attribute list
|
||||||
|
* (i.e. was bound by the user).
|
||||||
|
*/
|
||||||
|
GLint index = _mesa_lookup_parameter_index(shProg->Attributes,
|
||||||
|
-1, name);
|
||||||
|
GLint attr;
|
||||||
|
if (index >= 0) {
|
||||||
|
/* found, user must have specified a binding */
|
||||||
|
attr = shProg->Attributes->Parameters[index].StateIndexes[1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* not found, choose our own attribute number */
|
||||||
|
for (attr = 0; attr < MAX_VERTEX_ATTRIBS; attr++) {
|
||||||
|
if (((1 << attr) & usedAttributes) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (attr == MAX_VERTEX_ATTRIBS) {
|
||||||
|
/* too many! XXX record error log */
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
_mesa_add_attribute(shProg->Attributes, name, attr);
|
||||||
|
}
|
||||||
|
|
||||||
prog->TexturesUsed[inst->TexSrcUnit] |= (1 << inst->TexSrcTarget);
|
inst->SrcReg[j].Index = VERT_ATTRIB_GENERIC0 + attr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -366,6 +407,65 @@ _slang_update_inputs_outputs(struct gl_program *prog)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scan a vertex program looking for instances of
|
||||||
|
* (PROGRAM_INPUT, VERT_ATTRIB_GENERIC0 + oldAttrib) and replace with
|
||||||
|
* (PROGRAM_INPUT, VERT_ATTRIB_GENERIC0 + newAttrib).
|
||||||
|
* This is used when the user calls glBindAttribLocation on an already linked
|
||||||
|
* shader program.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_slang_remap_attribute(struct gl_program *prog, GLuint oldAttrib, GLuint newAttrib)
|
||||||
|
{
|
||||||
|
GLuint i, j;
|
||||||
|
|
||||||
|
assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
|
||||||
|
|
||||||
|
for (i = 0; i < prog->NumInstructions; i++) {
|
||||||
|
struct prog_instruction *inst = prog->Instructions + i;
|
||||||
|
for (j = 0; j < 3; j++) {
|
||||||
|
if (inst->SrcReg[j].File == PROGRAM_INPUT) {
|
||||||
|
if (inst->SrcReg[j].Index == VERT_ATTRIB_GENERIC0 + oldAttrib) {
|
||||||
|
inst->SrcReg[j].Index = VERT_ATTRIB_GENERIC0 + newAttrib;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_slang_update_inputs_outputs(prog);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scan program for texture instructions, lookup sampler/uniform's value
|
||||||
|
* to determine which texture unit to use.
|
||||||
|
* Also, update the program's TexturesUsed[] array.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_slang_resolve_samplers(struct gl_shader_program *shProg,
|
||||||
|
struct gl_program *prog)
|
||||||
|
{
|
||||||
|
GLuint i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
|
||||||
|
prog->TexturesUsed[i] = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < prog->NumInstructions; i++) {
|
||||||
|
struct prog_instruction *inst = prog->Instructions + i;
|
||||||
|
if (inst->Opcode == OPCODE_TEX ||
|
||||||
|
inst->Opcode == OPCODE_TXB ||
|
||||||
|
inst->Opcode == OPCODE_TXP) {
|
||||||
|
GLint sampleUnit = (GLint) shProg->Uniforms->ParameterValues[inst->Sampler][0];
|
||||||
|
assert(sampleUnit < MAX_TEXTURE_IMAGE_UNITS);
|
||||||
|
inst->TexSrcUnit = sampleUnit;
|
||||||
|
|
||||||
|
prog->TexturesUsed[inst->TexSrcUnit] |= (1 << inst->TexSrcTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** cast wrapper */
|
/** cast wrapper */
|
||||||
static struct gl_vertex_program *
|
static struct gl_vertex_program *
|
||||||
@@ -463,10 +563,12 @@ _slang_link2(GLcontext *ctx,
|
|||||||
|
|
||||||
_slang_resolve_branches(&shProg->VertexProgram->Base);
|
_slang_resolve_branches(&shProg->VertexProgram->Base);
|
||||||
_slang_resolve_branches(&shProg->FragmentProgram->Base);
|
_slang_resolve_branches(&shProg->FragmentProgram->Base);
|
||||||
#if 1
|
|
||||||
_slang_resolve_samplers(shProg, &shProg->VertexProgram->Base);
|
_slang_resolve_samplers(shProg, &shProg->VertexProgram->Base);
|
||||||
_slang_resolve_samplers(shProg, &shProg->FragmentProgram->Base);
|
_slang_resolve_samplers(shProg, &shProg->FragmentProgram->Base);
|
||||||
#endif
|
|
||||||
|
_slang_resolve_attributes(shProg, &shProg->VertexProgram->Base);
|
||||||
|
|
||||||
_slang_update_inputs_outputs(&shProg->VertexProgram->Base);
|
_slang_update_inputs_outputs(&shProg->VertexProgram->Base);
|
||||||
_slang_update_inputs_outputs(&shProg->FragmentProgram->Base);
|
_slang_update_inputs_outputs(&shProg->FragmentProgram->Base);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user