diff options
-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 0fae19dfd78..ee86f8230fb 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 224d5737753..fdbdb4b192d 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 1e5a2721651..3aa8deb63c8 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; + } } } |