Merge commit 'lb2/arb_fragment_coord_conventions'

This commit is contained in:
Keith Whitwell 2010-01-29 20:24:26 +00:00
commit 3fc73c389a
27 changed files with 357 additions and 14 deletions

View File

@ -159,7 +159,9 @@ static const char *property_names[] =
{
"GS_INPUT_PRIMITIVE",
"GS_OUTPUT_PRIMITIVE",
"GS_MAX_OUTPUT_VERTICES"
"GS_MAX_OUTPUT_VERTICES",
"FS_COORD_ORIGIN",
"FS_COORD_PIXEL_CENTER"
};
static const char *primitive_names[] =
@ -176,6 +178,18 @@ static const char *primitive_names[] =
"POLYGON"
};
static const char *fs_coord_origin_names[] =
{
"UPPER_LEFT",
"LOWER_LEFT"
};
static const char *fs_coord_pixel_center_names[] =
{
"HALF_INTEGER",
"INTEGER"
};
static void
_dump_register_dst(
@ -366,6 +380,12 @@ iter_property(
case TGSI_PROPERTY_GS_OUTPUT_PRIM:
ENM(prop->u[i].Data, primitive_names);
break;
case TGSI_PROPERTY_FS_COORD_ORIGIN:
ENM(prop->u[i].Data, fs_coord_origin_names);
break;
case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER:
ENM(prop->u[i].Data, fs_coord_pixel_center_names);
break;
default:
SID( prop->u[i].Data );
break;

View File

@ -1129,7 +1129,9 @@ static const char *property_names[] =
{
"GS_INPUT_PRIMITIVE",
"GS_OUTPUT_PRIMITIVE",
"GS_MAX_OUTPUT_VERTICES"
"GS_MAX_OUTPUT_VERTICES",
"FS_COORD_ORIGIN",
"FS_COORD_PIXEL_CENTER"
};
static const char *primitive_names[] =
@ -1146,6 +1148,19 @@ static const char *primitive_names[] =
"POLYGON"
};
static const char *fs_coord_origin_names[] =
{
"UPPER_LEFT",
"LOWER_LEFT"
};
static const char *fs_coord_pixel_center_names[] =
{
"HALF_INTEGER",
"INTEGER"
};
static boolean
parse_primitive( const char **pcur, uint *primitive )
{
@ -1163,6 +1178,40 @@ parse_primitive( const char **pcur, uint *primitive )
return FALSE;
}
static boolean
parse_fs_coord_origin( const char **pcur, uint *fs_coord_origin )
{
uint i;
for (i = 0; i < sizeof(fs_coord_origin_names) / sizeof(fs_coord_origin_names[0]); i++) {
const char *cur = *pcur;
if (str_match_no_case( &cur, fs_coord_origin_names[i])) {
*fs_coord_origin = i;
*pcur = cur;
return TRUE;
}
}
return FALSE;
}
static boolean
parse_fs_coord_pixel_center( const char **pcur, uint *fs_coord_pixel_center )
{
uint i;
for (i = 0; i < sizeof(fs_coord_pixel_center_names) / sizeof(fs_coord_pixel_center_names[0]); i++) {
const char *cur = *pcur;
if (str_match_no_case( &cur, fs_coord_pixel_center_names[i])) {
*fs_coord_pixel_center = i;
*pcur = cur;
return TRUE;
}
}
return FALSE;
}
static boolean parse_property( struct translate_ctx *ctx )
{
@ -1204,6 +1253,18 @@ static boolean parse_property( struct translate_ctx *ctx )
ctx->implied_array_size = u_vertices_per_prim(values[0]);
}
break;
case TGSI_PROPERTY_FS_COORD_ORIGIN:
if (!parse_fs_coord_origin(&ctx->cur, &values[0] )) {
report_error( ctx, "Unknown coord origin as property: must be UPPER_LEFT or LOWER_LEFT!" );
return FALSE;
}
break;
case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER:
if (!parse_fs_coord_pixel_center(&ctx->cur, &values[0] )) {
report_error( ctx, "Unknown coord pixel center as property: must be HALF_INTEGER or INTEGER!" );
return FALSE;
}
break;
default:
if (!parse_uint(&ctx->cur, &values[0] )) {
report_error( ctx, "Expected unsigned integer as property!" );

View File

@ -142,6 +142,8 @@ struct ureg_program
unsigned property_gs_input_prim;
unsigned property_gs_output_prim;
unsigned property_gs_max_vertices;
unsigned char property_fs_coord_origin; /* = TGSI_FS_COORD_ORIGIN_* */
unsigned char property_fs_coord_pixel_center; /* = TGSI_FS_COORD_PIXEL_CENTER_* */
unsigned nr_addrs;
unsigned nr_preds;
@ -265,6 +267,20 @@ ureg_property_gs_max_vertices(struct ureg_program *ureg,
ureg->property_gs_max_vertices = max_vertices;
}
void
ureg_property_fs_coord_origin(struct ureg_program *ureg,
unsigned fs_coord_origin)
{
ureg->property_fs_coord_origin = fs_coord_origin;
}
void
ureg_property_fs_coord_pixel_center(struct ureg_program *ureg,
unsigned fs_coord_pixel_center)
{
ureg->property_fs_coord_pixel_center = fs_coord_pixel_center;
}
struct ureg_src
@ -1202,6 +1218,22 @@ static void emit_decls( struct ureg_program *ureg )
ureg->property_gs_max_vertices);
}
if (ureg->property_fs_coord_origin) {
assert(ureg->processor == TGSI_PROCESSOR_FRAGMENT);
emit_property(ureg,
TGSI_PROPERTY_FS_COORD_ORIGIN,
ureg->property_fs_coord_origin);
}
if (ureg->property_fs_coord_pixel_center) {
assert(ureg->processor == TGSI_PROCESSOR_FRAGMENT);
emit_property(ureg,
TGSI_PROPERTY_FS_COORD_PIXEL_CENTER,
ureg->property_fs_coord_pixel_center);
}
if (ureg->processor == TGSI_PROCESSOR_VERTEX) {
for (i = 0; i < UREG_MAX_INPUT; i++) {
if (ureg->vs_inputs[i/32] & (1 << (i%32))) {

View File

@ -136,6 +136,13 @@ void
ureg_property_gs_max_vertices(struct ureg_program *ureg,
unsigned max_vertices);
void
ureg_property_fs_coord_origin(struct ureg_program *ureg,
unsigned fs_coord_origin);
void
ureg_property_fs_coord_pixel_center(struct ureg_program *ureg,
unsigned fs_coord_pixel_center);
/***********************************************************************
* Build shader declarations:

View File

@ -57,6 +57,14 @@ The integer capabilities:
only permit binding one constant buffer per shader, and the shaders will
not permit two-dimensional access to constants.
* ``MAX_CONST_BUFFER_SIZE``: Maximum byte size of a single constant buffer.
* ``PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT``: Whether the TGSI property
FS_COORD_ORIGIN with value UPPER_LEFT is supported
* ``PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT``: Whether the TGSI property
FS_COORD_ORIGIN with value LOWER_LEFT is supported
* ``PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER``: Whether the TGSI
property FS_COORD_PIXEL_CENTER with value HALF_INTEGER is supported
* ``PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER``: Whether the TGSI
property FS_COORD_PIXEL_CENTER with value INTEGER is supported
The floating-point capabilities:

View File

@ -1319,9 +1319,8 @@ are the Cartesian coordinates, and ``w`` is the homogenous coordinate and used
for the perspective divide, if enabled.
As a vertex shader output, position should be scaled to the viewport. When
used in fragment shaders, position will ---
XXX --- wait a minute. Should position be in [0,1] for x and y?
used in fragment shaders, position will be in window coordinates. The convention
used depends on the FS_COORD_ORIGIN and FS_COORD_PIXEL_CENTER properties.
XXX additionally, is there a way to configure the perspective divide? it's
accelerated on most chipsets AFAIK...
@ -1400,3 +1399,45 @@ TGSI_SEMANTIC_EDGEFLAG
""""""""""""""""""""""
XXX no clue
Properties
^^^^^^^^^^^^^^^^^^^^^^^^
Properties are general directives that apply to the whole TGSI program.
FS_COORD_ORIGIN
"""""""""""""""
Specifies the fragment shader TGSI_SEMANTIC_POSITION coordinate origin.
The default value is UPPER_LEFT.
If UPPER_LEFT, the position will be (0,0) at the upper left corner and
increase downward and rightward.
If LOWER_LEFT, the position will be (0,0) at the lower left corner and
increase upward and rightward.
OpenGL defaults to LOWER_LEFT, and is configurable with the
GL_ARB_fragment_coord_conventions extension.
DirectX 9/10 use UPPER_LEFT.
FS_COORD_PIXEL_CENTER
"""""""""""""""""""""
Specifies the fragment shader TGSI_SEMANTIC_POSITION pixel center convention.
The default value is HALF_INTEGER.
If HALF_INTEGER, the fractionary part of the position will be 0.5
If INTEGER, the fractionary part of the position will be 0.0
Note that this does not affect the set of fragments generated by
rasterization, which is instead controlled by gl_rasterization_rules in the
rasterizer.
OpenGL defaults to HALF_INTEGER, and is configurable with the
GL_ARB_fragment_coord_conventions extension.
DirectX 9 uses INTEGER.
DirectX 10 uses HALF_INTEGER.

View File

@ -86,6 +86,12 @@ cell_get_param(struct pipe_screen *screen, int param)
return 0; /* XXX to do */
case PIPE_CAP_TGSI_CONT_SUPPORTED:
return 1;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 0;
default:
return 0;
}

View File

@ -117,6 +117,12 @@ i915_get_param(struct pipe_screen *screen, int param)
return 8; /* max 128x128x128 */
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
return 11; /* max 1024x1024 */
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 0;
default:
return 0;
}

View File

@ -175,6 +175,12 @@ brw_get_param(struct pipe_screen *screen, int param)
return 8; /* max 128x128x128 */
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
return 11; /* max 1024x1024 */
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 0;
default:
return 0;
}

View File

@ -114,6 +114,12 @@ llvmpipe_get_param(struct pipe_screen *screen, int param)
return 0;
case PIPE_CAP_INDEP_BLEND_FUNC:
return 0;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 1;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 0;
default:
return 0;
}

View File

@ -49,6 +49,12 @@ nv04_screen_get_param(struct pipe_screen *screen, int param)
return 0;
case PIPE_CAP_INDEP_BLEND_FUNC:
return 0;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 0;
default:
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
return 0;

View File

@ -44,6 +44,12 @@ nv10_screen_get_param(struct pipe_screen *screen, int param)
return 0;
case PIPE_CAP_INDEP_BLEND_FUNC:
return 0;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 0;
default:
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
return 0;

View File

@ -44,6 +44,12 @@ nv20_screen_get_param(struct pipe_screen *screen, int param)
return 0;
case PIPE_CAP_INDEP_BLEND_FUNC:
return 0;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 0;
default:
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
return 0;

View File

@ -71,6 +71,12 @@ nv30_screen_get_param(struct pipe_screen *pscreen, int param)
return 0;
case PIPE_CAP_INDEP_BLEND_FUNC:
return 0;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 0;
default:
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
return 0;

View File

@ -56,6 +56,12 @@ nv40_screen_get_param(struct pipe_screen *pscreen, int param)
return 0;
case PIPE_CAP_INDEP_BLEND_FUNC:
return 0;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 0;
default:
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
return 0;

View File

@ -139,6 +139,12 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param)
return 1;
case PIPE_CAP_INDEP_BLEND_FUNC:
return 0;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 0;
default:
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
return 0;

View File

@ -156,6 +156,12 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)
return 1;
case PIPE_CAP_INDEP_BLEND_FUNC:
return 0;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 0;
default:
debug_printf("r300: Implementation error: Bad param %d\n",
param);

View File

@ -99,6 +99,11 @@ softpipe_get_param(struct pipe_screen *screen, int param)
return 1;
case PIPE_CAP_INDEP_BLEND_FUNC:
return 1;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 1;
default:
return 0;
}

View File

@ -504,21 +504,24 @@ static void tri_persp_coeff( struct setup_context *setup,
/**
* Special coefficient setup for gl_FragCoord.
* X and Y are trivial, though Y has to be inverted for OpenGL.
* X and Y are trivial, though Y may have to be inverted for OpenGL.
* Z and W are copied from posCoef which should have already been computed.
* We could do a bit less work if we'd examine gl_FragCoord's swizzle mask.
*/
static void
setup_fragcoord_coeff(struct setup_context *setup, uint slot)
{
struct sp_fragment_shader* spfs = setup->softpipe->fs;
/*X*/
setup->coef[slot].a0[0] = 0;
setup->coef[slot].a0[0] = spfs->pixel_center_integer ? 0.0 : 0.5;
setup->coef[slot].dadx[0] = 1.0;
setup->coef[slot].dady[0] = 0.0;
/*Y*/
setup->coef[slot].a0[1] = 0.0;
setup->coef[slot].a0[1] =
(spfs->origin_lower_left ? setup->softpipe->framebuffer.height : 0)
+ (spfs->pixel_center_integer ? 0.0 : 0.5);
setup->coef[slot].dadx[1] = 0.0;
setup->coef[slot].dady[1] = 1.0;
setup->coef[slot].dady[1] = spfs->origin_lower_left ? -1.0 : 1.0;
/*Z*/
setup->coef[slot].a0[2] = setup->posCoef.a0[2];
setup->coef[slot].dadx[2] = setup->posCoef.dadx[2];

View File

@ -68,6 +68,9 @@ struct sp_fragment_shader {
struct tgsi_shader_info info;
boolean origin_lower_left; /**< fragment shader uses lower left position origin? */
boolean pixel_center_integer; /**< fragment shader uses integer pixel center? */
void (*prepare)( const struct sp_fragment_shader *shader,
struct tgsi_exec_machine *machine,
struct tgsi_sampler **samplers);

View File

@ -44,6 +44,7 @@ softpipe_create_fs_state(struct pipe_context *pipe,
{
struct softpipe_context *softpipe = softpipe_context(pipe);
struct sp_fragment_shader *state;
unsigned i;
/* debug */
if (softpipe->dump_fs)
@ -60,6 +61,13 @@ softpipe_create_fs_state(struct pipe_context *pipe,
/* get/save the summary info for this shader */
tgsi_scan_shader(templ->tokens, &state->info);
for (i = 0; i < state->info.num_properties; ++i) {
if (state->info.properties[i].name == TGSI_PROPERTY_FS_COORD_ORIGIN)
state->origin_lower_left = state->info.properties[i].data[0];
else if (state->info.properties[i].name == TGSI_PROPERTY_FS_COORD_PIXEL_CENTER)
state->pixel_center_integer = state->info.properties[i].data[0];
}
return state;
}

View File

@ -144,6 +144,13 @@ svga_get_paramf(struct pipe_screen *screen, int param)
case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */
return 1;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 0;
default:
return 0;
}

View File

@ -409,6 +409,10 @@ enum pipe_transfer_usage {
#define PIPE_CAP_MAX_CONST_BUFFER_SIZE 33 /*< In bytes */
#define PIPE_CAP_INDEP_BLEND_ENABLE 34 /*< blend enables and write masks per rendertarget */
#define PIPE_CAP_INDEP_BLEND_FUNC 35 /*< different blend funcs per rendertarget */
#define PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT 36
#define PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT 37
#define PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER 38
#define PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER 39
/**

View File

@ -170,7 +170,9 @@ union tgsi_immediate_data
#define TGSI_PROPERTY_GS_INPUT_PRIM 0
#define TGSI_PROPERTY_GS_OUTPUT_PRIM 1
#define TGSI_PROPERTY_GS_MAX_VERTICES 2
#define TGSI_PROPERTY_COUNT 3
#define TGSI_PROPERTY_FS_COORD_ORIGIN 3
#define TGSI_PROPERTY_FS_COORD_PIXEL_CENTER 4
#define TGSI_PROPERTY_COUNT 5
struct tgsi_property {
unsigned Type : 4; /**< TGSI_TOKEN_TYPE_PROPERTY */
@ -179,6 +181,12 @@ struct tgsi_property {
unsigned Padding : 12;
};
#define TGSI_FS_COORD_ORIGIN_UPPER_LEFT 0
#define TGSI_FS_COORD_ORIGIN_LOWER_LEFT 1
#define TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER 0
#define TGSI_FS_COORD_PIXEL_CENTER_INTEGER 1
struct tgsi_property_data {
unsigned Data;
};

View File

@ -50,7 +50,8 @@ static const struct {
{ OFF, "GL_ARB_depth_clamp", F(ARB_depth_clamp) },
{ ON, "GL_ARB_draw_buffers", F(ARB_draw_buffers) },
{ OFF, "GL_ARB_draw_elements_base_vertex", F(ARB_draw_elements_base_vertex) },
{ OFF, "GL_ARB_fragment_coord_conventions", F(ARB_fragment_coord_conventions) },
/* TODO: uncomment the following line once GLSL layout(...) support is implemented */
/* { OFF, "GL_ARB_fragment_coord_conventions", F(ARB_fragment_coord_conventions) }, */
{ OFF, "GL_ARB_fragment_program", F(ARB_fragment_program) },
{ OFF, "GL_ARB_fragment_program_shadow", F(ARB_fragment_program_shadow) },
{ OFF, "GL_ARB_fragment_shader", F(ARB_fragment_shader) },

View File

@ -147,6 +147,7 @@ void st_init_extensions(struct st_context *st)
* Extensions that are supported by all Gallium drivers:
*/
ctx->Extensions.ARB_copy_buffer = GL_TRUE;
ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE;
ctx->Extensions.ARB_fragment_program = GL_TRUE;
ctx->Extensions.ARB_map_buffer_range = GL_TRUE;
ctx->Extensions.ARB_multisample = GL_TRUE;

View File

@ -34,8 +34,10 @@
#include "pipe/p_compiler.h"
#include "pipe/p_shader_tokens.h"
#include "pipe/p_state.h"
#include "pipe/p_context.h"
#include "tgsi/tgsi_ureg.h"
#include "st_mesa_to_tgsi.h"
#include "st_context.h"
#include "shader/prog_instruction.h"
#include "shader/prog_parameter.h"
#include "shader/prog_print.h"
@ -665,6 +667,22 @@ compile_instruction(
}
}
/**
* Emit the TGSI instructions to adjust the WPOS pixel center convention
*/
static void
emit_adjusted_wpos( struct st_translate *t,
const struct gl_program *program, GLfloat value)
{
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]];
ureg_ADD(ureg, ureg_writemask(wpos_temp, TGSI_WRITEMASK_X | TGSI_WRITEMASK_Y),
wpos_input, ureg_imm1f(ureg, value));
t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp);
}
/**
* Emit the TGSI instructions for inverting the WPOS y coordinate.
@ -690,12 +708,17 @@ emit_inverted_wpos( struct st_translate *t,
winSizeState);
struct ureg_src winsize = ureg_DECL_constant( ureg, winHeightConst );
struct ureg_dst wpos_temp = ureg_DECL_temporary( ureg );
struct ureg_dst wpos_temp;
struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]];
/* MOV wpos_temp, input[wpos]
*/
ureg_MOV( ureg, wpos_temp, wpos_input );
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 );
}
/* SUB wpos_temp.y, winsize_const, wpos_input
*/
@ -801,6 +824,7 @@ st_translate_mesa_program(
* Declare input attributes.
*/
if (procType == TGSI_PROCESSOR_FRAGMENT) {
struct gl_fragment_program* fp = (struct gl_fragment_program*)program;
for (i = 0; i < numInputs; i++) {
t->inputs[i] = ureg_DECL_fs_input(ureg,
inputSemanticName[i],
@ -812,7 +836,51 @@ st_translate_mesa_program(
/* Must do this after setting up t->inputs, and before
* emitting constant references, below:
*/
emit_inverted_wpos( t, program );
struct pipe_screen* pscreen = st_context(ctx)->pipe->screen;
boolean invert = FALSE;
if (fp->OriginUpperLeft) {
if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) {
}
else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) {
ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT);
invert = TRUE;
}
else
assert(0);
}
else {
if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT))
ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT);
else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT))
invert = TRUE;
else
assert(0);
}
if (fp->PixelCenterInteger) {
if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER))
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))
emit_adjusted_wpos(t, program, invert ? 0.5f : -0.5f);
else
assert(0);
}
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_INTEGER)) {
ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER);
emit_adjusted_wpos(t, program, invert ? -0.5f : 0.5f);
}
else
assert(0);
}
/* 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);
}
if (program->InputsRead & FRAG_BIT_FACE) {