@@ -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: |
@@ -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; | |||
@@ -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; | |||
} | |||
} | |||
} | |||