r300g: fix rectangle textures on r3xx
authorMarek Olšák <maraeo@gmail.com>
Sat, 14 Nov 2009 21:14:42 +0000 (22:14 +0100)
committerCorbin Simpson <MostAwesomeDude@gmail.com>
Fri, 20 Nov 2009 22:47:31 +0000 (14:47 -0800)
Adapted from Maciej Cencora's patch.

src/gallium/drivers/r300/r300_emit.c
src/gallium/drivers/r300/r300_state.c

index c50c989f01abadf4840f7af891bf9093c52dbb52..0bdf58202f0da4a5944caa3bfb20e9eae8fc1b8a 100644 (file)
@@ -129,7 +129,9 @@ static const float * get_shader_constant(
     struct rc_constant * constant,
     struct r300_constant_buffer * externals)
 {
-    static const float zero[4] = { 0.0, 0.0, 0.0, 0.0 };
+    static float vec[4] = { 0.0, 0.0, 0.0, 0.0 };
+    struct pipe_texture *tex;
+
     switch(constant->Type) {
         case RC_CONSTANT_EXTERNAL:
             return externals->constants[constant->u.External];
@@ -137,10 +139,26 @@ static const float * get_shader_constant(
         case RC_CONSTANT_IMMEDIATE:
             return constant->u.Immediate;
 
+        case RC_CONSTANT_STATE:
+            switch (constant->u.State[0])
+            {
+                /* R3xx-specific */
+                case RC_STATE_R300_TEXRECT_FACTOR:
+                    tex = &r300->textures[constant->u.State[1]]->tex;
+                    vec[0] = 1.0 / tex->width[0];
+                    vec[1] = 1.0 / tex->height[0];
+                    vec[2] = vec[3] = 1;
+                    break;
+
+                default:
+                    assert(0);
+            }
+            return vec;
+
         default:
             debug_printf("r300: Implementation error: Unhandled constant type %i\n",
                 constant->Type);
-            return zero;
+            return vec;
     }
 }
 
index d1eced61db1a1ec45e71af72e7a69256010d355e..00f10ffd73c11ee7150948f62fabc6568d5f6abd 100644 (file)
@@ -571,6 +571,7 @@ static void r300_set_sampler_textures(struct pipe_context* pipe,
                                       struct pipe_texture** texture)
 {
     struct r300_context* r300 = r300_context(pipe);
+    boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
     int i;
 
     /* XXX magic num */
@@ -585,6 +586,13 @@ static void r300_set_sampler_textures(struct pipe_context* pipe,
             pipe_texture_reference((struct pipe_texture**)&r300->textures[i],
                 texture[i]);
             r300->dirty_state |= (R300_NEW_TEXTURE << i);
+
+            /* R300-specific - set the texrect factor in a fragment shader */
+            if (!is_r500 && r300->textures[i]->is_npot) {
+                /* XXX It would be nice to re-emit just 1 constant,
+                 * XXX not all of them */
+                r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+            }
         }
     }