mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 13:48:06 +02:00
Merge branch 'new-frag-attribs'
This branch introduces new FRAG_ATTRIB_FACE and FRAG_ATTRIB_PNTC fragment program inputs for GLSL gl_FrontFacing and gl_PointCoord. Before, these attributes were packed with the FOG attribute. That made things complicated elsewhere.
This commit is contained in:
commit
f3b215cba2
12 changed files with 107 additions and 151 deletions
|
|
@ -28,6 +28,30 @@
|
|||
/* Authors: Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Notes on wide points and sprite mode:
|
||||
*
|
||||
* In wide point/sprite mode we effectively need to convert each incoming
|
||||
* vertex into four outgoing vertices specifying the corners of a quad.
|
||||
* Since we don't (yet) have geometry shaders, we have to handle this here
|
||||
* in the draw module.
|
||||
*
|
||||
* For sprites, it also means that this is where we have to handle texcoords
|
||||
* for the vertices of the quad. OpenGL's GL_COORD_REPLACE state specifies
|
||||
* if/how enabled texcoords are automatically generated for sprites. We pass
|
||||
* that info through gallium in the pipe_rasterizer_state::sprite_coord_mode
|
||||
* array.
|
||||
*
|
||||
* Additionally, GLSL's gl_PointCoord fragment attribute has to be handled
|
||||
* here as well. This is basically an additional texture/generic attribute
|
||||
* that varies .x from 0 to 1 horizontally across the point and varies .y
|
||||
* vertically from 0 to 1 down the sprite.
|
||||
*
|
||||
* With geometry shaders, the state tracker could create a GS to do
|
||||
* most/all of this.
|
||||
*/
|
||||
|
||||
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "pipe/p_defines.h"
|
||||
|
|
@ -52,7 +76,7 @@ struct widepoint_stage {
|
|||
|
||||
int psize_slot;
|
||||
|
||||
int point_coord_fs_input; /**< input for pointcoord (and fog) */
|
||||
int point_coord_fs_input; /**< input for pointcoord */
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -64,8 +88,6 @@ widepoint_stage( struct draw_stage *stage )
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the vertex texcoords for sprite mode.
|
||||
* Coords may be left untouched or set to a right-side-up or upside-down
|
||||
|
|
@ -89,10 +111,12 @@ static void set_texcoords(const struct widepoint_stage *wide,
|
|||
}
|
||||
|
||||
if (wide->point_coord_fs_input >= 0) {
|
||||
/* put gl_PointCoord into extra vertex output's zw components */
|
||||
uint k = wide->stage.draw->extra_vp_outputs.slot;
|
||||
v->data[k][2] = tc[0];
|
||||
v->data[k][3] = tc[1];
|
||||
/* put gl_PointCoord into the extra vertex slot */
|
||||
uint slot = wide->stage.draw->extra_vp_outputs.slot;
|
||||
v->data[slot][0] = tc[0];
|
||||
v->data[slot][1] = tc[1];
|
||||
v->data[slot][2] = 0.0F;
|
||||
v->data[slot][3] = 1.0F;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -182,10 +206,10 @@ static void widepoint_point( struct draw_stage *stage,
|
|||
|
||||
|
||||
static int
|
||||
find_fog_input_attrib(struct draw_context *draw)
|
||||
find_pntc_input_attrib(struct draw_context *draw)
|
||||
{
|
||||
/* Scan the fragment program's input decls to find the fogcoord
|
||||
* attribute. The z/w components will store the point coord.
|
||||
/* Scan the fragment program's input decls to find the pointcoord
|
||||
* attribute. The xy components will store the point coord.
|
||||
*/
|
||||
return 0; /* XXX fix this */
|
||||
}
|
||||
|
|
@ -229,8 +253,8 @@ static void widepoint_first_point( struct draw_stage *stage,
|
|||
}
|
||||
wide->num_texcoords = j;
|
||||
|
||||
/* find fragment shader PointCoord/Fog input */
|
||||
wide->point_coord_fs_input = find_fog_input_attrib(draw);
|
||||
/* find fragment shader PointCoord input */
|
||||
wide->point_coord_fs_input = find_pntc_input_attrib(draw);
|
||||
|
||||
/* setup extra vp output (point coord implemented as a texcoord) */
|
||||
draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
|
||||
|
|
|
|||
|
|
@ -409,14 +409,6 @@ static void emit_interp( struct brw_wm_compile *c,
|
|||
}
|
||||
break;
|
||||
case FRAG_ATTRIB_FOGC:
|
||||
/* The FOGC input is really special. When a program uses glFogFragCoord,
|
||||
* the results returned are supposed to be (f,0,0,1). But for Mesa GLSL,
|
||||
* the glFrontFacing and glPointCoord values are also stashed in FOGC.
|
||||
* So, write the interpolated fog value to X, then either 0, 1, or the
|
||||
* stashed values to Y, Z, W. Note that this means that
|
||||
* glFogFragCoord.yzw can be wrong in those cases!
|
||||
*/
|
||||
|
||||
/* Interpolate the fog coordinate */
|
||||
emit_op(c,
|
||||
WM_PINTERP,
|
||||
|
|
@ -426,26 +418,40 @@ static void emit_interp( struct brw_wm_compile *c,
|
|||
deltas,
|
||||
get_pixel_w(c));
|
||||
|
||||
/* Move the front facing value into FOGC.y if it's needed. */
|
||||
if (c->fp->program.UsesFrontFacing) {
|
||||
emit_op(c,
|
||||
WM_FRONTFACING,
|
||||
dst_mask(dst, WRITEMASK_Y),
|
||||
0,
|
||||
src_undef(),
|
||||
src_undef(),
|
||||
src_undef());
|
||||
} else {
|
||||
emit_op(c,
|
||||
OPCODE_MOV,
|
||||
dst_mask(dst, WRITEMASK_Y),
|
||||
0,
|
||||
src_swizzle1(interp, SWIZZLE_ZERO),
|
||||
src_undef(),
|
||||
src_undef());
|
||||
}
|
||||
emit_op(c,
|
||||
OPCODE_MOV,
|
||||
dst_mask(dst, WRITEMASK_YZW),
|
||||
0,
|
||||
src_swizzle(interp,
|
||||
SWIZZLE_ZERO,
|
||||
SWIZZLE_ZERO,
|
||||
SWIZZLE_ZERO,
|
||||
SWIZZLE_ONE),
|
||||
src_undef(),
|
||||
src_undef());
|
||||
break;
|
||||
|
||||
case FRAG_ATTRIB_FACE:
|
||||
/* XXX review/test this case */
|
||||
emit_op(c,
|
||||
WM_FRONTFACING,
|
||||
dst_mask(dst, WRITEMASK_X),
|
||||
0,
|
||||
src_undef(),
|
||||
src_undef(),
|
||||
src_undef());
|
||||
break;
|
||||
|
||||
case FRAG_ATTRIB_PNTC:
|
||||
/* XXX review/test this case */
|
||||
emit_op(c,
|
||||
WM_PINTERP,
|
||||
dst_mask(dst, WRITEMASK_XY),
|
||||
0,
|
||||
interp,
|
||||
deltas,
|
||||
get_pixel_w(c));
|
||||
|
||||
/* Should do the PointCoord thing here. */
|
||||
emit_op(c,
|
||||
OPCODE_MOV,
|
||||
dst_mask(dst, WRITEMASK_ZW),
|
||||
|
|
@ -458,6 +464,7 @@ static void emit_interp( struct brw_wm_compile *c,
|
|||
src_undef(),
|
||||
src_undef());
|
||||
break;
|
||||
|
||||
default:
|
||||
emit_op(c,
|
||||
WM_PINTERP,
|
||||
|
|
|
|||
|
|
@ -228,7 +228,9 @@ typedef enum
|
|||
FRAG_ATTRIB_TEX5 = 9,
|
||||
FRAG_ATTRIB_TEX6 = 10,
|
||||
FRAG_ATTRIB_TEX7 = 11,
|
||||
FRAG_ATTRIB_VAR0 = 12, /**< shader varying */
|
||||
FRAG_ATTRIB_FACE = 12, /**< front/back face */
|
||||
FRAG_ATTRIB_PNTC = 13, /**< sprite/point coord */
|
||||
FRAG_ATTRIB_VAR0 = 14, /**< shader varying */
|
||||
FRAG_ATTRIB_MAX = (FRAG_ATTRIB_VAR0 + MAX_VARYING)
|
||||
} gl_frag_attrib;
|
||||
|
||||
|
|
@ -240,6 +242,8 @@ typedef enum
|
|||
#define FRAG_BIT_COL0 (1 << FRAG_ATTRIB_COL0)
|
||||
#define FRAG_BIT_COL1 (1 << FRAG_ATTRIB_COL1)
|
||||
#define FRAG_BIT_FOGC (1 << FRAG_ATTRIB_FOGC)
|
||||
#define FRAG_BIT_FACE (1 << FRAG_ATTRIB_FACE)
|
||||
#define FRAG_BIT_PNTC (1 << FRAG_ATTRIB_PNTC)
|
||||
#define FRAG_BIT_TEX0 (1 << FRAG_ATTRIB_TEX0)
|
||||
#define FRAG_BIT_TEX1 (1 << FRAG_ATTRIB_TEX1)
|
||||
#define FRAG_BIT_TEX2 (1 << FRAG_ATTRIB_TEX2)
|
||||
|
|
@ -1835,9 +1839,6 @@ struct gl_fragment_program
|
|||
struct gl_program Base; /**< base class */
|
||||
GLenum FogOption;
|
||||
GLboolean UsesKill; /**< shader uses KIL instruction */
|
||||
GLboolean UsesPointCoord; /**< shader uses gl_PointCoord */
|
||||
GLboolean UsesFrontFacing; /**< shader used gl_FrontFacing */
|
||||
GLboolean UsesFogFragCoord; /**< shader used gl_FogFragCoord */
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3975,13 +3975,6 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target,
|
|||
if (program->FogOption)
|
||||
program->Base.InputsRead |= FRAG_BIT_FOGC;
|
||||
|
||||
/* XXX: assume that ARB fragment programs don't have access to the
|
||||
* FrontFacing and PointCoord values stuffed into the fog
|
||||
* coordinate in GLSL shaders.
|
||||
*/
|
||||
if (program->Base.InputsRead & FRAG_BIT_FOGC)
|
||||
program->UsesFogFragCoord = GL_TRUE;
|
||||
|
||||
if (program->Base.Instructions)
|
||||
_mesa_free(program->Base.Instructions);
|
||||
program->Base.Instructions = ap.Base.Instructions;
|
||||
|
|
|
|||
|
|
@ -396,7 +396,6 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog)
|
|||
fprog->Base.Instructions = newInst;
|
||||
fprog->Base.NumInstructions = inst - newInst;
|
||||
fprog->Base.InputsRead |= FRAG_BIT_FOGC;
|
||||
fprog->UsesFogFragCoord = GL_TRUE;
|
||||
/* XXX do this? fprog->FogOption = GL_NONE; */
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -752,8 +752,9 @@ static const struct input_info fragInputs[] = {
|
|||
{ "gl_TexCoord", FRAG_ATTRIB_TEX0, GL_FLOAT_VEC4, SWIZZLE_NOOP },
|
||||
/* note: we're packing several quantities into the fogcoord vector */
|
||||
{ "gl_FogFragCoord", FRAG_ATTRIB_FOGC, GL_FLOAT, SWIZZLE_XXXX },
|
||||
{ "gl_FrontFacing", FRAG_ATTRIB_FOGC, GL_BOOL, SWIZZLE_YYYY }, /*XXX*/
|
||||
{ "gl_PointCoord", FRAG_ATTRIB_FOGC, GL_FLOAT_VEC2, SWIZZLE_ZWWW },
|
||||
{ "gl_FogFragCoord", FRAG_ATTRIB_FOGC, GL_FLOAT, SWIZZLE_XXXX },
|
||||
{ "gl_FrontFacing", FRAG_ATTRIB_FACE, GL_FLOAT, SWIZZLE_XXXX },
|
||||
{ "gl_PointCoord", FRAG_ATTRIB_PNTC, GL_FLOAT_VEC2, SWIZZLE_XYZW },
|
||||
{ NULL, 0, SWIZZLE_NOOP }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -504,20 +504,6 @@ _slang_update_inputs_outputs(struct gl_program *prog)
|
|||
for (j = 0; j < numSrc; j++) {
|
||||
if (inst->SrcReg[j].File == PROGRAM_INPUT) {
|
||||
prog->InputsRead |= 1 << inst->SrcReg[j].Index;
|
||||
if (prog->Target == GL_FRAGMENT_PROGRAM_ARB &&
|
||||
inst->SrcReg[j].Index == FRAG_ATTRIB_FOGC) {
|
||||
/* The fragment shader FOGC input is used for fog,
|
||||
* front-facing and sprite/point coord.
|
||||
*/
|
||||
struct gl_fragment_program *fp = fragment_program(prog);
|
||||
const GLint swz = GET_SWZ(inst->SrcReg[j].Swizzle, 0);
|
||||
if (swz == SWIZZLE_X)
|
||||
fp->UsesFogFragCoord = GL_TRUE;
|
||||
else if (swz == SWIZZLE_Y)
|
||||
fp->UsesFrontFacing = GL_TRUE;
|
||||
else if (swz == SWIZZLE_Z || swz == SWIZZLE_W)
|
||||
fp->UsesPointCoord = GL_TRUE;
|
||||
}
|
||||
}
|
||||
else if (inst->SrcReg[j].File == PROGRAM_ADDRESS) {
|
||||
maxAddrReg = MAX2(maxAddrReg, (GLuint) (inst->SrcReg[j].Index + 1));
|
||||
|
|
|
|||
|
|
@ -139,23 +139,6 @@ find_translated_vp(struct st_context *st,
|
|||
if (fragInputsRead & (1 << inAttr)) {
|
||||
stfp->input_to_slot[inAttr] = numIn;
|
||||
numIn++;
|
||||
if (((1 << inAttr) & FRAG_BIT_FOGC)) {
|
||||
/* leave placeholders for the
|
||||
* extra registers we extract from fog */
|
||||
if (stfp->Base.UsesFrontFacing) {
|
||||
if (!stfp->Base.UsesFogFragCoord)
|
||||
--stfp->input_to_slot[inAttr];
|
||||
else
|
||||
++numIn;
|
||||
}
|
||||
if (stfp->Base.UsesPointCoord) {
|
||||
if (!stfp->Base.UsesFrontFacing &&
|
||||
!stfp->Base.UsesFogFragCoord)
|
||||
stfp->input_to_slot[inAttr] -= 2;
|
||||
else
|
||||
++numIn;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
stfp->input_to_slot[inAttr] = UNUSED;
|
||||
|
|
|
|||
|
|
@ -112,27 +112,6 @@ map_register_file_index(
|
|||
{
|
||||
switch( file ) {
|
||||
case TGSI_FILE_INPUT:
|
||||
if (procType == TGSI_PROCESSOR_FRAGMENT &&
|
||||
index == FRAG_ATTRIB_FOGC) {
|
||||
if (GET_SWZ(*swizzle, 0) == SWIZZLE_X) {
|
||||
/* do nothing we're, ok */
|
||||
} else if (GET_SWZ(*swizzle, 0) == SWIZZLE_Y) {
|
||||
/* replace the swizzle with xxxx */
|
||||
*swizzle = MAKE_SWIZZLE4(SWIZZLE_X,
|
||||
SWIZZLE_X,
|
||||
SWIZZLE_X,
|
||||
SWIZZLE_X);
|
||||
/* register after fog */
|
||||
return inputMapping[index] + 1;
|
||||
} else {
|
||||
*swizzle = MAKE_SWIZZLE4(SWIZZLE_Z,
|
||||
SWIZZLE_W,
|
||||
SWIZZLE_Z,
|
||||
SWIZZLE_W);
|
||||
/* register after frontface */
|
||||
return inputMapping[index] + 2;
|
||||
}
|
||||
}
|
||||
/* inputs are mapped according to the user-defined map */
|
||||
return inputMapping[index];
|
||||
|
||||
|
|
|
|||
|
|
@ -458,34 +458,20 @@ st_translate_fragment_program(struct st_context *st,
|
|||
stfp->input_semantic_index[slot] = 1;
|
||||
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
|
||||
break;
|
||||
case FRAG_ATTRIB_FOGC: {
|
||||
int extra_decls = 0;
|
||||
if (stfp->Base.UsesFogFragCoord) {
|
||||
stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
|
||||
stfp->input_semantic_index[slot] = 0;
|
||||
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
|
||||
input_flags[slot] = stfp->Base.Base.InputFlags[attr];
|
||||
++extra_decls;
|
||||
}
|
||||
if (stfp->Base.UsesFrontFacing) {
|
||||
GLint idx = slot + extra_decls;
|
||||
stfp->input_semantic_name[idx] = TGSI_SEMANTIC_FACE;
|
||||
stfp->input_semantic_index[idx] = 0;
|
||||
interpMode[idx] = TGSI_INTERPOLATE_CONSTANT;
|
||||
input_flags[idx] = stfp->Base.Base.InputFlags[attr];
|
||||
++extra_decls;
|
||||
}
|
||||
if (stfp->Base.UsesPointCoord) {
|
||||
GLint idx = slot + extra_decls;
|
||||
stfp->input_semantic_name[idx] = TGSI_SEMANTIC_GENERIC;
|
||||
stfp->input_semantic_index[idx] = num_generic++;
|
||||
interpMode[idx] = TGSI_INTERPOLATE_PERSPECTIVE;
|
||||
input_flags[idx] = stfp->Base.Base.InputFlags[attr];
|
||||
++extra_decls;
|
||||
}
|
||||
fs_num_inputs += extra_decls - 1;
|
||||
continue;
|
||||
}
|
||||
case FRAG_ATTRIB_FOGC:
|
||||
stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
|
||||
stfp->input_semantic_index[slot] = 0;
|
||||
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
|
||||
break;
|
||||
case FRAG_ATTRIB_FACE:
|
||||
stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FACE;
|
||||
stfp->input_semantic_index[slot] = num_generic++;
|
||||
interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
|
||||
break;
|
||||
case FRAG_ATTRIB_PNTC:
|
||||
stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||
stfp->input_semantic_index[slot] = num_generic++;
|
||||
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
|
||||
break;
|
||||
case FRAG_ATTRIB_TEX0:
|
||||
case FRAG_ATTRIB_TEX1:
|
||||
|
|
|
|||
|
|
@ -157,9 +157,8 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine,
|
|||
|
||||
/* if running a GLSL program (not ARB_fragment_program) */
|
||||
if (ctx->Shader.CurrentProgram) {
|
||||
/* Store front/back facing value in register FOGC.Y */
|
||||
machine->Attribs[FRAG_ATTRIB_FOGC][col][1] = 1.0 - span->facing;
|
||||
/* Note FOGC.ZW is gl_PointCoord if drawing a sprite */
|
||||
/* Store front/back facing value */
|
||||
machine->Attribs[FRAG_ATTRIB_FACE][col][0] = 1.0 - span->facing;
|
||||
}
|
||||
|
||||
machine->CurElement = col;
|
||||
|
|
|
|||
|
|
@ -139,9 +139,10 @@ sprite_point(GLcontext *ctx, const SWvertex *vert)
|
|||
}
|
||||
|
||||
ATTRIB_LOOP_BEGIN
|
||||
if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0) {
|
||||
if (attr >= FRAG_ATTRIB_TEX0 && attr <= FRAG_ATTRIB_TEX7) {
|
||||
/* a texcoord attribute */
|
||||
const GLuint u = attr - FRAG_ATTRIB_TEX0;
|
||||
/* a texcoord */
|
||||
ASSERT(u < Elements(ctx->Point.CoordReplace));
|
||||
if (ctx->Point.CoordReplace[u]) {
|
||||
tCoords[numTcoords++] = attr;
|
||||
|
||||
|
|
@ -170,15 +171,15 @@ sprite_point(GLcontext *ctx, const SWvertex *vert)
|
|||
continue;
|
||||
}
|
||||
}
|
||||
else if (attr == FRAG_ATTRIB_FOGC) {
|
||||
/* GLSL gl_PointCoord is stored in fog.zw */
|
||||
span.attrStart[FRAG_ATTRIB_FOGC][2] = 0.0;
|
||||
span.attrStart[FRAG_ATTRIB_FOGC][3] = 0.0; /* t0 set below */
|
||||
span.attrStepX[FRAG_ATTRIB_FOGC][2] = dsdx;
|
||||
span.attrStepX[FRAG_ATTRIB_FOGC][3] = 0.0;
|
||||
span.attrStepY[FRAG_ATTRIB_FOGC][2] = 0.0;
|
||||
span.attrStepY[FRAG_ATTRIB_FOGC][3] = dtdy;
|
||||
tCoords[numTcoords++] = FRAG_ATTRIB_FOGC;
|
||||
else if (attr == FRAG_ATTRIB_PNTC) {
|
||||
/* GLSL gl_PointCoord.xy (.zw undefined) */
|
||||
span.attrStart[FRAG_ATTRIB_PNTC][0] = 0.0;
|
||||
span.attrStart[FRAG_ATTRIB_PNTC][1] = 0.0; /* t0 set below */
|
||||
span.attrStepX[FRAG_ATTRIB_PNTC][0] = dsdx;
|
||||
span.attrStepX[FRAG_ATTRIB_PNTC][1] = 0.0;
|
||||
span.attrStepY[FRAG_ATTRIB_PNTC][0] = 0.0;
|
||||
span.attrStepY[FRAG_ATTRIB_PNTC][1] = dtdy;
|
||||
tCoords[numTcoords++] = FRAG_ATTRIB_PNTC;
|
||||
continue;
|
||||
}
|
||||
/* use vertex's texcoord/attrib */
|
||||
|
|
@ -221,10 +222,7 @@ sprite_point(GLcontext *ctx, const SWvertex *vert)
|
|||
GLuint i;
|
||||
/* setup texcoord T for this row */
|
||||
for (i = 0; i < numTcoords; i++) {
|
||||
if (tCoords[i] == FRAG_ATTRIB_FOGC)
|
||||
span.attrStart[FRAG_ATTRIB_FOGC][3] = tcoord;
|
||||
else
|
||||
span.attrStart[tCoords[i]][1] = tcoord;
|
||||
span.attrStart[tCoords[i]][1] = tcoord;
|
||||
}
|
||||
|
||||
/* these might get changed by span clipping */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue