tgsi: add properties for fragment coord conventions (v3)
Changes in v3: - Documented the new properties - Added comments for property values - Rebased to current master Changes in v2: - Caps are added in a separate, subsequent patch This adds two TGSI fragment program properties that indicate the fragment coord conventions. The properties behave as described in the extension spec for GL_ARB_fragment_coord_conventions, but the default origin in upper left instead of lower left as in OpenGL. The syntax is: PROPERTY FS_COORD_ORIGIN [UPPER_LEFT|LOWER_LEFT] PROPERTY FS_COORD_PIXEL_CENTER [HALF_INTEGER|INTEGER] The names have been chosen for consistency with the GS properties and the OpenGL extension spec. The defaults are of course the previously assumed conventions: UPPER_LEFT and HALF_INTEGER.
This commit is contained in:
@@ -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;
|
||||
|
@@ -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!" );
|
||||
|
@@ -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))) {
|
||||
|
@@ -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:
|
||||
|
@@ -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.
|
||||
|
@@ -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;
|
||||
};
|
||||
|
Reference in New Issue
Block a user