mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-05 06:50:10 +01:00
mesa/st: Backport WPOS adjustment fixes from st_mesa_to_tgsi.c to st_glsl_to_tgsi.cpp.
This is a trivial verbatim copy of the code from Christoph Bumiller's commit
f986a6560f.
Fixes fdo 39939 and 39942.
This commit is contained in:
parent
60f67cd1f1
commit
35ffe94a34
1 changed files with 83 additions and 51 deletions
|
|
@ -4322,37 +4322,15 @@ compile_tgsi_instruction(struct st_translate *t,
|
|||
}
|
||||
|
||||
/**
|
||||
* Emit the TGSI instructions to adjust the WPOS pixel center convention
|
||||
* Basically, add (adjX, adjY) to the fragment position.
|
||||
*/
|
||||
static void
|
||||
emit_adjusted_wpos(struct st_translate *t,
|
||||
const struct gl_program *program,
|
||||
float adjX, float adjY)
|
||||
{
|
||||
struct ureg_program *ureg = t->ureg;
|
||||
struct ureg_dst wpos_temp = ureg_DECL_temporary(ureg);
|
||||
struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]];
|
||||
|
||||
/* Note that we bias X and Y and pass Z and W through unchanged.
|
||||
* The shader might also use gl_FragCoord.w and .z.
|
||||
*/
|
||||
ureg_ADD(ureg, wpos_temp, wpos_input,
|
||||
ureg_imm4f(ureg, adjX, adjY, 0.0f, 0.0f));
|
||||
|
||||
t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Emit the TGSI instructions for inverting the WPOS y coordinate.
|
||||
* Emit the TGSI instructions for inverting and adjusting WPOS.
|
||||
* This code is unavoidable because it also depends on whether
|
||||
* a FBO is bound (STATE_FB_WPOS_Y_TRANSFORM).
|
||||
*/
|
||||
static void
|
||||
emit_wpos_inversion(struct st_translate *t,
|
||||
const struct gl_program *program,
|
||||
bool invert)
|
||||
emit_wpos_adjustment( struct st_translate *t,
|
||||
const struct gl_program *program,
|
||||
boolean invert,
|
||||
GLfloat adjX, GLfloat adjY[2])
|
||||
{
|
||||
struct ureg_program *ureg = t->ureg;
|
||||
|
||||
|
|
@ -4371,35 +4349,55 @@ emit_wpos_inversion(struct st_translate *t,
|
|||
unsigned wposTransConst = _mesa_add_state_reference(program->Parameters,
|
||||
wposTransformState);
|
||||
|
||||
struct ureg_src wpostrans = ureg_DECL_constant(ureg, wposTransConst);
|
||||
struct ureg_dst wpos_temp;
|
||||
struct ureg_src wpostrans = ureg_DECL_constant( ureg, wposTransConst );
|
||||
struct ureg_dst wpos_temp = ureg_DECL_temporary( ureg );
|
||||
struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]];
|
||||
|
||||
/* MOV wpos_temp, input[wpos]
|
||||
*/
|
||||
if (wpos_input.File == TGSI_FILE_TEMPORARY)
|
||||
wpos_temp = ureg_dst(wpos_input);
|
||||
else {
|
||||
wpos_temp = ureg_DECL_temporary(ureg);
|
||||
ureg_MOV(ureg, wpos_temp, wpos_input);
|
||||
/* First, apply the coordinate shift: */
|
||||
if (adjX || adjY[0] || adjY[1]) {
|
||||
if (adjY[0] != adjY[1]) {
|
||||
/* Adjust the y coordinate by adjY[1] or adjY[0] respectively
|
||||
* depending on whether inversion is actually going to be applied
|
||||
* or not, which is determined by testing against the inversion
|
||||
* state variable used below, which will be either +1 or -1.
|
||||
*/
|
||||
struct ureg_dst adj_temp = ureg_DECL_temporary(ureg);
|
||||
|
||||
ureg_CMP(ureg, adj_temp,
|
||||
ureg_scalar(wpostrans, invert ? 2 : 0),
|
||||
ureg_imm4f(ureg, adjX, adjY[0], 0.0f, 0.0f),
|
||||
ureg_imm4f(ureg, adjX, adjY[1], 0.0f, 0.0f));
|
||||
ureg_ADD(ureg, wpos_temp, wpos_input, ureg_src(adj_temp));
|
||||
} else {
|
||||
ureg_ADD(ureg, wpos_temp, wpos_input,
|
||||
ureg_imm4f(ureg, adjX, adjY[0], 0.0f, 0.0f));
|
||||
}
|
||||
wpos_input = ureg_src(wpos_temp);
|
||||
} else {
|
||||
/* MOV wpos_temp, input[wpos]
|
||||
*/
|
||||
ureg_MOV( ureg, wpos_temp, wpos_input );
|
||||
}
|
||||
|
||||
/* Now the conditional y flip: STATE_FB_WPOS_Y_TRANSFORM.xy/zw will be
|
||||
* inversion/identity, or the other way around if we're drawing to an FBO.
|
||||
*/
|
||||
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));
|
||||
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));
|
||||
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:
|
||||
|
|
@ -4420,8 +4418,37 @@ emit_wpos(struct st_context *st,
|
|||
const struct gl_fragment_program *fp =
|
||||
(const struct gl_fragment_program *) program;
|
||||
struct pipe_screen *pscreen = st->pipe->screen;
|
||||
GLfloat adjX = 0.0f;
|
||||
GLfloat adjY[2] = { 0.0f, 0.0f };
|
||||
boolean invert = FALSE;
|
||||
|
||||
/* Query the pixel center conventions supported by the pipe driver and set
|
||||
* adjX, adjY to help out if it cannot handle the requested one internally.
|
||||
*
|
||||
* The bias of the y-coordinate depends on whether y-inversion takes place
|
||||
* (adjY[1]) or not (adjY[0]), which is in turn dependent on whether we are
|
||||
* drawing to an FBO (causes additional inversion), and whether the the pipe
|
||||
* driver origin and the requested origin differ (the latter condition is
|
||||
* stored in the 'invert' variable).
|
||||
*
|
||||
* For height = 100 (i = integer, h = half-integer, l = lower, u = upper):
|
||||
*
|
||||
* center shift only:
|
||||
* i -> h: +0.5
|
||||
* h -> i: -0.5
|
||||
*
|
||||
* inversion only:
|
||||
* l,i -> u,i: ( 0.0 + 1.0) * -1 + 100 = 99
|
||||
* l,h -> u,h: ( 0.5 + 0.0) * -1 + 100 = 99.5
|
||||
* u,i -> l,i: (99.0 + 1.0) * -1 + 100 = 0
|
||||
* u,h -> l,h: (99.5 + 0.0) * -1 + 100 = 0.5
|
||||
*
|
||||
* inversion and center shift:
|
||||
* l,i -> u,h: ( 0.0 + 0.5) * -1 + 100 = 99.5
|
||||
* l,h -> u,i: ( 0.5 + 0.5) * -1 + 100 = 99
|
||||
* u,i -> l,h: (99.0 + 0.5) * -1 + 100 = 0.5
|
||||
* u,h -> l,i: (99.5 + 0.5) * -1 + 100 = 0
|
||||
*/
|
||||
if (fp->OriginUpperLeft) {
|
||||
/* Fragment shader wants origin in upper-left */
|
||||
if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) {
|
||||
|
|
@ -4449,12 +4476,17 @@ emit_wpos(struct st_context *st,
|
|||
|
||||
if (fp->PixelCenterInteger) {
|
||||
/* Fragment shader wants pixel center integer */
|
||||
if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER))
|
||||
if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) {
|
||||
/* the driver supports pixel center integer */
|
||||
adjY[1] = 1.0f;
|
||||
ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER);
|
||||
else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER))
|
||||
}
|
||||
else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) {
|
||||
/* the driver supports pixel center half integer, need to bias X,Y */
|
||||
emit_adjusted_wpos(t, program, 0.5f, invert ? 0.5f : -0.5f);
|
||||
adjX = -0.5f;
|
||||
adjY[0] = -0.5f;
|
||||
adjY[1] = 0.5f;
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
|
|
@ -4465,8 +4497,8 @@ emit_wpos(struct st_context *st,
|
|||
}
|
||||
else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) {
|
||||
/* the driver supports pixel center integer, need to bias X,Y */
|
||||
adjX = adjY[0] = adjY[1] = 0.5f;
|
||||
ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER);
|
||||
emit_adjusted_wpos(t, program, 0.5f, invert ? -0.5f : 0.5f);
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
|
|
@ -4474,7 +4506,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 */
|
||||
emit_wpos_inversion(t, program, invert);
|
||||
emit_wpos_adjustment(t, program, invert, adjX, adjY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue