diff options
| author | Marek Olšák <maraeo@gmail.com> | 2010-06-21 00:42:06 +0200 | 
|---|---|---|
| committer | Marek Olšák <maraeo@gmail.com> | 2010-06-21 04:07:11 +0200 | 
| commit | d82f6253331abf09ca714b844b1a9179ed8050b3 (patch) | |
| tree | 22f4004ee529baa4aaa7e71d48db232d335131d9 | |
| parent | 646e9c2fd7b5974480fcbed0bef7281b4d4a0e65 (diff) | |
r300g: fix the KIL opcode for r3xx-r4xx (v4)
| -rw-r--r-- | src/gallium/drivers/r300/r300_context.c | 36 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_context.h | 4 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_state_derived.c | 34 | 
3 files changed, 74 insertions, 0 deletions
| diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 0fae19dfd7..ee86f8230f 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -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: diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 224d573775..fdbdb4b192 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -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; diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 1e5a272165..3aa8deb63c 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -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; +            }          }      } | 
