[Mesa-dev] [PATCH 4/4] i965: Support GL_FIXED and packed vertex formats natively on Haswell+.
Kenneth Graunke
kenneth at whitecape.org
Fri Jan 4 07:53:12 PST 2013
Haswell and later support the GL_FIXED and 2_10_10_10_rev vertex formats
natively, and don't need shader workarounds.
---
src/mesa/drivers/dri/i965/brw_draw_upload.c | 60 ++++++++++++++++++++++++-----
src/mesa/drivers/dri/i965/brw_vs.c | 45 ++++++++++++----------
2 files changed, 75 insertions(+), 30 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index 515a7a8..8e1b9bb 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -65,6 +65,14 @@ static GLuint half_float_types[5] = {
BRW_SURFACEFORMAT_R16G16B16A16_FLOAT
};
+static GLuint fixed_point_types[5] = {
+ 0,
+ BRW_SURFACEFORMAT_R32_SFIXED,
+ BRW_SURFACEFORMAT_R32G32_SFIXED,
+ BRW_SURFACEFORMAT_R32G32B32_SFIXED,
+ BRW_SURFACEFORMAT_R32G32B32A32_SFIXED,
+};
+
static GLuint uint_types_direct[5] = {
0,
BRW_SURFACEFORMAT_R32_UINT,
@@ -215,8 +223,9 @@ static GLuint byte_types_scale[5] = {
* the appopriate hardware surface type.
* Format will be GL_RGBA or possibly GL_BGRA for GLubyte[4] color arrays.
*/
-static GLuint get_surface_type( GLenum type, GLuint size,
- GLenum format, bool normalized, bool integer )
+static unsigned
+get_surface_type(struct intel_context *intel, GLenum type, GLuint size,
+ GLenum format, bool normalized, bool integer)
{
if (unlikely(INTEL_DEBUG & DEBUG_VERTS))
printf("type %s size %d normalized %d\n",
@@ -253,13 +262,25 @@ static GLuint get_surface_type( GLenum type, GLuint size,
return ubyte_types_norm[size];
}
/* See GL_ARB_vertex_type_2_10_10_10_rev.
- * W/A: the hardware doesn't really support the formats we'd
+ * W/A: Pre-Haswell, the hardware doesn't really support the formats we'd
* like to use here, so upload everything as UINT and fix
* it in the shader
*/
case GL_INT_2_10_10_10_REV:
+ assert(size == 4);
+ if (intel->gen >= 8 || intel->is_haswell) {
+ return format == GL_BGRA
+ ? BRW_SURFACEFORMAT_B10G10R10A2_SNORM
+ : BRW_SURFACEFORMAT_R10G10B10A2_SNORM;
+ }
+ return BRW_SURFACEFORMAT_R10G10B10A2_UINT;
case GL_UNSIGNED_INT_2_10_10_10_REV:
assert(size == 4);
+ if (intel->gen >= 8 || intel->is_haswell) {
+ return format == GL_BGRA
+ ? BRW_SURFACEFORMAT_B10G10R10A2_UNORM
+ : BRW_SURFACEFORMAT_R10G10B10A2_UNORM;
+ }
return BRW_SURFACEFORMAT_R10G10B10A2_UINT;
default: assert(0); return 0;
}
@@ -270,8 +291,21 @@ static GLuint get_surface_type( GLenum type, GLuint size,
* like to use here, so upload everything as UINT and fix
* it in the shader
*/
- if (type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) {
+ if (type == GL_INT_2_10_10_10_REV) {
assert(size == 4);
+ if (intel->gen >= 8 || intel->is_haswell) {
+ return format == GL_BGRA
+ ? BRW_SURFACEFORMAT_B10G10R10A2_SSCALED
+ : BRW_SURFACEFORMAT_R10G10B10A2_SSCALED;
+ }
+ return BRW_SURFACEFORMAT_R10G10B10A2_UINT;
+ } else if (type == GL_UNSIGNED_INT_2_10_10_10_REV) {
+ assert(size == 4);
+ if (intel->gen >= 8 || intel->is_haswell) {
+ return format == GL_BGRA
+ ? BRW_SURFACEFORMAT_B10G10R10A2_USCALED
+ : BRW_SURFACEFORMAT_R10G10B10A2_USCALED;
+ }
return BRW_SURFACEFORMAT_R10G10B10A2_UINT;
}
assert(format == GL_RGBA); /* sanity check */
@@ -285,10 +319,14 @@ static GLuint get_surface_type( GLenum type, GLuint size,
case GL_UNSIGNED_INT: return uint_types_scale[size];
case GL_UNSIGNED_SHORT: return ushort_types_scale[size];
case GL_UNSIGNED_BYTE: return ubyte_types_scale[size];
- /* This produces GL_FIXED inputs as values between INT32_MIN and
- * INT32_MAX, which will be scaled down by 1/65536 by the VS.
- */
- case GL_FIXED: return int_types_scale[size];
+ case GL_FIXED:
+ if (intel->gen >= 8 || intel->is_haswell)
+ return fixed_point_types[size];
+
+ /* This produces GL_FIXED inputs as values between INT32_MIN and
+ * INT32_MAX, which will be scaled down by 1/65536 by the VS.
+ */
+ return int_types_scale[size];
default: assert(0); return 0;
}
}
@@ -659,7 +697,8 @@ static void brw_emit_vertices(struct brw_context *brw)
OUT_BATCH((_3DSTATE_VERTEX_ELEMENTS << 16) | (2 * nr_elements - 1));
for (i = 0; i < brw->vb.nr_enabled; i++) {
struct brw_vertex_element *input = brw->vb.enabled[i];
- uint32_t format = get_surface_type(input->glarray->Type,
+ uint32_t format = get_surface_type(intel,
+ input->glarray->Type,
input->glarray->Size,
input->glarray->Format,
input->glarray->Normalized,
@@ -724,7 +763,8 @@ static void brw_emit_vertices(struct brw_context *brw)
}
if (intel->gen >= 6 && gen6_edgeflag_input) {
- uint32_t format = get_surface_type(gen6_edgeflag_input->glarray->Type,
+ uint32_t format = get_surface_type(intel,
+ gen6_edgeflag_input->glarray->Type,
gen6_edgeflag_input->glarray->Size,
gen6_edgeflag_input->glarray->Format,
gen6_edgeflag_input->glarray->Normalized,
diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c
index fc57f8a..0a20055 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.c
+++ b/src/mesa/drivers/dri/i965/brw_vs.c
@@ -440,33 +440,38 @@ static void brw_upload_vs_prog(struct brw_context *brw)
brw_populate_sampler_prog_key_data(ctx, prog, &key.tex);
/* BRW_NEW_VERTICES */
- for (i = 0; i < VERT_ATTRIB_MAX; i++) {
- if (vp->program.Base.InputsRead & BITFIELD64_BIT(i)) {
- uint8_t wa_flags = 0;
+ if (intel->gen < 8 && !intel->is_haswell) {
+ /* Prior to Haswell, the hardware can't natively support GL_FIXED or
+ * 2_10_10_10_REV vertex formats. Set appropriate workaround flags.
+ */
+ for (i = 0; i < VERT_ATTRIB_MAX; i++) {
+ if (vp->program.Base.InputsRead & BITFIELD64_BIT(i)) {
+ uint8_t wa_flags = 0;
- switch (brw->vb.inputs[i].glarray->Type) {
+ switch (brw->vb.inputs[i].glarray->Type) {
- case GL_FIXED:
- wa_flags = brw->vb.inputs[i].glarray->Size;
- break;
+ case GL_FIXED:
+ wa_flags = brw->vb.inputs[i].glarray->Size;
+ break;
- case GL_INT_2_10_10_10_REV:
- wa_flags |= BRW_ATTRIB_WA_SIGN;
- /* fallthough */
+ case GL_INT_2_10_10_10_REV:
+ wa_flags |= BRW_ATTRIB_WA_SIGN;
+ /* fallthough */
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- if (brw->vb.inputs[i].glarray->Format == GL_BGRA)
- wa_flags |= BRW_ATTRIB_WA_BGRA;
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ if (brw->vb.inputs[i].glarray->Format == GL_BGRA)
+ wa_flags |= BRW_ATTRIB_WA_BGRA;
- if (brw->vb.inputs[i].glarray->Normalized)
- wa_flags |= BRW_ATTRIB_WA_NORMALIZE;
- else if (!brw->vb.inputs[i].glarray->Integer)
- wa_flags |= BRW_ATTRIB_WA_SCALE;
+ if (brw->vb.inputs[i].glarray->Normalized)
+ wa_flags |= BRW_ATTRIB_WA_NORMALIZE;
+ else if (!brw->vb.inputs[i].glarray->Integer)
+ wa_flags |= BRW_ATTRIB_WA_SCALE;
- break;
- }
+ break;
+ }
- key.gl_attrib_wa_flags[i] = wa_flags;
+ key.gl_attrib_wa_flags[i] = wa_flags;
+ }
}
}
--
1.8.0.1
More information about the mesa-dev
mailing list