From a643bc62463efbd88e34a85cda50a19d8ace6292 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Thu, 19 May 2016 14:33:50 -0700 Subject: [PATCH] i965/draw: Use 3-channel formats for vertex fetch when possible. For a long time, several of the 3-channel vertex formats didn't exist so we faked them with 4-channel versions. Starting with Sandy Bridge, we can use R16G16B16_FLOAT and 8 and 16-bit integer formats become available on Haswell and Bay Trail. Reviewed-by: Kenneth Graunke --- src/mesa/drivers/dri/i965/brw_draw_upload.c | 48 ++++++++++++++++----- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index b651fd202cd..d9e46ec92bf 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -65,7 +65,7 @@ static const GLuint half_float_types[5] = { 0, BRW_SURFACEFORMAT_R16_FLOAT, BRW_SURFACEFORMAT_R16G16_FLOAT, - BRW_SURFACEFORMAT_R16G16B16A16_FLOAT, + BRW_SURFACEFORMAT_R16G16B16_FLOAT, BRW_SURFACEFORMAT_R16G16B16A16_FLOAT }; @@ -129,7 +129,7 @@ static const GLuint ushort_types_direct[5] = { 0, BRW_SURFACEFORMAT_R16_UINT, BRW_SURFACEFORMAT_R16G16_UINT, - BRW_SURFACEFORMAT_R16G16B16A16_UINT, + BRW_SURFACEFORMAT_R16G16B16_UINT, BRW_SURFACEFORMAT_R16G16B16A16_UINT }; @@ -153,7 +153,7 @@ static const GLuint short_types_direct[5] = { 0, BRW_SURFACEFORMAT_R16_SINT, BRW_SURFACEFORMAT_R16G16_SINT, - BRW_SURFACEFORMAT_R16G16B16A16_SINT, + BRW_SURFACEFORMAT_R16G16B16_SINT, BRW_SURFACEFORMAT_R16G16B16A16_SINT }; @@ -177,7 +177,7 @@ static const GLuint ubyte_types_direct[5] = { 0, BRW_SURFACEFORMAT_R8_UINT, BRW_SURFACEFORMAT_R8G8_UINT, - BRW_SURFACEFORMAT_R8G8B8A8_UINT, + BRW_SURFACEFORMAT_R8G8B8_UINT, BRW_SURFACEFORMAT_R8G8B8A8_UINT }; @@ -201,7 +201,7 @@ static const GLuint byte_types_direct[5] = { 0, BRW_SURFACEFORMAT_R8_SINT, BRW_SURFACEFORMAT_R8G8_SINT, - BRW_SURFACEFORMAT_R8G8B8A8_SINT, + BRW_SURFACEFORMAT_R8G8B8_SINT, BRW_SURFACEFORMAT_R8G8B8A8_SINT }; @@ -248,6 +248,8 @@ brw_get_vertex_surface_type(struct brw_context *brw, const struct gl_client_array *glarray) { int size = glarray->Size; + const bool is_ivybridge_or_older = + brw->gen <= 7 && !brw->is_baytrail && !brw->is_haswell; if (unlikely(INTEL_DEBUG & DEBUG_VERTS)) fprintf(stderr, "type %s size %d normalized %d\n", @@ -258,11 +260,27 @@ brw_get_vertex_surface_type(struct brw_context *brw, assert(glarray->Format == GL_RGBA); /* sanity check */ switch (glarray->Type) { case GL_INT: return int_types_direct[size]; - case GL_SHORT: return short_types_direct[size]; - case GL_BYTE: return byte_types_direct[size]; + case GL_SHORT: + if (is_ivybridge_or_older && size == 3) + return short_types_direct[4]; + else + return short_types_direct[size]; + case GL_BYTE: + if (is_ivybridge_or_older && size == 3) + return byte_types_direct[4]; + else + return byte_types_direct[size]; case GL_UNSIGNED_INT: return uint_types_direct[size]; - case GL_UNSIGNED_SHORT: return ushort_types_direct[size]; - case GL_UNSIGNED_BYTE: return ubyte_types_direct[size]; + case GL_UNSIGNED_SHORT: + if (is_ivybridge_or_older && size == 3) + return ushort_types_direct[4]; + else + return ushort_types_direct[size]; + case GL_UNSIGNED_BYTE: + if (is_ivybridge_or_older && size == 3) + return ubyte_types_direct[4]; + else + return ubyte_types_direct[size]; default: unreachable("not reached"); } } else if (glarray->Type == GL_UNSIGNED_INT_10F_11F_11F_REV) { @@ -271,7 +289,11 @@ brw_get_vertex_surface_type(struct brw_context *brw, switch (glarray->Type) { case GL_DOUBLE: return double_types(brw, size, glarray->Doubles); case GL_FLOAT: return float_types[size]; - case GL_HALF_FLOAT: return half_float_types[size]; + case GL_HALF_FLOAT: + if (brw->gen < 6 && size == 3) + return half_float_types[4]; + else + return half_float_types[size]; case GL_INT: return int_types_norm[size]; case GL_SHORT: return short_types_norm[size]; case GL_BYTE: return byte_types_norm[size]; @@ -345,7 +367,11 @@ brw_get_vertex_surface_type(struct brw_context *brw, switch (glarray->Type) { case GL_DOUBLE: return double_types(brw, size, glarray->Doubles); case GL_FLOAT: return float_types[size]; - case GL_HALF_FLOAT: return half_float_types[size]; + case GL_HALF_FLOAT: + if (brw->gen < 6 && size == 3) + return half_float_types[4]; + else + return half_float_types[size]; case GL_INT: return int_types_scale[size]; case GL_SHORT: return short_types_scale[size]; case GL_BYTE: return byte_types_scale[size]; -- 2.30.2