From 29e2bc8b13be0f7ec48f8514e47322353e041365 Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Mon, 31 Oct 2011 17:31:16 -0700 Subject: [PATCH] i965: Add support for integral vertex attributes. When a vertex shader input attribute is declared with an integral type (e.g. ivec4), we need to ensure that the generated vertex shader code addresses the vertex attribute register using the proper register type. (Previously, we assumed all vertex shader input attributes were floating-point). In addition, when uploading vertex data that was specified with VertexAttribIPointer, we need to instruct the vertex fetch unit to convert the data to signed or unsigned int, rather than float. And when filling in the implied w=1 on a vector with less than 4 components, we need to fill it in with the integer representation of 1 rather than the floating-point representation of 1. Fixes piglit tests vs-attrib-{ivec4,uvec4}-precision. Reviewed-by: Kenneth Graunke --- src/mesa/drivers/dri/i965/brw_draw_upload.c | 69 +++++++++++++++++-- src/mesa/drivers/dri/i965/brw_vec4_emit.cpp | 1 + .../drivers/dri/i965/brw_vec4_visitor.cpp | 1 + 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index b7ae4cdd719..db0cb1823bd 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 uint_types_direct[5] = { + 0, + BRW_SURFACEFORMAT_R32_UINT, + BRW_SURFACEFORMAT_R32G32_UINT, + BRW_SURFACEFORMAT_R32G32B32_UINT, + BRW_SURFACEFORMAT_R32G32B32A32_UINT +}; + static GLuint uint_types_norm[5] = { 0, BRW_SURFACEFORMAT_R32_UNORM, @@ -81,6 +89,14 @@ static GLuint uint_types_scale[5] = { BRW_SURFACEFORMAT_R32G32B32A32_USCALED }; +static GLuint int_types_direct[5] = { + 0, + BRW_SURFACEFORMAT_R32_SINT, + BRW_SURFACEFORMAT_R32G32_SINT, + BRW_SURFACEFORMAT_R32G32B32_SINT, + BRW_SURFACEFORMAT_R32G32B32A32_SINT +}; + static GLuint int_types_norm[5] = { 0, BRW_SURFACEFORMAT_R32_SNORM, @@ -97,6 +113,14 @@ static GLuint int_types_scale[5] = { BRW_SURFACEFORMAT_R32G32B32A32_SSCALED }; +static GLuint ushort_types_direct[5] = { + 0, + BRW_SURFACEFORMAT_R16_UINT, + BRW_SURFACEFORMAT_R16G16_UINT, + BRW_SURFACEFORMAT_R16G16B16A16_UINT, + BRW_SURFACEFORMAT_R16G16B16A16_UINT +}; + static GLuint ushort_types_norm[5] = { 0, BRW_SURFACEFORMAT_R16_UNORM, @@ -113,6 +137,14 @@ static GLuint ushort_types_scale[5] = { BRW_SURFACEFORMAT_R16G16B16A16_USCALED }; +static GLuint short_types_direct[5] = { + 0, + BRW_SURFACEFORMAT_R16_SINT, + BRW_SURFACEFORMAT_R16G16_SINT, + BRW_SURFACEFORMAT_R16G16B16A16_SINT, + BRW_SURFACEFORMAT_R16G16B16A16_SINT +}; + static GLuint short_types_norm[5] = { 0, BRW_SURFACEFORMAT_R16_SNORM, @@ -129,6 +161,14 @@ static GLuint short_types_scale[5] = { BRW_SURFACEFORMAT_R16G16B16A16_SSCALED }; +static GLuint ubyte_types_direct[5] = { + 0, + BRW_SURFACEFORMAT_R8_UINT, + BRW_SURFACEFORMAT_R8G8_UINT, + BRW_SURFACEFORMAT_R8G8B8A8_UINT, + BRW_SURFACEFORMAT_R8G8B8A8_UINT +}; + static GLuint ubyte_types_norm[5] = { 0, BRW_SURFACEFORMAT_R8_UNORM, @@ -145,6 +185,14 @@ static GLuint ubyte_types_scale[5] = { BRW_SURFACEFORMAT_R8G8B8A8_USCALED }; +static GLuint byte_types_direct[5] = { + 0, + BRW_SURFACEFORMAT_R8_SINT, + BRW_SURFACEFORMAT_R8G8_SINT, + BRW_SURFACEFORMAT_R8G8B8A8_SINT, + BRW_SURFACEFORMAT_R8G8B8A8_SINT +}; + static GLuint byte_types_norm[5] = { 0, BRW_SURFACEFORMAT_R8_SNORM, @@ -168,13 +216,24 @@ static GLuint byte_types_scale[5] = { * 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 ) + GLenum format, bool normalized, bool integer ) { if (unlikely(INTEL_DEBUG & DEBUG_VERTS)) printf("type %s size %d normalized %d\n", _mesa_lookup_enum_by_nr(type), size, normalized); - if (normalized) { + if (integer) { + assert(format == GL_RGBA); /* sanity check */ + switch (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_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]; + default: assert(0); return 0; + } + } else if (normalized) { switch (type) { case GL_DOUBLE: return double_types[size]; case GL_FLOAT: return float_types[size]; @@ -620,7 +679,8 @@ static void brw_emit_vertices(struct brw_context *brw) uint32_t format = get_surface_type(input->glarray->Type, input->glarray->Size, input->glarray->Format, - input->glarray->Normalized); + input->glarray->Normalized, + input->glarray->Integer); uint32_t comp0 = BRW_VE1_COMPONENT_STORE_SRC; uint32_t comp1 = BRW_VE1_COMPONENT_STORE_SRC; uint32_t comp2 = BRW_VE1_COMPONENT_STORE_SRC; @@ -630,7 +690,8 @@ static void brw_emit_vertices(struct brw_context *brw) case 0: comp0 = BRW_VE1_COMPONENT_STORE_0; case 1: comp1 = BRW_VE1_COMPONENT_STORE_0; case 2: comp2 = BRW_VE1_COMPONENT_STORE_0; - case 3: comp3 = BRW_VE1_COMPONENT_STORE_1_FLT; + case 3: comp3 = input->glarray->Integer ? BRW_VE1_COMPONENT_STORE_1_INT + : BRW_VE1_COMPONENT_STORE_1_FLT; break; } diff --git a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp index 73898b78789..66c3b7e13d9 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp @@ -67,6 +67,7 @@ vec4_visitor::setup_attributes(int payload_reg) struct brw_reg reg = brw_vec8_grf(grf, 0); reg.dw1.bits.swizzle = inst->src[i].swizzle; + reg.type = inst->src[i].type; if (inst->src[i].abs) reg = brw_abs(reg); if (inst->src[i].negate) diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp index e5d59979b2e..5b80f559015 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp @@ -842,6 +842,7 @@ vec4_visitor::visit(ir_variable *ir) continue; dst_reg dst = *reg; + dst.type = brw_type_for_base_type(ir->type); dst.writemask = (1 << c->key.gl_fixed_input_size[i]) - 1; emit(MUL(dst, src_reg(dst), src_reg(1.0f / 65536.0f))); } -- 2.30.2