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_INPUT_PRIMITIVE",
|
||||||
"GS_OUTPUT_PRIMITIVE",
|
"GS_OUTPUT_PRIMITIVE",
|
||||||
"GS_MAX_OUTPUT_VERTICES"
|
"GS_MAX_OUTPUT_VERTICES",
|
||||||
|
"FS_COORD_ORIGIN",
|
||||||
|
"FS_COORD_PIXEL_CENTER"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *primitive_names[] =
|
static const char *primitive_names[] =
|
||||||
@@ -176,6 +178,18 @@ static const char *primitive_names[] =
|
|||||||
"POLYGON"
|
"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
|
static void
|
||||||
_dump_register_dst(
|
_dump_register_dst(
|
||||||
@@ -366,6 +380,12 @@ iter_property(
|
|||||||
case TGSI_PROPERTY_GS_OUTPUT_PRIM:
|
case TGSI_PROPERTY_GS_OUTPUT_PRIM:
|
||||||
ENM(prop->u[i].Data, primitive_names);
|
ENM(prop->u[i].Data, primitive_names);
|
||||||
break;
|
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:
|
default:
|
||||||
SID( prop->u[i].Data );
|
SID( prop->u[i].Data );
|
||||||
break;
|
break;
|
||||||
|
@@ -1129,7 +1129,9 @@ static const char *property_names[] =
|
|||||||
{
|
{
|
||||||
"GS_INPUT_PRIMITIVE",
|
"GS_INPUT_PRIMITIVE",
|
||||||
"GS_OUTPUT_PRIMITIVE",
|
"GS_OUTPUT_PRIMITIVE",
|
||||||
"GS_MAX_OUTPUT_VERTICES"
|
"GS_MAX_OUTPUT_VERTICES",
|
||||||
|
"FS_COORD_ORIGIN",
|
||||||
|
"FS_COORD_PIXEL_CENTER"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *primitive_names[] =
|
static const char *primitive_names[] =
|
||||||
@@ -1146,6 +1148,19 @@ static const char *primitive_names[] =
|
|||||||
"POLYGON"
|
"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
|
static boolean
|
||||||
parse_primitive( const char **pcur, uint *primitive )
|
parse_primitive( const char **pcur, uint *primitive )
|
||||||
{
|
{
|
||||||
@@ -1163,6 +1178,40 @@ parse_primitive( const char **pcur, uint *primitive )
|
|||||||
return FALSE;
|
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 )
|
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]);
|
ctx->implied_array_size = u_vertices_per_prim(values[0]);
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
if (!parse_uint(&ctx->cur, &values[0] )) {
|
if (!parse_uint(&ctx->cur, &values[0] )) {
|
||||||
report_error( ctx, "Expected unsigned integer as property!" );
|
report_error( ctx, "Expected unsigned integer as property!" );
|
||||||
|
@@ -142,6 +142,8 @@ struct ureg_program
|
|||||||
unsigned property_gs_input_prim;
|
unsigned property_gs_input_prim;
|
||||||
unsigned property_gs_output_prim;
|
unsigned property_gs_output_prim;
|
||||||
unsigned property_gs_max_vertices;
|
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_addrs;
|
||||||
unsigned nr_preds;
|
unsigned nr_preds;
|
||||||
@@ -265,6 +267,20 @@ ureg_property_gs_max_vertices(struct ureg_program *ureg,
|
|||||||
ureg->property_gs_max_vertices = max_vertices;
|
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
|
struct ureg_src
|
||||||
@@ -1202,6 +1218,22 @@ static void emit_decls( struct ureg_program *ureg )
|
|||||||
ureg->property_gs_max_vertices);
|
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) {
|
if (ureg->processor == TGSI_PROCESSOR_VERTEX) {
|
||||||
for (i = 0; i < UREG_MAX_INPUT; i++) {
|
for (i = 0; i < UREG_MAX_INPUT; i++) {
|
||||||
if (ureg->vs_inputs[i/32] & (1 << (i%32))) {
|
if (ureg->vs_inputs[i/32] & (1 << (i%32))) {
|
||||||
|
@@ -136,6 +136,13 @@ void
|
|||||||
ureg_property_gs_max_vertices(struct ureg_program *ureg,
|
ureg_property_gs_max_vertices(struct ureg_program *ureg,
|
||||||
unsigned max_vertices);
|
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:
|
* 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.
|
for the perspective divide, if enabled.
|
||||||
|
|
||||||
As a vertex shader output, position should be scaled to the viewport. When
|
As a vertex shader output, position should be scaled to the viewport. When
|
||||||
used in fragment shaders, position will ---
|
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 --- wait a minute. Should position be in [0,1] for x and y?
|
|
||||||
|
|
||||||
XXX additionally, is there a way to configure the perspective divide? it's
|
XXX additionally, is there a way to configure the perspective divide? it's
|
||||||
accelerated on most chipsets AFAIK...
|
accelerated on most chipsets AFAIK...
|
||||||
@@ -1400,3 +1399,45 @@ TGSI_SEMANTIC_EDGEFLAG
|
|||||||
""""""""""""""""""""""
|
""""""""""""""""""""""
|
||||||
|
|
||||||
XXX no clue
|
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_INPUT_PRIM 0
|
||||||
#define TGSI_PROPERTY_GS_OUTPUT_PRIM 1
|
#define TGSI_PROPERTY_GS_OUTPUT_PRIM 1
|
||||||
#define TGSI_PROPERTY_GS_MAX_VERTICES 2
|
#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 {
|
struct tgsi_property {
|
||||||
unsigned Type : 4; /**< TGSI_TOKEN_TYPE_PROPERTY */
|
unsigned Type : 4; /**< TGSI_TOKEN_TYPE_PROPERTY */
|
||||||
@@ -179,6 +181,12 @@ struct tgsi_property {
|
|||||||
unsigned Padding : 12;
|
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 {
|
struct tgsi_property_data {
|
||||||
unsigned Data;
|
unsigned Data;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user