i965: Add support for integral vertex attributes.
authorPaul Berry <stereotype441@gmail.com>
Tue, 1 Nov 2011 00:31:16 +0000 (17:31 -0700)
committerPaul Berry <stereotype441@gmail.com>
Wed, 2 Nov 2011 16:29:35 +0000 (09:29 -0700)
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 <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_draw_upload.c
src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp

index b7ae4cdd7194596db8a776a5d2bc29b79f8e1a59..db0cb1823bd9e84ce10481a5a456a02b94e180e0 100644 (file)
@@ -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;
       }
 
index 73898b787896a27d1fcd2f9d9e687eac60fee922..66c3b7e13d95b1ab76bea4fb7d7a31d0a0ca315b 100644 (file)
@@ -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)
index e5d59979b2e29da326d497eaa95ef697169f8372..5b80f559015510f267b701fc9bcc5847efeea30c 100644 (file)
@@ -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)));
       }