mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-02 04:30:25 +01:00
mesa, st/mesa: fix gl_FragCoord with FBOs in Gallium
gl_FragCoord.y needs to be flipped upside down if a FBO is bound.
This fixes:
- piglit/fbo-fragcoord
- https://bugs.freedesktop.org/show_bug.cgi?id=29420
Here I add a new program state STATE_FB_WPOS_Y_TRANSFORM, which is set based
on whether a FBO is bound. The state contains a pair of transformations.
It can be either (XY=identity, ZW=transformY) if a FBO is bound,
or (XY=transformY, ZW=identity) otherwise, where identity = (1, 0),
transformY = (-1, height-1).
A classic driver (or st/mesa) may, based on some other state, choose whether
to use XY or ZW, thus negate the conditional "if (is a FBO bound) ...".
The reason for this is that a Gallium driver is allowed to only support WPOS
relative to either the lower left or the upper left corner, so we must flip
the Y axis accordingly again. (the "invert" parameter in emit_wpos_inversion)
NOTE: This is a candidate for the 7.9 branch.
Signed-off-by: Marek Olšák <maraeo@gmail.com>
Signed-off-by: Brian Paul <brianp@vmware.com>
(cherry picked from commit d531f9c2f5)
This commit is contained in:
parent
564a6a15fe
commit
2cb8522523
3 changed files with 51 additions and 15 deletions
|
|
@ -584,6 +584,24 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
|
|||
value[3] = 0.0F;
|
||||
return;
|
||||
|
||||
case STATE_FB_WPOS_Y_TRANSFORM:
|
||||
/* A driver may negate this conditional by using ZW swizzle
|
||||
* instead of XY (based on e.g. some other state). */
|
||||
if (ctx->DrawBuffer->Name != 0) {
|
||||
/* Identity (XY) followed by flipping Y upside down (ZW). */
|
||||
value[0] = 1.0F;
|
||||
value[1] = 0.0F;
|
||||
value[2] = -1.0F;
|
||||
value[3] = (GLfloat) (ctx->DrawBuffer->Height - 1);
|
||||
} else {
|
||||
/* Flipping Y upside down (XY) followed by identity (ZW). */
|
||||
value[0] = -1.0F;
|
||||
value[1] = (GLfloat) (ctx->DrawBuffer->Height - 1);
|
||||
value[2] = 1.0F;
|
||||
value[3] = 0.0F;
|
||||
}
|
||||
return;
|
||||
|
||||
case STATE_ROT_MATRIX_0:
|
||||
{
|
||||
const int unit = (int) state[2];
|
||||
|
|
@ -711,6 +729,7 @@ _mesa_program_state_flags(const gl_state_index state[STATE_LENGTH])
|
|||
return _NEW_PIXEL;
|
||||
|
||||
case STATE_FB_SIZE:
|
||||
case STATE_FB_WPOS_Y_TRANSFORM:
|
||||
return _NEW_BUFFERS;
|
||||
|
||||
default:
|
||||
|
|
@ -925,6 +944,9 @@ append_token(char *dst, gl_state_index k)
|
|||
case STATE_FB_SIZE:
|
||||
append(dst, "FbSize");
|
||||
break;
|
||||
case STATE_FB_WPOS_Y_TRANSFORM:
|
||||
append(dst, "FbWposYTransform");
|
||||
break;
|
||||
case STATE_ROT_MATRIX_0:
|
||||
append(dst, "rotMatrixRow0");
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@ typedef enum gl_state_index_ {
|
|||
STATE_PCM_BIAS, /**< Post color matrix RGBA bias */
|
||||
STATE_SHADOW_AMBIENT, /**< ARB_shadow_ambient fail value; token[2] is texture unit index */
|
||||
STATE_FB_SIZE, /**< (width-1, height-1, 0, 0) */
|
||||
STATE_FB_WPOS_Y_TRANSFORM, /**< (1, 0, -1, height-1) if a FBO is bound, (-1, height-1, 1, 0) otherwise */
|
||||
STATE_ROT_MATRIX_0, /**< ATI_envmap_bumpmap, rot matrix row 0 */
|
||||
STATE_ROT_MATRIX_1, /**< ATI_envmap_bumpmap, rot matrix row 1 */
|
||||
STATE_INTERNAL_DRIVER /* first available state index for drivers (must be last) */
|
||||
|
|
|
|||
|
|
@ -760,10 +760,13 @@ emit_adjusted_wpos( struct st_translate *t,
|
|||
|
||||
/**
|
||||
* Emit the TGSI instructions for inverting the WPOS y coordinate.
|
||||
* This code is unavoidable because it also depends on whether
|
||||
* a FBO is bound (STATE_FB_WPOS_Y_TRANSFORM).
|
||||
*/
|
||||
static void
|
||||
emit_inverted_wpos( struct st_translate *t,
|
||||
const struct gl_program *program )
|
||||
emit_wpos_inversion( struct st_translate *t,
|
||||
const struct gl_program *program,
|
||||
boolean invert)
|
||||
{
|
||||
struct ureg_program *ureg = t->ureg;
|
||||
|
||||
|
|
@ -771,17 +774,17 @@ emit_inverted_wpos( struct st_translate *t,
|
|||
* Need to replace instances of INPUT[WPOS] with temp T
|
||||
* where T = INPUT[WPOS] by y is inverted.
|
||||
*/
|
||||
static const gl_state_index winSizeState[STATE_LENGTH]
|
||||
= { STATE_INTERNAL, STATE_FB_SIZE, 0, 0, 0 };
|
||||
static const gl_state_index wposTransformState[STATE_LENGTH]
|
||||
= { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM, 0, 0, 0 };
|
||||
|
||||
/* XXX: note we are modifying the incoming shader here! Need to
|
||||
* do this before emitting the constant decls below, or this
|
||||
* will be missed:
|
||||
*/
|
||||
unsigned winHeightConst = _mesa_add_state_reference(program->Parameters,
|
||||
winSizeState);
|
||||
unsigned wposTransConst = _mesa_add_state_reference(program->Parameters,
|
||||
wposTransformState);
|
||||
|
||||
struct ureg_src winsize = ureg_DECL_constant( ureg, winHeightConst );
|
||||
struct ureg_src wpostrans = ureg_DECL_constant( ureg, wposTransConst );
|
||||
struct ureg_dst wpos_temp;
|
||||
struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]];
|
||||
|
||||
|
|
@ -794,12 +797,23 @@ emit_inverted_wpos( struct st_translate *t,
|
|||
ureg_MOV( ureg, wpos_temp, wpos_input );
|
||||
}
|
||||
|
||||
/* SUB wpos_temp.y, winsize_const, wpos_input
|
||||
*/
|
||||
ureg_SUB( ureg,
|
||||
ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ),
|
||||
winsize,
|
||||
wpos_input);
|
||||
if (invert) {
|
||||
/* MAD wpos_temp.y, wpos_input, wpostrans.xxxx, wpostrans.yyyy
|
||||
*/
|
||||
ureg_MAD( ureg,
|
||||
ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ),
|
||||
wpos_input,
|
||||
ureg_scalar(wpostrans, 0),
|
||||
ureg_scalar(wpostrans, 1));
|
||||
} else {
|
||||
/* MAD wpos_temp.y, wpos_input, wpostrans.zzzz, wpostrans.wwww
|
||||
*/
|
||||
ureg_MAD( ureg,
|
||||
ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ),
|
||||
wpos_input,
|
||||
ureg_scalar(wpostrans, 2),
|
||||
ureg_scalar(wpostrans, 3));
|
||||
}
|
||||
|
||||
/* Use wpos_temp as position input from here on:
|
||||
*/
|
||||
|
|
@ -861,8 +875,7 @@ emit_wpos(struct st_context *st,
|
|||
|
||||
/* we invert after adjustment so that we avoid the MOV to temporary,
|
||||
* and reuse the adjustment ADD instead */
|
||||
if (invert)
|
||||
emit_inverted_wpos(t, program);
|
||||
emit_wpos_inversion(t, program, invert);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue