Re-implement GLSL texture sampler variables.
GLSL sampler variables indicate which texture unit to use for TEX instructions. Previously, this was baked into the fragment/vertex program and couldn't be readily changed once set. Now, SamplerUnits[] array indicates which texture unit is to be used for each sampler variable. These values are set with glUniform1i(). This is extra state that must be passed to the fragment/vertex program executor at runtime.
This commit is contained in:
@@ -207,6 +207,7 @@
|
|||||||
#define MAX_PROGRAM_ADDRESS_REGS 2
|
#define MAX_PROGRAM_ADDRESS_REGS 2
|
||||||
#define MAX_UNIFORMS 128
|
#define MAX_UNIFORMS 128
|
||||||
#define MAX_VARYING 8
|
#define MAX_VARYING 8
|
||||||
|
#define MAX_SAMPLERS 8
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
/** For GL_ARB_vertex_shader */
|
/** For GL_ARB_vertex_shader */
|
||||||
|
@@ -1901,6 +1901,7 @@ struct gl_program
|
|||||||
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 */
|
||||||
|
GLbitfield SamplersUsed; /**< Bitfield of which samplers are used */
|
||||||
GLbitfield ShadowSamplers; /**< Texture units used for shadow sampling. */
|
GLbitfield ShadowSamplers; /**< Texture units used for shadow sampling. */
|
||||||
|
|
||||||
/** Named parameters, constants, etc. from program text */
|
/** Named parameters, constants, etc. from program text */
|
||||||
@@ -1913,6 +1914,11 @@ struct gl_program
|
|||||||
/** Vertex program user-defined attributes */
|
/** Vertex program user-defined attributes */
|
||||||
struct gl_program_parameter_list *Attributes;
|
struct gl_program_parameter_list *Attributes;
|
||||||
|
|
||||||
|
/** Map from sampler unit to texture unit (set by glUniform1i()) */
|
||||||
|
GLubyte SamplerUnits[MAX_SAMPLERS];
|
||||||
|
/** Which texture target is being sampled (TEXTURE_1D/2D/3D/etc_INDEX) */
|
||||||
|
GLubyte SamplerTargets[MAX_SAMPLERS];
|
||||||
|
|
||||||
/** Logical counts */
|
/** Logical counts */
|
||||||
/*@{*/
|
/*@{*/
|
||||||
GLuint NumInstructions;
|
GLuint NumInstructions;
|
||||||
|
@@ -84,6 +84,7 @@ struct failover_context {
|
|||||||
struct pipe_framebuffer_state framebuffer;
|
struct pipe_framebuffer_state framebuffer;
|
||||||
struct pipe_poly_stipple poly_stipple;
|
struct pipe_poly_stipple poly_stipple;
|
||||||
struct pipe_scissor_state scissor;
|
struct pipe_scissor_state scissor;
|
||||||
|
uint sampler_units[PIPE_MAX_SAMPLERS];
|
||||||
struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
|
struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
|
||||||
struct pipe_viewport_state viewport;
|
struct pipe_viewport_state viewport;
|
||||||
struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
|
struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
|
||||||
|
@@ -294,6 +294,19 @@ failover_set_polygon_stipple( struct pipe_context *pipe,
|
|||||||
failover->hw->set_polygon_stipple( failover->hw, stipple );
|
failover->hw->set_polygon_stipple( failover->hw, stipple );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
failover_set_sampler_units( struct pipe_context *pipe,
|
||||||
|
uint num_samplers, const uint *units )
|
||||||
|
{
|
||||||
|
struct failover_context *failover = failover_context(pipe);
|
||||||
|
uint i;
|
||||||
|
|
||||||
|
for (i = 0; i < num_samplers; i++)
|
||||||
|
failover->sampler_units[i] = units[i];
|
||||||
|
failover->dirty |= FO_NEW_SAMPLER;
|
||||||
|
failover->hw->set_sampler_units(failover->hw, num_samplers, units);
|
||||||
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
failover_create_rasterizer_state(struct pipe_context *pipe,
|
failover_create_rasterizer_state(struct pipe_context *pipe,
|
||||||
const struct pipe_rasterizer_state *templ)
|
const struct pipe_rasterizer_state *templ)
|
||||||
@@ -470,6 +483,7 @@ failover_init_state_functions( struct failover_context *failover )
|
|||||||
failover->pipe.set_clear_color_state = failover_set_clear_color_state;
|
failover->pipe.set_clear_color_state = failover_set_clear_color_state;
|
||||||
failover->pipe.set_framebuffer_state = failover_set_framebuffer_state;
|
failover->pipe.set_framebuffer_state = failover_set_framebuffer_state;
|
||||||
failover->pipe.set_polygon_stipple = failover_set_polygon_stipple;
|
failover->pipe.set_polygon_stipple = failover_set_polygon_stipple;
|
||||||
|
failover->pipe.set_sampler_units = failover_set_sampler_units;
|
||||||
failover->pipe.set_scissor_state = failover_set_scissor_state;
|
failover->pipe.set_scissor_state = failover_set_scissor_state;
|
||||||
failover->pipe.set_texture_state = failover_set_texture_state;
|
failover->pipe.set_texture_state = failover_set_texture_state;
|
||||||
failover->pipe.set_viewport_state = failover_set_viewport_state;
|
failover->pipe.set_viewport_state = failover_set_viewport_state;
|
||||||
|
@@ -173,6 +173,7 @@ struct i915_context
|
|||||||
struct pipe_framebuffer_state framebuffer;
|
struct pipe_framebuffer_state framebuffer;
|
||||||
struct pipe_poly_stipple poly_stipple;
|
struct pipe_poly_stipple poly_stipple;
|
||||||
struct pipe_scissor_state scissor;
|
struct pipe_scissor_state scissor;
|
||||||
|
uint sampler_units[PIPE_MAX_SAMPLERS];
|
||||||
struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
|
struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
|
||||||
struct pipe_viewport_state viewport;
|
struct pipe_viewport_state viewport;
|
||||||
struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
|
struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
|
||||||
|
@@ -446,6 +446,15 @@ static void i915_set_polygon_stipple( struct pipe_context *pipe,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void i915_set_sampler_units(struct pipe_context *pipe,
|
||||||
|
uint numSamplers, const uint *units)
|
||||||
|
{
|
||||||
|
struct i915_context *i915 = i915_context(pipe);
|
||||||
|
uint i;
|
||||||
|
for (i = 0; i < numSamplers; i++)
|
||||||
|
i915->sampler_units[i] = units[i];
|
||||||
|
}
|
||||||
|
|
||||||
static void * i915_create_fs_state(struct pipe_context *pipe,
|
static void * i915_create_fs_state(struct pipe_context *pipe,
|
||||||
const struct pipe_shader_state *templ)
|
const struct pipe_shader_state *templ)
|
||||||
{
|
{
|
||||||
@@ -765,6 +774,7 @@ i915_init_state_functions( struct i915_context *i915 )
|
|||||||
i915->pipe.set_feedback_buffer = i915_set_feedback_buffer;
|
i915->pipe.set_feedback_buffer = i915_set_feedback_buffer;
|
||||||
|
|
||||||
i915->pipe.set_polygon_stipple = i915_set_polygon_stipple;
|
i915->pipe.set_polygon_stipple = i915_set_polygon_stipple;
|
||||||
|
i915->pipe.set_sampler_units = i915_set_sampler_units;
|
||||||
i915->pipe.set_scissor_state = i915_set_scissor_state;
|
i915->pipe.set_scissor_state = i915_set_scissor_state;
|
||||||
i915->pipe.set_texture_state = i915_set_texture_state;
|
i915->pipe.set_texture_state = i915_set_texture_state;
|
||||||
i915->pipe.set_viewport_state = i915_set_viewport_state;
|
i915->pipe.set_viewport_state = i915_set_viewport_state;
|
||||||
|
@@ -148,6 +148,9 @@ struct pipe_context {
|
|||||||
void (*set_polygon_stipple)( struct pipe_context *,
|
void (*set_polygon_stipple)( struct pipe_context *,
|
||||||
const struct pipe_poly_stipple * );
|
const struct pipe_poly_stipple * );
|
||||||
|
|
||||||
|
void (*set_sampler_units)( struct pipe_context *,
|
||||||
|
uint num_samplers, const uint *units );
|
||||||
|
|
||||||
void (*set_scissor_state)( struct pipe_context *,
|
void (*set_scissor_state)( struct pipe_context *,
|
||||||
const struct pipe_scissor_state * );
|
const struct pipe_scissor_state * );
|
||||||
|
|
||||||
|
@@ -318,6 +318,7 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
|
|||||||
softpipe->pipe.set_feedback_state = softpipe_set_feedback_state;
|
softpipe->pipe.set_feedback_state = softpipe_set_feedback_state;
|
||||||
softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
|
softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
|
||||||
softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple;
|
softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple;
|
||||||
|
softpipe->pipe.set_sampler_units = softpipe_set_sampler_units;
|
||||||
softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;
|
softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;
|
||||||
softpipe->pipe.set_texture_state = softpipe_set_texture_state;
|
softpipe->pipe.set_texture_state = softpipe_set_texture_state;
|
||||||
softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
|
softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
|
||||||
|
@@ -95,6 +95,7 @@ struct softpipe_context {
|
|||||||
struct pipe_viewport_state viewport;
|
struct pipe_viewport_state viewport;
|
||||||
struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
|
struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
|
||||||
struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX];
|
struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX];
|
||||||
|
uint sampler_units[PIPE_MAX_SAMPLERS];
|
||||||
unsigned dirty;
|
unsigned dirty;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -85,6 +85,7 @@ shade_quad(
|
|||||||
/* Consts does not require 16 byte alignment. */
|
/* Consts does not require 16 byte alignment. */
|
||||||
machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT];
|
machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT];
|
||||||
|
|
||||||
|
machine->SamplerUnits = softpipe->sampler_units;
|
||||||
machine->InterpCoefs = quad->coef;
|
machine->InterpCoefs = quad->coef;
|
||||||
|
|
||||||
machine->Inputs[0].xyzw[0].f[0] = fx;
|
machine->Inputs[0].xyzw[0].f[0] = fx;
|
||||||
|
@@ -99,6 +99,9 @@ void softpipe_delete_vs_state(struct pipe_context *, void *);
|
|||||||
void softpipe_set_polygon_stipple( struct pipe_context *,
|
void softpipe_set_polygon_stipple( struct pipe_context *,
|
||||||
const struct pipe_poly_stipple * );
|
const struct pipe_poly_stipple * );
|
||||||
|
|
||||||
|
void softpipe_set_sampler_units( struct pipe_context *,
|
||||||
|
uint numSamplers, const uint *units );
|
||||||
|
|
||||||
void softpipe_set_scissor_state( struct pipe_context *,
|
void softpipe_set_scissor_state( struct pipe_context *,
|
||||||
const struct pipe_scissor_state * );
|
const struct pipe_scissor_state * );
|
||||||
|
|
||||||
|
@@ -78,3 +78,17 @@ softpipe_set_texture_state(struct pipe_context *pipe,
|
|||||||
|
|
||||||
softpipe->dirty |= SP_NEW_TEXTURE;
|
softpipe->dirty |= SP_NEW_TEXTURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
softpipe_set_sampler_units(struct pipe_context *pipe,
|
||||||
|
uint num_samplers, const uint *units )
|
||||||
|
{
|
||||||
|
struct softpipe_context *softpipe = softpipe_context(pipe);
|
||||||
|
uint i;
|
||||||
|
for (i = 0; i < num_samplers; i++)
|
||||||
|
softpipe->sampler_units[i] = units[i];
|
||||||
|
softpipe->dirty |= SP_NEW_SAMPLER;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1219,11 +1219,14 @@ exec_tex(struct tgsi_exec_machine *mach,
|
|||||||
const struct tgsi_full_instruction *inst,
|
const struct tgsi_full_instruction *inst,
|
||||||
boolean biasLod)
|
boolean biasLod)
|
||||||
{
|
{
|
||||||
const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index;
|
const uint sampler = inst->FullSrcRegisters[1].SrcRegister.Index;
|
||||||
|
const uint unit = mach->SamplerUnits[sampler];
|
||||||
union tgsi_exec_channel r[8];
|
union tgsi_exec_channel r[8];
|
||||||
uint chan_index;
|
uint chan_index;
|
||||||
float lodBias;
|
float lodBias;
|
||||||
|
|
||||||
|
// printf("Sampler %u unit %u\n", sampler, unit);
|
||||||
|
|
||||||
switch (inst->InstructionExtTexture.Texture) {
|
switch (inst->InstructionExtTexture.Texture) {
|
||||||
case TGSI_TEXTURE_1D:
|
case TGSI_TEXTURE_1D:
|
||||||
|
|
||||||
|
@@ -118,6 +118,7 @@ struct tgsi_exec_machine
|
|||||||
struct tgsi_exec_vector *Temps;
|
struct tgsi_exec_vector *Temps;
|
||||||
struct tgsi_exec_vector *Addrs;
|
struct tgsi_exec_vector *Addrs;
|
||||||
|
|
||||||
|
uint *SamplerUnits;
|
||||||
struct tgsi_sampler *Samplers;
|
struct tgsi_sampler *Samplers;
|
||||||
|
|
||||||
float Imms[TGSI_EXEC_NUM_IMMEDIATES][4];
|
float Imms[TGSI_EXEC_NUM_IMMEDIATES][4];
|
||||||
|
@@ -1316,22 +1316,22 @@ _mesa_execute_program(GLcontext * ctx,
|
|||||||
* The rest of the time, just use zero (until we get a more
|
* The rest of the time, just use zero (until we get a more
|
||||||
* sophisticated way of computing lambda).
|
* sophisticated way of computing lambda).
|
||||||
*/
|
*/
|
||||||
|
const GLuint unit = machine->Samplers[inst->TexSrcUnit];
|
||||||
GLfloat coord[4], color[4], lambda;
|
GLfloat coord[4], color[4], lambda;
|
||||||
#if 0
|
#if 0
|
||||||
if (inst->SrcReg[0].File == PROGRAM_INPUT &&
|
if (inst->SrcReg[0].File == PROGRAM_INPUT &&
|
||||||
inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit)
|
inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + unit)
|
||||||
lambda = span->array->lambda[inst->TexSrcUnit][column];
|
lambda = span->array->lambda[unit][column];
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
lambda = 0.0;
|
lambda = 0.0;
|
||||||
fetch_vector4(&inst->SrcReg[0], machine, coord);
|
fetch_vector4(&inst->SrcReg[0], machine, coord);
|
||||||
machine->FetchTexelLod(ctx, coord, lambda, inst->TexSrcUnit,
|
machine->FetchTexelLod(ctx, coord, lambda, unit, color);
|
||||||
color);
|
|
||||||
if (DEBUG_PROG) {
|
if (DEBUG_PROG) {
|
||||||
printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g], "
|
printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g], "
|
||||||
"lod %f\n",
|
"lod %f\n",
|
||||||
color[0], color[1], color[2], color[3],
|
color[0], color[1], color[2], color[3],
|
||||||
inst->TexSrcUnit,
|
unit,
|
||||||
coord[0], coord[1], coord[2], coord[3], lambda);
|
coord[0], coord[1], coord[2], coord[3], lambda);
|
||||||
}
|
}
|
||||||
store_vector4(inst, machine, color);
|
store_vector4(inst, machine, color);
|
||||||
@@ -1375,11 +1375,12 @@ _mesa_execute_program(GLcontext * ctx,
|
|||||||
case OPCODE_TXP: /* GL_ARB_fragment_program only */
|
case OPCODE_TXP: /* GL_ARB_fragment_program only */
|
||||||
/* Texture lookup w/ projective divide */
|
/* Texture lookup w/ projective divide */
|
||||||
{
|
{
|
||||||
|
const GLuint unit = machine->Samplers[inst->TexSrcUnit];
|
||||||
GLfloat texcoord[4], color[4], lambda;
|
GLfloat texcoord[4], color[4], lambda;
|
||||||
#if 0
|
#if 0
|
||||||
if (inst->SrcReg[0].File == PROGRAM_INPUT &&
|
if (inst->SrcReg[0].File == PROGRAM_INPUT &&
|
||||||
inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit)
|
inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit)
|
||||||
lambda = span->array->lambda[inst->TexSrcUnit][column];
|
lambda = span->array->lambda[unit][column];
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
lambda = 0.0;
|
lambda = 0.0;
|
||||||
@@ -1393,8 +1394,7 @@ _mesa_execute_program(GLcontext * ctx,
|
|||||||
texcoord[1] /= texcoord[3];
|
texcoord[1] /= texcoord[3];
|
||||||
texcoord[2] /= texcoord[3];
|
texcoord[2] /= texcoord[3];
|
||||||
}
|
}
|
||||||
machine->FetchTexelLod(ctx, texcoord, lambda,
|
machine->FetchTexelLod(ctx, texcoord, lambda, unit, color);
|
||||||
inst->TexSrcUnit, color);
|
|
||||||
store_vector4(inst, machine, color);
|
store_vector4(inst, machine, color);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@@ -62,6 +62,8 @@ struct gl_program_machine
|
|||||||
GLuint CondCodes[4]; /**< COND_* value for x/y/z/w */
|
GLuint CondCodes[4]; /**< COND_* value for x/y/z/w */
|
||||||
GLint AddressReg[MAX_PROGRAM_ADDRESS_REGS][4];
|
GLint AddressReg[MAX_PROGRAM_ADDRESS_REGS][4];
|
||||||
|
|
||||||
|
GLuint *Samplers; /** Array mapping sampler var to tex unit */
|
||||||
|
|
||||||
GLuint CallStack[MAX_PROGRAM_CALL_DEPTH]; /**< For CAL/RET instructions */
|
GLuint CallStack[MAX_PROGRAM_CALL_DEPTH]; /**< For CAL/RET instructions */
|
||||||
GLuint StackDepth; /**< Index/ptr to top of CallStack[] */
|
GLuint StackDepth; /**< Index/ptr to top of CallStack[] */
|
||||||
|
|
||||||
|
@@ -246,6 +246,17 @@ _mesa_num_inst_dst_regs(gl_inst_opcode opcode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return string name for given program opcode.
|
* Return string name for given program opcode.
|
||||||
*/
|
*/
|
||||||
|
@@ -413,11 +413,13 @@ struct prog_instruction
|
|||||||
*/
|
*/
|
||||||
GLint BranchTarget;
|
GLint BranchTarget;
|
||||||
|
|
||||||
|
#if 0
|
||||||
/**
|
/**
|
||||||
* For TEX instructions in shaders, the sampler to use for the
|
* For TEX instructions in shaders, the sampler to use for the
|
||||||
* texture lookup.
|
* texture lookup.
|
||||||
*/
|
*/
|
||||||
GLint Sampler;
|
GLint Sampler;
|
||||||
|
#endif
|
||||||
|
|
||||||
const char *Comment;
|
const char *Comment;
|
||||||
};
|
};
|
||||||
@@ -443,6 +445,9 @@ _mesa_num_inst_src_regs(gl_inst_opcode opcode);
|
|||||||
extern GLuint
|
extern GLuint
|
||||||
_mesa_num_inst_dst_regs(gl_inst_opcode opcode);
|
_mesa_num_inst_dst_regs(gl_inst_opcode opcode);
|
||||||
|
|
||||||
|
extern GLboolean
|
||||||
|
_mesa_is_tex_instruction(gl_inst_opcode opcode);
|
||||||
|
|
||||||
extern const char *
|
extern const char *
|
||||||
_mesa_opcode_string(gl_inst_opcode opcode);
|
_mesa_opcode_string(gl_inst_opcode opcode);
|
||||||
|
|
||||||
|
@@ -283,22 +283,25 @@ _mesa_add_uniform(struct gl_program_parameter_list *paramList,
|
|||||||
* Add a sampler to the parameter list.
|
* Add a sampler to the parameter list.
|
||||||
* \param name uniform's name
|
* \param name uniform's name
|
||||||
* \param datatype GL_SAMPLER_2D, GL_SAMPLER_2D_RECT_ARB, etc.
|
* \param datatype GL_SAMPLER_2D, GL_SAMPLER_2D_RECT_ARB, etc.
|
||||||
|
* \param index the sampler number (as seen in TEX instructions)
|
||||||
*/
|
*/
|
||||||
GLint
|
GLint
|
||||||
_mesa_add_sampler(struct gl_program_parameter_list *paramList,
|
_mesa_add_sampler(struct gl_program_parameter_list *paramList,
|
||||||
const char *name, GLenum datatype)
|
const char *name, GLenum datatype, GLuint index)
|
||||||
{
|
{
|
||||||
GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
|
GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
|
||||||
if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_SAMPLER) {
|
if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_SAMPLER) {
|
||||||
ASSERT(paramList->Parameters[i].Size == 1);
|
ASSERT(paramList->Parameters[i].Size == 1);
|
||||||
ASSERT(paramList->Parameters[i].DataType == datatype);
|
ASSERT(paramList->Parameters[i].DataType == datatype);
|
||||||
|
ASSERT(paramList->ParameterValues[i][0] == index);
|
||||||
/* already in list */
|
/* already in list */
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
GLfloat indexf = index;
|
||||||
const GLint size = 1; /* a sampler is basically a texture unit number */
|
const GLint size = 1; /* a sampler is basically a texture unit number */
|
||||||
i = _mesa_add_parameter(paramList, PROGRAM_SAMPLER, name,
|
i = _mesa_add_parameter(paramList, PROGRAM_SAMPLER, name,
|
||||||
size, datatype, NULL, NULL);
|
size, datatype, &indexf, NULL);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -104,7 +104,7 @@ _mesa_add_uniform(struct gl_program_parameter_list *paramList,
|
|||||||
|
|
||||||
extern GLint
|
extern GLint
|
||||||
_mesa_add_sampler(struct gl_program_parameter_list *paramList,
|
_mesa_add_sampler(struct gl_program_parameter_list *paramList,
|
||||||
const char *name, GLenum datatype);
|
const char *name, GLenum datatype, GLuint index);
|
||||||
|
|
||||||
extern GLint
|
extern GLint
|
||||||
_mesa_add_varying(struct gl_program_parameter_list *paramList,
|
_mesa_add_varying(struct gl_program_parameter_list *paramList,
|
||||||
|
@@ -719,6 +719,8 @@ _mesa_print_program_opt(const struct gl_program *prog,
|
|||||||
void
|
void
|
||||||
_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog)
|
_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog)
|
||||||
{
|
{
|
||||||
|
GLuint i;
|
||||||
|
|
||||||
_mesa_printf("InputsRead: 0x%x\n", prog->InputsRead);
|
_mesa_printf("InputsRead: 0x%x\n", prog->InputsRead);
|
||||||
_mesa_printf("OutputsWritten: 0x%x\n", prog->OutputsWritten);
|
_mesa_printf("OutputsWritten: 0x%x\n", prog->OutputsWritten);
|
||||||
_mesa_printf("NumInstructions=%d\n", prog->NumInstructions);
|
_mesa_printf("NumInstructions=%d\n", prog->NumInstructions);
|
||||||
@@ -726,6 +728,11 @@ _mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog)
|
|||||||
_mesa_printf("NumParameters=%d\n", prog->NumParameters);
|
_mesa_printf("NumParameters=%d\n", prog->NumParameters);
|
||||||
_mesa_printf("NumAttributes=%d\n", prog->NumAttributes);
|
_mesa_printf("NumAttributes=%d\n", prog->NumAttributes);
|
||||||
_mesa_printf("NumAddressRegs=%d\n", prog->NumAddressRegs);
|
_mesa_printf("NumAddressRegs=%d\n", prog->NumAddressRegs);
|
||||||
|
_mesa_printf("Samplers=[ ");
|
||||||
|
for (i = 0; i < MAX_SAMPLERS; i++) {
|
||||||
|
_mesa_printf("%d ", prog->SamplerUnits[i]);
|
||||||
|
}
|
||||||
|
_mesa_printf("]\n");
|
||||||
|
|
||||||
_mesa_load_state_parameters(ctx, prog->Parameters);
|
_mesa_load_state_parameters(ctx, prog->Parameters);
|
||||||
|
|
||||||
|
@@ -187,12 +187,17 @@ _mesa_init_program_struct( GLcontext *ctx, struct gl_program *prog,
|
|||||||
{
|
{
|
||||||
(void) ctx;
|
(void) ctx;
|
||||||
if (prog) {
|
if (prog) {
|
||||||
|
GLuint i;
|
||||||
_mesa_bzero(prog, sizeof(*prog));
|
_mesa_bzero(prog, sizeof(*prog));
|
||||||
prog->Id = id;
|
prog->Id = id;
|
||||||
prog->Target = target;
|
prog->Target = target;
|
||||||
prog->Resident = GL_TRUE;
|
prog->Resident = GL_TRUE;
|
||||||
prog->RefCount = 1;
|
prog->RefCount = 1;
|
||||||
prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB;
|
prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB;
|
||||||
|
|
||||||
|
/* default mapping from samplers to texture units */
|
||||||
|
for (i = 0; i < MAX_SAMPLERS; i++)
|
||||||
|
prog->SamplerUnits[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return prog;
|
return prog;
|
||||||
|
@@ -1045,6 +1045,28 @@ _mesa_use_program(GLcontext *ctx, GLuint program)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the vertex and fragment program's TexturesUsed arrays.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
update_textures_used(struct gl_program *prog)
|
||||||
|
{
|
||||||
|
GLuint s;
|
||||||
|
|
||||||
|
memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
|
||||||
|
|
||||||
|
for (s = 0; s < MAX_SAMPLERS; s++) {
|
||||||
|
if (prog->SamplersUsed & (1 << s)) {
|
||||||
|
GLuint u = prog->SamplerUnits[s];
|
||||||
|
GLuint t = prog->SamplerTargets[s];
|
||||||
|
assert(u < MAX_TEXTURE_IMAGE_UNITS);
|
||||||
|
prog->TexturesUsed[u] |= (1 << t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called via ctx->Driver.Uniform().
|
* Called via ctx->Driver.Uniform().
|
||||||
*/
|
*/
|
||||||
@@ -1067,26 +1089,6 @@ _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
|
|||||||
|
|
||||||
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
|
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
|
||||||
|
|
||||||
/*
|
|
||||||
* If we're setting a sampler, we must use glUniformi1()!
|
|
||||||
*/
|
|
||||||
if (shProg->Uniforms->Parameters[location].Type == PROGRAM_SAMPLER) {
|
|
||||||
GLint unit;
|
|
||||||
if (type != GL_INT || count != 1) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
|
||||||
"glUniform(only glUniform1i can be used "
|
|
||||||
"to set sampler uniforms)");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* check that the sampler (tex unit index) is legal */
|
|
||||||
unit = ((GLint *) values)[0];
|
|
||||||
if (unit >= ctx->Const.MaxTextureImageUnits) {
|
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE,
|
|
||||||
"glUniform1(invalid sampler/tex unit index)");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count < 0) {
|
if (count < 0) {
|
||||||
_mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)");
|
_mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)");
|
||||||
return;
|
return;
|
||||||
@@ -1119,32 +1121,61 @@ _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (k = 0; k < count; k++) {
|
|
||||||
GLfloat *uniformVal = shProg->Uniforms->ParameterValues[location + k];
|
|
||||||
if (type == GL_INT ||
|
|
||||||
type == GL_INT_VEC2 ||
|
|
||||||
type == GL_INT_VEC3 ||
|
|
||||||
type == GL_INT_VEC4) {
|
|
||||||
const GLint *iValues = ((const GLint *) values) + k * elems;
|
|
||||||
for (i = 0; i < elems; i++) {
|
|
||||||
uniformVal[i] = (GLfloat) iValues[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
|
|
||||||
for (i = 0; i < elems; i++) {
|
|
||||||
uniformVal[i] = fValues[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shProg->Uniforms->Parameters[location].Type == PROGRAM_SAMPLER) {
|
if (shProg->Uniforms->Parameters[location].Type == PROGRAM_SAMPLER) {
|
||||||
if (shProg->VertexProgram)
|
/* This controls which texture unit which is used by a sampler */
|
||||||
_slang_resolve_samplers(shProg, &shProg->VertexProgram->Base);
|
GLuint texUnit, sampler;
|
||||||
if (shProg->FragmentProgram)
|
|
||||||
_slang_resolve_samplers(shProg, &shProg->FragmentProgram->Base);
|
/* data type for setting samplers must be int */
|
||||||
|
if (type != GL_INT || count != 1) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||||
|
"glUniform(only glUniform1i can be used "
|
||||||
|
"to set sampler uniforms)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sampler = (GLuint) shProg->Uniforms->ParameterValues[location][0];
|
||||||
|
texUnit = ((GLuint *) values)[0];
|
||||||
|
|
||||||
|
/* check that the sampler (tex unit index) is legal */
|
||||||
|
if (texUnit >= ctx->Const.MaxTextureImageUnits) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_VALUE,
|
||||||
|
"glUniform1(invalid sampler/tex unit index)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shProg->VertexProgram) {
|
||||||
|
shProg->VertexProgram->Base.SamplerUnits[sampler] = texUnit;
|
||||||
|
update_textures_used(&shProg->VertexProgram->Base);
|
||||||
|
}
|
||||||
|
if (shProg->FragmentProgram) {
|
||||||
|
shProg->FragmentProgram->Base.SamplerUnits[sampler] = texUnit;
|
||||||
|
update_textures_used(&shProg->FragmentProgram->Base);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
|
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
/* ordinary uniform variable */
|
||||||
|
for (k = 0; k < count; k++) {
|
||||||
|
GLfloat *uniformVal = shProg->Uniforms->ParameterValues[location + k];
|
||||||
|
if (type == GL_INT ||
|
||||||
|
type == GL_INT_VEC2 ||
|
||||||
|
type == GL_INT_VEC3 ||
|
||||||
|
type == GL_INT_VEC4) {
|
||||||
|
const GLint *iValues = ((const GLint *) values) + k * elems;
|
||||||
|
for (i = 0; i < elems; i++) {
|
||||||
|
uniformVal[i] = (GLfloat) iValues[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
|
||||||
|
for (i = 0; i < elems; i++) {
|
||||||
|
uniformVal[i] = fValues[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -2874,14 +2874,23 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
|
|||||||
const GLint texIndex = sampler_to_texture_index(var->type.specifier.type);
|
const GLint texIndex = sampler_to_texture_index(var->type.specifier.type);
|
||||||
|
|
||||||
if (texIndex != -1) {
|
if (texIndex != -1) {
|
||||||
/* Texture sampler:
|
/* This is a texture sampler variable...
|
||||||
* store->File = PROGRAM_SAMPLER
|
* store->File = PROGRAM_SAMPLER
|
||||||
* store->Index = sampler uniform location
|
* store->Index = sampler number (0..7, typically)
|
||||||
* store->Size = texture type index (1D, 2D, 3D, cube, etc)
|
* store->Size = texture type index (1D, 2D, 3D, cube, etc)
|
||||||
*/
|
*/
|
||||||
|
#if 0
|
||||||
GLint samplerUniform
|
GLint samplerUniform
|
||||||
= _mesa_add_sampler(prog->Parameters, varName, datatype);
|
= _mesa_add_sampler(prog->Parameters, varName, datatype);
|
||||||
store = _slang_new_ir_storage(PROGRAM_SAMPLER, samplerUniform, texIndex);
|
#elif 0
|
||||||
|
GLint samplerUniform
|
||||||
|
= _mesa_add_sampler(prog->Samplers, varName, datatype);
|
||||||
|
(void) _mesa_add_sampler(prog->Parameters, varName, datatype); /* dummy entry */
|
||||||
|
#else
|
||||||
|
const GLint sampNum = A->numSamplers++;
|
||||||
|
_mesa_add_sampler(prog->Parameters, varName, datatype, sampNum);
|
||||||
|
#endif
|
||||||
|
store = _slang_new_ir_storage(PROGRAM_SAMPLER, sampNum, texIndex);
|
||||||
if (dbg) printf("SAMPLER ");
|
if (dbg) printf("SAMPLER ");
|
||||||
}
|
}
|
||||||
else if (var->type.qualifier == SLANG_QUAL_UNIFORM) {
|
else if (var->type.qualifier == SLANG_QUAL_UNIFORM) {
|
||||||
|
@@ -1618,6 +1618,7 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,
|
|||||||
A.program = O->program;
|
A.program = O->program;
|
||||||
A.vartable = O->vartable;
|
A.vartable = O->vartable;
|
||||||
A.curFuncEndLabel = NULL;
|
A.curFuncEndLabel = NULL;
|
||||||
|
A.numSamplers = 0;
|
||||||
if (!_slang_codegen_global_variable(&A, var, C->type))
|
if (!_slang_codegen_global_variable(&A, var, C->type))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1640,6 +1641,7 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,
|
|||||||
A.space.funcs = O->funs;
|
A.space.funcs = O->funs;
|
||||||
A.space.structs = O->structs;
|
A.space.structs = O->structs;
|
||||||
A.space.vars = O->vars;
|
A.space.vars = O->vars;
|
||||||
|
A.numSamplers = 0;
|
||||||
if (!initialize_global(&A, var))
|
if (!initialize_global(&A, var))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1773,6 +1775,7 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
|
|||||||
A.program = O->program;
|
A.program = O->program;
|
||||||
A.vartable = O->vartable;
|
A.vartable = O->vartable;
|
||||||
A.log = C->L;
|
A.log = C->L;
|
||||||
|
A.numSamplers = 0;
|
||||||
|
|
||||||
_slang_codegen_function(&A, *parsed_func_ret);
|
_slang_codegen_function(&A, *parsed_func_ret);
|
||||||
}
|
}
|
||||||
@@ -2152,6 +2155,9 @@ _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();
|
shader->Programs[0]->Attributes = _mesa_new_parameter_list();
|
||||||
|
#if 0
|
||||||
|
shader->Programs[0]->Samplers = _mesa_new_parameter_list();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
slang_info_log_construct(&info_log);
|
slang_info_log_construct(&info_log);
|
||||||
|
@@ -906,11 +906,15 @@ emit_tex(slang_emit_info *emitInfo, slang_ir_node *n)
|
|||||||
assert(n->Children[0]->Store->Size >= TEXTURE_1D_INDEX);
|
assert(n->Children[0]->Store->Size >= TEXTURE_1D_INDEX);
|
||||||
assert(n->Children[0]->Store->Size <= TEXTURE_RECT_INDEX);
|
assert(n->Children[0]->Store->Size <= TEXTURE_RECT_INDEX);
|
||||||
|
|
||||||
inst->Sampler = n->Children[0]->Store->Index; /* i.e. uniform's index */
|
|
||||||
inst->TexSrcTarget = n->Children[0]->Store->Size;
|
inst->TexSrcTarget = n->Children[0]->Store->Size;
|
||||||
|
#if 0
|
||||||
inst->TexSrcUnit = 27; /* Dummy value; the TexSrcUnit will be computed at
|
inst->TexSrcUnit = 27; /* Dummy value; the TexSrcUnit will be computed at
|
||||||
* link time, using the sampler uniform's value.
|
* link time, using the sampler uniform's value.
|
||||||
*/
|
*/
|
||||||
|
inst->Sampler = n->Children[0]->Store->Index; /* i.e. uniform's index */
|
||||||
|
#else
|
||||||
|
inst->TexSrcUnit = n->Children[0]->Store->Index; /* i.e. uniform's index */
|
||||||
|
#endif
|
||||||
return inst;
|
return inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -144,10 +144,14 @@ is_uniform(GLuint file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static GLuint shProg_NumSamplers = 0; /** XXX temporary */
|
||||||
|
|
||||||
|
|
||||||
static GLboolean
|
static GLboolean
|
||||||
link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog)
|
link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog)
|
||||||
{
|
{
|
||||||
GLuint *map, i;
|
GLuint *map, i;
|
||||||
|
GLuint samplerMap[MAX_SAMPLERS];
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
printf("================ pre link uniforms ===============\n");
|
printf("================ pre link uniforms ===============\n");
|
||||||
@@ -168,10 +172,13 @@ link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog)
|
|||||||
/* sanity check */
|
/* sanity check */
|
||||||
assert(is_uniform(p->Type));
|
assert(is_uniform(p->Type));
|
||||||
|
|
||||||
|
/* See if this uniform is already in the linked program's list */
|
||||||
if (p->Name) {
|
if (p->Name) {
|
||||||
|
/* this is a named uniform */
|
||||||
j = _mesa_lookup_parameter_index(shProg->Uniforms, -1, p->Name);
|
j = _mesa_lookup_parameter_index(shProg->Uniforms, -1, p->Name);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
/* this is an unnamed constant */
|
||||||
/*GLuint swizzle;*/
|
/*GLuint swizzle;*/
|
||||||
ASSERT(p->Type == PROGRAM_CONSTANT);
|
ASSERT(p->Type == PROGRAM_CONSTANT);
|
||||||
if (_mesa_lookup_parameter_constant(shProg->Uniforms, pVals,
|
if (_mesa_lookup_parameter_constant(shProg->Uniforms, pVals,
|
||||||
@@ -184,7 +191,8 @@ link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (j >= 0) {
|
if (j >= 0) {
|
||||||
/* already in list, check size XXX check this */
|
/* already in linked program's list */
|
||||||
|
/* check size XXX check this */
|
||||||
#if 0
|
#if 0
|
||||||
assert(p->Size == shProg->Uniforms->Parameters[j].Size);
|
assert(p->Size == shProg->Uniforms->Parameters[j].Size);
|
||||||
#endif
|
#endif
|
||||||
@@ -205,7 +213,15 @@ link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog)
|
|||||||
j = _mesa_add_uniform(shProg->Uniforms, p->Name, p->Size, p->DataType);
|
j = _mesa_add_uniform(shProg->Uniforms, p->Name, p->Size, p->DataType);
|
||||||
break;
|
break;
|
||||||
case PROGRAM_SAMPLER:
|
case PROGRAM_SAMPLER:
|
||||||
j = _mesa_add_sampler(shProg->Uniforms, p->Name, p->DataType);
|
{
|
||||||
|
GLuint sampNum = shProg_NumSamplers++;
|
||||||
|
GLuint oldSampNum;
|
||||||
|
j = _mesa_add_sampler(shProg->Uniforms, p->Name,
|
||||||
|
p->DataType, sampNum);
|
||||||
|
oldSampNum = (GLuint) prog->Parameters->ParameterValues[i][0];
|
||||||
|
assert(oldSampNum < MAX_SAMPLERS);
|
||||||
|
samplerMap[oldSampNum] = sampNum;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
_mesa_problem(NULL, "bad parameter type in link_uniform_vars()");
|
_mesa_problem(NULL, "bad parameter type in link_uniform_vars()");
|
||||||
@@ -243,6 +259,7 @@ link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog)
|
|||||||
/* OK, now scan the program/shader instructions looking for uniform vars,
|
/* OK, now scan the program/shader instructions looking for uniform vars,
|
||||||
* replacing the old index with the new index.
|
* replacing the old index with the new index.
|
||||||
*/
|
*/
|
||||||
|
prog->SamplersUsed = 0x0;
|
||||||
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;
|
||||||
GLuint j;
|
GLuint j;
|
||||||
@@ -257,14 +274,15 @@ link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inst->Opcode == OPCODE_TEX ||
|
if (_mesa_is_tex_instruction(inst->Opcode)) {
|
||||||
inst->Opcode == OPCODE_TXB ||
|
|
||||||
inst->Opcode == OPCODE_TXP) {
|
|
||||||
/*
|
/*
|
||||||
printf("====== remap sampler from %d to %d\n",
|
printf("====== remap sampler from %d to %d\n",
|
||||||
inst->Sampler, map[ inst->Sampler ]);
|
inst->Sampler, map[ inst->Sampler ]);
|
||||||
*/
|
*/
|
||||||
inst->Sampler = map[ inst->Sampler ];
|
/* here, texUnit is really samplerUnit */
|
||||||
|
inst->TexSrcUnit = samplerMap[inst->TexSrcUnit];
|
||||||
|
prog->SamplerTargets[inst->TexSrcUnit] = inst->TexSrcTarget;
|
||||||
|
prog->SamplersUsed |= (1 << inst->TexSrcUnit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,36 +422,6 @@ _slang_remap_attribute(struct gl_program *prog, GLuint oldAttrib, GLuint newAttr
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 *
|
||||||
vertex_program(struct gl_program *prog)
|
vertex_program(struct gl_program *prog)
|
||||||
@@ -490,6 +478,8 @@ _slang_link(GLcontext *ctx,
|
|||||||
const struct gl_fragment_program *fragProg;
|
const struct gl_fragment_program *fragProg;
|
||||||
GLuint i;
|
GLuint i;
|
||||||
|
|
||||||
|
shProg_NumSamplers = 0; /** XXX temporary */
|
||||||
|
|
||||||
_mesa_clear_shader_program_data(ctx, shProg);
|
_mesa_clear_shader_program_data(ctx, shProg);
|
||||||
|
|
||||||
shProg->Uniforms = _mesa_new_parameter_list();
|
shProg->Uniforms = _mesa_new_parameter_list();
|
||||||
@@ -549,13 +539,6 @@ _slang_link(GLcontext *ctx,
|
|||||||
shProg->FragmentProgram->Base.Parameters = shProg->Uniforms;
|
shProg->FragmentProgram->Base.Parameters = shProg->Uniforms;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shProg->VertexProgram) {
|
|
||||||
_slang_resolve_samplers(shProg, &shProg->VertexProgram->Base);
|
|
||||||
}
|
|
||||||
if (shProg->FragmentProgram) {
|
|
||||||
_slang_resolve_samplers(shProg, &shProg->FragmentProgram->Base);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shProg->VertexProgram) {
|
if (shProg->VertexProgram) {
|
||||||
if (!_slang_resolve_attributes(shProg, &shProg->VertexProgram->Base)) {
|
if (!_slang_resolve_attributes(shProg, &shProg->VertexProgram->Base)) {
|
||||||
/*goto cleanup;*/
|
/*goto cleanup;*/
|
||||||
@@ -601,7 +584,7 @@ _slang_link(GLcontext *ctx,
|
|||||||
_mesa_print_program(&fragProg->Base);
|
_mesa_print_program(&fragProg->Base);
|
||||||
_mesa_print_program_parameters(ctx, &fragProg->Base);
|
_mesa_print_program_parameters(ctx, &fragProg->Base);
|
||||||
#endif
|
#endif
|
||||||
#if 0
|
#if 01
|
||||||
printf("************** linked fragment prog\n");
|
printf("************** linked fragment prog\n");
|
||||||
_mesa_print_program(&shProg->FragmentProgram->Base);
|
_mesa_print_program(&shProg->FragmentProgram->Base);
|
||||||
_mesa_print_program_parameters(ctx, &shProg->FragmentProgram->Base);
|
_mesa_print_program_parameters(ctx, &shProg->FragmentProgram->Base);
|
||||||
|
@@ -32,10 +32,6 @@ extern void
|
|||||||
_slang_link(GLcontext *ctx, GLhandleARB h,
|
_slang_link(GLcontext *ctx, GLhandleARB h,
|
||||||
struct gl_shader_program *shProg);
|
struct gl_shader_program *shProg);
|
||||||
|
|
||||||
extern void
|
|
||||||
_slang_resolve_samplers(struct gl_shader_program *shProg,
|
|
||||||
struct gl_program *prog);
|
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
_slang_remap_attribute(struct gl_program *prog, GLuint oldAttrib,
|
_slang_remap_attribute(struct gl_program *prog, GLuint oldAttrib,
|
||||||
GLuint newAttrib);
|
GLuint newAttrib);
|
||||||
|
@@ -65,6 +65,7 @@ typedef struct slang_assemble_ctx_
|
|||||||
struct slang_label_ *curFuncEndLabel;
|
struct slang_label_ *curFuncEndLabel;
|
||||||
struct slang_ir_node_ *CurLoop;
|
struct slang_ir_node_ *CurLoop;
|
||||||
struct slang_function_ *CurFunction;
|
struct slang_function_ *CurFunction;
|
||||||
|
GLuint numSamplers;
|
||||||
} slang_assemble_ctx;
|
} slang_assemble_ctx;
|
||||||
|
|
||||||
|
|
||||||
|
@@ -113,6 +113,23 @@ gl_filter_to_img_filter(GLenum filter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct gl_fragment_program *
|
||||||
|
current_fragment_program(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
struct gl_fragment_program *f;
|
||||||
|
|
||||||
|
if (ctx->Shader.CurrentProgram &&
|
||||||
|
ctx->Shader.CurrentProgram->LinkStatus &&
|
||||||
|
ctx->Shader.CurrentProgram->FragmentProgram) {
|
||||||
|
f = ctx->Shader.CurrentProgram->FragmentProgram;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
f = ctx->FragmentProgram._Current;
|
||||||
|
assert(f);
|
||||||
|
}
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_samplers(struct st_context *st)
|
update_samplers(struct st_context *st)
|
||||||
@@ -165,13 +182,27 @@ update_samplers(struct st_context *st)
|
|||||||
st->pipe->bind_sampler_state(st->pipe, u, cso->data);
|
st->pipe->bind_sampler_state(st->pipe, u, cso->data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* mapping from sampler vars to texture units */
|
||||||
|
{
|
||||||
|
struct gl_fragment_program *fprog = current_fragment_program(st->ctx);
|
||||||
|
const GLubyte *samplerUnits = fprog->Base.SamplerUnits;
|
||||||
|
uint sample_units[PIPE_MAX_SAMPLERS];
|
||||||
|
uint s;
|
||||||
|
for (s = 0; s < PIPE_MAX_SAMPLERS; s++) {
|
||||||
|
sample_units[s] = fprog->Base.SamplerUnits[s];
|
||||||
|
}
|
||||||
|
|
||||||
|
st->pipe->set_sampler_units(st->pipe, PIPE_MAX_SAMPLERS, sample_units);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const struct st_tracked_state st_update_sampler = {
|
const struct st_tracked_state st_update_sampler = {
|
||||||
.name = "st_update_sampler",
|
.name = "st_update_sampler",
|
||||||
.dirty = {
|
.dirty = {
|
||||||
.mesa = _NEW_TEXTURE,
|
.mesa = _NEW_TEXTURE | _NEW_PROGRAM,
|
||||||
.st = 0,
|
.st = 0,
|
||||||
},
|
},
|
||||||
.update = update_samplers
|
.update = update_samplers
|
||||||
|
@@ -113,6 +113,8 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine,
|
|||||||
machine->DerivY = (GLfloat (*)[4]) span->attrStepY;
|
machine->DerivY = (GLfloat (*)[4]) span->attrStepY;
|
||||||
machine->NumDeriv = FRAG_ATTRIB_MAX;
|
machine->NumDeriv = FRAG_ATTRIB_MAX;
|
||||||
|
|
||||||
|
machine->Samplers = program->Base.SamplerUnits;
|
||||||
|
|
||||||
/* if running a GLSL program (not ARB_fragment_program) */
|
/* if running a GLSL program (not ARB_fragment_program) */
|
||||||
if (ctx->Shader.CurrentProgram) {
|
if (ctx->Shader.CurrentProgram) {
|
||||||
/* Store front/back facing value in register FOGC.Y */
|
/* Store front/back facing value in register FOGC.Y */
|
||||||
|
Reference in New Issue
Block a user