r300g: fix the KIL opcode for r3xx-r4xx (v4)
authorMarek Olšák <maraeo@gmail.com>
Sun, 20 Jun 2010 22:42:06 +0000 (00:42 +0200)
committerMarek Olšák <maraeo@gmail.com>
Mon, 21 Jun 2010 02:07:11 +0000 (04:07 +0200)
src/gallium/drivers/r300/r300_context.c
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_state_derived.c

index 0fae19d..ee86f82 100644 (file)
@@ -23,6 +23,7 @@
 #include "draw/draw_context.h"
 
 #include "util/u_memory.h"
+#include "util/u_sampler.h"
 #include "util/u_simple_list.h"
 #include "util/u_upload_mgr.h"
 
@@ -42,6 +43,12 @@ static void r300_destroy_context(struct pipe_context* context)
     struct r300_query *query, *temp;
     struct r300_atom *atom;
 
+    if (r300->texkill_sampler) {
+        pipe_sampler_view_reference(
+                (struct pipe_sampler_view**)r300->texkill_sampler,
+                NULL);
+    }
+
     util_blitter_destroy(r300->blitter);
     draw_destroy(r300->draw);
 
@@ -251,6 +258,35 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
 
     r300_init_states(&r300->context);
 
+    /* The KIL opcode needs the first texture unit to be enabled
+     * on r3xx-r4xx. In order to calm down the CS checker, we bind this
+     * dummy texture there. */
+    if (!r300->screen->caps.is_r500) {
+        struct pipe_resource *tex;
+        struct pipe_resource rtempl = {{0}};
+        struct pipe_sampler_view vtempl = {{0}};
+
+        rtempl.target = PIPE_TEXTURE_2D;
+        rtempl.format = PIPE_FORMAT_I8_UNORM;
+        rtempl.bind = PIPE_BIND_SAMPLER_VIEW;
+        rtempl.width0 = 1;
+        rtempl.height0 = 1;
+        rtempl.depth0 = 1;
+        tex = screen->resource_create(screen, &rtempl);
+
+        u_sampler_view_default_template(&vtempl, tex, tex->format);
+
+        r300->texkill_sampler = (struct r300_sampler_view*)
+            r300->context.create_sampler_view(&r300->context, tex, &vtempl);
+
+        pipe_resource_reference(&tex, NULL);
+
+        /* This will make sure that the dummy texture is set up
+         * from the beginning even if an application does not use
+         * textures. */
+        r300->textures_state.dirty = TRUE;
+    }
+
     return &r300->context;
 
  no_upload_ib:
index 224d573..fdbdb4b 100644 (file)
@@ -401,6 +401,10 @@ struct r300_context {
 
     /* Vertex buffer for rendering. */
     struct pipe_resource* vbo;
+    /* The KIL opcode needs the first texture unit to be enabled
+     * on r3xx-r4xx. In order to calm down the CS checker, we bind this
+     * dummy texture there. */
+    struct r300_sampler_view *texkill_sampler;
     /* Offset into the VBO. */
     size_t vbo_offset;
 
index 1e5a272..3aa8deb 100644 (file)
@@ -536,6 +536,10 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
         UTIL_FORMAT_SWIZZLE_X
     };
 
+    /* The KIL opcode fix, see below. */
+    if (!count && !r300->screen->caps.is_r500)
+        count = 1;
+
     state->tx_enable = 0;
     state->count = 0;
     size = 2;
@@ -615,6 +619,36 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
 
             size += 16;
             state->count = i+1;
+        } else {
+            /* For the KIL opcode to work on r3xx-r4xx, the texture unit
+             * assigned to this opcode (it's always the first one) must be
+             * enabled. Otherwise the opcode doesn't work.
+             *
+             * In order to not depend on the fragment shader, we just make
+             * the first unit enabled all the time. */
+            if (i == 0 && !r300->screen->caps.is_r500) {
+                pipe_sampler_view_reference(
+                        (struct pipe_sampler_view**)&state->sampler_views[i],
+                        &r300->texkill_sampler->base);
+
+                state->tx_enable |= 1 << i;
+
+                texstate = &state->regs[i];
+
+                /* Just set some valid state. */
+                texstate->format = r300->texkill_sampler->format;
+                texstate->filter0 =
+                        r300_translate_tex_filters(PIPE_TEX_FILTER_NEAREST,
+                                                   PIPE_TEX_FILTER_NEAREST,
+                                                   PIPE_TEX_FILTER_NEAREST,
+                                                   FALSE);
+                texstate->filter1 = 0;
+                texstate->border_color = 0;
+
+                texstate->filter0 |= i << 28;
+                size += 16;
+                state->count = i+1;
+            }
         }
     }