From aa5db684382bd8662a83ca09ed000e4a5a1013f9 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 16 Jul 2009 14:14:32 +0100 Subject: softpipe: remove backwards dependency from tilecache to softpipe The tile cache is a utility, it shouldn't know anything about the entity which is making use of it (ie softpipe). Remove softpipe parameter to all the tilecache function calls, and also remove the need to keep a softpipe pointer in the sampler structs. --- src/gallium/drivers/softpipe/sp_context.c | 8 ++---- src/gallium/drivers/softpipe/sp_flush.c | 6 ++--- src/gallium/drivers/softpipe/sp_quad_blend.c | 6 ++--- src/gallium/drivers/softpipe/sp_quad_colormask.c | 3 +-- src/gallium/drivers/softpipe/sp_quad_depth_test.c | 2 +- src/gallium/drivers/softpipe/sp_quad_output.c | 3 +-- src/gallium/drivers/softpipe/sp_quad_stencil.c | 2 +- src/gallium/drivers/softpipe/sp_state_derived.c | 22 ++++++++++++++++ src/gallium/drivers/softpipe/sp_state_sampler.c | 2 +- src/gallium/drivers/softpipe/sp_state_surface.c | 4 +-- src/gallium/drivers/softpipe/sp_tex_sample.c | 32 ++++++++--------------- src/gallium/drivers/softpipe/sp_tex_sample.h | 5 ++-- src/gallium/drivers/softpipe/sp_tile_cache.c | 20 ++++++-------- src/gallium/drivers/softpipe/sp_tile_cache.h | 12 +++------ 14 files changed, 62 insertions(+), 65 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 86df320ea8a..f085889d3a0 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -73,8 +73,8 @@ softpipe_unmap_transfers(struct softpipe_context *sp) uint i; for (i = 0; i < sp->framebuffer.nr_cbufs; i++) - sp_flush_tile_cache(sp, sp->cbuf_cache[i]); - sp_flush_tile_cache(sp, sp->zsbuf_cache); + sp_flush_tile_cache(sp->cbuf_cache[i]); + sp_flush_tile_cache(sp->zsbuf_cache); for (i = 0; i < sp->framebuffer.nr_cbufs; i++) { sp_tile_cache_unmap_transfers(sp->cbuf_cache[i]); @@ -254,8 +254,6 @@ softpipe_create( struct pipe_screen *screen ) /* vertex shader samplers */ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { softpipe->tgsi.vert_samplers[i].base.get_samples = sp_get_samples_vertex; - softpipe->tgsi.vert_samplers[i].unit = i; - softpipe->tgsi.vert_samplers[i].sp = softpipe; softpipe->tgsi.vert_samplers[i].cache = softpipe->tex_cache[i]; softpipe->tgsi.vert_samplers_list[i] = &softpipe->tgsi.vert_samplers[i]; } @@ -263,8 +261,6 @@ softpipe_create( struct pipe_screen *screen ) /* fragment shader samplers */ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples_fragment; - softpipe->tgsi.frag_samplers[i].unit = i; - softpipe->tgsi.frag_samplers[i].sp = softpipe; softpipe->tgsi.frag_samplers[i].cache = softpipe->tex_cache[i]; softpipe->tgsi.frag_samplers_list[i] = &softpipe->tgsi.frag_samplers[i]; } diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index 4a14d49686e..732277a2c58 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -52,17 +52,17 @@ softpipe_flush( struct pipe_context *pipe, if (flags & PIPE_FLUSH_TEXTURE_CACHE) { for (i = 0; i < softpipe->num_textures; i++) { - sp_flush_tile_cache(softpipe, softpipe->tex_cache[i]); + sp_flush_tile_cache(softpipe->tex_cache[i]); } } if (flags & PIPE_FLUSH_RENDER_CACHE) { for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) if (softpipe->cbuf_cache[i]) - sp_flush_tile_cache(softpipe, softpipe->cbuf_cache[i]); + sp_flush_tile_cache(softpipe->cbuf_cache[i]); if (softpipe->zsbuf_cache) - sp_flush_tile_cache(softpipe, softpipe->zsbuf_cache); + sp_flush_tile_cache(softpipe->zsbuf_cache); /* Need this call for hardware buffers before swapbuffers. * diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index b1e18805c70..04b5daf3a41 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -130,8 +130,7 @@ logicop_quad(struct quad_stage *qs, struct quad_header *quad) uint *dst4 = (uint *) dst; uint *res4 = (uint *) res; struct softpipe_cached_tile * - tile = sp_get_cached_tile(softpipe, - softpipe->cbuf_cache[cbuf], + tile = sp_get_cached_tile(softpipe->cbuf_cache[cbuf], quad->input.x0, quad->input.y0); float (*quadColor)[4] = quad->output.color[cbuf]; uint i, j; @@ -260,8 +259,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) { float source[4][QUAD_SIZE], dest[4][QUAD_SIZE]; struct softpipe_cached_tile *tile - = sp_get_cached_tile(softpipe, - softpipe->cbuf_cache[cbuf], + = sp_get_cached_tile(softpipe->cbuf_cache[cbuf], quad->input.x0, quad->input.y0); float (*quadColor)[4] = quad->output.color[cbuf]; uint i, j; diff --git a/src/gallium/drivers/softpipe/sp_quad_colormask.c b/src/gallium/drivers/softpipe/sp_quad_colormask.c index dc90e5d5e99..89efbe3b024 100644 --- a/src/gallium/drivers/softpipe/sp_quad_colormask.c +++ b/src/gallium/drivers/softpipe/sp_quad_colormask.c @@ -54,8 +54,7 @@ colormask_quad(struct quad_stage *qs, struct quad_header *quad) for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) { float dest[4][QUAD_SIZE]; struct softpipe_cached_tile *tile - = sp_get_cached_tile(softpipe, - softpipe->cbuf_cache[cbuf], + = sp_get_cached_tile(softpipe->cbuf_cache[cbuf], quad->input.x0, quad->input.y0); float (*quadColor)[4] = quad->output.color[cbuf]; uint i, j; diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index d463930bae1..768b9275b30 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -60,7 +60,7 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) unsigned zmask = 0; unsigned j; struct softpipe_cached_tile *tile - = sp_get_cached_tile(softpipe, softpipe->zsbuf_cache, quad->input.x0, quad->input.y0); + = sp_get_cached_tile(softpipe->zsbuf_cache, quad->input.x0, quad->input.y0); assert(ps); /* shouldn't get here if there's no zbuffer */ diff --git a/src/gallium/drivers/softpipe/sp_quad_output.c b/src/gallium/drivers/softpipe/sp_quad_output.c index 92d5f9f3c1a..dd8f5377e91 100644 --- a/src/gallium/drivers/softpipe/sp_quad_output.c +++ b/src/gallium/drivers/softpipe/sp_quad_output.c @@ -50,8 +50,7 @@ output_quad(struct quad_stage *qs, struct quad_header *quad) /* loop over colorbuffer outputs */ for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) { struct softpipe_cached_tile *tile - = sp_get_cached_tile(softpipe, - softpipe->cbuf_cache[cbuf], + = sp_get_cached_tile(softpipe->cbuf_cache[cbuf], quad->input.x0, quad->input.y0); float (*quadColor)[4] = quad->output.color[cbuf]; int i, j; diff --git a/src/gallium/drivers/softpipe/sp_quad_stencil.c b/src/gallium/drivers/softpipe/sp_quad_stencil.c index 5e9d447737d..34a8d9e9f6a 100644 --- a/src/gallium/drivers/softpipe/sp_quad_stencil.c +++ b/src/gallium/drivers/softpipe/sp_quad_stencil.c @@ -206,7 +206,7 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad) ubyte ref, wrtMask, valMask; ubyte stencilVals[QUAD_SIZE]; struct softpipe_cached_tile *tile - = sp_get_cached_tile(softpipe, softpipe->zsbuf_cache, quad->input.x0, quad->input.y0); + = sp_get_cached_tile(softpipe->zsbuf_cache, quad->input.x0, quad->input.y0); uint j; uint face = quad->input.facing; diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 75551000c9b..75be99768c9 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -184,11 +184,33 @@ compute_cliprect(struct softpipe_context *sp) } +static void +update_tgsi_samplers( struct softpipe_context *softpipe ) +{ + unsigned i; + + /* vertex shader samplers */ + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + softpipe->tgsi.vert_samplers[i].sampler = softpipe->sampler[i]; + softpipe->tgsi.vert_samplers[i].texture = softpipe->texture[i]; + } + + /* fragment shader samplers */ + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + softpipe->tgsi.frag_samplers[i].sampler = softpipe->sampler[i]; + softpipe->tgsi.frag_samplers[i].texture = softpipe->texture[i]; + } +} + /* Hopefully this will remain quite simple, otherwise need to pull in * something like the state tracker mechanism. */ void softpipe_update_derived( struct softpipe_context *softpipe ) { + if (softpipe->dirty & (SP_NEW_SAMPLER | + SP_NEW_TEXTURE)) + update_tgsi_samplers( softpipe ); + if (softpipe->dirty & (SP_NEW_RASTERIZER | SP_NEW_FS | SP_NEW_VS)) diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index cb517b02e44..aa2f3f2ccd6 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -97,7 +97,7 @@ softpipe_set_sampler_textures(struct pipe_context *pipe, struct pipe_texture *tex = i < num ? texture[i] : NULL; pipe_texture_reference(&softpipe->texture[i], tex); - sp_tile_cache_set_texture(pipe, softpipe->tex_cache[i], tex); + sp_tile_cache_set_texture(softpipe->tex_cache[i], tex); } softpipe->num_textures = num; diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c index 7c06d864a75..1621a276146 100644 --- a/src/gallium/drivers/softpipe/sp_state_surface.c +++ b/src/gallium/drivers/softpipe/sp_state_surface.c @@ -53,7 +53,7 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, /* check if changing cbuf */ if (sp->framebuffer.cbufs[i] != fb->cbufs[i]) { /* flush old */ - sp_flush_tile_cache(sp, sp->cbuf_cache[i]); + sp_flush_tile_cache(sp->cbuf_cache[i]); /* assign new */ sp->framebuffer.cbufs[i] = fb->cbufs[i]; @@ -68,7 +68,7 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, /* zbuf changing? */ if (sp->framebuffer.zsbuf != fb->zsbuf) { /* flush old */ - sp_flush_tile_cache(sp, sp->zsbuf_cache); + sp_flush_tile_cache(sp->zsbuf_cache); /* assign new */ sp->framebuffer.zsbuf = fb->zsbuf; diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index a1d3bade27a..3daa88eedda 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -668,10 +668,8 @@ get_texel(const struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j) { const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); - struct softpipe_context *sp = samp->sp; - const uint unit = samp->unit; - const struct pipe_texture *texture = sp->texture[unit]; - const struct pipe_sampler_state *sampler = sp->sampler[unit]; + const struct pipe_texture *texture = samp->texture; + const struct pipe_sampler_state *sampler = samp->sampler; if (x < 0 || x >= (int) texture->width[level] || y < 0 || y >= (int) texture->height[level] || @@ -685,7 +683,7 @@ get_texel(const struct tgsi_sampler *tgsi_sampler, const int tx = x % TILE_SIZE; const int ty = y % TILE_SIZE; const struct softpipe_cached_tile *tile - = sp_get_cached_tile_tex(sp, samp->cache, + = sp_get_cached_tile_tex(samp->cache, x, y, z, face, level); rgba[0][j] = tile->data.color[ty][tx][0]; rgba[1][j] = tile->data.color[ty][tx][1]; @@ -840,10 +838,8 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler, const unsigned faces[4]) { const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); - const struct softpipe_context *sp = samp->sp; - const uint unit = samp->unit; - const struct pipe_texture *texture = sp->texture[unit]; - const struct pipe_sampler_state *sampler = sp->sampler[unit]; + const struct pipe_texture *texture = samp->texture; + const struct pipe_sampler_state *sampler = samp->sampler; unsigned level0, level1, j, imgFilter; int width, height; float levelBlend; @@ -992,10 +988,8 @@ sp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); - const struct softpipe_context *sp = samp->sp; - const uint unit = samp->unit; - const struct pipe_texture *texture = sp->texture[unit]; - const struct pipe_sampler_state *sampler = sp->sampler[unit]; + const struct pipe_texture *texture = samp->texture; + const struct pipe_sampler_state *sampler = samp->sampler; /* get/map pipe_surfaces corresponding to 3D tex slices */ unsigned level0, level1, j, imgFilter; int width, height, depth; @@ -1139,10 +1133,8 @@ sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); - const struct softpipe_context *sp = samp->sp; - const uint unit = samp->unit; - const struct pipe_texture *texture = sp->texture[unit]; - const struct pipe_sampler_state *sampler = sp->sampler[unit]; + const struct pipe_texture *texture = samp->texture; + const struct pipe_sampler_state *sampler = samp->sampler; const uint face = 0; unsigned level0, level1, j, imgFilter; int width, height; @@ -1216,10 +1208,8 @@ sp_get_samples(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); - const struct softpipe_context *sp = samp->sp; - const uint unit = samp->unit; - const struct pipe_texture *texture = sp->texture[unit]; - const struct pipe_sampler_state *sampler = sp->sampler[unit]; + const struct pipe_texture *texture = samp->texture; + const struct pipe_sampler_state *sampler = samp->sampler; if (!texture) return; diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h index 40d8eb2c2a8..3c5beb560f2 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.h +++ b/src/gallium/drivers/softpipe/sp_tex_sample.h @@ -39,8 +39,9 @@ struct sp_shader_sampler { struct tgsi_sampler base; /**< base class */ - uint unit; - struct softpipe_context *sp; + const struct pipe_texture *texture; + const struct pipe_sampler_state *sampler; + struct softpipe_tile_cache *cache; }; diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 1f9b8f1f4fb..306284808cd 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -236,8 +236,7 @@ sp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc) * Specify the texture to cache. */ void -sp_tile_cache_set_texture(struct pipe_context *pipe, - struct softpipe_tile_cache *tc, +sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, struct pipe_texture *texture) { uint i; @@ -344,8 +343,7 @@ clear_tile(struct softpipe_cached_tile *tile, * Actually clear the tiles which were flagged as being in a clear state. */ static void -sp_tile_cache_flush_clear(struct pipe_context *pipe, - struct softpipe_tile_cache *tc) +sp_tile_cache_flush_clear(struct softpipe_tile_cache *tc) { struct pipe_transfer *pt = tc->transfer; const uint w = tc->transfer->width; @@ -382,8 +380,7 @@ sp_tile_cache_flush_clear(struct pipe_context *pipe, * any tiles "flagged" as cleared will be "really" cleared. */ void -sp_flush_tile_cache(struct softpipe_context *softpipe, - struct softpipe_tile_cache *tc) +sp_flush_tile_cache(struct softpipe_tile_cache *tc) { struct pipe_transfer *pt = tc->transfer; int inuse = 0, pos; @@ -409,7 +406,7 @@ sp_flush_tile_cache(struct softpipe_context *softpipe, } #if TILE_CLEAR_OPTIMIZATION - sp_tile_cache_flush_clear(&softpipe->pipe, tc); + sp_tile_cache_flush_clear(tc); #endif } else if (tc->texture) { @@ -431,8 +428,7 @@ sp_flush_tile_cache(struct softpipe_context *softpipe, * \param x, y position of tile, in pixels */ struct softpipe_cached_tile * -sp_get_cached_tile(struct softpipe_context *softpipe, - struct softpipe_tile_cache *tc, int x, int y) +sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y) { struct pipe_transfer *pt = tc->transfer; @@ -513,11 +509,11 @@ tex_cache_pos(int x, int y, int z, int face, int level) * Tiles are read-only and indexed with more params. */ const struct softpipe_cached_tile * -sp_get_cached_tile_tex(struct softpipe_context *sp, - struct softpipe_tile_cache *tc, int x, int y, int z, +sp_get_cached_tile_tex(struct softpipe_tile_cache *tc, + int x, int y, int z, int face, int level) { - struct pipe_screen *screen = sp->pipe.screen; + struct pipe_screen *screen = tc->screen; /* tile pos in framebuffer: */ const int tile_x = x & ~(TILE_SIZE - 1); const int tile_y = y & ~(TILE_SIZE - 1); diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h index 8f247d0e580..639cde67059 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tile_cache.h @@ -80,25 +80,21 @@ extern void sp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc); extern void -sp_tile_cache_set_texture(struct pipe_context *pipe, - struct softpipe_tile_cache *tc, +sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, struct pipe_texture *texture); extern void -sp_flush_tile_cache(struct softpipe_context *softpipe, - struct softpipe_tile_cache *tc); +sp_flush_tile_cache(struct softpipe_tile_cache *tc); extern void sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float *rgba, uint clearValue); extern struct softpipe_cached_tile * -sp_get_cached_tile(struct softpipe_context *softpipe, - struct softpipe_tile_cache *tc, int x, int y); +sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y); extern const struct softpipe_cached_tile * -sp_get_cached_tile_tex(struct softpipe_context *softpipe, - struct softpipe_tile_cache *tc, int x, int y, int z, +sp_get_cached_tile_tex(struct softpipe_tile_cache *tc, int x, int y, int z, int face, int level); -- cgit v1.2.3 From b5d583efeff5f195bff48c95125a225c273189e2 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 17 Jul 2009 10:44:22 +0100 Subject: softpipe: make some small steps to flush texture cache less frequently No performance gain yet, but the code is a bit cleaner. --- src/gallium/drivers/softpipe/sp_context.h | 3 +- src/gallium/drivers/softpipe/sp_state_derived.c | 14 +++++ src/gallium/drivers/softpipe/sp_texture.c | 3 +- src/gallium/drivers/softpipe/sp_texture.h | 2 +- src/gallium/drivers/softpipe/sp_tile_cache.c | 80 +++++++++++++++---------- src/gallium/drivers/softpipe/sp_tile_cache.h | 3 + 6 files changed, 70 insertions(+), 35 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 7888c2f644b..f66f0b7849d 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -149,7 +149,8 @@ struct softpipe_context { struct softpipe_tile_cache *cbuf_cache[PIPE_MAX_COLOR_BUFS]; struct softpipe_tile_cache *zsbuf_cache; - + + unsigned tex_timestamp; struct softpipe_tile_cache *tex_cache[PIPE_MAX_SAMPLERS]; unsigned use_sse : 1; diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 75be99768c9..629a1f8e293 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -32,6 +32,7 @@ #include "draw/draw_vertex.h" #include "draw/draw_private.h" #include "sp_context.h" +#include "sp_screen.h" #include "sp_state.h" @@ -200,6 +201,10 @@ update_tgsi_samplers( struct softpipe_context *softpipe ) softpipe->tgsi.frag_samplers[i].sampler = softpipe->sampler[i]; softpipe->tgsi.frag_samplers[i].texture = softpipe->texture[i]; } + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + sp_tile_cache_validate_texture( softpipe->tex_cache[i] ); + } } /* Hopefully this will remain quite simple, otherwise need to pull in @@ -207,6 +212,15 @@ update_tgsi_samplers( struct softpipe_context *softpipe ) */ void softpipe_update_derived( struct softpipe_context *softpipe ) { + struct softpipe_screen *sp_screen = softpipe_screen(softpipe->pipe.screen); + + /* Check for updated textures. + */ + if (softpipe->tex_timestamp != sp_screen->timestamp) { + softpipe->tex_timestamp = sp_screen->timestamp; + softpipe->dirty |= SP_NEW_TEXTURE; + } + if (softpipe->dirty & (SP_NEW_SAMPLER | SP_NEW_TEXTURE)) update_tgsi_samplers( softpipe ); diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 7a533dad9f0..0c84375bf10 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -227,7 +227,8 @@ softpipe_get_tex_surface(struct pipe_screen *screen, if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_GPU_WRITE)) { /* Mark the surface as dirty. The tile cache will look for this. */ - spt->modified = TRUE; + spt->timestamp++; + softpipe_screen(screen)->timestamp++; } ps->face = face; diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h index 893aa7d11d8..42df722a2d1 100644 --- a/src/gallium/drivers/softpipe/sp_texture.h +++ b/src/gallium/drivers/softpipe/sp_texture.h @@ -48,7 +48,7 @@ struct softpipe_texture */ struct pipe_buffer *buffer; - boolean modified; + unsigned timestamp; }; struct softpipe_transfer diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 306284808cd..79b1e036be8 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -54,7 +54,10 @@ struct softpipe_tile_cache struct pipe_surface *surface; /**< the surface we're caching */ struct pipe_transfer *transfer; void *transfer_map; + struct pipe_texture *texture; /**< if caching a texture */ + unsigned timestamp; + struct softpipe_cached_tile entries[NUM_ENTRIES]; uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32]; float clear_color[4]; /**< for color bufs */ @@ -231,6 +234,23 @@ sp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc) } } +void +sp_tile_cache_validate_texture(struct softpipe_tile_cache *tc) +{ + if (tc->texture) { + struct softpipe_texture *spt = softpipe_texture(tc->texture); + if (spt->timestamp != tc->timestamp) { + /* texture was modified, invalidate all cached tiles */ + uint i; + _debug_printf("INV %d %d\n", tc->timestamp, spt->timestamp); + for (i = 0; i < NUM_ENTRIES; i++) { + tc->entries[i].x = -3; + } + + tc->timestamp = spt->timestamp; + } + } +} /** * Specify the texture to cache. @@ -243,27 +263,29 @@ sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, assert(!tc->transfer); - pipe_texture_reference(&tc->texture, texture); + if (tc->texture != texture) { + pipe_texture_reference(&tc->texture, texture); - if (tc->tex_trans) { - struct pipe_screen *screen = tc->tex_trans->texture->screen; + if (tc->tex_trans) { + struct pipe_screen *screen = tc->tex_trans->texture->screen; + + if (tc->tex_trans_map) { + screen->transfer_unmap(screen, tc->tex_trans); + tc->tex_trans_map = NULL; + } - if (tc->tex_trans_map) { - screen->transfer_unmap(screen, tc->tex_trans); - tc->tex_trans_map = NULL; + screen->tex_transfer_destroy(tc->tex_trans); + tc->tex_trans = NULL; } - screen->tex_transfer_destroy(tc->tex_trans); - tc->tex_trans = NULL; - } + /* mark as entries as invalid/empty */ + /* XXX we should try to avoid this when the teximage hasn't changed */ + for (i = 0; i < NUM_ENTRIES; i++) { + tc->entries[i].x = -1; + } - /* mark as entries as invalid/empty */ - /* XXX we should try to avoid this when the teximage hasn't changed */ - for (i = 0; i < NUM_ENTRIES; i++) { - tc->entries[i].x = -1; + tc->tex_face = -1; /* any invalid value here */ } - - tc->tex_face = -1; /* any invalid value here */ } @@ -443,7 +465,7 @@ sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y) if (tile_x != tile->x || tile_y != tile->y) { - if (tile->x != -1) { + if (tile->x >= 0) { /* put dirty tile back in framebuffer */ if (tc->depth_stencil) { pipe_put_tile_raw(pt, @@ -522,30 +544,24 @@ sp_get_cached_tile_tex(struct softpipe_tile_cache *tc, face, level); struct softpipe_cached_tile *tile = tc->entries + pos; - if (tc->texture) { - struct softpipe_texture *spt = softpipe_texture(tc->texture); - if (spt->modified) { - /* texture was modified, invalidate all cached tiles */ - uint p; - for (p = 0; p < NUM_ENTRIES; p++) { - tile = tc->entries + p; - tile->x = -1; - } - spt->modified = FALSE; - } - } - if (tile_x != tile->x || tile_y != tile->y || z != tile->z || face != tile->face || level != tile->level) { - /* cache miss */ + /* cache miss. Most misses are because we've invaldiated the + * texture cache previously -- most commonly on binding a new + * texture. Currently we effectively flush the cache on texture + * bind. + */ #if 0 - printf("miss at %u x=%d y=%d z=%d face=%d level=%d\n", pos, - x/TILE_SIZE, y/TILE_SIZE, z, face, level); + _debug_printf("miss at %u: x=%d y=%d z=%d face=%d level=%d\n" + " tile %u: x=%d y=%d z=%d face=%d level=%d\n", + pos, x/TILE_SIZE, y/TILE_SIZE, z, face, level, + pos, tile->x, tile->y, tile->z, tile->face, tile->level); #endif + /* check if we need to get a new transfer */ if (!tc->tex_trans || tc->tex_face != face || diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h index 639cde67059..0d165b4ad74 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tile_cache.h @@ -83,6 +83,9 @@ extern void sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, struct pipe_texture *texture); +void +sp_tile_cache_validate_texture(struct softpipe_tile_cache *tc); + extern void sp_flush_tile_cache(struct softpipe_tile_cache *tc); -- cgit v1.2.3 From 73e7356385a703c214b35fbb29aaf3108764f033 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 17 Jul 2009 10:47:32 +0100 Subject: softpipe: simplify flush_spans No loss of performance, but simpler code. --- src/gallium/drivers/softpipe/sp_setup.c | 72 +++++++++------------------------ 1 file changed, 19 insertions(+), 53 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index de3ae3c3696..f29fcbd5a28 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -428,65 +428,31 @@ static void flush_spans( struct setup_context *setup ) int minleft, maxright; int x; - switch (setup->span.y_flags) { - case 0x3: - /* both odd and even lines written (both quad rows) */ - minleft = block(MIN2(xleft0, xleft1)); - maxright = block(MAX2(xright0, xright1)); - for (x = minleft; x <= maxright; x += 2) { - /* determine which of the four pixels is inside the span bounds */ - uint mask = 0x0; - if (x >= xleft0 && x < xright0) - mask |= MASK_TOP_LEFT; - if (x >= xleft1 && x < xright1) - mask |= MASK_BOTTOM_LEFT; - if (x+1 >= xleft0 && x+1 < xright0) - mask |= MASK_TOP_RIGHT; - if (x+1 >= xleft1 && x+1 < xright1) - mask |= MASK_BOTTOM_RIGHT; - if (mask) - EMIT_QUAD( setup, x, setup->span.y, mask ); - } - break; - - case 0x1: - /* only even line written (quad top row) */ - minleft = block(xleft0); - maxright = block(xright0); - for (x = minleft; x <= maxright; x += 2) { - uint mask = 0x0; - if (x >= xleft0 && x < xright0) - mask |= MASK_TOP_LEFT; - if (x+1 >= xleft0 && x+1 < xright0) - mask |= MASK_TOP_RIGHT; - if (mask) - EMIT_QUAD( setup, x, setup->span.y, mask ); - } - break; - - case 0x2: - /* only odd line written (quad bottom row) */ - minleft = block(xleft1); - maxright = block(xright1); - for (x = minleft; x <= maxright; x += 2) { - uint mask = 0x0; - if (x >= xleft1 && x < xright1) - mask |= MASK_BOTTOM_LEFT; - if (x+1 >= xleft1 && x+1 < xright1) - mask |= MASK_BOTTOM_RIGHT; - if (mask) - EMIT_QUAD( setup, x, setup->span.y, mask ); - } - break; - - default: - return; + minleft = block(MIN2(xleft0, xleft1)); + maxright = block(MAX2(xright0, xright1)); + + for (x = minleft; x <= maxright; x += 2) { + /* determine which of the four pixels is inside the span bounds */ + uint mask = 0x0; + if (x >= xleft0 && x < xright0) + mask |= MASK_TOP_LEFT; + if (x >= xleft1 && x < xright1) + mask |= MASK_BOTTOM_LEFT; + if (x+1 >= xleft0 && x+1 < xright0) + mask |= MASK_TOP_RIGHT; + if (x+1 >= xleft1 && x+1 < xright1) + mask |= MASK_BOTTOM_RIGHT; + if (mask) + EMIT_QUAD( setup, x, setup->span.y, mask ); } + setup->span.y = 0; setup->span.y_flags = 0; setup->span.right[0] = 0; setup->span.right[1] = 0; + setup->span.left[0] = 1; /* greater than right[0] */ + setup->span.left[1] = 1; /* greater than right[1] */ } -- cgit v1.2.3 From 0ed99f45529178c77e47838f226231ea1bc9b918 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 17 Jul 2009 12:03:51 +0100 Subject: softpipe: use bitwise logic to setup quad masks in sp_setup --- src/gallium/drivers/softpipe/sp_setup.c | 65 ++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 25 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index f29fcbd5a28..8ac22bd302b 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -388,19 +388,19 @@ emit_quad_job( struct setup_context *setup, uint thread, struct quad_job *job ) emit_quad( setup, &quad, thread ); } -#define EMIT_QUAD(setup,x,y,mask) do {\ +#define EMIT_QUAD(setup,x,y,qmask) do {\ setup->quad.input.x0 = x;\ setup->quad.input.y0 = y;\ - setup->quad.inout.mask = mask;\ + setup->quad.inout.mask = qmask;\ add_quad_job( &setup->que, &setup->quad, emit_quad_job );\ } while (0) #else -#define EMIT_QUAD(setup,x,y,mask) do {\ +#define EMIT_QUAD(setup,x,y,qmask) do {\ setup->quad.input.x0 = x;\ setup->quad.input.y0 = y;\ - setup->quad.inout.mask = mask;\ + setup->quad.inout.mask = qmask;\ emit_quad( setup, &setup->quad, 0 );\ } while (0) @@ -421,29 +421,42 @@ static INLINE int block( int x ) */ static void flush_spans( struct setup_context *setup ) { + const int step = 30; const int xleft0 = setup->span.left[0]; const int xleft1 = setup->span.left[1]; const int xright0 = setup->span.right[0]; const int xright1 = setup->span.right[1]; - int minleft, maxright; + + int minleft = block(MIN2(xleft0, xleft1)); + int maxright = MAX2(xright0, xright1); int x; - minleft = block(MIN2(xleft0, xleft1)); - maxright = block(MAX2(xright0, xright1)); - - for (x = minleft; x <= maxright; x += 2) { - /* determine which of the four pixels is inside the span bounds */ - uint mask = 0x0; - if (x >= xleft0 && x < xright0) - mask |= MASK_TOP_LEFT; - if (x >= xleft1 && x < xright1) - mask |= MASK_BOTTOM_LEFT; - if (x+1 >= xleft0 && x+1 < xright0) - mask |= MASK_TOP_RIGHT; - if (x+1 >= xleft1 && x+1 < xright1) - mask |= MASK_BOTTOM_RIGHT; - if (mask) - EMIT_QUAD( setup, x, setup->span.y, mask ); + for (x = minleft; x < maxright; x += step) { + unsigned skip_left0 = CLAMP(xleft0 - x, 0, step); + unsigned skip_left1 = CLAMP(xleft1 - x, 0, step); + unsigned skip_right0 = CLAMP(x + step - xright0, 0, step); + unsigned skip_right1 = CLAMP(x + step - xright1, 0, step); + unsigned lx = x; + + unsigned skipmask_left0 = (1U << skip_left0) - 1U; + unsigned skipmask_left1 = (1U << skip_left1) - 1U; + + /* These calculations fail when step == 32 and skip_right == 0. + */ + unsigned skipmask_right0 = ~0U << (unsigned)(step - skip_right0); + unsigned skipmask_right1 = ~0U << (unsigned)(step - skip_right1); + + unsigned mask0 = ~skipmask_left0 & ~skipmask_right0; + unsigned mask1 = ~skipmask_left1 & ~skipmask_right1; + + while (mask0 | mask1) { + unsigned quadmask = (mask0 & 3) | ((mask1 & 3) << 2); + if (quadmask) + EMIT_QUAD( setup, lx, setup->span.y, quadmask ); + mask0 >>= 2; + mask1 >>= 2; + lx += 2; + } } @@ -451,8 +464,8 @@ static void flush_spans( struct setup_context *setup ) setup->span.y_flags = 0; setup->span.right[0] = 0; setup->span.right[1] = 0; - setup->span.left[0] = 1; /* greater than right[0] */ - setup->span.left[1] = 1; /* greater than right[1] */ + setup->span.left[0] = 1000000; /* greater than right[0] */ + setup->span.left[1] = 1000000; /* greater than right[1] */ } @@ -810,11 +823,10 @@ static void subtriangle( struct setup_context *setup, /* clip top/bottom */ start_y = sy; - finish_y = sy + lines; - if (start_y < miny) start_y = miny; + finish_y = sy + lines; if (finish_y > maxy) finish_y = maxy; @@ -1495,6 +1507,9 @@ struct setup_context *setup_create_context( struct softpipe_context *softpipe ) setup->quad.coef = setup->coef; setup->quad.posCoef = &setup->posCoef; + setup->span.left[0] = 1000000; /* greater than right[0] */ + setup->span.left[1] = 1000000; /* greater than right[1] */ + #if SP_NUM_QUAD_THREADS > 1 setup->que.first = 0; setup->que.last = 0; -- cgit v1.2.3 From 13e2d35764e0c8de3356ee663885568fc00424f0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 17 Jul 2009 12:12:04 +0100 Subject: softpipe: remove unused vars in sp_setup.c --- src/gallium/drivers/softpipe/sp_setup.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 8ac22bd302b..d05c9ad57c4 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -178,8 +178,6 @@ struct setup_context { int left[2]; /**< [0] = row0, [1] = row1 */ int right[2]; int y; - unsigned y_flags; - unsigned mask; /**< mask of MASK_BOTTOM/TOP_LEFT/RIGHT bits */ } span; #if DEBUG_FRAGS @@ -461,7 +459,6 @@ static void flush_spans( struct setup_context *setup ) setup->span.y = 0; - setup->span.y_flags = 0; setup->span.right[0] = 0; setup->span.right[1] = 0; setup->span.left[0] = 1000000; /* greater than right[0] */ @@ -863,7 +860,6 @@ static void subtriangle( struct setup_context *setup, setup->span.left[_y&1] = left; setup->span.right[_y&1] = right; - setup->span.y_flags |= 1<<(_y&1); } } @@ -939,7 +935,6 @@ void setup_tri( struct setup_context *setup, setup->quad.input.prim = QUAD_PRIM_TRI; setup->span.y = 0; - setup->span.y_flags = 0; setup->span.right[0] = 0; setup->span.right[1] = 0; /* setup->span.z_mode = tri_z_mode( setup->ctx ); */ -- cgit v1.2.3 From f911c3b9897b90132c8621a72bfeb824eb3b01e5 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 22 Jul 2009 15:08:42 +0100 Subject: softpipe: shortcircuit repeated lookups of the same tile The sp_tile_cache is often called repeatedly to look up the same tile. Add a cache (to the cache) of the single tile most recently retreived and make a quick inline check to see if this matches the subsequent request. Add a tile_address bitfield struct to make this check easier. --- src/gallium/auxiliary/util/u_math.h | 12 +++ src/gallium/drivers/softpipe/sp_tex_sample.c | 12 ++- src/gallium/drivers/softpipe/sp_tile_cache.c | 153 ++++++++++++--------------- src/gallium/drivers/softpipe/sp_tile_cache.h | 88 ++++++++++++++- 4 files changed, 168 insertions(+), 97 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h index e5003af01d8..d30fa3c2d59 100644 --- a/src/gallium/auxiliary/util/u_math.h +++ b/src/gallium/auxiliary/util/u_math.h @@ -366,6 +366,18 @@ unsigned ffs( unsigned u ) #endif +/* Could also binary search for the highest bit. + */ +static INLINE unsigned +util_unsigned_logbase2(unsigned n) +{ + unsigned log2 = 0; + while (n >>= 1) + ++log2; + return log2; +} + + /** * Return float bits. */ diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 3daa88eedda..46c56b0c835 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -680,11 +680,13 @@ get_texel(const struct tgsi_sampler *tgsi_sampler, rgba[3][j] = sampler->border_color[3]; } else { - const int tx = x % TILE_SIZE; - const int ty = y % TILE_SIZE; - const struct softpipe_cached_tile *tile - = sp_get_cached_tile_tex(samp->cache, - x, y, z, face, level); + const unsigned tx = x % TILE_SIZE; + const unsigned ty = y % TILE_SIZE; + const struct softpipe_cached_tile *tile; + + tile = sp_get_cached_tile_tex(samp->cache, + tile_address(x, y, z, face, level)); + rgba[0][j] = tile->data.color[ty][tx][0]; rgba[1][j] = tile->data.color[ty][tx][1]; rgba[2][j] = tile->data.color[ty][tx][2]; diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 79b1e036be8..06d9c6a80ab 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -40,36 +40,6 @@ #include "sp_texture.h" #include "sp_tile_cache.h" -#define NUM_ENTRIES 50 - - -/** XXX move these */ -#define MAX_WIDTH 2048 -#define MAX_HEIGHT 2048 - - -struct softpipe_tile_cache -{ - struct pipe_screen *screen; - struct pipe_surface *surface; /**< the surface we're caching */ - struct pipe_transfer *transfer; - void *transfer_map; - - struct pipe_texture *texture; /**< if caching a texture */ - unsigned timestamp; - - struct softpipe_cached_tile entries[NUM_ENTRIES]; - uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32]; - float clear_color[4]; /**< for color bufs */ - uint clear_val; /**< for z+stencil, or packed color clear value */ - boolean depth_stencil; /**< Is the surface a depth/stencil format? */ - - struct pipe_transfer *tex_trans; - void *tex_trans_map; - int tex_face, tex_level, tex_z; - - struct softpipe_cached_tile tile; /**< scratch tile for clears */ -}; /** @@ -124,9 +94,9 @@ sp_create_tile_cache( struct pipe_screen *screen ) if (tc) { tc->screen = screen; for (pos = 0; pos < NUM_ENTRIES; pos++) { - tc->entries[pos].x = - tc->entries[pos].y = -1; + tc->entries[pos].addr.bits.invalid = 1; } + tc->last_tile = &tc->entries[0]; /* any tile */ } return tc; } @@ -244,7 +214,7 @@ sp_tile_cache_validate_texture(struct softpipe_tile_cache *tc) uint i; _debug_printf("INV %d %d\n", tc->timestamp, spt->timestamp); for (i = 0; i < NUM_ENTRIES; i++) { - tc->entries[i].x = -3; + tc->entries[i].addr.bits.invalid = 1; } tc->timestamp = spt->timestamp; @@ -281,7 +251,7 @@ sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, /* mark as entries as invalid/empty */ /* XXX we should try to avoid this when the teximage hasn't changed */ for (i = 0; i < NUM_ENTRIES; i++) { - tc->entries[i].x = -1; + tc->entries[i].addr.bits.invalid = 1; } tc->tex_face = -1; /* any invalid value here */ @@ -411,18 +381,22 @@ sp_flush_tile_cache(struct softpipe_tile_cache *tc) /* caching a drawing transfer */ for (pos = 0; pos < NUM_ENTRIES; pos++) { struct softpipe_cached_tile *tile = tc->entries + pos; - if (tile->x >= 0) { + if (!tile->addr.bits.invalid) { if (tc->depth_stencil) { pipe_put_tile_raw(pt, - tile->x, tile->y, TILE_SIZE, TILE_SIZE, + tile->addr.bits.x * TILE_SIZE, + tile->addr.bits.y * TILE_SIZE, + TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); } else { pipe_put_tile_rgba(pt, - tile->x, tile->y, TILE_SIZE, TILE_SIZE, + tile->addr.bits.x * TILE_SIZE, + tile->addr.bits.y * TILE_SIZE, + TILE_SIZE, TILE_SIZE, (float *) tile->data.color); } - tile->x = tile->y = -1; /* mark as empty */ + tile->addr.bits.invalid = 1; /* mark as empty */ inuse++; } } @@ -434,7 +408,7 @@ sp_flush_tile_cache(struct softpipe_tile_cache *tc) else if (tc->texture) { /* caching a texture, mark all entries as empty */ for (pos = 0; pos < NUM_ENTRIES; pos++) { - tc->entries[pos].x = -1; + tc->entries[pos].addr.bits.invalid = 1; } tc->tex_face = -1; } @@ -453,34 +427,34 @@ struct softpipe_cached_tile * sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y) { struct pipe_transfer *pt = tc->transfer; - + /* tile pos in framebuffer: */ - const int tile_x = x & ~(TILE_SIZE - 1); - const int tile_y = y & ~(TILE_SIZE - 1); - + union tile_address addr = tile_address( x, y, 0, 0, 0 ); /* cache pos/entry: */ const int pos = CACHE_POS(x, y); struct softpipe_cached_tile *tile = tc->entries + pos; - if (tile_x != tile->x || - tile_y != tile->y) { + if (addr.value != tile->addr.value) { - if (tile->x >= 0) { + if (tile->addr.bits.invalid == 0) { /* put dirty tile back in framebuffer */ if (tc->depth_stencil) { pipe_put_tile_raw(pt, - tile->x, tile->y, TILE_SIZE, TILE_SIZE, + tile->addr.bits.x * TILE_SIZE, + tile->addr.bits.y * TILE_SIZE, + TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); } else { pipe_put_tile_rgba(pt, - tile->x, tile->y, TILE_SIZE, TILE_SIZE, + tile->addr.bits.x * TILE_SIZE, + tile->addr.bits.y * TILE_SIZE, + TILE_SIZE, TILE_SIZE, (float *) tile->data.color); } } - tile->x = tile_x; - tile->y = tile_y; + tile->addr = addr; if (is_clear_flag_set(tc->clear_flags, x, y)) { /* don't get tile from framebuffer, just clear it */ @@ -496,12 +470,16 @@ sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y) /* get new tile data from transfer */ if (tc->depth_stencil) { pipe_get_tile_raw(pt, - tile->x, tile->y, TILE_SIZE, TILE_SIZE, + tile->addr.bits.x * TILE_SIZE, + tile->addr.bits.y * TILE_SIZE, + TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); } else { pipe_get_tile_rgba(pt, - tile->x, tile->y, TILE_SIZE, TILE_SIZE, + tile->addr.bits.x * TILE_SIZE, + tile->addr.bits.y * TILE_SIZE, + TILE_SIZE, TILE_SIZE, (float *) tile->data.color); } } @@ -519,36 +497,31 @@ sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y) * XXX There's probably lots of ways in which we can improve this. */ static INLINE uint -tex_cache_pos(int x, int y, int z, int face, int level) +tex_cache_pos( union tile_address addr ) { - uint entry = x + y * 9 + z * 3 + face + level * 7; + uint entry = (addr.bits.x + + addr.bits.y * 9 + + addr.bits.z * 3 + + addr.bits.face + + addr.bits.level * 7); + return entry % NUM_ENTRIES; } - /** * Similar to sp_get_cached_tile() but for textures. * Tiles are read-only and indexed with more params. */ const struct softpipe_cached_tile * -sp_get_cached_tile_tex(struct softpipe_tile_cache *tc, - int x, int y, int z, - int face, int level) +sp_find_cached_tile_tex(struct softpipe_tile_cache *tc, + union tile_address addr ) { struct pipe_screen *screen = tc->screen; - /* tile pos in framebuffer: */ - const int tile_x = x & ~(TILE_SIZE - 1); - const int tile_y = y & ~(TILE_SIZE - 1); - /* cache pos/entry: */ - const uint pos = tex_cache_pos(x / TILE_SIZE, y / TILE_SIZE, z, - face, level); - struct softpipe_cached_tile *tile = tc->entries + pos; + struct softpipe_cached_tile *tile; + + tile = tc->entries + tex_cache_pos( addr ); - if (tile_x != tile->x || - tile_y != tile->y || - z != tile->z || - face != tile->face || - level != tile->level) { + if (addr.value != tile->addr.value) { /* cache miss. Most misses are because we've invaldiated the * texture cache previously -- most commonly on binding a new @@ -559,14 +532,14 @@ sp_get_cached_tile_tex(struct softpipe_tile_cache *tc, _debug_printf("miss at %u: x=%d y=%d z=%d face=%d level=%d\n" " tile %u: x=%d y=%d z=%d face=%d level=%d\n", pos, x/TILE_SIZE, y/TILE_SIZE, z, face, level, - pos, tile->x, tile->y, tile->z, tile->face, tile->level); + pos, tile->addr.bits.x, tile->addr.bits.y, tile->z, tile->face, tile->level); #endif /* check if we need to get a new transfer */ if (!tc->tex_trans || - tc->tex_face != face || - tc->tex_level != level || - tc->tex_z != z) { + tc->tex_face != addr.bits.face || + tc->tex_level != addr.bits.level || + tc->tex_z != addr.bits.z) { /* get new transfer (view into texture) */ if (tc->tex_trans) { @@ -579,28 +552,32 @@ sp_get_cached_tile_tex(struct softpipe_tile_cache *tc, tc->tex_trans = NULL; } - tc->tex_trans = screen->get_tex_transfer(screen, tc->texture, face, level, z, - PIPE_TRANSFER_READ, 0, 0, - tc->texture->width[level], - tc->texture->height[level]); + tc->tex_trans = + screen->get_tex_transfer(screen, tc->texture, + addr.bits.face, + addr.bits.level, + addr.bits.z, + PIPE_TRANSFER_READ, 0, 0, + tc->texture->width[addr.bits.level], + tc->texture->height[addr.bits.level]); + tc->tex_trans_map = screen->transfer_map(screen, tc->tex_trans); - tc->tex_face = face; - tc->tex_level = level; - tc->tex_z = z; + tc->tex_face = addr.bits.face; + tc->tex_level = addr.bits.level; + tc->tex_z = addr.bits.z; } /* get tile from the transfer (view into texture) */ pipe_get_tile_rgba(tc->tex_trans, - tile_x, tile_y, TILE_SIZE, TILE_SIZE, + addr.bits.x * TILE_SIZE, + addr.bits.y * TILE_SIZE, + TILE_SIZE, TILE_SIZE, (float *) tile->data.color); - tile->x = tile_x; - tile->y = tile_y; - tile->z = z; - tile->face = face; - tile->level = level; + tile->addr = addr; } + tc->last_tile = tile; return tile; } @@ -633,6 +610,6 @@ sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float *rgba, for (pos = 0; pos < NUM_ENTRIES; pos++) { struct softpipe_cached_tile *tile = tc->entries + pos; - tile->x = tile->y = -1; + tile->addr.bits.invalid = 1; } } diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h index 0d165b4ad74..3017fcbebc9 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tile_cache.h @@ -44,11 +44,25 @@ struct softpipe_tile_cache; #define TILE_SIZE 64 +/* If we need to support > 4096, just expand this to be a 64 bit + * union, or consider tiling in Z as well. + */ +union tile_address { + struct { + unsigned x:6; /* 4096 / TILE_SIZE */ + unsigned y:6; /* 4096 / TILE_SIZE */ + unsigned z:12; /* 4096 -- z not tiled */ + unsigned face:3; + unsigned level:4; + unsigned invalid:1; + } bits; + unsigned value; +}; + struct softpipe_cached_tile { - int x, y; /**< pos of tile in window coords */ - int z, face, level; /**< Extra texture indexes */ + union tile_address addr; union { float color[TILE_SIZE][TILE_SIZE][4]; uint color32[TILE_SIZE][TILE_SIZE]; @@ -59,6 +73,39 @@ struct softpipe_cached_tile } data; }; +#define NUM_ENTRIES 50 + + +/** XXX move these */ +#define MAX_WIDTH 2048 +#define MAX_HEIGHT 2048 + + +struct softpipe_tile_cache +{ + struct pipe_screen *screen; + struct pipe_surface *surface; /**< the surface we're caching */ + struct pipe_transfer *transfer; + void *transfer_map; + + struct pipe_texture *texture; /**< if caching a texture */ + unsigned timestamp; + + struct softpipe_cached_tile entries[NUM_ENTRIES]; + uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32]; + float clear_color[4]; /**< for color bufs */ + uint clear_val; /**< for z+stencil, or packed color clear value */ + boolean depth_stencil; /**< Is the surface a depth/stencil format? */ + + struct pipe_transfer *tex_trans; + void *tex_trans_map; + int tex_face, tex_level, tex_z; + + struct softpipe_cached_tile tile; /**< scratch tile for clears */ + + struct softpipe_cached_tile *last_tile; /**< most recently retrieved tile */ +}; + extern struct softpipe_tile_cache * sp_create_tile_cache( struct pipe_screen *screen ); @@ -97,8 +144,41 @@ extern struct softpipe_cached_tile * sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y); extern const struct softpipe_cached_tile * -sp_get_cached_tile_tex(struct softpipe_tile_cache *tc, int x, int y, int z, - int face, int level); +sp_find_cached_tile_tex(struct softpipe_tile_cache *tc, + union tile_address addr ); + +static INLINE const union tile_address +tile_address( unsigned x, + unsigned y, + unsigned z, + unsigned face, + unsigned level ) +{ + union tile_address addr; + + addr.value = 0; + addr.bits.x = x / TILE_SIZE; + addr.bits.y = y / TILE_SIZE; + addr.bits.z = z; + addr.bits.face = face; + addr.bits.level = level; + + return addr; +} + +/* Quickly retrieve tile if it matches last lookup. + */ +static INLINE const struct softpipe_cached_tile * +sp_get_cached_tile_tex(struct softpipe_tile_cache *tc, + union tile_address addr ) +{ + if (tc->last_tile->addr.value == addr.value) + return tc->last_tile; + + return sp_find_cached_tile_tex( tc, addr ); +} + + #endif /* SP_TILE_CACHE_H */ -- cgit v1.2.3 From 19097907ef042b97bbbda39b34bf3212f4cf154a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 22 Jul 2009 15:36:25 +0100 Subject: softpipe: also shortcircuit non-texture tile lookups --- src/gallium/drivers/softpipe/sp_tile_cache.c | 33 ++++++++++++++-------------- src/gallium/drivers/softpipe/sp_tile_cache.h | 16 +++++++++++++- 2 files changed, 31 insertions(+), 18 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 06d9c6a80ab..77d02fa3e7a 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -49,7 +49,7 @@ * a LRU replacement policy. */ #define CACHE_POS(x, y) \ - (((x) / TILE_SIZE + ((y) / TILE_SIZE) * 5) % NUM_ENTRIES) + (((x) + (y) * 5) % NUM_ENTRIES) @@ -57,12 +57,10 @@ * Is the tile at (x,y) in cleared state? */ static INLINE uint -is_clear_flag_set(const uint *bitvec, int x, int y) +is_clear_flag_set(const uint *bitvec, union tile_address addr) { int pos, bit; - x /= TILE_SIZE; - y /= TILE_SIZE; - pos = y * (MAX_WIDTH / TILE_SIZE) + x; + pos = addr.bits.y * (MAX_WIDTH / TILE_SIZE) + addr.bits.x; assert(pos / 32 < (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32); bit = bitvec[pos / 32] & (1 << (pos & 31)); return bit; @@ -73,12 +71,10 @@ is_clear_flag_set(const uint *bitvec, int x, int y) * Mark the tile at (x,y) as not cleared. */ static INLINE void -clear_clear_flag(uint *bitvec, int x, int y) +clear_clear_flag(uint *bitvec, union tile_address addr) { int pos; - x /= TILE_SIZE; - y /= TILE_SIZE; - pos = y * (MAX_WIDTH / TILE_SIZE) + x; + pos = addr.bits.y * (MAX_WIDTH / TILE_SIZE) + addr.bits.x; assert(pos / 32 < (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32); bitvec[pos / 32] &= ~(1 << (pos & 31)); } @@ -349,13 +345,15 @@ sp_tile_cache_flush_clear(struct softpipe_tile_cache *tc) /* push the tile to all positions marked as clear */ for (y = 0; y < h; y += TILE_SIZE) { for (x = 0; x < w; x += TILE_SIZE) { - if (is_clear_flag_set(tc->clear_flags, x, y)) { + union tile_address addr = tile_address(x, y, 0, 0, 0); + + if (is_clear_flag_set(tc->clear_flags, addr)) { pipe_put_tile_raw(pt, x, y, TILE_SIZE, TILE_SIZE, tc->tile.data.color32, 0/*STRIDE*/); /* do this? */ - clear_clear_flag(tc->clear_flags, x, y); + clear_clear_flag(tc->clear_flags, addr); numCleared++; } @@ -424,14 +422,14 @@ sp_flush_tile_cache(struct softpipe_tile_cache *tc) * \param x, y position of tile, in pixels */ struct softpipe_cached_tile * -sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y) +sp_find_cached_tile(struct softpipe_tile_cache *tc, + union tile_address addr ) { struct pipe_transfer *pt = tc->transfer; - /* tile pos in framebuffer: */ - union tile_address addr = tile_address( x, y, 0, 0, 0 ); /* cache pos/entry: */ - const int pos = CACHE_POS(x, y); + const int pos = CACHE_POS(addr.bits.x, + addr.bits.y); struct softpipe_cached_tile *tile = tc->entries + pos; if (addr.value != tile->addr.value) { @@ -456,7 +454,7 @@ sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y) tile->addr = addr; - if (is_clear_flag_set(tc->clear_flags, x, y)) { + if (is_clear_flag_set(tc->clear_flags, addr)) { /* don't get tile from framebuffer, just clear it */ if (tc->depth_stencil) { clear_tile(tile, pt->format, tc->clear_val); @@ -464,7 +462,7 @@ sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y) else { clear_tile_rgba(tile, pt->format, tc->clear_color); } - clear_clear_flag(tc->clear_flags, x, y); + clear_clear_flag(tc->clear_flags, addr); } else { /* get new tile data from transfer */ @@ -485,6 +483,7 @@ sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y) } } + tc->last_tile = tile; return tile; } diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h index 3017fcbebc9..ac2aae58758 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tile_cache.h @@ -141,7 +141,8 @@ sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float *rgba, uint clearValue); extern struct softpipe_cached_tile * -sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y); +sp_find_cached_tile(struct softpipe_tile_cache *tc, + union tile_address addr ); extern const struct softpipe_cached_tile * sp_find_cached_tile_tex(struct softpipe_tile_cache *tc, @@ -179,6 +180,19 @@ sp_get_cached_tile_tex(struct softpipe_tile_cache *tc, } +static INLINE struct softpipe_cached_tile * +sp_get_cached_tile(struct softpipe_tile_cache *tc, + int x, int y ) +{ + union tile_address addr = tile_address( x, y, 0, 0, 0 ); + + if (tc->last_tile->addr.value == addr.value) + return tc->last_tile; + + return sp_find_cached_tile( tc, addr ); +} + + #endif /* SP_TILE_CACHE_H */ -- cgit v1.2.3 From 93a026d4baf90266f4c9cc48d039b4d65ce1ab6d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 23 Jul 2009 11:14:39 +0100 Subject: softpipe: avoid flushing depth buffer cache on swapbuffers There's no need to push out depth buffer contents on swapbuffers. Note that this change doesn't throw away depth buffer changes, it simply holds them in the cache over calls to swapbuffers. The hope is that swapbuffers will be followed by a clear() which means in that case we won't have to write the changes out. --- src/gallium/drivers/softpipe/sp_context.c | 5 +---- src/gallium/drivers/softpipe/sp_flush.c | 20 +++++++++++++++----- 2 files changed, 16 insertions(+), 9 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index f085889d3a0..1b2c6aded0e 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -72,13 +72,10 @@ softpipe_unmap_transfers(struct softpipe_context *sp) { uint i; - for (i = 0; i < sp->framebuffer.nr_cbufs; i++) - sp_flush_tile_cache(sp->cbuf_cache[i]); - sp_flush_tile_cache(sp->zsbuf_cache); - for (i = 0; i < sp->framebuffer.nr_cbufs; i++) { sp_tile_cache_unmap_transfers(sp->cbuf_cache[i]); } + sp_tile_cache_unmap_transfers(sp->zsbuf_cache); } diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index 732277a2c58..679ad0cd3d4 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -56,14 +56,16 @@ softpipe_flush( struct pipe_context *pipe, } } - if (flags & PIPE_FLUSH_RENDER_CACHE) { + if (flags & PIPE_FLUSH_SWAPBUFFERS) { + /* If this is a swapbuffers, just flush color buffers. + * + * The zbuffer changes are not discarded, but held in the cache + * in the hope that a later clear will wipe them out. + */ for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) if (softpipe->cbuf_cache[i]) sp_flush_tile_cache(softpipe->cbuf_cache[i]); - if (softpipe->zsbuf_cache) - sp_flush_tile_cache(softpipe->zsbuf_cache); - /* Need this call for hardware buffers before swapbuffers. * * there should probably be another/different flush-type function @@ -71,7 +73,15 @@ softpipe_flush( struct pipe_context *pipe, * to unmap surfaces when flushing. */ softpipe_unmap_transfers(softpipe); - + } + else if (flags & PIPE_FLUSH_RENDER_CACHE) { + for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) + if (softpipe->cbuf_cache[i]) + sp_flush_tile_cache(softpipe->cbuf_cache[i]); + + if (softpipe->zsbuf_cache) + sp_flush_tile_cache(softpipe->zsbuf_cache); + softpipe->dirty_render_cache = FALSE; } -- cgit v1.2.3 From 6153a1c28f118be1a74ffee0e19c16fb83b5cab7 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 24 Jul 2009 16:12:48 +0100 Subject: softpipe: rip out old mulithread support --- src/gallium/drivers/softpipe/sp_context.c | 48 +++--- src/gallium/drivers/softpipe/sp_context.h | 13 +- src/gallium/drivers/softpipe/sp_quad_pipe.c | 48 ++---- src/gallium/drivers/softpipe/sp_setup.c | 253 ++-------------------------- 4 files changed, 57 insertions(+), 305 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 1b2c6aded0e..4418ef0ff4c 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -88,19 +88,17 @@ static void softpipe_destroy( struct pipe_context *pipe ) if (softpipe->draw) draw_destroy( softpipe->draw ); - for (i = 0; i < SP_NUM_QUAD_THREADS; i++) { - softpipe->quad[i].polygon_stipple->destroy( softpipe->quad[i].polygon_stipple ); - softpipe->quad[i].earlyz->destroy( softpipe->quad[i].earlyz ); - softpipe->quad[i].shade->destroy( softpipe->quad[i].shade ); - softpipe->quad[i].alpha_test->destroy( softpipe->quad[i].alpha_test ); - softpipe->quad[i].depth_test->destroy( softpipe->quad[i].depth_test ); - softpipe->quad[i].stencil_test->destroy( softpipe->quad[i].stencil_test ); - softpipe->quad[i].occlusion->destroy( softpipe->quad[i].occlusion ); - softpipe->quad[i].coverage->destroy( softpipe->quad[i].coverage ); - softpipe->quad[i].blend->destroy( softpipe->quad[i].blend ); - softpipe->quad[i].colormask->destroy( softpipe->quad[i].colormask ); - softpipe->quad[i].output->destroy( softpipe->quad[i].output ); - } + softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple ); + softpipe->quad.earlyz->destroy( softpipe->quad.earlyz ); + softpipe->quad.shade->destroy( softpipe->quad.shade ); + softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test ); + softpipe->quad.depth_test->destroy( softpipe->quad.depth_test ); + softpipe->quad.stencil_test->destroy( softpipe->quad.stencil_test ); + softpipe->quad.occlusion->destroy( softpipe->quad.occlusion ); + softpipe->quad.coverage->destroy( softpipe->quad.coverage ); + softpipe->quad.blend->destroy( softpipe->quad.blend ); + softpipe->quad.colormask->destroy( softpipe->quad.colormask ); + softpipe->quad.output->destroy( softpipe->quad.output ); for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) sp_destroy_tile_cache(softpipe->cbuf_cache[i]); @@ -234,19 +232,17 @@ softpipe_create( struct pipe_screen *screen ) /* setup quad rendering stages */ - for (i = 0; i < SP_NUM_QUAD_THREADS; i++) { - softpipe->quad[i].polygon_stipple = sp_quad_polygon_stipple_stage(softpipe); - softpipe->quad[i].earlyz = sp_quad_earlyz_stage(softpipe); - softpipe->quad[i].shade = sp_quad_shade_stage(softpipe); - softpipe->quad[i].alpha_test = sp_quad_alpha_test_stage(softpipe); - softpipe->quad[i].depth_test = sp_quad_depth_test_stage(softpipe); - softpipe->quad[i].stencil_test = sp_quad_stencil_test_stage(softpipe); - softpipe->quad[i].occlusion = sp_quad_occlusion_stage(softpipe); - softpipe->quad[i].coverage = sp_quad_coverage_stage(softpipe); - softpipe->quad[i].blend = sp_quad_blend_stage(softpipe); - softpipe->quad[i].colormask = sp_quad_colormask_stage(softpipe); - softpipe->quad[i].output = sp_quad_output_stage(softpipe); - } + softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe); + softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe); + softpipe->quad.shade = sp_quad_shade_stage(softpipe); + softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe); + softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe); + softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe); + softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe); + softpipe->quad.coverage = sp_quad_coverage_stage(softpipe); + softpipe->quad.blend = sp_quad_blend_stage(softpipe); + softpipe->quad.colormask = sp_quad_colormask_stage(softpipe); + softpipe->quad.output = sp_quad_output_stage(softpipe); /* vertex shader samplers */ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index f66f0b7849d..414d903a376 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -39,17 +39,6 @@ #include "sp_tex_sample.h" -/** - * This is a temporary variable for testing draw-stage polygon stipple. - * If zero, do stipple in sp_quad_stipple.c - */ -#define USE_DRAW_STAGE_PSTIPPLE 1 - -/* Number of threads working on individual quads. - * Setting to 1 disables this feature. - */ -#define SP_NUM_QUAD_THREADS 1 - struct softpipe_vbuf_render; struct draw_context; struct draw_stage; @@ -129,7 +118,7 @@ struct softpipe_context { struct quad_stage *output; struct quad_stage *first; /**< points to one of the above stages */ - } quad[SP_NUM_QUAD_THREADS]; + } quad; /** TGSI exec things */ struct { diff --git a/src/gallium/drivers/softpipe/sp_quad_pipe.c b/src/gallium/drivers/softpipe/sp_quad_pipe.c index b5f69b74264..3a3359d303d 100644 --- a/src/gallium/drivers/softpipe/sp_quad_pipe.c +++ b/src/gallium/drivers/softpipe/sp_quad_pipe.c @@ -31,35 +31,29 @@ #include "pipe/p_shader_tokens.h" static void -sp_push_quad_first( - struct softpipe_context *sp, - struct quad_stage *quad, - uint i ) +sp_push_quad_first( struct softpipe_context *sp, + struct quad_stage *quad ) { - quad->next = sp->quad[i].first; - sp->quad[i].first = quad; + quad->next = sp->quad.first; + sp->quad.first = quad; } static void -sp_build_depth_stencil( - struct softpipe_context *sp, - uint i ) +sp_build_depth_stencil( struct softpipe_context *sp ) { if (sp->depth_stencil->stencil[0].enabled || sp->depth_stencil->stencil[1].enabled) { - sp_push_quad_first( sp, sp->quad[i].stencil_test, i ); + sp_push_quad_first( sp, sp->quad.stencil_test ); } else if (sp->depth_stencil->depth.enabled && sp->framebuffer.zsbuf) { - sp_push_quad_first( sp, sp->quad[i].depth_test, i ); + sp_push_quad_first( sp, sp->quad.depth_test ); } } void sp_build_quad_pipeline(struct softpipe_context *sp) { - uint i; - boolean early_depth_test = sp->depth_stencil->depth.enabled && sp->framebuffer.zsbuf && @@ -68,51 +62,43 @@ sp_build_quad_pipeline(struct softpipe_context *sp) !sp->fs->info.writes_z; /* build up the pipeline in reverse order... */ - for (i = 0; i < SP_NUM_QUAD_THREADS; i++) { - sp->quad[i].first = sp->quad[i].output; + sp->quad.first = sp->quad.output; if (sp->blend->colormask != 0xf) { - sp_push_quad_first( sp, sp->quad[i].colormask, i ); + sp_push_quad_first( sp, sp->quad.colormask ); } if (sp->blend->blend_enable || sp->blend->logicop_enable) { - sp_push_quad_first( sp, sp->quad[i].blend, i ); + sp_push_quad_first( sp, sp->quad.blend ); } if (sp->active_query_count) { - sp_push_quad_first( sp, sp->quad[i].occlusion, i ); + sp_push_quad_first( sp, sp->quad.occlusion ); } if (sp->rasterizer->poly_smooth || sp->rasterizer->line_smooth || sp->rasterizer->point_smooth) { - sp_push_quad_first( sp, sp->quad[i].coverage, i ); + sp_push_quad_first( sp, sp->quad.coverage ); } if (!early_depth_test) { - sp_build_depth_stencil( sp, i ); + sp_build_depth_stencil( sp ); } if (sp->depth_stencil->alpha.enabled) { - sp_push_quad_first( sp, sp->quad[i].alpha_test, i ); + sp_push_quad_first( sp, sp->quad.alpha_test ); } /* XXX always enable shader? */ if (1) { - sp_push_quad_first( sp, sp->quad[i].shade, i ); + sp_push_quad_first( sp, sp->quad.shade ); } if (early_depth_test) { - sp_build_depth_stencil( sp, i ); - sp_push_quad_first( sp, sp->quad[i].earlyz, i ); - } - -#if !USE_DRAW_STAGE_PSTIPPLE - if (sp->rasterizer->poly_stipple_enable) { - sp_push_quad_first( sp, sp->quad[i].polygon_stipple, i ); + sp_build_depth_stencil( sp ); + sp_push_quad_first( sp, sp->quad.earlyz ); } -#endif - } } diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index d05c9ad57c4..eaf84ed9de9 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -61,87 +61,7 @@ struct edge { int lines; /**< number of lines on this edge */ }; -#if SP_NUM_QUAD_THREADS > 1 -/* Set to 1 if you want other threads to be instantly - * notified of pending jobs. - */ -#define INSTANT_NOTEMPTY_NOTIFY 0 - -struct thread_info -{ - struct setup_context *setup; - uint id; - pipe_thread handle; -}; - -struct quad_job; - -typedef void (* quad_job_routine)( struct setup_context *setup, uint thread, struct quad_job *job ); - -struct quad_job -{ - struct quad_header_input input; - struct quad_header_inout inout; - quad_job_routine routine; -}; - -#define NUM_QUAD_JOBS 64 - -struct quad_job_que -{ - struct quad_job jobs[NUM_QUAD_JOBS]; - uint first; - uint last; - pipe_mutex que_mutex; - pipe_condvar que_notfull_condvar; - pipe_condvar que_notempty_condvar; - uint jobs_added; - uint jobs_done; - pipe_condvar que_done_condvar; -}; - -static void -add_quad_job( struct quad_job_que *que, struct quad_header *quad, quad_job_routine routine ) -{ -#if INSTANT_NOTEMPTY_NOTIFY - boolean empty; -#endif - - /* Wait for empty slot, see if the que is empty. - */ - pipe_mutex_lock( que->que_mutex ); - while ((que->last + 1) % NUM_QUAD_JOBS == que->first) { -#if !INSTANT_NOTEMPTY_NOTIFY - pipe_condvar_broadcast( que->que_notempty_condvar ); -#endif - pipe_condvar_wait( que->que_notfull_condvar, que->que_mutex ); - } -#if INSTANT_NOTEMPTY_NOTIFY - empty = que->last == que->first; -#endif - que->jobs_added++; - pipe_mutex_unlock( que->que_mutex ); - - /* Submit new job. - */ - que->jobs[que->last].input = quad->input; - que->jobs[que->last].inout = quad->inout; - que->jobs[que->last].routine = routine; - que->last = (que->last + 1) % NUM_QUAD_JOBS; - -#if INSTANT_NOTEMPTY_NOTIFY - /* If the que was empty, notify consumers there's a job to be done. - */ - if (empty) { - pipe_mutex_lock( que->que_mutex ); - pipe_condvar_broadcast( que->que_notempty_condvar ); - pipe_mutex_unlock( que->que_mutex ); - } -#endif -} - -#endif /** * Triangle setup info (derived from draw_stage). @@ -169,11 +89,6 @@ struct setup_context { struct tgsi_interp_coef posCoef; /* For Z, W */ struct quad_header quad; -#if SP_NUM_QUAD_THREADS > 1 - struct quad_job_que que; - struct thread_info threads[SP_NUM_QUAD_THREADS]; -#endif - struct { int left[2]; /**< [0] = row0, [1] = row1 */ int right[2]; @@ -188,67 +103,6 @@ struct setup_context { unsigned winding; /* which winding to cull */ }; -#if SP_NUM_QUAD_THREADS > 1 - -static PIPE_THREAD_ROUTINE( quad_thread, param ) -{ - struct thread_info *info = (struct thread_info *) param; - struct quad_job_que *que = &info->setup->que; - - for (;;) { - struct quad_job job; - boolean full; - - /* Wait for an available job. - */ - pipe_mutex_lock( que->que_mutex ); - while (que->last == que->first) - pipe_condvar_wait( que->que_notempty_condvar, que->que_mutex ); - - /* See if the que is full. - */ - full = (que->last + 1) % NUM_QUAD_JOBS == que->first; - - /* Take a job and remove it from que. - */ - job = que->jobs[que->first]; - que->first = (que->first + 1) % NUM_QUAD_JOBS; - - /* Notify the producer if the que is not full. - */ - if (full) - pipe_condvar_signal( que->que_notfull_condvar ); - pipe_mutex_unlock( que->que_mutex ); - - job.routine( info->setup, info->id, &job ); - - /* Notify the producer if that's the last finished job. - */ - pipe_mutex_lock( que->que_mutex ); - que->jobs_done++; - if (que->jobs_added == que->jobs_done) - pipe_condvar_signal( que->que_done_condvar ); - pipe_mutex_unlock( que->que_mutex ); - } - - return NULL; -} - -#define WAIT_FOR_COMPLETION(setup) \ - do {\ - pipe_mutex_lock( setup->que.que_mutex );\ - if (!INSTANT_NOTEMPTY_NOTIFY)\ - pipe_condvar_broadcast( setup->que.que_notempty_condvar );\ - while (setup->que.jobs_added != setup->que.jobs_done)\ - pipe_condvar_wait( setup->que.que_done_condvar, setup->que.que_mutex );\ - pipe_mutex_unlock( setup->que.que_mutex );\ - } while (0) - -#else - -#define WAIT_FOR_COMPLETION(setup) ((void) 0) - -#endif @@ -311,39 +165,17 @@ quad_clip( struct setup_context *setup, struct quad_header *quad ) * Emit a quad (pass to next stage) with clipping. */ static INLINE void -clip_emit_quad( struct setup_context *setup, struct quad_header *quad, uint thread ) +clip_emit_quad( struct setup_context *setup, struct quad_header *quad ) { quad_clip( setup, quad ); + if (quad->inout.mask) { struct softpipe_context *sp = setup->softpipe; - sp->quad[thread].first->run( sp->quad[thread].first, quad ); + sp->quad.first->run( sp->quad.first, quad ); } } -#if SP_NUM_QUAD_THREADS > 1 - -static void -clip_emit_quad_job( struct setup_context *setup, uint thread, struct quad_job *job ) -{ - struct quad_header quad; - - quad.input = job->input; - quad.inout = job->inout; - quad.coef = setup->quad.coef; - quad.posCoef = setup->quad.posCoef; - quad.nr_attrs = setup->quad.nr_attrs; - clip_emit_quad( setup, &quad, thread ); -} - -#define CLIP_EMIT_QUAD(setup) add_quad_job( &setup->que, &setup->quad, clip_emit_quad_job ) - -#else - -#define CLIP_EMIT_QUAD(setup) clip_emit_quad( setup, &setup->quad, 0 ) - -#endif - /** * Emit a quad (pass to next stage). No clipping is done. */ @@ -361,7 +193,7 @@ emit_quad( struct setup_context *setup, struct quad_header *quad, uint thread ) if (mask & 4) setup->numFragsEmitted++; if (mask & 8) setup->numFragsEmitted++; #endif - sp->quad[thread].first->run( sp->quad[thread].first, quad ); + sp->quad.first->run( sp->quad.first, quad ); #if DEBUG_FRAGS mask = quad->inout.mask; if (mask & 1) setup->numFragsWritten++; @@ -371,38 +203,15 @@ emit_quad( struct setup_context *setup, struct quad_header *quad, uint thread ) #endif } -#if SP_NUM_QUAD_THREADS > 1 - -static void -emit_quad_job( struct setup_context *setup, uint thread, struct quad_job *job ) -{ - struct quad_header quad; - - quad.input = job->input; - quad.inout = job->inout; - quad.coef = setup->quad.coef; - quad.posCoef = setup->quad.posCoef; - quad.nr_attrs = setup->quad.nr_attrs; - emit_quad( setup, &quad, thread ); -} - -#define EMIT_QUAD(setup,x,y,qmask) do {\ - setup->quad.input.x0 = x;\ - setup->quad.input.y0 = y;\ - setup->quad.inout.mask = qmask;\ - add_quad_job( &setup->que, &setup->quad, emit_quad_job );\ - } while (0) -#else +#define EMIT_QUAD(setup,x,y,qmask) \ +do { \ + setup->quad.input.x0 = x; \ + setup->quad.input.y0 = y; \ + setup->quad.inout.mask = qmask; \ + emit_quad( setup, &setup->quad, 0 ); \ +} while (0) -#define EMIT_QUAD(setup,x,y,qmask) do {\ - setup->quad.input.x0 = x;\ - setup->quad.input.y0 = y;\ - setup->quad.inout.mask = qmask;\ - emit_quad( setup, &setup->quad, 0 );\ - } while (0) - -#endif /** * Given an X or Y coordinate, return the block/quad coordinate that it @@ -956,8 +765,6 @@ void setup_tri( struct setup_context *setup, flush_spans( setup ); - WAIT_FOR_COMPLETION(setup); - #if DEBUG_FRAGS printf("Tri: %u frags emitted, %u written\n", setup->numFragsEmitted, @@ -1101,7 +908,7 @@ plot(struct setup_context *setup, int x, int y) /* flush prev quad, start new quad */ if (setup->quad.input.x0 != -1) - CLIP_EMIT_QUAD(setup); + clip_emit_quad( setup, &setup->quad ); setup->quad.input.x0 = quadX; setup->quad.input.y0 = quadY; @@ -1223,10 +1030,8 @@ setup_line(struct setup_context *setup, /* draw final quad */ if (setup->quad.inout.mask) { - CLIP_EMIT_QUAD(setup); + clip_emit_quad( setup, &setup->quad ); } - - WAIT_FOR_COMPLETION(setup); } @@ -1334,7 +1139,7 @@ setup_point( struct setup_context *setup, setup->quad.input.x0 = (int) x - ix; setup->quad.input.y0 = (int) y - iy; setup->quad.inout.mask = (1 << ix) << (2 * iy); - CLIP_EMIT_QUAD(setup); + clip_emit_quad( setup, &setup->quad ); } else { if (round) { @@ -1395,7 +1200,7 @@ setup_point( struct setup_context *setup, if (setup->quad.inout.mask) { setup->quad.input.x0 = ix; setup->quad.input.y0 = iy; - CLIP_EMIT_QUAD(setup); + clip_emit_quad( setup, &setup->quad ); } } } @@ -1442,19 +1247,16 @@ setup_point( struct setup_context *setup, setup->quad.inout.mask = mask; setup->quad.input.x0 = ix; setup->quad.input.y0 = iy; - CLIP_EMIT_QUAD(setup); + clip_emit_quad( setup, &setup->quad ); } } } } - - WAIT_FOR_COMPLETION(setup); } void setup_prepare( struct setup_context *setup ) { struct softpipe_context *sp = setup->softpipe; - unsigned i; if (sp->dirty) { softpipe_update_derived(sp); @@ -1463,9 +1265,7 @@ void setup_prepare( struct setup_context *setup ) /* Note: nr_attrs is only used for debugging (vertex printing) */ setup->quad.nr_attrs = draw_num_vs_outputs(sp->draw); - for (i = 0; i < SP_NUM_QUAD_THREADS; i++) { - sp->quad[i].first->begin( sp->quad[i].first ); - } + sp->quad.first->begin( sp->quad.first ); if (sp->reduced_api_prim == PIPE_PRIM_TRIANGLES && sp->rasterizer->fill_cw == PIPE_POLYGON_MODE_FILL && @@ -1493,9 +1293,6 @@ void setup_destroy_context( struct setup_context *setup ) struct setup_context *setup_create_context( struct softpipe_context *softpipe ) { struct setup_context *setup = CALLOC_STRUCT(setup_context); -#if SP_NUM_QUAD_THREADS > 1 - uint i; -#endif setup->softpipe = softpipe; @@ -1505,22 +1302,6 @@ struct setup_context *setup_create_context( struct softpipe_context *softpipe ) setup->span.left[0] = 1000000; /* greater than right[0] */ setup->span.left[1] = 1000000; /* greater than right[1] */ -#if SP_NUM_QUAD_THREADS > 1 - setup->que.first = 0; - setup->que.last = 0; - pipe_mutex_init( setup->que.que_mutex ); - pipe_condvar_init( setup->que.que_notfull_condvar ); - pipe_condvar_init( setup->que.que_notempty_condvar ); - setup->que.jobs_added = 0; - setup->que.jobs_done = 0; - pipe_condvar_init( setup->que.que_done_condvar ); - for (i = 0; i < SP_NUM_QUAD_THREADS; i++) { - setup->threads[i].setup = setup; - setup->threads[i].id = i; - setup->threads[i].handle = pipe_thread_create( quad_thread, &setup->threads[i] ); - } -#endif - return setup; } -- cgit v1.2.3 From ab9fb5167023a26566b53e98f206dd73a18000f3 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 24 Jul 2009 16:49:35 +0100 Subject: softpipe: expand quad pipeline to process >1 quad at a time This is part one -- we still only pass a single quad down, but the code can now cope with more. The quads must all be from the same tile. --- src/gallium/drivers/softpipe/sp_quad_alpha_test.c | 106 ++-- src/gallium/drivers/softpipe/sp_quad_blend.c | 730 +++++++++++----------- src/gallium/drivers/softpipe/sp_quad_colormask.c | 15 +- src/gallium/drivers/softpipe/sp_quad_coverage.c | 48 +- src/gallium/drivers/softpipe/sp_quad_depth_test.c | 23 +- src/gallium/drivers/softpipe/sp_quad_earlyz.c | 28 +- src/gallium/drivers/softpipe/sp_quad_fs.c | 40 +- src/gallium/drivers/softpipe/sp_quad_occlusion.c | 10 +- src/gallium/drivers/softpipe/sp_quad_output.c | 49 +- src/gallium/drivers/softpipe/sp_quad_pipe.c | 88 +-- src/gallium/drivers/softpipe/sp_quad_pipe.h | 4 +- src/gallium/drivers/softpipe/sp_quad_stencil.c | 185 +++--- src/gallium/drivers/softpipe/sp_quad_stipple.c | 48 +- src/gallium/drivers/softpipe/sp_setup.c | 4 +- 14 files changed, 745 insertions(+), 633 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_quad_alpha_test.c b/src/gallium/drivers/softpipe/sp_quad_alpha_test.c index 0845bae0e68..3a282208b6b 100644 --- a/src/gallium/drivers/softpipe/sp_quad_alpha_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_alpha_test.c @@ -9,76 +9,80 @@ #include "pipe/p_defines.h" #include "util/u_memory.h" +#define ALPHATEST( FUNC, COMP ) \ + static void \ + alpha_test_quads_##FUNC( struct quad_stage *qs, \ + struct quad_header *quads[], \ + unsigned nr ) \ + { \ + const float ref = qs->softpipe->depth_stencil->alpha.ref_value; \ + const uint cbuf = 0; /* only output[0].alpha is tested */ \ + unsigned pass_nr = 0; \ + unsigned i; \ + \ + for (i = 0; i < nr; i++) { \ + const float *aaaa = quads[i]->output.color[cbuf][3]; \ + unsigned passMask = 0; \ + \ + if (aaaa[0] COMP ref) passMask |= (1 << 0); \ + if (aaaa[1] COMP ref) passMask |= (1 << 1); \ + if (aaaa[2] COMP ref) passMask |= (1 << 2); \ + if (aaaa[3] COMP ref) passMask |= (1 << 3); \ + \ + quads[i]->inout.mask &= passMask; \ + \ + if (quads[i]->inout.mask) \ + quads[pass_nr++] = quads[i]; \ + } \ + \ + if (pass_nr) \ + qs->next->run(qs->next, quads, pass_nr); \ + } + + +ALPHATEST( LESS, < ) +ALPHATEST( EQUAL, == ) +ALPHATEST( LEQUAL, <= ) +ALPHATEST( GREATER, > ) +ALPHATEST( NOTEQUAL, != ) +ALPHATEST( GEQUAL, >= ) + +/* XXX: Incorporate into shader using KILP. + */ static void -alpha_test_quad(struct quad_stage *qs, struct quad_header *quad) +alpha_test_quad(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) { - struct softpipe_context *softpipe = qs->softpipe; - const float ref = softpipe->depth_stencil->alpha.ref_value; - unsigned passMask = 0x0, j; - const uint cbuf = 0; /* only output[0].alpha is tested */ - const float *aaaa = quad->output.color[cbuf][3]; - - switch (softpipe->depth_stencil->alpha.func) { - case PIPE_FUNC_NEVER: - break; + switch (qs->softpipe->depth_stencil->alpha.func) { case PIPE_FUNC_LESS: - /* - * If mask were an array [4] we could do this SIMD-style: - * passMask = (quad->outputs.color[0][3] <= vec4(ref)); - */ - for (j = 0; j < QUAD_SIZE; j++) { - if (aaaa[j] < ref) { - passMask |= (1 << j); - } - } + alpha_test_quads_LESS( qs, quads, nr ); break; case PIPE_FUNC_EQUAL: - for (j = 0; j < QUAD_SIZE; j++) { - if (aaaa[j] == ref) { - passMask |= (1 << j); - } - } + alpha_test_quads_EQUAL( qs, quads, nr ); break; case PIPE_FUNC_LEQUAL: - for (j = 0; j < QUAD_SIZE; j++) { - if (aaaa[j] <= ref) { - passMask |= (1 << j); - } - } + alpha_test_quads_LEQUAL( qs, quads, nr ); break; case PIPE_FUNC_GREATER: - for (j = 0; j < QUAD_SIZE; j++) { - if (aaaa[j] > ref) { - passMask |= (1 << j); - } - } + alpha_test_quads_GREATER( qs, quads, nr ); break; case PIPE_FUNC_NOTEQUAL: - for (j = 0; j < QUAD_SIZE; j++) { - if (aaaa[j] != ref) { - passMask |= (1 << j); - } - } + alpha_test_quads_NOTEQUAL( qs, quads, nr ); break; case PIPE_FUNC_GEQUAL: - for (j = 0; j < QUAD_SIZE; j++) { - if (aaaa[j] >= ref) { - passMask |= (1 << j); - } - } + alpha_test_quads_GEQUAL( qs, quads, nr ); break; case PIPE_FUNC_ALWAYS: - passMask = MASK_ALL; + assert(0); /* should be caught earlier */ + qs->next->run(qs->next, quads, nr); break; + case PIPE_FUNC_NEVER: default: - assert(0); + assert(0); /* should be caught earlier */ + return; } - - quad->inout.mask &= passMask; - - if (quad->inout.mask) - qs->next->run(qs->next, quad); } diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index 04b5daf3a41..fdf1bb45522 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -117,10 +117,16 @@ do { \ static void -logicop_quad(struct quad_stage *qs, struct quad_header *quad) +logicop_quad(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) { struct softpipe_context *softpipe = qs->softpipe; uint cbuf; + struct softpipe_cached_tile * + tile = sp_get_cached_tile(softpipe->cbuf_cache[cbuf], + quads[0]->input.x0, + quads[0]->input.y0); /* loop over colorbuffer outputs */ for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) { @@ -129,165 +135,161 @@ logicop_quad(struct quad_stage *qs, struct quad_header *quad) uint *src4 = (uint *) src; uint *dst4 = (uint *) dst; uint *res4 = (uint *) res; - struct softpipe_cached_tile * - tile = sp_get_cached_tile(softpipe->cbuf_cache[cbuf], - quad->input.x0, quad->input.y0); - float (*quadColor)[4] = quad->output.color[cbuf]; uint i, j; - /* get/swizzle dest colors */ - for (j = 0; j < QUAD_SIZE; j++) { - int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1); - int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1); - for (i = 0; i < 4; i++) { - dest[i][j] = tile->data.color[y][x][i]; + for (i = 0; i < nr; i++) { + struct quad_header *quad = quads[i]; + float (*quadColor)[4] = quad->output.color[cbuf]; + + /* get/swizzle dest colors */ + for (j = 0; j < QUAD_SIZE; j++) { + int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1); + int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1); + for (i = 0; i < 4; i++) { + dest[i][j] = tile->data.color[y][x][i]; + } } - } - /* convert to ubyte */ - for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */ - dst[j][0] = float_to_ubyte(dest[j][0]); /* P0 */ - dst[j][1] = float_to_ubyte(dest[j][1]); /* P1 */ - dst[j][2] = float_to_ubyte(dest[j][2]); /* P2 */ - dst[j][3] = float_to_ubyte(dest[j][3]); /* P3 */ - - src[j][0] = float_to_ubyte(quadColor[j][0]); /* P0 */ - src[j][1] = float_to_ubyte(quadColor[j][1]); /* P1 */ - src[j][2] = float_to_ubyte(quadColor[j][2]); /* P2 */ - src[j][3] = float_to_ubyte(quadColor[j][3]); /* P3 */ - } + /* convert to ubyte */ + for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */ + dst[j][0] = float_to_ubyte(dest[j][0]); /* P0 */ + dst[j][1] = float_to_ubyte(dest[j][1]); /* P1 */ + dst[j][2] = float_to_ubyte(dest[j][2]); /* P2 */ + dst[j][3] = float_to_ubyte(dest[j][3]); /* P3 */ + + src[j][0] = float_to_ubyte(quadColor[j][0]); /* P0 */ + src[j][1] = float_to_ubyte(quadColor[j][1]); /* P1 */ + src[j][2] = float_to_ubyte(quadColor[j][2]); /* P2 */ + src[j][3] = float_to_ubyte(quadColor[j][3]); /* P3 */ + } - switch (softpipe->blend->logicop_func) { - case PIPE_LOGICOP_CLEAR: - for (j = 0; j < 4; j++) - res4[j] = 0; - break; - case PIPE_LOGICOP_NOR: - for (j = 0; j < 4; j++) - res4[j] = ~(src4[j] | dst4[j]); - break; - case PIPE_LOGICOP_AND_INVERTED: - for (j = 0; j < 4; j++) - res4[j] = ~src4[j] & dst4[j]; - break; - case PIPE_LOGICOP_COPY_INVERTED: - for (j = 0; j < 4; j++) - res4[j] = ~src4[j]; - break; - case PIPE_LOGICOP_AND_REVERSE: - for (j = 0; j < 4; j++) - res4[j] = src4[j] & ~dst4[j]; - break; - case PIPE_LOGICOP_INVERT: - for (j = 0; j < 4; j++) - res4[j] = ~dst4[j]; - break; - case PIPE_LOGICOP_XOR: - for (j = 0; j < 4; j++) - res4[j] = dst4[j] ^ src4[j]; - break; - case PIPE_LOGICOP_NAND: - for (j = 0; j < 4; j++) - res4[j] = ~(src4[j] & dst4[j]); - break; - case PIPE_LOGICOP_AND: - for (j = 0; j < 4; j++) - res4[j] = src4[j] & dst4[j]; - break; - case PIPE_LOGICOP_EQUIV: - for (j = 0; j < 4; j++) - res4[j] = ~(src4[j] ^ dst4[j]); - break; - case PIPE_LOGICOP_NOOP: - for (j = 0; j < 4; j++) - res4[j] = dst4[j]; - break; - case PIPE_LOGICOP_OR_INVERTED: - for (j = 0; j < 4; j++) - res4[j] = ~src4[j] | dst4[j]; - break; - case PIPE_LOGICOP_COPY: - for (j = 0; j < 4; j++) - res4[j] = src4[j]; - break; - case PIPE_LOGICOP_OR_REVERSE: - for (j = 0; j < 4; j++) - res4[j] = src4[j] | ~dst4[j]; - break; - case PIPE_LOGICOP_OR: - for (j = 0; j < 4; j++) - res4[j] = src4[j] | dst4[j]; - break; - case PIPE_LOGICOP_SET: - for (j = 0; j < 4; j++) - res4[j] = ~0; - break; - default: - assert(0); - } + switch (softpipe->blend->logicop_func) { + case PIPE_LOGICOP_CLEAR: + for (j = 0; j < 4; j++) + res4[j] = 0; + break; + case PIPE_LOGICOP_NOR: + for (j = 0; j < 4; j++) + res4[j] = ~(src4[j] | dst4[j]); + break; + case PIPE_LOGICOP_AND_INVERTED: + for (j = 0; j < 4; j++) + res4[j] = ~src4[j] & dst4[j]; + break; + case PIPE_LOGICOP_COPY_INVERTED: + for (j = 0; j < 4; j++) + res4[j] = ~src4[j]; + break; + case PIPE_LOGICOP_AND_REVERSE: + for (j = 0; j < 4; j++) + res4[j] = src4[j] & ~dst4[j]; + break; + case PIPE_LOGICOP_INVERT: + for (j = 0; j < 4; j++) + res4[j] = ~dst4[j]; + break; + case PIPE_LOGICOP_XOR: + for (j = 0; j < 4; j++) + res4[j] = dst4[j] ^ src4[j]; + break; + case PIPE_LOGICOP_NAND: + for (j = 0; j < 4; j++) + res4[j] = ~(src4[j] & dst4[j]); + break; + case PIPE_LOGICOP_AND: + for (j = 0; j < 4; j++) + res4[j] = src4[j] & dst4[j]; + break; + case PIPE_LOGICOP_EQUIV: + for (j = 0; j < 4; j++) + res4[j] = ~(src4[j] ^ dst4[j]); + break; + case PIPE_LOGICOP_NOOP: + for (j = 0; j < 4; j++) + res4[j] = dst4[j]; + break; + case PIPE_LOGICOP_OR_INVERTED: + for (j = 0; j < 4; j++) + res4[j] = ~src4[j] | dst4[j]; + break; + case PIPE_LOGICOP_COPY: + for (j = 0; j < 4; j++) + res4[j] = src4[j]; + break; + case PIPE_LOGICOP_OR_REVERSE: + for (j = 0; j < 4; j++) + res4[j] = src4[j] | ~dst4[j]; + break; + case PIPE_LOGICOP_OR: + for (j = 0; j < 4; j++) + res4[j] = src4[j] | dst4[j]; + break; + case PIPE_LOGICOP_SET: + for (j = 0; j < 4; j++) + res4[j] = ~0; + break; + default: + assert(0); + } - for (j = 0; j < 4; j++) { - quadColor[j][0] = ubyte_to_float(res[j][0]); - quadColor[j][1] = ubyte_to_float(res[j][1]); - quadColor[j][2] = ubyte_to_float(res[j][2]); - quadColor[j][3] = ubyte_to_float(res[j][3]); + for (j = 0; j < 4; j++) { + quadColor[j][0] = ubyte_to_float(res[j][0]); + quadColor[j][1] = ubyte_to_float(res[j][1]); + quadColor[j][2] = ubyte_to_float(res[j][2]); + quadColor[j][3] = ubyte_to_float(res[j][3]); + } } } - - /* pass quad to next stage */ - qs->next->run(qs->next, quad); } - - static void -blend_quad(struct quad_stage *qs, struct quad_header *quad) +blend_quads(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) { static const float zero[4] = { 0, 0, 0, 0 }; static const float one[4] = { 1, 1, 1, 1 }; - struct softpipe_context *softpipe = qs->softpipe; uint cbuf; - if (softpipe->blend->logicop_enable) { - logicop_quad(qs, quad); - return; - } - /* loop over colorbuffer outputs */ for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) { float source[4][QUAD_SIZE], dest[4][QUAD_SIZE]; struct softpipe_cached_tile *tile = sp_get_cached_tile(softpipe->cbuf_cache[cbuf], - quad->input.x0, quad->input.y0); - float (*quadColor)[4] = quad->output.color[cbuf]; - uint i, j; - - /* get/swizzle dest colors */ - for (j = 0; j < QUAD_SIZE; j++) { - int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1); - int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1); - for (i = 0; i < 4; i++) { - dest[i][j] = tile->data.color[y][x][i]; + quads[0]->input.x0, + quads[0]->input.y0); + uint q, i, j; + + for (q = 0; q < nr; q++) { + struct quad_header *quad = quads[q]; + float (*quadColor)[4] = quad->output.color[cbuf]; + + /* get/swizzle dest colors */ + for (j = 0; j < QUAD_SIZE; j++) { + int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1); + int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1); + for (i = 0; i < 4; i++) { + dest[i][j] = tile->data.color[y][x][i]; + } } - } - /* - * Compute src/first term RGB - */ - switch (softpipe->blend->rgb_src_factor) { - case PIPE_BLENDFACTOR_ONE: - VEC4_COPY(source[0], quadColor[0]); /* R */ - VEC4_COPY(source[1], quadColor[1]); /* G */ - VEC4_COPY(source[2], quadColor[2]); /* B */ - break; - case PIPE_BLENDFACTOR_SRC_COLOR: - VEC4_MUL(source[0], quadColor[0], quadColor[0]); /* R */ - VEC4_MUL(source[1], quadColor[1], quadColor[1]); /* G */ - VEC4_MUL(source[2], quadColor[2], quadColor[2]); /* B */ - break; - case PIPE_BLENDFACTOR_SRC_ALPHA: + /* + * Compute src/first term RGB + */ + switch (softpipe->blend->rgb_src_factor) { + case PIPE_BLENDFACTOR_ONE: + VEC4_COPY(source[0], quadColor[0]); /* R */ + VEC4_COPY(source[1], quadColor[1]); /* G */ + VEC4_COPY(source[2], quadColor[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + VEC4_MUL(source[0], quadColor[0], quadColor[0]); /* R */ + VEC4_MUL(source[1], quadColor[1], quadColor[1]); /* G */ + VEC4_MUL(source[2], quadColor[2], quadColor[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA: { const float *alpha = quadColor[3]; VEC4_MUL(source[0], quadColor[0], alpha); /* R */ @@ -295,12 +297,12 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(source[2], quadColor[2], alpha); /* B */ } break; - case PIPE_BLENDFACTOR_DST_COLOR: - VEC4_MUL(source[0], quadColor[0], dest[0]); /* R */ - VEC4_MUL(source[1], quadColor[1], dest[1]); /* G */ - VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */ - break; - case PIPE_BLENDFACTOR_DST_ALPHA: + case PIPE_BLENDFACTOR_DST_COLOR: + VEC4_MUL(source[0], quadColor[0], dest[0]); /* R */ + VEC4_MUL(source[1], quadColor[1], dest[1]); /* G */ + VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */ + break; + case PIPE_BLENDFACTOR_DST_ALPHA: { const float *alpha = dest[3]; VEC4_MUL(source[0], quadColor[0], alpha); /* R */ @@ -308,7 +310,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(source[2], quadColor[2], alpha); /* B */ } break; - case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: { const float *alpha = quadColor[3]; float diff[4], temp[4]; @@ -319,7 +321,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(source[2], quadColor[2], temp); /* B */ } break; - case PIPE_BLENDFACTOR_CONST_COLOR: + case PIPE_BLENDFACTOR_CONST_COLOR: { float comp[4]; VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */ @@ -330,7 +332,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(source[2], quadColor[2], comp); /* B */ } break; - case PIPE_BLENDFACTOR_CONST_ALPHA: + case PIPE_BLENDFACTOR_CONST_ALPHA: { float alpha[4]; VEC4_SCALAR(alpha, softpipe->blend_color.color[3]); @@ -339,18 +341,18 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(source[2], quadColor[2], alpha); /* B */ } break; - case PIPE_BLENDFACTOR_SRC1_COLOR: - assert(0); /* to do */ - break; - case PIPE_BLENDFACTOR_SRC1_ALPHA: - assert(0); /* to do */ - break; - case PIPE_BLENDFACTOR_ZERO: - VEC4_COPY(source[0], zero); /* R */ - VEC4_COPY(source[1], zero); /* G */ - VEC4_COPY(source[2], zero); /* B */ - break; - case PIPE_BLENDFACTOR_INV_SRC_COLOR: + case PIPE_BLENDFACTOR_SRC1_COLOR: + assert(0); /* to do */ + break; + case PIPE_BLENDFACTOR_SRC1_ALPHA: + assert(0); /* to do */ + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(source[0], zero); /* R */ + VEC4_COPY(source[1], zero); /* G */ + VEC4_COPY(source[2], zero); /* B */ + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: { float inv_comp[4]; VEC4_SUB(inv_comp, one, quadColor[0]); /* R */ @@ -361,7 +363,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */ } break; - case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: { float inv_alpha[4]; VEC4_SUB(inv_alpha, one, quadColor[3]); @@ -370,7 +372,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ } break; - case PIPE_BLENDFACTOR_INV_DST_ALPHA: + case PIPE_BLENDFACTOR_INV_DST_ALPHA: { float inv_alpha[4]; VEC4_SUB(inv_alpha, one, dest[3]); @@ -379,7 +381,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ } break; - case PIPE_BLENDFACTOR_INV_DST_COLOR: + case PIPE_BLENDFACTOR_INV_DST_COLOR: { float inv_comp[4]; VEC4_SUB(inv_comp, one, dest[0]); /* R */ @@ -390,7 +392,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */ } break; - case PIPE_BLENDFACTOR_INV_CONST_COLOR: + case PIPE_BLENDFACTOR_INV_CONST_COLOR: { float inv_comp[4]; /* R */ @@ -404,7 +406,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(source[2], quadColor[2], inv_comp); } break; - case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: { float inv_alpha[4]; VEC4_SCALAR(inv_alpha, 1.0f - softpipe->blend_color.color[3]); @@ -413,73 +415,73 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ } break; - case PIPE_BLENDFACTOR_INV_SRC1_COLOR: - assert(0); /* to do */ - break; - case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: - assert(0); /* to do */ - break; - default: - assert(0); - } + case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + assert(0); /* to do */ + break; + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + assert(0); /* to do */ + break; + default: + assert(0); + } - /* - * Compute src/first term A - */ - switch (softpipe->blend->alpha_src_factor) { - case PIPE_BLENDFACTOR_ONE: - VEC4_COPY(source[3], quadColor[3]); /* A */ - break; - case PIPE_BLENDFACTOR_SRC_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_SRC_ALPHA: + /* + * Compute src/first term A + */ + switch (softpipe->blend->alpha_src_factor) { + case PIPE_BLENDFACTOR_ONE: + VEC4_COPY(source[3], quadColor[3]); /* A */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_SRC_ALPHA: { const float *alpha = quadColor[3]; VEC4_MUL(source[3], quadColor[3], alpha); /* A */ } break; - case PIPE_BLENDFACTOR_DST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_DST_ALPHA: - VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */ - break; - case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: - /* multiply alpha by 1.0 */ - VEC4_COPY(source[3], quadColor[3]); /* A */ - break; - case PIPE_BLENDFACTOR_CONST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_CONST_ALPHA: + case PIPE_BLENDFACTOR_DST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_DST_ALPHA: + VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + /* multiply alpha by 1.0 */ + VEC4_COPY(source[3], quadColor[3]); /* A */ + break; + case PIPE_BLENDFACTOR_CONST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_CONST_ALPHA: { float comp[4]; VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ VEC4_MUL(source[3], quadColor[3], comp); /* A */ } break; - case PIPE_BLENDFACTOR_ZERO: - VEC4_COPY(source[3], zero); /* A */ - break; - case PIPE_BLENDFACTOR_INV_SRC_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(source[3], zero); /* A */ + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: { float inv_alpha[4]; VEC4_SUB(inv_alpha, one, quadColor[3]); VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ } break; - case PIPE_BLENDFACTOR_INV_DST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_INV_DST_ALPHA: + case PIPE_BLENDFACTOR_INV_DST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_DST_ALPHA: { float inv_alpha[4]; VEC4_SUB(inv_alpha, one, dest[3]); VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ } break; - case PIPE_BLENDFACTOR_INV_CONST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: { float inv_comp[4]; /* A */ @@ -487,42 +489,42 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(source[3], quadColor[3], inv_comp); } break; - default: - assert(0); - } + default: + assert(0); + } - /* - * Compute dest/second term RGB - */ - switch (softpipe->blend->rgb_dst_factor) { - case PIPE_BLENDFACTOR_ONE: - /* dest = dest * 1 NO-OP, leave dest as-is */ - break; - case PIPE_BLENDFACTOR_SRC_COLOR: - VEC4_MUL(dest[0], dest[0], quadColor[0]); /* R */ - VEC4_MUL(dest[1], dest[1], quadColor[1]); /* G */ - VEC4_MUL(dest[2], dest[2], quadColor[2]); /* B */ - break; - case PIPE_BLENDFACTOR_SRC_ALPHA: - VEC4_MUL(dest[0], dest[0], quadColor[3]); /* R * A */ - VEC4_MUL(dest[1], dest[1], quadColor[3]); /* G * A */ - VEC4_MUL(dest[2], dest[2], quadColor[3]); /* B * A */ - break; - case PIPE_BLENDFACTOR_DST_ALPHA: - VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */ - VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */ - VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */ - break; - case PIPE_BLENDFACTOR_DST_COLOR: - VEC4_MUL(dest[0], dest[0], dest[0]); /* R */ - VEC4_MUL(dest[1], dest[1], dest[1]); /* G */ - VEC4_MUL(dest[2], dest[2], dest[2]); /* B */ - break; - case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: - assert(0); /* illegal */ - break; - case PIPE_BLENDFACTOR_CONST_COLOR: + /* + * Compute dest/second term RGB + */ + switch (softpipe->blend->rgb_dst_factor) { + case PIPE_BLENDFACTOR_ONE: + /* dest = dest * 1 NO-OP, leave dest as-is */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + VEC4_MUL(dest[0], dest[0], quadColor[0]); /* R */ + VEC4_MUL(dest[1], dest[1], quadColor[1]); /* G */ + VEC4_MUL(dest[2], dest[2], quadColor[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA: + VEC4_MUL(dest[0], dest[0], quadColor[3]); /* R * A */ + VEC4_MUL(dest[1], dest[1], quadColor[3]); /* G * A */ + VEC4_MUL(dest[2], dest[2], quadColor[3]); /* B * A */ + break; + case PIPE_BLENDFACTOR_DST_ALPHA: + VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */ + VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */ + VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */ + break; + case PIPE_BLENDFACTOR_DST_COLOR: + VEC4_MUL(dest[0], dest[0], dest[0]); /* R */ + VEC4_MUL(dest[1], dest[1], dest[1]); /* G */ + VEC4_MUL(dest[2], dest[2], dest[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + assert(0); /* illegal */ + break; + case PIPE_BLENDFACTOR_CONST_COLOR: { float comp[4]; VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */ @@ -533,7 +535,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(dest[2], dest[2], comp); /* B */ } break; - case PIPE_BLENDFACTOR_CONST_ALPHA: + case PIPE_BLENDFACTOR_CONST_ALPHA: { float comp[4]; VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ @@ -542,17 +544,17 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(dest[2], dest[2], comp); /* B */ } break; - case PIPE_BLENDFACTOR_ZERO: - VEC4_COPY(dest[0], zero); /* R */ - VEC4_COPY(dest[1], zero); /* G */ - VEC4_COPY(dest[2], zero); /* B */ - break; - case PIPE_BLENDFACTOR_SRC1_COLOR: - case PIPE_BLENDFACTOR_SRC1_ALPHA: - /* XXX what are these? */ - assert(0); - break; - case PIPE_BLENDFACTOR_INV_SRC_COLOR: + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(dest[0], zero); /* R */ + VEC4_COPY(dest[1], zero); /* G */ + VEC4_COPY(dest[2], zero); /* B */ + break; + case PIPE_BLENDFACTOR_SRC1_COLOR: + case PIPE_BLENDFACTOR_SRC1_ALPHA: + /* XXX what are these? */ + assert(0); + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: { float inv_comp[4]; VEC4_SUB(inv_comp, one, quadColor[0]); /* R */ @@ -563,7 +565,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ } break; - case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: { float one_minus_alpha[QUAD_SIZE]; VEC4_SUB(one_minus_alpha, one, quadColor[3]); @@ -572,7 +574,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */ } break; - case PIPE_BLENDFACTOR_INV_DST_ALPHA: + case PIPE_BLENDFACTOR_INV_DST_ALPHA: { float inv_comp[4]; VEC4_SUB(inv_comp, one, dest[3]); /* A */ @@ -581,7 +583,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ } break; - case PIPE_BLENDFACTOR_INV_DST_COLOR: + case PIPE_BLENDFACTOR_INV_DST_COLOR: { float inv_comp[4]; VEC4_SUB(inv_comp, one, dest[0]); /* R */ @@ -592,7 +594,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(dest[2], dest[2], inv_comp); /* B */ } break; - case PIPE_BLENDFACTOR_INV_CONST_COLOR: + case PIPE_BLENDFACTOR_INV_CONST_COLOR: { float inv_comp[4]; /* R */ @@ -606,7 +608,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(dest[2], dest[2], inv_comp); } break; - case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: { float inv_comp[4]; VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]); @@ -615,138 +617,154 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(dest[2], dest[2], inv_comp); } break; - case PIPE_BLENDFACTOR_INV_SRC1_COLOR: - case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: - /* XXX what are these? */ - assert(0); - break; - default: - assert(0); - } + case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + /* XXX what are these? */ + assert(0); + break; + default: + assert(0); + } - /* - * Compute dest/second term A - */ - switch (softpipe->blend->alpha_dst_factor) { - case PIPE_BLENDFACTOR_ONE: - /* dest = dest * 1 NO-OP, leave dest as-is */ - break; - case PIPE_BLENDFACTOR_SRC_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_SRC_ALPHA: - VEC4_MUL(dest[3], dest[3], quadColor[3]); /* A * A */ - break; - case PIPE_BLENDFACTOR_DST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_DST_ALPHA: - VEC4_MUL(dest[3], dest[3], dest[3]); /* A */ - break; - case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: - assert(0); /* illegal */ - break; - case PIPE_BLENDFACTOR_CONST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_CONST_ALPHA: + /* + * Compute dest/second term A + */ + switch (softpipe->blend->alpha_dst_factor) { + case PIPE_BLENDFACTOR_ONE: + /* dest = dest * 1 NO-OP, leave dest as-is */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_SRC_ALPHA: + VEC4_MUL(dest[3], dest[3], quadColor[3]); /* A * A */ + break; + case PIPE_BLENDFACTOR_DST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_DST_ALPHA: + VEC4_MUL(dest[3], dest[3], dest[3]); /* A */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + assert(0); /* illegal */ + break; + case PIPE_BLENDFACTOR_CONST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_CONST_ALPHA: { float comp[4]; VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ VEC4_MUL(dest[3], dest[3], comp); /* A */ } break; - case PIPE_BLENDFACTOR_ZERO: - VEC4_COPY(dest[3], zero); /* A */ - break; - case PIPE_BLENDFACTOR_INV_SRC_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(dest[3], zero); /* A */ + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: { float one_minus_alpha[QUAD_SIZE]; VEC4_SUB(one_minus_alpha, one, quadColor[3]); VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* A */ } break; - case PIPE_BLENDFACTOR_INV_DST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_INV_DST_ALPHA: + case PIPE_BLENDFACTOR_INV_DST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_DST_ALPHA: { float inv_comp[4]; VEC4_SUB(inv_comp, one, dest[3]); /* A */ VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */ } break; - case PIPE_BLENDFACTOR_INV_CONST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: { float inv_comp[4]; VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]); VEC4_MUL(dest[3], dest[3], inv_comp); } break; - default: - assert(0); - } + default: + assert(0); + } - /* - * Combine RGB terms - */ - switch (softpipe->blend->rgb_func) { - case PIPE_BLEND_ADD: - VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */ - VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */ - VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */ - break; - case PIPE_BLEND_SUBTRACT: - VEC4_SUB_SAT(quadColor[0], source[0], dest[0]); /* R */ - VEC4_SUB_SAT(quadColor[1], source[1], dest[1]); /* G */ - VEC4_SUB_SAT(quadColor[2], source[2], dest[2]); /* B */ - break; - case PIPE_BLEND_REVERSE_SUBTRACT: - VEC4_SUB_SAT(quadColor[0], dest[0], source[0]); /* R */ - VEC4_SUB_SAT(quadColor[1], dest[1], source[1]); /* G */ - VEC4_SUB_SAT(quadColor[2], dest[2], source[2]); /* B */ - break; - case PIPE_BLEND_MIN: - VEC4_MIN(quadColor[0], source[0], dest[0]); /* R */ - VEC4_MIN(quadColor[1], source[1], dest[1]); /* G */ - VEC4_MIN(quadColor[2], source[2], dest[2]); /* B */ - break; - case PIPE_BLEND_MAX: - VEC4_MAX(quadColor[0], source[0], dest[0]); /* R */ - VEC4_MAX(quadColor[1], source[1], dest[1]); /* G */ - VEC4_MAX(quadColor[2], source[2], dest[2]); /* B */ - break; - default: - assert(0); - } + /* + * Combine RGB terms + */ + switch (softpipe->blend->rgb_func) { + case PIPE_BLEND_ADD: + VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */ + VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */ + VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */ + break; + case PIPE_BLEND_SUBTRACT: + VEC4_SUB_SAT(quadColor[0], source[0], dest[0]); /* R */ + VEC4_SUB_SAT(quadColor[1], source[1], dest[1]); /* G */ + VEC4_SUB_SAT(quadColor[2], source[2], dest[2]); /* B */ + break; + case PIPE_BLEND_REVERSE_SUBTRACT: + VEC4_SUB_SAT(quadColor[0], dest[0], source[0]); /* R */ + VEC4_SUB_SAT(quadColor[1], dest[1], source[1]); /* G */ + VEC4_SUB_SAT(quadColor[2], dest[2], source[2]); /* B */ + break; + case PIPE_BLEND_MIN: + VEC4_MIN(quadColor[0], source[0], dest[0]); /* R */ + VEC4_MIN(quadColor[1], source[1], dest[1]); /* G */ + VEC4_MIN(quadColor[2], source[2], dest[2]); /* B */ + break; + case PIPE_BLEND_MAX: + VEC4_MAX(quadColor[0], source[0], dest[0]); /* R */ + VEC4_MAX(quadColor[1], source[1], dest[1]); /* G */ + VEC4_MAX(quadColor[2], source[2], dest[2]); /* B */ + break; + default: + assert(0); + } - /* - * Combine A terms - */ - switch (softpipe->blend->alpha_func) { - case PIPE_BLEND_ADD: - VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */ - break; - case PIPE_BLEND_SUBTRACT: - VEC4_SUB_SAT(quadColor[3], source[3], dest[3]); /* A */ - break; - case PIPE_BLEND_REVERSE_SUBTRACT: - VEC4_SUB_SAT(quadColor[3], dest[3], source[3]); /* A */ - break; - case PIPE_BLEND_MIN: - VEC4_MIN(quadColor[3], source[3], dest[3]); /* A */ - break; - case PIPE_BLEND_MAX: - VEC4_MAX(quadColor[3], source[3], dest[3]); /* A */ - break; - default: - assert(0); + /* + * Combine A terms + */ + switch (softpipe->blend->alpha_func) { + case PIPE_BLEND_ADD: + VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */ + break; + case PIPE_BLEND_SUBTRACT: + VEC4_SUB_SAT(quadColor[3], source[3], dest[3]); /* A */ + break; + case PIPE_BLEND_REVERSE_SUBTRACT: + VEC4_SUB_SAT(quadColor[3], dest[3], source[3]); /* A */ + break; + case PIPE_BLEND_MIN: + VEC4_MIN(quadColor[3], source[3], dest[3]); /* A */ + break; + case PIPE_BLEND_MAX: + VEC4_MAX(quadColor[3], source[3], dest[3]); /* A */ + break; + default: + assert(0); + } } - } /* cbuf loop */ +} + + +static void +blend_quad(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) +{ + struct softpipe_context *softpipe = qs->softpipe; + + if (softpipe->blend->logicop_enable) { + logicop_quad(qs, quads, nr); + } + else if (softpipe->blend->blend_enable) { + blend_quads(qs, quads, nr ); + } /* pass blended quad to next stage */ - qs->next->run(qs->next, quad); + qs->next->run(qs->next, quads, nr); } diff --git a/src/gallium/drivers/softpipe/sp_quad_colormask.c b/src/gallium/drivers/softpipe/sp_quad_colormask.c index 89efbe3b024..ac742874733 100644 --- a/src/gallium/drivers/softpipe/sp_quad_colormask.c +++ b/src/gallium/drivers/softpipe/sp_quad_colormask.c @@ -84,12 +84,23 @@ colormask_quad(struct quad_stage *qs, struct quad_header *quad) if (!(softpipe->blend->colormask & PIPE_MASK_A)) COPY_4V(quadColor[3], dest[3]); } +} + +static void +colormask_quads(struct quad_stage *qs, struct quad_header *quads[], + unsigned nr) +{ + unsigned i; + + for (i = 0; i < nr; i++) + colormask_quad(qs, quads[i]); /* pass quad to next stage */ - qs->next->run(qs->next, quad); + qs->next->run(qs->next, quads, nr); } + static void colormask_begin(struct quad_stage *qs) { qs->next->begin(qs->next); @@ -108,7 +119,7 @@ struct quad_stage *sp_quad_colormask_stage( struct softpipe_context *softpipe ) stage->softpipe = softpipe; stage->begin = colormask_begin; - stage->run = colormask_quad; + stage->run = colormask_quads; stage->destroy = colormask_destroy; return stage; diff --git a/src/gallium/drivers/softpipe/sp_quad_coverage.c b/src/gallium/drivers/softpipe/sp_quad_coverage.c index 4aeee858705..eda5ce8e630 100644 --- a/src/gallium/drivers/softpipe/sp_quad_coverage.c +++ b/src/gallium/drivers/softpipe/sp_quad_coverage.c @@ -42,33 +42,47 @@ /** * Multiply quad's alpha values by the fragment coverage. */ -static void +static INLINE void coverage_quad(struct quad_stage *qs, struct quad_header *quad) { struct softpipe_context *softpipe = qs->softpipe; - const uint prim = quad->input.prim; + uint cbuf; + + /* loop over colorbuffer outputs */ + for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) { + float (*quadColor)[4] = quad->output.color[cbuf]; + unsigned j; + for (j = 0; j < QUAD_SIZE; j++) { + assert(quad->input.coverage[j] >= 0.0); + assert(quad->input.coverage[j] <= 1.0); + quadColor[3][j] *= quad->input.coverage[j]; + } + } +} + + +/* XXX: Incorporate into shader after alpha_test. + */ +static void +coverage_run(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) +{ + struct softpipe_context *softpipe = qs->softpipe; + const uint prim = quads[0]->input.prim; + unsigned i; if ((softpipe->rasterizer->poly_smooth && prim == QUAD_PRIM_TRI) || (softpipe->rasterizer->line_smooth && prim == QUAD_PRIM_LINE) || (softpipe->rasterizer->point_smooth && prim == QUAD_PRIM_POINT)) { - uint cbuf; - - /* loop over colorbuffer outputs */ - for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) { - float (*quadColor)[4] = quad->output.color[cbuf]; - unsigned j; - for (j = 0; j < QUAD_SIZE; j++) { - assert(quad->input.coverage[j] >= 0.0); - assert(quad->input.coverage[j] <= 1.0); - quadColor[3][j] *= quad->input.coverage[j]; - } - } + + for (i = 0; i < nr; i++) + coverage_quad( qs, quads[i] ); } - qs->next->run(qs->next, quad); + qs->next->run(qs->next, quads, nr); } - static void coverage_begin(struct quad_stage *qs) { qs->next->begin(qs->next); @@ -87,7 +101,7 @@ struct quad_stage *sp_quad_coverage_stage( struct softpipe_context *softpipe ) stage->softpipe = softpipe; stage->begin = coverage_begin; - stage->run = coverage_quad; + stage->run = coverage_run; stage->destroy = coverage_destroy; return stage; diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index 768b9275b30..8f223a7eaeb 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -49,7 +49,7 @@ * Try to effectively do that with codegen... */ -void +boolean sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) { struct softpipe_context *softpipe = qs->softpipe; @@ -193,6 +193,8 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) } quad->inout.mask &= zmask; + if (quad->inout.mask == 0) + return FALSE; if (softpipe->depth_stencil->depth.writemask) { @@ -252,16 +254,25 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) assert(0); } } + + return TRUE; } static void -depth_test_quad(struct quad_stage *qs, struct quad_header *quad) +depth_test_quads(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) { - sp_depth_test_quad(qs, quad); + unsigned i, pass = 0; - if (quad->inout.mask) - qs->next->run(qs->next, quad); + for (i = 0; i < nr; i++) { + if (sp_depth_test_quad(qs, quads[i])) + quads[pass++] = quads[i]; + } + + if (pass) + qs->next->run(qs->next, quads, pass); } @@ -283,7 +294,7 @@ struct quad_stage *sp_quad_depth_test_stage( struct softpipe_context *softpipe ) stage->softpipe = softpipe; stage->begin = depth_test_begin; - stage->run = depth_test_quad; + stage->run = depth_test_quads; stage->destroy = depth_test_destroy; return stage; diff --git a/src/gallium/drivers/softpipe/sp_quad_earlyz.c b/src/gallium/drivers/softpipe/sp_quad_earlyz.c index 496fd39ed1a..1048d449843 100644 --- a/src/gallium/drivers/softpipe/sp_quad_earlyz.c +++ b/src/gallium/drivers/softpipe/sp_quad_earlyz.c @@ -43,20 +43,26 @@ static void earlyz_quad( struct quad_stage *qs, - struct quad_header *quad ) + struct quad_header *quads[], + unsigned nr ) { - const float fx = (float) quad->input.x0; - const float fy = (float) quad->input.y0; - const float dzdx = quad->posCoef->dadx[2]; - const float dzdy = quad->posCoef->dady[2]; - const float z0 = quad->posCoef->a0[2] + dzdx * fx + dzdy * fy; + const float a0z = quads[0]->posCoef->a0[2]; + const float dzdx = quads[0]->posCoef->dadx[2]; + const float dzdy = quads[0]->posCoef->dady[2]; + unsigned i; - quad->output.depth[0] = z0; - quad->output.depth[1] = z0 + dzdx; - quad->output.depth[2] = z0 + dzdy; - quad->output.depth[3] = z0 + dzdx + dzdy; + for (i = 0; i < nr; i++) { + const float fx = (float) quads[i]->input.x0; + const float fy = (float) quads[i]->input.y0; + const float z0 = a0z + dzdx * fx + dzdy * fy; - qs->next->run( qs->next, quad ); + quads[i]->output.depth[0] = z0; + quads[i]->output.depth[1] = z0 + dzdx; + quads[i]->output.depth[2] = z0 + dzdy; + quads[i]->output.depth[3] = z0 + dzdx + dzdy; + } + + qs->next->run( qs->next, quads, nr ); } static void diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index 28f8d1a60ea..ea5ed3bbd07 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -68,21 +68,18 @@ quad_shade_stage(struct quad_stage *qs) /** * Execute fragment shader for the four fragments in the quad. */ -static void +static boolean shade_quad(struct quad_stage *qs, struct quad_header *quad) { struct quad_shade_stage *qss = quad_shade_stage( qs ); struct softpipe_context *softpipe = qs->softpipe; struct tgsi_exec_machine *machine = qss->machine; boolean z_written; - - /* Consts do not require 16 byte alignment. */ - machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT]; - - machine->InterpCoefs = quad->coef; /* run shader */ quad->inout.mask &= softpipe->fs->run( softpipe->fs, machine, quad ); + if (quad->inout.mask == 0) + return FALSE; /* store outputs */ z_written = FALSE; @@ -129,11 +126,34 @@ shade_quad(struct quad_stage *qs, struct quad_header *quad) quad->output.depth[3] = z0 + dzdx + dzdy; } - /* shader may cull fragments */ - if (quad->inout.mask) { - qs->next->run( qs->next, quad ); + return TRUE; +} + +static void +shade_quads(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) +{ + struct quad_shade_stage *qss = quad_shade_stage( qs ); + struct softpipe_context *softpipe = qs->softpipe; + struct tgsi_exec_machine *machine = qss->machine; + + unsigned i, pass = 0; + + machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT]; + machine->InterpCoefs = quads[0]->coef; + + for (i = 0; i < nr; i++) { + if (shade_quad(qs, quads[i])) + quads[pass++] = quads[i]; } + + if (pass) + qs->next->run(qs->next, quads, pass); } + + + /** @@ -174,7 +194,7 @@ sp_quad_shade_stage( struct softpipe_context *softpipe ) qss->stage.softpipe = softpipe; qss->stage.begin = shade_begin; - qss->stage.run = shade_quad; + qss->stage.run = shade_quads; qss->stage.destroy = shade_destroy; qss->machine = tgsi_exec_machine_create(); diff --git a/src/gallium/drivers/softpipe/sp_quad_occlusion.c b/src/gallium/drivers/softpipe/sp_quad_occlusion.c index dfa7ff3b1d1..4adeb16546a 100644 --- a/src/gallium/drivers/softpipe/sp_quad_occlusion.c +++ b/src/gallium/drivers/softpipe/sp_quad_occlusion.c @@ -50,13 +50,15 @@ static unsigned count_bits( unsigned val ) } static void -occlusion_count_quad(struct quad_stage *qs, struct quad_header *quad) +occlusion_count_quads(struct quad_stage *qs, struct quad_header *quads[], unsigned nr) { struct softpipe_context *softpipe = qs->softpipe; + unsigned i; - softpipe->occlusion_count += count_bits(quad->inout.mask); + for (i = 0; i < nr; i++) + softpipe->occlusion_count += count_bits(quads[i]->inout.mask); - qs->next->run(qs->next, quad); + qs->next->run(qs->next, quads, nr); } @@ -78,7 +80,7 @@ struct quad_stage *sp_quad_occlusion_stage( struct softpipe_context *softpipe ) stage->softpipe = softpipe; stage->begin = occlusion_begin; - stage->run = occlusion_count_quad; + stage->run = occlusion_count_quads; stage->destroy = occlusion_destroy; return stage; diff --git a/src/gallium/drivers/softpipe/sp_quad_output.c b/src/gallium/drivers/softpipe/sp_quad_output.c index dd8f5377e91..79a222ff58d 100644 --- a/src/gallium/drivers/softpipe/sp_quad_output.c +++ b/src/gallium/drivers/softpipe/sp_quad_output.c @@ -38,11 +38,8 @@ * taking mask into account. */ static void -output_quad(struct quad_stage *qs, struct quad_header *quad) +output_quad(struct quad_stage *qs, struct quad_header *quads[], unsigned nr) { - /* in-tile pos: */ - const int itx = quad->input.x0 % TILE_SIZE; - const int ity = quad->input.y0 % TILE_SIZE; struct softpipe_context *softpipe = qs->softpipe; uint cbuf; @@ -51,25 +48,35 @@ output_quad(struct quad_stage *qs, struct quad_header *quad) for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) { struct softpipe_cached_tile *tile = sp_get_cached_tile(softpipe->cbuf_cache[cbuf], - quad->input.x0, quad->input.y0); - float (*quadColor)[4] = quad->output.color[cbuf]; - int i, j; + quads[0]->input.x0, + quads[0]->input.y0); + int i, j, q; /* get/swizzle dest colors */ - for (j = 0; j < QUAD_SIZE; j++) { - if (quad->inout.mask & (1 << j)) { - int x = itx + (j & 1); - int y = ity + (j >> 1); - for (i = 0; i < 4; i++) { /* loop over color chans */ - tile->data.color[y][x][i] = quadColor[i][j]; - } - if (0) { - debug_printf("sp write pixel %d,%d: %g, %g, %g\n", - quad->input.x0 + x, - quad->input.y0 + y, - quadColor[0][j], - quadColor[1][j], - quadColor[2][j]); + for (q = 0; q < nr; q++) { + struct quad_header *quad = quads[q]; + float (*quadColor)[4] = quad->output.color[cbuf]; + + /* in-tile pos: */ + const int itx = quad->input.x0 % TILE_SIZE; + const int ity = quad->input.y0 % TILE_SIZE; + + + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->inout.mask & (1 << j)) { + int x = itx + (j & 1); + int y = ity + (j >> 1); + for (i = 0; i < 4; i++) { /* loop over color chans */ + tile->data.color[y][x][i] = quadColor[i][j]; + } + if (0) { + debug_printf("sp write pixel %d,%d: %g, %g, %g\n", + quad->input.x0 + x, + quad->input.y0 + y, + quadColor[0][j], + quadColor[1][j], + quadColor[2][j]); + } } } } diff --git a/src/gallium/drivers/softpipe/sp_quad_pipe.c b/src/gallium/drivers/softpipe/sp_quad_pipe.c index 3a3359d303d..594fade4557 100644 --- a/src/gallium/drivers/softpipe/sp_quad_pipe.c +++ b/src/gallium/drivers/softpipe/sp_quad_pipe.c @@ -55,50 +55,52 @@ void sp_build_quad_pipeline(struct softpipe_context *sp) { boolean early_depth_test = - sp->depth_stencil->depth.enabled && - sp->framebuffer.zsbuf && - !sp->depth_stencil->alpha.enabled && - !sp->fs->info.uses_kill && - !sp->fs->info.writes_z; + sp->depth_stencil->depth.enabled && + sp->framebuffer.zsbuf && + !sp->depth_stencil->alpha.enabled && + !sp->fs->info.uses_kill && + !sp->fs->info.writes_z; /* build up the pipeline in reverse order... */ - sp->quad.first = sp->quad.output; - - if (sp->blend->colormask != 0xf) { - sp_push_quad_first( sp, sp->quad.colormask ); - } - - if (sp->blend->blend_enable || - sp->blend->logicop_enable) { - sp_push_quad_first( sp, sp->quad.blend ); - } - - if (sp->active_query_count) { - sp_push_quad_first( sp, sp->quad.occlusion ); - } - - if (sp->rasterizer->poly_smooth || - sp->rasterizer->line_smooth || - sp->rasterizer->point_smooth) { - sp_push_quad_first( sp, sp->quad.coverage ); - } - - if (!early_depth_test) { - sp_build_depth_stencil( sp ); - } - - if (sp->depth_stencil->alpha.enabled) { - sp_push_quad_first( sp, sp->quad.alpha_test ); - } - - /* XXX always enable shader? */ - if (1) { - sp_push_quad_first( sp, sp->quad.shade ); - } - - if (early_depth_test) { - sp_build_depth_stencil( sp ); - sp_push_quad_first( sp, sp->quad.earlyz ); - } + + /* Color combine + */ + sp->quad.first = sp->quad.output; + + if (sp->blend->colormask != 0xf) { + sp_push_quad_first( sp, sp->quad.colormask ); + } + + if (sp->blend->blend_enable || + sp->blend->logicop_enable) { + sp_push_quad_first( sp, sp->quad.blend ); + } + + if (sp->rasterizer->poly_smooth || + sp->rasterizer->line_smooth || + sp->rasterizer->point_smooth) { + sp_push_quad_first( sp, sp->quad.coverage ); + } + + /* Shade/Depth/Stencil/Alpha + */ + if (sp->active_query_count) { + sp_push_quad_first( sp, sp->quad.occlusion ); + } + + if (!early_depth_test) { + sp_build_depth_stencil( sp ); + } + + if (sp->depth_stencil->alpha.enabled) { + sp_push_quad_first( sp, sp->quad.alpha_test ); + } + + sp_push_quad_first( sp, sp->quad.shade ); + + if (early_depth_test) { + sp_build_depth_stencil( sp ); + sp_push_quad_first( sp, sp->quad.earlyz ); + } } diff --git a/src/gallium/drivers/softpipe/sp_quad_pipe.h b/src/gallium/drivers/softpipe/sp_quad_pipe.h index 0e40586ffc8..add31ba7056 100644 --- a/src/gallium/drivers/softpipe/sp_quad_pipe.h +++ b/src/gallium/drivers/softpipe/sp_quad_pipe.h @@ -49,7 +49,7 @@ struct quad_stage { void (*begin)(struct quad_stage *qs); /** the stage action */ - void (*run)(struct quad_stage *qs, struct quad_header *quad); + void (*run)(struct quad_stage *qs, struct quad_header *quad[], unsigned nr); void (*destroy)(struct quad_stage *qs); }; @@ -69,6 +69,6 @@ struct quad_stage *sp_quad_output_stage( struct softpipe_context *softpipe ); void sp_build_quad_pipeline(struct softpipe_context *sp); -void sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad); +boolean sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad); #endif /* SP_QUAD_PIPE_H */ diff --git a/src/gallium/drivers/softpipe/sp_quad_stencil.c b/src/gallium/drivers/softpipe/sp_quad_stencil.c index 34a8d9e9f6a..706dd2f756b 100644 --- a/src/gallium/drivers/softpipe/sp_quad_stencil.c +++ b/src/gallium/drivers/softpipe/sp_quad_stencil.c @@ -198,7 +198,8 @@ apply_stencil_op(ubyte stencilVals[QUAD_SIZE], * depth testing. */ static void -stencil_test_quad(struct quad_stage *qs, struct quad_header *quad) +stencil_test_quad(struct quad_stage *qs, struct quad_header *quads[], + unsigned nr) { struct softpipe_context *softpipe = qs->softpipe; struct pipe_surface *ps = softpipe->framebuffer.zsbuf; @@ -206,9 +207,12 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad) ubyte ref, wrtMask, valMask; ubyte stencilVals[QUAD_SIZE]; struct softpipe_cached_tile *tile - = sp_get_cached_tile(softpipe->zsbuf_cache, quad->input.x0, quad->input.y0); - uint j; - uint face = quad->input.facing; + = sp_get_cached_tile(softpipe->zsbuf_cache, + quads[0]->input.x0, + quads[0]->input.y0); + uint face = quads[0]->input.facing; + uint pass = 0; + uint j, q; if (!softpipe->depth_stencil->stencil[1].enabled) { /* single-sided stencil test, use front (face=0) state */ @@ -227,103 +231,110 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad) assert(ps); /* shouldn't get here if there's no stencil buffer */ - /* get stencil values from cached tile */ - switch (ps->format) { - case PIPE_FORMAT_S8Z24_UNORM: - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - stencilVals[j] = tile->data.depth32[y][x] >> 24; - } - break; - case PIPE_FORMAT_Z24S8_UNORM: - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - stencilVals[j] = tile->data.depth32[y][x] & 0xff; - } - break; - case PIPE_FORMAT_S8_UNORM: - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - stencilVals[j] = tile->data.stencil8[y][x]; + for (q = 0; q < nr; q++) { + struct quad_header *quad = quads[q]; + + /* get stencil values from cached tile */ + switch (ps->format) { + case PIPE_FORMAT_S8Z24_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + stencilVals[j] = tile->data.depth32[y][x] >> 24; + } + break; + case PIPE_FORMAT_Z24S8_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + stencilVals[j] = tile->data.depth32[y][x] & 0xff; + } + break; + case PIPE_FORMAT_S8_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + stencilVals[j] = tile->data.stencil8[y][x]; + } + break; + default: + assert(0); } - break; - default: - assert(0); - } - /* do the stencil test first */ - { - unsigned passMask, failMask; - passMask = do_stencil_test(stencilVals, func, ref, valMask); - failMask = quad->inout.mask & ~passMask; - quad->inout.mask &= passMask; + /* do the stencil test first */ + { + unsigned passMask, failMask; + passMask = do_stencil_test(stencilVals, func, ref, valMask); + failMask = quad->inout.mask & ~passMask; + quad->inout.mask &= passMask; - if (failOp != PIPE_STENCIL_OP_KEEP) { - apply_stencil_op(stencilVals, failMask, failOp, ref, wrtMask); + if (failOp != PIPE_STENCIL_OP_KEEP) { + apply_stencil_op(stencilVals, failMask, failOp, ref, wrtMask); + } } - } - if (quad->inout.mask) { - /* now the pixels that passed the stencil test are depth tested */ - if (softpipe->depth_stencil->depth.enabled) { - const unsigned origMask = quad->inout.mask; + if (quad->inout.mask) { + /* now the pixels that passed the stencil test are depth tested */ + if (softpipe->depth_stencil->depth.enabled) { + const unsigned origMask = quad->inout.mask; - sp_depth_test_quad(qs, quad); /* quad->mask is updated */ + sp_depth_test_quad(qs, quad); /* quad->mask is updated */ - /* update stencil buffer values according to z pass/fail result */ - if (zFailOp != PIPE_STENCIL_OP_KEEP) { - const unsigned failMask = origMask & ~quad->inout.mask; - apply_stencil_op(stencilVals, failMask, zFailOp, ref, wrtMask); - } + /* update stencil buffer values according to z pass/fail result */ + if (zFailOp != PIPE_STENCIL_OP_KEEP) { + const unsigned failMask = origMask & ~quad->inout.mask; + apply_stencil_op(stencilVals, failMask, zFailOp, ref, wrtMask); + } - if (zPassOp != PIPE_STENCIL_OP_KEEP) { - const unsigned passMask = origMask & quad->inout.mask; - apply_stencil_op(stencilVals, passMask, zPassOp, ref, wrtMask); + if (zPassOp != PIPE_STENCIL_OP_KEEP) { + const unsigned passMask = origMask & quad->inout.mask; + apply_stencil_op(stencilVals, passMask, zPassOp, ref, wrtMask); + } + } + else { + /* no depth test, apply Zpass operator to stencil buffer values */ + apply_stencil_op(stencilVals, quad->inout.mask, zPassOp, ref, wrtMask); } - } - else { - /* no depth test, apply Zpass operator to stencil buffer values */ - apply_stencil_op(stencilVals, quad->inout.mask, zPassOp, ref, wrtMask); - } - - } - /* put new stencil values into cached tile */ - switch (ps->format) { - case PIPE_FORMAT_S8Z24_UNORM: - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - uint s8z24 = tile->data.depth32[y][x]; - s8z24 = (stencilVals[j] << 24) | (s8z24 & 0xffffff); - tile->data.depth32[y][x] = s8z24; } - break; - case PIPE_FORMAT_Z24S8_UNORM: - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - uint z24s8 = tile->data.depth32[y][x]; - z24s8 = (z24s8 & 0xffffff00) | stencilVals[j]; - tile->data.depth32[y][x] = z24s8; - } - break; - case PIPE_FORMAT_S8_UNORM: - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - tile->data.stencil8[y][x] = stencilVals[j]; + + /* put new stencil values into cached tile */ + switch (ps->format) { + case PIPE_FORMAT_S8Z24_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + uint s8z24 = tile->data.depth32[y][x]; + s8z24 = (stencilVals[j] << 24) | (s8z24 & 0xffffff); + tile->data.depth32[y][x] = s8z24; + } + break; + case PIPE_FORMAT_Z24S8_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + uint z24s8 = tile->data.depth32[y][x]; + z24s8 = (z24s8 & 0xffffff00) | stencilVals[j]; + tile->data.depth32[y][x] = z24s8; + } + break; + case PIPE_FORMAT_S8_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + tile->data.stencil8[y][x] = stencilVals[j]; + } + break; + default: + assert(0); } - break; - default: - assert(0); + + if (quad->inout.mask) + quads[pass++] = q; } - if (quad->inout.mask) - qs->next->run(qs->next, quad); + if (pass) + qs->next->run(qs->next, quads, pass); } diff --git a/src/gallium/drivers/softpipe/sp_quad_stipple.c b/src/gallium/drivers/softpipe/sp_quad_stipple.c index 07162db7b6e..05665d8e263 100644 --- a/src/gallium/drivers/softpipe/sp_quad_stipple.c +++ b/src/gallium/drivers/softpipe/sp_quad_stipple.c @@ -14,40 +14,46 @@ * Apply polygon stipple to quads produced by triangle rasterization */ static void -stipple_quad(struct quad_stage *qs, struct quad_header *quad) +stipple_quad(struct quad_stage *qs, struct quad_header *quads[], unsigned nr) { static const uint bit31 = 1 << 31; static const uint bit30 = 1 << 30; + unsigned pass = nr; - if (quad->input.prim == QUAD_PRIM_TRI) { + if (quads[0]->input.prim == QUAD_PRIM_TRI) { struct softpipe_context *softpipe = qs->softpipe; - /* need to invert Y to index into OpenGL's stipple pattern */ - const int col0 = quad->input.x0 % 32; - const int y0 = quad->input.y0; - const int y1 = y0 + 1; - const uint stipple0 = softpipe->poly_stipple.stipple[y0 % 32]; - const uint stipple1 = softpipe->poly_stipple.stipple[y1 % 32]; + unsigned q; - /* turn off quad mask bits that fail the stipple test */ - if ((stipple0 & (bit31 >> col0)) == 0) - quad->inout.mask &= ~MASK_TOP_LEFT; + pass = 0; - if ((stipple0 & (bit30 >> col0)) == 0) - quad->inout.mask &= ~MASK_TOP_RIGHT; + for (q = 0; q < nr; q++) { + struct quad_header *quad = quads[q]; - if ((stipple1 & (bit31 >> col0)) == 0) - quad->inout.mask &= ~MASK_BOTTOM_LEFT; + const int col0 = quad->input.x0 % 32; + const int y0 = quad->input.y0; + const int y1 = y0 + 1; + const uint stipple0 = softpipe->poly_stipple.stipple[y0 % 32]; + const uint stipple1 = softpipe->poly_stipple.stipple[y1 % 32]; - if ((stipple1 & (bit30 >> col0)) == 0) - quad->inout.mask &= ~MASK_BOTTOM_RIGHT; + /* turn off quad mask bits that fail the stipple test */ + if ((stipple0 & (bit31 >> col0)) == 0) + quad->inout.mask &= ~MASK_TOP_LEFT; - if (!quad->inout.mask) { - /* all fragments failed stipple test, end of quad pipeline */ - return; + if ((stipple0 & (bit30 >> col0)) == 0) + quad->inout.mask &= ~MASK_TOP_RIGHT; + + if ((stipple1 & (bit31 >> col0)) == 0) + quad->inout.mask &= ~MASK_BOTTOM_LEFT; + + if ((stipple1 & (bit30 >> col0)) == 0) + quad->inout.mask &= ~MASK_BOTTOM_RIGHT; + + if (quad->inout.mask) + quads[pass++] = quad; } } - qs->next->run(qs->next, quad); + qs->next->run(qs->next, quads, pass); } diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index eaf84ed9de9..23dcae89c69 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -172,7 +172,7 @@ clip_emit_quad( struct setup_context *setup, struct quad_header *quad ) if (quad->inout.mask) { struct softpipe_context *sp = setup->softpipe; - sp->quad.first->run( sp->quad.first, quad ); + sp->quad.first->run( sp->quad.first, &quad, 1 ); } } @@ -193,7 +193,7 @@ emit_quad( struct setup_context *setup, struct quad_header *quad, uint thread ) if (mask & 4) setup->numFragsEmitted++; if (mask & 8) setup->numFragsEmitted++; #endif - sp->quad.first->run( sp->quad.first, quad ); + sp->quad.first->run( sp->quad.first, &quad, 1 ); #if DEBUG_FRAGS mask = quad->inout.mask; if (mask & 1) setup->numFragsWritten++; -- cgit v1.2.3 From a1dbd7aa159e266592a1e52504680992327ca9e0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 24 Jul 2009 18:17:05 +0100 Subject: softpipe: actually pass >1 quad from triangle routine First attempt --- src/gallium/drivers/softpipe/sp_context.h | 11 +- src/gallium/drivers/softpipe/sp_prim_vbuf.c | 2 + src/gallium/drivers/softpipe/sp_quad.h | 6 +- src/gallium/drivers/softpipe/sp_quad_blend.c | 9 +- src/gallium/drivers/softpipe/sp_quad_coverage.c | 10 +- src/gallium/drivers/softpipe/sp_quad_pipe.c | 6 +- src/gallium/drivers/softpipe/sp_quad_stipple.c | 44 +++--- src/gallium/drivers/softpipe/sp_setup.c | 186 ++++++++++++------------ 8 files changed, 135 insertions(+), 139 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 414d903a376..153a648b0ef 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -96,7 +96,16 @@ struct softpipe_context { /** Which vertex shader output slot contains point size */ int psize_slot; - unsigned reduced_api_prim; /**< PIPE_PRIM_POINTS, _LINES or _TRIANGLES */ + /* The reduced version of the primitive supplied by the state + * tracker. + */ + unsigned reduced_api_prim; + + /* The reduced primitive after unfilled triangles, wide-line + * decomposition, etc, are taken into account. This is the + * primitive actually rasterized. + */ + unsigned reduced_prim; /** Derived from scissor and surface bounds: */ struct pipe_scissor_state cliprect; diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index 42021789ea8..1dd63d99ffd 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -44,6 +44,7 @@ #include "draw/draw_context.h" #include "draw/draw_vbuf.h" #include "util/u_memory.h" +#include "util/u_prim.h" #define SP_MAX_VBUF_INDEXES 1024 @@ -167,6 +168,7 @@ sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim) setup_prepare( setup_ctx ); + cvbr->softpipe->reduced_prim = u_reduced_prim(prim); cvbr->prim = prim; return TRUE; diff --git a/src/gallium/drivers/softpipe/sp_quad.h b/src/gallium/drivers/softpipe/sp_quad.h index bd6c6cb9123..a3236bd1169 100644 --- a/src/gallium/drivers/softpipe/sp_quad.h +++ b/src/gallium/drivers/softpipe/sp_quad.h @@ -97,10 +97,10 @@ struct quad_header { struct quad_header_inout inout; struct quad_header_output output; - const struct tgsi_interp_coef *coef; + /* Redundant/duplicated: + */ const struct tgsi_interp_coef *posCoef; - - unsigned nr_attrs; + const struct tgsi_interp_coef *coef; }; #endif /* SP_QUAD_H */ diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index fdf1bb45522..8ef8666c0e4 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -123,10 +123,6 @@ logicop_quad(struct quad_stage *qs, { struct softpipe_context *softpipe = qs->softpipe; uint cbuf; - struct softpipe_cached_tile * - tile = sp_get_cached_tile(softpipe->cbuf_cache[cbuf], - quads[0]->input.x0, - quads[0]->input.y0); /* loop over colorbuffer outputs */ for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) { @@ -137,6 +133,11 @@ logicop_quad(struct quad_stage *qs, uint *res4 = (uint *) res; uint i, j; + struct softpipe_cached_tile * + tile = sp_get_cached_tile(softpipe->cbuf_cache[cbuf], + quads[0]->input.x0, + quads[0]->input.y0); + for (i = 0; i < nr; i++) { struct quad_header *quad = quads[i]; float (*quadColor)[4] = quad->output.color[cbuf]; diff --git a/src/gallium/drivers/softpipe/sp_quad_coverage.c b/src/gallium/drivers/softpipe/sp_quad_coverage.c index eda5ce8e630..f06a385b3c2 100644 --- a/src/gallium/drivers/softpipe/sp_quad_coverage.c +++ b/src/gallium/drivers/softpipe/sp_quad_coverage.c @@ -69,16 +69,10 @@ coverage_run(struct quad_stage *qs, unsigned nr) { struct softpipe_context *softpipe = qs->softpipe; - const uint prim = quads[0]->input.prim; unsigned i; - if ((softpipe->rasterizer->poly_smooth && prim == QUAD_PRIM_TRI) || - (softpipe->rasterizer->line_smooth && prim == QUAD_PRIM_LINE) || - (softpipe->rasterizer->point_smooth && prim == QUAD_PRIM_POINT)) { - - for (i = 0; i < nr; i++) - coverage_quad( qs, quads[i] ); - } + for (i = 0; i < nr; i++) + coverage_quad( qs, quads[i] ); qs->next->run(qs->next, quads, nr); } diff --git a/src/gallium/drivers/softpipe/sp_quad_pipe.c b/src/gallium/drivers/softpipe/sp_quad_pipe.c index 594fade4557..6fae7d552f8 100644 --- a/src/gallium/drivers/softpipe/sp_quad_pipe.c +++ b/src/gallium/drivers/softpipe/sp_quad_pipe.c @@ -76,9 +76,9 @@ sp_build_quad_pipeline(struct softpipe_context *sp) sp_push_quad_first( sp, sp->quad.blend ); } - if (sp->rasterizer->poly_smooth || - sp->rasterizer->line_smooth || - sp->rasterizer->point_smooth) { + if ((sp->rasterizer->poly_smooth && sp->reduced_prim == PIPE_PRIM_TRIANGLES) || + (sp->rasterizer->line_smooth && sp->reduced_prim == PIPE_PRIM_LINES) || + (sp->rasterizer->point_smooth && sp->reduced_prim == PIPE_PRIM_POINTS)) { sp_push_quad_first( sp, sp->quad.coverage ); } diff --git a/src/gallium/drivers/softpipe/sp_quad_stipple.c b/src/gallium/drivers/softpipe/sp_quad_stipple.c index 05665d8e263..a0527a596a6 100644 --- a/src/gallium/drivers/softpipe/sp_quad_stipple.c +++ b/src/gallium/drivers/softpipe/sp_quad_stipple.c @@ -20,37 +20,35 @@ stipple_quad(struct quad_stage *qs, struct quad_header *quads[], unsigned nr) static const uint bit30 = 1 << 30; unsigned pass = nr; - if (quads[0]->input.prim == QUAD_PRIM_TRI) { - struct softpipe_context *softpipe = qs->softpipe; - unsigned q; + struct softpipe_context *softpipe = qs->softpipe; + unsigned q; - pass = 0; + pass = 0; - for (q = 0; q < nr; q++) { - struct quad_header *quad = quads[q]; + for (q = 0; q < nr; q++) { + struct quad_header *quad = quads[q]; - const int col0 = quad->input.x0 % 32; - const int y0 = quad->input.y0; - const int y1 = y0 + 1; - const uint stipple0 = softpipe->poly_stipple.stipple[y0 % 32]; - const uint stipple1 = softpipe->poly_stipple.stipple[y1 % 32]; + const int col0 = quad->input.x0 % 32; + const int y0 = quad->input.y0; + const int y1 = y0 + 1; + const uint stipple0 = softpipe->poly_stipple.stipple[y0 % 32]; + const uint stipple1 = softpipe->poly_stipple.stipple[y1 % 32]; - /* turn off quad mask bits that fail the stipple test */ - if ((stipple0 & (bit31 >> col0)) == 0) - quad->inout.mask &= ~MASK_TOP_LEFT; + /* turn off quad mask bits that fail the stipple test */ + if ((stipple0 & (bit31 >> col0)) == 0) + quad->inout.mask &= ~MASK_TOP_LEFT; - if ((stipple0 & (bit30 >> col0)) == 0) - quad->inout.mask &= ~MASK_TOP_RIGHT; + if ((stipple0 & (bit30 >> col0)) == 0) + quad->inout.mask &= ~MASK_TOP_RIGHT; - if ((stipple1 & (bit31 >> col0)) == 0) - quad->inout.mask &= ~MASK_BOTTOM_LEFT; + if ((stipple1 & (bit31 >> col0)) == 0) + quad->inout.mask &= ~MASK_BOTTOM_LEFT; - if ((stipple1 & (bit30 >> col0)) == 0) - quad->inout.mask &= ~MASK_BOTTOM_RIGHT; + if ((stipple1 & (bit30 >> col0)) == 0) + quad->inout.mask &= ~MASK_BOTTOM_RIGHT; - if (quad->inout.mask) - quads[pass++] = quad; - } + if (quad->inout.mask) + quads[pass++] = quad; } qs->next->run(qs->next, quads, pass); diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 23dcae89c69..a132911c99d 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -62,6 +62,8 @@ struct edge { }; +#define MAX_QUADS 16 + /** * Triangle setup info (derived from draw_stage). @@ -84,10 +86,14 @@ struct setup_context { struct edge emaj; float oneoverarea; + int facing; + + struct quad_header quad[MAX_QUADS]; + struct quad_header *quad_ptrs[MAX_QUADS]; + unsigned count; struct tgsi_interp_coef coef[PIPE_MAX_SHADER_INPUTS]; struct tgsi_interp_coef posCoef; /* For Z, W */ - struct quad_header quad; struct { int left[2]; /**< [0] = row0, [1] = row1 */ @@ -176,41 +182,6 @@ clip_emit_quad( struct setup_context *setup, struct quad_header *quad ) } } -/** - * Emit a quad (pass to next stage). No clipping is done. - */ -static INLINE void -emit_quad( struct setup_context *setup, struct quad_header *quad, uint thread ) -{ - struct softpipe_context *sp = setup->softpipe; -#if DEBUG_FRAGS - uint mask = quad->inout.mask; -#endif - -#if DEBUG_FRAGS - if (mask & 1) setup->numFragsEmitted++; - if (mask & 2) setup->numFragsEmitted++; - if (mask & 4) setup->numFragsEmitted++; - if (mask & 8) setup->numFragsEmitted++; -#endif - sp->quad.first->run( sp->quad.first, &quad, 1 ); -#if DEBUG_FRAGS - mask = quad->inout.mask; - if (mask & 1) setup->numFragsWritten++; - if (mask & 2) setup->numFragsWritten++; - if (mask & 4) setup->numFragsWritten++; - if (mask & 8) setup->numFragsWritten++; -#endif -} - - -#define EMIT_QUAD(setup,x,y,qmask) \ -do { \ - setup->quad.input.x0 = x; \ - setup->quad.input.y0 = y; \ - setup->quad.inout.mask = qmask; \ - emit_quad( setup, &setup->quad, 0 ); \ -} while (0) /** @@ -219,7 +190,12 @@ do { \ */ static INLINE int block( int x ) { - return x & ~1; + return x & ~(2-1); +} + +static INLINE int block_x( int x ) +{ + return x & ~(16-1); } @@ -228,13 +204,15 @@ static INLINE int block( int x ) */ static void flush_spans( struct setup_context *setup ) { - const int step = 30; + const int step = 16; const int xleft0 = setup->span.left[0]; const int xleft1 = setup->span.left[1]; const int xright0 = setup->span.right[0]; const int xright1 = setup->span.right[1]; + struct quad_stage *pipe = setup->softpipe->quad.first; + - int minleft = block(MIN2(xleft0, xleft1)); + int minleft = block_x(MIN2(xleft0, xleft1)); int maxright = MAX2(xright0, xright1); int x; @@ -244,7 +222,8 @@ static void flush_spans( struct setup_context *setup ) unsigned skip_right0 = CLAMP(x + step - xright0, 0, step); unsigned skip_right1 = CLAMP(x + step - xright1, 0, step); unsigned lx = x; - + unsigned q = 0; + unsigned skipmask_left0 = (1U << skip_left0) - 1U; unsigned skipmask_left1 = (1U << skip_left1) - 1U; @@ -256,13 +235,22 @@ static void flush_spans( struct setup_context *setup ) unsigned mask0 = ~skipmask_left0 & ~skipmask_right0; unsigned mask1 = ~skipmask_left1 & ~skipmask_right1; - while (mask0 | mask1) { - unsigned quadmask = (mask0 & 3) | ((mask1 & 3) << 2); - if (quadmask) - EMIT_QUAD( setup, lx, setup->span.y, quadmask ); - mask0 >>= 2; - mask1 >>= 2; - lx += 2; + if (mask0 | mask1) { + do { + unsigned quadmask = (mask0 & 3) | ((mask1 & 3) << 2); + if (quadmask) { + setup->quad[q].input.x0 = lx; + setup->quad[q].input.y0 = setup->span.y; + setup->quad[q].inout.mask = quadmask; + setup->quad_ptrs[q] = &setup->quad[q]; + q++; + } + mask0 >>= 2; + mask1 >>= 2; + lx += 2; + } while (mask0 | mask1); + + pipe->run( pipe, setup->quad_ptrs, q ); } } @@ -281,7 +269,7 @@ static void print_vertex(const struct setup_context *setup, { int i; debug_printf(" Vertex: (%p)\n", v); - for (i = 0; i < setup->quad.nr_attrs; i++) { + for (i = 0; i < setup->quad[0].nr_attrs; i++) { debug_printf(" %d: %f %f %f %f\n", i, v[i][0], v[i][1], v[i][2], v[i][3]); if (util_is_inf_or_nan(v[i][0])) { @@ -386,7 +374,9 @@ static boolean setup_sort_vertices( struct setup_context *setup, * - the GLSL gl_FrontFacing fragment attribute (bool) * - two-sided stencil test */ - setup->quad.input.facing = (det > 0.0) ^ (setup->softpipe->rasterizer->front_winding == PIPE_WINDING_CW); + setup->facing = + ((det > 0.0) ^ + (setup->softpipe->rasterizer->front_winding == PIPE_WINDING_CW)); return TRUE; } @@ -573,7 +563,7 @@ static void setup_tri_coefficients( struct setup_context *setup ) } if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { - setup->coef[fragSlot].a0[0] = 1.0f - setup->quad.input.facing; + setup->coef[fragSlot].a0[0] = 1.0f - setup->facing; setup->coef[fragSlot].dadx[0] = 0.0; setup->coef[fragSlot].dady[0] = 0.0; } @@ -741,7 +731,7 @@ void setup_tri( struct setup_context *setup, setup_tri_coefficients( setup ); setup_tri_edges( setup ); - setup->quad.input.prim = QUAD_PRIM_TRI; + assert(setup->softpipe->reduced_prim == PIPE_PRIM_TRIANGLES); setup->span.y = 0; setup->span.right[0] = 0; @@ -881,7 +871,7 @@ setup_line_coefficients(struct setup_context *setup, } if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { - setup->coef[fragSlot].a0[0] = 1.0f - setup->quad.input.facing; + setup->coef[fragSlot].a0[0] = 1.0f - setup->facing; setup->coef[fragSlot].dadx[0] = 0.0; setup->coef[fragSlot].dady[0] = 0.0; } @@ -902,20 +892,20 @@ plot(struct setup_context *setup, int x, int y) const int quadY = y - iy; const int mask = (1 << ix) << (2 * iy); - if (quadX != setup->quad.input.x0 || - quadY != setup->quad.input.y0) + if (quadX != setup->quad[0].input.x0 || + quadY != setup->quad[0].input.y0) { /* flush prev quad, start new quad */ - if (setup->quad.input.x0 != -1) - clip_emit_quad( setup, &setup->quad ); + if (setup->quad[0].input.x0 != -1) + clip_emit_quad( setup, &setup->quad[0] ); - setup->quad.input.x0 = quadX; - setup->quad.input.y0 = quadY; - setup->quad.inout.mask = 0x0; + setup->quad[0].input.x0 = quadX; + setup->quad[0].input.y0 = quadY; + setup->quad[0].inout.mask = 0x0; } - setup->quad.inout.mask |= mask; + setup->quad[0].inout.mask |= mask; } @@ -975,17 +965,18 @@ setup_line(struct setup_context *setup, assert(dx >= 0); assert(dy >= 0); + assert(setup->softpipe->reduced_prim == PIPE_PRIM_LINES); + + setup->quad[0].input.x0 = setup->quad[0].input.y0 = -1; + setup->quad[0].inout.mask = 0x0; - setup->quad.input.x0 = setup->quad.input.y0 = -1; - setup->quad.inout.mask = 0x0; - setup->quad.input.prim = QUAD_PRIM_LINE; /* XXX temporary: set coverage to 1.0 so the line appears * if AA mode happens to be enabled. */ - setup->quad.input.coverage[0] = - setup->quad.input.coverage[1] = - setup->quad.input.coverage[2] = - setup->quad.input.coverage[3] = 1.0; + setup->quad[0].input.coverage[0] = + setup->quad[0].input.coverage[1] = + setup->quad[0].input.coverage[2] = + setup->quad[0].input.coverage[3] = 1.0; if (dx > dy) { /*** X-major line ***/ @@ -1029,8 +1020,8 @@ setup_line(struct setup_context *setup, } /* draw final quad */ - if (setup->quad.inout.mask) { - clip_emit_quad( setup, &setup->quad ); + if (setup->quad[0].inout.mask) { + clip_emit_quad( setup, &setup->quad[0] ); } } @@ -1078,6 +1069,8 @@ setup_point( struct setup_context *setup, if (softpipe->no_rast) return; + assert(setup->softpipe->reduced_prim == PIPE_PRIM_POINTS); + /* For points, all interpolants are constant-valued. * However, for point sprites, we'll need to setup texcoords appropriately. * XXX: which coefficients are the texcoords??? @@ -1124,22 +1117,21 @@ setup_point( struct setup_context *setup, } if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { - setup->coef[fragSlot].a0[0] = 1.0f - setup->quad.input.facing; + setup->coef[fragSlot].a0[0] = 1.0f - setup->facing; setup->coef[fragSlot].dadx[0] = 0.0; setup->coef[fragSlot].dady[0] = 0.0; } } - setup->quad.input.prim = QUAD_PRIM_POINT; if (halfSize <= 0.5 && !round) { /* special case for 1-pixel points */ const int ix = ((int) x) & 1; const int iy = ((int) y) & 1; - setup->quad.input.x0 = (int) x - ix; - setup->quad.input.y0 = (int) y - iy; - setup->quad.inout.mask = (1 << ix) << (2 * iy); - clip_emit_quad( setup, &setup->quad ); + setup->quad[0].input.x0 = (int) x - ix; + setup->quad[0].input.y0 = (int) y - iy; + setup->quad[0].inout.mask = (1 << ix) << (2 * iy); + clip_emit_quad( setup, &setup->quad[0] ); } else { if (round) { @@ -1159,15 +1151,15 @@ setup_point( struct setup_context *setup, for (ix = ixmin; ix <= ixmax; ix += 2) { float dx, dy, dist2, cover; - setup->quad.inout.mask = 0x0; + setup->quad[0].inout.mask = 0x0; dx = (ix + 0.5f) - x; dy = (iy + 0.5f) - y; dist2 = dx * dx + dy * dy; if (dist2 <= rmax2) { cover = 1.0F - (dist2 - rmin2) * cscale; - setup->quad.input.coverage[QUAD_TOP_LEFT] = MIN2(cover, 1.0f); - setup->quad.inout.mask |= MASK_TOP_LEFT; + setup->quad[0].input.coverage[QUAD_TOP_LEFT] = MIN2(cover, 1.0f); + setup->quad[0].inout.mask |= MASK_TOP_LEFT; } dx = (ix + 1.5f) - x; @@ -1175,8 +1167,8 @@ setup_point( struct setup_context *setup, dist2 = dx * dx + dy * dy; if (dist2 <= rmax2) { cover = 1.0F - (dist2 - rmin2) * cscale; - setup->quad.input.coverage[QUAD_TOP_RIGHT] = MIN2(cover, 1.0f); - setup->quad.inout.mask |= MASK_TOP_RIGHT; + setup->quad[0].input.coverage[QUAD_TOP_RIGHT] = MIN2(cover, 1.0f); + setup->quad[0].inout.mask |= MASK_TOP_RIGHT; } dx = (ix + 0.5f) - x; @@ -1184,8 +1176,8 @@ setup_point( struct setup_context *setup, dist2 = dx * dx + dy * dy; if (dist2 <= rmax2) { cover = 1.0F - (dist2 - rmin2) * cscale; - setup->quad.input.coverage[QUAD_BOTTOM_LEFT] = MIN2(cover, 1.0f); - setup->quad.inout.mask |= MASK_BOTTOM_LEFT; + setup->quad[0].input.coverage[QUAD_BOTTOM_LEFT] = MIN2(cover, 1.0f); + setup->quad[0].inout.mask |= MASK_BOTTOM_LEFT; } dx = (ix + 1.5f) - x; @@ -1193,14 +1185,14 @@ setup_point( struct setup_context *setup, dist2 = dx * dx + dy * dy; if (dist2 <= rmax2) { cover = 1.0F - (dist2 - rmin2) * cscale; - setup->quad.input.coverage[QUAD_BOTTOM_RIGHT] = MIN2(cover, 1.0f); - setup->quad.inout.mask |= MASK_BOTTOM_RIGHT; + setup->quad[0].input.coverage[QUAD_BOTTOM_RIGHT] = MIN2(cover, 1.0f); + setup->quad[0].inout.mask |= MASK_BOTTOM_RIGHT; } - if (setup->quad.inout.mask) { - setup->quad.input.x0 = ix; - setup->quad.input.y0 = iy; - clip_emit_quad( setup, &setup->quad ); + if (setup->quad[0].inout.mask) { + setup->quad[0].input.x0 = ix; + setup->quad[0].input.y0 = iy; + clip_emit_quad( setup, &setup->quad[0] ); } } } @@ -1244,10 +1236,10 @@ setup_point( struct setup_context *setup, mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); } - setup->quad.inout.mask = mask; - setup->quad.input.x0 = ix; - setup->quad.input.y0 = iy; - clip_emit_quad( setup, &setup->quad ); + setup->quad[0].inout.mask = mask; + setup->quad[0].input.x0 = ix; + setup->quad[0].input.y0 = iy; + clip_emit_quad( setup, &setup->quad[0] ); } } } @@ -1262,9 +1254,6 @@ void setup_prepare( struct setup_context *setup ) softpipe_update_derived(sp); } - /* Note: nr_attrs is only used for debugging (vertex printing) */ - setup->quad.nr_attrs = draw_num_vs_outputs(sp->draw); - sp->quad.first->begin( sp->quad.first ); if (sp->reduced_api_prim == PIPE_PRIM_TRIANGLES && @@ -1293,11 +1282,14 @@ void setup_destroy_context( struct setup_context *setup ) struct setup_context *setup_create_context( struct softpipe_context *softpipe ) { struct setup_context *setup = CALLOC_STRUCT(setup_context); + unsigned i; setup->softpipe = softpipe; - setup->quad.coef = setup->coef; - setup->quad.posCoef = &setup->posCoef; + for (i = 0; i < MAX_QUADS; i++) { + setup->quad[i].coef = setup->coef; + setup->quad[i].posCoef = &setup->posCoef; + } setup->span.left[0] = 1000000; /* greater than right[0] */ setup->span.left[1] = 1000000; /* greater than right[1] */ -- cgit v1.2.3 From 333ec94380af502b1c492f61dcc1897bcf43a96c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 24 Jul 2009 18:46:17 +0100 Subject: softpipe: example fastpaths in blending --- src/gallium/drivers/softpipe/sp_quad_blend.c | 132 ++++++++++++++++++++++++--- 1 file changed, 121 insertions(+), 11 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index 8ef8666c0e4..1ef7529cff7 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -117,9 +117,9 @@ do { \ static void -logicop_quad(struct quad_stage *qs, - struct quad_header *quads[], - unsigned nr) +logicop_quads(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) { struct softpipe_context *softpipe = qs->softpipe; uint cbuf; @@ -241,13 +241,102 @@ logicop_quad(struct quad_stage *qs, } } } + + /* pass blended quad to next stage */ + qs->next->run(qs->next, quads, nr); +} + +static void +blend_single_add_src_alpha_inv_src_alpha(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) +{ + static const float one[4] = { 1, 1, 1, 1 }; + float one_minus_alpha[QUAD_SIZE]; + float dest[4][QUAD_SIZE]; + float source[4][QUAD_SIZE]; + uint i, j, q; + + struct softpipe_cached_tile *tile + = sp_get_cached_tile(qs->softpipe->cbuf_cache[0], + quads[0]->input.x0, + quads[0]->input.y0); + + for (q = 0; q < nr; q++) { + struct quad_header *quad = quads[q]; + float (*quadColor)[4] = quad->output.color[0]; + const float *alpha = quadColor[3]; + + /* get/swizzle dest colors */ + for (j = 0; j < QUAD_SIZE; j++) { + int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1); + int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1); + for (i = 0; i < 4; i++) { + dest[i][j] = tile->data.color[y][x][i]; + } + } + + VEC4_MUL(source[0], quadColor[0], alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], alpha); /* B */ + VEC4_MUL(source[3], quadColor[3], alpha); /* A */ + + VEC4_SUB(one_minus_alpha, one, alpha); + VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */ + VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */ + VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */ + VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* B */ + + VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */ + VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */ + VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */ + VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */ + } + + /* pass blended quad to next stage */ + qs->next->run(qs->next, quads, nr); } +static void +blend_single_add_one_one(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) +{ + float dest[4][QUAD_SIZE]; + uint i, j, q; + + struct softpipe_cached_tile *tile + = sp_get_cached_tile(qs->softpipe->cbuf_cache[0], + quads[0]->input.x0, + quads[0]->input.y0); + + for (q = 0; q < nr; q++) { + struct quad_header *quad = quads[q]; + float (*quadColor)[4] = quad->output.color[0]; + + /* get/swizzle dest colors */ + for (j = 0; j < QUAD_SIZE; j++) { + int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1); + int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1); + for (i = 0; i < 4; i++) { + dest[i][j] = tile->data.color[y][x][i]; + } + } + + VEC4_ADD_SAT(quadColor[0], quadColor[0], dest[0]); /* R */ + VEC4_ADD_SAT(quadColor[1], quadColor[1], dest[1]); /* G */ + VEC4_ADD_SAT(quadColor[2], quadColor[2], dest[2]); /* B */ + VEC4_ADD_SAT(quadColor[3], quadColor[3], dest[3]); /* A */ + } + + /* pass blended quad to next stage */ + qs->next->run(qs->next, quads, nr); +} static void -blend_quads(struct quad_stage *qs, - struct quad_header *quads[], - unsigned nr) +blend_quads_fallback(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) { static const float zero[4] = { 0, 0, 0, 0 }; static const float one[4] = { 1, 1, 1, 1 }; @@ -747,6 +836,9 @@ blend_quads(struct quad_stage *qs, } } } /* cbuf loop */ + + /* pass blended quad to next stage */ + qs->next->run(qs->next, quads, nr); } @@ -756,21 +848,39 @@ blend_quad(struct quad_stage *qs, unsigned nr) { struct softpipe_context *softpipe = qs->softpipe; + const struct pipe_blend_state *blend = softpipe->blend; if (softpipe->blend->logicop_enable) { - logicop_quad(qs, quads, nr); + qs->run = logicop_quads; } - else if (softpipe->blend->blend_enable) { - blend_quads(qs, quads, nr ); + else { + qs->run = blend_quads_fallback; + + if (blend->rgb_src_factor == blend->alpha_src_factor && + blend->rgb_dst_factor == blend->alpha_dst_factor && + blend->rgb_func == blend->alpha_func && + softpipe->framebuffer.nr_cbufs == 1) + { + if (blend->alpha_func == PIPE_BLEND_ADD) { + if (blend->rgb_src_factor == PIPE_BLENDFACTOR_ONE && + blend->rgb_dst_factor == PIPE_BLENDFACTOR_ONE) { + qs->run = blend_single_add_one_one; + } + else if (blend->rgb_src_factor == PIPE_BLENDFACTOR_SRC_ALPHA && + blend->rgb_dst_factor == PIPE_BLENDFACTOR_INV_SRC_ALPHA) + qs->run = blend_single_add_src_alpha_inv_src_alpha; + + } + } } - /* pass blended quad to next stage */ - qs->next->run(qs->next, quads, nr); + qs->run(qs, quads, nr); } static void blend_begin(struct quad_stage *qs) { + qs->run = blend_quad; qs->next->begin(qs->next); } -- cgit v1.2.3 From 42f1757189ba965e6d917d1124d0d6cf78b19a70 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 24 Jul 2009 20:18:52 +0100 Subject: softpipe: fix typo --- src/gallium/drivers/softpipe/sp_quad_stencil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_quad_stencil.c b/src/gallium/drivers/softpipe/sp_quad_stencil.c index 706dd2f756b..d9ee80e59a3 100644 --- a/src/gallium/drivers/softpipe/sp_quad_stencil.c +++ b/src/gallium/drivers/softpipe/sp_quad_stencil.c @@ -330,7 +330,7 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quads[], } if (quad->inout.mask) - quads[pass++] = q; + quads[pass++] = quad; } if (pass) -- cgit v1.2.3 From a2f7ab1d155da52c689f7c6390c233e4eae44643 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 24 Jul 2009 20:19:18 +0100 Subject: softpipe: move all color-combine code into sp_quad_blend.c Consolidate the read-modify-write color combining code from the blend, colormask and output stages. --- src/gallium/drivers/softpipe/Makefile | 14 +- src/gallium/drivers/softpipe/SConscript | 2 - src/gallium/drivers/softpipe/sp_context.c | 4 - src/gallium/drivers/softpipe/sp_context.h | 2 - src/gallium/drivers/softpipe/sp_quad_blend.c | 1352 ++++++++++++---------- src/gallium/drivers/softpipe/sp_quad_bufloop.c | 74 -- src/gallium/drivers/softpipe/sp_quad_colormask.c | 126 -- src/gallium/drivers/softpipe/sp_quad_coverage.c | 1 - src/gallium/drivers/softpipe/sp_quad_output.c | 109 -- src/gallium/drivers/softpipe/sp_quad_pipe.c | 15 +- 10 files changed, 727 insertions(+), 972 deletions(-) delete mode 100644 src/gallium/drivers/softpipe/sp_quad_bufloop.c delete mode 100644 src/gallium/drivers/softpipe/sp_quad_colormask.c delete mode 100644 src/gallium/drivers/softpipe/sp_quad_output.c (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile index 516e3992fdd..bdc1a5819fc 100644 --- a/src/gallium/drivers/softpipe/Makefile +++ b/src/gallium/drivers/softpipe/Makefile @@ -15,17 +15,15 @@ C_SOURCES = \ sp_prim_setup.c \ sp_prim_vbuf.c \ sp_quad_pipe.c \ - sp_quad_alpha_test.c \ - sp_quad_blend.c \ - sp_quad_colormask.c \ - sp_quad_coverage.c \ - sp_quad_depth_test.c \ + sp_quad_stipple.c \ sp_quad_earlyz.c \ + sp_quad_depth_test.c \ + sp_quad_stencil.c \ sp_quad_fs.c \ + sp_quad_alpha_test.c \ sp_quad_occlusion.c \ - sp_quad_output.c \ - sp_quad_stencil.c \ - sp_quad_stipple.c \ + sp_quad_coverage.c \ + sp_quad_blend.c \ sp_screen.c \ sp_setup.c \ sp_state_blend.c \ diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript index f8720638a76..dcc25732baf 100644 --- a/src/gallium/drivers/softpipe/SConscript +++ b/src/gallium/drivers/softpipe/SConscript @@ -18,13 +18,11 @@ softpipe = env.ConvenienceLibrary( 'sp_quad_alpha_test.c', 'sp_quad_blend.c', 'sp_quad_pipe.c', - 'sp_quad_colormask.c', 'sp_quad_coverage.c', 'sp_quad_depth_test.c', 'sp_quad_earlyz.c', 'sp_quad_fs.c', 'sp_quad_occlusion.c', - 'sp_quad_output.c', 'sp_quad_stencil.c', 'sp_quad_stipple.c', 'sp_query.c', diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 4418ef0ff4c..28a0dd62ac2 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -97,8 +97,6 @@ static void softpipe_destroy( struct pipe_context *pipe ) softpipe->quad.occlusion->destroy( softpipe->quad.occlusion ); softpipe->quad.coverage->destroy( softpipe->quad.coverage ); softpipe->quad.blend->destroy( softpipe->quad.blend ); - softpipe->quad.colormask->destroy( softpipe->quad.colormask ); - softpipe->quad.output->destroy( softpipe->quad.output ); for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) sp_destroy_tile_cache(softpipe->cbuf_cache[i]); @@ -241,8 +239,6 @@ softpipe_create( struct pipe_screen *screen ) softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe); softpipe->quad.coverage = sp_quad_coverage_stage(softpipe); softpipe->quad.blend = sp_quad_blend_stage(softpipe); - softpipe->quad.colormask = sp_quad_colormask_stage(softpipe); - softpipe->quad.output = sp_quad_output_stage(softpipe); /* vertex shader samplers */ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 153a648b0ef..b76ff610a3f 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -123,8 +123,6 @@ struct softpipe_context { struct quad_stage *occlusion; struct quad_stage *coverage; struct quad_stage *blend; - struct quad_stage *colormask; - struct quad_stage *output; struct quad_stage *first; /**< points to one of the above stages */ } quad; diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index 1ef7529cff7..e1f0e772554 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -117,135 +117,677 @@ do { \ static void -logicop_quads(struct quad_stage *qs, - struct quad_header *quads[], - unsigned nr) +logicop_quad(struct quad_stage *qs, + float (*quadColor)[4], + float (*dest)[4]) { struct softpipe_context *softpipe = qs->softpipe; - uint cbuf; + ubyte src[4][4], dst[4][4], res[4][4]; + uint *src4 = (uint *) src; + uint *dst4 = (uint *) dst; + uint *res4 = (uint *) res; + uint j; + + + /* convert to ubyte */ + for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */ + dst[j][0] = float_to_ubyte(dest[j][0]); /* P0 */ + dst[j][1] = float_to_ubyte(dest[j][1]); /* P1 */ + dst[j][2] = float_to_ubyte(dest[j][2]); /* P2 */ + dst[j][3] = float_to_ubyte(dest[j][3]); /* P3 */ + + src[j][0] = float_to_ubyte(quadColor[j][0]); /* P0 */ + src[j][1] = float_to_ubyte(quadColor[j][1]); /* P1 */ + src[j][2] = float_to_ubyte(quadColor[j][2]); /* P2 */ + src[j][3] = float_to_ubyte(quadColor[j][3]); /* P3 */ + } + + switch (softpipe->blend->logicop_func) { + case PIPE_LOGICOP_CLEAR: + for (j = 0; j < 4; j++) + res4[j] = 0; + break; + case PIPE_LOGICOP_NOR: + for (j = 0; j < 4; j++) + res4[j] = ~(src4[j] | dst4[j]); + break; + case PIPE_LOGICOP_AND_INVERTED: + for (j = 0; j < 4; j++) + res4[j] = ~src4[j] & dst4[j]; + break; + case PIPE_LOGICOP_COPY_INVERTED: + for (j = 0; j < 4; j++) + res4[j] = ~src4[j]; + break; + case PIPE_LOGICOP_AND_REVERSE: + for (j = 0; j < 4; j++) + res4[j] = src4[j] & ~dst4[j]; + break; + case PIPE_LOGICOP_INVERT: + for (j = 0; j < 4; j++) + res4[j] = ~dst4[j]; + break; + case PIPE_LOGICOP_XOR: + for (j = 0; j < 4; j++) + res4[j] = dst4[j] ^ src4[j]; + break; + case PIPE_LOGICOP_NAND: + for (j = 0; j < 4; j++) + res4[j] = ~(src4[j] & dst4[j]); + break; + case PIPE_LOGICOP_AND: + for (j = 0; j < 4; j++) + res4[j] = src4[j] & dst4[j]; + break; + case PIPE_LOGICOP_EQUIV: + for (j = 0; j < 4; j++) + res4[j] = ~(src4[j] ^ dst4[j]); + break; + case PIPE_LOGICOP_NOOP: + for (j = 0; j < 4; j++) + res4[j] = dst4[j]; + break; + case PIPE_LOGICOP_OR_INVERTED: + for (j = 0; j < 4; j++) + res4[j] = ~src4[j] | dst4[j]; + break; + case PIPE_LOGICOP_COPY: + for (j = 0; j < 4; j++) + res4[j] = src4[j]; + break; + case PIPE_LOGICOP_OR_REVERSE: + for (j = 0; j < 4; j++) + res4[j] = src4[j] | ~dst4[j]; + break; + case PIPE_LOGICOP_OR: + for (j = 0; j < 4; j++) + res4[j] = src4[j] | dst4[j]; + break; + case PIPE_LOGICOP_SET: + for (j = 0; j < 4; j++) + res4[j] = ~0; + break; + default: + assert(0); + } + + for (j = 0; j < 4; j++) { + quadColor[j][0] = ubyte_to_float(res[j][0]); + quadColor[j][1] = ubyte_to_float(res[j][1]); + quadColor[j][2] = ubyte_to_float(res[j][2]); + quadColor[j][3] = ubyte_to_float(res[j][3]); + } +} + + + +static void +blend_quad(struct quad_stage *qs, + float (*quadColor)[4], + float (*dest)[4]) +{ + static const float zero[4] = { 0, 0, 0, 0 }; + static const float one[4] = { 1, 1, 1, 1 }; + struct softpipe_context *softpipe = qs->softpipe; + float source[4][QUAD_SIZE]; + + /* + * Compute src/first term RGB + */ + switch (softpipe->blend->rgb_src_factor) { + case PIPE_BLENDFACTOR_ONE: + VEC4_COPY(source[0], quadColor[0]); /* R */ + VEC4_COPY(source[1], quadColor[1]); /* G */ + VEC4_COPY(source[2], quadColor[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + VEC4_MUL(source[0], quadColor[0], quadColor[0]); /* R */ + VEC4_MUL(source[1], quadColor[1], quadColor[1]); /* G */ + VEC4_MUL(source[2], quadColor[2], quadColor[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA: + { + const float *alpha = quadColor[3]; + VEC4_MUL(source[0], quadColor[0], alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_DST_COLOR: + VEC4_MUL(source[0], quadColor[0], dest[0]); /* R */ + VEC4_MUL(source[1], quadColor[1], dest[1]); /* G */ + VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */ + break; + case PIPE_BLENDFACTOR_DST_ALPHA: + { + const float *alpha = dest[3]; + VEC4_MUL(source[0], quadColor[0], alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + { + const float *alpha = quadColor[3]; + float diff[4], temp[4]; + VEC4_SUB(diff, one, dest[3]); + VEC4_MIN(temp, alpha, diff); + VEC4_MUL(source[0], quadColor[0], temp); /* R */ + VEC4_MUL(source[1], quadColor[1], temp); /* G */ + VEC4_MUL(source[2], quadColor[2], temp); /* B */ + } + break; + case PIPE_BLENDFACTOR_CONST_COLOR: + { + float comp[4]; + VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */ + VEC4_MUL(source[0], quadColor[0], comp); /* R */ + VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */ + VEC4_MUL(source[1], quadColor[1], comp); /* G */ + VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */ + VEC4_MUL(source[2], quadColor[2], comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_CONST_ALPHA: + { + float alpha[4]; + VEC4_SCALAR(alpha, softpipe->blend_color.color[3]); + VEC4_MUL(source[0], quadColor[0], alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_SRC1_COLOR: + assert(0); /* to do */ + break; + case PIPE_BLENDFACTOR_SRC1_ALPHA: + assert(0); /* to do */ + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(source[0], zero); /* R */ + VEC4_COPY(source[1], zero); /* G */ + VEC4_COPY(source[2], zero); /* B */ + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, quadColor[0]); /* R */ + VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */ + VEC4_SUB(inv_comp, one, quadColor[1]); /* G */ + VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */ + VEC4_SUB(inv_comp, one, quadColor[2]); /* B */ + VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + { + float inv_alpha[4]; + VEC4_SUB(inv_alpha, one, quadColor[3]); + VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + { + float inv_alpha[4]; + VEC4_SUB(inv_alpha, one, dest[3]); + VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, dest[0]); /* R */ + VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */ + VEC4_SUB(inv_comp, one, dest[1]); /* G */ + VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */ + VEC4_SUB(inv_comp, one, dest[2]); /* B */ + VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + { + float inv_comp[4]; + /* R */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]); + VEC4_MUL(source[0], quadColor[0], inv_comp); + /* G */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]); + VEC4_MUL(source[1], quadColor[1], inv_comp); + /* B */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]); + VEC4_MUL(source[2], quadColor[2], inv_comp); + } + break; + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + { + float inv_alpha[4]; + VEC4_SCALAR(inv_alpha, 1.0f - softpipe->blend_color.color[3]); + VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + assert(0); /* to do */ + break; + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + assert(0); /* to do */ + break; + default: + assert(0); + } + + /* + * Compute src/first term A + */ + switch (softpipe->blend->alpha_src_factor) { + case PIPE_BLENDFACTOR_ONE: + VEC4_COPY(source[3], quadColor[3]); /* A */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_SRC_ALPHA: + { + const float *alpha = quadColor[3]; + VEC4_MUL(source[3], quadColor[3], alpha); /* A */ + } + break; + case PIPE_BLENDFACTOR_DST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_DST_ALPHA: + VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + /* multiply alpha by 1.0 */ + VEC4_COPY(source[3], quadColor[3]); /* A */ + break; + case PIPE_BLENDFACTOR_CONST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_CONST_ALPHA: + { + float comp[4]; + VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ + VEC4_MUL(source[3], quadColor[3], comp); /* A */ + } + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(source[3], zero); /* A */ + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + { + float inv_alpha[4]; + VEC4_SUB(inv_alpha, one, quadColor[3]); + VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + { + float inv_alpha[4]; + VEC4_SUB(inv_alpha, one, dest[3]); + VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ + } + break; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + { + float inv_comp[4]; + /* A */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]); + VEC4_MUL(source[3], quadColor[3], inv_comp); + } + break; + default: + assert(0); + } + - /* loop over colorbuffer outputs */ - for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) { + /* + * Compute dest/second term RGB + */ + switch (softpipe->blend->rgb_dst_factor) { + case PIPE_BLENDFACTOR_ONE: + /* dest = dest * 1 NO-OP, leave dest as-is */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + VEC4_MUL(dest[0], dest[0], quadColor[0]); /* R */ + VEC4_MUL(dest[1], dest[1], quadColor[1]); /* G */ + VEC4_MUL(dest[2], dest[2], quadColor[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA: + VEC4_MUL(dest[0], dest[0], quadColor[3]); /* R * A */ + VEC4_MUL(dest[1], dest[1], quadColor[3]); /* G * A */ + VEC4_MUL(dest[2], dest[2], quadColor[3]); /* B * A */ + break; + case PIPE_BLENDFACTOR_DST_ALPHA: + VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */ + VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */ + VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */ + break; + case PIPE_BLENDFACTOR_DST_COLOR: + VEC4_MUL(dest[0], dest[0], dest[0]); /* R */ + VEC4_MUL(dest[1], dest[1], dest[1]); /* G */ + VEC4_MUL(dest[2], dest[2], dest[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + assert(0); /* illegal */ + break; + case PIPE_BLENDFACTOR_CONST_COLOR: + { + float comp[4]; + VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */ + VEC4_MUL(dest[0], dest[0], comp); /* R */ + VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */ + VEC4_MUL(dest[1], dest[1], comp); /* G */ + VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */ + VEC4_MUL(dest[2], dest[2], comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_CONST_ALPHA: + { + float comp[4]; + VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ + VEC4_MUL(dest[0], dest[0], comp); /* R */ + VEC4_MUL(dest[1], dest[1], comp); /* G */ + VEC4_MUL(dest[2], dest[2], comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(dest[0], zero); /* R */ + VEC4_COPY(dest[1], zero); /* G */ + VEC4_COPY(dest[2], zero); /* B */ + break; + case PIPE_BLENDFACTOR_SRC1_COLOR: + case PIPE_BLENDFACTOR_SRC1_ALPHA: + /* XXX what are these? */ + assert(0); + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, quadColor[0]); /* R */ + VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */ + VEC4_SUB(inv_comp, one, quadColor[1]); /* G */ + VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */ + VEC4_SUB(inv_comp, one, quadColor[2]); /* B */ + VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + { + float one_minus_alpha[QUAD_SIZE]; + VEC4_SUB(one_minus_alpha, one, quadColor[3]); + VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */ + VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */ + VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, dest[3]); /* A */ + VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */ + VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */ + VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, dest[0]); /* R */ + VEC4_MUL(dest[0], dest[0], inv_comp); /* R */ + VEC4_SUB(inv_comp, one, dest[1]); /* G */ + VEC4_MUL(dest[1], dest[1], inv_comp); /* G */ + VEC4_SUB(inv_comp, one, dest[2]); /* B */ + VEC4_MUL(dest[2], dest[2], inv_comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + { + float inv_comp[4]; + /* R */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]); + VEC4_MUL(dest[0], dest[0], inv_comp); + /* G */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]); + VEC4_MUL(dest[1], dest[1], inv_comp); + /* B */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]); + VEC4_MUL(dest[2], dest[2], inv_comp); + } + break; + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + { + float inv_comp[4]; + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]); + VEC4_MUL(dest[0], dest[0], inv_comp); + VEC4_MUL(dest[1], dest[1], inv_comp); + VEC4_MUL(dest[2], dest[2], inv_comp); + } + break; + case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + /* XXX what are these? */ + assert(0); + break; + default: + assert(0); + } + + /* + * Compute dest/second term A + */ + switch (softpipe->blend->alpha_dst_factor) { + case PIPE_BLENDFACTOR_ONE: + /* dest = dest * 1 NO-OP, leave dest as-is */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_SRC_ALPHA: + VEC4_MUL(dest[3], dest[3], quadColor[3]); /* A * A */ + break; + case PIPE_BLENDFACTOR_DST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_DST_ALPHA: + VEC4_MUL(dest[3], dest[3], dest[3]); /* A */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + assert(0); /* illegal */ + break; + case PIPE_BLENDFACTOR_CONST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_CONST_ALPHA: + { + float comp[4]; + VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ + VEC4_MUL(dest[3], dest[3], comp); /* A */ + } + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(dest[3], zero); /* A */ + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + { + float one_minus_alpha[QUAD_SIZE]; + VEC4_SUB(one_minus_alpha, one, quadColor[3]); + VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* A */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, dest[3]); /* A */ + VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */ + } + break; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + { + float inv_comp[4]; + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]); + VEC4_MUL(dest[3], dest[3], inv_comp); + } + break; + default: + assert(0); + } + + /* + * Combine RGB terms + */ + switch (softpipe->blend->rgb_func) { + case PIPE_BLEND_ADD: + VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */ + VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */ + VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */ + break; + case PIPE_BLEND_SUBTRACT: + VEC4_SUB_SAT(quadColor[0], source[0], dest[0]); /* R */ + VEC4_SUB_SAT(quadColor[1], source[1], dest[1]); /* G */ + VEC4_SUB_SAT(quadColor[2], source[2], dest[2]); /* B */ + break; + case PIPE_BLEND_REVERSE_SUBTRACT: + VEC4_SUB_SAT(quadColor[0], dest[0], source[0]); /* R */ + VEC4_SUB_SAT(quadColor[1], dest[1], source[1]); /* G */ + VEC4_SUB_SAT(quadColor[2], dest[2], source[2]); /* B */ + break; + case PIPE_BLEND_MIN: + VEC4_MIN(quadColor[0], source[0], dest[0]); /* R */ + VEC4_MIN(quadColor[1], source[1], dest[1]); /* G */ + VEC4_MIN(quadColor[2], source[2], dest[2]); /* B */ + break; + case PIPE_BLEND_MAX: + VEC4_MAX(quadColor[0], source[0], dest[0]); /* R */ + VEC4_MAX(quadColor[1], source[1], dest[1]); /* G */ + VEC4_MAX(quadColor[2], source[2], dest[2]); /* B */ + break; + default: + assert(0); + } + + /* + * Combine A terms + */ + switch (softpipe->blend->alpha_func) { + case PIPE_BLEND_ADD: + VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */ + break; + case PIPE_BLEND_SUBTRACT: + VEC4_SUB_SAT(quadColor[3], source[3], dest[3]); /* A */ + break; + case PIPE_BLEND_REVERSE_SUBTRACT: + VEC4_SUB_SAT(quadColor[3], dest[3], source[3]); /* A */ + break; + case PIPE_BLEND_MIN: + VEC4_MIN(quadColor[3], source[3], dest[3]); /* A */ + break; + case PIPE_BLEND_MAX: + VEC4_MAX(quadColor[3], source[3], dest[3]); /* A */ + break; + default: + assert(0); + } +} + +static void +colormask_quad(struct quad_stage *qs, + float (*quadColor)[4], + float (*dest)[4]) +{ + struct softpipe_context *softpipe = qs->softpipe; + + /* R */ + if (!(softpipe->blend->colormask & PIPE_MASK_R)) + COPY_4V(quadColor[0], dest[0]); + + /* G */ + if (!(softpipe->blend->colormask & PIPE_MASK_G)) + COPY_4V(quadColor[1], dest[1]); + + /* B */ + if (!(softpipe->blend->colormask & PIPE_MASK_B)) + COPY_4V(quadColor[2], dest[2]); + + /* A */ + if (!(softpipe->blend->colormask & PIPE_MASK_A)) + COPY_4V(quadColor[3], dest[3]); +} + + +static void +blend_fallback(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) +{ + struct softpipe_context *softpipe = qs->softpipe; + const struct pipe_blend_state *blend = softpipe->blend; + unsigned cbuf; + + for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) + { float dest[4][QUAD_SIZE]; - ubyte src[4][4], dst[4][4], res[4][4]; - uint *src4 = (uint *) src; - uint *dst4 = (uint *) dst; - uint *res4 = (uint *) res; - uint i, j; - - struct softpipe_cached_tile * - tile = sp_get_cached_tile(softpipe->cbuf_cache[cbuf], - quads[0]->input.x0, - quads[0]->input.y0); - - for (i = 0; i < nr; i++) { - struct quad_header *quad = quads[i]; + struct softpipe_cached_tile *tile + = sp_get_cached_tile(softpipe->cbuf_cache[cbuf], + quads[0]->input.x0, + quads[0]->input.y0); + uint q, i, j; + + for (q = 0; q < nr; q++) { + struct quad_header *quad = quads[q]; float (*quadColor)[4] = quad->output.color[cbuf]; + const int itx = (quad->input.x0 & (TILE_SIZE-1)); + const int ity = (quad->input.y0 & (TILE_SIZE-1)); - /* get/swizzle dest colors */ + /* get/swizzle dest colors + */ for (j = 0; j < QUAD_SIZE; j++) { - int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1); - int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1); + int x = itx + (j & 1); + int y = ity + (j >> 1); for (i = 0; i < 4; i++) { dest[i][j] = tile->data.color[y][x][i]; } } - /* convert to ubyte */ - for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */ - dst[j][0] = float_to_ubyte(dest[j][0]); /* P0 */ - dst[j][1] = float_to_ubyte(dest[j][1]); /* P1 */ - dst[j][2] = float_to_ubyte(dest[j][2]); /* P2 */ - dst[j][3] = float_to_ubyte(dest[j][3]); /* P3 */ - - src[j][0] = float_to_ubyte(quadColor[j][0]); /* P0 */ - src[j][1] = float_to_ubyte(quadColor[j][1]); /* P1 */ - src[j][2] = float_to_ubyte(quadColor[j][2]); /* P2 */ - src[j][3] = float_to_ubyte(quadColor[j][3]); /* P3 */ - } - switch (softpipe->blend->logicop_func) { - case PIPE_LOGICOP_CLEAR: - for (j = 0; j < 4; j++) - res4[j] = 0; - break; - case PIPE_LOGICOP_NOR: - for (j = 0; j < 4; j++) - res4[j] = ~(src4[j] | dst4[j]); - break; - case PIPE_LOGICOP_AND_INVERTED: - for (j = 0; j < 4; j++) - res4[j] = ~src4[j] & dst4[j]; - break; - case PIPE_LOGICOP_COPY_INVERTED: - for (j = 0; j < 4; j++) - res4[j] = ~src4[j]; - break; - case PIPE_LOGICOP_AND_REVERSE: - for (j = 0; j < 4; j++) - res4[j] = src4[j] & ~dst4[j]; - break; - case PIPE_LOGICOP_INVERT: - for (j = 0; j < 4; j++) - res4[j] = ~dst4[j]; - break; - case PIPE_LOGICOP_XOR: - for (j = 0; j < 4; j++) - res4[j] = dst4[j] ^ src4[j]; - break; - case PIPE_LOGICOP_NAND: - for (j = 0; j < 4; j++) - res4[j] = ~(src4[j] & dst4[j]); - break; - case PIPE_LOGICOP_AND: - for (j = 0; j < 4; j++) - res4[j] = src4[j] & dst4[j]; - break; - case PIPE_LOGICOP_EQUIV: - for (j = 0; j < 4; j++) - res4[j] = ~(src4[j] ^ dst4[j]); - break; - case PIPE_LOGICOP_NOOP: - for (j = 0; j < 4; j++) - res4[j] = dst4[j]; - break; - case PIPE_LOGICOP_OR_INVERTED: - for (j = 0; j < 4; j++) - res4[j] = ~src4[j] | dst4[j]; - break; - case PIPE_LOGICOP_COPY: - for (j = 0; j < 4; j++) - res4[j] = src4[j]; - break; - case PIPE_LOGICOP_OR_REVERSE: - for (j = 0; j < 4; j++) - res4[j] = src4[j] | ~dst4[j]; - break; - case PIPE_LOGICOP_OR: - for (j = 0; j < 4; j++) - res4[j] = src4[j] | dst4[j]; - break; - case PIPE_LOGICOP_SET: - for (j = 0; j < 4; j++) - res4[j] = ~0; - break; - default: - assert(0); + if (blend->logicop_enable) { + logicop_quad( qs, quadColor, dest ); + } + else if (blend->blend_enable) { + blend_quad( qs, quadColor, dest ); } - for (j = 0; j < 4; j++) { - quadColor[j][0] = ubyte_to_float(res[j][0]); - quadColor[j][1] = ubyte_to_float(res[j][1]); - quadColor[j][2] = ubyte_to_float(res[j][2]); - quadColor[j][3] = ubyte_to_float(res[j][3]); + if (blend->colormask != 0xf) + colormask_quad( qs, quadColor, dest ); + + /* Output color values + */ + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->inout.mask & (1 << j)) { + int x = itx + (j & 1); + int y = ity + (j >> 1); + for (i = 0; i < 4; i++) { /* loop over color chans */ + tile->data.color[y][x][i] = quadColor[i][j]; + } + } } } } - - /* pass blended quad to next stage */ - qs->next->run(qs->next, quads, nr); } + static void blend_single_add_src_alpha_inv_src_alpha(struct quad_stage *qs, struct quad_header *quads[], @@ -266,11 +808,13 @@ blend_single_add_src_alpha_inv_src_alpha(struct quad_stage *qs, struct quad_header *quad = quads[q]; float (*quadColor)[4] = quad->output.color[0]; const float *alpha = quadColor[3]; + const int itx = (quad->input.x0 & (TILE_SIZE-1)); + const int ity = (quad->input.y0 & (TILE_SIZE-1)); /* get/swizzle dest colors */ for (j = 0; j < QUAD_SIZE; j++) { - int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1); - int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1); + int x = itx + (j & 1); + int y = ity + (j >> 1); for (i = 0; i < 4; i++) { dest[i][j] = tile->data.color[y][x][i]; } @@ -291,10 +835,17 @@ blend_single_add_src_alpha_inv_src_alpha(struct quad_stage *qs, VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */ VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */ VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */ - } - /* pass blended quad to next stage */ - qs->next->run(qs->next, quads, nr); + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->inout.mask & (1 << j)) { + int x = itx + (j & 1); + int y = ity + (j >> 1); + for (i = 0; i < 4; i++) { /* loop over color chans */ + tile->data.color[y][x][i] = quadColor[i][j]; + } + } + } + } } static void @@ -313,11 +864,13 @@ blend_single_add_one_one(struct quad_stage *qs, for (q = 0; q < nr; q++) { struct quad_header *quad = quads[q]; float (*quadColor)[4] = quad->output.color[0]; + const int itx = (quad->input.x0 & (TILE_SIZE-1)); + const int ity = (quad->input.y0 & (TILE_SIZE-1)); /* get/swizzle dest colors */ for (j = 0; j < QUAD_SIZE; j++) { - int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1); - int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1); + int x = itx + (j & 1); + int y = ity + (j >> 1); for (i = 0; i < 4; i++) { dest[i][j] = tile->data.color[y][x][i]; } @@ -327,539 +880,71 @@ blend_single_add_one_one(struct quad_stage *qs, VEC4_ADD_SAT(quadColor[1], quadColor[1], dest[1]); /* G */ VEC4_ADD_SAT(quadColor[2], quadColor[2], dest[2]); /* B */ VEC4_ADD_SAT(quadColor[3], quadColor[3], dest[3]); /* A */ - } - /* pass blended quad to next stage */ - qs->next->run(qs->next, quads, nr); + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->inout.mask & (1 << j)) { + int x = itx + (j & 1); + int y = ity + (j >> 1); + for (i = 0; i < 4; i++) { /* loop over color chans */ + tile->data.color[y][x][i] = quadColor[i][j]; + } + } + } + } } + static void -blend_quads_fallback(struct quad_stage *qs, - struct quad_header *quads[], - unsigned nr) +single_output_color(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) { - static const float zero[4] = { 0, 0, 0, 0 }; - static const float one[4] = { 1, 1, 1, 1 }; - struct softpipe_context *softpipe = qs->softpipe; - uint cbuf; - - /* loop over colorbuffer outputs */ - for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) { - float source[4][QUAD_SIZE], dest[4][QUAD_SIZE]; - struct softpipe_cached_tile *tile - = sp_get_cached_tile(softpipe->cbuf_cache[cbuf], - quads[0]->input.x0, - quads[0]->input.y0); - uint q, i, j; + uint i, j, q; - for (q = 0; q < nr; q++) { - struct quad_header *quad = quads[q]; - float (*quadColor)[4] = quad->output.color[cbuf]; + struct softpipe_cached_tile *tile + = sp_get_cached_tile(qs->softpipe->cbuf_cache[0], + quads[0]->input.x0, + quads[0]->input.y0); - /* get/swizzle dest colors */ - for (j = 0; j < QUAD_SIZE; j++) { - int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1); - int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1); - for (i = 0; i < 4; i++) { - dest[i][j] = tile->data.color[y][x][i]; + for (q = 0; q < nr; q++) { + struct quad_header *quad = quads[q]; + float (*quadColor)[4] = quad->output.color[0]; + const int itx = (quad->input.x0 & (TILE_SIZE-1)); + const int ity = (quad->input.y0 & (TILE_SIZE-1)); + + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->inout.mask & (1 << j)) { + int x = itx + (j & 1); + int y = ity + (j >> 1); + for (i = 0; i < 4; i++) { /* loop over color chans */ + tile->data.color[y][x][i] = quadColor[i][j]; } } - - /* - * Compute src/first term RGB - */ - switch (softpipe->blend->rgb_src_factor) { - case PIPE_BLENDFACTOR_ONE: - VEC4_COPY(source[0], quadColor[0]); /* R */ - VEC4_COPY(source[1], quadColor[1]); /* G */ - VEC4_COPY(source[2], quadColor[2]); /* B */ - break; - case PIPE_BLENDFACTOR_SRC_COLOR: - VEC4_MUL(source[0], quadColor[0], quadColor[0]); /* R */ - VEC4_MUL(source[1], quadColor[1], quadColor[1]); /* G */ - VEC4_MUL(source[2], quadColor[2], quadColor[2]); /* B */ - break; - case PIPE_BLENDFACTOR_SRC_ALPHA: - { - const float *alpha = quadColor[3]; - VEC4_MUL(source[0], quadColor[0], alpha); /* R */ - VEC4_MUL(source[1], quadColor[1], alpha); /* G */ - VEC4_MUL(source[2], quadColor[2], alpha); /* B */ - } - break; - case PIPE_BLENDFACTOR_DST_COLOR: - VEC4_MUL(source[0], quadColor[0], dest[0]); /* R */ - VEC4_MUL(source[1], quadColor[1], dest[1]); /* G */ - VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */ - break; - case PIPE_BLENDFACTOR_DST_ALPHA: - { - const float *alpha = dest[3]; - VEC4_MUL(source[0], quadColor[0], alpha); /* R */ - VEC4_MUL(source[1], quadColor[1], alpha); /* G */ - VEC4_MUL(source[2], quadColor[2], alpha); /* B */ - } - break; - case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: - { - const float *alpha = quadColor[3]; - float diff[4], temp[4]; - VEC4_SUB(diff, one, dest[3]); - VEC4_MIN(temp, alpha, diff); - VEC4_MUL(source[0], quadColor[0], temp); /* R */ - VEC4_MUL(source[1], quadColor[1], temp); /* G */ - VEC4_MUL(source[2], quadColor[2], temp); /* B */ - } - break; - case PIPE_BLENDFACTOR_CONST_COLOR: - { - float comp[4]; - VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */ - VEC4_MUL(source[0], quadColor[0], comp); /* R */ - VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */ - VEC4_MUL(source[1], quadColor[1], comp); /* G */ - VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */ - VEC4_MUL(source[2], quadColor[2], comp); /* B */ - } - break; - case PIPE_BLENDFACTOR_CONST_ALPHA: - { - float alpha[4]; - VEC4_SCALAR(alpha, softpipe->blend_color.color[3]); - VEC4_MUL(source[0], quadColor[0], alpha); /* R */ - VEC4_MUL(source[1], quadColor[1], alpha); /* G */ - VEC4_MUL(source[2], quadColor[2], alpha); /* B */ - } - break; - case PIPE_BLENDFACTOR_SRC1_COLOR: - assert(0); /* to do */ - break; - case PIPE_BLENDFACTOR_SRC1_ALPHA: - assert(0); /* to do */ - break; - case PIPE_BLENDFACTOR_ZERO: - VEC4_COPY(source[0], zero); /* R */ - VEC4_COPY(source[1], zero); /* G */ - VEC4_COPY(source[2], zero); /* B */ - break; - case PIPE_BLENDFACTOR_INV_SRC_COLOR: - { - float inv_comp[4]; - VEC4_SUB(inv_comp, one, quadColor[0]); /* R */ - VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */ - VEC4_SUB(inv_comp, one, quadColor[1]); /* G */ - VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */ - VEC4_SUB(inv_comp, one, quadColor[2]); /* B */ - VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */ - } - break; - case PIPE_BLENDFACTOR_INV_SRC_ALPHA: - { - float inv_alpha[4]; - VEC4_SUB(inv_alpha, one, quadColor[3]); - VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ - VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ - VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ - } - break; - case PIPE_BLENDFACTOR_INV_DST_ALPHA: - { - float inv_alpha[4]; - VEC4_SUB(inv_alpha, one, dest[3]); - VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ - VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ - VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ - } - break; - case PIPE_BLENDFACTOR_INV_DST_COLOR: - { - float inv_comp[4]; - VEC4_SUB(inv_comp, one, dest[0]); /* R */ - VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */ - VEC4_SUB(inv_comp, one, dest[1]); /* G */ - VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */ - VEC4_SUB(inv_comp, one, dest[2]); /* B */ - VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */ - } - break; - case PIPE_BLENDFACTOR_INV_CONST_COLOR: - { - float inv_comp[4]; - /* R */ - VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]); - VEC4_MUL(source[0], quadColor[0], inv_comp); - /* G */ - VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]); - VEC4_MUL(source[1], quadColor[1], inv_comp); - /* B */ - VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]); - VEC4_MUL(source[2], quadColor[2], inv_comp); - } - break; - case PIPE_BLENDFACTOR_INV_CONST_ALPHA: - { - float inv_alpha[4]; - VEC4_SCALAR(inv_alpha, 1.0f - softpipe->blend_color.color[3]); - VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ - VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ - VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ - } - break; - case PIPE_BLENDFACTOR_INV_SRC1_COLOR: - assert(0); /* to do */ - break; - case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: - assert(0); /* to do */ - break; - default: - assert(0); - } - - /* - * Compute src/first term A - */ - switch (softpipe->blend->alpha_src_factor) { - case PIPE_BLENDFACTOR_ONE: - VEC4_COPY(source[3], quadColor[3]); /* A */ - break; - case PIPE_BLENDFACTOR_SRC_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_SRC_ALPHA: - { - const float *alpha = quadColor[3]; - VEC4_MUL(source[3], quadColor[3], alpha); /* A */ - } - break; - case PIPE_BLENDFACTOR_DST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_DST_ALPHA: - VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */ - break; - case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: - /* multiply alpha by 1.0 */ - VEC4_COPY(source[3], quadColor[3]); /* A */ - break; - case PIPE_BLENDFACTOR_CONST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_CONST_ALPHA: - { - float comp[4]; - VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ - VEC4_MUL(source[3], quadColor[3], comp); /* A */ - } - break; - case PIPE_BLENDFACTOR_ZERO: - VEC4_COPY(source[3], zero); /* A */ - break; - case PIPE_BLENDFACTOR_INV_SRC_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_INV_SRC_ALPHA: - { - float inv_alpha[4]; - VEC4_SUB(inv_alpha, one, quadColor[3]); - VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ - } - break; - case PIPE_BLENDFACTOR_INV_DST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_INV_DST_ALPHA: - { - float inv_alpha[4]; - VEC4_SUB(inv_alpha, one, dest[3]); - VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ - } - break; - case PIPE_BLENDFACTOR_INV_CONST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_INV_CONST_ALPHA: - { - float inv_comp[4]; - /* A */ - VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]); - VEC4_MUL(source[3], quadColor[3], inv_comp); - } - break; - default: - assert(0); - } - - - /* - * Compute dest/second term RGB - */ - switch (softpipe->blend->rgb_dst_factor) { - case PIPE_BLENDFACTOR_ONE: - /* dest = dest * 1 NO-OP, leave dest as-is */ - break; - case PIPE_BLENDFACTOR_SRC_COLOR: - VEC4_MUL(dest[0], dest[0], quadColor[0]); /* R */ - VEC4_MUL(dest[1], dest[1], quadColor[1]); /* G */ - VEC4_MUL(dest[2], dest[2], quadColor[2]); /* B */ - break; - case PIPE_BLENDFACTOR_SRC_ALPHA: - VEC4_MUL(dest[0], dest[0], quadColor[3]); /* R * A */ - VEC4_MUL(dest[1], dest[1], quadColor[3]); /* G * A */ - VEC4_MUL(dest[2], dest[2], quadColor[3]); /* B * A */ - break; - case PIPE_BLENDFACTOR_DST_ALPHA: - VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */ - VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */ - VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */ - break; - case PIPE_BLENDFACTOR_DST_COLOR: - VEC4_MUL(dest[0], dest[0], dest[0]); /* R */ - VEC4_MUL(dest[1], dest[1], dest[1]); /* G */ - VEC4_MUL(dest[2], dest[2], dest[2]); /* B */ - break; - case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: - assert(0); /* illegal */ - break; - case PIPE_BLENDFACTOR_CONST_COLOR: - { - float comp[4]; - VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */ - VEC4_MUL(dest[0], dest[0], comp); /* R */ - VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */ - VEC4_MUL(dest[1], dest[1], comp); /* G */ - VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */ - VEC4_MUL(dest[2], dest[2], comp); /* B */ - } - break; - case PIPE_BLENDFACTOR_CONST_ALPHA: - { - float comp[4]; - VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ - VEC4_MUL(dest[0], dest[0], comp); /* R */ - VEC4_MUL(dest[1], dest[1], comp); /* G */ - VEC4_MUL(dest[2], dest[2], comp); /* B */ - } - break; - case PIPE_BLENDFACTOR_ZERO: - VEC4_COPY(dest[0], zero); /* R */ - VEC4_COPY(dest[1], zero); /* G */ - VEC4_COPY(dest[2], zero); /* B */ - break; - case PIPE_BLENDFACTOR_SRC1_COLOR: - case PIPE_BLENDFACTOR_SRC1_ALPHA: - /* XXX what are these? */ - assert(0); - break; - case PIPE_BLENDFACTOR_INV_SRC_COLOR: - { - float inv_comp[4]; - VEC4_SUB(inv_comp, one, quadColor[0]); /* R */ - VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */ - VEC4_SUB(inv_comp, one, quadColor[1]); /* G */ - VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */ - VEC4_SUB(inv_comp, one, quadColor[2]); /* B */ - VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ - } - break; - case PIPE_BLENDFACTOR_INV_SRC_ALPHA: - { - float one_minus_alpha[QUAD_SIZE]; - VEC4_SUB(one_minus_alpha, one, quadColor[3]); - VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */ - VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */ - VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */ - } - break; - case PIPE_BLENDFACTOR_INV_DST_ALPHA: - { - float inv_comp[4]; - VEC4_SUB(inv_comp, one, dest[3]); /* A */ - VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */ - VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */ - VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ - } - break; - case PIPE_BLENDFACTOR_INV_DST_COLOR: - { - float inv_comp[4]; - VEC4_SUB(inv_comp, one, dest[0]); /* R */ - VEC4_MUL(dest[0], dest[0], inv_comp); /* R */ - VEC4_SUB(inv_comp, one, dest[1]); /* G */ - VEC4_MUL(dest[1], dest[1], inv_comp); /* G */ - VEC4_SUB(inv_comp, one, dest[2]); /* B */ - VEC4_MUL(dest[2], dest[2], inv_comp); /* B */ - } - break; - case PIPE_BLENDFACTOR_INV_CONST_COLOR: - { - float inv_comp[4]; - /* R */ - VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]); - VEC4_MUL(dest[0], dest[0], inv_comp); - /* G */ - VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]); - VEC4_MUL(dest[1], dest[1], inv_comp); - /* B */ - VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]); - VEC4_MUL(dest[2], dest[2], inv_comp); - } - break; - case PIPE_BLENDFACTOR_INV_CONST_ALPHA: - { - float inv_comp[4]; - VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]); - VEC4_MUL(dest[0], dest[0], inv_comp); - VEC4_MUL(dest[1], dest[1], inv_comp); - VEC4_MUL(dest[2], dest[2], inv_comp); - } - break; - case PIPE_BLENDFACTOR_INV_SRC1_COLOR: - case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: - /* XXX what are these? */ - assert(0); - break; - default: - assert(0); - } - - /* - * Compute dest/second term A - */ - switch (softpipe->blend->alpha_dst_factor) { - case PIPE_BLENDFACTOR_ONE: - /* dest = dest * 1 NO-OP, leave dest as-is */ - break; - case PIPE_BLENDFACTOR_SRC_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_SRC_ALPHA: - VEC4_MUL(dest[3], dest[3], quadColor[3]); /* A * A */ - break; - case PIPE_BLENDFACTOR_DST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_DST_ALPHA: - VEC4_MUL(dest[3], dest[3], dest[3]); /* A */ - break; - case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: - assert(0); /* illegal */ - break; - case PIPE_BLENDFACTOR_CONST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_CONST_ALPHA: - { - float comp[4]; - VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ - VEC4_MUL(dest[3], dest[3], comp); /* A */ - } - break; - case PIPE_BLENDFACTOR_ZERO: - VEC4_COPY(dest[3], zero); /* A */ - break; - case PIPE_BLENDFACTOR_INV_SRC_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_INV_SRC_ALPHA: - { - float one_minus_alpha[QUAD_SIZE]; - VEC4_SUB(one_minus_alpha, one, quadColor[3]); - VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* A */ - } - break; - case PIPE_BLENDFACTOR_INV_DST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_INV_DST_ALPHA: - { - float inv_comp[4]; - VEC4_SUB(inv_comp, one, dest[3]); /* A */ - VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */ - } - break; - case PIPE_BLENDFACTOR_INV_CONST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_INV_CONST_ALPHA: - { - float inv_comp[4]; - VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]); - VEC4_MUL(dest[3], dest[3], inv_comp); - } - break; - default: - assert(0); - } - - /* - * Combine RGB terms - */ - switch (softpipe->blend->rgb_func) { - case PIPE_BLEND_ADD: - VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */ - VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */ - VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */ - break; - case PIPE_BLEND_SUBTRACT: - VEC4_SUB_SAT(quadColor[0], source[0], dest[0]); /* R */ - VEC4_SUB_SAT(quadColor[1], source[1], dest[1]); /* G */ - VEC4_SUB_SAT(quadColor[2], source[2], dest[2]); /* B */ - break; - case PIPE_BLEND_REVERSE_SUBTRACT: - VEC4_SUB_SAT(quadColor[0], dest[0], source[0]); /* R */ - VEC4_SUB_SAT(quadColor[1], dest[1], source[1]); /* G */ - VEC4_SUB_SAT(quadColor[2], dest[2], source[2]); /* B */ - break; - case PIPE_BLEND_MIN: - VEC4_MIN(quadColor[0], source[0], dest[0]); /* R */ - VEC4_MIN(quadColor[1], source[1], dest[1]); /* G */ - VEC4_MIN(quadColor[2], source[2], dest[2]); /* B */ - break; - case PIPE_BLEND_MAX: - VEC4_MAX(quadColor[0], source[0], dest[0]); /* R */ - VEC4_MAX(quadColor[1], source[1], dest[1]); /* G */ - VEC4_MAX(quadColor[2], source[2], dest[2]); /* B */ - break; - default: - assert(0); - } - - /* - * Combine A terms - */ - switch (softpipe->blend->alpha_func) { - case PIPE_BLEND_ADD: - VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */ - break; - case PIPE_BLEND_SUBTRACT: - VEC4_SUB_SAT(quadColor[3], source[3], dest[3]); /* A */ - break; - case PIPE_BLEND_REVERSE_SUBTRACT: - VEC4_SUB_SAT(quadColor[3], dest[3], source[3]); /* A */ - break; - case PIPE_BLEND_MIN: - VEC4_MIN(quadColor[3], source[3], dest[3]); /* A */ - break; - case PIPE_BLEND_MAX: - VEC4_MAX(quadColor[3], source[3], dest[3]); /* A */ - break; - default: - assert(0); - } } - } /* cbuf loop */ - - /* pass blended quad to next stage */ - qs->next->run(qs->next, quads, nr); + } } static void -blend_quad(struct quad_stage *qs, - struct quad_header *quads[], - unsigned nr) +choose_blend_quad(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) { struct softpipe_context *softpipe = qs->softpipe; const struct pipe_blend_state *blend = softpipe->blend; - if (softpipe->blend->logicop_enable) { - qs->run = logicop_quads; - } - else { - qs->run = blend_quads_fallback; + qs->run = blend_fallback; - if (blend->rgb_src_factor == blend->alpha_src_factor && - blend->rgb_dst_factor == blend->alpha_dst_factor && - blend->rgb_func == blend->alpha_func && - softpipe->framebuffer.nr_cbufs == 1) + if (!softpipe->blend->logicop_enable && + softpipe->blend->colormask == 0xf) + { + if (!blend->blend_enable) { + qs->run = single_output_color; + } + else if (blend->rgb_src_factor == blend->alpha_src_factor && + blend->rgb_dst_factor == blend->alpha_dst_factor && + blend->rgb_func == blend->alpha_func && + softpipe->framebuffer.nr_cbufs == 1) { if (blend->alpha_func == PIPE_BLEND_ADD) { if (blend->rgb_src_factor == PIPE_BLENDFACTOR_ONE && @@ -871,7 +956,7 @@ blend_quad(struct quad_stage *qs, qs->run = blend_single_add_src_alpha_inv_src_alpha; } - } + } } qs->run(qs, quads, nr); @@ -880,8 +965,7 @@ blend_quad(struct quad_stage *qs, static void blend_begin(struct quad_stage *qs) { - qs->run = blend_quad; - qs->next->begin(qs->next); + qs->run = choose_blend_quad; } @@ -897,7 +981,7 @@ struct quad_stage *sp_quad_blend_stage( struct softpipe_context *softpipe ) stage->softpipe = softpipe; stage->begin = blend_begin; - stage->run = blend_quad; + stage->run = choose_blend_quad; stage->destroy = blend_destroy; return stage; diff --git a/src/gallium/drivers/softpipe/sp_quad_bufloop.c b/src/gallium/drivers/softpipe/sp_quad_bufloop.c deleted file mode 100644 index 953d8516b90..00000000000 --- a/src/gallium/drivers/softpipe/sp_quad_bufloop.c +++ /dev/null @@ -1,74 +0,0 @@ - -#include "util/u_memory.h" -#include "sp_context.h" -#include "sp_quad.h" -#include "sp_surface.h" -#include "sp_quad_pipe.h" - - -/** - * Loop over colorbuffers, passing quad to next stage each time. - */ -static void -cbuf_loop_quad(struct quad_stage *qs, struct quad_header *quad) -{ - struct softpipe_context *softpipe = qs->softpipe; - float tmp[PIPE_MAX_COLOR_BUFS][4][QUAD_SIZE]; - unsigned i; - - assert(sizeof(quad->outputs.color) == sizeof(tmp)); - assert(softpipe->framebuffer.nr_cbufs <= PIPE_MAX_COLOR_BUFS); - - /* make copy of original colors since they can get modified - * by blending and masking. - * XXX we won't have to do this if the fragment program actually emits - * N separate colors and we're drawing to N color buffers (MRT). - * But if we emitted one color and glDrawBuffer(GL_FRONT_AND_BACK) is - * in effect, we need to save/restore colors like this. - */ - memcpy(tmp, quad->outputs.color, sizeof(tmp)); - - for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) { - /* set current cbuffer */ -#if 0 /* obsolete & going away */ - softpipe->current_cbuf = i; -#endif - - /* pass blended quad to next stage */ - qs->next->run(qs->next, quad); - - /* restore quad's colors for next buffer */ - memcpy(quad->outputs.color, tmp, sizeof(tmp)); - } -} - - -static void cbuf_loop_begin(struct quad_stage *qs) -{ - qs->next->begin(qs->next); -} - - -static void cbuf_loop_destroy(struct quad_stage *qs) -{ - FREE( qs ); -} - - -/** - * Create the colorbuffer loop stage. - * This is used to implement multiple render targets and GL_FRONT_AND_BACK - * rendering. - */ -struct quad_stage *sp_quad_bufloop_stage( struct softpipe_context *softpipe ) -{ - struct quad_stage *stage = CALLOC_STRUCT(quad_stage); - - stage->softpipe = softpipe; - stage->begin = cbuf_loop_begin; - stage->run = cbuf_loop_quad; - stage->destroy = cbuf_loop_destroy; - - return stage; -} - diff --git a/src/gallium/drivers/softpipe/sp_quad_colormask.c b/src/gallium/drivers/softpipe/sp_quad_colormask.c deleted file mode 100644 index ac742874733..00000000000 --- a/src/gallium/drivers/softpipe/sp_quad_colormask.c +++ /dev/null @@ -1,126 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \brief quad colormask stage - * \author Brian Paul - */ - -#include "pipe/p_defines.h" -#include "util/u_math.h" -#include "util/u_memory.h" -#include "sp_context.h" -#include "sp_quad.h" -#include "sp_surface.h" -#include "sp_quad_pipe.h" -#include "sp_tile_cache.h" - - - -/** - * XXX colormask could be rolled into blending... - */ -static void -colormask_quad(struct quad_stage *qs, struct quad_header *quad) -{ - struct softpipe_context *softpipe = qs->softpipe; - uint cbuf; - - /* loop over colorbuffer outputs */ - for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) { - float dest[4][QUAD_SIZE]; - struct softpipe_cached_tile *tile - = sp_get_cached_tile(softpipe->cbuf_cache[cbuf], - quad->input.x0, quad->input.y0); - float (*quadColor)[4] = quad->output.color[cbuf]; - uint i, j; - - /* get/swizzle dest colors */ - for (j = 0; j < QUAD_SIZE; j++) { - int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1); - int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1); - for (i = 0; i < 4; i++) { - dest[i][j] = tile->data.color[y][x][i]; - } - } - - /* R */ - if (!(softpipe->blend->colormask & PIPE_MASK_R)) - COPY_4V(quadColor[0], dest[0]); - - /* G */ - if (!(softpipe->blend->colormask & PIPE_MASK_G)) - COPY_4V(quadColor[1], dest[1]); - - /* B */ - if (!(softpipe->blend->colormask & PIPE_MASK_B)) - COPY_4V(quadColor[2], dest[2]); - - /* A */ - if (!(softpipe->blend->colormask & PIPE_MASK_A)) - COPY_4V(quadColor[3], dest[3]); - } -} - -static void -colormask_quads(struct quad_stage *qs, struct quad_header *quads[], - unsigned nr) -{ - unsigned i; - - for (i = 0; i < nr; i++) - colormask_quad(qs, quads[i]); - - /* pass quad to next stage */ - qs->next->run(qs->next, quads, nr); -} - - - -static void colormask_begin(struct quad_stage *qs) -{ - qs->next->begin(qs->next); -} - - -static void colormask_destroy(struct quad_stage *qs) -{ - FREE( qs ); -} - - -struct quad_stage *sp_quad_colormask_stage( struct softpipe_context *softpipe ) -{ - struct quad_stage *stage = CALLOC_STRUCT(quad_stage); - - stage->softpipe = softpipe; - stage->begin = colormask_begin; - stage->run = colormask_quads; - stage->destroy = colormask_destroy; - - return stage; -} diff --git a/src/gallium/drivers/softpipe/sp_quad_coverage.c b/src/gallium/drivers/softpipe/sp_quad_coverage.c index f06a385b3c2..989e997f81b 100644 --- a/src/gallium/drivers/softpipe/sp_quad_coverage.c +++ b/src/gallium/drivers/softpipe/sp_quad_coverage.c @@ -68,7 +68,6 @@ coverage_run(struct quad_stage *qs, struct quad_header *quads[], unsigned nr) { - struct softpipe_context *softpipe = qs->softpipe; unsigned i; for (i = 0; i < nr; i++) diff --git a/src/gallium/drivers/softpipe/sp_quad_output.c b/src/gallium/drivers/softpipe/sp_quad_output.c deleted file mode 100644 index 79a222ff58d..00000000000 --- a/src/gallium/drivers/softpipe/sp_quad_output.c +++ /dev/null @@ -1,109 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "util/u_memory.h" -#include "sp_context.h" -#include "sp_quad.h" -#include "sp_surface.h" -#include "sp_quad_pipe.h" -#include "sp_tile_cache.h" - - -/** - * Last step of quad processing: write quad colors to the framebuffer, - * taking mask into account. - */ -static void -output_quad(struct quad_stage *qs, struct quad_header *quads[], unsigned nr) -{ - - struct softpipe_context *softpipe = qs->softpipe; - uint cbuf; - - /* loop over colorbuffer outputs */ - for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) { - struct softpipe_cached_tile *tile - = sp_get_cached_tile(softpipe->cbuf_cache[cbuf], - quads[0]->input.x0, - quads[0]->input.y0); - int i, j, q; - - /* get/swizzle dest colors */ - for (q = 0; q < nr; q++) { - struct quad_header *quad = quads[q]; - float (*quadColor)[4] = quad->output.color[cbuf]; - - /* in-tile pos: */ - const int itx = quad->input.x0 % TILE_SIZE; - const int ity = quad->input.y0 % TILE_SIZE; - - - for (j = 0; j < QUAD_SIZE; j++) { - if (quad->inout.mask & (1 << j)) { - int x = itx + (j & 1); - int y = ity + (j >> 1); - for (i = 0; i < 4; i++) { /* loop over color chans */ - tile->data.color[y][x][i] = quadColor[i][j]; - } - if (0) { - debug_printf("sp write pixel %d,%d: %g, %g, %g\n", - quad->input.x0 + x, - quad->input.y0 + y, - quadColor[0][j], - quadColor[1][j], - quadColor[2][j]); - } - } - } - } - } -} - - -static void output_begin(struct quad_stage *qs) -{ - assert(qs->next == NULL); -} - - -static void output_destroy(struct quad_stage *qs) -{ - FREE( qs ); -} - - -struct quad_stage *sp_quad_output_stage( struct softpipe_context *softpipe ) -{ - struct quad_stage *stage = CALLOC_STRUCT(quad_stage); - - stage->softpipe = softpipe; - stage->begin = output_begin; - stage->run = output_quad; - stage->destroy = output_destroy; - - return stage; -} diff --git a/src/gallium/drivers/softpipe/sp_quad_pipe.c b/src/gallium/drivers/softpipe/sp_quad_pipe.c index 6fae7d552f8..d138d417acb 100644 --- a/src/gallium/drivers/softpipe/sp_quad_pipe.c +++ b/src/gallium/drivers/softpipe/sp_quad_pipe.c @@ -65,25 +65,16 @@ sp_build_quad_pipeline(struct softpipe_context *sp) /* Color combine */ - sp->quad.first = sp->quad.output; - - if (sp->blend->colormask != 0xf) { - sp_push_quad_first( sp, sp->quad.colormask ); - } - - if (sp->blend->blend_enable || - sp->blend->logicop_enable) { - sp_push_quad_first( sp, sp->quad.blend ); - } + sp->quad.first = sp->quad.blend; + /* Shade/Depth/Stencil/Alpha + */ if ((sp->rasterizer->poly_smooth && sp->reduced_prim == PIPE_PRIM_TRIANGLES) || (sp->rasterizer->line_smooth && sp->reduced_prim == PIPE_PRIM_LINES) || (sp->rasterizer->point_smooth && sp->reduced_prim == PIPE_PRIM_POINTS)) { sp_push_quad_first( sp, sp->quad.coverage ); } - /* Shade/Depth/Stencil/Alpha - */ if (sp->active_query_count) { sp_push_quad_first( sp, sp->quad.occlusion ); } -- cgit v1.2.3 From ade8984f5023b05412f2467add4a59d14af53185 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 25 Jul 2009 10:01:06 +0100 Subject: softpipe: cleanup framebuffer state routine slightly --- src/gallium/drivers/softpipe/sp_state_surface.c | 50 +++++-------------------- 1 file changed, 10 insertions(+), 40 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c index 1621a276146..c8f55c3cec4 100644 --- a/src/gallium/drivers/softpipe/sp_state_surface.c +++ b/src/gallium/drivers/softpipe/sp_state_surface.c @@ -75,51 +75,21 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, /* update cache */ sp_tile_cache_set_surface(sp->zsbuf_cache, fb->zsbuf); - } - -#if 0 - /* XXX combined depth/stencil here */ - - /* sbuf changing? */ - if (sp->framebuffer.sbuf != fb->sbuf) { - /* flush old */ - sp_flush_tile_cache(sp, sp->sbuf_cache_sep); - - /* assign new */ - sp->framebuffer.sbuf = fb->sbuf; - - /* update cache */ - if (fb->sbuf != fb->zbuf) { - /* separate stencil buf */ - sp->sbuf_cache = sp->sbuf_cache_sep; - sp_tile_cache_set_surface(sp->sbuf_cache, fb->sbuf); - } - else { - /* combined depth/stencil */ - sp->sbuf_cache = sp->zbuf_cache; - sp_tile_cache_set_surface(sp->sbuf_cache, fb->sbuf); - } - } -#endif - /* Tell draw module how deep the Z/depth buffer is */ - { - int depth_bits; - double mrd; + /* Tell draw module how deep the Z/depth buffer is */ if (sp->framebuffer.zsbuf) { + int depth_bits; + double mrd; depth_bits = pf_get_component_bits(sp->framebuffer.zsbuf->format, PIPE_FORMAT_COMP_Z); + if (depth_bits > 16) { + mrd = 0.0000001; + } + else { + mrd = 0.00002; + } + draw_set_mrd(sp->draw, mrd); } - else { - depth_bits = 0; - } - if (depth_bits > 16) { - mrd = 0.0000001; - } - else { - mrd = 0.00002; - } - draw_set_mrd(sp->draw, mrd); } sp->framebuffer.width = fb->width; -- cgit v1.2.3 From 85613cc4f14de968ddd503610c5b8fcc77234c81 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 25 Jul 2009 11:01:48 +0100 Subject: softpipe: fix error in scissor state dependencies --- src/gallium/drivers/softpipe/sp_state_derived.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 629a1f8e293..02265012678 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -165,11 +165,19 @@ softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe) static void compute_cliprect(struct softpipe_context *sp) { + /* SP_NEW_FRAMEBUFFER + */ uint surfWidth = sp->framebuffer.width; uint surfHeight = sp->framebuffer.height; + /* SP_NEW_RASTERIZER + */ if (sp->rasterizer->scissor) { - /* clip to scissor rect */ + + /* SP_NEW_SCISSOR + * + * clip to scissor rect: + */ sp->cliprect.minx = MAX2(sp->scissor.minx, 0); sp->cliprect.miny = MAX2(sp->scissor.miny, 0); sp->cliprect.maxx = MIN2(sp->scissor.maxx, surfWidth); @@ -231,7 +239,7 @@ void softpipe_update_derived( struct softpipe_context *softpipe ) invalidate_vertex_layout( softpipe ); if (softpipe->dirty & (SP_NEW_SCISSOR | - SP_NEW_DEPTH_STENCIL_ALPHA | + SP_NEW_RASTERIZER | SP_NEW_FRAMEBUFFER)) compute_cliprect(softpipe); -- cgit v1.2.3 From bac8e34c9e4077d370923773d67fe565ce154849 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 27 Jul 2009 08:17:45 +0100 Subject: softpipe: move all depth/stencil/alpha pixel processing into one stage --- src/gallium/drivers/softpipe/Makefile | 5 - src/gallium/drivers/softpipe/sp_context.c | 12 - src/gallium/drivers/softpipe/sp_context.h | 6 - src/gallium/drivers/softpipe/sp_quad_alpha_test.c | 112 ---- src/gallium/drivers/softpipe/sp_quad_coverage.c | 101 ---- src/gallium/drivers/softpipe/sp_quad_depth_test.c | 659 ++++++++++++++++++---- src/gallium/drivers/softpipe/sp_quad_earlyz.c | 94 --- src/gallium/drivers/softpipe/sp_quad_fs.c | 46 +- src/gallium/drivers/softpipe/sp_quad_occlusion.c | 87 --- src/gallium/drivers/softpipe/sp_quad_pipe.c | 46 +- src/gallium/drivers/softpipe/sp_quad_pipe.h | 2 - src/gallium/drivers/softpipe/sp_quad_stencil.c | 363 ------------ src/gallium/drivers/softpipe/sp_state_derived.c | 4 +- 13 files changed, 580 insertions(+), 957 deletions(-) delete mode 100644 src/gallium/drivers/softpipe/sp_quad_alpha_test.c delete mode 100644 src/gallium/drivers/softpipe/sp_quad_coverage.c delete mode 100644 src/gallium/drivers/softpipe/sp_quad_earlyz.c delete mode 100644 src/gallium/drivers/softpipe/sp_quad_occlusion.c delete mode 100644 src/gallium/drivers/softpipe/sp_quad_stencil.c (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile index bdc1a5819fc..48522abe98f 100644 --- a/src/gallium/drivers/softpipe/Makefile +++ b/src/gallium/drivers/softpipe/Makefile @@ -16,13 +16,8 @@ C_SOURCES = \ sp_prim_vbuf.c \ sp_quad_pipe.c \ sp_quad_stipple.c \ - sp_quad_earlyz.c \ sp_quad_depth_test.c \ - sp_quad_stencil.c \ sp_quad_fs.c \ - sp_quad_alpha_test.c \ - sp_quad_occlusion.c \ - sp_quad_coverage.c \ sp_quad_blend.c \ sp_screen.c \ sp_setup.c \ diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 28a0dd62ac2..e35c6b3aec7 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -88,14 +88,8 @@ static void softpipe_destroy( struct pipe_context *pipe ) if (softpipe->draw) draw_destroy( softpipe->draw ); - softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple ); - softpipe->quad.earlyz->destroy( softpipe->quad.earlyz ); softpipe->quad.shade->destroy( softpipe->quad.shade ); - softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test ); softpipe->quad.depth_test->destroy( softpipe->quad.depth_test ); - softpipe->quad.stencil_test->destroy( softpipe->quad.stencil_test ); - softpipe->quad.occlusion->destroy( softpipe->quad.occlusion ); - softpipe->quad.coverage->destroy( softpipe->quad.coverage ); softpipe->quad.blend->destroy( softpipe->quad.blend ); for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) @@ -230,14 +224,8 @@ softpipe_create( struct pipe_screen *screen ) /* setup quad rendering stages */ - softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe); - softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe); softpipe->quad.shade = sp_quad_shade_stage(softpipe); - softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe); softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe); - softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe); - softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe); - softpipe->quad.coverage = sp_quad_coverage_stage(softpipe); softpipe->quad.blend = sp_quad_blend_stage(softpipe); /* vertex shader samplers */ diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index b76ff610a3f..fa3306c020a 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -114,14 +114,8 @@ struct softpipe_context { /** Software quad rendering pipeline */ struct { - struct quad_stage *polygon_stipple; - struct quad_stage *earlyz; struct quad_stage *shade; - struct quad_stage *alpha_test; - struct quad_stage *stencil_test; struct quad_stage *depth_test; - struct quad_stage *occlusion; - struct quad_stage *coverage; struct quad_stage *blend; struct quad_stage *first; /**< points to one of the above stages */ diff --git a/src/gallium/drivers/softpipe/sp_quad_alpha_test.c b/src/gallium/drivers/softpipe/sp_quad_alpha_test.c deleted file mode 100644 index 3a282208b6b..00000000000 --- a/src/gallium/drivers/softpipe/sp_quad_alpha_test.c +++ /dev/null @@ -1,112 +0,0 @@ - -/** - * quad alpha test - */ - -#include "sp_context.h" -#include "sp_quad.h" -#include "sp_quad_pipe.h" -#include "pipe/p_defines.h" -#include "util/u_memory.h" - -#define ALPHATEST( FUNC, COMP ) \ - static void \ - alpha_test_quads_##FUNC( struct quad_stage *qs, \ - struct quad_header *quads[], \ - unsigned nr ) \ - { \ - const float ref = qs->softpipe->depth_stencil->alpha.ref_value; \ - const uint cbuf = 0; /* only output[0].alpha is tested */ \ - unsigned pass_nr = 0; \ - unsigned i; \ - \ - for (i = 0; i < nr; i++) { \ - const float *aaaa = quads[i]->output.color[cbuf][3]; \ - unsigned passMask = 0; \ - \ - if (aaaa[0] COMP ref) passMask |= (1 << 0); \ - if (aaaa[1] COMP ref) passMask |= (1 << 1); \ - if (aaaa[2] COMP ref) passMask |= (1 << 2); \ - if (aaaa[3] COMP ref) passMask |= (1 << 3); \ - \ - quads[i]->inout.mask &= passMask; \ - \ - if (quads[i]->inout.mask) \ - quads[pass_nr++] = quads[i]; \ - } \ - \ - if (pass_nr) \ - qs->next->run(qs->next, quads, pass_nr); \ - } - - -ALPHATEST( LESS, < ) -ALPHATEST( EQUAL, == ) -ALPHATEST( LEQUAL, <= ) -ALPHATEST( GREATER, > ) -ALPHATEST( NOTEQUAL, != ) -ALPHATEST( GEQUAL, >= ) - - -/* XXX: Incorporate into shader using KILP. - */ -static void -alpha_test_quad(struct quad_stage *qs, - struct quad_header *quads[], - unsigned nr) -{ - switch (qs->softpipe->depth_stencil->alpha.func) { - case PIPE_FUNC_LESS: - alpha_test_quads_LESS( qs, quads, nr ); - break; - case PIPE_FUNC_EQUAL: - alpha_test_quads_EQUAL( qs, quads, nr ); - break; - case PIPE_FUNC_LEQUAL: - alpha_test_quads_LEQUAL( qs, quads, nr ); - break; - case PIPE_FUNC_GREATER: - alpha_test_quads_GREATER( qs, quads, nr ); - break; - case PIPE_FUNC_NOTEQUAL: - alpha_test_quads_NOTEQUAL( qs, quads, nr ); - break; - case PIPE_FUNC_GEQUAL: - alpha_test_quads_GEQUAL( qs, quads, nr ); - break; - case PIPE_FUNC_ALWAYS: - assert(0); /* should be caught earlier */ - qs->next->run(qs->next, quads, nr); - break; - case PIPE_FUNC_NEVER: - default: - assert(0); /* should be caught earlier */ - return; - } -} - - -static void alpha_test_begin(struct quad_stage *qs) -{ - qs->next->begin(qs->next); -} - - -static void alpha_test_destroy(struct quad_stage *qs) -{ - FREE( qs ); -} - - -struct quad_stage * -sp_quad_alpha_test_stage( struct softpipe_context *softpipe ) -{ - struct quad_stage *stage = CALLOC_STRUCT(quad_stage); - - stage->softpipe = softpipe; - stage->begin = alpha_test_begin; - stage->run = alpha_test_quad; - stage->destroy = alpha_test_destroy; - - return stage; -} diff --git a/src/gallium/drivers/softpipe/sp_quad_coverage.c b/src/gallium/drivers/softpipe/sp_quad_coverage.c deleted file mode 100644 index 989e997f81b..00000000000 --- a/src/gallium/drivers/softpipe/sp_quad_coverage.c +++ /dev/null @@ -1,101 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/** - * \brief Apply AA coverage to quad alpha valus - * \author Brian Paul - */ - - -#include "pipe/p_defines.h" -#include "util/u_memory.h" -#include "sp_context.h" -#include "sp_quad.h" -#include "sp_quad_pipe.h" - - -/** - * Multiply quad's alpha values by the fragment coverage. - */ -static INLINE void -coverage_quad(struct quad_stage *qs, struct quad_header *quad) -{ - struct softpipe_context *softpipe = qs->softpipe; - uint cbuf; - - /* loop over colorbuffer outputs */ - for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) { - float (*quadColor)[4] = quad->output.color[cbuf]; - unsigned j; - for (j = 0; j < QUAD_SIZE; j++) { - assert(quad->input.coverage[j] >= 0.0); - assert(quad->input.coverage[j] <= 1.0); - quadColor[3][j] *= quad->input.coverage[j]; - } - } -} - - -/* XXX: Incorporate into shader after alpha_test. - */ -static void -coverage_run(struct quad_stage *qs, - struct quad_header *quads[], - unsigned nr) -{ - unsigned i; - - for (i = 0; i < nr; i++) - coverage_quad( qs, quads[i] ); - - qs->next->run(qs->next, quads, nr); -} - -static void coverage_begin(struct quad_stage *qs) -{ - qs->next->begin(qs->next); -} - - -static void coverage_destroy(struct quad_stage *qs) -{ - FREE( qs ); -} - - -struct quad_stage *sp_quad_coverage_stage( struct softpipe_context *softpipe ) -{ - struct quad_stage *stage = CALLOC_STRUCT(quad_stage); - - stage->softpipe = softpipe; - stage->begin = coverage_begin; - stage->run = coverage_run; - stage->destroy = coverage_destroy; - - return stage; -} diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index 8f223a7eaeb..bf65799a818 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -31,61 +31,109 @@ #include "pipe/p_defines.h" #include "util/u_memory.h" +#include "tgsi/tgsi_scan.h" #include "sp_context.h" #include "sp_quad.h" #include "sp_surface.h" #include "sp_quad_pipe.h" #include "sp_tile_cache.h" +#include "sp_state.h" /* for sp_fragment_shader */ -/** - * Do depth testing for a quad. - * Not static since it's used by the stencil code. - */ +struct depth_data { + struct pipe_surface *ps; + enum pipe_format format; + unsigned bzzzz[QUAD_SIZE]; /**< Z values fetched from depth buffer */ + unsigned qzzzz[QUAD_SIZE]; /**< Z values from the quad */ + ubyte stencilVals[QUAD_SIZE]; + struct softpipe_cached_tile *tile; +}; -/* - * To increase efficiency, we should probably have multiple versions - * of this function that are specifically for Z16, Z32 and FP Z buffers. - * Try to effectively do that with codegen... - */ -boolean -sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) + +static void +get_depth_stencil_values( struct depth_data *data, + const struct quad_header *quad ) { - struct softpipe_context *softpipe = qs->softpipe; - struct pipe_surface *ps = softpipe->framebuffer.zsbuf; - const enum pipe_format format = ps->format; - unsigned bzzzz[QUAD_SIZE]; /**< Z values fetched from depth buffer */ - unsigned qzzzz[QUAD_SIZE]; /**< Z values from the quad */ - unsigned zmask = 0; unsigned j; - struct softpipe_cached_tile *tile - = sp_get_cached_tile(softpipe->zsbuf_cache, quad->input.x0, quad->input.y0); + const struct softpipe_cached_tile *tile = data->tile; + + switch (data->format) { + case PIPE_FORMAT_Z16_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + data->bzzzz[j] = tile->data.depth16[y][x]; + } + break; + case PIPE_FORMAT_Z32_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + data->bzzzz[j] = tile->data.depth32[y][x]; + } + break; + case PIPE_FORMAT_X8Z24_UNORM: + case PIPE_FORMAT_S8Z24_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + data->bzzzz[j] = tile->data.depth32[y][x] & 0xffffff; + data->stencilVals[j] = tile->data.depth32[y][x] >> 24; + } + break; + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + data->bzzzz[j] = tile->data.depth32[y][x] >> 8; + data->stencilVals[j] = tile->data.depth32[y][x] & 0xff; + } + break; + default: + assert(0); + } +} - assert(ps); /* shouldn't get here if there's no zbuffer */ +/* If the shader has not been run, interpolate the depth values + * ourselves. + */ +static void +interpolate_quad_depth( struct quad_header *quad ) +{ + const float fx = (float) quad->input.x0; + const float fy = (float) quad->input.y0; + const float dzdx = quad->posCoef->dadx[2]; + const float dzdy = quad->posCoef->dady[2]; + const float z0 = quad->posCoef->a0[2] + dzdx * fx + dzdy * fy; + + quad->output.depth[0] = z0; + quad->output.depth[1] = z0 + dzdx; + quad->output.depth[2] = z0 + dzdy; + quad->output.depth[3] = z0 + dzdx + dzdy; +} - /* - * Convert quad's float depth values to int depth values (qzzzz). + +static void +convert_quad_depth( struct depth_data *data, + const struct quad_header *quad ) +{ + unsigned j; + + /* Convert quad's float depth values to int depth values (qzzzz). * If the Z buffer stores integer values, we _have_ to do the depth * compares with integers (not floats). Otherwise, the float->int->float * conversion of Z values (which isn't an identity function) will cause * Z-fighting errors. - * - * Also, get the zbuffer values (bzzzz) from the cached tile. */ - switch (format) { + switch (data->format) { case PIPE_FORMAT_Z16_UNORM: { float scale = 65535.0; for (j = 0; j < QUAD_SIZE; j++) { - qzzzz[j] = (unsigned) (quad->output.depth[j] * scale); - } - - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - bzzzz[j] = tile->data.depth16[y][x]; + data->qzzzz[j] = (unsigned) (quad->output.depth[j] * scale); } } break; @@ -94,47 +142,247 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) double scale = (double) (uint) ~0UL; for (j = 0; j < QUAD_SIZE; j++) { - qzzzz[j] = (unsigned) (quad->output.depth[j] * scale); - } - - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - bzzzz[j] = tile->data.depth32[y][x]; + data->qzzzz[j] = (unsigned) (quad->output.depth[j] * scale); } } break; case PIPE_FORMAT_X8Z24_UNORM: - /* fall-through */ case PIPE_FORMAT_S8Z24_UNORM: { float scale = (float) ((1 << 24) - 1); for (j = 0; j < QUAD_SIZE; j++) { - qzzzz[j] = (unsigned) (quad->output.depth[j] * scale); - } - - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - bzzzz[j] = tile->data.depth32[y][x] & 0xffffff; + data->qzzzz[j] = (unsigned) (quad->output.depth[j] * scale); } } break; case PIPE_FORMAT_Z24X8_UNORM: - /* fall-through */ case PIPE_FORMAT_Z24S8_UNORM: { float scale = (float) ((1 << 24) - 1); for (j = 0; j < QUAD_SIZE; j++) { - qzzzz[j] = (unsigned) (quad->output.depth[j] * scale); + data->qzzzz[j] = (unsigned) (quad->output.depth[j] * scale); } + } + break; + default: + assert(0); + } +} - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - bzzzz[j] = tile->data.depth32[y][x] >> 8; + + +static void +write_depth_stencil_values( struct depth_data *data, + struct quad_header *quad ) +{ + struct softpipe_cached_tile *tile = data->tile; + unsigned j; + + /* put updated Z values back into cached tile */ + switch (data->format) { + case PIPE_FORMAT_Z16_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + tile->data.depth16[y][x] = (ushort) data->bzzzz[j]; + } + break; + case PIPE_FORMAT_X8Z24_UNORM: + case PIPE_FORMAT_Z32_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + tile->data.depth32[y][x] = data->bzzzz[j]; + } + break; + case PIPE_FORMAT_S8Z24_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + tile->data.depth32[y][x] = (data->stencilVals[j] << 24) | data->bzzzz[j]; + } + break; + case PIPE_FORMAT_Z24S8_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + tile->data.depth32[y][x] = (data->bzzzz[j] << 8) | data->stencilVals[j]; + } + break; + case PIPE_FORMAT_Z24X8_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + tile->data.depth32[y][x] = data->bzzzz[j] << 8; + } + break; + default: + assert(0); + } +} + + + + +/** Only 8-bit stencil supported */ +#define STENCIL_MAX 0xff + + +/** + * Do the basic stencil test (compare stencil buffer values against the + * reference value. + * + * \param data->stencilVals the stencil values from the stencil buffer + * \param func the stencil func (PIPE_FUNC_x) + * \param ref the stencil reference value + * \param valMask the stencil value mask indicating which bits of the stencil + * values and ref value are to be used. + * \return mask indicating which pixels passed the stencil test + */ +static unsigned +do_stencil_test(struct depth_data *data, + unsigned func, + unsigned ref, unsigned valMask) +{ + unsigned passMask = 0x0; + unsigned j; + + ref &= valMask; + + switch (func) { + case PIPE_FUNC_NEVER: + /* passMask = 0x0 */ + break; + case PIPE_FUNC_LESS: + for (j = 0; j < QUAD_SIZE; j++) { + if (ref < (data->stencilVals[j] & valMask)) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_EQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (ref == (data->stencilVals[j] & valMask)) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_LEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (ref <= (data->stencilVals[j] & valMask)) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_GREATER: + for (j = 0; j < QUAD_SIZE; j++) { + if (ref > (data->stencilVals[j] & valMask)) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_NOTEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (ref != (data->stencilVals[j] & valMask)) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_GEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (ref >= (data->stencilVals[j] & valMask)) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_ALWAYS: + passMask = MASK_ALL; + break; + default: + assert(0); + } + + return passMask; +} + + +/** + * Apply the stencil operator to stencil values. + * + * \param data->stencilVals the stencil buffer values (read and written) + * \param mask indicates which pixels to update + * \param op the stencil operator (PIPE_STENCIL_OP_x) + * \param ref the stencil reference value + * \param wrtMask writemask controlling which bits are changed in the + * stencil values + */ +static void +apply_stencil_op(struct depth_data *data, + unsigned mask, unsigned op, ubyte ref, ubyte wrtMask) +{ + unsigned j; + ubyte newstencil[QUAD_SIZE]; + + for (j = 0; j < QUAD_SIZE; j++) { + newstencil[j] = data->stencilVals[j]; + } + + switch (op) { + case PIPE_STENCIL_OP_KEEP: + /* no-op */ + break; + case PIPE_STENCIL_OP_ZERO: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + newstencil[j] = 0; + } + } + break; + case PIPE_STENCIL_OP_REPLACE: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + newstencil[j] = ref; + } + } + break; + case PIPE_STENCIL_OP_INCR: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + if (data->stencilVals[j] < STENCIL_MAX) { + newstencil[j] = data->stencilVals[j] + 1; + } + } + } + break; + case PIPE_STENCIL_OP_DECR: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + if (data->stencilVals[j] > 0) { + newstencil[j] = data->stencilVals[j] - 1; + } + } + } + break; + case PIPE_STENCIL_OP_INCR_WRAP: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + newstencil[j] = data->stencilVals[j] + 1; + } + } + break; + case PIPE_STENCIL_OP_DECR_WRAP: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + newstencil[j] = data->stencilVals[j] - 1; + } + } + break; + case PIPE_STENCIL_OP_INVERT: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + newstencil[j] = ~data->stencilVals[j]; } } break; @@ -142,6 +390,39 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) assert(0); } + /* + * update the stencil values + */ + if (wrtMask != STENCIL_MAX) { + /* apply bit-wise stencil buffer writemask */ + for (j = 0; j < QUAD_SIZE; j++) { + data->stencilVals[j] = (wrtMask & newstencil[j]) | (~wrtMask & data->stencilVals[j]); + } + } + else { + for (j = 0; j < QUAD_SIZE; j++) { + data->stencilVals[j] = newstencil[j]; + } + } +} + + + +/* + * To increase efficiency, we should probably have multiple versions + * of this function that are specifically for Z16, Z32 and FP Z buffers. + * Try to effectively do that with codegen... + */ + +static boolean +depth_test_quad(struct quad_stage *qs, + struct depth_data *data, + struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + unsigned zmask = 0; + unsigned j; + switch (softpipe->depth_stencil->depth.func) { case PIPE_FUNC_NEVER: /* zmask = 0 */ @@ -151,37 +432,37 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) * Like this: quad->mask &= (quad->outputs.depth < zzzz); */ for (j = 0; j < QUAD_SIZE; j++) { - if (qzzzz[j] < bzzzz[j]) + if (data->qzzzz[j] < data->bzzzz[j]) zmask |= 1 << j; } break; case PIPE_FUNC_EQUAL: for (j = 0; j < QUAD_SIZE; j++) { - if (qzzzz[j] == bzzzz[j]) + if (data->qzzzz[j] == data->bzzzz[j]) zmask |= 1 << j; } break; case PIPE_FUNC_LEQUAL: for (j = 0; j < QUAD_SIZE; j++) { - if (qzzzz[j] <= bzzzz[j]) + if (data->qzzzz[j] <= data->bzzzz[j]) zmask |= (1 << j); } break; case PIPE_FUNC_GREATER: for (j = 0; j < QUAD_SIZE; j++) { - if (qzzzz[j] > bzzzz[j]) + if (data->qzzzz[j] > data->bzzzz[j]) zmask |= (1 << j); } break; case PIPE_FUNC_NOTEQUAL: for (j = 0; j < QUAD_SIZE; j++) { - if (qzzzz[j] != bzzzz[j]) + if (data->qzzzz[j] != data->bzzzz[j]) zmask |= (1 << j); } break; case PIPE_FUNC_GEQUAL: for (j = 0; j < QUAD_SIZE; j++) { - if (qzzzz[j] >= bzzzz[j]) + if (data->qzzzz[j] >= data->bzzzz[j]) zmask |= (1 << j); } break; @@ -196,83 +477,231 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) if (quad->inout.mask == 0) return FALSE; + /* Update our internal copy only if writemask set. Even if + * depth.writemask is FALSE, may still need to write out buffer + * data due to stencil changes. + */ if (softpipe->depth_stencil->depth.writemask) { - - /* This is also efficient with sse / spe instructions: - */ for (j = 0; j < QUAD_SIZE; j++) { - if (quad->inout.mask & (1 << j)) { - bzzzz[j] = qzzzz[j]; - } + if (quad->inout.mask & (1 << j)) { + data->bzzzz[j] = data->qzzzz[j]; + } } + } - /* put updated Z values back into cached tile */ - switch (format) { - case PIPE_FORMAT_Z16_UNORM: - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - tile->data.depth16[y][x] = (ushort) bzzzz[j]; - } - break; - case PIPE_FORMAT_X8Z24_UNORM: - /* fall-through */ - /* (yes, this falls through to a different case than above) */ - case PIPE_FORMAT_Z32_UNORM: - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - tile->data.depth32[y][x] = bzzzz[j]; - } - break; - case PIPE_FORMAT_S8Z24_UNORM: - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - uint s8z24 = tile->data.depth32[y][x]; - s8z24 = (s8z24 & 0xff000000) | bzzzz[j]; - tile->data.depth32[y][x] = s8z24; - } - break; - case PIPE_FORMAT_Z24S8_UNORM: - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - uint z24s8 = tile->data.depth32[y][x]; - z24s8 = (z24s8 & 0xff) | (bzzzz[j] << 8); - tile->data.depth32[y][x] = z24s8; + return TRUE; +} + + + +/** + * Do stencil (and depth) testing. Stenciling depends on the outcome of + * depth testing. + */ +static boolean +depth_stencil_test_quad(struct quad_stage *qs, + struct depth_data *data, + struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + unsigned func, zFailOp, zPassOp, failOp; + ubyte ref, wrtMask, valMask; + uint face = quad->input.facing; + + if (!softpipe->depth_stencil->stencil[1].enabled) { + /* single-sided stencil test, use front (face=0) state */ + face = 0; + } + + /* choose front or back face function, operator, etc */ + /* XXX we could do these initializations once per primitive */ + func = softpipe->depth_stencil->stencil[face].func; + failOp = softpipe->depth_stencil->stencil[face].fail_op; + zFailOp = softpipe->depth_stencil->stencil[face].zfail_op; + zPassOp = softpipe->depth_stencil->stencil[face].zpass_op; + ref = softpipe->depth_stencil->stencil[face].ref_value; + wrtMask = softpipe->depth_stencil->stencil[face].writemask; + valMask = softpipe->depth_stencil->stencil[face].valuemask; + + + /* do the stencil test first */ + { + unsigned passMask, failMask; + passMask = do_stencil_test(data, func, ref, valMask); + failMask = quad->inout.mask & ~passMask; + quad->inout.mask &= passMask; + + if (failOp != PIPE_STENCIL_OP_KEEP) { + apply_stencil_op(data, failMask, failOp, ref, wrtMask); + } + } + + if (quad->inout.mask) { + /* now the pixels that passed the stencil test are depth tested */ + if (softpipe->depth_stencil->depth.enabled) { + const unsigned origMask = quad->inout.mask; + + depth_test_quad(qs, data, quad); /* quad->mask is updated */ + + /* update stencil buffer values according to z pass/fail result */ + if (zFailOp != PIPE_STENCIL_OP_KEEP) { + const unsigned failMask = origMask & ~quad->inout.mask; + apply_stencil_op(data, failMask, zFailOp, ref, wrtMask); } - break; - case PIPE_FORMAT_Z24X8_UNORM: - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - tile->data.depth32[y][x] = bzzzz[j] << 8; + + if (zPassOp != PIPE_STENCIL_OP_KEEP) { + const unsigned passMask = origMask & quad->inout.mask; + apply_stencil_op(data, passMask, zPassOp, ref, wrtMask); } - break; - default: - assert(0); + } + else { + /* no depth test, apply Zpass operator to stencil buffer values */ + apply_stencil_op(data, quad->inout.mask, zPassOp, ref, wrtMask); } } - return TRUE; + return quad->inout.mask != 0; } +#define ALPHATEST( FUNC, COMP ) \ + static int \ + alpha_test_quads_##FUNC( struct quad_stage *qs, \ + struct quad_header *quads[], \ + unsigned nr ) \ + { \ + const float ref = qs->softpipe->depth_stencil->alpha.ref_value; \ + const uint cbuf = 0; /* only output[0].alpha is tested */ \ + unsigned pass_nr = 0; \ + unsigned i; \ + \ + for (i = 0; i < nr; i++) { \ + const float *aaaa = quads[i]->output.color[cbuf][3]; \ + unsigned passMask = 0; \ + \ + if (aaaa[0] COMP ref) passMask |= (1 << 0); \ + if (aaaa[1] COMP ref) passMask |= (1 << 1); \ + if (aaaa[2] COMP ref) passMask |= (1 << 2); \ + if (aaaa[3] COMP ref) passMask |= (1 << 3); \ + \ + quads[i]->inout.mask &= passMask; \ + \ + if (quads[i]->inout.mask) \ + quads[pass_nr++] = quads[i]; \ + } \ + \ + return pass_nr; \ + } + + +ALPHATEST( LESS, < ) +ALPHATEST( EQUAL, == ) +ALPHATEST( LEQUAL, <= ) +ALPHATEST( GREATER, > ) +ALPHATEST( NOTEQUAL, != ) +ALPHATEST( GEQUAL, >= ) + + +/* XXX: Incorporate into shader using KILP. + */ +static int +alpha_test_quads(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) +{ + switch (qs->softpipe->depth_stencil->alpha.func) { + case PIPE_FUNC_LESS: + return alpha_test_quads_LESS( qs, quads, nr ); + case PIPE_FUNC_EQUAL: + return alpha_test_quads_EQUAL( qs, quads, nr ); + break; + case PIPE_FUNC_LEQUAL: + return alpha_test_quads_LEQUAL( qs, quads, nr ); + case PIPE_FUNC_GREATER: + return alpha_test_quads_GREATER( qs, quads, nr ); + case PIPE_FUNC_NOTEQUAL: + return alpha_test_quads_NOTEQUAL( qs, quads, nr ); + case PIPE_FUNC_GEQUAL: + return alpha_test_quads_GEQUAL( qs, quads, nr ); + case PIPE_FUNC_ALWAYS: + return nr; + case PIPE_FUNC_NEVER: + default: + return 0; + } +} + +static unsigned mask_count[0x8] = +{ + 0, /* 0x0 */ + 1, /* 0x1 */ + 1, /* 0x2 */ + 2, /* 0x3 */ + 1, /* 0x4 */ + 2, /* 0x5 */ + 2, /* 0x6 */ + 3, /* 0x7 */ +}; + + + static void depth_test_quads(struct quad_stage *qs, struct quad_header *quads[], unsigned nr) { unsigned i, pass = 0; + const struct sp_fragment_shader *fs = qs->softpipe->fs; + boolean interp_depth = !fs->info.writes_z; + struct depth_data data; - for (i = 0; i < nr; i++) { - if (sp_depth_test_quad(qs, quads[i])) + + if (qs->softpipe->depth_stencil->alpha.enabled) { + nr = alpha_test_quads(qs, quads, nr); + } + + if (qs->softpipe->framebuffer.zsbuf && + (qs->softpipe->depth_stencil->depth.enabled || + qs->softpipe->depth_stencil->stencil[0].enabled)) { + + data.ps = qs->softpipe->framebuffer.zsbuf; + data.format = data.ps->format; + data.tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, + quads[0]->input.x0, + quads[0]->input.y0); + + for (i = 0; i < nr; i++) { + get_depth_stencil_values(&data, quads[i]); + + if (qs->softpipe->depth_stencil->depth.enabled) { + if (interp_depth) + interpolate_quad_depth(quads[i]); + + convert_quad_depth(&data, quads[i]); + } + + if (qs->softpipe->depth_stencil->stencil[0].enabled) { + if (!depth_stencil_test_quad(qs, &data, quads[i])) + continue; + } + else { + if (!depth_test_quad(qs, &data, quads[i])) + continue; + } + + if (qs->softpipe->depth_stencil->stencil[0].enabled || + qs->softpipe->depth_stencil->depth.writemask) + write_depth_stencil_values(&data, quads[i]); + + qs->softpipe->occlusion_count += mask_count[quads[i]->inout.mask]; quads[pass++] = quads[i]; + } + + nr = pass; } - - if (pass) - qs->next->run(qs->next, quads, pass); + + if (nr) + qs->next->run(qs->next, quads, nr); } diff --git a/src/gallium/drivers/softpipe/sp_quad_earlyz.c b/src/gallium/drivers/softpipe/sp_quad_earlyz.c deleted file mode 100644 index 1048d449843..00000000000 --- a/src/gallium/drivers/softpipe/sp_quad_earlyz.c +++ /dev/null @@ -1,94 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \brief Quad early-z testing - */ - -#include "pipe/p_defines.h" -#include "util/u_memory.h" -#include "sp_quad.h" -#include "sp_quad_pipe.h" - - -/** - * All this stage does is compute the quad's Z values (which is normally - * done by the shading stage). - * The next stage will do the actual depth test. - */ -static void -earlyz_quad( - struct quad_stage *qs, - struct quad_header *quads[], - unsigned nr ) -{ - const float a0z = quads[0]->posCoef->a0[2]; - const float dzdx = quads[0]->posCoef->dadx[2]; - const float dzdy = quads[0]->posCoef->dady[2]; - unsigned i; - - for (i = 0; i < nr; i++) { - const float fx = (float) quads[i]->input.x0; - const float fy = (float) quads[i]->input.y0; - const float z0 = a0z + dzdx * fx + dzdy * fy; - - quads[i]->output.depth[0] = z0; - quads[i]->output.depth[1] = z0 + dzdx; - quads[i]->output.depth[2] = z0 + dzdy; - quads[i]->output.depth[3] = z0 + dzdx + dzdy; - } - - qs->next->run( qs->next, quads, nr ); -} - -static void -earlyz_begin( - struct quad_stage *qs ) -{ - qs->next->begin( qs->next ); -} - -static void -earlyz_destroy( - struct quad_stage *qs ) -{ - FREE( qs ); -} - -struct quad_stage * -sp_quad_earlyz_stage( - struct softpipe_context *softpipe ) -{ - struct quad_stage *stage = CALLOC_STRUCT( quad_stage ); - - stage->softpipe = softpipe; - stage->begin = earlyz_begin; - stage->run = earlyz_quad; - stage->destroy = earlyz_destroy; - - return stage; -} diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index ea5ed3bbd07..56a8f55d774 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -111,24 +111,31 @@ shade_quad(struct quad_stage *qs, struct quad_header *quad) } } - if (!z_written) { - /* compute Z values now, as in the quad earlyz stage */ - /* XXX we should really only do this if the earlyz stage is not used */ - const float fx = (float) quad->input.x0; - const float fy = (float) quad->input.y0; - const float dzdx = quad->posCoef->dadx[2]; - const float dzdy = quad->posCoef->dady[2]; - const float z0 = quad->posCoef->a0[2] + dzdx * fx + dzdy * fy; - - quad->output.depth[0] = z0; - quad->output.depth[1] = z0 + dzdx; - quad->output.depth[2] = z0 + dzdy; - quad->output.depth[3] = z0 + dzdx + dzdy; - } - return TRUE; } + + +static void +coverage_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + uint cbuf; + + /* loop over colorbuffer outputs */ + for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) { + float (*quadColor)[4] = quad->output.color[cbuf]; + unsigned j; + for (j = 0; j < QUAD_SIZE; j++) { + assert(quad->input.coverage[j] >= 0.0); + assert(quad->input.coverage[j] <= 1.0); + quadColor[3][j] *= quad->input.coverage[j]; + } + } +} + + + static void shade_quads(struct quad_stage *qs, struct quad_header *quads[], @@ -144,8 +151,13 @@ shade_quads(struct quad_stage *qs, machine->InterpCoefs = quads[0]->coef; for (i = 0; i < nr; i++) { - if (shade_quad(qs, quads[i])) - quads[pass++] = quads[i]; + if (!shade_quad(qs, quads[i])) + continue; + + if (/*do_coverage*/ 0) + coverage_quad( qs, quads[i] ); + + quads[pass++] = quads[i]; } if (pass) diff --git a/src/gallium/drivers/softpipe/sp_quad_occlusion.c b/src/gallium/drivers/softpipe/sp_quad_occlusion.c deleted file mode 100644 index 4adeb16546a..00000000000 --- a/src/gallium/drivers/softpipe/sp_quad_occlusion.c +++ /dev/null @@ -1,87 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/** - * \brief Quad occlusion counter stage - * \author Brian Paul - */ - - -#include "pipe/p_defines.h" -#include "util/u_memory.h" -#include "sp_context.h" -#include "sp_quad.h" -#include "sp_surface.h" -#include "sp_quad_pipe.h" - -static unsigned count_bits( unsigned val ) -{ - unsigned i; - - for (i = 0; val ; val >>= 1) - i += (val & 1); - - return i; -} - -static void -occlusion_count_quads(struct quad_stage *qs, struct quad_header *quads[], unsigned nr) -{ - struct softpipe_context *softpipe = qs->softpipe; - unsigned i; - - for (i = 0; i < nr; i++) - softpipe->occlusion_count += count_bits(quads[i]->inout.mask); - - qs->next->run(qs->next, quads, nr); -} - - -static void occlusion_begin(struct quad_stage *qs) -{ - qs->next->begin(qs->next); -} - - -static void occlusion_destroy(struct quad_stage *qs) -{ - FREE( qs ); -} - - -struct quad_stage *sp_quad_occlusion_stage( struct softpipe_context *softpipe ) -{ - struct quad_stage *stage = CALLOC_STRUCT(quad_stage); - - stage->softpipe = softpipe; - stage->begin = occlusion_begin; - stage->run = occlusion_count_quads; - stage->destroy = occlusion_destroy; - - return stage; -} diff --git a/src/gallium/drivers/softpipe/sp_quad_pipe.c b/src/gallium/drivers/softpipe/sp_quad_pipe.c index d138d417acb..1b5bab4eca6 100644 --- a/src/gallium/drivers/softpipe/sp_quad_pipe.c +++ b/src/gallium/drivers/softpipe/sp_quad_pipe.c @@ -38,18 +38,6 @@ sp_push_quad_first( struct softpipe_context *sp, sp->quad.first = quad; } -static void -sp_build_depth_stencil( struct softpipe_context *sp ) -{ - if (sp->depth_stencil->stencil[0].enabled || - sp->depth_stencil->stencil[1].enabled) { - sp_push_quad_first( sp, sp->quad.stencil_test ); - } - else if (sp->depth_stencil->depth.enabled && - sp->framebuffer.zsbuf) { - sp_push_quad_first( sp, sp->quad.depth_test ); - } -} void sp_build_quad_pipeline(struct softpipe_context *sp) @@ -61,37 +49,15 @@ sp_build_quad_pipeline(struct softpipe_context *sp) !sp->fs->info.uses_kill && !sp->fs->info.writes_z; - /* build up the pipeline in reverse order... */ - - /* Color combine - */ sp->quad.first = sp->quad.blend; - /* Shade/Depth/Stencil/Alpha - */ - if ((sp->rasterizer->poly_smooth && sp->reduced_prim == PIPE_PRIM_TRIANGLES) || - (sp->rasterizer->line_smooth && sp->reduced_prim == PIPE_PRIM_LINES) || - (sp->rasterizer->point_smooth && sp->reduced_prim == PIPE_PRIM_POINTS)) { - sp_push_quad_first( sp, sp->quad.coverage ); - } - - if (sp->active_query_count) { - sp_push_quad_first( sp, sp->quad.occlusion ); - } - - if (!early_depth_test) { - sp_build_depth_stencil( sp ); - } - - if (sp->depth_stencil->alpha.enabled) { - sp_push_quad_first( sp, sp->quad.alpha_test ); - } - - sp_push_quad_first( sp, sp->quad.shade ); - if (early_depth_test) { - sp_build_depth_stencil( sp ); - sp_push_quad_first( sp, sp->quad.earlyz ); + sp_push_quad_first( sp, sp->quad.shade ); + sp_push_quad_first( sp, sp->quad.depth_test ); + } + else { + sp_push_quad_first( sp, sp->quad.depth_test ); + sp_push_quad_first( sp, sp->quad.shade ); } } diff --git a/src/gallium/drivers/softpipe/sp_quad_pipe.h b/src/gallium/drivers/softpipe/sp_quad_pipe.h index add31ba7056..c0aa1348319 100644 --- a/src/gallium/drivers/softpipe/sp_quad_pipe.h +++ b/src/gallium/drivers/softpipe/sp_quad_pipe.h @@ -69,6 +69,4 @@ struct quad_stage *sp_quad_output_stage( struct softpipe_context *softpipe ); void sp_build_quad_pipeline(struct softpipe_context *sp); -boolean sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad); - #endif /* SP_QUAD_PIPE_H */ diff --git a/src/gallium/drivers/softpipe/sp_quad_stencil.c b/src/gallium/drivers/softpipe/sp_quad_stencil.c deleted file mode 100644 index d9ee80e59a3..00000000000 --- a/src/gallium/drivers/softpipe/sp_quad_stencil.c +++ /dev/null @@ -1,363 +0,0 @@ - -/** - * \brief Quad stencil testing - */ - - -#include "sp_context.h" -#include "sp_quad.h" -#include "sp_surface.h" -#include "sp_tile_cache.h" -#include "sp_quad_pipe.h" -#include "pipe/p_defines.h" -#include "util/u_memory.h" - - -/** Only 8-bit stencil supported */ -#define STENCIL_MAX 0xff - - -/** - * Do the basic stencil test (compare stencil buffer values against the - * reference value. - * - * \param stencilVals the stencil values from the stencil buffer - * \param func the stencil func (PIPE_FUNC_x) - * \param ref the stencil reference value - * \param valMask the stencil value mask indicating which bits of the stencil - * values and ref value are to be used. - * \return mask indicating which pixels passed the stencil test - */ -static unsigned -do_stencil_test(const ubyte stencilVals[QUAD_SIZE], unsigned func, - unsigned ref, unsigned valMask) -{ - unsigned passMask = 0x0; - unsigned j; - - ref &= valMask; - - switch (func) { - case PIPE_FUNC_NEVER: - /* passMask = 0x0 */ - break; - case PIPE_FUNC_LESS: - for (j = 0; j < QUAD_SIZE; j++) { - if (ref < (stencilVals[j] & valMask)) { - passMask |= (1 << j); - } - } - break; - case PIPE_FUNC_EQUAL: - for (j = 0; j < QUAD_SIZE; j++) { - if (ref == (stencilVals[j] & valMask)) { - passMask |= (1 << j); - } - } - break; - case PIPE_FUNC_LEQUAL: - for (j = 0; j < QUAD_SIZE; j++) { - if (ref <= (stencilVals[j] & valMask)) { - passMask |= (1 << j); - } - } - break; - case PIPE_FUNC_GREATER: - for (j = 0; j < QUAD_SIZE; j++) { - if (ref > (stencilVals[j] & valMask)) { - passMask |= (1 << j); - } - } - break; - case PIPE_FUNC_NOTEQUAL: - for (j = 0; j < QUAD_SIZE; j++) { - if (ref != (stencilVals[j] & valMask)) { - passMask |= (1 << j); - } - } - break; - case PIPE_FUNC_GEQUAL: - for (j = 0; j < QUAD_SIZE; j++) { - if (ref >= (stencilVals[j] & valMask)) { - passMask |= (1 << j); - } - } - break; - case PIPE_FUNC_ALWAYS: - passMask = MASK_ALL; - break; - default: - assert(0); - } - - return passMask; -} - - -/** - * Apply the stencil operator to stencil values. - * - * \param stencilVals the stencil buffer values (read and written) - * \param mask indicates which pixels to update - * \param op the stencil operator (PIPE_STENCIL_OP_x) - * \param ref the stencil reference value - * \param wrtMask writemask controlling which bits are changed in the - * stencil values - */ -static void -apply_stencil_op(ubyte stencilVals[QUAD_SIZE], - unsigned mask, unsigned op, ubyte ref, ubyte wrtMask) -{ - unsigned j; - ubyte newstencil[QUAD_SIZE]; - - for (j = 0; j < QUAD_SIZE; j++) { - newstencil[j] = stencilVals[j]; - } - - switch (op) { - case PIPE_STENCIL_OP_KEEP: - /* no-op */ - break; - case PIPE_STENCIL_OP_ZERO: - for (j = 0; j < QUAD_SIZE; j++) { - if (mask & (1 << j)) { - newstencil[j] = 0; - } - } - break; - case PIPE_STENCIL_OP_REPLACE: - for (j = 0; j < QUAD_SIZE; j++) { - if (mask & (1 << j)) { - newstencil[j] = ref; - } - } - break; - case PIPE_STENCIL_OP_INCR: - for (j = 0; j < QUAD_SIZE; j++) { - if (mask & (1 << j)) { - if (stencilVals[j] < STENCIL_MAX) { - newstencil[j] = stencilVals[j] + 1; - } - } - } - break; - case PIPE_STENCIL_OP_DECR: - for (j = 0; j < QUAD_SIZE; j++) { - if (mask & (1 << j)) { - if (stencilVals[j] > 0) { - newstencil[j] = stencilVals[j] - 1; - } - } - } - break; - case PIPE_STENCIL_OP_INCR_WRAP: - for (j = 0; j < QUAD_SIZE; j++) { - if (mask & (1 << j)) { - newstencil[j] = stencilVals[j] + 1; - } - } - break; - case PIPE_STENCIL_OP_DECR_WRAP: - for (j = 0; j < QUAD_SIZE; j++) { - if (mask & (1 << j)) { - newstencil[j] = stencilVals[j] - 1; - } - } - break; - case PIPE_STENCIL_OP_INVERT: - for (j = 0; j < QUAD_SIZE; j++) { - if (mask & (1 << j)) { - newstencil[j] = ~stencilVals[j]; - } - } - break; - default: - assert(0); - } - - /* - * update the stencil values - */ - if (wrtMask != STENCIL_MAX) { - /* apply bit-wise stencil buffer writemask */ - for (j = 0; j < QUAD_SIZE; j++) { - stencilVals[j] = (wrtMask & newstencil[j]) | (~wrtMask & stencilVals[j]); - } - } - else { - for (j = 0; j < QUAD_SIZE; j++) { - stencilVals[j] = newstencil[j]; - } - } -} - - -/** - * Do stencil (and depth) testing. Stenciling depends on the outcome of - * depth testing. - */ -static void -stencil_test_quad(struct quad_stage *qs, struct quad_header *quads[], - unsigned nr) -{ - struct softpipe_context *softpipe = qs->softpipe; - struct pipe_surface *ps = softpipe->framebuffer.zsbuf; - unsigned func, zFailOp, zPassOp, failOp; - ubyte ref, wrtMask, valMask; - ubyte stencilVals[QUAD_SIZE]; - struct softpipe_cached_tile *tile - = sp_get_cached_tile(softpipe->zsbuf_cache, - quads[0]->input.x0, - quads[0]->input.y0); - uint face = quads[0]->input.facing; - uint pass = 0; - uint j, q; - - if (!softpipe->depth_stencil->stencil[1].enabled) { - /* single-sided stencil test, use front (face=0) state */ - face = 0; - } - - /* choose front or back face function, operator, etc */ - /* XXX we could do these initializations once per primitive */ - func = softpipe->depth_stencil->stencil[face].func; - failOp = softpipe->depth_stencil->stencil[face].fail_op; - zFailOp = softpipe->depth_stencil->stencil[face].zfail_op; - zPassOp = softpipe->depth_stencil->stencil[face].zpass_op; - ref = softpipe->depth_stencil->stencil[face].ref_value; - wrtMask = softpipe->depth_stencil->stencil[face].writemask; - valMask = softpipe->depth_stencil->stencil[face].valuemask; - - assert(ps); /* shouldn't get here if there's no stencil buffer */ - - for (q = 0; q < nr; q++) { - struct quad_header *quad = quads[q]; - - /* get stencil values from cached tile */ - switch (ps->format) { - case PIPE_FORMAT_S8Z24_UNORM: - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - stencilVals[j] = tile->data.depth32[y][x] >> 24; - } - break; - case PIPE_FORMAT_Z24S8_UNORM: - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - stencilVals[j] = tile->data.depth32[y][x] & 0xff; - } - break; - case PIPE_FORMAT_S8_UNORM: - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - stencilVals[j] = tile->data.stencil8[y][x]; - } - break; - default: - assert(0); - } - - /* do the stencil test first */ - { - unsigned passMask, failMask; - passMask = do_stencil_test(stencilVals, func, ref, valMask); - failMask = quad->inout.mask & ~passMask; - quad->inout.mask &= passMask; - - if (failOp != PIPE_STENCIL_OP_KEEP) { - apply_stencil_op(stencilVals, failMask, failOp, ref, wrtMask); - } - } - - if (quad->inout.mask) { - /* now the pixels that passed the stencil test are depth tested */ - if (softpipe->depth_stencil->depth.enabled) { - const unsigned origMask = quad->inout.mask; - - sp_depth_test_quad(qs, quad); /* quad->mask is updated */ - - /* update stencil buffer values according to z pass/fail result */ - if (zFailOp != PIPE_STENCIL_OP_KEEP) { - const unsigned failMask = origMask & ~quad->inout.mask; - apply_stencil_op(stencilVals, failMask, zFailOp, ref, wrtMask); - } - - if (zPassOp != PIPE_STENCIL_OP_KEEP) { - const unsigned passMask = origMask & quad->inout.mask; - apply_stencil_op(stencilVals, passMask, zPassOp, ref, wrtMask); - } - } - else { - /* no depth test, apply Zpass operator to stencil buffer values */ - apply_stencil_op(stencilVals, quad->inout.mask, zPassOp, ref, wrtMask); - } - - } - - /* put new stencil values into cached tile */ - switch (ps->format) { - case PIPE_FORMAT_S8Z24_UNORM: - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - uint s8z24 = tile->data.depth32[y][x]; - s8z24 = (stencilVals[j] << 24) | (s8z24 & 0xffffff); - tile->data.depth32[y][x] = s8z24; - } - break; - case PIPE_FORMAT_Z24S8_UNORM: - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - uint z24s8 = tile->data.depth32[y][x]; - z24s8 = (z24s8 & 0xffffff00) | stencilVals[j]; - tile->data.depth32[y][x] = z24s8; - } - break; - case PIPE_FORMAT_S8_UNORM: - for (j = 0; j < QUAD_SIZE; j++) { - int x = quad->input.x0 % TILE_SIZE + (j & 1); - int y = quad->input.y0 % TILE_SIZE + (j >> 1); - tile->data.stencil8[y][x] = stencilVals[j]; - } - break; - default: - assert(0); - } - - if (quad->inout.mask) - quads[pass++] = quad; - } - - if (pass) - qs->next->run(qs->next, quads, pass); -} - - -static void stencil_begin(struct quad_stage *qs) -{ - qs->next->begin(qs->next); -} - - -static void stencil_destroy(struct quad_stage *qs) -{ - FREE( qs ); -} - - -struct quad_stage *sp_quad_stencil_test_stage( struct softpipe_context *softpipe ) -{ - struct quad_stage *stage = CALLOC_STRUCT(quad_stage); - - stage->softpipe = softpipe; - stage->begin = stencil_begin; - stage->run = stencil_test_quad; - stage->destroy = stencil_destroy; - - return stage; -} diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 02265012678..8654069bdeb 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -246,9 +246,7 @@ void softpipe_update_derived( struct softpipe_context *softpipe ) if (softpipe->dirty & (SP_NEW_BLEND | SP_NEW_DEPTH_STENCIL_ALPHA | SP_NEW_FRAMEBUFFER | - SP_NEW_RASTERIZER | - SP_NEW_FS | - SP_NEW_QUERY)) + SP_NEW_FS)) sp_build_quad_pipeline(softpipe); softpipe->dirty = 0; -- cgit v1.2.3 From 1078844d18367b4259cd3b6a3a73e3cd72ea019f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 27 Jul 2009 11:23:51 +0100 Subject: softpipe: cope with nr_cbufs == 0 Disable blend code when no color buffer --- src/gallium/drivers/softpipe/sp_quad_blend.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index e1f0e772554..e243c63fa23 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -924,6 +924,13 @@ single_output_color(struct quad_stage *qs, } } +static void +blend_noop(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) +{ +} + static void choose_blend_quad(struct quad_stage *qs, @@ -934,9 +941,12 @@ choose_blend_quad(struct quad_stage *qs, const struct pipe_blend_state *blend = softpipe->blend; qs->run = blend_fallback; - - if (!softpipe->blend->logicop_enable && - softpipe->blend->colormask == 0xf) + + if (softpipe->framebuffer.nr_cbufs == 0) { + qs->run = blend_noop; + } + else if (!softpipe->blend->logicop_enable && + softpipe->blend->colormask == 0xf) { if (!blend->blend_enable) { qs->run = single_output_color; -- cgit v1.2.3 From c61145820556833dccd728eb6df3397bec7f70da Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 27 Jul 2009 12:11:16 +0100 Subject: softpipe: fastpath for interpolated z16 less depthtesting Because this is interpolated (ie. early) depth, we can build in an assumption about the quads emitted by triangle setup, ie that they are actually linear spans. Interpolate z over those spans in z16 format to save on math & conversion. --- src/gallium/drivers/softpipe/sp_quad_depth_test.c | 143 +++++++++++++++++++++- 1 file changed, 139 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index bf65799a818..506867f4d07 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -646,9 +646,9 @@ static unsigned mask_count[0x8] = static void -depth_test_quads(struct quad_stage *qs, - struct quad_header *quads[], - unsigned nr) +depth_test_quads_fallback(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) { unsigned i, pass = 0; const struct sp_fragment_shader *fs = qs->softpipe->fs; @@ -704,9 +704,144 @@ depth_test_quads(struct quad_stage *qs, qs->next->run(qs->next, quads, nr); } +/* XXX: this function assumes setup function actually emits linear + * spans of quads. It seems a lot more natural to do (early) + * depth-testing on spans rather than quads. + */ +static void +depth_interp_z16_less_write(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) +{ + unsigned i, pass = 0; + const unsigned ix = quads[0]->input.x0; + const unsigned iy = quads[0]->input.y0; + const float fx = (float) ix; + const float fy = (float) iy; + const float dzdx = quads[0]->posCoef->dadx[2]; + const float dzdy = quads[0]->posCoef->dady[2]; + const float z0 = quads[0]->posCoef->a0[2] + dzdx * fx + dzdy * fy; + struct softpipe_cached_tile *tile; + ushort (*depth16)[TILE_SIZE]; + ushort idepth[4], depth_step; + const float scale = 65535.0; + + idepth[0] = (ushort)((z0) * scale); + idepth[1] = (ushort)((z0 + dzdx) * scale); + idepth[2] = (ushort)((z0 + dzdy) * scale); + idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale); + + depth_step = (ushort)(dzdx * 2 * scale); + + tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, ix, iy); + + depth16 = (ushort (*)[TILE_SIZE]) + &tile->data.depth16[iy % TILE_SIZE][ix % TILE_SIZE]; + + for (i = 0; i < nr; i++) { + unsigned outmask = quads[i]->inout.mask; + unsigned mask = 0; + + if ((outmask & 1) && idepth[0] < depth16[0][0]) { + depth16[0][0] = idepth[0]; + mask |= (1 << 0); + } + + if ((outmask & 2) && idepth[1] < depth16[0][1]) { + depth16[0][1] = idepth[1]; + mask |= (1 << 1); + } + + if ((outmask & 4) && idepth[2] < depth16[1][0]) { + depth16[1][0] = idepth[2]; + mask |= (1 << 2); + } + + if ((outmask & 8) && idepth[3] < depth16[1][1]) { + depth16[1][1] = idepth[3]; + mask |= (1 << 3); + } + + idepth[0] += depth_step; + idepth[1] += depth_step; + idepth[2] += depth_step; + idepth[3] += depth_step; + + depth16 = (ushort (*)[TILE_SIZE]) &depth16[0][2]; + + quads[i]->inout.mask = mask; + if (quads[i]->inout.mask) + quads[pass++] = quads[i]; + } + + if (pass) + qs->next->run(qs->next, quads, pass); + +} + + +static void +depth_noop(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) +{ + qs->next->run(qs->next, quads, nr); +} + + + +static void +choose_depth_test(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) +{ + boolean interp_depth = !qs->softpipe->fs->info.writes_z; + + boolean alpha = qs->softpipe->depth_stencil->alpha.enabled; + + boolean depth = (qs->softpipe->framebuffer.zsbuf && + qs->softpipe->depth_stencil->depth.enabled); + + unsigned depthfunc = qs->softpipe->depth_stencil->depth.func; + + boolean stencil = qs->softpipe->depth_stencil->stencil[0].enabled; + + boolean depthwrite = qs->softpipe->depth_stencil->depth.writemask; + + + qs->run = depth_test_quads_fallback; + + if (!alpha && + !depth && + !stencil) { + qs->run = depth_noop; + } + else if (!alpha && + interp_depth && + depth && + depthfunc == PIPE_FUNC_LESS && + depthwrite && + !stencil) + { + switch (qs->softpipe->framebuffer.zsbuf->format) { + case PIPE_FORMAT_Z16_UNORM: + qs->run = depth_interp_z16_less_write; + break; + default: + break; + } + } + + qs->run( qs, quads, nr ); +} + + + + static void depth_test_begin(struct quad_stage *qs) { + qs->run = choose_depth_test; qs->next->begin(qs->next); } @@ -723,7 +858,7 @@ struct quad_stage *sp_quad_depth_test_stage( struct softpipe_context *softpipe ) stage->softpipe = softpipe; stage->begin = depth_test_begin; - stage->run = depth_test_quads; + stage->run = choose_depth_test; stage->destroy = depth_test_destroy; return stage; -- cgit v1.2.3 From 6142de393fe34ff0866f8489f1292eb473276f11 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 27 Jul 2009 12:44:58 +0100 Subject: softpipe: example fast paths for simple samplers All these fastpaths are examples of the types of things we'd code-generate in a more sophisticated version of softpipe. --- src/gallium/drivers/softpipe/sp_state_derived.c | 1 + src/gallium/drivers/softpipe/sp_tex_sample.c | 327 +++++++++++++++++++++++- src/gallium/drivers/softpipe/sp_tex_sample.h | 10 +- 3 files changed, 333 insertions(+), 5 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 8654069bdeb..3ed1de7e178 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -208,6 +208,7 @@ update_tgsi_samplers( struct softpipe_context *softpipe ) for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { softpipe->tgsi.frag_samplers[i].sampler = softpipe->sampler[i]; softpipe->tgsi.frag_samplers[i].texture = softpipe->texture[i]; + softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples_fragment; } for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 46c56b0c835..8248576e98e 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -662,10 +662,64 @@ choose_mipmap_levels(const struct pipe_texture *texture, * XXX maybe move this into sp_tile_cache.c and merge with the * sp_get_cached_tile_tex() function. Also, get 4 texels instead of 1... */ +static void +get_texel_quad_2d(const struct tgsi_sampler *tgsi_sampler, + unsigned face, unsigned level, int x, int y, + const float *out[4]) +{ + const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); + + const struct softpipe_cached_tile *tile + = sp_get_cached_tile_tex(samp->cache, + tile_address(x, y, 0, face, level)); + + y %= TILE_SIZE; + x %= TILE_SIZE; + + out[0] = &tile->data.color[y ][x ][0]; + out[1] = &tile->data.color[y ][x+1][0]; + out[2] = &tile->data.color[y+1][x ][0]; + out[3] = &tile->data.color[y+1][x+1][0]; +} + +static INLINE const float * +get_texel_2d_ptr(const struct tgsi_sampler *tgsi_sampler, + unsigned face, unsigned level, int x, int y) +{ + const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); + + const struct softpipe_cached_tile *tile + = sp_get_cached_tile_tex(samp->cache, + tile_address(x, y, 0, face, level)); + + y %= TILE_SIZE; + x %= TILE_SIZE; + + return &tile->data.color[y][x][0]; +} + + +static void +get_texel_quad_2d_mt(const struct tgsi_sampler *tgsi_sampler, + unsigned face, unsigned level, + int x0, int y0, + int x1, int y1, + const float *out[4]) +{ + unsigned i; + + for (i = 0; i < 4; i++) { + unsigned tx = (i & 1) ? x1 : x0; + unsigned ty = (i >> 1) ? y1 : y0; + + out[i] = get_texel_2d_ptr( tgsi_sampler, face, level, tx, ty ); + } +} + static void get_texel(const struct tgsi_sampler *tgsi_sampler, - unsigned face, unsigned level, int x, int y, int z, - float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j) + unsigned face, unsigned level, int x, int y, int z, + float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j) { const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); const struct pipe_texture *texture = samp->texture; @@ -825,6 +879,193 @@ shadow_compare4(const struct pipe_sampler_state *sampler, } + +static void +sp_get_samples_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); + unsigned j; + unsigned level = samp->level; + unsigned xpot = 1 << (samp->xpot - level); + unsigned ypot = 1 << (samp->ypot - level); + + for (j = 0; j < QUAD_SIZE; j++) { + int c; + + float u = s[j] * xpot - 0.5F; + float v = t[j] * ypot - 0.5F; + + int uflr = util_ifloor(u); + int vflr = util_ifloor(v); + + float xw = u - (float)uflr; + float yw = v - (float)vflr; + + int x0 = uflr & (xpot - 1); + int y0 = vflr & (ypot - 1); + + const float *tx[4]; + + + /* Can we fetch all four at once: + */ + if (x0 % TILE_SIZE != TILE_SIZE-1 && + y0 % TILE_SIZE != TILE_SIZE-1) + { + get_texel_quad_2d(tgsi_sampler, 0, level, x0, y0, tx); + } + else + { + unsigned x1 = (uflr + 1) & (xpot - 1); + unsigned y1 = (vflr + 1) & (ypot - 1); + get_texel_quad_2d_mt(tgsi_sampler, 0, level, + x0, y0, x1, y1, tx); + } + + + /* interpolate R, G, B, A */ + for (c = 0; c < 4; c++) { + rgba[c][j] = lerp_2d(xw, yw, + tx[0][c], tx[1][c], + tx[2][c], tx[3][c]); + } + } +} + + +static void +sp_get_samples_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); + unsigned j; + unsigned level = samp->level; + unsigned xpot = 1 << (samp->xpot - level); + unsigned ypot = 1 << (samp->ypot - level); + + for (j = 0; j < QUAD_SIZE; j++) { + int c; + + float u = s[j] * xpot - 0.5F; + float v = t[j] * ypot - 0.5F; + + int uflr = util_ifloor(u); + int vflr = util_ifloor(v); + + int x0 = uflr & (xpot - 1); + int y0 = vflr & (ypot - 1); + + const float *out = get_texel_2d_ptr(tgsi_sampler, 0, level, x0, y0); + + for (c = 0; c < 4; c++) { + rgba[c][j] = out[c]; + } + } +} + + +static void +sp_get_samples_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); + unsigned j; + unsigned level = samp->level; + unsigned xpot = (1<xpot); + unsigned ypot = (1<ypot); + + for (j = 0; j < QUAD_SIZE; j++) { + int c; + + float u = s[j] * xpot - 0.5F; + float v = t[j] * ypot - 0.5F; + + int x0, y0; + const float *out; + + x0 = util_ifloor(u); + if (x0 < 0) + x0 = 0; + else if (x0 > xpot - 1) + x0 = xpot - 1; + + y0 = util_ifloor(v); + if (y0 < 0) + y0 = 0; + else if (y0 > ypot - 1) + y0 = ypot - 1; + + out = get_texel_2d_ptr(tgsi_sampler, 0, level, x0, y0); + + for (c = 0; c < 4; c++) { + rgba[c][j] = out[c]; + } + } +} + + +static void +sp_get_samples_2d_linear_mip_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); + const struct pipe_texture *texture = samp->texture; + const struct pipe_sampler_state *sampler = samp->sampler; + int level0, level1; + float lambda; + + lambda = compute_lambda(texture, sampler, s, t, p, lodbias); + level0 = (int)lambda; + level1 = level0 + 1; + + if (lambda < 0.0) { + samp->level = 0; + sp_get_samples_2d_linear_repeat_POT( tgsi_sampler, + s, t, p, lodbias, rgba ); + } + else if (level0 >= texture->last_level) { + samp->level = texture->last_level; + sp_get_samples_2d_linear_repeat_POT( tgsi_sampler, + s, t, p, lodbias, rgba ); + } + else { + float rgba0[4][4]; + float rgba1[4][4]; + int c,j; + + float levelBlend = lambda - level0; /* blending weight between levels */ + + samp->level = level0; + sp_get_samples_2d_linear_repeat_POT( tgsi_sampler, + s, t, p, lodbias, rgba0 ); + + samp->level++; + sp_get_samples_2d_linear_repeat_POT( tgsi_sampler, + s, t, p, lodbias, rgba1 ); + + for (c = 0; c < 4; c++) + for (j = 0; j < 4; j++) + rgba[c][j] = lerp(levelBlend, rgba0[c][j], rgba1[c][j]); + } +} + /** * Common code for sampling 1D/2D/cube textures. * Could probably extend for 3D... @@ -1254,6 +1495,16 @@ sp_get_samples(struct tgsi_sampler *tgsi_sampler, #endif } +static void +sp_get_samples_fallback(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + sp_get_samples(tgsi_sampler, s, t, p, TRUE, lodbias, rgba); +} /** * Called via tgsi_sampler::get_samples() when running a fragment shader. @@ -1267,7 +1518,77 @@ sp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler, float lodbias, float rgba[NUM_CHANNELS][QUAD_SIZE]) { - sp_get_samples(tgsi_sampler, s, t, p, TRUE, lodbias, rgba); + struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); + const struct pipe_texture *texture = samp->texture; + const struct pipe_sampler_state *sampler = samp->sampler; + + tgsi_sampler->get_samples = sp_get_samples_fallback; + + /* Try to hook in a faster sampler. Ultimately we'll have to + * code-generate these. Luckily most of this looks like it is + * orthogonal state within the sampler. + */ + if (texture->target == PIPE_TEXTURE_2D && + sampler->min_img_filter == sampler->mag_img_filter && + sampler->wrap_s == sampler->wrap_t && + sampler->compare_mode == FALSE && + sampler->normalized_coords) + { + samp->xpot = util_unsigned_logbase2( samp->texture->width[0] ); + samp->ypot = util_unsigned_logbase2( samp->texture->height[0] ); + + if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { + samp->level = CLAMP((int) sampler->min_lod, + 0, (int) texture->last_level); + + if (sampler->wrap_s == PIPE_TEX_WRAP_REPEAT) { + switch (sampler->min_img_filter) { + case PIPE_TEX_FILTER_NEAREST: + tgsi_sampler->get_samples = sp_get_samples_2d_nearest_repeat_POT; + break; + case PIPE_TEX_FILTER_LINEAR: + tgsi_sampler->get_samples = sp_get_samples_2d_linear_repeat_POT; + break; + default: + break; + } + } + else if (sampler->wrap_s == PIPE_TEX_WRAP_CLAMP) { + switch (sampler->min_img_filter) { + case PIPE_TEX_FILTER_NEAREST: + tgsi_sampler->get_samples = sp_get_samples_2d_nearest_clamp_POT; + break; + default: + break; + } + } + } + else if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_LINEAR) { + if (sampler->wrap_s == PIPE_TEX_WRAP_REPEAT) { + switch (sampler->min_img_filter) { + case PIPE_TEX_FILTER_LINEAR: + /* This one not working yet: + */ + if (0) + tgsi_sampler->get_samples = sp_get_samples_2d_linear_mip_linear_repeat_POT; + break; + default: + break; + } + } + } + } + else if (0) { + _debug_printf("target %d/%d min_mip %d/%d min_img %d/%d wrap %d/%d compare %d/%d norm %d/%d\n", + texture->target, PIPE_TEXTURE_2D, + sampler->min_mip_filter, PIPE_TEX_MIPFILTER_NONE, + sampler->min_img_filter, sampler->mag_img_filter, + sampler->wrap_s, sampler->wrap_t, + sampler->compare_mode, FALSE, + sampler->normalized_coords, TRUE); + } + + tgsi_sampler->get_samples( tgsi_sampler, s, t, p, lodbias, rgba ); } diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h index 3c5beb560f2..0650c7830b9 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.h +++ b/src/gallium/drivers/softpipe/sp_tex_sample.h @@ -39,6 +39,12 @@ struct sp_shader_sampler { struct tgsi_sampler base; /**< base class */ + /* For sp_get_samples_2d_linear_POT: + */ + unsigned xpot; + unsigned ypot; + unsigned level; + const struct pipe_texture *texture; const struct pipe_sampler_state *sampler; @@ -47,10 +53,10 @@ struct sp_shader_sampler -static INLINE const struct sp_shader_sampler * +static INLINE struct sp_shader_sampler * sp_shader_sampler(const struct tgsi_sampler *sampler) { - return (const struct sp_shader_sampler *) sampler; + return (struct sp_shader_sampler *) sampler; } -- cgit v1.2.3 From 5fdac2dcea09c654725666b3cab5f59dfc9e31a5 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 27 Jul 2009 15:51:15 +0100 Subject: softpipe: fix off-by-one in nearest texcoord routines Stray '- 0.5' copied from linear versions. --- src/gallium/drivers/softpipe/sp_tex_sample.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 8248576e98e..4651d781a95 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -955,8 +955,8 @@ sp_get_samples_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler, for (j = 0; j < QUAD_SIZE; j++) { int c; - float u = s[j] * xpot - 0.5F; - float v = t[j] * ypot - 0.5F; + float u = s[j] * xpot; + float v = t[j] * ypot; int uflr = util_ifloor(u); int vflr = util_ifloor(v); @@ -990,8 +990,8 @@ sp_get_samples_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler, for (j = 0; j < QUAD_SIZE; j++) { int c; - float u = s[j] * xpot - 0.5F; - float v = t[j] * ypot - 0.5F; + float u = s[j] * xpot; + float v = t[j] * ypot; int x0, y0; const float *out; -- cgit v1.2.3 From 572c2fb5bb6cec71ef42e93416251a6a6c183de0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 30 Jul 2009 11:34:36 +0100 Subject: softpipe: remove unused variable in shade_quad --- src/gallium/drivers/softpipe/sp_quad_fs.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index 56a8f55d774..e1bc0712def 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -74,7 +74,6 @@ shade_quad(struct quad_stage *qs, struct quad_header *quad) struct quad_shade_stage *qss = quad_shade_stage( qs ); struct softpipe_context *softpipe = qs->softpipe; struct tgsi_exec_machine *machine = qss->machine; - boolean z_written; /* run shader */ quad->inout.mask &= softpipe->fs->run( softpipe->fs, machine, quad ); @@ -82,7 +81,6 @@ shade_quad(struct quad_stage *qs, struct quad_header *quad) return FALSE; /* store outputs */ - z_written = FALSE; { const ubyte *sem_name = softpipe->fs->info.output_semantic_name; const ubyte *sem_index = softpipe->fs->info.output_semantic_index; @@ -104,7 +102,6 @@ shade_quad(struct quad_stage *qs, struct quad_header *quad) for (j = 0; j < 4; j++) { quad->output.depth[j] = machine->Outputs[0].xyzw[2].f[j]; } - z_written = TRUE; } break; } -- cgit v1.2.3 From 73a6178a73a4cc34195348a537d3f94aab6a43e1 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 30 Jul 2009 11:35:08 +0100 Subject: softpipe: add depth-lequal z16 path --- src/gallium/drivers/softpipe/sp_quad_depth_test.c | 107 ++++++++++++++++++++-- 1 file changed, 100 insertions(+), 7 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index 506867f4d07..9cffea2c9e6 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -780,6 +780,81 @@ depth_interp_z16_less_write(struct quad_stage *qs, } +static void +depth_interp_z16_lequal_write(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) +{ + unsigned i, pass = 0; + const unsigned ix = quads[0]->input.x0; + const unsigned iy = quads[0]->input.y0; + const float fx = (float) ix; + const float fy = (float) iy; + const float dzdx = quads[0]->posCoef->dadx[2]; + const float dzdy = quads[0]->posCoef->dady[2]; + const float z0 = quads[0]->posCoef->a0[2] + dzdx * fx + dzdy * fy; + struct softpipe_cached_tile *tile; + ushort (*depth16)[TILE_SIZE]; + ushort idepth[4], depth_step; + const float scale = 65535.0; + + idepth[0] = (ushort)((z0) * scale); + idepth[1] = (ushort)((z0 + dzdx) * scale); + idepth[2] = (ushort)((z0 + dzdy) * scale); + idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale); + + depth_step = (ushort)(dzdx * 2 * scale); + + tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, ix, iy); + + depth16 = (ushort (*)[TILE_SIZE]) + &tile->data.depth16[iy % TILE_SIZE][ix % TILE_SIZE]; + + for (i = 0; i < nr; i++) { + unsigned outmask = quads[i]->inout.mask; + unsigned mask = 0; + + if ((outmask & 1) && idepth[0] <= depth16[0][0]) { + depth16[0][0] = idepth[0]; + mask |= (1 << 0); + } + + if ((outmask & 2) && idepth[1] <= depth16[0][1]) { + depth16[0][1] = idepth[1]; + mask |= (1 << 1); + } + + if ((outmask & 4) && idepth[2] <= depth16[1][0]) { + depth16[1][0] = idepth[2]; + mask |= (1 << 2); + } + + if ((outmask & 8) && idepth[3] <= depth16[1][1]) { + depth16[1][1] = idepth[3]; + mask |= (1 << 3); + } + + idepth[0] += depth_step; + idepth[1] += depth_step; + idepth[2] += depth_step; + idepth[3] += depth_step; + + depth16 = (ushort (*)[TILE_SIZE]) &depth16[0][2]; + + quads[i]->inout.mask = mask; + if (quads[i]->inout.mask) + quads[pass++] = quads[i]; + } + + if (pass) + qs->next->run(qs->next, quads, pass); + +} + + + + + static void depth_noop(struct quad_stage *qs, struct quad_header *quads[], @@ -809,8 +884,6 @@ choose_depth_test(struct quad_stage *qs, boolean depthwrite = qs->softpipe->depth_stencil->depth.writemask; - qs->run = depth_test_quads_fallback; - if (!alpha && !depth && !stencil) { @@ -819,18 +892,38 @@ choose_depth_test(struct quad_stage *qs, else if (!alpha && interp_depth && depth && - depthfunc == PIPE_FUNC_LESS && depthwrite && !stencil) { - switch (qs->softpipe->framebuffer.zsbuf->format) { - case PIPE_FORMAT_Z16_UNORM: - qs->run = depth_interp_z16_less_write; + switch (depthfunc) { + case PIPE_FUNC_LESS: + switch (qs->softpipe->framebuffer.zsbuf->format) { + case PIPE_FORMAT_Z16_UNORM: + qs->run = depth_interp_z16_less_write; + break; + default: + qs->run = depth_test_quads_fallback; + break; + } break; - default: + case PIPE_FUNC_LEQUAL: + switch (qs->softpipe->framebuffer.zsbuf->format) { + case PIPE_FORMAT_Z16_UNORM: + qs->run = depth_interp_z16_lequal_write; + break; + default: + qs->run = depth_test_quads_fallback; + break; + } break; + default: + qs->run = depth_test_quads_fallback; } } + else { + qs->run = depth_test_quads_fallback; + } + qs->run( qs, quads, nr ); } -- cgit v1.2.3 From 1295cf423e21dad04a947960782ffa8db2739709 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 30 Jul 2009 11:35:50 +0100 Subject: softpipe: rearrange blend fastpaths --- src/gallium/drivers/softpipe/sp_quad_blend.c | 82 +++++++++------------------- 1 file changed, 27 insertions(+), 55 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index e243c63fa23..b8ed0867343 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -793,10 +793,7 @@ blend_single_add_src_alpha_inv_src_alpha(struct quad_stage *qs, struct quad_header *quads[], unsigned nr) { - static const float one[4] = { 1, 1, 1, 1 }; - float one_minus_alpha[QUAD_SIZE]; - float dest[4][QUAD_SIZE]; - float source[4][QUAD_SIZE]; + float source[4]; uint i, j, q; struct softpipe_cached_tile *tile @@ -806,45 +803,26 @@ blend_single_add_src_alpha_inv_src_alpha(struct quad_stage *qs, for (q = 0; q < nr; q++) { struct quad_header *quad = quads[q]; - float (*quadColor)[4] = quad->output.color[0]; - const float *alpha = quadColor[3]; const int itx = (quad->input.x0 & (TILE_SIZE-1)); const int ity = (quad->input.y0 & (TILE_SIZE-1)); + float (*swzColor)[4] = quad->output.color[0]; - /* get/swizzle dest colors */ - for (j = 0; j < QUAD_SIZE; j++) { - int x = itx + (j & 1); - int y = ity + (j >> 1); - for (i = 0; i < 4; i++) { - dest[i][j] = tile->data.color[y][x][i]; - } - } - - VEC4_MUL(source[0], quadColor[0], alpha); /* R */ - VEC4_MUL(source[1], quadColor[1], alpha); /* G */ - VEC4_MUL(source[2], quadColor[2], alpha); /* B */ - VEC4_MUL(source[3], quadColor[3], alpha); /* A */ + for (j = 0; j < 4; j++) { + if (quad->inout.mask & (1<data.color[ity + (j>>1)][itx + (j&1)]; + const float alpha = swzColor[3][j]; + const float one_minus_alpha = 1.0 - alpha; - VEC4_SUB(one_minus_alpha, one, alpha); - VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */ - VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */ - VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */ - VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* B */ - - VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */ - VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */ - VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */ - VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */ + for (i = 0; i < 4; i++) { + dest[i] *= one_minus_alpha; + dest[i] += swzColor[i][j] * alpha; - for (j = 0; j < QUAD_SIZE; j++) { - if (quad->inout.mask & (1 << j)) { - int x = itx + (j & 1); - int y = ity + (j >> 1); - for (i = 0; i < 4; i++) { /* loop over color chans */ - tile->data.color[y][x][i] = quadColor[i][j]; + /* XXX: redundant, will be clamped later for argb8 surfaces: + */ + dest[i] = CLAMP(dest[i], 0.0, 1.0); } } - } + } } } @@ -863,33 +841,27 @@ blend_single_add_one_one(struct quad_stage *qs, for (q = 0; q < nr; q++) { struct quad_header *quad = quads[q]; - float (*quadColor)[4] = quad->output.color[0]; const int itx = (quad->input.x0 & (TILE_SIZE-1)); const int ity = (quad->input.y0 & (TILE_SIZE-1)); - + float (*dest)[64][4] = (float (*)[64][4])&tile->data.color[ity][itx]; + float (*swzColor)[4] = quad->output.color[0]; + float quadColor[4][4]; + /* get/swizzle dest colors */ for (j = 0; j < QUAD_SIZE; j++) { - int x = itx + (j & 1); - int y = ity + (j >> 1); for (i = 0; i < 4; i++) { - dest[i][j] = tile->data.color[y][x][i]; + quadColor[i][j] = swzColor[j][i]; } } - VEC4_ADD_SAT(quadColor[0], quadColor[0], dest[0]); /* R */ - VEC4_ADD_SAT(quadColor[1], quadColor[1], dest[1]); /* G */ - VEC4_ADD_SAT(quadColor[2], quadColor[2], dest[2]); /* B */ - VEC4_ADD_SAT(quadColor[3], quadColor[3], dest[3]); /* A */ - - for (j = 0; j < QUAD_SIZE; j++) { - if (quad->inout.mask & (1 << j)) { - int x = itx + (j & 1); - int y = ity + (j >> 1); - for (i = 0; i < 4; i++) { /* loop over color chans */ - tile->data.color[y][x][i] = quadColor[i][j]; - } - } - } + if (quad->inout.mask & 1) + VEC4_ADD_SAT(dest[0][0], quadColor[0], dest[0][0]); + if (quad->inout.mask & 2) + VEC4_ADD_SAT(dest[0][1], quadColor[1], dest[0][1]); + if (quad->inout.mask & 4) + VEC4_ADD_SAT(dest[1][0], quadColor[2], dest[1][0]); + if (quad->inout.mask & 8) + VEC4_ADD_SAT(dest[1][1], quadColor[3], dest[1][1]); } } -- cgit v1.2.3 From 95f7ed4638d4e379783abdd5b250e203b6b1b435 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 30 Jul 2009 11:59:32 +0100 Subject: softpipe: setup quad outputs from with fs->run --- src/gallium/drivers/softpipe/sp_fs_exec.c | 34 ++++++++++++++++++++++++++++- src/gallium/drivers/softpipe/sp_fs_sse.c | 35 +++++++++++++++++++++++++++++- src/gallium/drivers/softpipe/sp_quad_fs.c | 36 ++----------------------------- 3 files changed, 69 insertions(+), 36 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c index 9ee86fe7878..91e04687c5b 100644 --- a/src/gallium/drivers/softpipe/sp_fs_exec.c +++ b/src/gallium/drivers/softpipe/sp_fs_exec.c @@ -126,7 +126,39 @@ exec_run( const struct sp_fragment_shader *base, (float)quad->input.x0, (float)quad->input.y0, &machine->QuadPos); - return tgsi_exec_machine_run( machine ); + quad->inout.mask &= tgsi_exec_machine_run( machine ); + if (quad->inout.mask == 0) + return FALSE; + + /* store outputs */ + { + const ubyte *sem_name = base->info.output_semantic_name; + const ubyte *sem_index = base->info.output_semantic_index; + const uint n = base->info.num_outputs; + uint i; + for (i = 0; i < n; i++) { + switch (sem_name[i]) { + case TGSI_SEMANTIC_COLOR: + { + uint cbuf = sem_index[i]; + memcpy(quad->output.color[cbuf], + &machine->Outputs[i].xyzw[0].f[0], + sizeof(quad->output.color[0]) ); + } + break; + case TGSI_SEMANTIC_POSITION: + { + uint j; + for (j = 0; j < 4; j++) { + quad->output.depth[j] = machine->Outputs[0].xyzw[2].f[j]; + } + } + break; + } + } + } + + return TRUE; } diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index f4fa0905d74..364bb94a5f6 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -104,7 +104,40 @@ fs_sse_run( const struct sp_fragment_shader *base, // , &machine->QuadPos ); - return ~(machine->Temps[TGSI_EXEC_TEMP_KILMASK_I].xyzw[TGSI_EXEC_TEMP_KILMASK_C].u[0]); + quad->inout.mask &= ~(machine->Temps[TGSI_EXEC_TEMP_KILMASK_I].xyzw[TGSI_EXEC_TEMP_KILMASK_C].u[0]); + if (quad->inout.mask == 0) + return FALSE; + + + /* store outputs */ + { + const ubyte *sem_name = shader->base.info.output_semantic_name; + const ubyte *sem_index = shader->base.info.output_semantic_index; + const uint n = shader->base.info.num_outputs; + uint i; + for (i = 0; i < n; i++) { + switch (sem_name[i]) { + case TGSI_SEMANTIC_COLOR: + { + uint cbuf = sem_index[i]; + memcpy(quad->output.color[cbuf], + &machine->Outputs[i].xyzw[0].f[0], + sizeof(quad->output.color[0]) ); + } + break; + case TGSI_SEMANTIC_POSITION: + { + uint j; + for (j = 0; j < 4; j++) { + quad->output.depth[j] = machine->Outputs[0].xyzw[2].f[j]; + } + } + break; + } + } + } + + return TRUE; } diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index e1bc0712def..1e7533d0f9e 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -68,7 +68,7 @@ quad_shade_stage(struct quad_stage *qs) /** * Execute fragment shader for the four fragments in the quad. */ -static boolean +static INLINE boolean shade_quad(struct quad_stage *qs, struct quad_header *quad) { struct quad_shade_stage *qss = quad_shade_stage( qs ); @@ -76,39 +76,7 @@ shade_quad(struct quad_stage *qs, struct quad_header *quad) struct tgsi_exec_machine *machine = qss->machine; /* run shader */ - quad->inout.mask &= softpipe->fs->run( softpipe->fs, machine, quad ); - if (quad->inout.mask == 0) - return FALSE; - - /* store outputs */ - { - const ubyte *sem_name = softpipe->fs->info.output_semantic_name; - const ubyte *sem_index = softpipe->fs->info.output_semantic_index; - const uint n = qss->stage.softpipe->fs->info.num_outputs; - uint i; - for (i = 0; i < n; i++) { - switch (sem_name[i]) { - case TGSI_SEMANTIC_COLOR: - { - uint cbuf = sem_index[i]; - memcpy(quad->output.color[cbuf], - &machine->Outputs[i].xyzw[0].f[0], - sizeof(quad->output.color[0]) ); - } - break; - case TGSI_SEMANTIC_POSITION: - { - uint j; - for (j = 0; j < 4; j++) { - quad->output.depth[j] = machine->Outputs[0].xyzw[2].f[j]; - } - } - break; - } - } - } - - return TRUE; + return softpipe->fs->run( softpipe->fs, machine, quad ); } -- cgit v1.2.3 From b5c389721aec09c260789e6371910937f15ef1a0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 11 Aug 2009 18:03:01 +0100 Subject: softpipe: remove gallivm fragment shaders However we do llvm integration, it will be different & more comprehensive than this. --- src/gallium/drivers/softpipe/Makefile | 1 - src/gallium/drivers/softpipe/sp_fs_llvm.c | 205 ----------------------------- src/gallium/drivers/softpipe/sp_state_fs.c | 7 +- 3 files changed, 2 insertions(+), 211 deletions(-) delete mode 100644 src/gallium/drivers/softpipe/sp_fs_llvm.c (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile index 48522abe98f..a6ed7ea6a2a 100644 --- a/src/gallium/drivers/softpipe/Makefile +++ b/src/gallium/drivers/softpipe/Makefile @@ -6,7 +6,6 @@ LIBNAME = softpipe C_SOURCES = \ sp_fs_exec.c \ sp_fs_sse.c \ - sp_fs_llvm.c \ sp_clear.c \ sp_flush.c \ sp_query.c \ diff --git a/src/gallium/drivers/softpipe/sp_fs_llvm.c b/src/gallium/drivers/softpipe/sp_fs_llvm.c deleted file mode 100644 index 95c0d982d12..00000000000 --- a/src/gallium/drivers/softpipe/sp_fs_llvm.c +++ /dev/null @@ -1,205 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * Execute fragment shader using LLVM code generation. - * Authors: - * Zack Rusin - */ - -#include "sp_context.h" -#include "sp_state.h" -#include "sp_fs.h" - -#include "pipe/p_state.h" -#include "pipe/p_defines.h" -#include "util/u_memory.h" -#include "tgsi/tgsi_sse2.h" - -#if 0 - -/** - * Subclass of sp_fragment_shader - */ -struct sp_llvm_fragment_shader -{ - struct sp_fragment_shader base; - struct gallivm_prog *llvm_prog; -}; - - -static void -shade_quad_llvm(struct quad_stage *qs, - struct quad_header *quad) -{ - struct quad_shade_stage *qss = quad_shade_stage(qs); - struct softpipe_context *softpipe = qs->softpipe; - float dests[4][16][4] ALIGN16_ATTRIB; - float inputs[4][16][4] ALIGN16_ATTRIB; - const float fx = (float) quad->x0; - const float fy = (float) quad->y0; - struct gallivm_prog *llvm = qss->llvm_prog; - - inputs[0][0][0] = fx; - inputs[1][0][0] = fx + 1.0f; - inputs[2][0][0] = fx; - inputs[3][0][0] = fx + 1.0f; - - inputs[0][0][1] = fy; - inputs[1][0][1] = fy; - inputs[2][0][1] = fy + 1.0f; - inputs[3][0][1] = fy + 1.0f; - - - gallivm_prog_inputs_interpolate(llvm, inputs, quad->coef); - -#if DLLVM - debug_printf("MASK = %d\n", quad->mask); - for (int i = 0; i < 4; ++i) { - for (int j = 0; j < 2; ++j) { - debug_printf("IN(%d,%d) [%f %f %f %f]\n", i, j, - inputs[i][j][0], inputs[i][j][1], inputs[i][j][2], inputs[i][j][3]); - } - } -#endif - - quad->mask &= - gallivm_fragment_shader_exec(llvm, fx, fy, dests, inputs, - softpipe->mapped_constants[PIPE_SHADER_FRAGMENT], - qss->samplers); -#if DLLVM - debug_printf("OUT LLVM = 1[%f %f %f %f], 2[%f %f %f %f]\n", - dests[0][0][0], dests[0][0][1], dests[0][0][2], dests[0][0][3], - dests[0][1][0], dests[0][1][1], dests[0][1][2], dests[0][1][3]); -#endif - - /* store result color */ - if (qss->colorOutSlot >= 0) { - unsigned i; - /* XXX need to handle multiple color outputs someday */ - allvmrt(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot] - == TGSI_SEMANTIC_COLOR); - for (i = 0; i < QUAD_SIZE; ++i) { - quad->outputs.color[0][0][i] = dests[i][qss->colorOutSlot][0]; - quad->outputs.color[0][1][i] = dests[i][qss->colorOutSlot][1]; - quad->outputs.color[0][2][i] = dests[i][qss->colorOutSlot][2]; - quad->outputs.color[0][3][i] = dests[i][qss->colorOutSlot][3]; - } - } -#if DLLVM - for (int i = 0; i < QUAD_SIZE; ++i) { - debug_printf("QLLVM%d(%d) [%f, %f, %f, %f]\n", i, qss->colorOutSlot, - quad->outputs.color[0][0][i], - quad->outputs.color[0][1][i], - quad->outputs.color[0][2][i], - quad->outputs.color[0][3][i]); - } -#endif - - /* store result Z */ - if (qss->depthOutSlot >= 0) { - /* output[slot] is new Z */ - uint i; - for (i = 0; i < 4; i++) { - quad->outputs.depth[i] = dests[i][0][2]; - } - } - else { - /* copy input Z (which was interpolated by the executor) to output Z */ - uint i; - for (i = 0; i < 4; i++) { - quad->outputs.depth[i] = inputs[i][0][2]; - } - } -#if DLLVM - debug_printf("D [%f, %f, %f, %f] mask = %d\n", - quad->outputs.depth[0], - quad->outputs.depth[1], - quad->outputs.depth[2], - quad->outputs.depth[3], quad->mask); -#endif - - /* shader may cull fragments */ - if( quad->mask ) { - qs->next->run( qs->next, quad ); - } -} - - -unsigned -run_llvm_fs( const struct sp_fragment_shader *base, - struct foo *machine ) -{ -} - - -void -delete_llvm_fs( struct sp_fragment_shader *base ) -{ - FREE(base); -} - - -struct sp_fragment_shader * -softpipe_create_fs_llvm(struct softpipe_context *softpipe, - const struct pipe_shader_state *templ) -{ - struct sp_llvm_fragment_shader *shader = NULL; - - /* LLVM fragment shaders currently disabled: - */ - state = CALLOC_STRUCT(sp_llvm_shader_state); - if (!state) - return NULL; - - state->llvm_prog = 0; - - if (!gallivm_global_cpu_engine()) { - gallivm_cpu_engine_create(state->llvm_prog); - } - else - gallivm_cpu_jit_compile(gallivm_global_cpu_engine(), state->llvm_prog); - - if (shader) { - shader->base.run = run_llvm_fs; - shader->base.delete = delete_llvm_fs; - } - - return shader; -} - - -#else - -struct sp_fragment_shader * -softpipe_create_fs_llvm(struct softpipe_context *softpipe, - const struct pipe_shader_state *templ) -{ - return NULL; -} - -#endif diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 4330c203935..108ac8b9bb1 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -51,12 +51,9 @@ softpipe_create_fs_state(struct pipe_context *pipe, tgsi_dump(templ->tokens, 0); /* codegen */ - state = softpipe_create_fs_llvm( softpipe, templ ); + state = softpipe_create_fs_sse( softpipe, templ ); if (!state) { - state = softpipe_create_fs_sse( softpipe, templ ); - if (!state) { - state = softpipe_create_fs_exec( softpipe, templ ); - } + state = softpipe_create_fs_exec( softpipe, templ ); } assert(state); -- cgit v1.2.3 From da319095f2ca8869657ebda0db54eb9b2f7393ce Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 11 Aug 2009 18:06:16 +0100 Subject: softpipe: reduce textual differences between exec and sse shader paths Unshare one function (setup_pos_vector) as we want to push this code into the generated shader in the SSE case. --- src/gallium/drivers/softpipe/sp_fs_exec.c | 51 ++++++++++++++++--------------- src/gallium/drivers/softpipe/sp_fs_sse.c | 50 +++++++++++++++++++++++++----- 2 files changed, 69 insertions(+), 32 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c index 91e04687c5b..c469ac63407 100644 --- a/src/gallium/drivers/softpipe/sp_fs_exec.c +++ b/src/gallium/drivers/softpipe/sp_fs_exec.c @@ -59,15 +59,34 @@ sp_exec_fragment_shader(const struct sp_fragment_shader *base) } +static void +exec_prepare( const struct sp_fragment_shader *base, + struct tgsi_exec_machine *machine, + struct tgsi_sampler **samplers ) +{ + /* + * Bind tokens/shader to the interpreter's machine state. + * Avoid redundant binding. + */ + if (machine->Tokens != base->shader.tokens) { + tgsi_exec_machine_bind_shader( machine, + base->shader.tokens, + PIPE_MAX_SAMPLERS, + samplers ); + } +} + + + /** * Compute quad X,Y,Z,W for the four fragments in a quad. * * This should really be part of the compiled shader. */ -void -sp_setup_pos_vector(const struct tgsi_interp_coef *coef, - float x, float y, - struct tgsi_exec_vector *quadpos) +static void +setup_pos_vector(const struct tgsi_interp_coef *coef, + float x, float y, + struct tgsi_exec_vector *quadpos) { uint chan; /* do X */ @@ -95,24 +114,6 @@ sp_setup_pos_vector(const struct tgsi_interp_coef *coef, } -static void -exec_prepare( const struct sp_fragment_shader *base, - struct tgsi_exec_machine *machine, - struct tgsi_sampler **samplers ) -{ - /* - * Bind tokens/shader to the interpreter's machine state. - * Avoid redundant binding. - */ - if (machine->Tokens != base->shader.tokens) { - tgsi_exec_machine_bind_shader( machine, - base->shader.tokens, - PIPE_MAX_SAMPLERS, - samplers ); - } -} - - /* TODO: hide the machine struct in here somewhere, remove from this * interface: */ @@ -122,9 +123,9 @@ exec_run( const struct sp_fragment_shader *base, struct quad_header *quad ) { /* Compute X, Y, Z, W vals for this quad */ - sp_setup_pos_vector(quad->posCoef, - (float)quad->input.x0, (float)quad->input.y0, - &machine->QuadPos); + setup_pos_vector(quad->posCoef, + (float)quad->input.x0, (float)quad->input.y0, + &machine->QuadPos); quad->inout.mask &= tgsi_exec_machine_run( machine ); if (quad->inout.mask == 0) diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index 364bb94a5f6..9d3e4670eef 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -76,6 +76,43 @@ fs_sse_prepare( const struct sp_fragment_shader *base, } + +/** + * Compute quad X,Y,Z,W for the four fragments in a quad. + * + * This should really be part of the compiled shader. + */ +static void +setup_pos_vector(const struct tgsi_interp_coef *coef, + float x, float y, + struct tgsi_exec_vector *quadpos) +{ + uint chan; + /* do X */ + quadpos->xyzw[0].f[0] = x; + quadpos->xyzw[0].f[1] = x + 1; + quadpos->xyzw[0].f[2] = x; + quadpos->xyzw[0].f[3] = x + 1; + + /* do Y */ + quadpos->xyzw[1].f[0] = y; + quadpos->xyzw[1].f[1] = y; + quadpos->xyzw[1].f[2] = y + 1; + quadpos->xyzw[1].f[3] = y + 1; + + /* do Z and W for all fragments in the quad */ + for (chan = 2; chan < 4; chan++) { + const float dadx = coef->dadx[chan]; + const float dady = coef->dady[chan]; + const float a0 = coef->a0[chan] + dadx * x + dady * y; + quadpos->xyzw[chan].f[0] = a0; + quadpos->xyzw[chan].f[1] = a0 + dadx; + quadpos->xyzw[chan].f[2] = a0 + dady; + quadpos->xyzw[chan].f[3] = a0 + dadx + dady; + } +} + + /* TODO: codegenerate the whole run function, skip this wrapper. * TODO: break dependency on tgsi_exec_machine struct * TODO: push Position calculation into the generated shader @@ -89,9 +126,9 @@ fs_sse_run( const struct sp_fragment_shader *base, struct sp_sse_fragment_shader *shader = sp_sse_fragment_shader(base); /* Compute X, Y, Z, W vals for this quad -- place in temp[0] for now */ - sp_setup_pos_vector(quad->posCoef, - (float)quad->input.x0, (float)quad->input.y0, - machine->Temps); + setup_pos_vector(quad->posCoef, + (float)quad->input.x0, (float)quad->input.y0, + machine->Temps); /* init kill mask */ tgsi_set_kill_mask(machine, 0x0); @@ -108,12 +145,11 @@ fs_sse_run( const struct sp_fragment_shader *base, if (quad->inout.mask == 0) return FALSE; - /* store outputs */ { - const ubyte *sem_name = shader->base.info.output_semantic_name; - const ubyte *sem_index = shader->base.info.output_semantic_index; - const uint n = shader->base.info.num_outputs; + const ubyte *sem_name = base->info.output_semantic_name; + const ubyte *sem_index = base->info.output_semantic_index; + const uint n = base->info.num_outputs; uint i; for (i = 0; i < n; i++) { switch (sem_name[i]) { -- cgit v1.2.3 From 99ec78d9462d2a553982d0ea15d538b36b1c123b Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 11 Aug 2009 18:23:28 +0100 Subject: Revert "softpipe: rearrange blend fastpaths" This reverts commit 1295cf423e21dad04a947960782ffa8db2739709. The original formulation was easier to understand & work with. Will revisit this later. --- src/gallium/drivers/softpipe/sp_quad_blend.c | 82 +++++++++++++++++++--------- 1 file changed, 55 insertions(+), 27 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index b8ed0867343..e243c63fa23 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -793,7 +793,10 @@ blend_single_add_src_alpha_inv_src_alpha(struct quad_stage *qs, struct quad_header *quads[], unsigned nr) { - float source[4]; + static const float one[4] = { 1, 1, 1, 1 }; + float one_minus_alpha[QUAD_SIZE]; + float dest[4][QUAD_SIZE]; + float source[4][QUAD_SIZE]; uint i, j, q; struct softpipe_cached_tile *tile @@ -803,26 +806,45 @@ blend_single_add_src_alpha_inv_src_alpha(struct quad_stage *qs, for (q = 0; q < nr; q++) { struct quad_header *quad = quads[q]; + float (*quadColor)[4] = quad->output.color[0]; + const float *alpha = quadColor[3]; const int itx = (quad->input.x0 & (TILE_SIZE-1)); const int ity = (quad->input.y0 & (TILE_SIZE-1)); - float (*swzColor)[4] = quad->output.color[0]; - for (j = 0; j < 4; j++) { - if (quad->inout.mask & (1<data.color[ity + (j>>1)][itx + (j&1)]; - const float alpha = swzColor[3][j]; - const float one_minus_alpha = 1.0 - alpha; + /* get/swizzle dest colors */ + for (j = 0; j < QUAD_SIZE; j++) { + int x = itx + (j & 1); + int y = ity + (j >> 1); + for (i = 0; i < 4; i++) { + dest[i][j] = tile->data.color[y][x][i]; + } + } - for (i = 0; i < 4; i++) { - dest[i] *= one_minus_alpha; - dest[i] += swzColor[i][j] * alpha; + VEC4_MUL(source[0], quadColor[0], alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], alpha); /* B */ + VEC4_MUL(source[3], quadColor[3], alpha); /* A */ + + VEC4_SUB(one_minus_alpha, one, alpha); + VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */ + VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */ + VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */ + VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* B */ + + VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */ + VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */ + VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */ + VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */ - /* XXX: redundant, will be clamped later for argb8 surfaces: - */ - dest[i] = CLAMP(dest[i], 0.0, 1.0); + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->inout.mask & (1 << j)) { + int x = itx + (j & 1); + int y = ity + (j >> 1); + for (i = 0; i < 4; i++) { /* loop over color chans */ + tile->data.color[y][x][i] = quadColor[i][j]; } } - } + } } } @@ -841,27 +863,33 @@ blend_single_add_one_one(struct quad_stage *qs, for (q = 0; q < nr; q++) { struct quad_header *quad = quads[q]; + float (*quadColor)[4] = quad->output.color[0]; const int itx = (quad->input.x0 & (TILE_SIZE-1)); const int ity = (quad->input.y0 & (TILE_SIZE-1)); - float (*dest)[64][4] = (float (*)[64][4])&tile->data.color[ity][itx]; - float (*swzColor)[4] = quad->output.color[0]; - float quadColor[4][4]; - + /* get/swizzle dest colors */ for (j = 0; j < QUAD_SIZE; j++) { + int x = itx + (j & 1); + int y = ity + (j >> 1); for (i = 0; i < 4; i++) { - quadColor[i][j] = swzColor[j][i]; + dest[i][j] = tile->data.color[y][x][i]; } } - if (quad->inout.mask & 1) - VEC4_ADD_SAT(dest[0][0], quadColor[0], dest[0][0]); - if (quad->inout.mask & 2) - VEC4_ADD_SAT(dest[0][1], quadColor[1], dest[0][1]); - if (quad->inout.mask & 4) - VEC4_ADD_SAT(dest[1][0], quadColor[2], dest[1][0]); - if (quad->inout.mask & 8) - VEC4_ADD_SAT(dest[1][1], quadColor[3], dest[1][1]); + VEC4_ADD_SAT(quadColor[0], quadColor[0], dest[0]); /* R */ + VEC4_ADD_SAT(quadColor[1], quadColor[1], dest[1]); /* G */ + VEC4_ADD_SAT(quadColor[2], quadColor[2], dest[2]); /* B */ + VEC4_ADD_SAT(quadColor[3], quadColor[3], dest[3]); /* A */ + + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->inout.mask & (1 << j)) { + int x = itx + (j & 1); + int y = ity + (j >> 1); + for (i = 0; i < 4; i++) { /* loop over color chans */ + tile->data.color[y][x][i] = quadColor[i][j]; + } + } + } } } -- cgit v1.2.3 From d12bae9368e0c44a9943d9b37ab848ea307d70c7 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 18 Aug 2009 16:21:12 +0100 Subject: softpipe: move flatshade-first check out of loop --- src/gallium/drivers/softpipe/sp_prim_vbuf.c | 80 ++++++++++++++++++----------- 1 file changed, 50 insertions(+), 30 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index 1dd63d99ffd..76524a8d411 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -239,14 +239,16 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) break; case PIPE_PRIM_TRIANGLES: - for (i = 2; i < nr; i += 3) { - if (softpipe->rasterizer->flatshade_first) { + if (softpipe->rasterizer->flatshade_first) { + for (i = 2; i < nr; i += 3) { setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-0], stride), get_vert(vertex_buffer, indices[i-2], stride) ); } - else { + } + else { + for (i = 2; i < nr; i += 3) { setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-2], stride), get_vert(vertex_buffer, indices[i-1], stride), @@ -256,14 +258,16 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) break; case PIPE_PRIM_TRIANGLE_STRIP: - for (i = 2; i < nr; i += 1) { - if (softpipe->rasterizer->flatshade_first) { + if (softpipe->rasterizer->flatshade_first) { + for (i = 2; i < nr; i += 1) { setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i+(i&1)-1], stride), get_vert(vertex_buffer, indices[i-(i&1)], stride), get_vert(vertex_buffer, indices[i-2], stride) ); } - else { + } + else { + for (i = 2; i < nr; i += 1) { setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i+(i&1)-2], stride), get_vert(vertex_buffer, indices[i-(i&1)-1], stride), @@ -273,14 +277,16 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) break; case PIPE_PRIM_TRIANGLE_FAN: - for (i = 2; i < nr; i += 1) { - if (softpipe->rasterizer->flatshade_first) { + if (softpipe->rasterizer->flatshade_first) { + for (i = 2; i < nr; i += 1) { setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-0], stride), get_vert(vertex_buffer, indices[0], stride), get_vert(vertex_buffer, indices[i-1], stride) ); } - else { + } + else { + for (i = 2; i < nr; i += 1) { setup_tri( setup_ctx, get_vert(vertex_buffer, indices[0], stride), get_vert(vertex_buffer, indices[i-1], stride), @@ -290,8 +296,8 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) break; case PIPE_PRIM_QUADS: - for (i = 3; i < nr; i += 4) { - if (softpipe->rasterizer->flatshade_first) { + if (softpipe->rasterizer->flatshade_first) { + for (i = 3; i < nr; i += 4) { setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-2], stride), get_vert(vertex_buffer, indices[i-1], stride), @@ -301,7 +307,9 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) get_vert(vertex_buffer, indices[i-0], stride), get_vert(vertex_buffer, indices[i-3], stride) ); } - else { + } + else { + for (i = 3; i < nr; i += 4) { setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-3], stride), get_vert(vertex_buffer, indices[i-2], stride), @@ -316,8 +324,8 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) break; case PIPE_PRIM_QUAD_STRIP: - for (i = 3; i < nr; i += 2) { - if (softpipe->rasterizer->flatshade_first) { + if (softpipe->rasterizer->flatshade_first) { + for (i = 3; i < nr; i += 2) { setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-0], stride), get_vert(vertex_buffer, indices[i-1], stride), @@ -327,7 +335,9 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) get_vert(vertex_buffer, indices[i-0], stride), get_vert(vertex_buffer, indices[i-3], stride) ); } - else { + } + else { + for (i = 3; i < nr; i += 2) { setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-3], stride), get_vert(vertex_buffer, indices[i-2], stride), @@ -423,14 +433,16 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) break; case PIPE_PRIM_TRIANGLES: - for (i = 2; i < nr; i += 3) { - if (softpipe->rasterizer->flatshade_first) { + if (softpipe->rasterizer->flatshade_first) { + for (i = 2; i < nr; i += 3) { setup_tri( setup_ctx, get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride), get_vert(vertex_buffer, i-2, stride) ); } - else { + } + else { + for (i = 2; i < nr; i += 3) { setup_tri( setup_ctx, get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i-1, stride), @@ -440,14 +452,16 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) break; case PIPE_PRIM_TRIANGLE_STRIP: - for (i = 2; i < nr; i++) { - if (softpipe->rasterizer->flatshade_first) { + if (softpipe->rasterizer->flatshade_first) { + for (i = 2; i < nr; i++) { setup_tri( setup_ctx, get_vert(vertex_buffer, i+(i&1)-1, stride), get_vert(vertex_buffer, i-(i&1), stride), get_vert(vertex_buffer, i-2, stride) ); } - else { + } + else { + for (i = 2; i < nr; i++) { setup_tri( setup_ctx, get_vert(vertex_buffer, i+(i&1)-2, stride), get_vert(vertex_buffer, i-(i&1)-1, stride), @@ -457,14 +471,16 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) break; case PIPE_PRIM_TRIANGLE_FAN: - for (i = 2; i < nr; i += 1) { - if (softpipe->rasterizer->flatshade_first) { + if (softpipe->rasterizer->flatshade_first) { + for (i = 2; i < nr; i += 1) { setup_tri( setup_ctx, get_vert(vertex_buffer, i-0, stride), get_vert(vertex_buffer, 0, stride), get_vert(vertex_buffer, i-1, stride) ); } - else { + } + else { + for (i = 2; i < nr; i += 1) { setup_tri( setup_ctx, get_vert(vertex_buffer, 0, stride), get_vert(vertex_buffer, i-1, stride), @@ -474,8 +490,8 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) break; case PIPE_PRIM_QUADS: - for (i = 3; i < nr; i += 4) { - if (softpipe->rasterizer->flatshade_first) { + if (softpipe->rasterizer->flatshade_first) { + for (i = 3; i < nr; i += 4) { setup_tri( setup_ctx, get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i-1, stride), @@ -485,7 +501,9 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) get_vert(vertex_buffer, i-0, stride), get_vert(vertex_buffer, i-3, stride) ); } - else { + } + else { + for (i = 3; i < nr; i += 4) { setup_tri( setup_ctx, get_vert(vertex_buffer, i-3, stride), get_vert(vertex_buffer, i-2, stride), @@ -499,8 +517,8 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) break; case PIPE_PRIM_QUAD_STRIP: - for (i = 3; i < nr; i += 2) { - if (softpipe->rasterizer->flatshade_first) { + if (softpipe->rasterizer->flatshade_first) { + for (i = 3; i < nr; i += 2) { setup_tri( setup_ctx, get_vert(vertex_buffer, i-0, stride), get_vert(vertex_buffer, i-1, stride), @@ -510,7 +528,9 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) get_vert(vertex_buffer, i-0, stride), get_vert(vertex_buffer, i-3, stride) ); } - else { + } + else { + for (i = 3; i < nr; i += 2) { setup_tri( setup_ctx, get_vert(vertex_buffer, i-3, stride), get_vert(vertex_buffer, i-2, stride), -- cgit v1.2.3 From 80c78472ad43f4288c9ef5076074ba9d31a39885 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 29 Jul 2009 07:40:50 +0100 Subject: softpipe: split texture and surface tile caches These do similar jobs but with largely disjoint code. Will want to evolve them separately going forward. --- src/gallium/drivers/softpipe/Makefile | 1 + src/gallium/drivers/softpipe/SConscript | 1 + src/gallium/drivers/softpipe/sp_context.c | 4 +- src/gallium/drivers/softpipe/sp_context.h | 3 +- src/gallium/drivers/softpipe/sp_flush.c | 3 +- src/gallium/drivers/softpipe/sp_state_derived.c | 2 +- src/gallium/drivers/softpipe/sp_state_sampler.c | 4 +- src/gallium/drivers/softpipe/sp_tex_sample.c | 16 +- src/gallium/drivers/softpipe/sp_tex_sample.h | 2 +- src/gallium/drivers/softpipe/sp_tex_tile_cache.c | 274 +++++++++++++++++++++++ src/gallium/drivers/softpipe/sp_tex_tile_cache.h | 161 +++++++++++++ src/gallium/drivers/softpipe/sp_tile_cache.c | 171 +------------- src/gallium/drivers/softpipe/sp_tile_cache.h | 42 +--- 13 files changed, 460 insertions(+), 224 deletions(-) create mode 100644 src/gallium/drivers/softpipe/sp_tex_tile_cache.c create mode 100644 src/gallium/drivers/softpipe/sp_tex_tile_cache.h (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile index a6ed7ea6a2a..3da9be6957e 100644 --- a/src/gallium/drivers/softpipe/Makefile +++ b/src/gallium/drivers/softpipe/Makefile @@ -30,6 +30,7 @@ C_SOURCES = \ sp_state_vertex.c \ sp_texture.c \ sp_tex_sample.c \ + sp_tex_tile_cache.c \ sp_tile_cache.c \ sp_surface.c diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript index dcc25732baf..30c099813e1 100644 --- a/src/gallium/drivers/softpipe/SConscript +++ b/src/gallium/drivers/softpipe/SConscript @@ -37,6 +37,7 @@ softpipe = env.ConvenienceLibrary( 'sp_state_vertex.c', 'sp_surface.c', 'sp_tex_sample.c', + 'sp_tex_tile_cache.c', 'sp_texture.c', 'sp_tile_cache.c', ]) diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index e35c6b3aec7..396d4c6557a 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -97,7 +97,7 @@ static void softpipe_destroy( struct pipe_context *pipe ) sp_destroy_tile_cache(softpipe->zsbuf_cache); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - sp_destroy_tile_cache(softpipe->tex_cache[i]); + sp_destroy_tex_tile_cache(softpipe->tex_cache[i]); for (i = 0; i < Elements(softpipe->constants); i++) { if (softpipe->constants[i].buffer) { @@ -220,7 +220,7 @@ softpipe_create( struct pipe_screen *screen ) softpipe->zsbuf_cache = sp_create_tile_cache( screen ); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - softpipe->tex_cache[i] = sp_create_tile_cache( screen ); + softpipe->tex_cache[i] = sp_create_tex_tile_cache( screen ); /* setup quad rendering stages */ diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index fa3306c020a..683c3aef9b6 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -43,6 +43,7 @@ struct softpipe_vbuf_render; struct draw_context; struct draw_stage; struct softpipe_tile_cache; +struct softpipe_tex_tile_cache; struct sp_fragment_shader; struct sp_vertex_shader; @@ -141,7 +142,7 @@ struct softpipe_context { struct softpipe_tile_cache *zsbuf_cache; unsigned tex_timestamp; - struct softpipe_tile_cache *tex_cache[PIPE_MAX_SAMPLERS]; + struct softpipe_tex_tile_cache *tex_cache[PIPE_MAX_SAMPLERS]; unsigned use_sse : 1; unsigned dump_fs : 1; diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index 679ad0cd3d4..e38b767cf2c 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -37,6 +37,7 @@ #include "sp_surface.h" #include "sp_state.h" #include "sp_tile_cache.h" +#include "sp_tex_tile_cache.h" #include "sp_winsys.h" @@ -52,7 +53,7 @@ softpipe_flush( struct pipe_context *pipe, if (flags & PIPE_FLUSH_TEXTURE_CACHE) { for (i = 0; i < softpipe->num_textures; i++) { - sp_flush_tile_cache(softpipe->tex_cache[i]); + sp_flush_tex_tile_cache(softpipe->tex_cache[i]); } } diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 3ed1de7e178..88a6e4fbdfa 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -212,7 +212,7 @@ update_tgsi_samplers( struct softpipe_context *softpipe ) } for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - sp_tile_cache_validate_texture( softpipe->tex_cache[i] ); + sp_tex_tile_cache_validate_texture( softpipe->tex_cache[i] ); } } diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index aa2f3f2ccd6..a725925264a 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -37,7 +37,7 @@ #include "sp_context.h" #include "sp_state.h" #include "sp_texture.h" -#include "sp_tile_cache.h" +#include "sp_tex_tile_cache.h" #include "draw/draw_context.h" @@ -97,7 +97,7 @@ softpipe_set_sampler_textures(struct pipe_context *pipe, struct pipe_texture *tex = i < num ? texture[i] : NULL; pipe_texture_reference(&softpipe->texture[i], tex); - sp_tile_cache_set_texture(softpipe->tex_cache[i], tex); + sp_tex_tile_cache_set_texture(softpipe->tex_cache[i], tex); } softpipe->num_textures = num; diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 4651d781a95..8bed573e8c1 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -38,7 +38,7 @@ #include "sp_surface.h" #include "sp_texture.h" #include "sp_tex_sample.h" -#include "sp_tile_cache.h" +#include "sp_tex_tile_cache.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "util/u_math.h" @@ -659,7 +659,7 @@ choose_mipmap_levels(const struct pipe_texture *texture, * \param rgba the quad to put the texel/color into * \param j which element of the rgba quad to write to * - * XXX maybe move this into sp_tile_cache.c and merge with the + * XXX maybe move this into sp_tex_tile_cache.c and merge with the * sp_get_cached_tile_tex() function. Also, get 4 texels instead of 1... */ static void @@ -669,9 +669,9 @@ get_texel_quad_2d(const struct tgsi_sampler *tgsi_sampler, { const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); - const struct softpipe_cached_tile *tile + const struct softpipe_tex_cached_tile *tile = sp_get_cached_tile_tex(samp->cache, - tile_address(x, y, 0, face, level)); + tex_tile_address(x, y, 0, face, level)); y %= TILE_SIZE; x %= TILE_SIZE; @@ -688,9 +688,9 @@ get_texel_2d_ptr(const struct tgsi_sampler *tgsi_sampler, { const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); - const struct softpipe_cached_tile *tile + const struct softpipe_tex_cached_tile *tile = sp_get_cached_tile_tex(samp->cache, - tile_address(x, y, 0, face, level)); + tex_tile_address(x, y, 0, face, level)); y %= TILE_SIZE; x %= TILE_SIZE; @@ -736,10 +736,10 @@ get_texel(const struct tgsi_sampler *tgsi_sampler, else { const unsigned tx = x % TILE_SIZE; const unsigned ty = y % TILE_SIZE; - const struct softpipe_cached_tile *tile; + const struct softpipe_tex_cached_tile *tile; tile = sp_get_cached_tile_tex(samp->cache, - tile_address(x, y, z, face, level)); + tex_tile_address(x, y, z, face, level)); rgba[0][j] = tile->data.color[ty][tx][0]; rgba[1][j] = tile->data.color[ty][tx][1]; diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h index 0650c7830b9..1756d3a4ee3 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.h +++ b/src/gallium/drivers/softpipe/sp_tex_sample.h @@ -48,7 +48,7 @@ struct sp_shader_sampler const struct pipe_texture *texture; const struct pipe_sampler_state *sampler; - struct softpipe_tile_cache *cache; + struct softpipe_tex_tile_cache *cache; }; diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c new file mode 100644 index 00000000000..c2dd68c7a2a --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c @@ -0,0 +1,274 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Texture tile caching. + * + * Author: + * Brian Paul + */ + +#include "pipe/p_inlines.h" +#include "util/u_memory.h" +#include "util/u_tile.h" +#include "sp_context.h" +#include "sp_surface.h" +#include "sp_texture.h" +#include "sp_tex_tile_cache.h" + + + +struct softpipe_tex_tile_cache * +sp_create_tex_tile_cache( struct pipe_screen *screen ) +{ + struct softpipe_tex_tile_cache *tc; + uint pos; + + tc = CALLOC_STRUCT( softpipe_tex_tile_cache ); + if (tc) { + tc->screen = screen; + for (pos = 0; pos < NUM_ENTRIES; pos++) { + tc->entries[pos].addr.bits.invalid = 1; + } + tc->last_tile = &tc->entries[0]; /* any tile */ + } + return tc; +} + + +void +sp_destroy_tex_tile_cache(struct softpipe_tex_tile_cache *tc) +{ + struct pipe_screen *screen; + uint pos; + + for (pos = 0; pos < NUM_ENTRIES; pos++) { + /*assert(tc->entries[pos].x < 0);*/ + } + if (tc->transfer) { + screen = tc->transfer->texture->screen; + screen->tex_transfer_destroy(tc->transfer); + } + if (tc->tex_trans) { + screen = tc->tex_trans->texture->screen; + screen->tex_transfer_destroy(tc->tex_trans); + } + + FREE( tc ); +} + + + + +void +sp_tex_tile_cache_map_transfers(struct softpipe_tex_tile_cache *tc) +{ + if (tc->tex_trans && !tc->tex_trans_map) + tc->tex_trans_map = tc->screen->transfer_map(tc->screen, tc->tex_trans); +} + + +void +sp_tex_tile_cache_unmap_transfers(struct softpipe_tex_tile_cache *tc) +{ + if (tc->tex_trans_map) { + tc->screen->transfer_unmap(tc->screen, tc->tex_trans); + tc->tex_trans_map = NULL; + } +} + +void +sp_tex_tile_cache_validate_texture(struct softpipe_tex_tile_cache *tc) +{ + if (tc->texture) { + struct softpipe_texture *spt = softpipe_texture(tc->texture); + if (spt->timestamp != tc->timestamp) { + /* texture was modified, invalidate all cached tiles */ + uint i; + _debug_printf("INV %d %d\n", tc->timestamp, spt->timestamp); + for (i = 0; i < NUM_ENTRIES; i++) { + tc->entries[i].addr.bits.invalid = 1; + } + + tc->timestamp = spt->timestamp; + } + } +} + +/** + * Specify the texture to cache. + */ +void +sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc, + struct pipe_texture *texture) +{ + uint i; + + assert(!tc->transfer); + + if (tc->texture != texture) { + pipe_texture_reference(&tc->texture, texture); + + if (tc->tex_trans) { + struct pipe_screen *screen = tc->tex_trans->texture->screen; + + if (tc->tex_trans_map) { + screen->transfer_unmap(screen, tc->tex_trans); + tc->tex_trans_map = NULL; + } + + screen->tex_transfer_destroy(tc->tex_trans); + tc->tex_trans = NULL; + } + + /* mark as entries as invalid/empty */ + /* XXX we should try to avoid this when the teximage hasn't changed */ + for (i = 0; i < NUM_ENTRIES; i++) { + tc->entries[i].addr.bits.invalid = 1; + } + + tc->tex_face = -1; /* any invalid value here */ + } +} + + + + +/** + * Flush the tile cache: write all dirty tiles back to the transfer. + * any tiles "flagged" as cleared will be "really" cleared. + */ +void +sp_flush_tex_tile_cache(struct softpipe_tex_tile_cache *tc) +{ + int pos; + + if (tc->texture) { + /* caching a texture, mark all entries as empty */ + for (pos = 0; pos < NUM_ENTRIES; pos++) { + tc->entries[pos].addr.bits.invalid = 1; + } + tc->tex_face = -1; + } + +} + + +/** + * Given the texture face, level, zslice, x and y values, compute + * the cache entry position/index where we'd hope to find the + * cached texture tile. + * This is basically a direct-map cache. + * XXX There's probably lots of ways in which we can improve this. + */ +static INLINE uint +tex_cache_pos( union tex_tile_address addr ) +{ + uint entry = (addr.bits.x + + addr.bits.y * 9 + + addr.bits.z * 3 + + addr.bits.face + + addr.bits.level * 7); + + return entry % NUM_ENTRIES; +} + +/** + * Similar to sp_get_cached_tile() but for textures. + * Tiles are read-only and indexed with more params. + */ +const struct softpipe_tex_cached_tile * +sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc, + union tex_tile_address addr ) +{ + struct pipe_screen *screen = tc->screen; + struct softpipe_tex_cached_tile *tile; + + tile = tc->entries + tex_cache_pos( addr ); + + if (addr.value != tile->addr.value) { + + /* cache miss. Most misses are because we've invaldiated the + * texture cache previously -- most commonly on binding a new + * texture. Currently we effectively flush the cache on texture + * bind. + */ +#if 0 + _debug_printf("miss at %u: x=%d y=%d z=%d face=%d level=%d\n" + " tile %u: x=%d y=%d z=%d face=%d level=%d\n", + pos, x/TILE_SIZE, y/TILE_SIZE, z, face, level, + pos, tile->addr.bits.x, tile->addr.bits.y, tile->z, tile->face, tile->level); +#endif + + /* check if we need to get a new transfer */ + if (!tc->tex_trans || + tc->tex_face != addr.bits.face || + tc->tex_level != addr.bits.level || + tc->tex_z != addr.bits.z) { + /* get new transfer (view into texture) */ + + if (tc->tex_trans) { + if (tc->tex_trans_map) { + tc->screen->transfer_unmap(tc->screen, tc->tex_trans); + tc->tex_trans_map = NULL; + } + + screen->tex_transfer_destroy(tc->tex_trans); + tc->tex_trans = NULL; + } + + tc->tex_trans = + screen->get_tex_transfer(screen, tc->texture, + addr.bits.face, + addr.bits.level, + addr.bits.z, + PIPE_TRANSFER_READ, 0, 0, + tc->texture->width[addr.bits.level], + tc->texture->height[addr.bits.level]); + + tc->tex_trans_map = screen->transfer_map(screen, tc->tex_trans); + + tc->tex_face = addr.bits.face; + tc->tex_level = addr.bits.level; + tc->tex_z = addr.bits.z; + } + + /* get tile from the transfer (view into texture) */ + pipe_get_tile_rgba(tc->tex_trans, + addr.bits.x * TILE_SIZE, + addr.bits.y * TILE_SIZE, + TILE_SIZE, TILE_SIZE, + (float *) tile->data.color); + tile->addr = addr; + } + + tc->last_tile = tile; + return tile; +} + + + diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h new file mode 100644 index 00000000000..c6003f35508 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h @@ -0,0 +1,161 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef SP_TEX_TILE_CACHE_H +#define SP_TEX_TILE_CACHE_H + + +#include "pipe/p_compiler.h" + + +struct softpipe_context; +struct softpipe_tex_tile_cache; + + +/** + * Cache tile size (width and height). This needs to be a power of two. + */ +#define TILE_SIZE 64 + + +/* If we need to support > 4096, just expand this to be a 64 bit + * union, or consider tiling in Z as well. + */ +union tex_tile_address { + struct { + unsigned x:6; /* 4096 / TILE_SIZE */ + unsigned y:6; /* 4096 / TILE_SIZE */ + unsigned z:12; /* 4096 -- z not tiled */ + unsigned face:3; + unsigned level:4; + unsigned invalid:1; + } bits; + unsigned value; +}; + + +struct softpipe_tex_cached_tile +{ + union tex_tile_address addr; + union { + float color[TILE_SIZE][TILE_SIZE][4]; + } data; +}; + +#define NUM_ENTRIES 50 + + +/** XXX move these */ +#define MAX_WIDTH 2048 +#define MAX_HEIGHT 2048 + + +struct softpipe_tex_tile_cache +{ + struct pipe_screen *screen; + struct pipe_transfer *transfer; + void *transfer_map; + + struct pipe_texture *texture; /**< if caching a texture */ + unsigned timestamp; + + struct softpipe_tex_cached_tile entries[NUM_ENTRIES]; + + struct pipe_transfer *tex_trans; + void *tex_trans_map; + int tex_face, tex_level, tex_z; + + struct softpipe_tex_cached_tile *last_tile; /**< most recently retrieved tile */ +}; + + +extern struct softpipe_tex_tile_cache * +sp_create_tex_tile_cache( struct pipe_screen *screen ); + +extern void +sp_destroy_tex_tile_cache(struct softpipe_tex_tile_cache *tc); + + +extern void +sp_tex_tile_cache_map_transfers(struct softpipe_tex_tile_cache *tc); + +extern void +sp_tex_tile_cache_unmap_transfers(struct softpipe_tex_tile_cache *tc); + +extern void +sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc, + struct pipe_texture *texture); + +void +sp_tex_tile_cache_validate_texture(struct softpipe_tex_tile_cache *tc); + +extern void +sp_flush_tex_tile_cache(struct softpipe_tex_tile_cache *tc); + + + +extern const struct softpipe_tex_cached_tile * +sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc, + union tex_tile_address addr ); + +static INLINE const union tex_tile_address +tex_tile_address( unsigned x, + unsigned y, + unsigned z, + unsigned face, + unsigned level ) +{ + union tex_tile_address addr; + + addr.value = 0; + addr.bits.x = x / TILE_SIZE; + addr.bits.y = y / TILE_SIZE; + addr.bits.z = z; + addr.bits.face = face; + addr.bits.level = level; + + return addr; +} + +/* Quickly retrieve tile if it matches last lookup. + */ +static INLINE const struct softpipe_tex_cached_tile * +sp_get_cached_tile_tex(struct softpipe_tex_tile_cache *tc, + union tex_tile_address addr ) +{ + if (tc->last_tile->addr.value == addr.value) + return tc->last_tile; + + return sp_find_cached_tile_tex( tc, addr ); +} + + + + + +#endif /* SP_TEX_TILE_CACHE_H */ + diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 77d02fa3e7a..2d82badcec3 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -26,7 +26,7 @@ **************************************************************************/ /** - * Texture tile caching. + * Render target tile caching. * * Author: * Brian Paul @@ -37,7 +37,6 @@ #include "util/u_tile.h" #include "sp_context.h" #include "sp_surface.h" -#include "sp_texture.h" #include "sp_tile_cache.h" @@ -111,10 +110,6 @@ sp_destroy_tile_cache(struct softpipe_tile_cache *tc) screen = tc->transfer->texture->screen; screen->tex_transfer_destroy(tc->transfer); } - if (tc->tex_trans) { - screen = tc->tex_trans->texture->screen; - screen->tex_transfer_destroy(tc->tex_trans); - } FREE( tc ); } @@ -127,8 +122,6 @@ void sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, struct pipe_surface *ps) { - assert(!tc->texture); - if (tc->transfer) { struct pipe_screen *screen = tc->transfer->texture->screen; @@ -180,9 +173,6 @@ sp_tile_cache_map_transfers(struct softpipe_tile_cache *tc) { if (tc->transfer && !tc->transfer_map) tc->transfer_map = tc->screen->transfer_map(tc->screen, tc->transfer); - - if (tc->tex_trans && !tc->tex_trans_map) - tc->tex_trans_map = tc->screen->transfer_map(tc->screen, tc->tex_trans); } @@ -193,68 +183,8 @@ sp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc) tc->screen->transfer_unmap(tc->screen, tc->transfer); tc->transfer_map = NULL; } - - if (tc->tex_trans_map) { - tc->screen->transfer_unmap(tc->screen, tc->tex_trans); - tc->tex_trans_map = NULL; - } -} - -void -sp_tile_cache_validate_texture(struct softpipe_tile_cache *tc) -{ - if (tc->texture) { - struct softpipe_texture *spt = softpipe_texture(tc->texture); - if (spt->timestamp != tc->timestamp) { - /* texture was modified, invalidate all cached tiles */ - uint i; - _debug_printf("INV %d %d\n", tc->timestamp, spt->timestamp); - for (i = 0; i < NUM_ENTRIES; i++) { - tc->entries[i].addr.bits.invalid = 1; - } - - tc->timestamp = spt->timestamp; - } - } -} - -/** - * Specify the texture to cache. - */ -void -sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, - struct pipe_texture *texture) -{ - uint i; - - assert(!tc->transfer); - - if (tc->texture != texture) { - pipe_texture_reference(&tc->texture, texture); - - if (tc->tex_trans) { - struct pipe_screen *screen = tc->tex_trans->texture->screen; - - if (tc->tex_trans_map) { - screen->transfer_unmap(screen, tc->tex_trans); - tc->tex_trans_map = NULL; - } - - screen->tex_transfer_destroy(tc->tex_trans); - tc->tex_trans = NULL; - } - - /* mark as entries as invalid/empty */ - /* XXX we should try to avoid this when the teximage hasn't changed */ - for (i = 0; i < NUM_ENTRIES; i++) { - tc->entries[i].addr.bits.invalid = 1; - } - - tc->tex_face = -1; /* any invalid value here */ - } } - /** * Set pixels in a tile to the given clear color/value, float. */ @@ -345,7 +275,7 @@ sp_tile_cache_flush_clear(struct softpipe_tile_cache *tc) /* push the tile to all positions marked as clear */ for (y = 0; y < h; y += TILE_SIZE) { for (x = 0; x < w; x += TILE_SIZE) { - union tile_address addr = tile_address(x, y, 0, 0, 0); + union tile_address addr = tile_address(x, y); if (is_clear_flag_set(tc->clear_flags, addr)) { pipe_put_tile_raw(pt, @@ -403,13 +333,6 @@ sp_flush_tile_cache(struct softpipe_tile_cache *tc) sp_tile_cache_flush_clear(tc); #endif } - else if (tc->texture) { - /* caching a texture, mark all entries as empty */ - for (pos = 0; pos < NUM_ENTRIES; pos++) { - tc->entries[pos].addr.bits.invalid = 1; - } - tc->tex_face = -1; - } #if 0 debug_printf("flushed tiles in use: %d\n", inuse); @@ -488,97 +411,7 @@ sp_find_cached_tile(struct softpipe_tile_cache *tc, } -/** - * Given the texture face, level, zslice, x and y values, compute - * the cache entry position/index where we'd hope to find the - * cached texture tile. - * This is basically a direct-map cache. - * XXX There's probably lots of ways in which we can improve this. - */ -static INLINE uint -tex_cache_pos( union tile_address addr ) -{ - uint entry = (addr.bits.x + - addr.bits.y * 9 + - addr.bits.z * 3 + - addr.bits.face + - addr.bits.level * 7); - - return entry % NUM_ENTRIES; -} - -/** - * Similar to sp_get_cached_tile() but for textures. - * Tiles are read-only and indexed with more params. - */ -const struct softpipe_cached_tile * -sp_find_cached_tile_tex(struct softpipe_tile_cache *tc, - union tile_address addr ) -{ - struct pipe_screen *screen = tc->screen; - struct softpipe_cached_tile *tile; - - tile = tc->entries + tex_cache_pos( addr ); - - if (addr.value != tile->addr.value) { - - /* cache miss. Most misses are because we've invaldiated the - * texture cache previously -- most commonly on binding a new - * texture. Currently we effectively flush the cache on texture - * bind. - */ -#if 0 - _debug_printf("miss at %u: x=%d y=%d z=%d face=%d level=%d\n" - " tile %u: x=%d y=%d z=%d face=%d level=%d\n", - pos, x/TILE_SIZE, y/TILE_SIZE, z, face, level, - pos, tile->addr.bits.x, tile->addr.bits.y, tile->z, tile->face, tile->level); -#endif - - /* check if we need to get a new transfer */ - if (!tc->tex_trans || - tc->tex_face != addr.bits.face || - tc->tex_level != addr.bits.level || - tc->tex_z != addr.bits.z) { - /* get new transfer (view into texture) */ - - if (tc->tex_trans) { - if (tc->tex_trans_map) { - tc->screen->transfer_unmap(tc->screen, tc->tex_trans); - tc->tex_trans_map = NULL; - } - - screen->tex_transfer_destroy(tc->tex_trans); - tc->tex_trans = NULL; - } - - tc->tex_trans = - screen->get_tex_transfer(screen, tc->texture, - addr.bits.face, - addr.bits.level, - addr.bits.z, - PIPE_TRANSFER_READ, 0, 0, - tc->texture->width[addr.bits.level], - tc->texture->height[addr.bits.level]); - - tc->tex_trans_map = screen->transfer_map(screen, tc->tex_trans); - tc->tex_face = addr.bits.face; - tc->tex_level = addr.bits.level; - tc->tex_z = addr.bits.z; - } - - /* get tile from the transfer (view into texture) */ - pipe_get_tile_rgba(tc->tex_trans, - addr.bits.x * TILE_SIZE, - addr.bits.y * TILE_SIZE, - TILE_SIZE, TILE_SIZE, - (float *) tile->data.color); - tile->addr = addr; - } - - tc->last_tile = tile; - return tile; -} /** diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h index ac2aae58758..3b0be274d5e 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tile_cache.h @@ -51,10 +51,8 @@ union tile_address { struct { unsigned x:6; /* 4096 / TILE_SIZE */ unsigned y:6; /* 4096 / TILE_SIZE */ - unsigned z:12; /* 4096 -- z not tiled */ - unsigned face:3; - unsigned level:4; unsigned invalid:1; + unsigned pad:19; } bits; unsigned value; }; @@ -88,19 +86,12 @@ struct softpipe_tile_cache struct pipe_transfer *transfer; void *transfer_map; - struct pipe_texture *texture; /**< if caching a texture */ - unsigned timestamp; - struct softpipe_cached_tile entries[NUM_ENTRIES]; uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32]; float clear_color[4]; /**< for color bufs */ uint clear_val; /**< for z+stencil, or packed color clear value */ boolean depth_stencil; /**< Is the surface a depth/stencil format? */ - struct pipe_transfer *tex_trans; - void *tex_trans_map; - int tex_face, tex_level, tex_z; - struct softpipe_cached_tile tile; /**< scratch tile for clears */ struct softpipe_cached_tile *last_tile; /**< most recently retrieved tile */ @@ -126,13 +117,6 @@ sp_tile_cache_map_transfers(struct softpipe_tile_cache *tc); extern void sp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc); -extern void -sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, - struct pipe_texture *texture); - -void -sp_tile_cache_validate_texture(struct softpipe_tile_cache *tc); - extern void sp_flush_tile_cache(struct softpipe_tile_cache *tc); @@ -144,47 +128,27 @@ extern struct softpipe_cached_tile * sp_find_cached_tile(struct softpipe_tile_cache *tc, union tile_address addr ); -extern const struct softpipe_cached_tile * -sp_find_cached_tile_tex(struct softpipe_tile_cache *tc, - union tile_address addr ); static INLINE const union tile_address tile_address( unsigned x, - unsigned y, - unsigned z, - unsigned face, - unsigned level ) + unsigned y ) { union tile_address addr; addr.value = 0; addr.bits.x = x / TILE_SIZE; addr.bits.y = y / TILE_SIZE; - addr.bits.z = z; - addr.bits.face = face; - addr.bits.level = level; return addr; } /* Quickly retrieve tile if it matches last lookup. */ -static INLINE const struct softpipe_cached_tile * -sp_get_cached_tile_tex(struct softpipe_tile_cache *tc, - union tile_address addr ) -{ - if (tc->last_tile->addr.value == addr.value) - return tc->last_tile; - - return sp_find_cached_tile_tex( tc, addr ); -} - - static INLINE struct softpipe_cached_tile * sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y ) { - union tile_address addr = tile_address( x, y, 0, 0, 0 ); + union tile_address addr = tile_address( x, y ); if (tc->last_tile->addr.value == addr.value) return tc->last_tile; -- cgit v1.2.3 From c84abe36a93312cfa061ce1bd005e43eb9f6a6df Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 29 Jul 2009 23:06:22 +0100 Subject: softpipe: fix typo in clear_tile --- src/gallium/drivers/softpipe/sp_tile_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 2d82badcec3..c520aef44fa 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -225,7 +225,7 @@ clear_tile(struct softpipe_cached_tile *tile, switch (pf_get_size(format)) { case 1: - memset(tile->data.any, 0, TILE_SIZE * TILE_SIZE); + memset(tile->data.any, clear_value, TILE_SIZE * TILE_SIZE); break; case 2: if (clear_value == 0) { -- cgit v1.2.3 From 4f409da3456070946eda2d8ff5153b3b4306bb46 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 20 Aug 2009 11:25:20 +0100 Subject: softpipe: optimized path for simple mipmap sampling linear-mip-linear-repeat-POT sampling faspath, provides a very nice speedup to apps that do this common type of texturing. Test case: demos/terrain, turn fog off, turn texturing on. Without patch: 12 fps With patch: 20 fps. --- src/gallium/drivers/softpipe/sp_tex_sample.c | 95 +++++++++++++++++++++------- 1 file changed, 71 insertions(+), 24 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 4651d781a95..b32ac9dabb3 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -921,8 +921,8 @@ sp_get_samples_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, } else { - unsigned x1 = (uflr + 1) & (xpot - 1); - unsigned y1 = (vflr + 1) & (ypot - 1); + unsigned x1 = (x0 + 1) & (xpot - 1); + unsigned y1 = (y0 + 1) & (ypot - 1); get_texel_quad_2d_mt(tgsi_sampler, 0, level, x0, y0, x1, y1, tx); } @@ -1028,42 +1028,92 @@ sp_get_samples_2d_linear_mip_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); const struct pipe_texture *texture = samp->texture; const struct pipe_sampler_state *sampler = samp->sampler; - int level0, level1; + int level0; float lambda; lambda = compute_lambda(texture, sampler, s, t, p, lodbias); level0 = (int)lambda; - level1 = level0 + 1; if (lambda < 0.0) { samp->level = 0; sp_get_samples_2d_linear_repeat_POT( tgsi_sampler, - s, t, p, lodbias, rgba ); + s, t, p, 0, rgba ); } else if (level0 >= texture->last_level) { samp->level = texture->last_level; sp_get_samples_2d_linear_repeat_POT( tgsi_sampler, - s, t, p, lodbias, rgba ); + s, t, p, 0, rgba ); } else { - float rgba0[4][4]; - float rgba1[4][4]; - int c,j; - float levelBlend = lambda - level0; /* blending weight between levels */ + unsigned xpot = 1 << (samp->xpot - level0); + unsigned ypot = 1 << (samp->ypot - level0); + unsigned xpot1 = 1 << (samp->xpot - (level0+1)); + unsigned ypot1 = 1 << (samp->ypot - (level0+1)); + unsigned j; - samp->level = level0; - sp_get_samples_2d_linear_repeat_POT( tgsi_sampler, - s, t, p, lodbias, rgba0 ); + for (j = 0; j < QUAD_SIZE; j++) { + int c; + + float u = s[j] * xpot - 0.5F; + float v = t[j] * ypot - 0.5F; - samp->level++; - sp_get_samples_2d_linear_repeat_POT( tgsi_sampler, - s, t, p, lodbias, rgba1 ); + int uflr = util_ifloor(u); + int vflr = util_ifloor(v); + + float xw = u - (float)uflr; + float yw = v - (float)vflr; + + int x0 = uflr & (xpot - 1); + int y0 = vflr & (ypot - 1); + + const float *tx0[4]; + const float *tx1[4]; + + if (x0 % TILE_SIZE != TILE_SIZE-1 && + y0 % TILE_SIZE != TILE_SIZE-1) + { + get_texel_quad_2d(tgsi_sampler, 0, level0, x0, y0, tx0); + } + else + { + unsigned x1 = (x0 + 1) & (xpot - 1); + unsigned y1 = (y0 + 1) & (ypot - 1); + get_texel_quad_2d_mt(tgsi_sampler, 0, level0, + x0, y0, x1, y1, tx0); + } - for (c = 0; c < 4; c++) - for (j = 0; j < 4; j++) - rgba[c][j] = lerp(levelBlend, rgba0[c][j], rgba1[c][j]); - } + x0 /= 2; + y0 /= 2; + /* also need to adjust xw, yw?? */ + + if (x0 % TILE_SIZE != TILE_SIZE-1 && + y0 % TILE_SIZE != TILE_SIZE-1) + { + get_texel_quad_2d(tgsi_sampler, 0, level0+1, x0, y0, tx1); + } + else + { + unsigned x1 = (x0 + 1) & (xpot1 - 1); + unsigned y1 = (y0 + 1) & (ypot1 - 1); + get_texel_quad_2d_mt(tgsi_sampler, 0, level0+1, + x0, y0, x1, y1, tx1); + } + + /* interpolate R, G, B, A */ + for (c = 0; c < 4; c++) { + float rgba0 = lerp_2d(xw, yw, + tx0[0][c], tx0[1][c], + tx0[2][c], tx0[3][c]); + + float rgba1 = lerp_2d(xw, yw, + tx1[0][c], tx1[1][c], + tx1[2][c], tx1[3][c]); + + rgba[c][j] = lerp(levelBlend, rgba0, rgba1); + } + } + } } /** @@ -1567,10 +1617,7 @@ sp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler, if (sampler->wrap_s == PIPE_TEX_WRAP_REPEAT) { switch (sampler->min_img_filter) { case PIPE_TEX_FILTER_LINEAR: - /* This one not working yet: - */ - if (0) - tgsi_sampler->get_samples = sp_get_samples_2d_linear_mip_linear_repeat_POT; + tgsi_sampler->get_samples = sp_get_samples_2d_linear_mip_linear_repeat_POT; break; default: break; -- cgit v1.2.3 From 79a7ddb57a04cde5a4a0c27eb4a9b6889d12622a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 20 Aug 2009 15:46:51 +0100 Subject: softpipe: fix glitch in texel lookups on fastpaths Fixes two issues - firstly for mipmap levels with one or more dimensions smaller than tilesize, the code was sampling off the edge of the texture (but still within the tile). Secondly, in the linear_mipmap_linear case, both the default code and new fastpath were incorrect. This change fixes the fastpath and adds a comment to the default path, which still needs to be fixed. Basically the issue is that the coordinates in the smaller texture level are/were being computed by just dividing thecoordinates from the larger texture level by two, as in: x0[j] /= 2; y0[j] /= 2; x1[j] /= 2; y1[j] /= 2; The issues with this are signficant. Initially x1 is most often equal to x0+1, but after this, it will likely be equal to x0, so we will not actually be performing the linear blend within the smaller mipmap. The fastpath code avoided this (recalculated x1), but was still using the weighting factors from the larger mipmap level (xw, yw), which were incorrect. Change the fastpath code to do two full, independent linear samples of the two mipmap levels before blending. The default code needs to do the same thing. --- src/gallium/drivers/softpipe/sp_tex_sample.c | 87 ++++++++-------------------- 1 file changed, 23 insertions(+), 64 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index b32ac9dabb3..24f33117723 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -894,6 +894,9 @@ sp_get_samples_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, unsigned xpot = 1 << (samp->xpot - level); unsigned ypot = 1 << (samp->ypot - level); + unsigned xmax = MIN2(TILE_SIZE, xpot) - 1; + unsigned ymax = MIN2(TILE_SIZE, ypot) - 1; + for (j = 0; j < QUAD_SIZE; j++) { int c; @@ -914,8 +917,7 @@ sp_get_samples_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, /* Can we fetch all four at once: */ - if (x0 % TILE_SIZE != TILE_SIZE-1 && - y0 % TILE_SIZE != TILE_SIZE-1) + if (x0 < xmax && y0 < ymax) { get_texel_quad_2d(tgsi_sampler, 0, level, x0, y0, tx); } @@ -1045,72 +1047,22 @@ sp_get_samples_2d_linear_mip_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler s, t, p, 0, rgba ); } else { - float levelBlend = lambda - level0; /* blending weight between levels */ - unsigned xpot = 1 << (samp->xpot - level0); - unsigned ypot = 1 << (samp->ypot - level0); - unsigned xpot1 = 1 << (samp->xpot - (level0+1)); - unsigned ypot1 = 1 << (samp->ypot - (level0+1)); - unsigned j; - - for (j = 0; j < QUAD_SIZE; j++) { - int c; - - float u = s[j] * xpot - 0.5F; - float v = t[j] * ypot - 0.5F; - - int uflr = util_ifloor(u); - int vflr = util_ifloor(v); - - float xw = u - (float)uflr; - float yw = v - (float)vflr; - - int x0 = uflr & (xpot - 1); - int y0 = vflr & (ypot - 1); - - const float *tx0[4]; - const float *tx1[4]; - - if (x0 % TILE_SIZE != TILE_SIZE-1 && - y0 % TILE_SIZE != TILE_SIZE-1) - { - get_texel_quad_2d(tgsi_sampler, 0, level0, x0, y0, tx0); - } - else - { - unsigned x1 = (x0 + 1) & (xpot - 1); - unsigned y1 = (y0 + 1) & (ypot - 1); - get_texel_quad_2d_mt(tgsi_sampler, 0, level0, - x0, y0, x1, y1, tx0); - } + float levelBlend = lambda - level0; + float rgba0[4][4]; + float rgba1[4][4]; + int c,j; - x0 /= 2; - y0 /= 2; - /* also need to adjust xw, yw?? */ + samp->level = level0; + sp_get_samples_2d_linear_repeat_POT( tgsi_sampler, + s, t, p, 0, rgba0 ); - if (x0 % TILE_SIZE != TILE_SIZE-1 && - y0 % TILE_SIZE != TILE_SIZE-1) - { - get_texel_quad_2d(tgsi_sampler, 0, level0+1, x0, y0, tx1); - } - else - { - unsigned x1 = (x0 + 1) & (xpot1 - 1); - unsigned y1 = (y0 + 1) & (ypot1 - 1); - get_texel_quad_2d_mt(tgsi_sampler, 0, level0+1, - x0, y0, x1, y1, tx1); - } + samp->level = level0+1; + sp_get_samples_2d_linear_repeat_POT( tgsi_sampler, + s, t, p, 0, rgba1 ); - /* interpolate R, G, B, A */ + for (j = 0; j < QUAD_SIZE; j++) { for (c = 0; c < 4; c++) { - float rgba0 = lerp_2d(xw, yw, - tx0[0][c], tx0[1][c], - tx0[2][c], tx0[3][c]); - - float rgba1 = lerp_2d(xw, yw, - tx1[0][c], tx1[1][c], - tx1[2][c], tx1[3][c]); - - rgba[c][j] = lerp(levelBlend, rgba0, rgba1); + rgba[c][j] = lerp(levelBlend, rgba0[c][j], rgba1[c][j]); } } } @@ -1209,6 +1161,13 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler, if (level0 != level1) { /* get texels from second mipmap level and blend */ float rgba2[4][4]; + + /* XXX: This is incorrect -- will often end up with (x0 + * == x1 && y0 == y1), meaning that we fetch the same + * texel four times and linearly interpolate between + * identical values. The correct approach would be to + * call linear_texcoord again for the second level. + */ x0[j] /= 2; y0[j] /= 2; x1[j] /= 2; -- cgit v1.2.3 From 1fd40e506c2207664f0c3f435e4614472ea4c540 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 20 Aug 2009 18:12:44 +0100 Subject: softpipe: slightly optimized tiling calculation --- src/gallium/drivers/softpipe/sp_tex_sample.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 24f33117723..90371d63530 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -893,9 +893,8 @@ sp_get_samples_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, unsigned level = samp->level; unsigned xpot = 1 << (samp->xpot - level); unsigned ypot = 1 << (samp->ypot - level); - - unsigned xmax = MIN2(TILE_SIZE, xpot) - 1; - unsigned ymax = MIN2(TILE_SIZE, ypot) - 1; + unsigned xmax = (xpot - 1) & (TILE_SIZE - 1); /* MIN2(TILE_SIZE, xpot) - 1; */ + unsigned ymax = (ypot - 1) & (TILE_SIZE - 1); /* MIN2(TILE_SIZE, ypot) - 1; */ for (j = 0; j < QUAD_SIZE; j++) { int c; -- cgit v1.2.3 From 0d9979d9ec5b931856d29c4ec44edb1f4931d1ac Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 20 Aug 2009 18:13:25 +0100 Subject: softpipe: fix xpot calculation typo in sp_get_samples_2d_nearest_clamp_POT --- src/gallium/drivers/softpipe/sp_tex_sample.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 90371d63530..2987548fb34 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -985,8 +985,8 @@ sp_get_samples_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler, const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); unsigned j; unsigned level = samp->level; - unsigned xpot = (1<xpot); - unsigned ypot = (1<ypot); + unsigned xpot = 1 << (samp->xpot - level); + unsigned ypot = 1 << (samp->ypot - level); for (j = 0; j < QUAD_SIZE; j++) { int c; -- cgit v1.2.3 From 00c835918259f8d41c3f74eca679a972713b11b2 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 20 Aug 2009 18:36:57 +0100 Subject: softpipe: allow the existing sampler routines to be hooked up directly Let eg. sp_get_samples_rect be hooked directly in as the tgsi sampler routine. Add a field to determine whether this is a vertex or fragment sampling call, and massage parameters to match the tgsi call. --- src/gallium/drivers/softpipe/sp_context.c | 6 +- src/gallium/drivers/softpipe/sp_state_derived.c | 3 +- src/gallium/drivers/softpipe/sp_tex_sample.c | 193 ++++++++++-------------- src/gallium/drivers/softpipe/sp_tex_sample.h | 21 +-- 4 files changed, 94 insertions(+), 129 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index e35c6b3aec7..a0196955c87 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -230,14 +230,16 @@ softpipe_create( struct pipe_screen *screen ) /* vertex shader samplers */ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - softpipe->tgsi.vert_samplers[i].base.get_samples = sp_get_samples_vertex; + softpipe->tgsi.vert_samplers[i].base.get_samples = sp_get_samples; + softpipe->tgsi.vert_samplers[i].processor = TGSI_PROCESSOR_VERTEX; softpipe->tgsi.vert_samplers[i].cache = softpipe->tex_cache[i]; softpipe->tgsi.vert_samplers_list[i] = &softpipe->tgsi.vert_samplers[i]; } /* fragment shader samplers */ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples_fragment; + softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples; + softpipe->tgsi.frag_samplers[i].processor = TGSI_PROCESSOR_FRAGMENT; softpipe->tgsi.frag_samplers[i].cache = softpipe->tex_cache[i]; softpipe->tgsi.frag_samplers_list[i] = &softpipe->tgsi.frag_samplers[i]; } diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 3ed1de7e178..1f6e2ccb836 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -202,13 +202,14 @@ update_tgsi_samplers( struct softpipe_context *softpipe ) for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { softpipe->tgsi.vert_samplers[i].sampler = softpipe->sampler[i]; softpipe->tgsi.vert_samplers[i].texture = softpipe->texture[i]; + softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples; } /* fragment shader samplers */ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { softpipe->tgsi.frag_samplers[i].sampler = softpipe->sampler[i]; softpipe->tgsi.frag_samplers[i].texture = softpipe->texture[i]; - softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples_fragment; + softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples; } for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 2987548fb34..6c75158d598 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -41,6 +41,7 @@ #include "sp_tile_cache.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -521,15 +522,20 @@ choose_cube_face(float rx, float ry, float rz, float *newS, float *newT) * This is only done for fragment shaders, not vertex shaders. */ static float -compute_lambda(const struct pipe_texture *tex, - const struct pipe_sampler_state *sampler, +compute_lambda(struct tgsi_sampler *tgsi_sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], float lodbias) { + const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); + const struct pipe_texture *texture = samp->texture; + const struct pipe_sampler_state *sampler = samp->sampler; float rho, lambda; + if (samp->processor == TGSI_PROCESSOR_VERTEX) + return lodbias; + assert(sampler->normalized_coords); assert(s); @@ -538,7 +544,7 @@ compute_lambda(const struct pipe_texture *tex, float dsdy = s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]; dsdx = fabsf(dsdx); dsdy = fabsf(dsdy); - rho = MAX2(dsdx, dsdy) * tex->width[0]; + rho = MAX2(dsdx, dsdy) * texture->width[0]; } if (t) { float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]; @@ -546,7 +552,7 @@ compute_lambda(const struct pipe_texture *tex, float max; dtdx = fabsf(dtdx); dtdy = fabsf(dtdy); - max = MAX2(dtdx, dtdy) * tex->height[0]; + max = MAX2(dtdx, dtdy) * texture->height[0]; rho = MAX2(rho, max); } if (p) { @@ -555,7 +561,7 @@ compute_lambda(const struct pipe_texture *tex, float max; dpdx = fabsf(dpdx); dpdy = fabsf(dpdy); - max = MAX2(dpdx, dpdy) * tex->depth[0]; + max = MAX2(dpdx, dpdy) * texture->depth[0]; rho = MAX2(rho, max); } @@ -579,16 +585,18 @@ compute_lambda(const struct pipe_texture *tex, * \param imgFilter Returns either the min or mag filter, depending on lambda */ static void -choose_mipmap_levels(const struct pipe_texture *texture, - const struct pipe_sampler_state *sampler, +choose_mipmap_levels(struct tgsi_sampler *tgsi_sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], - boolean computeLambda, float lodbias, unsigned *level0, unsigned *level1, float *levelBlend, unsigned *imgFilter) { + const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); + const struct pipe_texture *texture = samp->texture; + const struct pipe_sampler_state *sampler = samp->sampler; + if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { /* no mipmap selection needed */ *level0 = *level1 = CLAMP((int) sampler->min_lod, @@ -598,7 +606,7 @@ choose_mipmap_levels(const struct pipe_texture *texture, /* non-mipmapped texture, but still need to determine if doing * minification or magnification. */ - float lambda = compute_lambda(texture, sampler, s, t, p, lodbias); + float lambda = compute_lambda(tgsi_sampler, s, t, p, lodbias); if (lambda <= 0.0) { *imgFilter = sampler->mag_img_filter; } @@ -611,14 +619,7 @@ choose_mipmap_levels(const struct pipe_texture *texture, } } else { - float lambda; - - if (computeLambda) - /* fragment shader */ - lambda = compute_lambda(texture, sampler, s, t, p, lodbias); - else - /* vertex shader */ - lambda = lodbias; /* not really a bias, but absolute LOD */ + float lambda = compute_lambda(tgsi_sampler, s, t, p, lodbias); if (lambda <= 0.0) { /* XXX threshold depends on the filter */ /* magnifying */ @@ -1028,11 +1029,10 @@ sp_get_samples_2d_linear_mip_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler { struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); const struct pipe_texture *texture = samp->texture; - const struct pipe_sampler_state *sampler = samp->sampler; int level0; float lambda; - lambda = compute_lambda(texture, sampler, s, t, p, lodbias); + lambda = compute_lambda(tgsi_sampler, s, t, p, lodbias); level0 = (int)lambda; if (lambda < 0.0) { @@ -1072,11 +1072,10 @@ sp_get_samples_2d_linear_mip_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler * Could probably extend for 3D... */ static void -sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler, +sp_get_samples_2d_common(struct tgsi_sampler *tgsi_sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], - boolean computeLambda, float lodbias, float rgba[NUM_CHANNELS][QUAD_SIZE], const unsigned faces[4]) @@ -1088,7 +1087,8 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler, int width, height; float levelBlend; - choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias, + choose_mipmap_levels(tgsi_sampler, s, t, p, + lodbias, &level0, &level1, &levelBlend, &imgFilter); assert(sampler->normalized_coords); @@ -1199,42 +1199,39 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler, static INLINE void -sp_get_samples_1d(const struct tgsi_sampler *sampler, +sp_get_samples_1d(struct tgsi_sampler *sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], - boolean computeLambda, float lodbias, float rgba[NUM_CHANNELS][QUAD_SIZE]) { static const unsigned faces[4] = {0, 0, 0, 0}; static const float tzero[4] = {0, 0, 0, 0}; sp_get_samples_2d_common(sampler, s, tzero, NULL, - computeLambda, lodbias, rgba, faces); + lodbias, rgba, faces); } static INLINE void -sp_get_samples_2d(const struct tgsi_sampler *sampler, +sp_get_samples_2d(struct tgsi_sampler *sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], - boolean computeLambda, float lodbias, float rgba[NUM_CHANNELS][QUAD_SIZE]) { static const unsigned faces[4] = {0, 0, 0, 0}; sp_get_samples_2d_common(sampler, s, t, p, - computeLambda, lodbias, rgba, faces); + lodbias, rgba, faces); } static INLINE void -sp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler, +sp_get_samples_3d(struct tgsi_sampler *tgsi_sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], - boolean computeLambda, float lodbias, float rgba[NUM_CHANNELS][QUAD_SIZE]) { @@ -1247,7 +1244,8 @@ sp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler, float levelBlend; const uint face = 0; - choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias, + choose_mipmap_levels(tgsi_sampler, s, t, p, + lodbias, &level0, &level1, &levelBlend, &imgFilter); assert(sampler->normalized_coords); @@ -1356,11 +1354,10 @@ sp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler, static void -sp_get_samples_cube(const struct tgsi_sampler *sampler, +sp_get_samples_cube(struct tgsi_sampler *sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], - boolean computeLambda, float lodbias, float rgba[NUM_CHANNELS][QUAD_SIZE]) { @@ -1370,16 +1367,15 @@ sp_get_samples_cube(const struct tgsi_sampler *sampler, faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j); } sp_get_samples_2d_common(sampler, ssss, tttt, NULL, - computeLambda, lodbias, rgba, faces); + lodbias, rgba, faces); } static void -sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler, +sp_get_samples_rect(struct tgsi_sampler *tgsi_sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], - boolean computeLambda, float lodbias, float rgba[NUM_CHANNELS][QUAD_SIZE]) { @@ -1391,7 +1387,8 @@ sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler, int width, height; float levelBlend; - choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias, + choose_mipmap_levels(tgsi_sampler, s, t, p, + lodbias, &level0, &level1, &levelBlend, &imgFilter); /* texture RECTS cannot be mipmapped */ @@ -1447,90 +1444,77 @@ sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler, /** - * Common code for vertex/fragment program texture sampling. + * Error condition handler */ static INLINE void +sp_get_samples_null(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + int i,j; + + for (i = 0; i < 4; i++) + for (j = 0; j < 4; j++) + rgba[i][j] = 1.0; +} + +/** + * Called via tgsi_sampler::get_samples() when using a sampler for the + * first time. Determine the actual sampler function, link it in and + * call it. + */ +void sp_get_samples(struct tgsi_sampler *tgsi_sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], - boolean computeLambda, float lodbias, float rgba[NUM_CHANNELS][QUAD_SIZE]) { - const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); + struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); const struct pipe_texture *texture = samp->texture; const struct pipe_sampler_state *sampler = samp->sampler; - if (!texture) - return; + /* Default to the 'undefined' case: + */ + tgsi_sampler->get_samples = sp_get_samples_null; + + if (!texture) { + assert(0); /* is this legal?? */ + goto out; + } + + if (!sampler->normalized_coords) { + assert (texture->target == PIPE_TEXTURE_2D); + tgsi_sampler->get_samples = sp_get_samples_rect; + goto out; + } switch (texture->target) { case PIPE_TEXTURE_1D: - assert(sampler->normalized_coords); - sp_get_samples_1d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba); + tgsi_sampler->get_samples = sp_get_samples_1d; break; case PIPE_TEXTURE_2D: - if (sampler->normalized_coords) - sp_get_samples_2d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba); - else - sp_get_samples_rect(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba); + tgsi_sampler->get_samples = sp_get_samples_2d; break; case PIPE_TEXTURE_3D: - assert(sampler->normalized_coords); - sp_get_samples_3d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba); + tgsi_sampler->get_samples = sp_get_samples_3d; break; case PIPE_TEXTURE_CUBE: - assert(sampler->normalized_coords); - sp_get_samples_cube(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba); + tgsi_sampler->get_samples = sp_get_samples_cube; break; default: assert(0); + break; } -#if 0 /* DEBUG */ - { - int i; - printf("Sampled at %f, %f, %f:\n", s[0], t[0], p[0]); - for (i = 0; i < 4; i++) { - printf("Frag %d: %f %f %f %f\n", i, - rgba[0][i], - rgba[1][i], - rgba[2][i], - rgba[3][i]); - } - } -#endif -} - -static void -sp_get_samples_fallback(struct tgsi_sampler *tgsi_sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]) -{ - sp_get_samples(tgsi_sampler, s, t, p, TRUE, lodbias, rgba); -} - -/** - * Called via tgsi_sampler::get_samples() when running a fragment shader. - * Get four filtered RGBA values from the sampler's texture. - */ -void -sp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]) -{ - struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; - const struct pipe_sampler_state *sampler = samp->sampler; - - tgsi_sampler->get_samples = sp_get_samples_fallback; + /* Do this elsewhere: + */ + samp->xpot = util_unsigned_logbase2( samp->texture->width[0] ); + samp->ypot = util_unsigned_logbase2( samp->texture->height[0] ); /* Try to hook in a faster sampler. Ultimately we'll have to * code-generate these. Luckily most of this looks like it is @@ -1542,9 +1526,6 @@ sp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler, sampler->compare_mode == FALSE && sampler->normalized_coords) { - samp->xpot = util_unsigned_logbase2( samp->texture->width[0] ); - samp->ypot = util_unsigned_logbase2( samp->texture->height[0] ); - if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { samp->level = CLAMP((int) sampler->min_lod, 0, (int) texture->last_level); @@ -1593,21 +1574,7 @@ sp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler, sampler->normalized_coords, TRUE); } +out: tgsi_sampler->get_samples( tgsi_sampler, s, t, p, lodbias, rgba ); } - -/** - * Called via tgsi_sampler::get_samples() when running a vertex shader. - * Get four filtered RGBA values from the sampler's texture. - */ -void -sp_get_samples_vertex(struct tgsi_sampler *tgsi_sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]) -{ - sp_get_samples(tgsi_sampler, s, t, p, FALSE, lodbias, rgba); -} diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h index 0650c7830b9..c73ae441314 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.h +++ b/src/gallium/drivers/softpipe/sp_tex_sample.h @@ -39,6 +39,8 @@ struct sp_shader_sampler { struct tgsi_sampler base; /**< base class */ + unsigned processor; + /* For sp_get_samples_2d_linear_POT: */ unsigned xpot; @@ -60,21 +62,14 @@ sp_shader_sampler(const struct tgsi_sampler *sampler) } -extern void -sp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]); extern void -sp_get_samples_vertex(struct tgsi_sampler *tgsi_sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]); +sp_get_samples(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]); #endif /* SP_TEX_SAMPLE_H */ -- cgit v1.2.3 From 4fc7d0345a18042a79686940fb7cc4e698cc9192 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 21 Aug 2009 17:13:11 +0100 Subject: softpipe: rework texture sampling code Split into component pieces, stitch together at runtime using function pointers. Make it possible to utilize the existing fastpaths as image-level filters for generic mip-filtering routines. Remove special case for rectangle filtering, as it can now be handled by the 2d path. As most of the mesa demo texturing was already covered by fast paths, its harder to find examples of speedups, but tunnel gets a boost as mip-nearest filtering is now able to access the img_2d_linear_wrap_POT functions for sampling within a mipmap level. --- src/gallium/drivers/softpipe/sp_context.c | 15 - src/gallium/drivers/softpipe/sp_context.h | 23 +- src/gallium/drivers/softpipe/sp_state.h | 1 + src/gallium/drivers/softpipe/sp_state_blend.c | 4 +- src/gallium/drivers/softpipe/sp_state_derived.c | 18 +- src/gallium/drivers/softpipe/sp_state_fs.c | 3 + src/gallium/drivers/softpipe/sp_state_sampler.c | 104 +- src/gallium/drivers/softpipe/sp_tex_sample.c | 2198 ++++++++++++----------- src/gallium/drivers/softpipe/sp_tex_sample.h | 94 +- src/gallium/drivers/softpipe/sp_texture.c | 8 +- src/gallium/drivers/softpipe/sp_texture.h | 4 + 11 files changed, 1361 insertions(+), 1111 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index a0196955c87..ef8faab3bd8 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -228,21 +228,6 @@ softpipe_create( struct pipe_screen *screen ) softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe); softpipe->quad.blend = sp_quad_blend_stage(softpipe); - /* vertex shader samplers */ - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - softpipe->tgsi.vert_samplers[i].base.get_samples = sp_get_samples; - softpipe->tgsi.vert_samplers[i].processor = TGSI_PROCESSOR_VERTEX; - softpipe->tgsi.vert_samplers[i].cache = softpipe->tex_cache[i]; - softpipe->tgsi.vert_samplers_list[i] = &softpipe->tgsi.vert_samplers[i]; - } - - /* fragment shader samplers */ - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples; - softpipe->tgsi.frag_samplers[i].processor = TGSI_PROCESSOR_FRAGMENT; - softpipe->tgsi.frag_samplers[i].cache = softpipe->tex_cache[i]; - softpipe->tgsi.frag_samplers_list[i] = &softpipe->tgsi.frag_samplers[i]; - } /* * Create drawing context and plug our rendering stage into it. diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index fa3306c020a..068a892f250 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -36,7 +36,6 @@ #include "draw/draw_vertex.h" #include "sp_quad_pipe.h" -#include "sp_tex_sample.h" struct softpipe_vbuf_render; @@ -51,12 +50,12 @@ struct softpipe_context { struct pipe_context pipe; /**< base class */ /** Constant state objects */ - const struct pipe_blend_state *blend; - const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; - const struct pipe_depth_stencil_alpha_state *depth_stencil; - const struct pipe_rasterizer_state *rasterizer; - const struct sp_fragment_shader *fs; - const struct sp_vertex_shader *vs; + struct pipe_blend_state *blend; + struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; + struct pipe_depth_stencil_alpha_state *depth_stencil; + struct pipe_rasterizer_state *rasterizer; + struct sp_fragment_shader *fs; + struct sp_vertex_shader *vs; /** Other rendering state */ struct pipe_blend_color blend_color; @@ -123,10 +122,8 @@ struct softpipe_context { /** TGSI exec things */ struct { - struct sp_shader_sampler vert_samplers[PIPE_MAX_SAMPLERS]; - struct sp_shader_sampler *vert_samplers_list[PIPE_MAX_SAMPLERS]; - struct sp_shader_sampler frag_samplers[PIPE_MAX_SAMPLERS]; - struct sp_shader_sampler *frag_samplers_list[PIPE_MAX_SAMPLERS]; + struct sp_sampler_varient *vert_samplers_list[PIPE_MAX_SAMPLERS]; + struct sp_sampler_varient *frag_samplers_list[PIPE_MAX_SAMPLERS]; } tgsi; /** The primitive drawing context */ @@ -155,5 +152,9 @@ softpipe_context( struct pipe_context *pipe ) return (struct softpipe_context *)pipe; } +void +softpipe_reset_sampler_varients(struct softpipe_context *softpipe); + + #endif /* SP_CONTEXT_H */ diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 9776e978e3e..77ee3c1136b 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -87,6 +87,7 @@ struct sp_fragment_shader { struct sp_vertex_shader { struct pipe_shader_state shader; struct draw_vertex_shader *draw_data; + int max_sampler; /* -1 if no samplers */ }; diff --git a/src/gallium/drivers/softpipe/sp_state_blend.c b/src/gallium/drivers/softpipe/sp_state_blend.c index 384fe559afd..efed082f823 100644 --- a/src/gallium/drivers/softpipe/sp_state_blend.c +++ b/src/gallium/drivers/softpipe/sp_state_blend.c @@ -45,7 +45,7 @@ void softpipe_bind_blend_state( struct pipe_context *pipe, { struct softpipe_context *softpipe = softpipe_context(pipe); - softpipe->blend = (const struct pipe_blend_state *)blend; + softpipe->blend = (struct pipe_blend_state *)blend; softpipe->dirty |= SP_NEW_BLEND; } @@ -86,7 +86,7 @@ softpipe_bind_depth_stencil_state(struct pipe_context *pipe, { struct softpipe_context *softpipe = softpipe_context(pipe); - softpipe->depth_stencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil; + softpipe->depth_stencil = (struct pipe_depth_stencil_alpha_state *)depth_stencil; softpipe->dirty |= SP_NEW_DEPTH_STENCIL_ALPHA; } diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 1f6e2ccb836..53109283320 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -198,19 +198,7 @@ update_tgsi_samplers( struct softpipe_context *softpipe ) { unsigned i; - /* vertex shader samplers */ - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - softpipe->tgsi.vert_samplers[i].sampler = softpipe->sampler[i]; - softpipe->tgsi.vert_samplers[i].texture = softpipe->texture[i]; - softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples; - } - - /* fragment shader samplers */ - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - softpipe->tgsi.frag_samplers[i].sampler = softpipe->sampler[i]; - softpipe->tgsi.frag_samplers[i].texture = softpipe->texture[i]; - softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples; - } + softpipe_reset_sampler_varients( softpipe ); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { sp_tile_cache_validate_texture( softpipe->tex_cache[i] ); @@ -232,7 +220,9 @@ void softpipe_update_derived( struct softpipe_context *softpipe ) } if (softpipe->dirty & (SP_NEW_SAMPLER | - SP_NEW_TEXTURE)) + SP_NEW_TEXTURE | + SP_NEW_FS | + SP_NEW_VS)) update_tgsi_samplers( softpipe ); if (softpipe->dirty & (SP_NEW_RASTERIZER | diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 108ac8b9bb1..3a453219235 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -34,6 +34,7 @@ #include "pipe/internal/p_winsys_screen.h" #include "pipe/p_shader_tokens.h" #include "draw/draw_context.h" +#include "draw/draw_vs.h" #include "tgsi/tgsi_dump.h" #include "tgsi/tgsi_scan.h" #include "tgsi/tgsi_parse.h" @@ -108,6 +109,8 @@ softpipe_create_vs_state(struct pipe_context *pipe, if (state->draw_data == NULL) goto fail; + state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER]; + return state; fail: diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index aa2f3f2ccd6..714e6380487 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -38,15 +38,32 @@ #include "sp_state.h" #include "sp_texture.h" #include "sp_tile_cache.h" +#include "sp_tex_sample.h" #include "draw/draw_context.h" +struct sp_sampler { + struct pipe_sampler_state base; + struct sp_sampler_varient *varients; + struct sp_sampler_varient *current; +}; + +static struct sp_sampler *sp_sampler( struct pipe_sampler_state *sampler ) +{ + return (struct sp_sampler *)sampler; +} + void * softpipe_create_sampler_state(struct pipe_context *pipe, const struct pipe_sampler_state *sampler) { - return mem_dup(sampler, sizeof(*sampler)); + struct sp_sampler *sp_sampler = CALLOC_STRUCT(sp_sampler); + + sp_sampler->base = *sampler; + sp_sampler->varients = NULL; + + return (void *)sp_sampler; } @@ -106,10 +123,95 @@ softpipe_set_sampler_textures(struct pipe_context *pipe, } + +static struct sp_sampler_varient * +get_sampler_varient( struct sp_sampler *sampler, + struct pipe_texture *texture, + unsigned processor ) +{ + struct softpipe_texture *sp_texture = softpipe_texture(texture); + struct sp_sampler_varient *v = NULL; + union sp_sampler_key key; + + key.bits.target = sp_texture->base.target; + key.bits.is_pot = sp_texture->pot; + key.bits.processor = processor; + key.bits.pad = 0; + + if (sampler->current && + key.value == sampler->current->key.value) { + v = sampler->current; + } + + if (v == NULL) { + for (v = sampler->varients; v; v = v->next) + if (v->key.value == key.value) + break; + + if (v == NULL) { + v = sp_create_sampler_varient( &sampler->base, key ); + v->next = sampler->varients; + sampler->varients = v; + } + } + + sampler->current = v; + return v; +} + + + + +void +softpipe_reset_sampler_varients(struct softpipe_context *softpipe) +{ + int i; + + /* It's a bit hard to build these samplers ahead of time -- don't + * really know which samplers are going to be used for vertex and + * fragment programs. + */ + for (i = 0; i <= softpipe->vs->max_sampler; i++) { + if (softpipe->sampler[i]) { + softpipe->tgsi.vert_samplers_list[i] = + get_sampler_varient( sp_sampler(softpipe->sampler[i]), + softpipe->texture[i], + TGSI_PROCESSOR_VERTEX ); + + sp_sampler_varient_bind_texture( softpipe->tgsi.vert_samplers_list[i], + softpipe->tex_cache[i], + softpipe->texture[i] ); + } + } + + for (i = 0; i <= softpipe->fs->info.file_max[TGSI_FILE_SAMPLER]; i++) { + if (softpipe->sampler[i]) { + softpipe->tgsi.frag_samplers_list[i] = + get_sampler_varient( sp_sampler(softpipe->sampler[i]), + softpipe->texture[i], + TGSI_PROCESSOR_FRAGMENT ); + + sp_sampler_varient_bind_texture( softpipe->tgsi.frag_samplers_list[i], + softpipe->tex_cache[i], + softpipe->texture[i] ); + } + } +} + + + void softpipe_delete_sampler_state(struct pipe_context *pipe, void *sampler) { + struct sp_sampler *sp_sampler = (struct sp_sampler *)sampler; + struct sp_sampler_varient *v, *tmp; + + for (v = sp_sampler->varients; v; v = tmp) { + tmp = v->next; + sp_sampler_varient_destroy(v); + } + FREE( sampler ); } diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 6c75158d598..7bc689a298f 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -31,6 +31,7 @@ * * Authors: * Brian Paul + * Keith Whitwell */ #include "sp_context.h" @@ -116,133 +117,157 @@ lerp_3d(float a, float b, float c, * \param icoord returns the integer texcoords * \return integer texture index */ -static INLINE void -nearest_texcoord_4(unsigned wrapMode, const float s[4], unsigned size, +static void +wrap_nearest_repeat(const float s[4], unsigned size, + int icoord[4]) +{ + uint ch; + + /* s limited to [0,1) */ + /* i limited to [0,size-1] */ + for (ch = 0; ch < 4; ch++) { + int i = util_ifloor(s[ch] * size); + icoord[ch] = REMAINDER(i, size); + } +} + + +static void +wrap_nearest_clamp(const float s[4], unsigned size, int icoord[4]) { uint ch; - switch (wrapMode) { - case PIPE_TEX_WRAP_REPEAT: - /* s limited to [0,1) */ - /* i limited to [0,size-1] */ - for (ch = 0; ch < 4; ch++) { - int i = util_ifloor(s[ch] * size); - icoord[ch] = REMAINDER(i, size); - } - return; - case PIPE_TEX_WRAP_CLAMP: + /* s limited to [0,1] */ + /* i limited to [0,size-1] */ + for (ch = 0; ch < 4; ch++) { + if (s[ch] <= 0.0F) + icoord[ch] = 0; + else if (s[ch] >= 1.0F) + icoord[ch] = size - 1; + else + icoord[ch] = util_ifloor(s[ch] * size); + } +} + + +static void +wrap_nearest_clamp_to_edge(const float s[4], unsigned size, + int icoord[4]) +{ + uint ch; + /* s limited to [min,max] */ + /* i limited to [0, size-1] */ + const float min = 1.0F / (2.0F * size); + const float max = 1.0F - min; + for (ch = 0; ch < 4; ch++) { + if (s[ch] < min) + icoord[ch] = 0; + else if (s[ch] > max) + icoord[ch] = size - 1; + else + icoord[ch] = util_ifloor(s[ch] * size); + } +} + + +static void +wrap_nearest_clamp_to_border(const float s[4], unsigned size, + int icoord[4]) +{ + uint ch; + /* s limited to [min,max] */ + /* i limited to [-1, size] */ + const float min = -1.0F / (2.0F * size); + const float max = 1.0F - min; + for (ch = 0; ch < 4; ch++) { + if (s[ch] <= min) + icoord[ch] = -1; + else if (s[ch] >= max) + icoord[ch] = size; + else + icoord[ch] = util_ifloor(s[ch] * size); + } +} + +static void +wrap_nearest_mirror_repeat(const float s[4], unsigned size, + int icoord[4]) +{ + uint ch; + const float min = 1.0F / (2.0F * size); + const float max = 1.0F - min; + for (ch = 0; ch < 4; ch++) { + const int flr = util_ifloor(s[ch]); + float u; + if (flr & 1) + u = 1.0F - (s[ch] - (float) flr); + else + u = s[ch] - (float) flr; + if (u < min) + icoord[ch] = 0; + else if (u > max) + icoord[ch] = size - 1; + else + icoord[ch] = util_ifloor(u * size); + } +} + +static void +wrap_nearest_mirror_clamp(const float s[4], unsigned size, + int icoord[4]) +{ + uint ch; + for (ch = 0; ch < 4; ch++) { /* s limited to [0,1] */ /* i limited to [0,size-1] */ - for (ch = 0; ch < 4; ch++) { - if (s[ch] <= 0.0F) - icoord[ch] = 0; - else if (s[ch] >= 1.0F) - icoord[ch] = size - 1; - else - icoord[ch] = util_ifloor(s[ch] * size); - } - return; - case PIPE_TEX_WRAP_CLAMP_TO_EDGE: - { - /* s limited to [min,max] */ - /* i limited to [0, size-1] */ - const float min = 1.0F / (2.0F * size); - const float max = 1.0F - min; - for (ch = 0; ch < 4; ch++) { - if (s[ch] < min) - icoord[ch] = 0; - else if (s[ch] > max) - icoord[ch] = size - 1; - else - icoord[ch] = util_ifloor(s[ch] * size); - } - } - return; - case PIPE_TEX_WRAP_CLAMP_TO_BORDER: - { - /* s limited to [min,max] */ - /* i limited to [-1, size] */ - const float min = -1.0F / (2.0F * size); - const float max = 1.0F - min; - for (ch = 0; ch < 4; ch++) { - if (s[ch] <= min) - icoord[ch] = -1; - else if (s[ch] >= max) - icoord[ch] = size; - else - icoord[ch] = util_ifloor(s[ch] * size); - } - } - return; - case PIPE_TEX_WRAP_MIRROR_REPEAT: - { - const float min = 1.0F / (2.0F * size); - const float max = 1.0F - min; - for (ch = 0; ch < 4; ch++) { - const int flr = util_ifloor(s[ch]); - float u; - if (flr & 1) - u = 1.0F - (s[ch] - (float) flr); - else - u = s[ch] - (float) flr; - if (u < min) - icoord[ch] = 0; - else if (u > max) - icoord[ch] = size - 1; - else - icoord[ch] = util_ifloor(u * size); - } - } - return; - case PIPE_TEX_WRAP_MIRROR_CLAMP: - for (ch = 0; ch < 4; ch++) { - /* s limited to [0,1] */ - /* i limited to [0,size-1] */ - const float u = fabsf(s[ch]); - if (u <= 0.0F) - icoord[ch] = 0; - else if (u >= 1.0F) - icoord[ch] = size - 1; - else - icoord[ch] = util_ifloor(u * size); - } - return; - case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: - { - /* s limited to [min,max] */ - /* i limited to [0, size-1] */ - const float min = 1.0F / (2.0F * size); - const float max = 1.0F - min; - for (ch = 0; ch < 4; ch++) { - const float u = fabsf(s[ch]); - if (u < min) - icoord[ch] = 0; - else if (u > max) - icoord[ch] = size - 1; - else - icoord[ch] = util_ifloor(u * size); - } - } - return; - case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: - { - /* s limited to [min,max] */ - /* i limited to [0, size-1] */ - const float min = -1.0F / (2.0F * size); - const float max = 1.0F - min; - for (ch = 0; ch < 4; ch++) { - const float u = fabsf(s[ch]); - if (u < min) - icoord[ch] = -1; - else if (u > max) - icoord[ch] = size; - else - icoord[ch] = util_ifloor(u * size); - } - } - return; - default: - assert(0); + const float u = fabsf(s[ch]); + if (u <= 0.0F) + icoord[ch] = 0; + else if (u >= 1.0F) + icoord[ch] = size - 1; + else + icoord[ch] = util_ifloor(u * size); + } +} + +static void +wrap_nearest_mirror_clamp_to_edge(const float s[4], unsigned size, + int icoord[4]) +{ + uint ch; + /* s limited to [min,max] */ + /* i limited to [0, size-1] */ + const float min = 1.0F / (2.0F * size); + const float max = 1.0F - min; + for (ch = 0; ch < 4; ch++) { + const float u = fabsf(s[ch]); + if (u < min) + icoord[ch] = 0; + else if (u > max) + icoord[ch] = size - 1; + else + icoord[ch] = util_ifloor(u * size); + } +} + + +static void +wrap_nearest_mirror_clamp_to_border(const float s[4], unsigned size, + int icoord[4]) +{ + uint ch; + /* s limited to [min,max] */ + /* i limited to [0, size-1] */ + const float min = -1.0F / (2.0F * size); + const float max = 1.0F - min; + for (ch = 0; ch < 4; ch++) { + const float u = fabsf(s[ch]); + if (u < min) + icoord[ch] = -1; + else if (u > max) + icoord[ch] = size; + else + icoord[ch] = util_ifloor(u * size); } } @@ -257,125 +282,151 @@ nearest_texcoord_4(unsigned wrapMode, const float s[4], unsigned size, * \param w returns blend factor/weight between texture indexes * \param icoord returns the computed integer texture coords */ -static INLINE void -linear_texcoord_4(unsigned wrapMode, const float s[4], unsigned size, +static void +wrap_linear_repeat(const float s[4], unsigned size, + int icoord0[4], int icoord1[4], float w[4]) +{ + uint ch; + + for (ch = 0; ch < 4; ch++) { + float u = s[ch] * size - 0.5F; + icoord0[ch] = REMAINDER(util_ifloor(u), size); + icoord1[ch] = REMAINDER(icoord0[ch] + 1, size); + w[ch] = FRAC(u); + } +} + +static void +wrap_linear_clamp(const float s[4], unsigned size, int icoord0[4], int icoord1[4], float w[4]) { uint ch; + for (ch = 0; ch < 4; ch++) { + float u = CLAMP(s[ch], 0.0F, 1.0F); + u = u * size - 0.5f; + icoord0[ch] = util_ifloor(u); + icoord1[ch] = icoord0[ch] + 1; + w[ch] = FRAC(u); + } +} - switch (wrapMode) { - case PIPE_TEX_WRAP_REPEAT: - for (ch = 0; ch < 4; ch++) { - float u = s[ch] * size - 0.5F; - icoord0[ch] = REMAINDER(util_ifloor(u), size); - icoord1[ch] = REMAINDER(icoord0[ch] + 1, size); - w[ch] = FRAC(u); - } - break;; - case PIPE_TEX_WRAP_CLAMP: - for (ch = 0; ch < 4; ch++) { - float u = CLAMP(s[ch], 0.0F, 1.0F); - u = u * size - 0.5f; - icoord0[ch] = util_ifloor(u); - icoord1[ch] = icoord0[ch] + 1; - w[ch] = FRAC(u); - } - break;; - case PIPE_TEX_WRAP_CLAMP_TO_EDGE: - for (ch = 0; ch < 4; ch++) { - float u = CLAMP(s[ch], 0.0F, 1.0F); - u = u * size - 0.5f; - icoord0[ch] = util_ifloor(u); - icoord1[ch] = icoord0[ch] + 1; - if (icoord0[ch] < 0) - icoord0[ch] = 0; - if (icoord1[ch] >= (int) size) - icoord1[ch] = size - 1; - w[ch] = FRAC(u); - } - break;; - case PIPE_TEX_WRAP_CLAMP_TO_BORDER: - { - const float min = -1.0F / (2.0F * size); - const float max = 1.0F - min; - for (ch = 0; ch < 4; ch++) { - float u = CLAMP(s[ch], min, max); - u = u * size - 0.5f; - icoord0[ch] = util_ifloor(u); - icoord1[ch] = icoord0[ch] + 1; - w[ch] = FRAC(u); - } - } - break;; - case PIPE_TEX_WRAP_MIRROR_REPEAT: - for (ch = 0; ch < 4; ch++) { - const int flr = util_ifloor(s[ch]); - float u; - if (flr & 1) - u = 1.0F - (s[ch] - (float) flr); - else - u = s[ch] - (float) flr; - u = u * size - 0.5F; - icoord0[ch] = util_ifloor(u); - icoord1[ch] = icoord0[ch] + 1; - if (icoord0[ch] < 0) - icoord0[ch] = 0; - if (icoord1[ch] >= (int) size) - icoord1[ch] = size - 1; - w[ch] = FRAC(u); - } - break;; - case PIPE_TEX_WRAP_MIRROR_CLAMP: - for (ch = 0; ch < 4; ch++) { - float u = fabsf(s[ch]); - if (u >= 1.0F) - u = (float) size; - else - u *= size; - u -= 0.5F; - icoord0[ch] = util_ifloor(u); - icoord1[ch] = icoord0[ch] + 1; - w[ch] = FRAC(u); - } - break;; - case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: - for (ch = 0; ch < 4; ch++) { - float u = fabsf(s[ch]); - if (u >= 1.0F) - u = (float) size; - else - u *= size; - u -= 0.5F; - icoord0[ch] = util_ifloor(u); - icoord1[ch] = icoord0[ch] + 1; - if (icoord0[ch] < 0) - icoord0[ch] = 0; - if (icoord1[ch] >= (int) size) - icoord1[ch] = size - 1; - w[ch] = FRAC(u); - } - break;; - case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: - { - const float min = -1.0F / (2.0F * size); - const float max = 1.0F - min; - for (ch = 0; ch < 4; ch++) { - float u = fabsf(s[ch]); - if (u <= min) - u = min * size; - else if (u >= max) - u = max * size; - else - u *= size; - u -= 0.5F; - icoord0[ch] = util_ifloor(u); - icoord1[ch] = icoord0[ch] + 1; - w[ch] = FRAC(u); - } - } - break;; - default: - assert(0); +static void +wrap_linear_clamp_to_edge(const float s[4], unsigned size, + int icoord0[4], int icoord1[4], float w[4]) +{ + uint ch; + for (ch = 0; ch < 4; ch++) { + float u = CLAMP(s[ch], 0.0F, 1.0F); + u = u * size - 0.5f; + icoord0[ch] = util_ifloor(u); + icoord1[ch] = icoord0[ch] + 1; + if (icoord0[ch] < 0) + icoord0[ch] = 0; + if (icoord1[ch] >= (int) size) + icoord1[ch] = size - 1; + w[ch] = FRAC(u); + } +} + +static void +wrap_linear_clamp_to_border(const float s[4], unsigned size, + int icoord0[4], int icoord1[4], float w[4]) +{ + const float min = -1.0F / (2.0F * size); + const float max = 1.0F - min; + uint ch; + for (ch = 0; ch < 4; ch++) { + float u = CLAMP(s[ch], min, max); + u = u * size - 0.5f; + icoord0[ch] = util_ifloor(u); + icoord1[ch] = icoord0[ch] + 1; + w[ch] = FRAC(u); + } +} + + +static void +wrap_linear_mirror_repeat(const float s[4], unsigned size, + int icoord0[4], int icoord1[4], float w[4]) +{ + uint ch; + for (ch = 0; ch < 4; ch++) { + const int flr = util_ifloor(s[ch]); + float u; + if (flr & 1) + u = 1.0F - (s[ch] - (float) flr); + else + u = s[ch] - (float) flr; + u = u * size - 0.5F; + icoord0[ch] = util_ifloor(u); + icoord1[ch] = icoord0[ch] + 1; + if (icoord0[ch] < 0) + icoord0[ch] = 0; + if (icoord1[ch] >= (int) size) + icoord1[ch] = size - 1; + w[ch] = FRAC(u); + } +} + +static void +wrap_linear_mirror_clamp(const float s[4], unsigned size, + int icoord0[4], int icoord1[4], float w[4]) +{ + uint ch; + for (ch = 0; ch < 4; ch++) { + float u = fabsf(s[ch]); + if (u >= 1.0F) + u = (float) size; + else + u *= size; + u -= 0.5F; + icoord0[ch] = util_ifloor(u); + icoord1[ch] = icoord0[ch] + 1; + w[ch] = FRAC(u); + } +} + +static void +wrap_linear_mirror_clamp_to_edge(const float s[4], unsigned size, + int icoord0[4], int icoord1[4], float w[4]) +{ + uint ch; + for (ch = 0; ch < 4; ch++) { + float u = fabsf(s[ch]); + if (u >= 1.0F) + u = (float) size; + else + u *= size; + u -= 0.5F; + icoord0[ch] = util_ifloor(u); + icoord1[ch] = icoord0[ch] + 1; + if (icoord0[ch] < 0) + icoord0[ch] = 0; + if (icoord1[ch] >= (int) size) + icoord1[ch] = size - 1; + w[ch] = FRAC(u); + } +} + +static void +wrap_linear_mirror_clamp_to_border(const float s[4], unsigned size, + int icoord0[4], int icoord1[4], float w[4]) +{ + const float min = -1.0F / (2.0F * size); + const float max = 1.0F - min; + uint ch; + for (ch = 0; ch < 4; ch++) { + float u = fabsf(s[ch]); + if (u <= min) + u = min * size; + else if (u >= max) + u = max * size; + else + u *= size; + u -= 0.5F; + icoord0[ch] = util_ifloor(u); + icoord1[ch] = icoord0[ch] + 1; + w[ch] = FRAC(u); } } @@ -384,27 +435,26 @@ linear_texcoord_4(unsigned wrapMode, const float s[4], unsigned size, * For RECT textures / unnormalized texcoords * Only a subset of wrap modes supported. */ -static INLINE void -nearest_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size, +static void +wrap_nearest_unorm_clamp(const float s[4], unsigned size, int icoord[4]) { uint ch; - switch (wrapMode) { - case PIPE_TEX_WRAP_CLAMP: - for (ch = 0; ch < 4; ch++) { - int i = util_ifloor(s[ch]); - icoord[ch]= CLAMP(i, 0, (int) size-1); - } - return; - case PIPE_TEX_WRAP_CLAMP_TO_EDGE: - /* fall-through */ - case PIPE_TEX_WRAP_CLAMP_TO_BORDER: - for (ch = 0; ch < 4; ch++) { - icoord[ch]= util_ifloor( CLAMP(s[ch], 0.5F, (float) size - 0.5F) ); - } - return; - default: - assert(0); + for (ch = 0; ch < 4; ch++) { + int i = util_ifloor(s[ch]); + icoord[ch]= CLAMP(i, 0, (int) size-1); + } +} + +/* Handles clamp_to_edge and clamp_to_border: + */ +static void +wrap_nearest_unorm_clamp_to_border(const float s[4], unsigned size, + int icoord[4]) +{ + uint ch; + for (ch = 0; ch < 4; ch++) { + icoord[ch]= util_ifloor( CLAMP(s[ch], 0.5F, (float) size - 0.5F) ); } } @@ -413,157 +463,82 @@ nearest_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size, * For RECT textures / unnormalized texcoords. * Only a subset of wrap modes supported. */ -static INLINE void -linear_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size, +static void +wrap_linear_unorm_clamp(const float s[4], unsigned size, int icoord0[4], int icoord1[4], float w[4]) { uint ch; - switch (wrapMode) { - case PIPE_TEX_WRAP_CLAMP: - for (ch = 0; ch < 4; ch++) { - /* Not exactly what the spec says, but it matches NVIDIA output */ - float u = CLAMP(s[ch] - 0.5F, 0.0f, (float) size - 1.0f); - icoord0[ch] = util_ifloor(u); - icoord1[ch] = icoord0[ch] + 1; - w[ch] = FRAC(u); - } - return; - case PIPE_TEX_WRAP_CLAMP_TO_EDGE: - /* fall-through */ - case PIPE_TEX_WRAP_CLAMP_TO_BORDER: - for (ch = 0; ch < 4; ch++) { - float u = CLAMP(s[ch], 0.5F, (float) size - 0.5F); - u -= 0.5F; - icoord0[ch] = util_ifloor(u); - icoord1[ch] = icoord0[ch] + 1; - if (icoord1[ch] > (int) size - 1) - icoord1[ch] = size - 1; - w[ch] = FRAC(u); - } - break; - default: - assert(0); + for (ch = 0; ch < 4; ch++) { + /* Not exactly what the spec says, but it matches NVIDIA output */ + float u = CLAMP(s[ch] - 0.5F, 0.0f, (float) size - 1.0f); + icoord0[ch] = util_ifloor(u); + icoord1[ch] = icoord0[ch] + 1; + w[ch] = FRAC(u); } } - -static unsigned -choose_cube_face(float rx, float ry, float rz, float *newS, float *newT) +static void +wrap_linear_unorm_clamp_to_border( const float s[4], unsigned size, + int icoord0[4], int icoord1[4], float w[4]) { - /* - major axis - direction target sc tc ma - ---------- ------------------------------- --- --- --- - +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx - -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx - +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry - -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry - +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz - -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz - */ - const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz); - unsigned face; - float sc, tc, ma; - - if (arx > ary && arx > arz) { - if (rx >= 0.0F) { - face = PIPE_TEX_FACE_POS_X; - sc = -rz; - tc = -ry; - ma = arx; - } - else { - face = PIPE_TEX_FACE_NEG_X; - sc = rz; - tc = -ry; - ma = arx; - } - } - else if (ary > arx && ary > arz) { - if (ry >= 0.0F) { - face = PIPE_TEX_FACE_POS_Y; - sc = rx; - tc = rz; - ma = ary; - } - else { - face = PIPE_TEX_FACE_NEG_Y; - sc = rx; - tc = -rz; - ma = ary; - } - } - else { - if (rz > 0.0F) { - face = PIPE_TEX_FACE_POS_Z; - sc = rx; - tc = -ry; - ma = arz; - } - else { - face = PIPE_TEX_FACE_NEG_Z; - sc = -rx; - tc = -ry; - ma = arz; - } + uint ch; + for (ch = 0; ch < 4; ch++) { + float u = CLAMP(s[ch], 0.5F, (float) size - 0.5F); + u -= 0.5F; + icoord0[ch] = util_ifloor(u); + icoord1[ch] = icoord0[ch] + 1; + if (icoord1[ch] > (int) size - 1) + icoord1[ch] = size - 1; + w[ch] = FRAC(u); } +} + - *newS = ( sc / ma + 1.0F ) * 0.5F; - *newT = ( tc / ma + 1.0F ) * 0.5F; - return face; -} /** * Examine the quad's texture coordinates to compute the partial * derivatives w.r.t X and Y, then compute lambda (level of detail). - * - * This is only done for fragment shaders, not vertex shaders. */ static float -compute_lambda(struct tgsi_sampler *tgsi_sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias) +compute_lambda_1d(const struct sp_sampler_varient *samp, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias) { - const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); const struct pipe_texture *texture = samp->texture; const struct pipe_sampler_state *sampler = samp->sampler; - float rho, lambda; + float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]); + float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]); + float rho = MAX2(dsdx, dsdy) * texture->width[0]; + float lambda; - if (samp->processor == TGSI_PROCESSOR_VERTEX) - return lodbias; + lambda = util_fast_log2(rho); + lambda += lodbias + sampler->lod_bias; + lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod); - assert(sampler->normalized_coords); + return lambda; +} - assert(s); - { - float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]; - float dsdy = s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]; - dsdx = fabsf(dsdx); - dsdy = fabsf(dsdy); - rho = MAX2(dsdx, dsdy) * texture->width[0]; - } - if (t) { - float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]; - float dtdy = t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]; - float max; - dtdx = fabsf(dtdx); - dtdy = fabsf(dtdy); - max = MAX2(dtdx, dtdy) * texture->height[0]; - rho = MAX2(rho, max); - } - if (p) { - float dpdx = p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT]; - float dpdy = p[QUAD_TOP_LEFT] - p[QUAD_BOTTOM_LEFT]; - float max; - dpdx = fabsf(dpdx); - dpdy = fabsf(dpdy); - max = MAX2(dpdx, dpdy) * texture->depth[0]; - rho = MAX2(rho, max); - } +static float +compute_lambda_2d(const struct sp_sampler_varient *samp, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias) +{ + const struct pipe_texture *texture = samp->texture; + const struct pipe_sampler_state *sampler = samp->sampler; + float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]); + float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]); + float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]); + float dtdy = fabsf(t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]); + float maxx = MAX2(dsdx, dsdy) * texture->width[0]; + float maxy = MAX2(dtdx, dtdy) * texture->height[0]; + float rho = MAX2(maxx, maxy); + float lambda; lambda = util_fast_log2(rho); lambda += lodbias + sampler->lod_bias; @@ -573,88 +548,56 @@ compute_lambda(struct tgsi_sampler *tgsi_sampler, } -/** - * Do several things here: - * 1. Compute lambda from the texcoords, if needed - * 2. Determine if we're minifying or magnifying - * 3. If minifying, choose mipmap levels - * 4. Return image filter to use within mipmap images - * \param level0 Returns first mipmap level to sample from - * \param level1 Returns second mipmap level to sample from - * \param levelBlend Returns blend factor between levels, in [0,1] - * \param imgFilter Returns either the min or mag filter, depending on lambda - */ -static void -choose_mipmap_levels(struct tgsi_sampler *tgsi_sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - unsigned *level0, unsigned *level1, float *levelBlend, - unsigned *imgFilter) +static float +compute_lambda_3d(const struct sp_sampler_varient *samp, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias) { - const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); const struct pipe_texture *texture = samp->texture; const struct pipe_sampler_state *sampler = samp->sampler; + float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]); + float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]); + float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]); + float dtdy = fabsf(t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]); + float dpdx = fabsf(p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT]); + float dpdy = fabsf(p[QUAD_TOP_LEFT] - p[QUAD_BOTTOM_LEFT]); + float maxx = MAX2(dsdx, dsdy) * texture->width[0]; + float maxy = MAX2(dtdx, dtdy) * texture->height[0]; + float maxz = MAX2(dpdx, dpdy) * texture->depth[0]; + float rho, lambda; - if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { - /* no mipmap selection needed */ - *level0 = *level1 = CLAMP((int) sampler->min_lod, - 0, (int) texture->last_level); - - if (sampler->min_img_filter != sampler->mag_img_filter) { - /* non-mipmapped texture, but still need to determine if doing - * minification or magnification. - */ - float lambda = compute_lambda(tgsi_sampler, s, t, p, lodbias); - if (lambda <= 0.0) { - *imgFilter = sampler->mag_img_filter; - } - else { - *imgFilter = sampler->min_img_filter; - } - } - else { - *imgFilter = sampler->mag_img_filter; - } - } - else { - float lambda = compute_lambda(tgsi_sampler, s, t, p, lodbias); + rho = MAX2(maxx, maxy); + rho = MAX2(rho, maxz); - if (lambda <= 0.0) { /* XXX threshold depends on the filter */ - /* magnifying */ - *imgFilter = sampler->mag_img_filter; - *level0 = *level1 = 0; - } - else { - /* minifying */ - *imgFilter = sampler->min_img_filter; - - /* choose mipmap level(s) and compute the blend factor between them */ - if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) { - /* Nearest mipmap level */ - const int lvl = (int) (lambda + 0.5); - *level0 = - *level1 = CLAMP(lvl, 0, (int) texture->last_level); - } - else { - /* Linear interpolation between mipmap levels */ - const int lvl = (int) lambda; - *level0 = CLAMP(lvl, 0, (int) texture->last_level); - *level1 = CLAMP(lvl + 1, 0, (int) texture->last_level); - *levelBlend = FRAC(lambda); /* blending weight between levels */ - } - } - } + lambda = util_fast_log2(rho); + lambda += lodbias + sampler->lod_bias; + lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod); + + return lambda; } -/** - * Get a texel from a texture, using the texture tile cache. - * - * \param face the cube face in 0..5 - * \param level the mipmap level - * \param x the x coord of texel within 2D image + +static float +compute_lambda_vert(const struct sp_sampler_varient *samp, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias) +{ + return lodbias; +} + + + +/** + * Get a texel from a texture, using the texture tile cache. + * + * \param face the cube face in 0..5 + * \param level the mipmap level + * \param x the x coord of texel within 2D image * \param y the y coord of texel within 2D image * \param z which slice of a 3D texture * \param rgba the quad to put the texel/color into @@ -663,12 +606,12 @@ choose_mipmap_levels(struct tgsi_sampler *tgsi_sampler, * XXX maybe move this into sp_tile_cache.c and merge with the * sp_get_cached_tile_tex() function. Also, get 4 texels instead of 1... */ -static void +static INLINE void get_texel_quad_2d(const struct tgsi_sampler *tgsi_sampler, unsigned face, unsigned level, int x, int y, const float *out[4]) { - const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); + const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); const struct softpipe_cached_tile *tile = sp_get_cached_tile_tex(samp->cache, @@ -687,7 +630,7 @@ static INLINE const float * get_texel_2d_ptr(const struct tgsi_sampler *tgsi_sampler, unsigned face, unsigned level, int x, int y) { - const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); + const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); const struct softpipe_cached_tile *tile = sp_get_cached_tile_tex(samp->cache, @@ -700,7 +643,7 @@ get_texel_2d_ptr(const struct tgsi_sampler *tgsi_sampler, } -static void +static INLINE void get_texel_quad_2d_mt(const struct tgsi_sampler *tgsi_sampler, unsigned face, unsigned level, int x0, int y0, @@ -717,12 +660,12 @@ get_texel_quad_2d_mt(const struct tgsi_sampler *tgsi_sampler, } } -static void +static INLINE void get_texel(const struct tgsi_sampler *tgsi_sampler, unsigned face, unsigned level, int x, int y, int z, float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j) { - const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); + const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); const struct pipe_texture *texture = samp->texture; const struct pipe_sampler_state *sampler = samp->sampler; @@ -756,140 +699,18 @@ get_texel(const struct tgsi_sampler *tgsi_sampler, } -/** - * Compare texcoord 'p' (aka R) against texture value 'rgba[0]' - * When we sampled the depth texture, the depth value was put into all - * RGBA channels. We look at the red channel here. - * \param rgba quad of (depth) texel values - * \param p texture 'P' components for four pixels in quad - * \param j which pixel in the quad to test [0..3] - */ -static INLINE void -shadow_compare(const struct pipe_sampler_state *sampler, - float rgba[NUM_CHANNELS][QUAD_SIZE], - const float p[QUAD_SIZE], - uint j) -{ - int k; - switch (sampler->compare_func) { - case PIPE_FUNC_LESS: - k = p[j] < rgba[0][j]; - break; - case PIPE_FUNC_LEQUAL: - k = p[j] <= rgba[0][j]; - break; - case PIPE_FUNC_GREATER: - k = p[j] > rgba[0][j]; - break; - case PIPE_FUNC_GEQUAL: - k = p[j] >= rgba[0][j]; - break; - case PIPE_FUNC_EQUAL: - k = p[j] == rgba[0][j]; - break; - case PIPE_FUNC_NOTEQUAL: - k = p[j] != rgba[0][j]; - break; - case PIPE_FUNC_ALWAYS: - k = 1; - break; - case PIPE_FUNC_NEVER: - k = 0; - break; - default: - k = 0; - assert(0); - break; - } - /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */ - rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k; - rgba[3][j] = 1.0F; -} -/** - * As above, but do four z/texture comparisons. - */ static INLINE void -shadow_compare4(const struct pipe_sampler_state *sampler, - float rgba[NUM_CHANNELS][QUAD_SIZE], - const float p[QUAD_SIZE]) -{ - int j, k0, k1, k2, k3; - float val; - - /* compare four texcoords vs. four texture samples */ - switch (sampler->compare_func) { - case PIPE_FUNC_LESS: - k0 = p[0] < rgba[0][0]; - k1 = p[1] < rgba[0][1]; - k2 = p[2] < rgba[0][2]; - k3 = p[3] < rgba[0][3]; - break; - case PIPE_FUNC_LEQUAL: - k0 = p[0] <= rgba[0][0]; - k1 = p[1] <= rgba[0][1]; - k2 = p[2] <= rgba[0][2]; - k3 = p[3] <= rgba[0][3]; - break; - case PIPE_FUNC_GREATER: - k0 = p[0] > rgba[0][0]; - k1 = p[1] > rgba[0][1]; - k2 = p[2] > rgba[0][2]; - k3 = p[3] > rgba[0][3]; - break; - case PIPE_FUNC_GEQUAL: - k0 = p[0] >= rgba[0][0]; - k1 = p[1] >= rgba[0][1]; - k2 = p[2] >= rgba[0][2]; - k3 = p[3] >= rgba[0][3]; - break; - case PIPE_FUNC_EQUAL: - k0 = p[0] == rgba[0][0]; - k1 = p[1] == rgba[0][1]; - k2 = p[2] == rgba[0][2]; - k3 = p[3] == rgba[0][3]; - break; - case PIPE_FUNC_NOTEQUAL: - k0 = p[0] != rgba[0][0]; - k1 = p[1] != rgba[0][1]; - k2 = p[2] != rgba[0][2]; - k3 = p[3] != rgba[0][3]; - break; - case PIPE_FUNC_ALWAYS: - k0 = k1 = k2 = k3 = 1; - break; - case PIPE_FUNC_NEVER: - k0 = k1 = k2 = k3 = 0; - break; - default: - k0 = k1 = k2 = k3 = 0; - assert(0); - break; - } - - /* convert four pass/fail values to an intensity in [0,1] */ - val = 0.25F * (k0 + k1 + k2 + k3); - - /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */ - for (j = 0; j < 4; j++) { - rgba[0][j] = rgba[1][j] = rgba[2][j] = val; - rgba[3][j] = 1.0F; - } -} - - - -static void -sp_get_samples_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]) +img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) { - const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); + const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); unsigned j; unsigned level = samp->level; unsigned xpot = 1 << (samp->xpot - level); @@ -940,15 +761,15 @@ sp_get_samples_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, } -static void -sp_get_samples_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]) +static INLINE void +img_filter_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) { - const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); + const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); unsigned j; unsigned level = samp->level; unsigned xpot = 1 << (samp->xpot - level); @@ -975,15 +796,15 @@ sp_get_samples_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler, } -static void -sp_get_samples_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]) +static INLINE void +img_filter_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) { - const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); + const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); unsigned j; unsigned level = samp->level; unsigned xpot = 1 << (samp->xpot - level); @@ -1018,238 +839,78 @@ sp_get_samples_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler, } } - static void -sp_get_samples_2d_linear_mip_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]) +img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) { - struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); + const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); const struct pipe_texture *texture = samp->texture; - int level0; - float lambda; - - lambda = compute_lambda(tgsi_sampler, s, t, p, lodbias); - level0 = (int)lambda; + unsigned level0, j; + int width; + int x[4]; - if (lambda < 0.0) { - samp->level = 0; - sp_get_samples_2d_linear_repeat_POT( tgsi_sampler, - s, t, p, 0, rgba ); - } - else if (level0 >= texture->last_level) { - samp->level = texture->last_level; - sp_get_samples_2d_linear_repeat_POT( tgsi_sampler, - s, t, p, 0, rgba ); - } - else { - float levelBlend = lambda - level0; - float rgba0[4][4]; - float rgba1[4][4]; - int c,j; + level0 = samp->level; + width = texture->width[level0]; - samp->level = level0; - sp_get_samples_2d_linear_repeat_POT( tgsi_sampler, - s, t, p, 0, rgba0 ); + assert(width > 0); - samp->level = level0+1; - sp_get_samples_2d_linear_repeat_POT( tgsi_sampler, - s, t, p, 0, rgba1 ); + samp->nearest_texcoord_s(s, width, x); - for (j = 0; j < QUAD_SIZE; j++) { - for (c = 0; c < 4; c++) { - rgba[c][j] = lerp(levelBlend, rgba0[c][j], rgba1[c][j]); - } - } + for (j = 0; j < QUAD_SIZE; j++) { + get_texel(tgsi_sampler, 0, level0, x[j], 0, 0, rgba, j); } } -/** - * Common code for sampling 1D/2D/cube textures. - * Could probably extend for 3D... - */ + static void -sp_get_samples_2d_common(struct tgsi_sampler *tgsi_sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE], - const unsigned faces[4]) +img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) { - const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); + const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); const struct pipe_texture *texture = samp->texture; - const struct pipe_sampler_state *sampler = samp->sampler; - unsigned level0, level1, j, imgFilter; + const unsigned *faces = samp->faces; /* zero when not cube-mapping */ + unsigned level0, j; int width, height; - float levelBlend; - - choose_mipmap_levels(tgsi_sampler, s, t, p, - lodbias, - &level0, &level1, &levelBlend, &imgFilter); - - assert(sampler->normalized_coords); + int x[4], y[4]; + level0 = samp->level; width = texture->width[level0]; height = texture->height[level0]; assert(width > 0); - switch (imgFilter) { - case PIPE_TEX_FILTER_NEAREST: - { - int x[4], y[4]; - nearest_texcoord_4(sampler->wrap_s, s, width, x); - nearest_texcoord_4(sampler->wrap_t, t, height, y); - - for (j = 0; j < QUAD_SIZE; j++) { - get_texel(tgsi_sampler, faces[j], level0, x[j], y[j], 0, rgba, j); - if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { - shadow_compare(sampler, rgba, p, j); - } - - if (level0 != level1) { - /* get texels from second mipmap level and blend */ - float rgba2[4][4]; - unsigned c; - x[j] /= 2; - y[j] /= 2; - get_texel(tgsi_sampler, faces[j], level1, x[j], y[j], 0, - rgba2, j); - if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ - shadow_compare(sampler, rgba2, p, j); - } - - for (c = 0; c < NUM_CHANNELS; c++) { - rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]); - } - } - } - } - break; - case PIPE_TEX_FILTER_LINEAR: - case PIPE_TEX_FILTER_ANISO: - { - int x0[4], y0[4], x1[4], y1[4]; - float xw[4], yw[4]; /* weights */ - - linear_texcoord_4(sampler->wrap_s, s, width, x0, x1, xw); - linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw); - - for (j = 0; j < QUAD_SIZE; j++) { - float tx[4][4]; /* texels */ - int c; - get_texel(tgsi_sampler, faces[j], level0, x0[j], y0[j], 0, tx, 0); - get_texel(tgsi_sampler, faces[j], level0, x1[j], y0[j], 0, tx, 1); - get_texel(tgsi_sampler, faces[j], level0, x0[j], y1[j], 0, tx, 2); - get_texel(tgsi_sampler, faces[j], level0, x1[j], y1[j], 0, tx, 3); - if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { - shadow_compare4(sampler, tx, p); - } - - /* interpolate R, G, B, A */ - for (c = 0; c < 4; c++) { - rgba[c][j] = lerp_2d(xw[j], yw[j], - tx[c][0], tx[c][1], - tx[c][2], tx[c][3]); - } + samp->nearest_texcoord_s(s, width, x); + samp->nearest_texcoord_t(t, height, y); - if (level0 != level1) { - /* get texels from second mipmap level and blend */ - float rgba2[4][4]; - - /* XXX: This is incorrect -- will often end up with (x0 - * == x1 && y0 == y1), meaning that we fetch the same - * texel four times and linearly interpolate between - * identical values. The correct approach would be to - * call linear_texcoord again for the second level. - */ - x0[j] /= 2; - y0[j] /= 2; - x1[j] /= 2; - y1[j] /= 2; - get_texel(tgsi_sampler, faces[j], level1, x0[j], y0[j], 0, tx, 0); - get_texel(tgsi_sampler, faces[j], level1, x1[j], y0[j], 0, tx, 1); - get_texel(tgsi_sampler, faces[j], level1, x0[j], y1[j], 0, tx, 2); - get_texel(tgsi_sampler, faces[j], level1, x1[j], y1[j], 0, tx, 3); - if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ - shadow_compare4(sampler, tx, p); - } - - /* interpolate R, G, B, A */ - for (c = 0; c < 4; c++) { - rgba2[c][j] = lerp_2d(xw[j], yw[j], - tx[c][0], tx[c][1], tx[c][2], tx[c][3]); - } - - for (c = 0; c < NUM_CHANNELS; c++) { - rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]); - } - } - } - } - break; - default: - assert(0); + for (j = 0; j < QUAD_SIZE; j++) { + get_texel(tgsi_sampler, faces[j], level0, x[j], y[j], 0, rgba, j); } } -static INLINE void -sp_get_samples_1d(struct tgsi_sampler *sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]) -{ - static const unsigned faces[4] = {0, 0, 0, 0}; - static const float tzero[4] = {0, 0, 0, 0}; - sp_get_samples_2d_common(sampler, s, tzero, NULL, - lodbias, rgba, faces); -} - - -static INLINE void -sp_get_samples_2d(struct tgsi_sampler *sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]) -{ - static const unsigned faces[4] = {0, 0, 0, 0}; - sp_get_samples_2d_common(sampler, s, t, p, - lodbias, rgba, faces); -} - - -static INLINE void -sp_get_samples_3d(struct tgsi_sampler *tgsi_sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]) +static void +img_filter_3d_nearest(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) { - const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); + const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); const struct pipe_texture *texture = samp->texture; - const struct pipe_sampler_state *sampler = samp->sampler; - /* get/map pipe_surfaces corresponding to 3D tex slices */ - unsigned level0, level1, j, imgFilter; + unsigned level0, j; int width, height, depth; - float levelBlend; - const uint face = 0; - - choose_mipmap_levels(tgsi_sampler, s, t, p, - lodbias, - &level0, &level1, &levelBlend, &imgFilter); - - assert(sampler->normalized_coords); + int x[4], y[4], z[4]; + level0 = samp->level; width = texture->width[level0]; height = texture->height[level0]; depth = texture->depth[level0]; @@ -1258,323 +919,746 @@ sp_get_samples_3d(struct tgsi_sampler *tgsi_sampler, assert(height > 0); assert(depth > 0); - switch (imgFilter) { - case PIPE_TEX_FILTER_NEAREST: - { - int x[4], y[4], z[4]; - nearest_texcoord_4(sampler->wrap_s, s, width, x); - nearest_texcoord_4(sampler->wrap_t, t, height, y); - nearest_texcoord_4(sampler->wrap_r, p, depth, z); - for (j = 0; j < QUAD_SIZE; j++) { - get_texel(tgsi_sampler, face, level0, x[j], y[j], z[j], rgba, j); - if (level0 != level1) { - /* get texels from second mipmap level and blend */ - float rgba2[4][4]; - unsigned c; - x[j] /= 2; - y[j] /= 2; - z[j] /= 2; - get_texel(tgsi_sampler, face, level1, x[j], y[j], z[j], rgba2, j); - for (c = 0; c < NUM_CHANNELS; c++) { - rgba[c][j] = lerp(levelBlend, rgba2[c][j], rgba[c][j]); - } - } - } - } - break; - case PIPE_TEX_FILTER_LINEAR: - case PIPE_TEX_FILTER_ANISO: - { - int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4]; - float xw[4], yw[4], zw[4]; /* interpolation weights */ - linear_texcoord_4(sampler->wrap_s, s, width, x0, x1, xw); - linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw); - linear_texcoord_4(sampler->wrap_r, p, depth, z0, z1, zw); - - for (j = 0; j < QUAD_SIZE; j++) { - int c; - float tx0[4][4], tx1[4][4]; - get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z0[j], tx0, 0); - get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z0[j], tx0, 1); - get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z0[j], tx0, 2); - get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z0[j], tx0, 3); - get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z1[j], tx1, 0); - get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z1[j], tx1, 1); - get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z1[j], tx1, 2); - get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z1[j], tx1, 3); - - /* interpolate R, G, B, A */ - for (c = 0; c < 4; c++) { - rgba[c][j] = lerp_3d(xw[j], yw[j], zw[j], - tx0[c][0], tx0[c][1], - tx0[c][2], tx0[c][3], - tx1[c][0], tx1[c][1], - tx1[c][2], tx1[c][3]); - } + samp->nearest_texcoord_s(s, width, x); + samp->nearest_texcoord_t(t, height, y); + samp->nearest_texcoord_p(p, depth, z); - if (level0 != level1) { - /* get texels from second mipmap level and blend */ - float rgba2[4][4]; - x0[j] /= 2; - y0[j] /= 2; - z0[j] /= 2; - x1[j] /= 2; - y1[j] /= 2; - z1[j] /= 2; - get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z0[j], tx0, 0); - get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z0[j], tx0, 1); - get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z0[j], tx0, 2); - get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z0[j], tx0, 3); - get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z1[j], tx1, 0); - get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z1[j], tx1, 1); - get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z1[j], tx1, 2); - get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z1[j], tx1, 3); - - /* interpolate R, G, B, A */ - for (c = 0; c < 4; c++) { - rgba2[c][j] = lerp_3d(xw[j], yw[j], zw[j], - tx0[c][0], tx0[c][1], - tx0[c][2], tx0[c][3], - tx1[c][0], tx1[c][1], - tx1[c][2], tx1[c][3]); - } - - /* blend mipmap levels */ - for (c = 0; c < NUM_CHANNELS; c++) { - rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]); - } - } - } - } - break; - default: - assert(0); + for (j = 0; j < QUAD_SIZE; j++) { + get_texel(tgsi_sampler, 0, level0, x[j], y[j], z[j], rgba, j); } } static void -sp_get_samples_cube(struct tgsi_sampler *sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]) +img_filter_1d_linear(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) { - unsigned faces[QUAD_SIZE], j; - float ssss[4], tttt[4]; + const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + const struct pipe_texture *texture = samp->texture; + unsigned level0, j; + int width; + int x0[4], x1[4]; + float xw[4]; /* weights */ + + + level0 = samp->level; + width = texture->width[level0]; + + assert(width > 0); + + samp->linear_texcoord_s(s, width, x0, x1, xw); + + for (j = 0; j < QUAD_SIZE; j++) { - faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j); + float tx[4][4]; /* texels */ + int c; + get_texel(tgsi_sampler, 0, level0, x0[j], 0, 0, tx, 0); + get_texel(tgsi_sampler, 0, level0, x1[j], 0, 0, tx, 1); + + /* interpolate R, G, B, A */ + for (c = 0; c < 4; c++) { + rgba[c][j] = lerp(xw[j], tx[c][0], tx[c][1]); + } } - sp_get_samples_2d_common(sampler, ssss, tttt, NULL, - lodbias, rgba, faces); } - static void -sp_get_samples_rect(struct tgsi_sampler *tgsi_sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]) +img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) { - const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); + const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); const struct pipe_texture *texture = samp->texture; - const struct pipe_sampler_state *sampler = samp->sampler; - const uint face = 0; - unsigned level0, level1, j, imgFilter; + const unsigned *faces = samp->faces; /* zero when not cube-mapping */ + unsigned level0, j; int width, height; - float levelBlend; + int x0[4], y0[4], x1[4], y1[4]; + float xw[4], yw[4]; /* weights */ - choose_mipmap_levels(tgsi_sampler, s, t, p, - lodbias, - &level0, &level1, &levelBlend, &imgFilter); - - /* texture RECTS cannot be mipmapped */ - assert(level0 == level1); + level0 = samp->level; width = texture->width[level0]; height = texture->height[level0]; assert(width > 0); - switch (imgFilter) { - case PIPE_TEX_FILTER_NEAREST: - { - int x[4], y[4]; - nearest_texcoord_unnorm_4(sampler->wrap_s, s, width, x); - nearest_texcoord_unnorm_4(sampler->wrap_t, t, height, y); - for (j = 0; j < QUAD_SIZE; j++) { - get_texel(tgsi_sampler, face, level0, x[j], y[j], 0, rgba, j); - if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { - shadow_compare(sampler, rgba, p, j); - } - } + samp->linear_texcoord_s(s, width, x0, x1, xw); + samp->linear_texcoord_s(t, height, y0, y1, yw); + + for (j = 0; j < QUAD_SIZE; j++) { + float tx[4][4]; /* texels */ + int c; + get_texel(tgsi_sampler, faces[j], level0, x0[j], y0[j], 0, tx, 0); + get_texel(tgsi_sampler, faces[j], level0, x1[j], y0[j], 0, tx, 1); + get_texel(tgsi_sampler, faces[j], level0, x0[j], y1[j], 0, tx, 2); + get_texel(tgsi_sampler, faces[j], level0, x1[j], y1[j], 0, tx, 3); + + /* interpolate R, G, B, A */ + for (c = 0; c < 4; c++) { + rgba[c][j] = lerp_2d(xw[j], yw[j], + tx[c][0], tx[c][1], + tx[c][2], tx[c][3]); } - break; - case PIPE_TEX_FILTER_LINEAR: - case PIPE_TEX_FILTER_ANISO: - { - int x0[4], y0[4], x1[4], y1[4]; - float xw[4], yw[4]; /* weights */ - linear_texcoord_unnorm_4(sampler->wrap_s, s, width, x0, x1, xw); - linear_texcoord_unnorm_4(sampler->wrap_t, t, height, y0, y1, yw); - for (j = 0; j < QUAD_SIZE; j++) { - float tx[4][4]; /* texels */ - int c; - get_texel(tgsi_sampler, face, level0, x0[j], y0[j], 0, tx, 0); - get_texel(tgsi_sampler, face, level0, x1[j], y0[j], 0, tx, 1); - get_texel(tgsi_sampler, face, level0, x0[j], y1[j], 0, tx, 2); - get_texel(tgsi_sampler, face, level0, x1[j], y1[j], 0, tx, 3); - if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { - shadow_compare4(sampler, tx, p); - } - for (c = 0; c < 4; c++) { - rgba[c][j] = lerp_2d(xw[j], yw[j], - tx[c][0], tx[c][1], tx[c][2], tx[c][3]); - } + } +} + + +static void +img_filter_3d_linear(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + const struct pipe_texture *texture = samp->texture; + unsigned level0, j; + int width, height, depth; + int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4]; + float xw[4], yw[4], zw[4]; /* interpolation weights */ + + level0 = samp->level; + width = texture->width[level0]; + height = texture->height[level0]; + depth = texture->depth[level0]; + + assert(width > 0); + assert(height > 0); + assert(depth > 0); + + samp->linear_texcoord_s(s, width, x0, x1, xw); + samp->linear_texcoord_s(t, height, y0, y1, yw); + samp->linear_texcoord_s(p, depth, z0, z1, zw); + + for (j = 0; j < QUAD_SIZE; j++) { + float tx0[4][4], tx1[4][4]; + int c; + + get_texel(tgsi_sampler, 0, level0, x0[j], y0[j], z0[j], tx0, 0); + get_texel(tgsi_sampler, 0, level0, x1[j], y0[j], z0[j], tx0, 1); + get_texel(tgsi_sampler, 0, level0, x0[j], y1[j], z0[j], tx0, 2); + get_texel(tgsi_sampler, 0, level0, x1[j], y1[j], z0[j], tx0, 3); + get_texel(tgsi_sampler, 0, level0, x0[j], y0[j], z1[j], tx1, 0); + get_texel(tgsi_sampler, 0, level0, x1[j], y0[j], z1[j], tx1, 1); + get_texel(tgsi_sampler, 0, level0, x0[j], y1[j], z1[j], tx1, 2); + get_texel(tgsi_sampler, 0, level0, x1[j], y1[j], z1[j], tx1, 3); + + /* interpolate R, G, B, A */ + for (c = 0; c < 4; c++) { + rgba[c][j] = lerp_3d(xw[j], yw[j], zw[j], + tx0[c][0], tx0[c][1], + tx0[c][2], tx0[c][3], + tx1[c][0], tx1[c][1], + tx1[c][2], tx1[c][3]); + } + } +} + + + + + + + +static void +mip_filter_linear(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + const struct pipe_texture *texture = samp->texture; + int level0; + float lambda; + + lambda = samp->compute_lambda(samp, s, t, p, lodbias); + level0 = (int)lambda; + + if (lambda < 0.0) { + samp->level = 0; + samp->mag_img_filter( tgsi_sampler, s, t, p, 0, rgba ); + } + else if (level0 >= texture->last_level) { + samp->level = texture->last_level; + samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba ); + } + else { + float levelBlend = lambda - level0; + float rgba0[4][4]; + float rgba1[4][4]; + int c,j; + + samp->level = level0; + samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba0 ); + + samp->level = level0+1; + samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba1 ); + + for (j = 0; j < QUAD_SIZE; j++) { + for (c = 0; c < 4; c++) { + rgba[c][j] = lerp(levelBlend, rgba0[c][j], rgba1[c][j]); } } - break; - default: - assert(0); } } -/** - * Error condition handler + +static void +mip_filter_nearest(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + const struct pipe_texture *texture = samp->texture; + float lambda; + + lambda = samp->compute_lambda(samp, s, t, p, lodbias); + + if (lambda < 0.0) { + samp->level = 0; + samp->mag_img_filter( tgsi_sampler, s, t, p, 0, rgba ); + } + else { + samp->level = (int)(lambda + 0.5) ; + samp->level = MIN2(samp->level, (int)texture->last_level); + samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba ); + } +} + + +static void +mip_filter_none(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + float lambda = samp->compute_lambda(samp, s, t, p, lodbias); + + if (lambda < 0.0) { + samp->mag_img_filter( tgsi_sampler, s, t, p, 0, rgba ); + } + else { + samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba ); + } +} + + + +/* Specialized version of mip_filter_linear with hard-wired calls to + * 2d lambda calculation and 2d_linear_repeat_POT img filters. */ -static INLINE void -sp_get_samples_null(struct tgsi_sampler *tgsi_sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]) +static void +mip_filter_linear_2d_linear_repeat_POT( + struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) { - int i,j; + struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + const struct pipe_texture *texture = samp->texture; + int level0; + float lambda; - for (i = 0; i < 4; i++) - for (j = 0; j < 4; j++) - rgba[i][j] = 1.0; + lambda = compute_lambda_2d(samp, s, t, p, lodbias); + level0 = (int)lambda; + + /* Catches both negative and large values of level0: + */ + if ((unsigned)level0 >= texture->last_level) { + if (level0 < 0) + samp->level = 0; + else + samp->level = texture->last_level; + + img_filter_2d_linear_repeat_POT( tgsi_sampler, s, t, p, 0, rgba ); + } + else { + float levelBlend = lambda - level0; + float rgba0[4][4]; + float rgba1[4][4]; + int c,j; + + samp->level = level0; + img_filter_2d_linear_repeat_POT( tgsi_sampler, s, t, p, 0, rgba0 ); + + samp->level = level0+1; + img_filter_2d_linear_repeat_POT( tgsi_sampler, s, t, p, 0, rgba1 ); + + for (j = 0; j < QUAD_SIZE; j++) { + for (c = 0; c < 4; c++) { + rgba[c][j] = lerp(levelBlend, rgba0[c][j], rgba1[c][j]); + } + } + } } -/** - * Called via tgsi_sampler::get_samples() when using a sampler for the - * first time. Determine the actual sampler function, link it in and - * call it. + + +/* Compare stage in the little sampling pipeline. */ -void -sp_get_samples(struct tgsi_sampler *tgsi_sampler, +static void +sample_compare(struct tgsi_sampler *tgsi_sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], float lodbias, float rgba[NUM_CHANNELS][QUAD_SIZE]) { - struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); const struct pipe_sampler_state *sampler = samp->sampler; + int j, k0, k1, k2, k3; + float val; - /* Default to the 'undefined' case: - */ - tgsi_sampler->get_samples = sp_get_samples_null; + samp->mip_filter( tgsi_sampler, s, t, p, lodbias, rgba ); - if (!texture) { - assert(0); /* is this legal?? */ - goto out; - } - if (!sampler->normalized_coords) { - assert (texture->target == PIPE_TEXTURE_2D); - tgsi_sampler->get_samples = sp_get_samples_rect; - goto out; - } + /** + * Compare texcoord 'p' (aka R) against texture value 'rgba[0]' + * When we sampled the depth texture, the depth value was put into all + * RGBA channels. We look at the red channel here. + */ - switch (texture->target) { - case PIPE_TEXTURE_1D: - tgsi_sampler->get_samples = sp_get_samples_1d; + /* compare four texcoords vs. four texture samples */ + switch (sampler->compare_func) { + case PIPE_FUNC_LESS: + k0 = p[0] < rgba[0][0]; + k1 = p[1] < rgba[0][1]; + k2 = p[2] < rgba[0][2]; + k3 = p[3] < rgba[0][3]; break; - case PIPE_TEXTURE_2D: - tgsi_sampler->get_samples = sp_get_samples_2d; + case PIPE_FUNC_LEQUAL: + k0 = p[0] <= rgba[0][0]; + k1 = p[1] <= rgba[0][1]; + k2 = p[2] <= rgba[0][2]; + k3 = p[3] <= rgba[0][3]; break; - case PIPE_TEXTURE_3D: - tgsi_sampler->get_samples = sp_get_samples_3d; + case PIPE_FUNC_GREATER: + k0 = p[0] > rgba[0][0]; + k1 = p[1] > rgba[0][1]; + k2 = p[2] > rgba[0][2]; + k3 = p[3] > rgba[0][3]; break; - case PIPE_TEXTURE_CUBE: - tgsi_sampler->get_samples = sp_get_samples_cube; + case PIPE_FUNC_GEQUAL: + k0 = p[0] >= rgba[0][0]; + k1 = p[1] >= rgba[0][1]; + k2 = p[2] >= rgba[0][2]; + k3 = p[3] >= rgba[0][3]; + break; + case PIPE_FUNC_EQUAL: + k0 = p[0] == rgba[0][0]; + k1 = p[1] == rgba[0][1]; + k2 = p[2] == rgba[0][2]; + k3 = p[3] == rgba[0][3]; + break; + case PIPE_FUNC_NOTEQUAL: + k0 = p[0] != rgba[0][0]; + k1 = p[1] != rgba[0][1]; + k2 = p[2] != rgba[0][2]; + k3 = p[3] != rgba[0][3]; + break; + case PIPE_FUNC_ALWAYS: + k0 = k1 = k2 = k3 = 1; + break; + case PIPE_FUNC_NEVER: + k0 = k1 = k2 = k3 = 0; break; default: + k0 = k1 = k2 = k3 = 0; assert(0); break; } - /* Do this elsewhere: - */ - samp->xpot = util_unsigned_logbase2( samp->texture->width[0] ); - samp->ypot = util_unsigned_logbase2( samp->texture->height[0] ); + /* convert four pass/fail values to an intensity in [0,1] */ + val = 0.25F * (k0 + k1 + k2 + k3); + + /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */ + for (j = 0; j < 4; j++) { + rgba[0][j] = rgba[1][j] = rgba[2][j] = val; + rgba[3][j] = 1.0F; + } +} + +/* Calculate cube faces. + */ +static void +sample_cube(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + unsigned j; + float ssss[4], tttt[4]; + + /* + major axis + direction target sc tc ma + ---------- ------------------------------- --- --- --- + +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx + -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx + +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry + -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry + +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz + -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz + */ + for (j = 0; j < QUAD_SIZE; j++) { + float rx = s[j]; + float ry = t[j]; + float rz = p[j]; + const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz); + unsigned face; + float sc, tc, ma; + + if (arx > ary && arx > arz) { + if (rx >= 0.0F) { + face = PIPE_TEX_FACE_POS_X; + sc = -rz; + tc = -ry; + ma = arx; + } + else { + face = PIPE_TEX_FACE_NEG_X; + sc = rz; + tc = -ry; + ma = arx; + } + } + else if (ary > arx && ary > arz) { + if (ry >= 0.0F) { + face = PIPE_TEX_FACE_POS_Y; + sc = rx; + tc = rz; + ma = ary; + } + else { + face = PIPE_TEX_FACE_NEG_Y; + sc = rx; + tc = -rz; + ma = ary; + } + } + else { + if (rz > 0.0F) { + face = PIPE_TEX_FACE_POS_Z; + sc = rx; + tc = -ry; + ma = arz; + } + else { + face = PIPE_TEX_FACE_NEG_Z; + sc = -rx; + tc = -ry; + ma = arz; + } + } + + ssss[j] = ( sc / ma + 1.0F ) * 0.5F; + tttt[j] = ( tc / ma + 1.0F ) * 0.5F; + samp->faces[j] = face; + } - /* Try to hook in a faster sampler. Ultimately we'll have to - * code-generate these. Luckily most of this looks like it is - * orthogonal state within the sampler. + /* In our little pipeline, the compare stage is next. If compare + * is not active, this will point somewhere deeper into the + * pipeline, eg. to mip_filter or even img_filter. */ - if (texture->target == PIPE_TEXTURE_2D && - sampler->min_img_filter == sampler->mag_img_filter && - sampler->wrap_s == sampler->wrap_t && - sampler->compare_mode == FALSE && - sampler->normalized_coords) - { - if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { - samp->level = CLAMP((int) sampler->min_lod, - 0, (int) texture->last_level); - - if (sampler->wrap_s == PIPE_TEX_WRAP_REPEAT) { - switch (sampler->min_img_filter) { + samp->compare(tgsi_sampler, ssss, tttt, NULL, lodbias, rgba); +} + + + + +static wrap_nearest_func get_nearest_unorm_wrap( unsigned mode ) +{ + switch (mode) { + case PIPE_TEX_WRAP_CLAMP: + return wrap_nearest_unorm_clamp; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + return wrap_nearest_unorm_clamp_to_border; + default: + assert(0); + return wrap_nearest_unorm_clamp; + } +} + + +static wrap_nearest_func get_nearest_wrap( unsigned mode ) +{ + switch (mode) { + case PIPE_TEX_WRAP_REPEAT: + return wrap_nearest_repeat; + case PIPE_TEX_WRAP_CLAMP: + return wrap_nearest_clamp; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + return wrap_nearest_clamp_to_edge; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + return wrap_nearest_clamp_to_border; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + return wrap_nearest_mirror_repeat; + case PIPE_TEX_WRAP_MIRROR_CLAMP: + return wrap_nearest_mirror_clamp; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: + return wrap_nearest_mirror_clamp_to_edge; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: + return wrap_nearest_mirror_clamp_to_border; + default: + assert(0); + return wrap_nearest_repeat; + } +} + +static wrap_linear_func get_linear_unorm_wrap( unsigned mode ) +{ + switch (mode) { + case PIPE_TEX_WRAP_CLAMP: + return wrap_linear_unorm_clamp; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + return wrap_linear_unorm_clamp_to_border; + default: + assert(0); + return wrap_linear_unorm_clamp; + } +} + +static wrap_linear_func get_linear_wrap( unsigned mode ) +{ + switch (mode) { + case PIPE_TEX_WRAP_REPEAT: + return wrap_linear_repeat; + case PIPE_TEX_WRAP_CLAMP: + return wrap_linear_clamp; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + return wrap_linear_clamp_to_edge; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + return wrap_linear_clamp_to_border; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + return wrap_linear_mirror_repeat; + case PIPE_TEX_WRAP_MIRROR_CLAMP: + return wrap_linear_mirror_clamp; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: + return wrap_linear_mirror_clamp_to_edge; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: + return wrap_linear_mirror_clamp_to_border; + default: + assert(0); + return wrap_linear_repeat; + } +} + +static compute_lambda_func get_lambda_func( const union sp_sampler_key key ) +{ + if (key.bits.processor == TGSI_PROCESSOR_VERTEX) + return compute_lambda_vert; + + switch (key.bits.target) { + case PIPE_TEXTURE_1D: + return compute_lambda_1d; + case PIPE_TEXTURE_2D: + return compute_lambda_2d; + case PIPE_TEXTURE_3D: + return compute_lambda_3d; + default: + assert(0); + return compute_lambda_1d; + } +} + +static filter_func get_img_filter( const union sp_sampler_key key, + unsigned filter, + const struct pipe_sampler_state *sampler ) +{ + switch (key.bits.target) { + case PIPE_TEXTURE_1D: + if (filter == PIPE_TEX_FILTER_NEAREST) + return img_filter_1d_nearest; + else + return img_filter_1d_linear; + break; + case PIPE_TEXTURE_2D: + /* Try for fast path: + */ + if (key.bits.is_pot && + sampler->wrap_s == sampler->wrap_t && + sampler->normalized_coords) + { + switch (sampler->wrap_s) { + case PIPE_TEX_WRAP_REPEAT: + switch (filter) { case PIPE_TEX_FILTER_NEAREST: - tgsi_sampler->get_samples = sp_get_samples_2d_nearest_repeat_POT; - break; + return img_filter_2d_nearest_repeat_POT; case PIPE_TEX_FILTER_LINEAR: - tgsi_sampler->get_samples = sp_get_samples_2d_linear_repeat_POT; - break; + return img_filter_2d_linear_repeat_POT; default: break; } - } - else if (sampler->wrap_s == PIPE_TEX_WRAP_CLAMP) { - switch (sampler->min_img_filter) { + break; + case PIPE_TEX_WRAP_CLAMP: + switch (filter) { case PIPE_TEX_FILTER_NEAREST: - tgsi_sampler->get_samples = sp_get_samples_2d_nearest_clamp_POT; - break; + return img_filter_2d_nearest_clamp_POT; default: break; } } } - else if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_LINEAR) { - if (sampler->wrap_s == PIPE_TEX_WRAP_REPEAT) { - switch (sampler->min_img_filter) { - case PIPE_TEX_FILTER_LINEAR: - tgsi_sampler->get_samples = sp_get_samples_2d_linear_mip_linear_repeat_POT; - break; - default: - break; - } - } + /* Fallthrough to default versions: + */ + case PIPE_TEXTURE_CUBE: + if (filter == PIPE_TEX_FILTER_NEAREST) + return img_filter_2d_nearest; + else + return img_filter_2d_linear; + break; + case PIPE_TEXTURE_3D: + if (filter == PIPE_TEX_FILTER_NEAREST) + return img_filter_3d_nearest; + else + return img_filter_3d_linear; + break; + default: + assert(0); + return img_filter_1d_nearest; + } +} + + +void +sp_sampler_varient_bind_texture( struct sp_sampler_varient *samp, + struct softpipe_tile_cache *tex_cache, + const struct pipe_texture *texture ) +{ + const struct pipe_sampler_state *sampler = samp->sampler; + + samp->texture = texture; + samp->cache = tex_cache; + samp->xpot = util_unsigned_logbase2( texture->width[0] ); + samp->ypot = util_unsigned_logbase2( texture->height[0] ); + samp->level = CLAMP((int) sampler->min_lod, 0, (int) texture->last_level); +} + +/* Create a sampler varient for a given set of non-orthogonal state. Currently the + */ +struct sp_sampler_varient * +sp_create_sampler_varient( const struct pipe_sampler_state *sampler, + const union sp_sampler_key key ) +{ + struct sp_sampler_varient *samp = CALLOC_STRUCT(sp_sampler_varient); + if (!samp) + return NULL; + + samp->sampler = sampler; + samp->key = key; + + /* Note that (for instance) linear_texcoord_s and + * nearest_texcoord_s may be active at the same time, if the + * sampler min_img_filter differs from its mag_img_filter. + */ + if (sampler->normalized_coords) { + samp->linear_texcoord_s = get_linear_wrap( sampler->wrap_s ); + samp->linear_texcoord_t = get_linear_wrap( sampler->wrap_t ); + samp->linear_texcoord_p = get_linear_wrap( sampler->wrap_r ); + + samp->nearest_texcoord_s = get_nearest_wrap( sampler->wrap_s ); + samp->nearest_texcoord_t = get_nearest_wrap( sampler->wrap_t ); + samp->nearest_texcoord_p = get_nearest_wrap( sampler->wrap_r ); + } + else { + samp->linear_texcoord_s = get_linear_unorm_wrap( sampler->wrap_s ); + samp->linear_texcoord_t = get_linear_unorm_wrap( sampler->wrap_t ); + samp->linear_texcoord_p = get_linear_unorm_wrap( sampler->wrap_r ); + + samp->nearest_texcoord_s = get_nearest_unorm_wrap( sampler->wrap_s ); + samp->nearest_texcoord_t = get_nearest_unorm_wrap( sampler->wrap_t ); + samp->nearest_texcoord_p = get_nearest_unorm_wrap( sampler->wrap_r ); + } + + samp->compute_lambda = get_lambda_func( key ); + + samp->min_img_filter = get_img_filter(key, sampler->min_img_filter, sampler); + samp->mag_img_filter = get_img_filter(key, sampler->min_img_filter, sampler); + + switch (sampler->min_mip_filter) { + case PIPE_TEX_MIPFILTER_NONE: + if (sampler->min_img_filter == sampler->mag_img_filter) + samp->mip_filter = samp->min_img_filter; + else + samp->mip_filter = mip_filter_none; + break; + + case PIPE_TEX_MIPFILTER_NEAREST: + samp->mip_filter = mip_filter_nearest; + break; + + case PIPE_TEX_MIPFILTER_LINEAR: + if (key.bits.is_pot && + sampler->min_img_filter == sampler->mag_img_filter && + sampler->wrap_s == sampler->wrap_t && + sampler->normalized_coords && + sampler->wrap_s == sampler->wrap_t && + sampler->wrap_s == PIPE_TEX_WRAP_REPEAT && + sampler->min_img_filter == PIPE_TEX_FILTER_LINEAR) + { + samp->mip_filter = mip_filter_linear_2d_linear_repeat_POT; + } + else + { + samp->mip_filter = mip_filter_linear; } + break; + } + + if (sampler->compare_mode != FALSE) { + samp->compare = sample_compare; } - else if (0) { - _debug_printf("target %d/%d min_mip %d/%d min_img %d/%d wrap %d/%d compare %d/%d norm %d/%d\n", - texture->target, PIPE_TEXTURE_2D, - sampler->min_mip_filter, PIPE_TEX_MIPFILTER_NONE, - sampler->min_img_filter, sampler->mag_img_filter, - sampler->wrap_s, sampler->wrap_t, - sampler->compare_mode, FALSE, - sampler->normalized_coords, TRUE); + else { + /* Skip compare operation by promoting the mip_filter function + * pointer: + */ + samp->compare = samp->mip_filter; + } + + if (key.bits.target == PIPE_TEXTURE_CUBE) { + samp->base.get_samples = sample_cube; + } + else { + samp->faces[0] = 0; + samp->faces[1] = 0; + samp->faces[2] = 0; + samp->faces[3] = 0; + + /* Skip cube face determination by promoting the compare + * function pointer: + */ + samp->base.get_samples = samp->compare; } -out: - tgsi_sampler->get_samples( tgsi_sampler, s, t, p, lodbias, rgba ); + return samp; } + + + + + diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h index c73ae441314..26f80eb88a8 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.h +++ b/src/gallium/drivers/softpipe/sp_tex_sample.h @@ -31,14 +31,61 @@ #include "tgsi/tgsi_exec.h" +struct sp_sampler_varient; + +typedef void (*wrap_nearest_func)(const float s[4], + unsigned size, + int icoord[4]); + +typedef void (*wrap_linear_func)(const float s[4], + unsigned size, + int icoord0[4], + int icoord1[4], + float w[4]); + +typedef float (*compute_lambda_func)(const struct sp_sampler_varient *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias); + +typedef void (*filter_func)(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]); + + +union sp_sampler_key { + struct { + unsigned target:3; + unsigned is_pot:1; + unsigned processor:2; + unsigned pad:26; + } bits; + unsigned value; +}; /** * Subclass of tgsi_sampler */ -struct sp_shader_sampler +struct sp_sampler_varient { struct tgsi_sampler base; /**< base class */ + union sp_sampler_key key; + + /* The owner of this struct: + */ + const struct pipe_sampler_state *sampler; + + + /* Currently bound texture: + */ + const struct pipe_texture *texture; + struct softpipe_tile_cache *cache; + unsigned processor; /* For sp_get_samples_2d_linear_POT: @@ -47,22 +94,51 @@ struct sp_shader_sampler unsigned ypot; unsigned level; - const struct pipe_texture *texture; - const struct pipe_sampler_state *sampler; + unsigned faces[4]; + + wrap_nearest_func nearest_texcoord_s; + wrap_nearest_func nearest_texcoord_t; + wrap_nearest_func nearest_texcoord_p; - struct softpipe_tile_cache *cache; + wrap_linear_func linear_texcoord_s; + wrap_linear_func linear_texcoord_t; + wrap_linear_func linear_texcoord_p; + + filter_func min_img_filter; + filter_func mag_img_filter; + + compute_lambda_func compute_lambda; + + filter_func mip_filter; + filter_func compare; + + /* Linked list: + */ + struct sp_sampler_varient *next; }; +struct sp_sampler; + +/* Create a sampler varient for a given set of non-orthogonal state. Currently the + */ +struct sp_sampler_varient * +sp_create_sampler_varient( const struct pipe_sampler_state *sampler, + const union sp_sampler_key key ); +void sp_sampler_varient_bind_texture( struct sp_sampler_varient *varient, + struct softpipe_tile_cache *tex_cache, + const struct pipe_texture *tex ); -static INLINE struct sp_shader_sampler * -sp_shader_sampler(const struct tgsi_sampler *sampler) -{ - return (struct sp_shader_sampler *) sampler; -} +void sp_sampler_varient_destroy( struct sp_sampler_varient * ); +static INLINE struct sp_sampler_varient * +sp_sampler_varient(const struct tgsi_sampler *sampler) +{ + return (struct sp_sampler_varient *) sampler; +} + extern void sp_get_samples(struct tgsi_sampler *tgsi_sampler, const float s[QUAD_SIZE], diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 0c84375bf10..a3a54dada4a 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -120,16 +120,20 @@ softpipe_displaytarget_layout(struct pipe_screen *screen, static struct pipe_texture * softpipe_texture_create(struct pipe_screen *screen, - const struct pipe_texture *templat) + const struct pipe_texture *template) { struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture); if (!spt) return NULL; - spt->base = *templat; + spt->base = *template; pipe_reference_init(&spt->base.reference, 1); spt->base.screen = screen; + spt->pot = (util_is_power_of_two(template->width[0]) && + util_is_power_of_two(template->height[0]) && + util_is_power_of_two(template->depth[0])); + if (spt->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { if (!softpipe_displaytarget_layout(screen, spt)) goto fail; diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h index 42df722a2d1..4dd0c1239e2 100644 --- a/src/gallium/drivers/softpipe/sp_texture.h +++ b/src/gallium/drivers/softpipe/sp_texture.h @@ -48,6 +48,10 @@ struct softpipe_texture */ struct pipe_buffer *buffer; + /* True if texture images are power-of-two in all dimensions: + */ + boolean pot; + unsigned timestamp; }; -- cgit v1.2.3 From 4e5c385d2183e7006c9d7ac0823919156bd4b8e6 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 21 Aug 2009 11:40:33 -0600 Subject: softpipe: fix s/t/p typos --- src/gallium/drivers/softpipe/sp_tex_sample.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 7bc689a298f..a6267311052 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -990,7 +990,7 @@ img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler, assert(width > 0); samp->linear_texcoord_s(s, width, x0, x1, xw); - samp->linear_texcoord_s(t, height, y0, y1, yw); + samp->linear_texcoord_t(t, height, y0, y1, yw); for (j = 0; j < QUAD_SIZE; j++) { float tx[4][4]; /* texels */ @@ -1035,8 +1035,8 @@ img_filter_3d_linear(struct tgsi_sampler *tgsi_sampler, assert(depth > 0); samp->linear_texcoord_s(s, width, x0, x1, xw); - samp->linear_texcoord_s(t, height, y0, y1, yw); - samp->linear_texcoord_s(p, depth, z0, z1, zw); + samp->linear_texcoord_t(t, height, y0, y1, yw); + samp->linear_texcoord_p(p, depth, z0, z1, zw); for (j = 0; j < QUAD_SIZE; j++) { float tx0[4][4], tx1[4][4]; -- cgit v1.2.3 From 41483627f0fd3dc9df2cc55dfd5f3e5987fcfd22 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 21 Aug 2009 11:41:29 -0600 Subject: softpipe: fix min/mag filter typo --- src/gallium/drivers/softpipe/sp_tex_sample.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index a6267311052..9502b60479d 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -1597,7 +1597,7 @@ sp_create_sampler_varient( const struct pipe_sampler_state *sampler, samp->compute_lambda = get_lambda_func( key ); samp->min_img_filter = get_img_filter(key, sampler->min_img_filter, sampler); - samp->mag_img_filter = get_img_filter(key, sampler->min_img_filter, sampler); + samp->mag_img_filter = get_img_filter(key, sampler->mag_img_filter, sampler); switch (sampler->min_mip_filter) { case PIPE_TEX_MIPFILTER_NONE: -- cgit v1.2.3 From cf102b031e7ef33c8e3ffce2f9dcd064f44e8190 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 21 Aug 2009 11:43:48 -0600 Subject: softpipe: remove redundant comparison, make test easier to understand --- src/gallium/drivers/softpipe/sp_tex_sample.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 9502b60479d..51118ae38bd 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -1614,10 +1614,9 @@ sp_create_sampler_varient( const struct pipe_sampler_state *sampler, case PIPE_TEX_MIPFILTER_LINEAR: if (key.bits.is_pot && sampler->min_img_filter == sampler->mag_img_filter && - sampler->wrap_s == sampler->wrap_t && sampler->normalized_coords && - sampler->wrap_s == sampler->wrap_t && sampler->wrap_s == PIPE_TEX_WRAP_REPEAT && + sampler->wrap_t == PIPE_TEX_WRAP_REPEAT && sampler->min_img_filter == PIPE_TEX_FILTER_LINEAR) { samp->mip_filter = mip_filter_linear_2d_linear_repeat_POT; -- cgit v1.2.3 From ecfa8be150ed276af816467b467e76e026f5b541 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 21 Aug 2009 18:44:27 +0100 Subject: softpipe: add missing sp_sampler_varient_destroy --- src/gallium/drivers/softpipe/sp_tex_sample.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 51118ae38bd..a2e2a221e4b 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -1558,6 +1558,14 @@ sp_sampler_varient_bind_texture( struct sp_sampler_varient *samp, samp->level = CLAMP((int) sampler->min_lod, 0, (int) texture->last_level); } + +void +sp_sampler_varient_destroy( struct sp_sampler_varient *samp ) +{ + FREE(samp); +} + + /* Create a sampler varient for a given set of non-orthogonal state. Currently the */ struct sp_sampler_varient * -- cgit v1.2.3 From 87ec83afd58536c31bf02c307f1d5488abc84861 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 21 Aug 2009 11:47:27 -0600 Subject: softpipe: add missing PIPE_TEXTURE_CUBE case in get_lambda_func() Fixes progs/demos/cubemap --- src/gallium/drivers/softpipe/sp_tex_sample.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index a2e2a221e4b..f3710037082 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -1476,6 +1476,7 @@ static compute_lambda_func get_lambda_func( const union sp_sampler_key key ) case PIPE_TEXTURE_1D: return compute_lambda_1d; case PIPE_TEXTURE_2D: + case PIPE_TEXTURE_CUBE: return compute_lambda_2d; case PIPE_TEXTURE_3D: return compute_lambda_3d; -- cgit v1.2.3 From a29447c33d44b3427e0c40a761067c0cc6e71c39 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 21 Aug 2009 12:11:44 -0600 Subject: softpipe: per-unit sampler varients Can't share sampler varients across multiple tex units because the texture pointer is in the sampler varient. That prevents different textures per unit. Fixes progs/demos/multiarb, progs/glsl/samplers, etc. --- src/gallium/drivers/softpipe/sp_state_sampler.c | 24 ++++++++++++++++++++---- src/gallium/drivers/softpipe/sp_tex_sample.c | 3 +++ src/gallium/drivers/softpipe/sp_tex_sample.h | 3 ++- 3 files changed, 25 insertions(+), 5 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index 714e6380487..53210812f40 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -123,9 +123,19 @@ softpipe_set_sampler_textures(struct pipe_context *pipe, } - +/** + * Find/create an sp_sampler_varient object for sampling the given texture, + * sampler and tex unit. + * + * Note that the tex unit is significant. We can't re-use a sampler + * varient for multiple texture units because the sampler varient contains + * the texture object pointer. If the texture object pointer were stored + * somewhere outside the sampler varient, we could re-use samplers for + * multiple texture units. + */ static struct sp_sampler_varient * -get_sampler_varient( struct sp_sampler *sampler, +get_sampler_varient( unsigned unit, + struct sp_sampler *sampler, struct pipe_texture *texture, unsigned processor ) { @@ -133,9 +143,13 @@ get_sampler_varient( struct sp_sampler *sampler, struct sp_sampler_varient *v = NULL; union sp_sampler_key key; + /* if this fails, widen the key.unit field and update this assertion */ + assert(PIPE_MAX_SAMPLERS <= 16); + key.bits.target = sp_texture->base.target; key.bits.is_pot = sp_texture->pot; key.bits.processor = processor; + key.bits.unit = unit; key.bits.pad = 0; if (sampler->current && @@ -174,7 +188,8 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe) for (i = 0; i <= softpipe->vs->max_sampler; i++) { if (softpipe->sampler[i]) { softpipe->tgsi.vert_samplers_list[i] = - get_sampler_varient( sp_sampler(softpipe->sampler[i]), + get_sampler_varient( i, + sp_sampler(softpipe->sampler[i]), softpipe->texture[i], TGSI_PROCESSOR_VERTEX ); @@ -187,7 +202,8 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe) for (i = 0; i <= softpipe->fs->info.file_max[TGSI_FILE_SAMPLER]; i++) { if (softpipe->sampler[i]) { softpipe->tgsi.frag_samplers_list[i] = - get_sampler_varient( sp_sampler(softpipe->sampler[i]), + get_sampler_varient( i, + sp_sampler(softpipe->sampler[i]), softpipe->texture[i], TGSI_PROCESSOR_FRAGMENT ); diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index f3710037082..8f3dc12d0fa 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -1545,6 +1545,9 @@ static filter_func get_img_filter( const union sp_sampler_key key, } +/** + * Bind the given texture object and texture cache to the sampler varient. + */ void sp_sampler_varient_bind_texture( struct sp_sampler_varient *samp, struct softpipe_tile_cache *tex_cache, diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h index 26f80eb88a8..f6cd57ec0ac 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.h +++ b/src/gallium/drivers/softpipe/sp_tex_sample.h @@ -62,7 +62,8 @@ union sp_sampler_key { unsigned target:3; unsigned is_pot:1; unsigned processor:2; - unsigned pad:26; + unsigned unit:4; + unsigned pad:22; } bits; unsigned value; }; -- cgit v1.2.3 From 46fbc872881081ffcf0b526f8c4a909fd915ad78 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 21 Aug 2009 13:45:16 -0600 Subject: softpipe: remove unneeded const qualifier --- src/gallium/drivers/softpipe/sp_state_fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 3a453219235..a055d6295fe 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -128,7 +128,7 @@ softpipe_bind_vs_state(struct pipe_context *pipe, void *vs) { struct softpipe_context *softpipe = softpipe_context(pipe); - softpipe->vs = (const struct sp_vertex_shader *)vs; + softpipe->vs = (struct sp_vertex_shader *)vs; draw_bind_vertex_shader(softpipe->draw, (softpipe->vs ? softpipe->vs->draw_data : NULL)); -- cgit v1.2.3 From 4256c5829f8c23f8bd5c7c29491210f0f7813bf9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 21 Aug 2009 13:47:50 -0600 Subject: softpipe: remove unused #includes, white-space clean-up --- src/gallium/drivers/softpipe/sp_state_fs.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index a055d6295fe..256faa94b84 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -31,8 +31,6 @@ #include "pipe/p_defines.h" #include "util/u_memory.h" -#include "pipe/internal/p_winsys_screen.h" -#include "pipe/p_shader_tokens.h" #include "draw/draw_context.h" #include "draw/draw_vs.h" #include "tgsi/tgsi_dump.h" @@ -128,7 +126,7 @@ softpipe_bind_vs_state(struct pipe_context *pipe, void *vs) { struct softpipe_context *softpipe = softpipe_context(pipe); - softpipe->vs = (struct sp_vertex_shader *)vs; + softpipe->vs = (struct sp_vertex_shader *) vs; draw_bind_vertex_shader(softpipe->draw, (softpipe->vs ? softpipe->vs->draw_data : NULL)); @@ -142,8 +140,7 @@ softpipe_delete_vs_state(struct pipe_context *pipe, void *vs) { struct softpipe_context *softpipe = softpipe_context(pipe); - struct sp_vertex_shader *state = - (struct sp_vertex_shader *)vs; + struct sp_vertex_shader *state = (struct sp_vertex_shader *) vs; draw_delete_vertex_shader(softpipe->draw, state->draw_data); FREE( state ); -- cgit v1.2.3 From 3adc8c3779895c483ba8a1004939e7dd7d76fa9a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 21 Aug 2009 14:01:58 -0600 Subject: softpipe: minor code refactoring to remove softpipe/tile cache dependencies The tile cache code now has no hard dependencies on softpipe. --- src/gallium/drivers/softpipe/sp_state_derived.c | 13 ++++++++++++- src/gallium/drivers/softpipe/sp_tile_cache.c | 26 ++++++++++++------------- src/gallium/drivers/softpipe/sp_tile_cache.h | 1 - 3 files changed, 24 insertions(+), 16 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 53109283320..202a2bc94c8 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -34,6 +34,8 @@ #include "sp_context.h" #include "sp_screen.h" #include "sp_state.h" +#include "sp_texture.h" +#include "sp_tile_cache.h" /** @@ -201,10 +203,19 @@ update_tgsi_samplers( struct softpipe_context *softpipe ) softpipe_reset_sampler_varients( softpipe ); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - sp_tile_cache_validate_texture( softpipe->tex_cache[i] ); + struct softpipe_tile_cache *tc = softpipe->tex_cache[i]; + if (tc->texture) { + struct softpipe_texture *spt = softpipe_texture(tc->texture); + if (spt->timestamp != tc->timestamp) { + sp_tile_cache_validate_texture( tc ); + _debug_printf("INV %d %d\n", tc->timestamp, spt->timestamp); + tc->timestamp = spt->timestamp; + } + } } } + /* Hopefully this will remain quite simple, otherwise need to pull in * something like the state tracker mechanism. */ diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 77d02fa3e7a..e075ab62902 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -35,9 +35,6 @@ #include "pipe/p_inlines.h" #include "util/u_memory.h" #include "util/u_tile.h" -#include "sp_context.h" -#include "sp_surface.h" -#include "sp_texture.h" #include "sp_tile_cache.h" @@ -200,24 +197,25 @@ sp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc) } } + +/** + * Invalidate all cached tiles for the cached texture. + * Should be called when the texture is modified. + */ void sp_tile_cache_validate_texture(struct softpipe_tile_cache *tc) { - if (tc->texture) { - struct softpipe_texture *spt = softpipe_texture(tc->texture); - if (spt->timestamp != tc->timestamp) { - /* texture was modified, invalidate all cached tiles */ - uint i; - _debug_printf("INV %d %d\n", tc->timestamp, spt->timestamp); - for (i = 0; i < NUM_ENTRIES; i++) { - tc->entries[i].addr.bits.invalid = 1; - } + uint i; - tc->timestamp = spt->timestamp; - } + assert(tc); + assert(tc->texture); + + for (i = 0; i < NUM_ENTRIES; i++) { + tc->entries[i].addr.bits.invalid = 1; } } + /** * Specify the texture to cache. */ diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h index ac2aae58758..1596cd0ae76 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tile_cache.h @@ -34,7 +34,6 @@ #include "pipe/p_compiler.h" -struct softpipe_context; struct softpipe_tile_cache; -- cgit v1.2.3 From d204659c8c725c02212ad4a49275c7447f2d02a6 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 21 Aug 2009 14:04:47 -0600 Subject: softpipe: remove tex sample dependencies on softpipe The texture sampling code doesn't really have any dependencies on the rest of softpipe, just the tile cache. --- src/gallium/drivers/softpipe/sp_tex_sample.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 8f3dc12d0fa..a9efb82491b 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -34,17 +34,14 @@ * Keith Whitwell */ -#include "sp_context.h" -#include "sp_quad.h" -#include "sp_surface.h" -#include "sp_texture.h" -#include "sp_tex_sample.h" -#include "sp_tile_cache.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "sp_quad.h" /* only for #define QUAD_* tokens */ +#include "sp_tex_sample.h" +#include "sp_tile_cache.h" -- cgit v1.2.3 From 0f24886f922df3e00094a53b5b37b1588ea84bc0 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 21 Aug 2009 14:07:37 -0600 Subject: softpipe: remove duplicate #include, move another --- src/gallium/drivers/softpipe/sp_state_sampler.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index 53210812f40..afc6e1d2eb7 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -31,15 +31,14 @@ #include "util/u_memory.h" +#include "draw/draw_context.h" #include "draw/draw_context.h" -#include "sp_context.h" #include "sp_context.h" #include "sp_state.h" #include "sp_texture.h" #include "sp_tile_cache.h" #include "sp_tex_sample.h" -#include "draw/draw_context.h" struct sp_sampler { -- cgit v1.2.3 From 47800c572f199e7857e02e0f999b410c727a275d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 23 Aug 2009 11:13:20 +0100 Subject: softpipe: add missing header --- src/gallium/drivers/softpipe/sp_context.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 48ec540ebfd..3c465c95a53 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -42,6 +42,7 @@ #include "sp_state.h" #include "sp_surface.h" #include "sp_tile_cache.h" +#include "sp_tex_tile_cache.h" #include "sp_texture.h" #include "sp_winsys.h" #include "sp_query.h" -- cgit v1.2.3 From 4fe0fc3eba1f79beda890a5016359d549bab6ad4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 23 Aug 2009 11:22:41 +0100 Subject: softpipe: remove old prim_setup draw stage Everything now goes through the draw_vbuf handler, the same as regular drivers. --- src/gallium/drivers/softpipe/Makefile | 1 - src/gallium/drivers/softpipe/SConscript | 1 - src/gallium/drivers/softpipe/sp_context.c | 26 ++-- src/gallium/drivers/softpipe/sp_context.h | 5 +- src/gallium/drivers/softpipe/sp_prim_setup.c | 190 ------------------------ src/gallium/drivers/softpipe/sp_prim_setup.h | 85 ----------- src/gallium/drivers/softpipe/sp_prim_vbuf.c | 107 ++++--------- src/gallium/drivers/softpipe/sp_prim_vbuf.h | 4 +- src/gallium/drivers/softpipe/sp_setup.c | 1 - src/gallium/drivers/softpipe/sp_state_derived.c | 25 ++-- 10 files changed, 59 insertions(+), 386 deletions(-) delete mode 100644 src/gallium/drivers/softpipe/sp_prim_setup.c delete mode 100644 src/gallium/drivers/softpipe/sp_prim_setup.h (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile index 3da9be6957e..6ab37537628 100644 --- a/src/gallium/drivers/softpipe/Makefile +++ b/src/gallium/drivers/softpipe/Makefile @@ -11,7 +11,6 @@ C_SOURCES = \ sp_query.c \ sp_context.c \ sp_draw_arrays.c \ - sp_prim_setup.c \ sp_prim_vbuf.c \ sp_quad_pipe.c \ sp_quad_stipple.c \ diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript index 30c099813e1..153fe44546d 100644 --- a/src/gallium/drivers/softpipe/SConscript +++ b/src/gallium/drivers/softpipe/SConscript @@ -12,7 +12,6 @@ softpipe = env.ConvenienceLibrary( 'sp_context.c', 'sp_draw_arrays.c', 'sp_flush.c', - 'sp_prim_setup.c', 'sp_prim_vbuf.c', 'sp_setup.c', 'sp_quad_alpha_test.c', diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 3c465c95a53..6b75ee60023 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -31,13 +31,13 @@ */ #include "draw/draw_context.h" +#include "draw/draw_vbuf.h" #include "pipe/p_defines.h" #include "util/u_math.h" #include "util/u_memory.h" #include "sp_clear.h" #include "sp_context.h" #include "sp_flush.h" -#include "sp_prim_setup.h" #include "sp_prim_vbuf.h" #include "sp_state.h" #include "sp_surface.h" @@ -242,21 +242,21 @@ softpipe_create( struct pipe_screen *screen ) (struct tgsi_sampler **) softpipe->tgsi.vert_samplers_list); - softpipe->setup = sp_draw_render_stage(softpipe); - if (!softpipe->setup) - goto fail; - if (debug_get_bool_option( "SP_NO_RAST", FALSE )) softpipe->no_rast = TRUE; - if (debug_get_bool_option( "SP_NO_VBUF", FALSE )) { - /* Deprecated path -- vbuf is the intended interface to the draw module: - */ - draw_set_rasterize_stage(softpipe->draw, softpipe->setup); - } - else { - sp_init_vbuf(softpipe); - } + softpipe->vbuf_backend = sp_create_vbuf_backend(softpipe); + if (!softpipe->vbuf_backend) + goto fail; + + softpipe->vbuf = draw_vbuf_stage(softpipe->draw, softpipe->vbuf_backend); + if (!softpipe->vbuf) + goto fail; + + draw_set_rasterize_stage(softpipe->draw, softpipe->vbuf); + draw_set_render(softpipe->draw, softpipe->vbuf_backend); + + /* plug in AA line/point stages */ draw_install_aaline_stage(softpipe->draw, &softpipe->pipe); diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index df45d2249fc..43a195c8ef5 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -129,9 +129,10 @@ struct softpipe_context { /** The primitive drawing context */ struct draw_context *draw; - struct draw_stage *setup; + + /** Draw module backend */ + struct vbuf_render *vbuf_backend; struct draw_stage *vbuf; - struct softpipe_vbuf_render *vbuf_render; boolean dirty_render_cache; diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c deleted file mode 100644 index 038ff04d4f1..00000000000 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ /dev/null @@ -1,190 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \brief A draw stage that drives our triangle setup routines from - * within the draw pipeline. One of two ways to drive setup, the - * other being in sp_prim_vbuf.c. - * - * \author Keith Whitwell - * \author Brian Paul - */ - - -#include "sp_context.h" -#include "sp_setup.h" -#include "sp_state.h" -#include "sp_prim_setup.h" -#include "draw/draw_pipe.h" -#include "draw/draw_vertex.h" -#include "util/u_memory.h" - -/** - * Triangle setup info (derived from draw_stage). - * Also used for line drawing (taking some liberties). - */ -struct setup_stage { - struct draw_stage stage; /**< This must be first (base class) */ - - struct setup_context *setup; -}; - - - -/** - * Basically a cast wrapper. - */ -static INLINE struct setup_stage *setup_stage( struct draw_stage *stage ) -{ - return (struct setup_stage *)stage; -} - - -typedef const float (*cptrf4)[4]; - -static void -do_tri(struct draw_stage *stage, struct prim_header *prim) -{ - struct setup_stage *setup = setup_stage( stage ); - - setup_tri( setup->setup, - (cptrf4)prim->v[0]->data, - (cptrf4)prim->v[1]->data, - (cptrf4)prim->v[2]->data ); -} - -static void -do_line(struct draw_stage *stage, struct prim_header *prim) -{ - struct setup_stage *setup = setup_stage( stage ); - - setup_line( setup->setup, - (cptrf4)prim->v[0]->data, - (cptrf4)prim->v[1]->data ); -} - -static void -do_point(struct draw_stage *stage, struct prim_header *prim) -{ - struct setup_stage *setup = setup_stage( stage ); - - setup_point( setup->setup, - (cptrf4)prim->v[0]->data ); -} - - - - -static void setup_begin( struct draw_stage *stage ) -{ - struct setup_stage *setup = setup_stage(stage); - - setup_prepare( setup->setup ); - - stage->point = do_point; - stage->line = do_line; - stage->tri = do_tri; -} - - -static void setup_first_point( struct draw_stage *stage, - struct prim_header *header ) -{ - setup_begin(stage); - stage->point( stage, header ); -} - -static void setup_first_line( struct draw_stage *stage, - struct prim_header *header ) -{ - setup_begin(stage); - stage->line( stage, header ); -} - - -static void setup_first_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - setup_begin(stage); - stage->tri( stage, header ); -} - - - -static void setup_flush( struct draw_stage *stage, - unsigned flags ) -{ - stage->point = setup_first_point; - stage->line = setup_first_line; - stage->tri = setup_first_tri; -} - - -static void reset_stipple_counter( struct draw_stage *stage ) -{ -} - - -static void render_destroy( struct draw_stage *stage ) -{ - struct setup_stage *ssetup = setup_stage(stage); - setup_destroy_context(ssetup->setup); - FREE( stage ); -} - - -/** - * Create a new primitive setup/render stage. - */ -struct draw_stage *sp_draw_render_stage( struct softpipe_context *softpipe ) -{ - struct setup_stage *sstage = CALLOC_STRUCT(setup_stage); - - sstage->setup = setup_create_context(softpipe); - sstage->stage.draw = softpipe->draw; - sstage->stage.point = setup_first_point; - sstage->stage.line = setup_first_line; - sstage->stage.tri = setup_first_tri; - sstage->stage.flush = setup_flush; - sstage->stage.reset_stipple_counter = reset_stipple_counter; - sstage->stage.destroy = render_destroy; - - return (struct draw_stage *)sstage; -} - -struct setup_context * -sp_draw_setup_context( struct draw_stage *stage ) -{ - struct setup_stage *ssetup = setup_stage(stage); - return ssetup->setup; -} - -void -sp_draw_flush( struct draw_stage *stage ) -{ - stage->flush( stage, 0 ); -} diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.h b/src/gallium/drivers/softpipe/sp_prim_setup.h deleted file mode 100644 index 49bdd98ed87..00000000000 --- a/src/gallium/drivers/softpipe/sp_prim_setup.h +++ /dev/null @@ -1,85 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#ifndef SP_PRIM_SETUP_H -#define SP_PRIM_SETUP_H - - -/** - * vbuf is a special stage to gather the stream of triangles, lines, points - * together and reconstruct vertex buffers for hardware upload. - * - * First attempt, work in progress. - * - * TODO: - * - separate out vertex buffer building and primitive emit, ie >1 draw per vb. - * - tell vbuf stage how to build hw vertices directly - * - pass vbuf stage a buffer pointer for direct emit to agp/vram. - * - * - * - * Vertices are just an array of floats, with all the attributes - * packed. We currently assume a layout like: - * - * attr[0][0..3] - window position - * attr[1..n][0..3] - remaining attributes. - * - * Attributes are assumed to be 4 floats wide but are packed so that - * all the enabled attributes run contiguously. - */ - - -struct draw_stage; -struct softpipe_context; - - -typedef void (*vbuf_draw_func)( struct pipe_context *pipe, - unsigned prim, - const ushort *elements, - unsigned nr_elements, - const void *vertex_buffer, - unsigned nr_vertices ); - - -extern struct draw_stage * -sp_draw_render_stage( struct softpipe_context *softpipe ); - -extern struct setup_context * -sp_draw_setup_context( struct draw_stage * ); - -extern void -sp_draw_flush( struct draw_stage * ); - - -extern struct draw_stage * -sp_draw_vbuf_stage( struct draw_context *draw_context, - struct pipe_context *pipe, - vbuf_draw_func draw ); - - -#endif /* SP_PRIM_SETUP_H */ diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index 76524a8d411..e603c20fc4c 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -37,10 +37,9 @@ #include "sp_context.h" +#include "sp_setup.h" #include "sp_state.h" #include "sp_prim_vbuf.h" -#include "sp_prim_setup.h" -#include "sp_setup.h" #include "draw/draw_context.h" #include "draw/draw_vbuf.h" #include "util/u_memory.h" @@ -59,6 +58,8 @@ struct softpipe_vbuf_render { struct vbuf_render base; struct softpipe_context *softpipe; + struct setup_context *setup; + uint prim; uint vertex_size; uint nr_vertices; @@ -75,6 +76,11 @@ softpipe_vbuf_render(struct vbuf_render *vbr) } + + + + + static const struct vertex_info * sp_vbuf_get_vertex_info(struct vbuf_render *vbr) { @@ -105,36 +111,6 @@ sp_vbuf_allocate_vertices(struct vbuf_render *vbr, static void sp_vbuf_release_vertices(struct vbuf_render *vbr) { -#if 0 - { - struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); - const struct vertex_info *info = - softpipe_get_vbuf_vertex_info(cvbr->softpipe); - const float *vtx = (const float *) cvbr->vertex_buffer; - uint i, j; - debug_printf("%s (vtx_size = %u, vtx_used = %u)\n", - __FUNCTION__, cvbr->vertex_size, cvbr->nr_vertices); - for (i = 0; i < cvbr->nr_vertices; i++) { - for (j = 0; j < info->num_attribs; j++) { - uint k; - switch (info->attrib[j].emit) { - case EMIT_4F: k = 4; break; - case EMIT_3F: k = 3; break; - case EMIT_2F: k = 2; break; - case EMIT_1F: k = 1; break; - default: assert(0); - } - debug_printf("Vert %u attr %u: ", i, j); - while (k-- > 0) { - debug_printf("%g ", vtx[0]); - vtx++; - } - debug_printf("\n"); - } - } - } -#endif - /* keep the old allocation for next time */ } @@ -160,11 +136,7 @@ static boolean sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim) { struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); - - /* XXX: break this dependency - make setup_context live under - * softpipe, rename the old "setup" draw stage to something else. - */ - struct setup_context *setup_ctx = sp_draw_setup_context(cvbr->softpipe->setup); + struct setup_context *setup_ctx = cvbr->setup; setup_prepare( setup_ctx ); @@ -193,14 +165,9 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) struct softpipe_context *softpipe = cvbr->softpipe; const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float); const void *vertex_buffer = cvbr->vertex_buffer; + struct setup_context *setup_ctx = cvbr->setup; unsigned i; - /* XXX: break this dependency - make setup_context live under - * softpipe, rename the old "setup" draw stage to something else. - */ - struct draw_stage *setup = softpipe->setup; - struct setup_context *setup_ctx = sp_draw_setup_context(setup); - switch (cvbr->prim) { case PIPE_PRIM_POINTS: for (i = 0; i < nr; i++) { @@ -367,11 +334,6 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) default: assert(0); } - - /* XXX: why are we calling this??? If we had to call something, it - * would be a function in sp_setup.c: - */ - sp_draw_flush( setup ); } @@ -384,17 +346,12 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) { struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); struct softpipe_context *softpipe = cvbr->softpipe; + struct setup_context *setup_ctx = cvbr->setup; const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float); const void *vertex_buffer = (void *) get_vert(cvbr->vertex_buffer, start, stride); unsigned i; - /* XXX: break this dependency - make setup_context live under - * softpipe, rename the old "setup" draw stage to something else. - */ - struct draw_stage *setup = softpipe->setup; - struct setup_context *setup_ctx = sp_draw_setup_context(setup); - switch (cvbr->prim) { case PIPE_PRIM_POINTS: for (i = 0; i < nr; i++) { @@ -568,40 +525,38 @@ static void sp_vbuf_destroy(struct vbuf_render *vbr) { struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); - cvbr->softpipe->vbuf_render = NULL; + setup_destroy_context(cvbr->setup); FREE(cvbr); } /** - * Initialize the post-transform vertex buffer information for the given - * context. + * Create the post-transform vertex handler for the given context. */ -void -sp_init_vbuf(struct softpipe_context *sp) +struct vbuf_render * +sp_create_vbuf_backend(struct softpipe_context *sp) { - assert(sp->draw); + struct softpipe_vbuf_render *cvbr = CALLOC_STRUCT(softpipe_vbuf_render); - sp->vbuf_render = CALLOC_STRUCT(softpipe_vbuf_render); + assert(sp->draw); - sp->vbuf_render->base.max_indices = SP_MAX_VBUF_INDEXES; - sp->vbuf_render->base.max_vertex_buffer_bytes = SP_MAX_VBUF_SIZE; - sp->vbuf_render->base.get_vertex_info = sp_vbuf_get_vertex_info; - sp->vbuf_render->base.allocate_vertices = sp_vbuf_allocate_vertices; - sp->vbuf_render->base.map_vertices = sp_vbuf_map_vertices; - sp->vbuf_render->base.unmap_vertices = sp_vbuf_unmap_vertices; - sp->vbuf_render->base.set_primitive = sp_vbuf_set_primitive; - sp->vbuf_render->base.draw = sp_vbuf_draw; - sp->vbuf_render->base.draw_arrays = sp_vbuf_draw_arrays; - sp->vbuf_render->base.release_vertices = sp_vbuf_release_vertices; - sp->vbuf_render->base.destroy = sp_vbuf_destroy; + cvbr->base.max_indices = SP_MAX_VBUF_INDEXES; + cvbr->base.max_vertex_buffer_bytes = SP_MAX_VBUF_SIZE; - sp->vbuf_render->softpipe = sp; + cvbr->base.get_vertex_info = sp_vbuf_get_vertex_info; + cvbr->base.allocate_vertices = sp_vbuf_allocate_vertices; + cvbr->base.map_vertices = sp_vbuf_map_vertices; + cvbr->base.unmap_vertices = sp_vbuf_unmap_vertices; + cvbr->base.set_primitive = sp_vbuf_set_primitive; + cvbr->base.draw = sp_vbuf_draw; + cvbr->base.draw_arrays = sp_vbuf_draw_arrays; + cvbr->base.release_vertices = sp_vbuf_release_vertices; + cvbr->base.destroy = sp_vbuf_destroy; - sp->vbuf = draw_vbuf_stage(sp->draw, &sp->vbuf_render->base); + cvbr->softpipe = sp; - draw_set_rasterize_stage(sp->draw, sp->vbuf); + cvbr->setup = setup_create_context(cvbr->softpipe); - draw_set_render(sp->draw, &sp->vbuf_render->base); + return &cvbr->base; } diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.h b/src/gallium/drivers/softpipe/sp_prim_vbuf.h index 1de9cc2a894..ad01cc2f289 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.h +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.h @@ -31,8 +31,8 @@ struct softpipe_context; -extern void -sp_init_vbuf(struct softpipe_context *softpipe); +extern struct vbuf_render * +sp_create_vbuf_backend(struct softpipe_context *softpipe); #endif /* SP_VBUF_H */ diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index a132911c99d..bc8366b0e63 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -33,7 +33,6 @@ */ #include "sp_context.h" -#include "sp_prim_setup.h" #include "sp_quad.h" #include "sp_quad_pipe.h" #include "sp_setup.h" diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 04fc125e3d3..2a40589e842 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -68,24 +68,19 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe) const struct sp_fragment_shader *spfs = softpipe->fs; const enum interp_mode colorInterp = softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; + struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf; + const uint num = draw_num_vs_outputs(softpipe->draw); uint i; - if (softpipe->vbuf) { - /* if using the post-transform vertex buffer, tell draw_vbuf to - * simply emit the whole post-xform vertex as-is: - */ - struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf; - const uint num = draw_num_vs_outputs(softpipe->draw); - uint i; - - /* No longer any need to try and emit draw vertex_header info. - */ - vinfo_vbuf->num_attribs = 0; - for (i = 0; i < num; i++) { - draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i); - } - draw_compute_vertex_size(vinfo_vbuf); + /* Tell draw_vbuf to simply emit the whole post-xform vertex + * as-is. No longer any need to try and emit draw vertex_header + * info. + */ + vinfo_vbuf->num_attribs = 0; + for (i = 0; i < num; i++) { + draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i); } + draw_compute_vertex_size(vinfo_vbuf); /* * Loop over fragment shader inputs, searching for the matching output -- cgit v1.2.3 From 153e474d22d1b440bb6bd7b04dabf244d7455582 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 23 Aug 2009 13:38:10 +0100 Subject: softpipe: lift tex_address construction up to img_filter For fastpaths at least, can avoid recalculating this sometimes. --- src/gallium/drivers/softpipe/sp_tex_sample.c | 60 ++++++++++++++++------------ 1 file changed, 35 insertions(+), 25 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index d233924565f..f2d4f7eb8cc 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -605,14 +605,14 @@ compute_lambda_vert(const struct sp_sampler_varient *samp, */ static INLINE void get_texel_quad_2d(const struct tgsi_sampler *tgsi_sampler, - unsigned face, unsigned level, int x, int y, + union tex_tile_address addr, + unsigned x, unsigned y, const float *out[4]) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); const struct softpipe_tex_cached_tile *tile - = sp_get_cached_tile_tex(samp->cache, - tex_tile_address(x, y, 0, face, level)); + = sp_get_cached_tile_tex(samp->cache, addr); y %= TILE_SIZE; x %= TILE_SIZE; @@ -625,36 +625,33 @@ get_texel_quad_2d(const struct tgsi_sampler *tgsi_sampler, static INLINE const float * get_texel_2d_ptr(const struct tgsi_sampler *tgsi_sampler, - unsigned face, unsigned level, int x, int y) + union tex_tile_address addr, int x, int y) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + const struct softpipe_tex_cached_tile *tile; - const struct softpipe_tex_cached_tile *tile - = sp_get_cached_tile_tex(samp->cache, - tex_tile_address(x, y, 0, face, level)); - + addr.bits.x = x / TILE_SIZE; + addr.bits.y = y / TILE_SIZE; y %= TILE_SIZE; x %= TILE_SIZE; + tile = sp_get_cached_tile_tex(samp->cache, addr); + return &tile->data.color[y][x][0]; } static INLINE void get_texel_quad_2d_mt(const struct tgsi_sampler *tgsi_sampler, - unsigned face, unsigned level, + union tex_tile_address addr, int x0, int y0, int x1, int y1, const float *out[4]) { - unsigned i; - - for (i = 0; i < 4; i++) { - unsigned tx = (i & 1) ? x1 : x0; - unsigned ty = (i >> 1) ? y1 : y0; - - out[i] = get_texel_2d_ptr( tgsi_sampler, face, level, tx, ty ); - } + out[0] = get_texel_2d_ptr( tgsi_sampler, addr, x0, y0 ); + out[1] = get_texel_2d_ptr( tgsi_sampler, addr, x1, y0 ); + out[2] = get_texel_2d_ptr( tgsi_sampler, addr, x0, y1 ); + out[3] = get_texel_2d_ptr( tgsi_sampler, addr, x1, y1 ); } static INLINE void @@ -714,7 +711,12 @@ img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, unsigned ypot = 1 << (samp->ypot - level); unsigned xmax = (xpot - 1) & (TILE_SIZE - 1); /* MIN2(TILE_SIZE, xpot) - 1; */ unsigned ymax = (ypot - 1) & (TILE_SIZE - 1); /* MIN2(TILE_SIZE, ypot) - 1; */ - + union tex_tile_address addr; + + addr.value = 0; + addr.bits.level = samp->level; + + for (j = 0; j < QUAD_SIZE; j++) { int c; @@ -730,21 +732,21 @@ img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, int x0 = uflr & (xpot - 1); int y0 = vflr & (ypot - 1); - const float *tx[4]; + const float *tx[4]; - /* Can we fetch all four at once: */ if (x0 < xmax && y0 < ymax) { - get_texel_quad_2d(tgsi_sampler, 0, level, x0, y0, tx); + addr.bits.x = x0 / TILE_SIZE; + addr.bits.y = y0 / TILE_SIZE; + get_texel_quad_2d(tgsi_sampler, addr, x0, y0, tx); } else { unsigned x1 = (x0 + 1) & (xpot - 1); unsigned y1 = (y0 + 1) & (ypot - 1); - get_texel_quad_2d_mt(tgsi_sampler, 0, level, - x0, y0, x1, y1, tx); + get_texel_quad_2d_mt(tgsi_sampler, addr, x0, y0, x1, y1, tx); } @@ -771,6 +773,10 @@ img_filter_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler, unsigned level = samp->level; unsigned xpot = 1 << (samp->xpot - level); unsigned ypot = 1 << (samp->ypot - level); + union tex_tile_address addr; + + addr.value = 0; + addr.bits.level = samp->level; for (j = 0; j < QUAD_SIZE; j++) { int c; @@ -784,7 +790,7 @@ img_filter_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler, int x0 = uflr & (xpot - 1); int y0 = vflr & (ypot - 1); - const float *out = get_texel_2d_ptr(tgsi_sampler, 0, level, x0, y0); + const float *out = get_texel_2d_ptr(tgsi_sampler, addr, x0, y0); for (c = 0; c < 4; c++) { rgba[c][j] = out[c]; @@ -806,6 +812,10 @@ img_filter_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler, unsigned level = samp->level; unsigned xpot = 1 << (samp->xpot - level); unsigned ypot = 1 << (samp->ypot - level); + union tex_tile_address addr; + + addr.value = 0; + addr.bits.level = samp->level; for (j = 0; j < QUAD_SIZE; j++) { int c; @@ -828,7 +838,7 @@ img_filter_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler, else if (y0 > ypot - 1) y0 = ypot - 1; - out = get_texel_2d_ptr(tgsi_sampler, 0, level, x0, y0); + out = get_texel_2d_ptr(tgsi_sampler, addr, x0, y0); for (c = 0; c < 4; c++) { rgba[c][j] = out[c]; -- cgit v1.2.3 From 81601d85ef6b82297b046d5aab1b70e75168c2fa Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 23 Aug 2009 19:14:09 +0100 Subject: softpipe: make the various get_texel routines more similar Remove arguments, return const float * by default. Add specialized 3d versions and remove 3d texture support from the others. --- src/gallium/drivers/softpipe/sp_tex_sample.c | 268 ++++++++++++++++++--------- 1 file changed, 176 insertions(+), 92 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index f2d4f7eb8cc..82830107402 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -592,30 +592,68 @@ compute_lambda_vert(const struct sp_sampler_varient *samp, /** * Get a texel from a texture, using the texture tile cache. * - * \param face the cube face in 0..5 - * \param level the mipmap level + * \param addr the template tex address containing cube, z, face info. * \param x the x coord of texel within 2D image * \param y the y coord of texel within 2D image - * \param z which slice of a 3D texture * \param rgba the quad to put the texel/color into - * \param j which element of the rgba quad to write to * * XXX maybe move this into sp_tex_tile_cache.c and merge with the * sp_get_cached_tile_tex() function. Also, get 4 texels instead of 1... */ -static INLINE void -get_texel_quad_2d(const struct tgsi_sampler *tgsi_sampler, - union tex_tile_address addr, - unsigned x, unsigned y, - const float *out[4]) + + + + +static INLINE const float * +get_texel_2d_no_border(const struct sp_sampler_varient *samp, + union tex_tile_address addr, int x, int y) { - const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + const struct softpipe_tex_cached_tile *tile; + + addr.bits.x = x / TILE_SIZE; + addr.bits.y = y / TILE_SIZE; + y %= TILE_SIZE; + x %= TILE_SIZE; + + tile = sp_get_cached_tile_tex(samp->cache, addr); + + return &tile->data.color[y][x][0]; +} + + +static INLINE const float * +get_texel_2d(const struct sp_sampler_varient *samp, + union tex_tile_address addr, int x, int y) +{ + const struct pipe_texture *texture = samp->texture; + unsigned level = addr.bits.level; + + if (x < 0 || x >= (int) texture->width[level] || + y < 0 || y >= (int) texture->height[level]) { + return samp->sampler->border_color; + } + else { + return get_texel_2d_no_border( samp, addr, x, y ); + } +} - const struct softpipe_tex_cached_tile *tile - = sp_get_cached_tile_tex(samp->cache, addr); +/* Gather a quad of adjacent texels within a tile: + */ +static INLINE void +get_texel_quad_2d_no_border_single_tile(const struct sp_sampler_varient *samp, + union tex_tile_address addr, + unsigned x, unsigned y, + const float *out[4]) +{ + const struct softpipe_tex_cached_tile *tile; + + addr.bits.x = x / TILE_SIZE; + addr.bits.y = y / TILE_SIZE; y %= TILE_SIZE; x %= TILE_SIZE; + + tile = sp_get_cached_tile_tex(samp->cache, addr); out[0] = &tile->data.color[y ][x ][0]; out[1] = &tile->data.color[y ][x+1][0]; @@ -623,15 +661,50 @@ get_texel_quad_2d(const struct tgsi_sampler *tgsi_sampler, out[3] = &tile->data.color[y+1][x+1][0]; } + +/* Gather a quad of potentially non-adjacent texels: + */ +static INLINE void +get_texel_quad_2d_no_border(const struct sp_sampler_varient *samp, + union tex_tile_address addr, + int x0, int y0, + int x1, int y1, + const float *out[4]) +{ + out[0] = get_texel_2d_no_border( samp, addr, x0, y0 ); + out[1] = get_texel_2d_no_border( samp, addr, x1, y0 ); + out[2] = get_texel_2d_no_border( samp, addr, x0, y1 ); + out[3] = get_texel_2d_no_border( samp, addr, x1, y1 ); +} + +/* Can involve a lot of unnecessary checks for border color: + */ +static INLINE void +get_texel_quad_2d(const struct sp_sampler_varient *samp, + union tex_tile_address addr, + int x0, int y0, + int x1, int y1, + const float *out[4]) +{ + out[0] = get_texel_2d( samp, addr, x0, y0 ); + out[1] = get_texel_2d( samp, addr, x1, y0 ); + out[3] = get_texel_2d( samp, addr, x1, y1 ); + out[2] = get_texel_2d( samp, addr, x0, y1 ); +} + + + +/* 3d varients: + */ static INLINE const float * -get_texel_2d_ptr(const struct tgsi_sampler *tgsi_sampler, - union tex_tile_address addr, int x, int y) +get_texel_3d_no_border(const struct sp_sampler_varient *samp, + union tex_tile_address addr, int x, int y, int z) { - const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); const struct softpipe_tex_cached_tile *tile; addr.bits.x = x / TILE_SIZE; addr.bits.y = y / TILE_SIZE; + addr.bits.z = z; y %= TILE_SIZE; x %= TILE_SIZE; @@ -641,61 +714,26 @@ get_texel_2d_ptr(const struct tgsi_sampler *tgsi_sampler, } -static INLINE void -get_texel_quad_2d_mt(const struct tgsi_sampler *tgsi_sampler, - union tex_tile_address addr, - int x0, int y0, - int x1, int y1, - const float *out[4]) -{ - out[0] = get_texel_2d_ptr( tgsi_sampler, addr, x0, y0 ); - out[1] = get_texel_2d_ptr( tgsi_sampler, addr, x1, y0 ); - out[2] = get_texel_2d_ptr( tgsi_sampler, addr, x0, y1 ); - out[3] = get_texel_2d_ptr( tgsi_sampler, addr, x1, y1 ); -} - -static INLINE void -get_texel(const struct tgsi_sampler *tgsi_sampler, - unsigned face, unsigned level, int x, int y, int z, - float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j) +static INLINE const float * +get_texel_3d(const struct sp_sampler_varient *samp, + union tex_tile_address addr, int x, int y, int z ) { - const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); const struct pipe_texture *texture = samp->texture; - const struct pipe_sampler_state *sampler = samp->sampler; + unsigned level = addr.bits.level; if (x < 0 || x >= (int) texture->width[level] || y < 0 || y >= (int) texture->height[level] || z < 0 || z >= (int) texture->depth[level]) { - rgba[0][j] = sampler->border_color[0]; - rgba[1][j] = sampler->border_color[1]; - rgba[2][j] = sampler->border_color[2]; - rgba[3][j] = sampler->border_color[3]; + return samp->sampler->border_color; } else { - const unsigned tx = x % TILE_SIZE; - const unsigned ty = y % TILE_SIZE; - const struct softpipe_tex_cached_tile *tile; - - tile = sp_get_cached_tile_tex(samp->cache, - tex_tile_address(x, y, z, face, level)); - - rgba[0][j] = tile->data.color[ty][tx][0]; - rgba[1][j] = tile->data.color[ty][tx][1]; - rgba[2][j] = tile->data.color[ty][tx][2]; - rgba[3][j] = tile->data.color[ty][tx][3]; - if (0) - { - debug_printf("Get texel %f %f %f %f from %s\n", - rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j], - pf_name(texture->format)); - } + return get_texel_3d_no_border( samp, addr, x, y, z ); } } - - - +/* Some image-filter fastpaths: + */ static INLINE void img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, const float s[QUAD_SIZE], @@ -738,15 +776,13 @@ img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, */ if (x0 < xmax && y0 < ymax) { - addr.bits.x = x0 / TILE_SIZE; - addr.bits.y = y0 / TILE_SIZE; - get_texel_quad_2d(tgsi_sampler, addr, x0, y0, tx); + get_texel_quad_2d_no_border_single_tile(samp, addr, x0, y0, tx); } else { unsigned x1 = (x0 + 1) & (xpot - 1); unsigned y1 = (y0 + 1) & (ypot - 1); - get_texel_quad_2d_mt(tgsi_sampler, addr, x0, y0, x1, y1, tx); + get_texel_quad_2d_no_border(samp, addr, x0, y0, x1, y1, tx); } @@ -790,7 +826,7 @@ img_filter_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler, int x0 = uflr & (xpot - 1); int y0 = vflr & (ypot - 1); - const float *out = get_texel_2d_ptr(tgsi_sampler, addr, x0, y0); + const float *out = get_texel_2d_no_border(samp, addr, x0, y0); for (c = 0; c < 4; c++) { rgba[c][j] = out[c]; @@ -838,7 +874,7 @@ img_filter_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler, else if (y0 > ypot - 1) y0 = ypot - 1; - out = get_texel_2d_ptr(tgsi_sampler, addr, x0, y0); + out = get_texel_2d_no_border(samp, addr, x0, y0); for (c = 0; c < 4; c++) { rgba[c][j] = out[c]; @@ -859,20 +895,37 @@ img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler, unsigned level0, j; int width; int x[4]; + union tex_tile_address addr; level0 = samp->level; width = texture->width[level0]; assert(width > 0); + addr.value = 0; + addr.bits.level = samp->level; + samp->nearest_texcoord_s(s, width, x); for (j = 0; j < QUAD_SIZE; j++) { - get_texel(tgsi_sampler, 0, level0, x[j], 0, 0, rgba, j); + const float *out = get_texel_2d(samp, addr, x[j], 0); + int c; + for (c = 0; c < 4; c++) { + rgba[c][j] = out[c]; + } } } + + +static inline union tex_tile_address face( union tex_tile_address addr, + unsigned face ) +{ + addr.bits.face = face; + return addr; +} + static void img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler, const float s[QUAD_SIZE], @@ -887,18 +940,27 @@ img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler, unsigned level0, j; int width, height; int x[4], y[4]; + union tex_tile_address addr; + level0 = samp->level; width = texture->width[level0]; height = texture->height[level0]; assert(width > 0); + + addr.value = 0; + addr.bits.level = samp->level; samp->nearest_texcoord_s(s, width, x); samp->nearest_texcoord_t(t, height, y); for (j = 0; j < QUAD_SIZE; j++) { - get_texel(tgsi_sampler, faces[j], level0, x[j], y[j], 0, rgba, j); + const float *out = get_texel_2d(samp, face(addr, faces[j]), x[j], y[j]); + int c; + for (c = 0; c < 4; c++) { + rgba[c][j] = out[c]; + } } } @@ -916,6 +978,7 @@ img_filter_3d_nearest(struct tgsi_sampler *tgsi_sampler, unsigned level0, j; int width, height, depth; int x[4], y[4], z[4]; + union tex_tile_address addr; level0 = samp->level; width = texture->width[level0]; @@ -930,8 +993,15 @@ img_filter_3d_nearest(struct tgsi_sampler *tgsi_sampler, samp->nearest_texcoord_t(t, height, y); samp->nearest_texcoord_p(p, depth, z); + addr.value = 0; + addr.bits.level = samp->level; + for (j = 0; j < QUAD_SIZE; j++) { - get_texel(tgsi_sampler, 0, level0, x[j], y[j], z[j], rgba, j); + const float *out = get_texel_3d(samp, addr, x[j], y[j], z[j]); + int c; + for (c = 0; c < 4; c++) { + rgba[c][j] = out[c]; + } } } @@ -950,6 +1020,7 @@ img_filter_1d_linear(struct tgsi_sampler *tgsi_sampler, int width; int x0[4], x1[4]; float xw[4]; /* weights */ + union tex_tile_address addr; level0 = samp->level; @@ -957,22 +1028,27 @@ img_filter_1d_linear(struct tgsi_sampler *tgsi_sampler, assert(width > 0); + addr.value = 0; + addr.bits.level = samp->level; + samp->linear_texcoord_s(s, width, x0, x1, xw); for (j = 0; j < QUAD_SIZE; j++) { - float tx[4][4]; /* texels */ + const float *tx0 = get_texel_2d(samp, addr, x0[j], 0); + const float *tx1 = get_texel_2d(samp, addr, x1[j], 0); int c; - get_texel(tgsi_sampler, 0, level0, x0[j], 0, 0, tx, 0); - get_texel(tgsi_sampler, 0, level0, x1[j], 0, 0, tx, 1); /* interpolate R, G, B, A */ for (c = 0; c < 4; c++) { - rgba[c][j] = lerp(xw[j], tx[c][0], tx[c][1]); + rgba[c][j] = lerp(xw[j], tx0[c], tx1[c]); } } } + + + static void img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler, const float s[QUAD_SIZE], @@ -988,6 +1064,7 @@ img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler, int width, height; int x0[4], y0[4], x1[4], y1[4]; float xw[4], yw[4]; /* weights */ + union tex_tile_address addr; level0 = samp->level; @@ -996,22 +1073,25 @@ img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler, assert(width > 0); + addr.value = 0; + addr.bits.level = samp->level; + samp->linear_texcoord_s(s, width, x0, x1, xw); samp->linear_texcoord_t(t, height, y0, y1, yw); for (j = 0; j < QUAD_SIZE; j++) { - float tx[4][4]; /* texels */ + union tex_tile_address addrj = face(addr, faces[j]); + const float *tx0 = get_texel_2d(samp, addrj, x0[j], y0[j]); + const float *tx1 = get_texel_2d(samp, addrj, x1[j], y0[j]); + const float *tx2 = get_texel_2d(samp, addrj, x0[j], y1[j]); + const float *tx3 = get_texel_2d(samp, addrj, x1[j], y1[j]); int c; - get_texel(tgsi_sampler, faces[j], level0, x0[j], y0[j], 0, tx, 0); - get_texel(tgsi_sampler, faces[j], level0, x1[j], y0[j], 0, tx, 1); - get_texel(tgsi_sampler, faces[j], level0, x0[j], y1[j], 0, tx, 2); - get_texel(tgsi_sampler, faces[j], level0, x1[j], y1[j], 0, tx, 3); /* interpolate R, G, B, A */ for (c = 0; c < 4; c++) { rgba[c][j] = lerp_2d(xw[j], yw[j], - tx[c][0], tx[c][1], - tx[c][2], tx[c][3]); + tx0[c], tx1[c], + tx2[c], tx3[c]); } } } @@ -1031,12 +1111,16 @@ img_filter_3d_linear(struct tgsi_sampler *tgsi_sampler, int width, height, depth; int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4]; float xw[4], yw[4], zw[4]; /* interpolation weights */ + union tex_tile_address addr; level0 = samp->level; width = texture->width[level0]; height = texture->height[level0]; depth = texture->depth[level0]; + addr.value = 0; + addr.bits.level = level0; + assert(width > 0); assert(height > 0); assert(depth > 0); @@ -1046,25 +1130,25 @@ img_filter_3d_linear(struct tgsi_sampler *tgsi_sampler, samp->linear_texcoord_p(p, depth, z0, z1, zw); for (j = 0; j < QUAD_SIZE; j++) { - float tx0[4][4], tx1[4][4]; int c; - - get_texel(tgsi_sampler, 0, level0, x0[j], y0[j], z0[j], tx0, 0); - get_texel(tgsi_sampler, 0, level0, x1[j], y0[j], z0[j], tx0, 1); - get_texel(tgsi_sampler, 0, level0, x0[j], y1[j], z0[j], tx0, 2); - get_texel(tgsi_sampler, 0, level0, x1[j], y1[j], z0[j], tx0, 3); - get_texel(tgsi_sampler, 0, level0, x0[j], y0[j], z1[j], tx1, 0); - get_texel(tgsi_sampler, 0, level0, x1[j], y0[j], z1[j], tx1, 1); - get_texel(tgsi_sampler, 0, level0, x0[j], y1[j], z1[j], tx1, 2); - get_texel(tgsi_sampler, 0, level0, x1[j], y1[j], z1[j], tx1, 3); + const float *tx00 = get_texel_3d(samp, addr, x0[j], y0[j], z0[j]); + const float *tx01 = get_texel_3d(samp, addr, x1[j], y0[j], z0[j]); + const float *tx02 = get_texel_3d(samp, addr, x0[j], y1[j], z0[j]); + const float *tx03 = get_texel_3d(samp, addr, x1[j], y1[j], z0[j]); + + const float *tx10 = get_texel_3d(samp, addr, x0[j], y0[j], z1[j]); + const float *tx11 = get_texel_3d(samp, addr, x1[j], y0[j], z1[j]); + const float *tx12 = get_texel_3d(samp, addr, x0[j], y1[j], z1[j]); + const float *tx13 = get_texel_3d(samp, addr, x1[j], y1[j], z1[j]); + /* interpolate R, G, B, A */ for (c = 0; c < 4; c++) { rgba[c][j] = lerp_3d(xw[j], yw[j], zw[j], - tx0[c][0], tx0[c][1], - tx0[c][2], tx0[c][3], - tx1[c][0], tx1[c][1], - tx1[c][2], tx1[c][3]); + tx00[c], tx01[c], + tx02[c], tx03[c], + tx10[c], tx11[c], + tx12[c], tx13[c]); } } } -- cgit v1.2.3 From 60adc15ba5633190fc8a68e7c182f06dc7909df4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 23 Aug 2009 19:17:35 +0100 Subject: softpipe: separate out 2d and cube img filter functions --- src/gallium/drivers/softpipe/sp_tex_sample.c | 92 ++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 82830107402..3bc4599e045 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -917,8 +917,43 @@ img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler, } +static void +img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + const struct pipe_texture *texture = samp->texture; + unsigned level0, j; + int width, height; + int x[4], y[4]; + union tex_tile_address addr; + level0 = samp->level; + width = texture->width[level0]; + height = texture->height[level0]; + + assert(width > 0); + + addr.value = 0; + addr.bits.level = samp->level; + + samp->nearest_texcoord_s(s, width, x); + samp->nearest_texcoord_t(t, height, y); + + for (j = 0; j < QUAD_SIZE; j++) { + const float *out = get_texel_2d(samp, addr, x[j], y[j]); + int c; + for (c = 0; c < 4; c++) { + rgba[c][j] = out[c]; + } + } +} + static inline union tex_tile_address face( union tex_tile_address addr, unsigned face ) { @@ -927,7 +962,7 @@ static inline union tex_tile_address face( union tex_tile_address addr, } static void -img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler, +img_filter_cube_nearest(struct tgsi_sampler *tgsi_sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], @@ -1047,10 +1082,54 @@ img_filter_1d_linear(struct tgsi_sampler *tgsi_sampler, } +static void +img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + const struct pipe_texture *texture = samp->texture; + unsigned level0, j; + int width, height; + int x0[4], y0[4], x1[4], y1[4]; + float xw[4], yw[4]; /* weights */ + union tex_tile_address addr; + + + level0 = samp->level; + width = texture->width[level0]; + height = texture->height[level0]; + + assert(width > 0); + + addr.value = 0; + addr.bits.level = samp->level; + + samp->linear_texcoord_s(s, width, x0, x1, xw); + samp->linear_texcoord_t(t, height, y0, y1, yw); + + for (j = 0; j < QUAD_SIZE; j++) { + const float *tx0 = get_texel_2d(samp, addr, x0[j], y0[j]); + const float *tx1 = get_texel_2d(samp, addr, x1[j], y0[j]); + const float *tx2 = get_texel_2d(samp, addr, x0[j], y1[j]); + const float *tx3 = get_texel_2d(samp, addr, x1[j], y1[j]); + int c; + + /* interpolate R, G, B, A */ + for (c = 0; c < 4; c++) { + rgba[c][j] = lerp_2d(xw[j], yw[j], + tx0[c], tx1[c], + tx2[c], tx3[c]); + } + } +} static void -img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler, +img_filter_cube_linear(struct tgsi_sampler *tgsi_sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], @@ -1615,14 +1694,19 @@ static filter_func get_img_filter( const union sp_sampler_key key, } } } - /* Fallthrough to default versions: + /* Otherwise use default versions: */ - case PIPE_TEXTURE_CUBE: if (filter == PIPE_TEX_FILTER_NEAREST) return img_filter_2d_nearest; else return img_filter_2d_linear; break; + case PIPE_TEXTURE_CUBE: + if (filter == PIPE_TEX_FILTER_NEAREST) + return img_filter_cube_nearest; + else + return img_filter_cube_linear; + break; case PIPE_TEXTURE_3D: if (filter == PIPE_TEX_FILTER_NEAREST) return img_filter_3d_nearest; -- cgit v1.2.3 From fd19e8adcd82e88d0fc8d187360b528100fed244 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 23 Aug 2009 19:28:34 +0100 Subject: softpipe: use one fewer divide in sample_cube GCC won't do this for us. Makes a bigger difference to cubemap fps than previous set of compilcated rearrangements. --- src/gallium/drivers/softpipe/sp_tex_sample.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 3bc4599e045..50460df7cdf 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -1543,9 +1543,12 @@ sample_cube(struct tgsi_sampler *tgsi_sampler, } } - ssss[j] = ( sc / ma + 1.0F ) * 0.5F; - tttt[j] = ( tc / ma + 1.0F ) * 0.5F; - samp->faces[j] = face; + { + const float ima = 1.0 / ma; + ssss[j] = ( sc * ima + 1.0F ) * 0.5F; + tttt[j] = ( tc * ima + 1.0F ) * 0.5F; + samp->faces[j] = face; + } } /* In our little pipeline, the compare stage is next. If compare -- cgit v1.2.3 From 5a0b29050f22b4475426a6f05a0338a7cdf546a0 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 21 Sep 2009 08:34:00 -0600 Subject: softpipe: Fix cube face selection. If arx and ary are equal, we still want to choose from one of them, and not arz. (cherry picked from commit de685b37a91bc95dd4093a44a49b7b47385b1f7c) --- src/gallium/drivers/softpipe/sp_tex_sample.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 5de358dae93..81793ef7364 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -464,7 +464,7 @@ choose_cube_face(float rx, float ry, float rz, float *newS, float *newT) unsigned face; float sc, tc, ma; - if (arx > ary && arx > arz) { + if (arx >= ary && arx >= arz) { if (rx >= 0.0F) { face = PIPE_TEX_FACE_POS_X; sc = -rz; @@ -478,7 +478,7 @@ choose_cube_face(float rx, float ry, float rz, float *newS, float *newT) ma = arx; } } - else if (ary > arx && ary > arz) { + else if (ary >= arx && ary >= arz) { if (ry >= 0.0F) { face = PIPE_TEX_FACE_POS_Y; sc = rx; -- cgit v1.2.3 From 9ca94f91a3b48350b02a8fec5ecf60a819a24de5 Mon Sep 17 00:00:00 2001 From: Nicolai Hähnle Date: Mon, 21 Sep 2009 17:35:10 +0200 Subject: r300g: Fix bad formatting parameters in calls to debug_printf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nicolai Hähnle --- src/gallium/drivers/r300/r300_texture.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 6e8c3683200..7c041d17f71 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -48,7 +48,7 @@ static void r300_setup_texture_state(struct r300_texture* tex, state->format2 |= R500_TXHEIGHT_BIT11; } - debug_printf("r300: Set texture state (%dx%d, pitch %d, %d levels)\n", + debug_printf("r300: Set texture state (%dx%d, %d levels)\n", width, height, levels); } @@ -62,7 +62,7 @@ unsigned r300_texture_get_stride(struct r300_texture* tex, unsigned level) return tex->stride_override; if (level > tex->tex.last_level) { - debug_printf("%s: level (%u) > last_level (%u)\n", level, tex->tex.last_level); + debug_printf("%s: level (%u) > last_level (%u)\n", __FUNCTION__, level, tex->tex.last_level); return 0; } -- cgit v1.2.3 From e369294f760efd89754f4f66a1080bcf384ba4c6 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 22 Sep 2009 10:55:41 -0700 Subject: i915g: Do propper references of surfaces in context --- src/gallium/drivers/i915simple/i915_context.c | 7 +++++++ src/gallium/drivers/i915simple/i915_state.c | 10 +++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index b43f7352456..e745f3342d1 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -175,12 +175,19 @@ i915_is_buffer_referenced(struct pipe_context *pipe, static void i915_destroy(struct pipe_context *pipe) { struct i915_context *i915 = i915_context(pipe); + int i; draw_destroy(i915->draw); if(i915->batch) i915->iws->batchbuffer_destroy(i915->batch); + /* unbind framebuffer */ + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { + pipe_surface_reference(&i915->framebuffer.cbufs[i], NULL); + } + pipe_surface_reference(&i915->framebuffer.zsbuf, NULL); + FREE(i915); } diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index 0087dfa410f..7d48e6e84d5 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -588,9 +588,17 @@ static void i915_set_framebuffer_state(struct pipe_context *pipe, const struct pipe_framebuffer_state *fb) { struct i915_context *i915 = i915_context(pipe); + int i; + draw_flush(i915->draw); - i915->framebuffer = *fb; /* struct copy */ + i915->framebuffer.width = fb->width; + i915->framebuffer.height = fb->height; + i915->framebuffer.nr_cbufs = fb->nr_cbufs; + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { + pipe_surface_reference(&i915->framebuffer.cbufs[i], fb->cbufs[i]); + } + pipe_surface_reference(&i915->framebuffer.zsbuf, fb->zsbuf); i915->dirty |= I915_NEW_FRAMEBUFFER; } -- cgit v1.2.3 From b626176f0613852df908b4b0552b9b67d5830b4e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Sep 2009 19:26:08 +0100 Subject: softpipe: fix occlusion counting --- src/gallium/drivers/softpipe/sp_quad_depth_test.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index 9cffea2c9e6..ce1bab9341a 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -631,7 +631,7 @@ alpha_test_quads(struct quad_stage *qs, } } -static unsigned mask_count[0x8] = +static unsigned mask_count[16] = { 0, /* 0x0 */ 1, /* 0x1 */ @@ -641,6 +641,14 @@ static unsigned mask_count[0x8] = 2, /* 0x5 */ 2, /* 0x6 */ 3, /* 0x7 */ + 1, /* 0x8 */ + 2, /* 0x9 */ + 2, /* 0xa */ + 3, /* 0xb */ + 2, /* 0xc */ + 3, /* 0xd */ + 3, /* 0xe */ + 4, /* 0xf */ }; @@ -693,13 +701,17 @@ depth_test_quads_fallback(struct quad_stage *qs, qs->softpipe->depth_stencil->depth.writemask) write_depth_stencil_values(&data, quads[i]); - qs->softpipe->occlusion_count += mask_count[quads[i]->inout.mask]; quads[pass++] = quads[i]; } nr = pass; } + if (qs->softpipe->active_query_count) { + for (i = 0; i < nr; i++) + qs->softpipe->occlusion_count += mask_count[quads[i]->inout.mask]; + } + if (nr) qs->next->run(qs->next, quads, nr); } @@ -883,6 +895,8 @@ choose_depth_test(struct quad_stage *qs, boolean depthwrite = qs->softpipe->depth_stencil->depth.writemask; + boolean occlusion = qs->softpipe->active_query_count; + if (!alpha && !depth && @@ -893,6 +907,7 @@ choose_depth_test(struct quad_stage *qs, interp_depth && depth && depthwrite && + !occlusion && !stencil) { switch (depthfunc) { -- cgit v1.2.3 From b1139e9ad827d86886772a9c9d83dbb0071c702c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Sep 2009 19:38:34 +0100 Subject: softpipe: fix polygon stipple --- src/gallium/drivers/softpipe/sp_context.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 6b75ee60023..c4b8b33c6a2 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -262,10 +262,8 @@ softpipe_create( struct pipe_screen *screen ) draw_install_aaline_stage(softpipe->draw, &softpipe->pipe); draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe); -#if USE_DRAW_STAGE_PSTIPPLE /* Do polygon stipple w/ texture map + frag prog? */ draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe); -#endif sp_init_surface_functions(softpipe); -- cgit v1.2.3 From 207764894b6d565568bc46722e4c239d839a62fc Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Sep 2009 20:47:07 +0100 Subject: softpipe: set quad->facing value --- src/gallium/drivers/softpipe/sp_setup.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index bc8366b0e63..ade125662ad 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -240,6 +240,7 @@ static void flush_spans( struct setup_context *setup ) if (quadmask) { setup->quad[q].input.x0 = lx; setup->quad[q].input.y0 = setup->span.y; + setup->quad[q].input.facing = setup->facing; setup->quad[q].inout.mask = quadmask; setup->quad_ptrs[q] = &setup->quad[q]; q++; -- cgit v1.2.3 From fe9ca0f718cbc467e5cee99a2c20a5f257ed2fe1 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Sep 2009 20:47:37 +0100 Subject: softpipe: need to write depth/stencil values even when stencil fails --- src/gallium/drivers/softpipe/sp_quad_depth_test.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index ce1bab9341a..0ca86c4e1cb 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -498,7 +498,7 @@ depth_test_quad(struct quad_stage *qs, * Do stencil (and depth) testing. Stenciling depends on the outcome of * depth testing. */ -static boolean +static void depth_stencil_test_quad(struct quad_stage *qs, struct depth_data *data, struct quad_header *quad) @@ -545,13 +545,13 @@ depth_stencil_test_quad(struct quad_stage *qs, /* update stencil buffer values according to z pass/fail result */ if (zFailOp != PIPE_STENCIL_OP_KEEP) { - const unsigned failMask = origMask & ~quad->inout.mask; - apply_stencil_op(data, failMask, zFailOp, ref, wrtMask); + const unsigned zFailMask = origMask & ~quad->inout.mask; + apply_stencil_op(data, zFailMask, zFailOp, ref, wrtMask); } if (zPassOp != PIPE_STENCIL_OP_KEEP) { - const unsigned passMask = origMask & quad->inout.mask; - apply_stencil_op(data, passMask, zPassOp, ref, wrtMask); + const unsigned zPassMask = origMask & quad->inout.mask; + apply_stencil_op(data, zPassMask, zPassOp, ref, wrtMask); } } else { @@ -559,8 +559,6 @@ depth_stencil_test_quad(struct quad_stage *qs, apply_stencil_op(data, quad->inout.mask, zPassOp, ref, wrtMask); } } - - return quad->inout.mask != 0; } @@ -689,17 +687,17 @@ depth_test_quads_fallback(struct quad_stage *qs, } if (qs->softpipe->depth_stencil->stencil[0].enabled) { - if (!depth_stencil_test_quad(qs, &data, quads[i])) - continue; + depth_stencil_test_quad(qs, &data, quads[i]); + write_depth_stencil_values(&data, quads[i]); } else { if (!depth_test_quad(qs, &data, quads[i])) continue; + + if (qs->softpipe->depth_stencil->depth.writemask) + write_depth_stencil_values(&data, quads[i]); } - if (qs->softpipe->depth_stencil->stencil[0].enabled || - qs->softpipe->depth_stencil->depth.writemask) - write_depth_stencil_values(&data, quads[i]); quads[pass++] = quads[i]; } -- cgit v1.2.3 From 0670df5cb20c0b6630ab29511d9b2cbe18b47f65 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Sep 2009 16:42:15 -0600 Subject: softpipe: disable a _debug_printf() --- src/gallium/drivers/softpipe/sp_state_derived.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 2a40589e842..856c9ce176f 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -203,7 +203,9 @@ update_tgsi_samplers( struct softpipe_context *softpipe ) struct softpipe_texture *spt = softpipe_texture(tc->texture); if (spt->timestamp != tc->timestamp) { sp_tex_tile_cache_validate_texture( tc ); + /* _debug_printf("INV %d %d\n", tc->timestamp, spt->timestamp); + */ tc->timestamp = spt->timestamp; } } -- cgit v1.2.3 From 5dbedf3d7e99efe35fad308d382670e44cd60e25 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Sep 2009 16:59:28 -0600 Subject: softpipe: additional assertions --- src/gallium/drivers/softpipe/sp_tex_sample.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 50460df7cdf..be210d5671b 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -938,6 +938,7 @@ img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler, height = texture->height[level0]; assert(width > 0); + assert(height > 0); addr.value = 0; addr.bits.level = samp->level; @@ -983,6 +984,7 @@ img_filter_cube_nearest(struct tgsi_sampler *tgsi_sampler, height = texture->height[level0]; assert(width > 0); + assert(height > 0); addr.value = 0; addr.bits.level = samp->level; @@ -1104,6 +1106,7 @@ img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler, height = texture->height[level0]; assert(width > 0); + assert(height > 0); addr.value = 0; addr.bits.level = samp->level; @@ -1151,6 +1154,7 @@ img_filter_cube_linear(struct tgsi_sampler *tgsi_sampler, height = texture->height[level0]; assert(width > 0); + assert(height > 0); addr.value = 0; addr.bits.level = samp->level; -- cgit v1.2.3 From 75276ea316610a5737f2115326482024aa09d02a Mon Sep 17 00:00:00 2001 From: root Date: Tue, 22 Sep 2009 20:14:05 -0600 Subject: softpipe: fix bugs in POT texture sampling when texture is not square Before, if level was greater than the logbase2(base size) we were doing a negative bit shift and winding up with garbage values. --- src/gallium/drivers/softpipe/sp_tex_sample.c | 34 +++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index be210d5671b..ba9b91a378e 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -732,6 +732,20 @@ get_texel_3d(const struct sp_sampler_varient *samp, } +/** + * Given the logbase2 of a mipmap's base level size and a mipmap level, + * return the size (in texels) of that mipmap level. + * For example, if level[0].width = 256 then base_pot will be 8. + * If level = 2, then we'll return 64 (the width at level=2). + * Return 1 if level > base_pot. + */ +static INLINE unsigned +pot_level_size(unsigned base_pot, unsigned level) +{ + return (base_pot >= level) ? (1 << (base_pot - level)) : 1; +} + + /* Some image-filter fastpaths: */ static INLINE void @@ -745,8 +759,8 @@ img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); unsigned j; unsigned level = samp->level; - unsigned xpot = 1 << (samp->xpot - level); - unsigned ypot = 1 << (samp->ypot - level); + unsigned xpot = pot_level_size(samp->xpot, level); + unsigned ypot = pot_level_size(samp->ypot, level); unsigned xmax = (xpot - 1) & (TILE_SIZE - 1); /* MIN2(TILE_SIZE, xpot) - 1; */ unsigned ymax = (ypot - 1) & (TILE_SIZE - 1); /* MIN2(TILE_SIZE, ypot) - 1; */ union tex_tile_address addr; @@ -807,8 +821,8 @@ img_filter_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler, const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); unsigned j; unsigned level = samp->level; - unsigned xpot = 1 << (samp->xpot - level); - unsigned ypot = 1 << (samp->ypot - level); + unsigned xpot = pot_level_size(samp->xpot, level); + unsigned ypot = pot_level_size(samp->ypot, level); union tex_tile_address addr; addr.value = 0; @@ -846,8 +860,8 @@ img_filter_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler, const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); unsigned j; unsigned level = samp->level; - unsigned xpot = 1 << (samp->xpot - level); - unsigned ypot = 1 << (samp->ypot - level); + unsigned xpot = pot_level_size(samp->xpot, level); + unsigned ypot = pot_level_size(samp->ypot, level); union tex_tile_address addr; addr.value = 0; @@ -1311,6 +1325,14 @@ mip_filter_nearest(struct tgsi_sampler *tgsi_sampler, samp->level = MIN2(samp->level, (int)texture->last_level); samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba ); } + +#if 0 + printf("RGBA %g %g %g %g, %g %g %g %g, %g %g %g %g, %g %g %g %g\n", + rgba[0][0], rgba[1][0], rgba[2][0], rgba[3][0], + rgba[0][1], rgba[1][1], rgba[2][1], rgba[3][1], + rgba[0][2], rgba[1][2], rgba[2][2], rgba[3][2], + rgba[0][3], rgba[1][3], rgba[2][3], rgba[3][3]); +#endif } -- cgit v1.2.3 From 21a949365d1de2f1fea6cb87c6f389e30156566f Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 22 Sep 2009 17:16:35 +0100 Subject: gallium: Update vendor string. --- src/gallium/drivers/cell/ppu/cell_screen.c | 2 +- src/gallium/drivers/i915simple/i915_screen.c | 2 +- src/gallium/drivers/i965simple/brw_screen.c | 2 +- src/gallium/drivers/softpipe/sp_screen.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index 9161747fdbf..d185c6b8497 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.c +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -41,7 +41,7 @@ static const char * cell_get_vendor(struct pipe_screen *screen) { - return "Tungsten Graphics, Inc."; + return "VMware, Inc."; } diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c index a1dd43c1bcc..c66558c320e 100644 --- a/src/gallium/drivers/i915simple/i915_screen.c +++ b/src/gallium/drivers/i915simple/i915_screen.c @@ -46,7 +46,7 @@ static const char * i915_get_vendor(struct pipe_screen *screen) { - return "Tungsten Graphics, Inc."; + return "VMware, Inc."; } static const char * diff --git a/src/gallium/drivers/i965simple/brw_screen.c b/src/gallium/drivers/i965simple/brw_screen.c index fb68fd624b3..4a84c4db23f 100644 --- a/src/gallium/drivers/i965simple/brw_screen.c +++ b/src/gallium/drivers/i965simple/brw_screen.c @@ -39,7 +39,7 @@ static const char * brw_get_vendor( struct pipe_screen *screen ) { - return "Tungsten Graphics, Inc."; + return "VMware, Inc."; } diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index ce770184158..6cf45cded23 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -40,7 +40,7 @@ static const char * softpipe_get_vendor(struct pipe_screen *screen) { - return "Tungsten Graphics, Inc."; + return "VMware, Inc."; } -- cgit v1.2.3 From 84b956c29be7eb547130974df9ceb3d2f3354526 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Sep 2009 15:35:05 -0600 Subject: softpipe: increase MAX_WIDTH/HEIGTH 4096 to match max texture size --- src/gallium/drivers/softpipe/sp_tile_cache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 1f9b8f1f4fb..a524275a71c 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -44,8 +44,8 @@ /** XXX move these */ -#define MAX_WIDTH 2048 -#define MAX_HEIGHT 2048 +#define MAX_WIDTH 4096 +#define MAX_HEIGHT 4096 struct softpipe_tile_cache -- cgit v1.2.3 From e41707becaffd604fedc885719e5b061a4a5b363 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 23 Sep 2009 10:50:38 -0600 Subject: softpipe: added max texture/surface size sanity check --- src/gallium/drivers/softpipe/sp_tile_cache.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index a524275a71c..461cbb9f953 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -116,6 +116,12 @@ sp_create_tile_cache( struct pipe_screen *screen ) { struct softpipe_tile_cache *tc; uint pos; + int maxLevels, maxTexSize; + + /* sanity checking: max sure MAX_WIDTH/HEIGHT >= largest texture image */ + maxLevels = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS); + maxTexSize = 1 << (maxLevels - 1); + assert(MAX_WIDTH >= maxTexSize); tc = CALLOC_STRUCT( softpipe_tile_cache ); if (tc) { -- cgit v1.2.3 From b26f1df920a712da66c72f801e3292bf44ea9a83 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 23 Sep 2009 11:04:07 -0600 Subject: llvmpipe: increase MAX_WIDTH/HEIGHT to match max texture size --- src/gallium/drivers/llvmpipe/lp_tile_cache.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/llvmpipe/lp_tile_cache.h b/src/gallium/drivers/llvmpipe/lp_tile_cache.h index 6d8ba5ece7a..936fc8f0fa9 100644 --- a/src/gallium/drivers/llvmpipe/lp_tile_cache.h +++ b/src/gallium/drivers/llvmpipe/lp_tile_cache.h @@ -51,8 +51,8 @@ struct llvmpipe_cached_tile /** XXX move these */ -#define MAX_WIDTH 2048 -#define MAX_HEIGHT 2048 +#define MAX_WIDTH 4096 +#define MAX_HEIGHT 4096 struct llvmpipe_tile_cache -- cgit v1.2.3 From 5244ce786a3e115fac1675450c3df8ee11e20030 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 23 Sep 2009 11:04:57 -0600 Subject: llvmpipe: added max texture/surface size sanity check Carried over from softpipe driver. --- src/gallium/drivers/llvmpipe/lp_tile_cache.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/llvmpipe/lp_tile_cache.c b/src/gallium/drivers/llvmpipe/lp_tile_cache.c index 2e576e6039d..73460106f38 100644 --- a/src/gallium/drivers/llvmpipe/lp_tile_cache.c +++ b/src/gallium/drivers/llvmpipe/lp_tile_cache.c @@ -48,6 +48,12 @@ struct llvmpipe_tile_cache * lp_create_tile_cache( struct pipe_screen *screen ) { struct llvmpipe_tile_cache *tc; + int maxLevels, maxTexSize; + + /* sanity checking: max sure MAX_WIDTH/HEIGHT >= largest texture image */ + maxLevels = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS); + maxTexSize = 1 << (maxLevels - 1); + assert(MAX_WIDTH >= maxTexSize); tc = CALLOC_STRUCT( llvmpipe_tile_cache ); if(!tc) -- cgit v1.2.3 From e2329f2795d48d11131e9ac105e7aa3fd2c229c1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 23 Sep 2009 11:35:33 -0600 Subject: softpipe: white-space/formatting fixes and updated comments --- src/gallium/drivers/softpipe/sp_tex_sample.c | 173 ++++++++++++++------------- 1 file changed, 87 insertions(+), 86 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 21031c11b88..f74b86b3c27 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -115,11 +115,9 @@ lerp_3d(float a, float b, float c, * \return integer texture index */ static void -wrap_nearest_repeat(const float s[4], unsigned size, - int icoord[4]) +wrap_nearest_repeat(const float s[4], unsigned size, int icoord[4]) { uint ch; - /* s limited to [0,1) */ /* i limited to [0,size-1] */ for (ch = 0; ch < 4; ch++) { @@ -130,8 +128,7 @@ wrap_nearest_repeat(const float s[4], unsigned size, static void -wrap_nearest_clamp(const float s[4], unsigned size, - int icoord[4]) +wrap_nearest_clamp(const float s[4], unsigned size, int icoord[4]) { uint ch; /* s limited to [0,1] */ @@ -148,8 +145,7 @@ wrap_nearest_clamp(const float s[4], unsigned size, static void -wrap_nearest_clamp_to_edge(const float s[4], unsigned size, - int icoord[4]) +wrap_nearest_clamp_to_edge(const float s[4], unsigned size, int icoord[4]) { uint ch; /* s limited to [min,max] */ @@ -168,8 +164,7 @@ wrap_nearest_clamp_to_edge(const float s[4], unsigned size, static void -wrap_nearest_clamp_to_border(const float s[4], unsigned size, - int icoord[4]) +wrap_nearest_clamp_to_border(const float s[4], unsigned size, int icoord[4]) { uint ch; /* s limited to [min,max] */ @@ -186,9 +181,9 @@ wrap_nearest_clamp_to_border(const float s[4], unsigned size, } } + static void -wrap_nearest_mirror_repeat(const float s[4], unsigned size, - int icoord[4]) +wrap_nearest_mirror_repeat(const float s[4], unsigned size, int icoord[4]) { uint ch; const float min = 1.0F / (2.0F * size); @@ -209,9 +204,9 @@ wrap_nearest_mirror_repeat(const float s[4], unsigned size, } } + static void -wrap_nearest_mirror_clamp(const float s[4], unsigned size, - int icoord[4]) +wrap_nearest_mirror_clamp(const float s[4], unsigned size, int icoord[4]) { uint ch; for (ch = 0; ch < 4; ch++) { @@ -227,9 +222,10 @@ wrap_nearest_mirror_clamp(const float s[4], unsigned size, } } + static void wrap_nearest_mirror_clamp_to_edge(const float s[4], unsigned size, - int icoord[4]) + int icoord[4]) { uint ch; /* s limited to [min,max] */ @@ -284,7 +280,6 @@ wrap_linear_repeat(const float s[4], unsigned size, int icoord0[4], int icoord1[4], float w[4]) { uint ch; - for (ch = 0; ch < 4; ch++) { float u = s[ch] * size - 0.5F; icoord0[ch] = REMAINDER(util_ifloor(u), size); @@ -293,6 +288,7 @@ wrap_linear_repeat(const float s[4], unsigned size, } } + static void wrap_linear_clamp(const float s[4], unsigned size, int icoord0[4], int icoord1[4], float w[4]) @@ -307,6 +303,7 @@ wrap_linear_clamp(const float s[4], unsigned size, } } + static void wrap_linear_clamp_to_edge(const float s[4], unsigned size, int icoord0[4], int icoord1[4], float w[4]) @@ -325,6 +322,7 @@ wrap_linear_clamp_to_edge(const float s[4], unsigned size, } } + static void wrap_linear_clamp_to_border(const float s[4], unsigned size, int icoord0[4], int icoord1[4], float w[4]) @@ -365,6 +363,7 @@ wrap_linear_mirror_repeat(const float s[4], unsigned size, } } + static void wrap_linear_mirror_clamp(const float s[4], unsigned size, int icoord0[4], int icoord1[4], float w[4]) @@ -383,6 +382,7 @@ wrap_linear_mirror_clamp(const float s[4], unsigned size, } } + static void wrap_linear_mirror_clamp_to_edge(const float s[4], unsigned size, int icoord0[4], int icoord1[4], float w[4]) @@ -405,6 +405,7 @@ wrap_linear_mirror_clamp_to_edge(const float s[4], unsigned size, } } + static void wrap_linear_mirror_clamp_to_border(const float s[4], unsigned size, int icoord0[4], int icoord1[4], float w[4]) @@ -433,8 +434,7 @@ wrap_linear_mirror_clamp_to_border(const float s[4], unsigned size, * Only a subset of wrap modes supported. */ static void -wrap_nearest_unorm_clamp(const float s[4], unsigned size, - int icoord[4]) +wrap_nearest_unorm_clamp(const float s[4], unsigned size, int icoord[4]) { uint ch; for (ch = 0; ch < 4; ch++) { @@ -443,11 +443,13 @@ wrap_nearest_unorm_clamp(const float s[4], unsigned size, } } -/* Handles clamp_to_edge and clamp_to_border: + +/** + * Handles clamp_to_edge and clamp_to_border: */ static void wrap_nearest_unorm_clamp_to_border(const float s[4], unsigned size, - int icoord[4]) + int icoord[4]) { uint ch; for (ch = 0; ch < 4; ch++) { @@ -462,7 +464,7 @@ wrap_nearest_unorm_clamp_to_border(const float s[4], unsigned size, */ static void wrap_linear_unorm_clamp(const float s[4], unsigned size, - int icoord0[4], int icoord1[4], float w[4]) + int icoord0[4], int icoord1[4], float w[4]) { uint ch; for (ch = 0; ch < 4; ch++) { @@ -474,9 +476,10 @@ wrap_linear_unorm_clamp(const float s[4], unsigned size, } } + static void -wrap_linear_unorm_clamp_to_border( const float s[4], unsigned size, - int icoord0[4], int icoord1[4], float w[4]) +wrap_linear_unorm_clamp_to_border(const float s[4], unsigned size, + int icoord0[4], int icoord1[4], float w[4]) { uint ch; for (ch = 0; ch < 4; ch++) { @@ -492,8 +495,6 @@ wrap_linear_unorm_clamp_to_border( const float s[4], unsigned size, - - /** * Examine the quad's texture coordinates to compute the partial * derivatives w.r.t X and Y, then compute lambda (level of detail). @@ -519,6 +520,7 @@ compute_lambda_1d(const struct sp_sampler_varient *samp, return lambda; } + static float compute_lambda_2d(const struct sp_sampler_varient *samp, const float s[QUAD_SIZE], @@ -576,7 +578,10 @@ compute_lambda_3d(const struct sp_sampler_varient *samp, } - +/** + * Compute lambda for a vertex texture sampler. + * Since there aren't derivatives to use, just return the LOD bias. + */ static float compute_lambda_vert(const struct sp_sampler_varient *samp, const float s[QUAD_SIZE], @@ -698,7 +703,7 @@ get_texel_quad_2d(const struct sp_sampler_varient *samp, */ static INLINE const float * get_texel_3d_no_border(const struct sp_sampler_varient *samp, - union tex_tile_address addr, int x, int y, int z) + union tex_tile_address addr, int x, int y, int z) { const struct softpipe_tex_cached_tile *tile; @@ -716,7 +721,7 @@ get_texel_3d_no_border(const struct sp_sampler_varient *samp, static INLINE const float * get_texel_3d(const struct sp_sampler_varient *samp, - union tex_tile_address addr, int x, int y, int z ) + union tex_tile_address addr, int x, int y, int z) { const struct pipe_texture *texture = samp->texture; unsigned level = addr.bits.level; @@ -750,11 +755,11 @@ pot_level_size(unsigned base_pot, unsigned level) */ static INLINE void img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]) + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); unsigned j; @@ -768,7 +773,6 @@ img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, addr.value = 0; addr.bits.level = samp->level; - for (j = 0; j < QUAD_SIZE; j++) { int c; @@ -788,18 +792,15 @@ img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, /* Can we fetch all four at once: */ - if (x0 < xmax && y0 < ymax) - { + if (x0 < xmax && y0 < ymax) { get_texel_quad_2d_no_border_single_tile(samp, addr, x0, y0, tx); } - else - { + else { unsigned x1 = (x0 + 1) & (xpot - 1); unsigned y1 = (y0 + 1) & (ypot - 1); get_texel_quad_2d_no_border(samp, addr, x0, y0, x1, y1, tx); } - /* interpolate R, G, B, A */ for (c = 0; c < 4; c++) { rgba[c][j] = lerp_2d(xw, yw, @@ -896,6 +897,7 @@ img_filter_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler, } } + static void img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler, const float s[QUAD_SIZE], @@ -969,20 +971,22 @@ img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler, } } -static inline union tex_tile_address face( union tex_tile_address addr, - unsigned face ) + +static inline union tex_tile_address +face(union tex_tile_address addr, unsigned face ) { addr.bits.face = face; return addr; } + static void img_filter_cube_nearest(struct tgsi_sampler *tgsi_sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]) + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); const struct pipe_texture *texture = samp->texture; @@ -992,7 +996,6 @@ img_filter_cube_nearest(struct tgsi_sampler *tgsi_sampler, int x[4], y[4]; union tex_tile_address addr; - level0 = samp->level; width = texture->width[level0]; height = texture->height[level0]; @@ -1073,7 +1076,6 @@ img_filter_1d_linear(struct tgsi_sampler *tgsi_sampler, float xw[4]; /* weights */ union tex_tile_address addr; - level0 = samp->level; width = texture->width[level0]; @@ -1084,7 +1086,6 @@ img_filter_1d_linear(struct tgsi_sampler *tgsi_sampler, samp->linear_texcoord_s(s, width, x0, x1, xw); - for (j = 0; j < QUAD_SIZE; j++) { const float *tx0 = get_texel_2d(samp, addr, x0[j], 0); const float *tx1 = get_texel_2d(samp, addr, x1[j], 0); @@ -1114,7 +1115,6 @@ img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler, float xw[4], yw[4]; /* weights */ union tex_tile_address addr; - level0 = samp->level; width = texture->width[level0]; height = texture->height[level0]; @@ -1147,11 +1147,11 @@ img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler, static void img_filter_cube_linear(struct tgsi_sampler *tgsi_sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]) + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); const struct pipe_texture *texture = samp->texture; @@ -1162,7 +1162,6 @@ img_filter_cube_linear(struct tgsi_sampler *tgsi_sampler, float xw[4], yw[4]; /* weights */ union tex_tile_address addr; - level0 = samp->level; width = texture->width[level0]; height = texture->height[level0]; @@ -1251,18 +1250,13 @@ img_filter_3d_linear(struct tgsi_sampler *tgsi_sampler, } - - - - - static void mip_filter_linear(struct tgsi_sampler *tgsi_sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]) + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) { struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); const struct pipe_texture *texture = samp->texture; @@ -1301,7 +1295,6 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler, } - static void mip_filter_nearest(struct tgsi_sampler *tgsi_sampler, const float s[QUAD_SIZE], @@ -1357,7 +1350,8 @@ mip_filter_none(struct tgsi_sampler *tgsi_sampler, -/* Specialized version of mip_filter_linear with hard-wired calls to +/** + * Specialized version of mip_filter_linear with hard-wired calls to * 2d lambda calculation and 2d_linear_repeat_POT img filters. */ static void @@ -1409,7 +1403,8 @@ mip_filter_linear_2d_linear_repeat_POT( -/* Compare stage in the little sampling pipeline. +/** + * Do shadow/depth comparisons. */ static void sample_compare(struct tgsi_sampler *tgsi_sampler, @@ -1426,7 +1421,6 @@ sample_compare(struct tgsi_sampler *tgsi_sampler, samp->mip_filter( tgsi_sampler, s, t, p, lodbias, rgba ); - /** * Compare texcoord 'p' (aka R) against texture value 'rgba[0]' * When we sampled the depth texture, the depth value was put into all @@ -1493,7 +1487,10 @@ sample_compare(struct tgsi_sampler *tgsi_sampler, } } -/* Calculate cube faces. + +/** + * Compute which cube face is referenced by each texcoord and put that + * info into the sampler faces[] array. Then sample the cube faces */ static void sample_cube(struct tgsi_sampler *tgsi_sampler, @@ -1586,8 +1583,8 @@ sample_cube(struct tgsi_sampler *tgsi_sampler, - -static wrap_nearest_func get_nearest_unorm_wrap( unsigned mode ) +static wrap_nearest_func +get_nearest_unorm_wrap(unsigned mode) { switch (mode) { case PIPE_TEX_WRAP_CLAMP: @@ -1602,7 +1599,8 @@ static wrap_nearest_func get_nearest_unorm_wrap( unsigned mode ) } -static wrap_nearest_func get_nearest_wrap( unsigned mode ) +static wrap_nearest_func +get_nearest_wrap(unsigned mode) { switch (mode) { case PIPE_TEX_WRAP_REPEAT: @@ -1627,7 +1625,9 @@ static wrap_nearest_func get_nearest_wrap( unsigned mode ) } } -static wrap_linear_func get_linear_unorm_wrap( unsigned mode ) + +static wrap_linear_func +get_linear_unorm_wrap(unsigned mode) { switch (mode) { case PIPE_TEX_WRAP_CLAMP: @@ -1641,7 +1641,9 @@ static wrap_linear_func get_linear_unorm_wrap( unsigned mode ) } } -static wrap_linear_func get_linear_wrap( unsigned mode ) + +static wrap_linear_func +get_linear_wrap(unsigned mode) { switch (mode) { case PIPE_TEX_WRAP_REPEAT: @@ -1666,7 +1668,9 @@ static wrap_linear_func get_linear_wrap( unsigned mode ) } } -static compute_lambda_func get_lambda_func( const union sp_sampler_key key ) + +static compute_lambda_func +get_lambda_func(const union sp_sampler_key key) { if (key.bits.processor == TGSI_PROCESSOR_VERTEX) return compute_lambda_vert; @@ -1685,9 +1689,11 @@ static compute_lambda_func get_lambda_func( const union sp_sampler_key key ) } } -static filter_func get_img_filter( const union sp_sampler_key key, - unsigned filter, - const struct pipe_sampler_state *sampler ) + +static filter_func +get_img_filter(const union sp_sampler_key key, + unsigned filter, + const struct pipe_sampler_state *sampler) { switch (key.bits.target) { case PIPE_TEXTURE_1D: @@ -1774,7 +1780,8 @@ sp_sampler_varient_destroy( struct sp_sampler_varient *samp ) } -/* Create a sampler varient for a given set of non-orthogonal state. Currently the +/** + * Create a sampler varient for a given set of non-orthogonal state. */ struct sp_sampler_varient * sp_create_sampler_varient( const struct pipe_sampler_state *sampler, @@ -1871,9 +1878,3 @@ sp_create_sampler_varient( const struct pipe_sampler_state *sampler, return samp; } - - - - - - -- cgit v1.2.3 From b4a40d10524a4be6a59805589ee4209ebdb1de4f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 23 Sep 2009 11:51:52 -0600 Subject: softpipe: replace macros with inline functions And update comments. --- src/gallium/drivers/softpipe/sp_tex_sample.c | 53 +++++++++++++++++----------- 1 file changed, 32 insertions(+), 21 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index f74b86b3c27..2092a69740e 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -46,13 +46,18 @@ /* - * Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes - * see 1-pixel bands of improperly weighted linear-filtered textures. + * Return fractional part of 'f'. Used for computing interpolation weights. + * Need to be careful with negative values. + * Note, if this function isn't perfect you'll sometimes see 1-pixel bands + * of improperly weighted linear-filtered textures. * The tests/texwrap.c demo is a good test. - * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0. - * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x). */ -#define FRAC(f) ((f) - util_ifloor(f)) +static INLINE float +frac(float f) +{ + return f - util_ifloor(f); +} + /** @@ -99,10 +104,16 @@ lerp_3d(float a, float b, float c, /** - * If A is a signed integer, A % B doesn't give the right value for A < 0 - * (in terms of texture repeat). Just casting to unsigned fixes that. + * Compute coord % size for repeat wrap modes. + * Note that if coord is a signed integer, coord % size doesn't give + * the right value for coord < 0 (in terms of texture repeat). Just + * casting to unsigned fixes that. */ -#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B)) +static INLINE int +repeat(int coord, unsigned size) +{ + return (int) ((unsigned) coord % size); +} /** @@ -122,7 +133,7 @@ wrap_nearest_repeat(const float s[4], unsigned size, int icoord[4]) /* i limited to [0,size-1] */ for (ch = 0; ch < 4; ch++) { int i = util_ifloor(s[ch] * size); - icoord[ch] = REMAINDER(i, size); + icoord[ch] = repeat(i, size); } } @@ -282,9 +293,9 @@ wrap_linear_repeat(const float s[4], unsigned size, uint ch; for (ch = 0; ch < 4; ch++) { float u = s[ch] * size - 0.5F; - icoord0[ch] = REMAINDER(util_ifloor(u), size); - icoord1[ch] = REMAINDER(icoord0[ch] + 1, size); - w[ch] = FRAC(u); + icoord0[ch] = repeat(util_ifloor(u), size); + icoord1[ch] = repeat(icoord0[ch] + 1, size); + w[ch] = frac(u); } } @@ -299,7 +310,7 @@ wrap_linear_clamp(const float s[4], unsigned size, u = u * size - 0.5f; icoord0[ch] = util_ifloor(u); icoord1[ch] = icoord0[ch] + 1; - w[ch] = FRAC(u); + w[ch] = frac(u); } } @@ -318,7 +329,7 @@ wrap_linear_clamp_to_edge(const float s[4], unsigned size, icoord0[ch] = 0; if (icoord1[ch] >= (int) size) icoord1[ch] = size - 1; - w[ch] = FRAC(u); + w[ch] = frac(u); } } @@ -335,7 +346,7 @@ wrap_linear_clamp_to_border(const float s[4], unsigned size, u = u * size - 0.5f; icoord0[ch] = util_ifloor(u); icoord1[ch] = icoord0[ch] + 1; - w[ch] = FRAC(u); + w[ch] = frac(u); } } @@ -359,7 +370,7 @@ wrap_linear_mirror_repeat(const float s[4], unsigned size, icoord0[ch] = 0; if (icoord1[ch] >= (int) size) icoord1[ch] = size - 1; - w[ch] = FRAC(u); + w[ch] = frac(u); } } @@ -378,7 +389,7 @@ wrap_linear_mirror_clamp(const float s[4], unsigned size, u -= 0.5F; icoord0[ch] = util_ifloor(u); icoord1[ch] = icoord0[ch] + 1; - w[ch] = FRAC(u); + w[ch] = frac(u); } } @@ -401,7 +412,7 @@ wrap_linear_mirror_clamp_to_edge(const float s[4], unsigned size, icoord0[ch] = 0; if (icoord1[ch] >= (int) size) icoord1[ch] = size - 1; - w[ch] = FRAC(u); + w[ch] = frac(u); } } @@ -424,7 +435,7 @@ wrap_linear_mirror_clamp_to_border(const float s[4], unsigned size, u -= 0.5F; icoord0[ch] = util_ifloor(u); icoord1[ch] = icoord0[ch] + 1; - w[ch] = FRAC(u); + w[ch] = frac(u); } } @@ -472,7 +483,7 @@ wrap_linear_unorm_clamp(const float s[4], unsigned size, float u = CLAMP(s[ch] - 0.5F, 0.0f, (float) size - 1.0f); icoord0[ch] = util_ifloor(u); icoord1[ch] = icoord0[ch] + 1; - w[ch] = FRAC(u); + w[ch] = frac(u); } } @@ -489,7 +500,7 @@ wrap_linear_unorm_clamp_to_border(const float s[4], unsigned size, icoord1[ch] = icoord0[ch] + 1; if (icoord1[ch] > (int) size - 1) icoord1[ch] = size - 1; - w[ch] = FRAC(u); + w[ch] = frac(u); } } -- cgit v1.2.3 From 35af3f94a36d1850c8fbab3d1d0a23a904466429 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 23 Sep 2009 11:08:12 -0600 Subject: llvmpipe: move tile cache datatypes into .c file since they're private --- src/gallium/drivers/llvmpipe/lp_tile_cache.c | 37 ++++++++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_tile_cache.h | 37 +--------------------------- 2 files changed, 38 insertions(+), 36 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/llvmpipe/lp_tile_cache.c b/src/gallium/drivers/llvmpipe/lp_tile_cache.c index 73460106f38..0c06b659a1f 100644 --- a/src/gallium/drivers/llvmpipe/lp_tile_cache.c +++ b/src/gallium/drivers/llvmpipe/lp_tile_cache.c @@ -44,6 +44,43 @@ #include "lp_tile_cache.h" +#define MAX_WIDTH 4096 +#define MAX_HEIGHT 4096 + + +enum llvmpipe_tile_status +{ + LP_TILE_STATUS_UNDEFINED = 0, + LP_TILE_STATUS_CLEAR = 1, + LP_TILE_STATUS_DEFINED = 2 +}; + + +struct llvmpipe_cached_tile +{ + enum llvmpipe_tile_status status; + + /** color in SOA format */ + uint8_t *color; +}; + + +struct llvmpipe_tile_cache +{ + struct pipe_screen *screen; + struct pipe_surface *surface; /**< the surface we're caching */ + struct pipe_transfer *transfer; + void *transfer_map; + + struct llvmpipe_cached_tile entries[MAX_WIDTH/TILE_SIZE][MAX_HEIGHT/TILE_SIZE]; + + uint8_t clear_color[4]; /**< for color bufs */ + uint clear_val; /**< for z+stencil, or packed color clear value */ + + struct llvmpipe_cached_tile *last_tile; /**< most recently retrieved tile */ +}; + + struct llvmpipe_tile_cache * lp_create_tile_cache( struct pipe_screen *screen ) { diff --git a/src/gallium/drivers/llvmpipe/lp_tile_cache.h b/src/gallium/drivers/llvmpipe/lp_tile_cache.h index 936fc8f0fa9..161bab37991 100644 --- a/src/gallium/drivers/llvmpipe/lp_tile_cache.h +++ b/src/gallium/drivers/llvmpipe/lp_tile_cache.h @@ -33,42 +33,7 @@ #include "lp_tile_soa.h" -enum llvmpipe_tile_status -{ - LP_TILE_STATUS_UNDEFINED = 0, - LP_TILE_STATUS_CLEAR = 1, - LP_TILE_STATUS_DEFINED = 2 -}; - - -struct llvmpipe_cached_tile -{ - enum llvmpipe_tile_status status; - - /** color in SOA format */ - uint8_t *color; -}; - - -/** XXX move these */ -#define MAX_WIDTH 4096 -#define MAX_HEIGHT 4096 - - -struct llvmpipe_tile_cache -{ - struct pipe_screen *screen; - struct pipe_surface *surface; /**< the surface we're caching */ - struct pipe_transfer *transfer; - void *transfer_map; - - struct llvmpipe_cached_tile entries[MAX_WIDTH/TILE_SIZE][MAX_HEIGHT/TILE_SIZE]; - - uint8_t clear_color[4]; /**< for color bufs */ - uint clear_val; /**< for z+stencil, or packed color clear value */ - - struct llvmpipe_cached_tile *last_tile; /**< most recently retrieved tile */ -}; +struct llvmpipe_tile_cache; /* opaque */ extern struct llvmpipe_tile_cache * -- cgit v1.2.3 From e8e6d8853df19f7a32fb0e4f670259ee65e88b29 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 24 Sep 2009 15:27:03 +0100 Subject: softpipe: Update SConscript. --- src/gallium/drivers/softpipe/SConscript | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript index 153fe44546d..950c3d9955b 100644 --- a/src/gallium/drivers/softpipe/SConscript +++ b/src/gallium/drivers/softpipe/SConscript @@ -7,22 +7,16 @@ softpipe = env.ConvenienceLibrary( source = [ 'sp_fs_exec.c', 'sp_fs_sse.c', - 'sp_fs_llvm.c', 'sp_clear.c', 'sp_context.c', 'sp_draw_arrays.c', 'sp_flush.c', 'sp_prim_vbuf.c', 'sp_setup.c', - 'sp_quad_alpha_test.c', 'sp_quad_blend.c', 'sp_quad_pipe.c', - 'sp_quad_coverage.c', 'sp_quad_depth_test.c', - 'sp_quad_earlyz.c', 'sp_quad_fs.c', - 'sp_quad_occlusion.c', - 'sp_quad_stencil.c', 'sp_quad_stipple.c', 'sp_query.c', 'sp_screen.c', -- cgit v1.2.3 From 9659aa6482291d1530c74450612bcd952f542e01 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 24 Sep 2009 15:27:19 +0100 Subject: softpipe: Use portable INLINE macro. --- src/gallium/drivers/softpipe/sp_tex_sample.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 2092a69740e..c22ee86b66c 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -983,7 +983,7 @@ img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler, } -static inline union tex_tile_address +static INLINE union tex_tile_address face(union tex_tile_address addr, unsigned face ) { addr.bits.face = face; -- cgit v1.2.3 From d3beaf2f32044b36e2ffaf27679ddd1e5115df3f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 24 Sep 2009 16:49:27 +0100 Subject: softpipe: fix compiler warnings --- src/gallium/drivers/softpipe/sp_tex_tile_cache.h | 2 +- src/gallium/drivers/softpipe/sp_tile_cache.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h index 04e65ce2200..ac6886a3df1 100644 --- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h @@ -116,7 +116,7 @@ extern const struct softpipe_tex_cached_tile * sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc, union tex_tile_address addr ); -static INLINE const union tex_tile_address +static INLINE union tex_tile_address tex_tile_address( unsigned x, unsigned y, unsigned z, diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h index f21c74cb9ce..a12092702a6 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tile_cache.h @@ -128,7 +128,7 @@ sp_find_cached_tile(struct softpipe_tile_cache *tc, union tile_address addr ); -static INLINE const union tile_address +static INLINE union tile_address tile_address( unsigned x, unsigned y ) { -- cgit v1.2.3 From 90dcfb3b47c13044d671b8a1ab0c96ab2d21ea4d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 24 Sep 2009 16:49:40 +0100 Subject: trace: fix printf warnings --- src/gallium/drivers/trace/tr_context.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index ae0af4d0557..4940ce62a64 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -125,11 +125,11 @@ trace_context_draw_block(struct trace_context *tr_ctx, int flag) } else if ((tr_ctx->draw_rule.blocker & flag) && (tr_ctx->draw_blocker & 4)) { boolean block = FALSE; - debug_printf("%s (%lu %lu) (%lu %lu) (%lu %u) (%lu %u)\n", __FUNCTION__, - tr_ctx->draw_rule.fs, tr_ctx->curr.fs, - tr_ctx->draw_rule.vs, tr_ctx->curr.vs, - tr_ctx->draw_rule.surf, 0, - tr_ctx->draw_rule.tex, 0); + debug_printf("%s (%p %p) (%p %p) (%p %u) (%p %u)\n", __FUNCTION__, + tr_ctx->draw_rule.fs, tr_ctx->curr.fs, + tr_ctx->draw_rule.vs, tr_ctx->curr.vs, + tr_ctx->draw_rule.surf, 0, + tr_ctx->draw_rule.tex, 0); if (tr_ctx->draw_rule.fs && tr_ctx->draw_rule.fs == tr_ctx->curr.fs) block = TRUE; -- cgit v1.2.3 From 6be2bc56af5c0d281d07e427863789e949904db1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 24 Sep 2009 10:47:42 -0600 Subject: gallium/trace: casts to silence warnings --- src/gallium/drivers/trace/tr_context.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 4940ce62a64..bf470b46ae1 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -126,10 +126,10 @@ trace_context_draw_block(struct trace_context *tr_ctx, int flag) (tr_ctx->draw_blocker & 4)) { boolean block = FALSE; debug_printf("%s (%p %p) (%p %p) (%p %u) (%p %u)\n", __FUNCTION__, - tr_ctx->draw_rule.fs, tr_ctx->curr.fs, - tr_ctx->draw_rule.vs, tr_ctx->curr.vs, - tr_ctx->draw_rule.surf, 0, - tr_ctx->draw_rule.tex, 0); + (void *) tr_ctx->draw_rule.fs, (void *) tr_ctx->curr.fs, + (void *) tr_ctx->draw_rule.vs, (void *) tr_ctx->curr.vs, + (void *) tr_ctx->draw_rule.surf, 0, + (void *) tr_ctx->draw_rule.tex, 0); if (tr_ctx->draw_rule.fs && tr_ctx->draw_rule.fs == tr_ctx->curr.fs) block = TRUE; -- cgit v1.2.3 From 1730b8db1237485778abdc4ae37e122414b5423b Mon Sep 17 00:00:00 2001 From: Vinson Lee Date: Thu, 24 Sep 2009 15:59:57 -0600 Subject: softpipe: Increase GL_MAX_3D_TEXTURE_SIZE to 256. --- src/gallium/drivers/softpipe/sp_screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index cc39d33ede6..2e2668dfe49 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -84,7 +84,7 @@ softpipe_get_param(struct pipe_screen *screen, int param) case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: return 12; /* max 2Kx2K */ case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: - return 8; /* max 128x128x128 */ + return 9; /* max 256x256x256 */ case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: return 12; /* max 2Kx2K */ case PIPE_CAP_TGSI_CONT_SUPPORTED: -- cgit v1.2.3 From a665a3416e5a99dc84691c7f113a11190375f340 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 24 Sep 2009 16:07:45 -0600 Subject: llvmpipe: increase max 3D texture size to 256 --- src/gallium/drivers/llvmpipe/lp_screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index ff7ef8658a9..05189274589 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -82,7 +82,7 @@ llvmpipe_get_param(struct pipe_screen *screen, int param) case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: return 13; /* max 4Kx4K */ case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: - return 8; /* max 128x128x128 */ + return 9; /* max 256x256x256 */ case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: return 13; /* max 4Kx4K */ case PIPE_CAP_TGSI_CONT_SUPPORTED: -- cgit v1.2.3 From 01249c6d5653a0e66027202f44de2457be5942a5 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 24 Sep 2009 16:08:47 -0600 Subject: llvmpipe: add missing __FUNCTION__ parameter to debug_printf() calls --- src/gallium/drivers/llvmpipe/lp_bld_arit.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/llvmpipe/lp_bld_arit.c b/src/gallium/drivers/llvmpipe/lp_bld_arit.c index 0b115fc9b07..31433318a7e 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_arit.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_arit.c @@ -918,7 +918,8 @@ lp_build_pow(struct lp_build_context *bld, { /* TODO: optimize the constant case */ if(LLVMIsConstant(x) && LLVMIsConstant(y)) - debug_printf("%s: inefficient/imprecise constant arithmetic\n"); + debug_printf("%s: inefficient/imprecise constant arithmetic\n", + __FUNCTION__); return lp_build_exp2(bld, lp_build_mul(bld, lp_build_log2(bld, x), y)); } @@ -972,7 +973,8 @@ lp_build_polynomial(struct lp_build_context *bld, /* TODO: optimize the constant case */ if(LLVMIsConstant(x)) - debug_printf("%s: inefficient/imprecise constant arithmetic\n"); + debug_printf("%s: inefficient/imprecise constant arithmetic\n", + __FUNCTION__); for (i = num_coeffs; i--; ) { LLVMValueRef coeff = lp_build_const_scalar(type, coeffs[i]); @@ -1026,7 +1028,8 @@ lp_build_exp2_approx(struct lp_build_context *bld, if(p_exp2_int_part || p_frac_part || p_exp2) { /* TODO: optimize the constant case */ if(LLVMIsConstant(x)) - debug_printf("%s: inefficient/imprecise constant arithmetic\n"); + debug_printf("%s: inefficient/imprecise constant arithmetic\n", + __FUNCTION__); assert(type.floating && type.width == 32); @@ -1125,7 +1128,8 @@ lp_build_log2_approx(struct lp_build_context *bld, if(p_exp || p_floor_log2 || p_log2) { /* TODO: optimize the constant case */ if(LLVMIsConstant(x)) - debug_printf("%s: inefficient/imprecise constant arithmetic\n"); + debug_printf("%s: inefficient/imprecise constant arithmetic\n", + __FUNCTION__); assert(type.floating && type.width == 32); -- cgit v1.2.3 From 16a6ca9b2bd4f91aad69d4a5d36402e70a46bd37 Mon Sep 17 00:00:00 2001 From: Cooper Yuan Date: Fri, 25 Sep 2009 15:15:20 +0800 Subject: r300g: add texture format for xvmc --- src/gallium/drivers/r300/r300_texture.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index 3109af5baca..697669147d8 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -72,6 +72,9 @@ static INLINE uint32_t r300_translate_texformat(enum pipe_format format) /* W24_FP */ case PIPE_FORMAT_Z24S8_UNORM: return R300_EASY_TX_FORMAT(X, X, X, X, W24_FP); + /* Z5_Y6_X5 */ + case PIPE_FORMAT_R16_SNORM: + return R300_EASY_TX_FORMAT(X, X, X, X, Z5Y6X5); default: debug_printf("r300: Implementation error: " "Got unsupported texture format %s in %s\n", -- cgit v1.2.3 From 1196f9fbd68d9f3d1acd3d097711b382d7489f41 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Thu, 24 Sep 2009 16:39:56 +0200 Subject: nv50: implement IF, ELSE, ENDIF opcodes --- src/gallium/drivers/nv50/nv50_program.c | 188 +++++++++++++++++++++++++------- 1 file changed, 146 insertions(+), 42 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index eb90d5e66f9..2ab2ac35c2a 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -90,6 +90,9 @@ struct nv50_reg { int acc; /* instruction where this reg is last read (first insn == 1) */ }; +/* arbitrary limit */ +#define MAX_IF_DEPTH 4 + struct nv50_pc { struct nv50_program *p; @@ -121,6 +124,11 @@ struct nv50_pc { struct nv50_reg *iv_p; struct nv50_reg *iv_c; + struct nv50_program_exec *if_cond; + struct nv50_program_exec *if_insn[MAX_IF_DEPTH]; + struct nv50_program_exec *br_join[MAX_IF_DEPTH]; + int if_lvl; + /* current instruction and total number of insns */ unsigned insn_cur; unsigned insn_nr; @@ -890,6 +898,7 @@ emit_set(struct nv50_pc *pc, unsigned ccode, struct nv50_reg *dst, int wp, set_src_1(pc, src1, e); emit(pc, e); + pc->if_cond = pc->p->exec_tail; /* record for OPCODE_IF */ /* cvt.f32.u32/s32 (?) if we didn't only write the predicate */ if (rdst) @@ -1148,6 +1157,38 @@ emit_tex(struct nv50_pc *pc, struct nv50_reg **dst, unsigned mask, #endif } +static void +emit_branch(struct nv50_pc *pc, int pred, unsigned cc, + struct nv50_program_exec **join) +{ + struct nv50_program_exec *e = exec(pc); + + if (join) { + set_long(pc, e); + e->inst[0] |= 0xa0000002; + emit(pc, e); + *join = e; + e = exec(pc); + } + + set_long(pc, e); + e->inst[0] |= 0x10000002; + if (pred >= 0) + set_pred(pc, cc, pred, e); + emit(pc, e); +} + +static void +emit_nop(struct nv50_pc *pc) +{ + struct nv50_program_exec *e = exec(pc); + + e->inst[0] = 0xf0000000; + set_long(pc, e); + e->inst[1] = 0xe0000000; + emit(pc, e); +} + static void convert_to_long(struct nv50_pc *pc, struct nv50_program_exec *e) { @@ -1560,6 +1601,24 @@ nv50_program_tx_insn(struct nv50_pc *pc, if (mask & (1 << 0)) emit_mov_immdval(pc, dst[0], 1.0f); break; + case TGSI_OPCODE_ELSE: + emit_branch(pc, -1, 0, NULL); + pc->if_insn[--pc->if_lvl]->param.index = pc->p->exec_size; + pc->if_insn[pc->if_lvl++] = pc->p->exec_tail; + break; + case TGSI_OPCODE_ENDIF: + pc->if_insn[--pc->if_lvl]->param.index = pc->p->exec_size; + + if (pc->br_join[pc->if_lvl]) { + pc->br_join[pc->if_lvl]->param.index = pc->p->exec_size; + pc->br_join[pc->if_lvl] = NULL; + } + /* emit a NOP as join point, we could set it on the next + * one, but would have to make sure it is long and !immd + */ + emit_nop(pc); + pc->p->exec_tail->inst[1] |= 2; + break; case TGSI_OPCODE_EX2: emit_preex2(pc, temp, src[0][0]); emit_flop(pc, 6, brdc, temp); @@ -1580,6 +1639,13 @@ nv50_program_tx_insn(struct nv50_pc *pc, emit_sub(pc, dst[c], src[0][c], temp); } break; + case TGSI_OPCODE_IF: + /* emitting a join_at may not be necessary */ + assert(pc->if_lvl < MAX_IF_DEPTH); + set_pred_wr(pc, 1, 0, pc->if_cond); + emit_branch(pc, 0, 2, &pc->br_join[pc->if_lvl]); + pc->if_insn[pc->if_lvl++] = pc->p->exec_tail; + break; case TGSI_OPCODE_KIL: emit_kil(pc, src[0][0]); emit_kil(pc, src[0][1]); @@ -2237,6 +2303,8 @@ nv50_program_tx_prep(struct nv50_pc *pc) pc->result[i].rhw = rid++; if (p->info.writes_z) pc->result[2].rhw = rid; + + p->cfg.high_result = rid; } if (pc->immd_nr) { @@ -2362,12 +2430,75 @@ ctor_nv50_pc(struct nv50_pc *pc, struct nv50_program *p) return TRUE; } +static void +nv50_fp_move_results(struct nv50_pc *pc) +{ + struct nv50_reg reg; + unsigned i; + + ctor_reg(®, P_TEMP, -1, -1); + + for (i = 0; i < pc->result_nr * 4; ++i) { + if (pc->result[i].rhw < 0 || pc->result[i].hw < 0) + continue; + if (pc->result[i].rhw != pc->result[i].hw) { + reg.hw = pc->result[i].rhw; + emit_mov(pc, ®, &pc->result[i]); + } + } +} + +static void +nv50_program_fixup_insns(struct nv50_pc *pc) +{ + struct nv50_program_exec *e, *prev = NULL, **bra_list; + unsigned i, n, pos; + + bra_list = CALLOC(pc->p->exec_size, sizeof(struct nv50_program_exec *)); + + /* Collect branch instructions, we need to adjust their offsets + * when converting 32 bit instructions to 64 bit ones + */ + for (n = 0, e = pc->p->exec_head; e; e = e->next) + if (e->param.index >= 0 && !e->param.mask) + bra_list[n++] = e; + + /* Make sure we don't have any single 32 bit instructions. */ + for (e = pc->p->exec_head, pos = 0; e; e = e->next) { + pos += is_long(e) ? 2 : 1; + + if ((pos & 1) && (!e->next || is_long(e->next))) { + for (i = 0; i < n; ++i) + if (bra_list[i]->param.index >= pos) + bra_list[i]->param.index += 1; + convert_to_long(pc, e); + ++pos; + } + if (e->next) + prev = e; + } + + assert(!is_immd(pc->p->exec_head)); + assert(!is_immd(pc->p->exec_tail)); + + /* last instruction must be long so it can have the end bit set */ + if (!is_long(pc->p->exec_tail)) { + convert_to_long(pc, pc->p->exec_tail); + if (prev) + convert_to_long(pc, prev); + } + assert(!(pc->p->exec_tail->inst[1] & 2)); + /* set the end-bit */ + pc->p->exec_tail->inst[1] |= 1; + + FREE(bra_list); +} + static boolean nv50_program_tx(struct nv50_program *p) { struct tgsi_parse_context parse; struct nv50_pc *pc; - unsigned k; boolean ret; pc = CALLOC_STRUCT(nv50_pc); @@ -2405,48 +2536,10 @@ nv50_program_tx(struct nv50_program *p) } } - if (p->type == PIPE_SHADER_FRAGMENT) { - struct nv50_reg out; - ctor_reg(&out, P_TEMP, -1, -1); - - for (k = 0; k < pc->result_nr * 4; k++) { - if (pc->result[k].rhw == -1) - continue; - if (pc->result[k].hw != pc->result[k].rhw) { - out.hw = pc->result[k].rhw; - emit_mov(pc, &out, &pc->result[k]); - } - if (pc->p->cfg.high_result < (pc->result[k].rhw + 1)) - pc->p->cfg.high_result = pc->result[k].rhw + 1; - } - } - - /* look for single half instructions and make them long */ - struct nv50_program_exec *e, *e_prev; - - for (k = 0, e = pc->p->exec_head, e_prev = NULL; e; e = e->next) { - if (!is_long(e)) - k++; + if (pc->p->type == PIPE_SHADER_FRAGMENT) + nv50_fp_move_results(pc); - if (!e->next || is_long(e->next)) { - if (k & 1) - convert_to_long(pc, e); - k = 0; - } - - if (e->next) - e_prev = e; - } - - if (!is_long(pc->p->exec_tail)) { - /* this may occur if moving FP results */ - assert(e_prev && !is_long(e_prev)); - convert_to_long(pc, e_prev); - convert_to_long(pc, pc->p->exec_tail); - } - - assert(is_long(pc->p->exec_tail) && !is_immd(pc->p->exec_head)); - pc->p->exec_tail->inst[1] |= 0x00000001; + nv50_program_fixup_insns(pc); p->param_nr = pc->param_nr * 4; p->immd_nr = pc->immd_nr * 4; @@ -2558,6 +2651,17 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) if (e->param.index < 0) continue; + + if (e->param.mask == 0) { + assert(!(e->param.index & 1)); + /* seem to be 8 byte steps */ + ei = (e->param.index >> 1) + 0 /* START_ID */; + + e->inst[0] &= 0xf0000fff; + e->inst[0] |= ei << 12; + continue; + } + bs = (e->inst[1] >> 22) & 0x07; assert(bs < 2); ei = e->param.shift >> 5; -- cgit v1.2.3 From e2b8dc3e38d1efddf2ded2e47a9e3092455d0f8a Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Fri, 25 Sep 2009 10:24:40 +0200 Subject: nv50: implement BGNLOOP, BRK, ENDLOOP There's a good chance a loop won't execute correctly though since our TEMP allocation assumes programs to be executed linearly. Will fix later. --- src/gallium/drivers/nv50/nv50_program.c | 77 ++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 2ab2ac35c2a..8e66fdca49b 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -90,8 +90,9 @@ struct nv50_reg { int acc; /* instruction where this reg is last read (first insn == 1) */ }; -/* arbitrary limit */ +/* arbitrary limits */ #define MAX_IF_DEPTH 4 +#define MAX_LOOP_DEPTH 4 struct nv50_pc { struct nv50_program *p; @@ -127,7 +128,9 @@ struct nv50_pc { struct nv50_program_exec *if_cond; struct nv50_program_exec *if_insn[MAX_IF_DEPTH]; struct nv50_program_exec *br_join[MAX_IF_DEPTH]; - int if_lvl; + struct nv50_program_exec *br_loop[MAX_LOOP_DEPTH]; /* for BRK branch */ + int if_lvl, loop_lvl; + unsigned loop_pos[MAX_LOOP_DEPTH]; /* current instruction and total number of insns */ unsigned insn_cur; @@ -204,6 +207,10 @@ alloc_reg(struct nv50_pc *pc, struct nv50_reg *reg) assert(0); } +/* XXX: For shaders that aren't executed linearly (e.g. shaders that + * contain loops), we need to assign all hw regs to TGSI TEMPs early, + * lest we risk temp_temps overwriting regs alloc'd "later". + */ static struct nv50_reg * alloc_temp(struct nv50_pc *pc, struct nv50_reg *dst) { @@ -1485,6 +1492,55 @@ nv50_tgsi_dst_revdep(unsigned op, int s, int c) } } +static INLINE boolean +has_pred(struct nv50_program_exec *e, unsigned cc) +{ + if (!is_long(e) || is_immd(e)) + return FALSE; + return ((e->inst[1] & 0x780) == (cc << 7)); +} + +/* on ENDIF see if we can do "@p0.neu single_op" instead of: + * join_at ENDIF + * @p0.eq bra ENDIF + * single_op + * ENDIF: nop.join + */ +static boolean +nv50_kill_branch(struct nv50_pc *pc) +{ + int lvl = pc->if_lvl; + + if (pc->if_insn[lvl]->next != pc->p->exec_tail) + return FALSE; + + /* if ccode == 'true', the BRA is from an ELSE and the predicate + * reg may no longer be valid, since we currently always use $p0 + */ + if (has_pred(pc->if_insn[lvl], 0xf)) + return FALSE; + assert(pc->if_insn[lvl] && pc->br_join[lvl]); + + /* We'll use the exec allocated for JOIN_AT (as we can't easily + * update prev's next); if exec_tail is BRK, update the pointer. + */ + if (pc->loop_lvl && pc->br_loop[pc->loop_lvl - 1] == pc->p->exec_tail) + pc->br_loop[pc->loop_lvl - 1] = pc->br_join[lvl]; + + pc->p->exec_size -= 4; /* remove JOIN_AT and BRA */ + + *pc->br_join[lvl] = *pc->p->exec_tail; + + FREE(pc->if_insn[lvl]); + FREE(pc->p->exec_tail); + + pc->p->exec_tail = pc->br_join[lvl]; + pc->p->exec_tail->next = NULL; + set_pred(pc, 0xd, 0, pc->p->exec_tail); + + return TRUE; +} + static boolean nv50_program_tx_insn(struct nv50_pc *pc, const struct tgsi_full_instruction *inst) @@ -1554,6 +1610,14 @@ nv50_program_tx_insn(struct nv50_pc *pc, emit_add(pc, dst[c], src[0][c], src[1][c]); } break; + case TGSI_OPCODE_BGNLOOP: + pc->loop_pos[pc->loop_lvl++] = pc->p->exec_size; + break; + case TGSI_OPCODE_BRK: + emit_branch(pc, -1, 0, NULL); + assert(pc->loop_lvl > 0); + pc->br_loop[pc->loop_lvl - 1] = pc->p->exec_tail; + break; case TGSI_OPCODE_CEIL: for (c = 0; c < 4; c++) { if (!(mask & (1 << c))) @@ -1609,6 +1673,10 @@ nv50_program_tx_insn(struct nv50_pc *pc, case TGSI_OPCODE_ENDIF: pc->if_insn[--pc->if_lvl]->param.index = pc->p->exec_size; + /* try to replace branch over 1 insn with a predicated insn */ + if (nv50_kill_branch(pc) == TRUE) + break; + if (pc->br_join[pc->if_lvl]) { pc->br_join[pc->if_lvl]->param.index = pc->p->exec_size; pc->br_join[pc->if_lvl] = NULL; @@ -1619,6 +1687,11 @@ nv50_program_tx_insn(struct nv50_pc *pc, emit_nop(pc); pc->p->exec_tail->inst[1] |= 2; break; + case TGSI_OPCODE_ENDLOOP: + emit_branch(pc, -1, 0, NULL); + pc->p->exec_tail->param.index = pc->loop_pos[--pc->loop_lvl]; + pc->br_loop[pc->loop_lvl]->param.index = pc->p->exec_size; + break; case TGSI_OPCODE_EX2: emit_preex2(pc, temp, src[0][0]); emit_flop(pc, 6, brdc, temp); -- cgit v1.2.3 From ef6805710d5c1b139695704051754f39654c8a2e Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Fri, 25 Sep 2009 10:33:02 +0200 Subject: nv50: fix CEIL and TRUNC Separated the integer rounding mode flag for cvt. --- src/gallium/drivers/nv50/nv50_program.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 8e66fdca49b..2ad8cdf65c3 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -825,7 +825,8 @@ emit_precossin(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) #define CVT_F32_U32 0x64 #define CVT_S32_F32 0x8c #define CVT_S32_S32 0x0c -#define CVT_F32_F32_ROP 0xcc +#define CVT_NEG 0x20 +#define CVT_RI 0x08 static void emit_cvt(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src, @@ -933,7 +934,7 @@ map_tgsi_setop_cc(unsigned op) static INLINE void emit_flr(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) { - emit_cvt(pc, dst, src, -1, CVTOP_FLOOR, CVT_F32_F32_ROP); + emit_cvt(pc, dst, src, -1, CVTOP_FLOOR, CVT_F32_F32 | CVT_RI); } static void @@ -1623,7 +1624,7 @@ nv50_program_tx_insn(struct nv50_pc *pc, if (!(mask & (1 << c))) continue; emit_cvt(pc, dst[c], src[0][c], -1, - CVTOP_CEIL, CVT_F32_F32); + CVTOP_CEIL, CVT_F32_F32 | CVT_RI); } break; case TGSI_OPCODE_COS: @@ -1843,7 +1844,7 @@ nv50_program_tx_insn(struct nv50_pc *pc, if (!(mask & (1 << c))) continue; emit_cvt(pc, dst[c], src[0][c], -1, - CVTOP_TRUNC, CVT_F32_F32); + CVTOP_TRUNC, CVT_F32_F32 | CVT_RI); } break; case TGSI_OPCODE_XPD: -- cgit v1.2.3 From 001daf78c87b2d194b51bc650bf9f917d4224e31 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Thu, 24 Sep 2009 17:24:48 +0200 Subject: nv50: RCP and RSQ cannot load from VP inputs --- src/gallium/drivers/nv50/nv50_program.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 2ad8cdf65c3..272fd8d90ba 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -573,6 +573,22 @@ check_swap_src_0_1(struct nv50_pc *pc, return FALSE; } +static void +set_src_0_restricted(struct nv50_pc *pc, struct nv50_reg *src, + struct nv50_program_exec *e) +{ + struct nv50_reg *temp; + + if (src->type != P_TEMP) { + temp = temp_temp(pc); + emit_mov(pc, temp, src); + src = temp; + } + + alloc_reg(pc, src); + e->inst[0] |= (src->hw << 9); +} + static void set_src_0(struct nv50_pc *pc, struct nv50_reg *src, struct nv50_program_exec *e) { @@ -775,7 +791,11 @@ emit_flop(struct nv50_pc *pc, unsigned sub, } set_dst(pc, dst, e); - set_src_0(pc, src, e); + + if (sub == 0 || sub == 2) + set_src_0_restricted(pc, src, e); + else + set_src_0(pc, src, e); emit(pc, e); } -- cgit v1.2.3 From 513cadf5afad18516f7299ade246f59d520753d0 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Thu, 24 Sep 2009 17:37:08 +0200 Subject: nv50: actually enable view volume clipping Until now, only primitives wholly outside the view volume were not drawn. This was only visibile when using a viewport smaller than the window size, naturally. --- src/gallium/drivers/nv50/nv50_state_validate.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 5a3559ed181..4ed76973c4b 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -312,7 +312,7 @@ scissor_uptodate: goto viewport_uptodate; nv50->state.viewport_bypass = bypass; - so = so_new(12, 0); + so = so_new(14, 0); if (!bypass) { so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE(0), 3); so_data (so, fui(nv50->viewport.translate[0])); @@ -325,12 +325,21 @@ scissor_uptodate: so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1); so_data (so, 1); + /* 0x0000 = remove whole primitive only (xyz) + * 0x1018 = remove whole primitive only (xy), clamp z + * 0x1080 = clip primitive (xyz) + * 0x1098 = clip primitive (xy), clamp z + */ + so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1); + so_data (so, 0x1080); /* no idea what 0f90 does */ so_method(so, tesla, 0x0f90, 1); so_data (so, 0); } else { so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1); so_data (so, 0); + so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1); + so_data (so, 0x0000); so_method(so, tesla, 0x0f90, 1); so_data (so, 1); } -- cgit v1.2.3 From 5f4f7ad965c40327f16297606ed4f425598bfc2c Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Fri, 25 Sep 2009 10:53:01 +0200 Subject: nv50: fix TEX for WriteMask not equal 0xf If you e.g. only need alpha, it ends up in the first reg, not the last, as it would when reading rgb too. --- src/gallium/drivers/nv50/nv50_program.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 272fd8d90ba..576d075318f 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1166,10 +1166,11 @@ emit_tex(struct nv50_pc *pc, struct nv50_reg **dst, unsigned mask, emit(pc, e); #if 1 - if (mask & 1) emit_mov(pc, dst[0], t[0]); - if (mask & 2) emit_mov(pc, dst[1], t[1]); - if (mask & 4) emit_mov(pc, dst[2], t[2]); - if (mask & 8) emit_mov(pc, dst[3], t[3]); + c = 0; + if (mask & 1) emit_mov(pc, dst[0], t[c++]); + if (mask & 2) emit_mov(pc, dst[1], t[c++]); + if (mask & 4) emit_mov(pc, dst[2], t[c++]); + if (mask & 8) emit_mov(pc, dst[3], t[c]); free_temp4(pc, t); #else -- cgit v1.2.3 From a0fbc01ceaef08b33f97936d8840a6f48ec1654d Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 25 Sep 2009 10:48:19 +0200 Subject: softpipe: Do not advertise support for L16 and YCBCR formats. --- src/gallium/drivers/softpipe/sp_screen.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 3c61357eba8..81fb7aa20c6 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -135,6 +135,9 @@ softpipe_is_format_supported( struct pipe_screen *screen, target == PIPE_TEXTURE_CUBE); switch(format) { + case PIPE_FORMAT_L16_UNORM: + case PIPE_FORMAT_YCBCR_REV: + case PIPE_FORMAT_YCBCR: case PIPE_FORMAT_DXT1_RGB: case PIPE_FORMAT_DXT1_RGBA: case PIPE_FORMAT_DXT3_RGBA: -- cgit v1.2.3 From 69c7fc128c59bf72df461dbd583bf9794d9ed34d Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 25 Sep 2009 10:57:33 +0200 Subject: softpipe: Grab fs output z from the correct file. --- src/gallium/drivers/softpipe/sp_fs_exec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c index c469ac63407..4076114d392 100644 --- a/src/gallium/drivers/softpipe/sp_fs_exec.c +++ b/src/gallium/drivers/softpipe/sp_fs_exec.c @@ -151,7 +151,7 @@ exec_run( const struct sp_fragment_shader *base, { uint j; for (j = 0; j < 4; j++) { - quad->output.depth[j] = machine->Outputs[0].xyzw[2].f[j]; + quad->output.depth[j] = machine->Outputs[i].xyzw[2].f[j]; } } break; -- cgit v1.2.3 From 07183b73ebafe2d1083f1c572978317768725b99 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 26 Sep 2009 16:39:13 +1000 Subject: r300g: fix texture pitch to correct value. pitch is pixels - 1, not bytes. --- src/gallium/drivers/r300/r300_texture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 7c041d17f71..e8078ea9f13 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -37,7 +37,7 @@ static void r300_setup_texture_state(struct r300_texture* tex, /* XXX */ state->format1 = r300_translate_texformat(tex->tex.format); - state->format2 = r300_texture_get_stride(tex, 0); + state->format2 = (r300_texture_get_stride(tex, 0) / tex->tex.block.size) - 1; /* Assume (somewhat foolishly) that oversized textures will * not be permitted by the state tracker. */ -- cgit v1.2.3 From 20d3c85128192b2d3f75b68f47ab9aadc2719c5a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 26 Sep 2009 18:24:34 +1000 Subject: r300g: add z16 unorm texture format --- src/gallium/drivers/r300/r300_texture.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index 697669147d8..78ee0f1611a 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -75,6 +75,8 @@ static INLINE uint32_t r300_translate_texformat(enum pipe_format format) /* Z5_Y6_X5 */ case PIPE_FORMAT_R16_SNORM: return R300_EASY_TX_FORMAT(X, X, X, X, Z5Y6X5); + case PIPE_FORMAT_Z16_UNORM: + return R300_EASY_TX_FORMAT(X, X, X, X, X16); default: debug_printf("r300: Implementation error: " "Got unsupported texture format %s in %s\n", -- cgit v1.2.3 From 28f531e3fe95c9fad2bf2f09aef0343ab079bff2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 26 Sep 2009 18:25:00 +1000 Subject: r300g: report GL1.5, enable cap bits for OQ and shadow. Its not like it works well on 1.3 so may as well reach for greater heights. Signed-off-by: Dave Airlie --- src/gallium/drivers/r300/r300_screen.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 3b5b1bbd37f..8296d56840f 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -101,11 +101,9 @@ static int r300_get_param(struct pipe_screen* pscreen, int param) case PIPE_CAP_MAX_RENDER_TARGETS: return 4; case PIPE_CAP_OCCLUSION_QUERY: - /* IN THEORY */ - return 0; + return 1; case PIPE_CAP_TEXTURE_SHADOW_MAP: - /* IN THEORY */ - return 0; + return 1; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: if (r300screen->caps->is_r500) { /* 13 == 4096x4096 */ -- cgit v1.2.3 From 1df539ce87ab38ebae67d63a353b01f4cf5edc79 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sat, 26 Sep 2009 09:33:32 +0100 Subject: llvmpipe: Allow building with LLVM 2.6 too. --- src/gallium/drivers/llvmpipe/lp_jit.c | 5 +++++ src/gallium/drivers/llvmpipe/lp_test_format.c | 5 +++++ src/gallium/drivers/llvmpipe/lp_test_main.c | 5 +++++ 3 files changed, 15 insertions(+) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c index b4a22ff4a97..f7111c1e5cf 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.c +++ b/src/gallium/drivers/llvmpipe/lp_jit.c @@ -147,6 +147,11 @@ lp_jit_screen_init(struct llvmpipe_screen *screen) { char *error = NULL; +#ifdef LLVM_NATIVE_ARCH + LLVMLinkInJIT(); + LLVMInitializeNativeTarget(); +#endif + screen->module = LLVMModuleCreateWithName("llvmpipe"); screen->provider = LLVMCreateModuleProviderForExistingModule(screen->module); diff --git a/src/gallium/drivers/llvmpipe/lp_test_format.c b/src/gallium/drivers/llvmpipe/lp_test_format.c index d8455e56490..7d83f899e6a 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_format.c +++ b/src/gallium/drivers/llvmpipe/lp_test_format.c @@ -264,6 +264,11 @@ int main(int argc, char **argv) unsigned i; int ret; +#ifdef LLVM_NATIVE_ARCH + LLVMLinkInJIT(); + LLVMInitializeNativeTarget(); +#endif + for (i = 0; i < sizeof(test_cases)/sizeof(test_cases[0]); ++i) if(!test_format(&test_cases[i])) ret = 1; diff --git a/src/gallium/drivers/llvmpipe/lp_test_main.c b/src/gallium/drivers/llvmpipe/lp_test_main.c index 4592dc0b2d0..f07fa256f16 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_main.c +++ b/src/gallium/drivers/llvmpipe/lp_test_main.c @@ -365,6 +365,11 @@ int main(int argc, char **argv) n = atoi(argv[i]); } +#ifdef LLVM_NATIVE_ARCH + LLVMLinkInJIT(); + LLVMInitializeNativeTarget(); +#endif + if(fp) { /* Warm up the caches */ test_some(0, NULL, 100); -- cgit v1.2.3 From ec9c02187e698c26d7df3e408c1173acca9ccdd0 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 26 Sep 2009 18:38:07 +1000 Subject: r300g: add missing break in OQ emit --- src/gallium/drivers/r300/r300_emit.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index a1b36ba2ed1..77ce431cdc3 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -381,6 +381,7 @@ void r300_emit_query_end(struct r300_context* r300, OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 0), 0, RADEON_GEM_DOMAIN_GTT, 0); + break; default: debug_printf("r300: Implementation error: Chipset reports %d" " pixel pipes!\n", caps->num_frag_pipes); -- cgit v1.2.3 From 9bf85f6b95cb684d16b6035381b1f8a9c44f473f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 26 Sep 2009 18:38:39 +1000 Subject: r300g: only pass complete texture state to hw setup function No point passing things twice here, also allows more state to be setup properly. --- src/gallium/drivers/r300/r300_texture.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index e8078ea9f13..2ec07b453db 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -22,34 +22,32 @@ #include "r300_texture.h" -static void r300_setup_texture_state(struct r300_texture* tex, - unsigned width, - unsigned height, - unsigned levels) +static void r300_setup_texture_state(struct r300_texture* tex) { struct r300_texture_state* state = &tex->state; + struct pipe_texture *pt = &tex->tex; - state->format0 = R300_TX_WIDTH((width - 1) & 0x7ff) | - R300_TX_HEIGHT((height - 1) & 0x7ff) | - R300_TX_NUM_LEVELS(levels) | + state->format0 = R300_TX_WIDTH((pt->width[0] - 1) & 0x7ff) | + R300_TX_HEIGHT((pt->height[0] - 1) & 0x7ff) | + R300_TX_NUM_LEVELS(pt->last_level) | R300_TX_PITCH_EN; /* XXX */ - state->format1 = r300_translate_texformat(tex->tex.format); + state->format1 = r300_translate_texformat(pt->format); - state->format2 = (r300_texture_get_stride(tex, 0) / tex->tex.block.size) - 1; + state->format2 = (r300_texture_get_stride(tex, 0) / pt->block.size) - 1; /* Assume (somewhat foolishly) that oversized textures will * not be permitted by the state tracker. */ - if (width > 2048) { + if (pt->width[0] > 2048) { state->format2 |= R500_TXWIDTH_BIT11; } - if (height > 2048) { + if (pt->height[0] > 2048) { state->format2 |= R500_TXHEIGHT_BIT11; } debug_printf("r300: Set texture state (%dx%d, %d levels)\n", - width, height, levels); + pt->width[0], pt->height[0], pt->last_level); } /** @@ -120,8 +118,7 @@ static struct pipe_texture* r300_setup_miptree(tex); - r300_setup_texture_state(tex, template->width[0], template->height[0], - template->last_level); + r300_setup_texture_state(tex); tex->buffer = screen->buffer_create(screen, 1024, PIPE_BUFFER_USAGE_PIXEL, @@ -204,7 +201,7 @@ static struct pipe_texture* tex->stride_override = *stride; /* XXX */ - r300_setup_texture_state(tex, tex->tex.width[0], tex->tex.height[0], 0); + r300_setup_texture_state(tex); pipe_buffer_reference(&tex->buffer, buffer); -- cgit v1.2.3 From eb5dd947fbed35478784e777fe2e59564fee051b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 26 Sep 2009 19:32:46 +1000 Subject: r300g: add tx depth support in register. also enable cube/3d bits in txformat reg --- src/gallium/drivers/r300/r300_reg.h | 1 + src/gallium/drivers/r300/r300_texture.c | 7 +++++++ 2 files changed, 8 insertions(+) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h index 03cd219cde9..3abff5db622 100644 --- a/src/gallium/drivers/r300/r300_reg.h +++ b/src/gallium/drivers/r300/r300_reg.h @@ -1478,6 +1478,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_TX_PITCH_EN (1 << 31) # define R300_TX_WIDTH(x) ((x) << 0) # define R300_TX_HEIGHT(x) ((x) << 11) +# define R300_TX_DEPTH(x) ((x) << 22) # define R300_TX_NUM_LEVELS(x) ((x) << 26) #define R300_TX_FORMAT1_0 0x44C0 diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 2ec07b453db..ce60ded7caf 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -29,11 +29,18 @@ static void r300_setup_texture_state(struct r300_texture* tex) state->format0 = R300_TX_WIDTH((pt->width[0] - 1) & 0x7ff) | R300_TX_HEIGHT((pt->height[0] - 1) & 0x7ff) | + R300_TX_DEPTH(util_logbase2(pt->depth[0]) & 0xf) | R300_TX_NUM_LEVELS(pt->last_level) | R300_TX_PITCH_EN; /* XXX */ state->format1 = r300_translate_texformat(pt->format); + if (pt->target == PIPE_TEXTURE_CUBE) { + state->format1 |= R300_TX_FORMAT_CUBIC_MAP; + } + if (pt->target == PIPE_TEXTURE_3D) { + state->format1 |= R300_TX_FORMAT_3D; + } state->format2 = (r300_texture_get_stride(tex, 0) / pt->block.size) - 1; -- cgit v1.2.3 From a77226071f6814a53358a5d6caff685889d0e4ec Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sun, 27 Sep 2009 10:56:42 -0400 Subject: softpipe: Grab a ref when the fb is set. Nasty bug when the surface is freed and another is allocated right on top of it. The next time we set the fb state SP thinks it's the same surface and doesn't flush, and when the flush eventually happens the surface belongs to a completely different texture. --- src/gallium/drivers/softpipe/sp_context.c | 9 +++++++-- src/gallium/drivers/softpipe/sp_state_surface.c | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index e1e31ab047a..94d000a5acc 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -94,12 +94,17 @@ softpipe_destroy( struct pipe_context *pipe ) softpipe->quad.depth_test->destroy( softpipe->quad.depth_test ); softpipe->quad.blend->destroy( softpipe->quad.blend ); - for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { sp_destroy_tile_cache(softpipe->cbuf_cache[i]); + pipe_surface_reference(&softpipe->framebuffer.cbufs[i], NULL); + } sp_destroy_tile_cache(softpipe->zsbuf_cache); + pipe_surface_reference(&softpipe->framebuffer.zsbuf, NULL); - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { sp_destroy_tex_tile_cache(softpipe->tex_cache[i]); + pipe_texture_reference(&softpipe->texture[i], NULL); + } for (i = 0; i < Elements(softpipe->constants); i++) { if (softpipe->constants[i].buffer) { diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c index c8f55c3cec4..bc0e2011300 100644 --- a/src/gallium/drivers/softpipe/sp_state_surface.c +++ b/src/gallium/drivers/softpipe/sp_state_surface.c @@ -56,7 +56,7 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, sp_flush_tile_cache(sp->cbuf_cache[i]); /* assign new */ - sp->framebuffer.cbufs[i] = fb->cbufs[i]; + pipe_surface_reference(&sp->framebuffer.cbufs[i], fb->cbufs[i]); /* update cache */ sp_tile_cache_set_surface(sp->cbuf_cache[i], fb->cbufs[i]); @@ -71,7 +71,7 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, sp_flush_tile_cache(sp->zsbuf_cache); /* assign new */ - sp->framebuffer.zsbuf = fb->zsbuf; + pipe_surface_reference(&sp->framebuffer.zsbuf, fb->zsbuf); /* update cache */ sp_tile_cache_set_surface(sp->zsbuf_cache, fb->zsbuf); -- cgit v1.2.3 From 60d72d9e45b08c14ea4195950302f93e52e03603 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 23 Sep 2009 11:53:50 -0700 Subject: i915g: Use boolean --- src/gallium/drivers/i915simple/i915_texture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 6a6c6542717..1d0329817d9 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -165,7 +165,7 @@ i915_scanout_layout(struct i915_texture *tex) struct pipe_texture *pt = &tex->base; if (pt->last_level > 0 || pt->block.size != 4) - return 0; + return FALSE; i915_miptree_set_level_info(tex, 0, 1, tex->base.width[0], -- cgit v1.2.3 From 973e9a774a176be3a8f0849892b568888d41e932 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 23 Sep 2009 11:57:18 -0700 Subject: i915g: Tile shared buffers as well --- src/gallium/drivers/i915simple/i915_texture.c | 47 +++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 1d0329817d9..15ccc1fc73b 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -191,6 +191,38 @@ i915_scanout_layout(struct i915_texture *tex) return TRUE; } +/** + * Special case to deal with shared textures. + */ +static boolean +i915_display_target_layout(struct i915_texture *tex) +{ + struct pipe_texture *pt = &tex->base; + + if (pt->last_level > 0 || pt->block.size != 4) + return FALSE; + + /* fallback to normal textures for small textures */ + if (tex->base.width[0] < 240) + return FALSE; + + i915_miptree_set_level_info(tex, 0, 1, + tex->base.width[0], + tex->base.height[0], + 1); + i915_miptree_set_image_offset(tex, 0, 0, 0, 0); + + tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size); + tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8); + tex->hw_tiled = INTEL_TILE_X; + + debug_printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, + tex->base.width[0], tex->base.height[0], pt->block.size, + tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy); + + return TRUE; +} + static void i915_miptree_layout_2d(struct i915_texture *tex) { @@ -201,6 +233,16 @@ i915_miptree_layout_2d(struct i915_texture *tex) unsigned nblocksx = pt->nblocksx[0]; unsigned nblocksy = pt->nblocksy[0]; + /* used for scanouts that need special layouts */ + if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) + if (i915_scanout_layout(tex)) + return; + + /* for shared buffers we use some very like scanout */ + if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) + if (i915_display_target_layout(tex)) + return; + tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4); tex->total_nblocksy = 0; @@ -351,6 +393,11 @@ i945_miptree_layout_2d(struct i915_texture *tex) if (i915_scanout_layout(tex)) return; + /* for shared buffers we use some very like scanout */ + if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) + if (i915_display_target_layout(tex)) + return; + tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4); /* May need to adjust pitch to accomodate the placement of -- cgit v1.2.3 From 2d71b541d7de818f4cb47a61d3a86c0ffbb6163c Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sun, 27 Sep 2009 13:11:49 -0700 Subject: i915g: Fix warning --- src/gallium/drivers/i915simple/i915_prim_vbuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index b3a7774fd6a..aee8819ed91 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -198,7 +198,7 @@ i915_vbuf_render_map_vertices(struct vbuf_render *render) struct intel_winsys *iws = i915->iws; if (i915->vbo_flushed) - debug_printf("%s bad vbo flush occured stalling on hw\n"); + debug_printf("%s bad vbo flush occured stalling on hw\n", __func__); i915_render->vbo_ptr = iws->buffer_map(iws, i915_render->vbo, TRUE); -- cgit v1.2.3 From 48c45959ee106727fe9dd2d57bc0ca278710aab8 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sun, 27 Sep 2009 13:12:11 -0700 Subject: i915g: Submit direct vertex buffers --- src/gallium/drivers/i915simple/i915_prim_vbuf.c | 33 +++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index aee8819ed91..d50201642bd 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -389,14 +389,43 @@ i915_vbuf_render_draw_arrays(struct vbuf_render *render, uint nr) { struct i915_vbuf_render *i915_render = i915_vbuf_render(render); + struct i915_context *i915 = i915_render->i915; if (i915_render->fallback) { draw_arrays_fallback(render, start, nr); return; } - /* JB: TODO submit direct cmds */ - draw_arrays_fallback(render, start, nr); + if (i915->dirty) + i915_update_derived(i915); + + if (i915->hardware_dirty) + i915_emit_hardware_state(i915); + + if (!BEGIN_BATCH(2, 0)) { + FLUSH_BATCH(NULL); + + /* Make sure state is re-emitted after a flush: + */ + i915_update_derived(i915); + i915_emit_hardware_state(i915); + i915->vbo_flushed = 1; + + if (!BEGIN_BATCH(2, 0)) { + assert(0); + goto out; + } + } + + OUT_BATCH(_3DPRIMITIVE | + PRIM_INDIRECT | + PRIM_INDIRECT_SEQUENTIAL | + i915_render->hwprim | + nr); + OUT_BATCH(start); /* Beginning vertex index */ + +out: + return; } /** -- cgit v1.2.3 From 225c3375fdfc4a3744c3a7a777664ef94923a2ce Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 27 Sep 2009 20:31:55 +1000 Subject: r300g: silence compiler warning --- src/gallium/drivers/r300/r300_state_derived.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 5f6b225d340..62da8e293a1 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -164,7 +164,7 @@ static void r300_vs_tab_routes(struct r300_context* r300, vinfo->hwfmt[3] |= (4 << (3 * i)); } - for (i; i < texs; i++) { + for (; i < texs; i++) { draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, draw_find_vs_output(r300->draw, TGSI_SEMANTIC_GENERIC, i)); vinfo->hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i); -- cgit v1.2.3 From b1252c7a342e24571ccf5fe94938bbabbdf9aa11 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 27 Sep 2009 20:34:13 +1000 Subject: r300g: rewrite RS state setup. Not 100% sure this is correct, but its more correct than what was here previous however it may require changes in the input routing for the frag shader. --- src/gallium/drivers/r300/r300_state_derived.c | 37 ++++++++++----------------- 1 file changed, 13 insertions(+), 24 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 62da8e293a1..5493a098cba 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -334,48 +334,37 @@ static void r300_update_rs_block(struct r300_context* r300) struct r300_rs_block* rs = r300->rs_block; struct tgsi_shader_info* info = &r300->fs->info; int* tab = r300->vertex_info.fs_tab; - int col_count = 0, fp_offset = 0, i, memory_pos, tex_count = 0; - + int col_count = 0, fp_offset = 0, i, tex_count = 0; + int rs_tex_comp = 0; memset(rs, 0, sizeof(struct r300_rs_block)); if (r300_screen(r300->context.screen)->caps->is_r500) { for (i = 0; i < info->num_inputs; i++) { assert(tab[i] != -1); - memory_pos = tab[i] * 4; switch (info->input_semantic_name[i]) { case TGSI_SEMANTIC_COLOR: rs->ip[col_count] |= - R500_RS_COL_PTR(memory_pos) | + R500_RS_COL_PTR(col_count) | R500_RS_COL_FMT(R300_RS_COL_FMT_RGBA); col_count++; break; case TGSI_SEMANTIC_GENERIC: rs->ip[tex_count] |= - R500_RS_SEL_S(memory_pos) | - R500_RS_SEL_T(memory_pos + 1) | - R500_RS_SEL_R(memory_pos + 2) | - R500_RS_SEL_Q(memory_pos + 3); + R500_RS_SEL_S(rs_tex_comp) | + R500_RS_SEL_T(rs_tex_comp + 1) | + R500_RS_SEL_R(rs_tex_comp + 2) | + R500_RS_SEL_Q(rs_tex_comp + 3); tex_count++; + rs_tex_comp += 4; break; default: break; } } - if (col_count == 0) { - rs->ip[0] |= R500_RS_COL_FMT(R300_RS_COL_FMT_0001); - } - - if (tex_count == 0) { - rs->ip[0] |= - R500_RS_SEL_S(R500_RS_IP_PTR_K0) | - R500_RS_SEL_T(R500_RS_IP_PTR_K0) | - R500_RS_SEL_R(R500_RS_IP_PTR_K0) | - R500_RS_SEL_Q(R500_RS_IP_PTR_K1); - } - /* Rasterize at least one color, or bad things happen. */ if ((col_count == 0) && (tex_count == 0)) { + rs->ip[0] |= R500_RS_COL_FMT(R300_RS_COL_FMT_0001); col_count++; } @@ -393,22 +382,22 @@ static void r300_update_rs_block(struct r300_context* r300) } else { for (i = 0; i < info->num_inputs; i++) { assert(tab[i] != -1); - memory_pos = tab[i] * 4; switch (info->input_semantic_name[i]) { case TGSI_SEMANTIC_COLOR: rs->ip[col_count] |= - R300_RS_COL_PTR(memory_pos) | + R300_RS_COL_PTR(col_count) | R300_RS_COL_FMT(R300_RS_COL_FMT_RGBA); col_count++; break; case TGSI_SEMANTIC_GENERIC: rs->ip[tex_count] |= - R300_RS_TEX_PTR(memory_pos) | + R300_RS_TEX_PTR(rs_tex_count) | R300_RS_SEL_S(R300_RS_SEL_C0) | R300_RS_SEL_T(R300_RS_SEL_C1) | R300_RS_SEL_R(R300_RS_SEL_C2) | R300_RS_SEL_Q(R300_RS_SEL_C3); tex_count++; + rs_tex_count+=4; break; default: break; @@ -445,7 +434,7 @@ static void r300_update_rs_block(struct r300_context* r300) } } - rs->count = (tex_count * 4) | (col_count << R300_IC_COUNT_SHIFT) | + rs->count = (rs_tex_comp) | (col_count << R300_IC_COUNT_SHIFT) | R300_HIRES_EN; rs->inst_count = MAX2(MAX2(col_count - 1, tex_count - 1), 0); -- cgit v1.2.3 From d85fe842b86aef522e0e749d9360d85052a6e8cc Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 28 Sep 2009 06:42:25 +1000 Subject: r300g: fix r300 rs path --- src/gallium/drivers/r300/r300_state_derived.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 5493a098cba..2bbbcdfd9c2 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -391,13 +391,13 @@ static void r300_update_rs_block(struct r300_context* r300) break; case TGSI_SEMANTIC_GENERIC: rs->ip[tex_count] |= - R300_RS_TEX_PTR(rs_tex_count) | + R300_RS_TEX_PTR(rs_tex_comp) | R300_RS_SEL_S(R300_RS_SEL_C0) | R300_RS_SEL_T(R300_RS_SEL_C1) | R300_RS_SEL_R(R300_RS_SEL_C2) | R300_RS_SEL_Q(R300_RS_SEL_C3); tex_count++; - rs_tex_count+=4; + rs_tex_comp+=4; break; default: break; -- cgit v1.2.3 From a6eb593072298d60286f49a09e6d3a849b684dfb Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sun, 27 Sep 2009 22:15:15 +0200 Subject: r300g: add some debugging info --- src/gallium/drivers/r300/r300_cs.h | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h index 0a7e4703636..883f0a02dc5 100644 --- a/src/gallium/drivers/r300/r300_cs.h +++ b/src/gallium/drivers/r300/r300_cs.h @@ -68,11 +68,17 @@ } while (0) #define OUT_CS(value) do { \ + if (VERY_VERBOSE_CS || VERY_VERBOSE_REGISTERS) { \ + DBG(cs_context_copy, DBG_CS, "r300: writing %08x\n", value); \ + } \ cs_winsys->write_cs_dword(cs_winsys, (value)); \ cs_count--; \ } while (0) #define OUT_CS_32F(value) do { \ + if (VERY_VERBOSE_CS || VERY_VERBOSE_REGISTERS) { \ + DBG(cs_context_copy, DBG_CS, "r300: writing %f\n", value); \ + } \ cs_winsys->write_cs_dword(cs_winsys, fui(value)); \ cs_count--; \ } while (0) @@ -82,8 +88,9 @@ DBG(cs_context_copy, DBG_CS, "r300: writing 0x%08X to register 0x%04X\n", \ value, register); \ assert(register); \ - OUT_CS(CP_PACKET0(register, 0)); \ - OUT_CS(value); \ + cs_winsys->write_cs_dword(cs_winsys, CP_PACKET0(register, 0)); \ + cs_winsys->write_cs_dword(cs_winsys, value); \ + cs_count -= 2; \ } while (0) /* Note: This expects count to be the number of registers, @@ -93,7 +100,8 @@ DBG(cs_context_copy, DBG_CS, "r300: writing register sequence of %d to 0x%04X\n", \ count, register); \ assert(register); \ - OUT_CS(CP_PACKET0(register, ((count) - 1))); \ + cs_winsys->write_cs_dword(cs_winsys, CP_PACKET0((register), ((count) - 1))); \ + cs_count--; \ } while (0) #define OUT_CS_RELOC(bo, offset, rd, wd, flags) do { \ @@ -101,9 +109,9 @@ "domains (%d, %d, %d)\n", \ bo, offset, rd, wd, flags); \ assert(bo); \ - OUT_CS(offset); \ + cs_winsys->write_cs_dword(cs_winsys, offset); \ cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \ - cs_count -= 2; \ + cs_count -= 3; \ } while (0) #define END_CS do { \ @@ -131,24 +139,26 @@ DBG(cs_context_copy, DBG_CS, "r300: writing data sequence of %d to 0x%04X\n", \ count, register); \ assert(register); \ - OUT_CS(CP_PACKET0(register, ((count) - 1)) | RADEON_ONE_REG_WR); \ + cs_winsys->write_cs_dword(cs_winsys, CP_PACKET0((register), ((count) - 1)) | RADEON_ONE_REG_WR); \ + cs_count--; \ } while (0) #define CP_PACKET3(op, count) \ (RADEON_CP_PACKET3 | (op) | ((count) << 16)) #define OUT_CS_PKT3(op, count) do { \ - OUT_CS(CP_PACKET3(op, count)); \ + cs_winsys->write_cs_dword(cs_winsys, CP_PACKET3(op, count)); \ + cs_count--; \ } while (0) #define OUT_CS_INDEX_RELOC(bo, offset, count, rd, wd, flags) do { \ DBG(cs_context_copy, DBG_CS, "r300: writing relocation for index buffer %p," \ "offset %d\n", bo, offset); \ assert(bo); \ - OUT_CS(offset); \ - OUT_CS(count); \ + cs_winsys->write_cs_dword(cs_winsys, offset); \ + cs_winsys->write_cs_dword(cs_winsys, count); \ cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \ - cs_count -= 2; \ + cs_count -= 4; \ } while (0) #endif /* R300_CS_H */ -- cgit v1.2.3 From 8c8b77a5f3ec1dac0bddc98da3ccbb64f58f22e0 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sun, 27 Sep 2009 22:18:49 +0200 Subject: r300g: plug memory leak --- src/gallium/drivers/r300/r300_render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 737396d8d97..16f64040129 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -81,6 +81,7 @@ static boolean r300_render_allocate_vertices(struct vbuf_render* render, if (size + r300render->vbo_offset > r300render->vbo_size) { + pipe_buffer_reference(&r300->vbo, NULL); r300render->vbo = pipe_buffer_create(screen, 64, PIPE_BUFFER_USAGE_VERTEX, @@ -129,7 +130,6 @@ static void r300_render_release_vertices(struct vbuf_render* render) r300render->vbo_offset += r300render->vbo_max_used; r300render->vbo_max_used = 0; - r300->vbo = NULL; } static boolean r300_render_set_primitive(struct vbuf_render* render, -- cgit v1.2.3 From bedc6b7bdff40156b66cb2473c47512e5c95bdab Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sun, 27 Sep 2009 22:20:41 +0200 Subject: r300g: add some assertions Not sure why we are getting a shader with two inputs with position semantic, but we don't know how to handle it correctly so it's better to stop the app than lock the machine. --- src/gallium/drivers/r300/r300_state_derived.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 2bbbcdfd9c2..083861a0712 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -55,6 +55,7 @@ static void r300_vs_tab_routes(struct r300_context* r300, for (i = 0; i < info->num_inputs; i++) { switch (info->input_semantic_name[i]) { case TGSI_SEMANTIC_POSITION: + assert(pos == FALSE); pos = TRUE; tab[i] = 0; break; @@ -63,10 +64,12 @@ static void r300_vs_tab_routes(struct r300_context* r300, cols++; break; case TGSI_SEMANTIC_PSIZE: + assert(psize == FALSE); psize = TRUE; tab[i] = 15; break; case TGSI_SEMANTIC_FOG: + assert(fog == FALSE); fog = TRUE; /* Fall through */ case TGSI_SEMANTIC_GENERIC: -- cgit v1.2.3 From 98f6bea1685957fe9261e50f8a56f7dcb34f9b38 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sun, 27 Sep 2009 22:28:46 +0200 Subject: r300g: don't force vertex position for HW TCL path It could be generated by vertex shader. --- src/gallium/drivers/r300/r300_state_derived.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 083861a0712..ed5dc1b9ff0 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -128,7 +128,9 @@ static void r300_vs_tab_routes(struct r300_context* r300, vinfo->hwfmt[0] = 0x5555; /* XXX this is classic Mesa bonghits */ - if (!pos) { + /* We need to add vertex position attribute only for SW TCL case, + * for HW TCL case it could be generated by vertex shader */ + if (!pos && !r300screen->caps->has_tcl) { debug_printf("r300: Forcing vertex position attribute emit...\n"); /* Make room for the position attribute * at the beginning of the tab. */ -- cgit v1.2.3 From 540039887ac19b5fdd099ccaad6b44b5db973c25 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Sun, 27 Sep 2009 22:30:45 +0200 Subject: r300g: fix erroneous condition --- src/gallium/drivers/r300/r300_state_derived.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index ed5dc1b9ff0..5026afc8308 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -50,7 +50,7 @@ static void r300_vs_tab_routes(struct r300_context* r300, assert(info->num_inputs <= 16); - if (!r300screen->caps->has_tcl || !r300->rs_state->enable_vte) + if (!r300screen->caps->has_tcl) { for (i = 0; i < info->num_inputs; i++) { switch (info->input_semantic_name[i]) { -- cgit v1.2.3 From f547472bfa0a797adacc2a7688b4c1ba65381a80 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sun, 27 Sep 2009 19:49:06 -0400 Subject: g3dvl: pipe_video_context interface, softpipe impl, auxiliary libs --- configs/default | 2 +- configure.ac | 2 +- src/gallium/SConscript | 1 + src/gallium/auxiliary/vl/Makefile | 12 + src/gallium/auxiliary/vl/SConscript | 12 + src/gallium/auxiliary/vl/vl_bitstream_parser.c | 144 ++ src/gallium/auxiliary/vl/vl_bitstream_parser.h | 36 + src/gallium/auxiliary/vl/vl_compositor.c | 590 ++++++++ src/gallium/auxiliary/vl/vl_compositor.h | 47 + src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c | 1662 ++++++++++++++++++++++ src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h | 93 ++ src/gallium/auxiliary/vl/vl_shader_build.c | 215 +++ src/gallium/auxiliary/vl/vl_shader_build.h | 61 + src/gallium/drivers/softpipe/Makefile | 3 +- src/gallium/drivers/softpipe/SConscript | 3 +- src/gallium/drivers/softpipe/sp_texture.c | 56 + src/gallium/drivers/softpipe/sp_texture.h | 16 + src/gallium/drivers/softpipe/sp_video_context.c | 273 ++++ src/gallium/drivers/softpipe/sp_video_context.h | 30 + src/gallium/include/pipe/p_defines.h | 24 + src/gallium/include/pipe/p_format.h | 18 + src/gallium/include/pipe/p_screen.h | 16 +- src/gallium/include/pipe/p_video_context.h | 92 ++ src/gallium/include/pipe/p_video_state.h | 158 ++ 24 files changed, 3561 insertions(+), 5 deletions(-) create mode 100644 src/gallium/auxiliary/vl/Makefile create mode 100644 src/gallium/auxiliary/vl/SConscript create mode 100644 src/gallium/auxiliary/vl/vl_bitstream_parser.c create mode 100644 src/gallium/auxiliary/vl/vl_bitstream_parser.h create mode 100644 src/gallium/auxiliary/vl/vl_compositor.c create mode 100644 src/gallium/auxiliary/vl/vl_compositor.h create mode 100644 src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c create mode 100644 src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h create mode 100644 src/gallium/auxiliary/vl/vl_shader_build.c create mode 100644 src/gallium/auxiliary/vl/vl_shader_build.h create mode 100644 src/gallium/drivers/softpipe/sp_video_context.c create mode 100644 src/gallium/drivers/softpipe/sp_video_context.h create mode 100644 src/gallium/include/pipe/p_video_context.h create mode 100644 src/gallium/include/pipe/p_video_state.h (limited to 'src/gallium/drivers') diff --git a/configs/default b/configs/default index cb3ca1046f4..f1e2aa3ef5f 100644 --- a/configs/default +++ b/configs/default @@ -94,7 +94,7 @@ EGL_DRIVERS_DIRS = demo # Gallium directories and GALLIUM_DIRS = auxiliary drivers state_trackers -GALLIUM_AUXILIARY_DIRS = rbug draw translate cso_cache pipebuffer tgsi sct rtasm util indices +GALLIUM_AUXILIARY_DIRS = rbug draw translate cso_cache pipebuffer tgsi sct rtasm util indices vl GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a) GALLIUM_DRIVERS_DIRS = softpipe i915simple failover trace identity GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVERS_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a) diff --git a/configure.ac b/configure.ac index 2881bb6bc25..143fd31a022 100644 --- a/configure.ac +++ b/configure.ac @@ -417,7 +417,7 @@ WINDOW_SYSTEM="" GALLIUM_DIRS="auxiliary drivers state_trackers" GALLIUM_WINSYS_DIRS="" GALLIUM_WINSYS_DRM_DIRS="" -GALLIUM_AUXILIARY_DIRS="rbug draw translate cso_cache pipebuffer tgsi sct rtasm util indices" +GALLIUM_AUXILIARY_DIRS="rbug draw translate cso_cache pipebuffer tgsi sct rtasm util indices vl" GALLIUM_DRIVERS_DIRS="softpipe failover trace identity" GALLIUM_STATE_TRACKERS_DIRS="" diff --git a/src/gallium/SConscript b/src/gallium/SConscript index 89c69d7205e..8be84cddbe7 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -23,6 +23,7 @@ SConscript([ 'auxiliary/pipebuffer/SConscript', 'auxiliary/indices/SConscript', 'auxiliary/rbug/SConscript', + 'auxiliary/vl/SConscript', ]) for driver in env['drivers']: diff --git a/src/gallium/auxiliary/vl/Makefile b/src/gallium/auxiliary/vl/Makefile new file mode 100644 index 00000000000..71bfb937ad7 --- /dev/null +++ b/src/gallium/auxiliary/vl/Makefile @@ -0,0 +1,12 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = vl + +C_SOURCES = \ + vl_bitstream_parser.c \ + vl_mpeg12_mc_renderer.c \ + vl_compositor.c \ + vl_shader_build.c + +include ../../Makefile.template diff --git a/src/gallium/auxiliary/vl/SConscript b/src/gallium/auxiliary/vl/SConscript new file mode 100644 index 00000000000..eb50940c359 --- /dev/null +++ b/src/gallium/auxiliary/vl/SConscript @@ -0,0 +1,12 @@ +Import('*') + +vl = env.ConvenienceLibrary( + target = 'vl', + source = [ + 'vl_bitstream_parser.c', + 'vl_mpeg12_mc_renderer.c', + 'vl_compositor.c', + 'vl_shader_build.c', + ]) + +auxiliaries.insert(0, vl) diff --git a/src/gallium/auxiliary/vl/vl_bitstream_parser.c b/src/gallium/auxiliary/vl/vl_bitstream_parser.c new file mode 100644 index 00000000000..356faa13481 --- /dev/null +++ b/src/gallium/auxiliary/vl/vl_bitstream_parser.c @@ -0,0 +1,144 @@ +#include "vl_bitstream_parser.h" +#include +#include +#include + +static unsigned +grab_bits(unsigned cursor, unsigned how_many_bits, unsigned bitstream_elt) +{ + unsigned excess_bits = sizeof(unsigned) * CHAR_BIT - how_many_bits - cursor; + + assert(cursor < sizeof(unsigned) * CHAR_BIT); + assert(how_many_bits > 0 && how_many_bits <= sizeof(unsigned) * CHAR_BIT); + assert(cursor + how_many_bits <= sizeof(unsigned) * CHAR_BIT); + + return (bitstream_elt << excess_bits) >> (excess_bits + cursor); +} + +static unsigned +show_bits(unsigned cursor, unsigned how_many_bits, const unsigned *bitstream) +{ + unsigned cur_int = cursor / (sizeof(unsigned) * CHAR_BIT); + unsigned cur_bit = cursor % (sizeof(unsigned) * CHAR_BIT); + + assert(bitstream); + + if (cur_bit + how_many_bits > sizeof(unsigned) * CHAR_BIT) + { + return grab_bits(cur_bit, sizeof(unsigned) * CHAR_BIT - cur_bit, + bitstream[cur_int]) | + grab_bits(0, cur_bit + how_many_bits - sizeof(unsigned) * CHAR_BIT, + bitstream[cur_int + 1]) << (sizeof(unsigned) * CHAR_BIT - cur_bit); + } + else + return grab_bits(cur_bit, how_many_bits, bitstream[cur_int]); +} + +bool vl_bitstream_parser_init(struct vl_bitstream_parser *parser, + unsigned num_bitstreams, + const void **bitstreams, + const unsigned *sizes) +{ + assert(parser); + assert(num_bitstreams); + assert(bitstreams); + assert(sizes); + + parser->num_bitstreams = num_bitstreams; + parser->bitstreams = (const unsigned**)bitstreams; + parser->sizes = sizes; + parser->cur_bitstream = 0; + parser->cursor = 0; + + return true; +} + +void vl_bitstream_parser_cleanup(struct vl_bitstream_parser *parser) +{ + assert(parser); +} + +unsigned +vl_bitstream_parser_get_bits(struct vl_bitstream_parser *parser, + unsigned how_many_bits) +{ + unsigned bits; + + assert(parser); + + bits = vl_bitstream_parser_show_bits(parser, how_many_bits); + + vl_bitstream_parser_forward(parser, how_many_bits); + + return bits; +} + +unsigned +vl_bitstream_parser_show_bits(struct vl_bitstream_parser *parser, + unsigned how_many_bits) +{ + unsigned bits = 0; + unsigned shift = 0; + unsigned cursor; + unsigned cur_bitstream; + + assert(parser); + + cursor = parser->cursor; + cur_bitstream = parser->cur_bitstream; + + while (1) + { + unsigned bits_left = parser->sizes[cur_bitstream] * CHAR_BIT - cursor; + unsigned bits_to_show = how_many_bits > bits_left ? bits_left : how_many_bits; + + bits |= show_bits(cursor, bits_to_show, + parser->bitstreams[cur_bitstream]) << shift; + + if (how_many_bits > bits_to_show) + { + how_many_bits -= bits_to_show; + cursor = 0; + ++cur_bitstream; + shift += bits_to_show; + } + else + break; + } + + return bits; +} + +void vl_bitstream_parser_forward(struct vl_bitstream_parser *parser, + unsigned how_many_bits) +{ + assert(parser); + assert(how_many_bits); + + parser->cursor += how_many_bits; + + while (parser->cursor > parser->sizes[parser->cur_bitstream] * CHAR_BIT) + { + parser->cursor -= parser->sizes[parser->cur_bitstream++] * CHAR_BIT; + assert(parser->cur_bitstream < parser->num_bitstreams); + } +} + +void vl_bitstream_parser_rewind(struct vl_bitstream_parser *parser, + unsigned how_many_bits) +{ + signed c; + + assert(parser); + assert(how_many_bits); + + c = parser->cursor - how_many_bits; + + while (c < 0) + { + c += parser->sizes[parser->cur_bitstream--] * CHAR_BIT; + assert(parser->cur_bitstream < parser->num_bitstreams); + } + + parser->cursor = (unsigned)c; +} diff --git a/src/gallium/auxiliary/vl/vl_bitstream_parser.h b/src/gallium/auxiliary/vl/vl_bitstream_parser.h new file mode 100644 index 00000000000..46bebf470ff --- /dev/null +++ b/src/gallium/auxiliary/vl/vl_bitstream_parser.h @@ -0,0 +1,36 @@ +#ifndef vl_bitstream_parser_h +#define vl_bitstream_parser_h + +#include + +struct vl_bitstream_parser +{ + unsigned num_bitstreams; + const unsigned **bitstreams; + const unsigned *sizes; + unsigned cur_bitstream; + unsigned cursor; +}; + +bool vl_bitstream_parser_init(struct vl_bitstream_parser *parser, + unsigned num_bitstreams, + const void **bitstreams, + const unsigned *sizes); + +void vl_bitstream_parser_cleanup(struct vl_bitstream_parser *parser); + +unsigned +vl_bitstream_parser_get_bits(struct vl_bitstream_parser *parser, + unsigned how_many_bits); + +unsigned +vl_bitstream_parser_show_bits(struct vl_bitstream_parser *parser, + unsigned how_many_bits); + +void vl_bitstream_parser_forward(struct vl_bitstream_parser *parser, + unsigned how_many_bits); + +void vl_bitstream_parser_rewind(struct vl_bitstream_parser *parser, + unsigned how_many_bits); + +#endif /* vl_bitstream_parser_h */ diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c new file mode 100644 index 00000000000..0894421c0b8 --- /dev/null +++ b/src/gallium/auxiliary/vl/vl_compositor.c @@ -0,0 +1,590 @@ +#include "vl_compositor.h" +#include +#include +#include +#include +#include +#include +#include "vl_shader_build.h" + +struct vertex2f +{ + float x, y; +}; + +struct vertex4f +{ + float x, y, z, w; +}; + +struct vertex_shader_consts +{ + struct vertex4f dst_scale; + struct vertex4f dst_trans; + struct vertex4f src_scale; + struct vertex4f src_trans; +}; + +struct fragment_shader_consts +{ + struct vertex4f bias; + float matrix[16]; +}; + +/* + * Represents 2 triangles in a strip in normalized coords. + * Used to render the surface onto the frame buffer. + */ +static const struct vertex2f surface_verts[4] = +{ + {0.0f, 0.0f}, + {0.0f, 1.0f}, + {1.0f, 0.0f}, + {1.0f, 1.0f} +}; + +/* + * Represents texcoords for the above. We can use the position values directly. + * TODO: Duplicate these in the shader, no need to create a buffer. + */ +static const struct vertex2f *surface_texcoords = surface_verts; + +/* + * Identity color conversion constants, for debugging + */ +static const struct fragment_shader_consts identity = +{ + { + 0.0f, 0.0f, 0.0f, 0.0f + }, + { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + } +}; + +/* + * Converts ITU-R BT.601 YCbCr pixels to RGB pixels where: + * Y is in [16,235], Cb and Cr are in [16,240] + * R, G, and B are in [16,235] + */ +static const struct fragment_shader_consts bt_601 = +{ + { + 0.0f, 0.501960784f, 0.501960784f, 0.0f + }, + { + 1.0f, 0.0f, 1.371f, 0.0f, + 1.0f, -0.336f, -0.698f, 0.0f, + 1.0f, 1.732f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + } +}; + +/* + * Converts ITU-R BT.601 YCbCr pixels to RGB pixels where: + * Y is in [16,235], Cb and Cr are in [16,240] + * R, G, and B are in [0,255] + */ +static const struct fragment_shader_consts bt_601_full = +{ + { + 0.062745098f, 0.501960784f, 0.501960784f, 0.0f + }, + { + 1.164f, 0.0f, 1.596f, 0.0f, + 1.164f, -0.391f, -0.813f, 0.0f, + 1.164f, 2.018f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + } +}; + +/* + * Converts ITU-R BT.709 YCbCr pixels to RGB pixels where: + * Y is in [16,235], Cb and Cr are in [16,240] + * R, G, and B are in [16,235] + */ +static const struct fragment_shader_consts bt_709 = +{ + { + 0.0f, 0.501960784f, 0.501960784f, 0.0f + }, + { + 1.0f, 0.0f, 1.540f, 0.0f, + 1.0f, -0.183f, -0.459f, 0.0f, + 1.0f, 1.816f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + } +}; + +/* + * Converts ITU-R BT.709 YCbCr pixels to RGB pixels where: + * Y is in [16,235], Cb and Cr are in [16,240] + * R, G, and B are in [0,255] + */ +const struct fragment_shader_consts bt_709_full = +{ + { + 0.062745098f, 0.501960784f, 0.501960784f, 0.0f + }, + { + 1.164f, 0.0f, 1.793f, 0.0f, + 1.164f, -0.213f, -0.534f, 0.0f, + 1.164f, 2.115f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + } +}; + +static void +create_vert_shader(struct vl_compositor *c) +{ + const unsigned max_tokens = 50; + + struct pipe_shader_state vs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned ti; + + assert(c); + + tokens = (struct tgsi_token*)MALLOC(max_tokens * sizeof(struct tgsi_token)); + *(struct tgsi_version*)&tokens[0] = tgsi_build_version(); + header = (struct tgsi_header*)&tokens[1]; + *header = tgsi_build_header(); + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); + + ti = 3; + + /* + * decl i0 ; Vertex pos + * decl i1 ; Vertex texcoords + */ + for (unsigned i = 0; i < 2; i++) + { + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * decl c0 ; Scaling vector to scale vertex pos rect to destination size + * decl c1 ; Translation vector to move vertex pos rect into position + * decl c2 ; Scaling vector to scale texcoord rect to source size + * decl c3 ; Translation vector to move texcoord rect into position + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 3); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl o0 ; Vertex pos + * decl o1 ; Vertex texcoords + */ + for (unsigned i = 0; i < 2; i++) + { + decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* decl t0, t1 */ + decl = vl_decl_temps(0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * mad o0, i0, c0, c1 ; Scale and translate unit output rect to destination size and pos + * mad o1, i1, c2, c3 ; Scale and translate unit texcoord rect to source size and pos + */ + for (unsigned i = 0; i < 2; ++i) + { + inst = vl_inst4(TGSI_OPCODE_MAD, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i, TGSI_FILE_CONSTANT, i * 2, TGSI_FILE_CONSTANT, i * 2 + 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + assert(ti <= max_tokens); + + vs.tokens = tokens; + c->vertex_shader = c->pipe->create_vs_state(c->pipe, &vs); + FREE(tokens); +} + +static void +create_frag_shader(struct vl_compositor *c) +{ + const unsigned max_tokens = 50; + + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned ti; + + assert(c); + + tokens = (struct tgsi_token*)MALLOC(max_tokens * sizeof(struct tgsi_token)); + *(struct tgsi_version*)&tokens[0] = tgsi_build_version(); + header = (struct tgsi_header*)&tokens[1]; + *header = tgsi_build_header(); + *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); + + ti = 3; + + /* decl i0 ; Texcoords for s0 */ + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, 1, 0, 0, TGSI_INTERPOLATE_LINEAR); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl c0 ; Bias vector for CSC + * decl c1-c4 ; CSC matrix c1-c4 + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 4); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl t0 */ + decl = vl_decl_temps(0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl s0 ; Sampler for tex containing picture to display */ + decl = vl_decl_samplers(0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* tex2d t0, i0, s0 ; Read src pixel */ + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* sub t0, t0, c0 ; Subtract bias vector from pixel */ + inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* + * dp4 o0.x, t0, c1 ; Multiply pixel by the color conversion matrix + * dp4 o0.y, t0, c2 + * dp4 o0.z, t0, c3 + */ + for (unsigned i = 0; i < 3; ++i) + { + inst = vl_inst3(TGSI_OPCODE_DP4, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i + 1); + inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + assert(ti <= max_tokens); + + fs.tokens = tokens; + c->fragment_shader = c->pipe->create_fs_state(c->pipe, &fs); + FREE(tokens); +} + +static bool +init_pipe_state(struct vl_compositor *c) +{ + struct pipe_sampler_state sampler; + + assert(c); + + c->fb_state.nr_cbufs = 1; + c->fb_state.zsbuf = NULL; + + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; + sampler.compare_mode = PIPE_TEX_COMPARE_NONE; + sampler.compare_func = PIPE_FUNC_ALWAYS; + sampler.normalized_coords = 1; + /*sampler.prefilter = ;*/ + /*sampler.lod_bias = ;*/ + /*sampler.min_lod = ;*/ + /*sampler.max_lod = ;*/ + /*sampler.border_color[i] = ;*/ + /*sampler.max_anisotropy = ;*/ + c->sampler = c->pipe->create_sampler_state(c->pipe, &sampler); + + return true; +} + +static void cleanup_pipe_state(struct vl_compositor *c) +{ + assert(c); + + c->pipe->delete_sampler_state(c->pipe, c->sampler); +} + +static bool +init_shaders(struct vl_compositor *c) +{ + assert(c); + + create_vert_shader(c); + create_frag_shader(c); + + return true; +} + +static void cleanup_shaders(struct vl_compositor *c) +{ + assert(c); + + c->pipe->delete_vs_state(c->pipe, c->vertex_shader); + c->pipe->delete_fs_state(c->pipe, c->fragment_shader); +} + +static bool +init_buffers(struct vl_compositor *c) +{ + assert(c); + + /* + * Create our vertex buffer and vertex buffer element + * VB contains 4 vertices that render a quad covering the entire window + * to display a rendered surface + * Quad is rendered as a tri strip + */ + c->vertex_bufs[0].stride = sizeof(struct vertex2f); + c->vertex_bufs[0].max_index = 3; + c->vertex_bufs[0].buffer_offset = 0; + c->vertex_bufs[0].buffer = pipe_buffer_create + ( + c->pipe->screen, + 1, + PIPE_BUFFER_USAGE_VERTEX, + sizeof(struct vertex2f) * 4 + ); + + memcpy + ( + pipe_buffer_map(c->pipe->screen, c->vertex_bufs[0].buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + surface_verts, + sizeof(struct vertex2f) * 4 + ); + + pipe_buffer_unmap(c->pipe->screen, c->vertex_bufs[0].buffer); + + c->vertex_elems[0].src_offset = 0; + c->vertex_elems[0].vertex_buffer_index = 0; + c->vertex_elems[0].nr_components = 2; + c->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* + * Create our texcoord buffer and texcoord buffer element + * Texcoord buffer contains the TCs for mapping the rendered surface to the 4 vertices + */ + c->vertex_bufs[1].stride = sizeof(struct vertex2f); + c->vertex_bufs[1].max_index = 3; + c->vertex_bufs[1].buffer_offset = 0; + c->vertex_bufs[1].buffer = pipe_buffer_create + ( + c->pipe->screen, + 1, + PIPE_BUFFER_USAGE_VERTEX, + sizeof(struct vertex2f) * 4 + ); + + memcpy + ( + pipe_buffer_map(c->pipe->screen, c->vertex_bufs[1].buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + surface_texcoords, + sizeof(struct vertex2f) * 4 + ); + + pipe_buffer_unmap(c->pipe->screen, c->vertex_bufs[1].buffer); + + c->vertex_elems[1].src_offset = 0; + c->vertex_elems[1].vertex_buffer_index = 1; + c->vertex_elems[1].nr_components = 2; + c->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* + * Create our vertex shader's constant buffer + * Const buffer contains scaling and translation vectors + */ + c->vs_const_buf.buffer = pipe_buffer_create + ( + c->pipe->screen, + 1, + PIPE_BUFFER_USAGE_CONSTANT | PIPE_BUFFER_USAGE_DISCARD, + sizeof(struct vertex_shader_consts) + ); + + /* + * Create our fragment shader's constant buffer + * Const buffer contains the color conversion matrix and bias vectors + */ + c->fs_const_buf.buffer = pipe_buffer_create + ( + c->pipe->screen, + 1, + PIPE_BUFFER_USAGE_CONSTANT, + sizeof(struct fragment_shader_consts) + ); + + /* + * TODO: Refactor this into a seperate function, + * allow changing the CSC matrix at runtime to switch between regular & full versions + */ + memcpy + ( + pipe_buffer_map(c->pipe->screen, c->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + &bt_601_full, + sizeof(struct fragment_shader_consts) + ); + + pipe_buffer_unmap(c->pipe->screen, c->fs_const_buf.buffer); + + return true; +} + +static void +cleanup_buffers(struct vl_compositor *c) +{ + assert(c); + + for (unsigned i = 0; i < 2; ++i) + pipe_buffer_reference(&c->vertex_bufs[i].buffer, NULL); + + pipe_buffer_reference(&c->vs_const_buf.buffer, NULL); + pipe_buffer_reference(&c->fs_const_buf.buffer, NULL); +} + +bool vl_compositor_init(struct vl_compositor *compositor, struct pipe_context *pipe) +{ + assert(compositor); + + memset(compositor, 0, sizeof(struct vl_compositor)); + + compositor->pipe = pipe; + + if (!init_pipe_state(compositor)) + return false; + if (!init_shaders(compositor)) + { + cleanup_pipe_state(compositor); + return false; + } + if (!init_buffers(compositor)) + { + cleanup_shaders(compositor); + cleanup_pipe_state(compositor); + return false; + } + + return true; +} + +void vl_compositor_cleanup(struct vl_compositor *compositor) +{ + assert(compositor); + + cleanup_buffers(compositor); + cleanup_shaders(compositor); + cleanup_pipe_state(compositor); +} + +void vl_compositor_render(struct vl_compositor *compositor, + /*struct pipe_texture *backround, + struct pipe_video_rect *backround_area,*/ + struct pipe_texture *src_surface, + enum pipe_mpeg12_picture_type picture_type, + /*unsigned num_past_surfaces, + struct pipe_texture *past_surfaces, + unsigned num_future_surfaces, + struct pipe_texture *future_surfaces,*/ + struct pipe_video_rect *src_area, + struct pipe_texture *dst_surface, + struct pipe_video_rect *dst_area, + /*unsigned num_layers, + struct pipe_texture *layers, + struct pipe_video_rect *layer_src_areas, + struct pipe_video_rect *layer_dst_areas*/ + struct pipe_fence_handle **fence) +{ + struct vertex_shader_consts *vs_consts; + + assert(compositor); + assert(src_surface); + assert(src_area); + assert(dst_surface); + assert(dst_area); + assert(picture_type == PIPE_MPEG12_PICTURE_TYPE_FRAME); + + compositor->fb_state.width = dst_surface->width[0]; + compositor->fb_state.height = dst_surface->height[0]; + compositor->fb_state.cbufs[0] = compositor->pipe->screen->get_tex_surface + ( + compositor->pipe->screen, + dst_surface, + 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE + ); + + compositor->viewport.scale[0] = compositor->fb_state.width; + compositor->viewport.scale[1] = compositor->fb_state.height; + compositor->viewport.scale[2] = 1; + compositor->viewport.scale[3] = 1; + compositor->viewport.translate[0] = 0; + compositor->viewport.translate[1] = 0; + compositor->viewport.translate[2] = 0; + compositor->viewport.translate[3] = 0; + + compositor->pipe->set_framebuffer_state(compositor->pipe, &compositor->fb_state); + compositor->pipe->set_viewport_state(compositor->pipe, &compositor->viewport); + compositor->pipe->bind_sampler_states(compositor->pipe, 1, &compositor->sampler); + compositor->pipe->set_sampler_textures(compositor->pipe, 1, &src_surface); + compositor->pipe->bind_vs_state(compositor->pipe, compositor->vertex_shader); + compositor->pipe->bind_fs_state(compositor->pipe, compositor->fragment_shader); + compositor->pipe->set_vertex_buffers(compositor->pipe, 2, compositor->vertex_bufs); + compositor->pipe->set_vertex_elements(compositor->pipe, 2, compositor->vertex_elems); + compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_VERTEX, 0, &compositor->vs_const_buf); + compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_FRAGMENT, 0, &compositor->fs_const_buf); + + vs_consts = pipe_buffer_map + ( + compositor->pipe->screen, + compositor->vs_const_buf.buffer, + PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD + ); + + vs_consts->dst_scale.x = dst_area->w / (float)compositor->fb_state.cbufs[0]->width; + vs_consts->dst_scale.y = dst_area->h / (float)compositor->fb_state.cbufs[0]->height; + vs_consts->dst_scale.z = 1; + vs_consts->dst_scale.w = 1; + vs_consts->dst_trans.x = dst_area->x / (float)compositor->fb_state.cbufs[0]->width; + vs_consts->dst_trans.y = dst_area->y / (float)compositor->fb_state.cbufs[0]->height; + vs_consts->dst_trans.z = 0; + vs_consts->dst_trans.w = 0; + + vs_consts->src_scale.x = src_area->w / (float)src_surface->width[0]; + vs_consts->src_scale.y = src_area->h / (float)src_surface->height[0]; + vs_consts->src_scale.z = 1; + vs_consts->src_scale.w = 1; + vs_consts->src_trans.x = src_area->x / (float)src_surface->width[0]; + vs_consts->src_trans.y = src_area->y / (float)src_surface->height[0]; + vs_consts->src_trans.z = 0; + vs_consts->src_trans.w = 0; + + pipe_buffer_unmap(compositor->pipe->screen, compositor->vs_const_buf.buffer); + + compositor->pipe->draw_arrays(compositor->pipe, PIPE_PRIM_TRIANGLE_STRIP, 0, 4); + compositor->pipe->flush(compositor->pipe, PIPE_FLUSH_RENDER_CACHE, fence); + + pipe_surface_reference(&compositor->fb_state.cbufs[0], NULL); +} diff --git a/src/gallium/auxiliary/vl/vl_compositor.h b/src/gallium/auxiliary/vl/vl_compositor.h new file mode 100644 index 00000000000..2af41e1981f --- /dev/null +++ b/src/gallium/auxiliary/vl/vl_compositor.h @@ -0,0 +1,47 @@ +#ifndef vl_compositor_h +#define vl_compositor_h + +#include +#include +#include + +struct pipe_context; +struct pipe_texture; + +struct vl_compositor +{ + struct pipe_context *pipe; + + struct pipe_framebuffer_state fb_state; + void *sampler; + void *vertex_shader; + void *fragment_shader; + struct pipe_viewport_state viewport; + struct pipe_vertex_buffer vertex_bufs[2]; + struct pipe_vertex_element vertex_elems[2]; + struct pipe_constant_buffer vs_const_buf, fs_const_buf; +}; + +bool vl_compositor_init(struct vl_compositor *compositor, struct pipe_context *pipe); + +void vl_compositor_cleanup(struct vl_compositor *compositor); + +void vl_compositor_render(struct vl_compositor *compositor, + /*struct pipe_texture *backround, + struct pipe_video_rect *backround_area,*/ + struct pipe_texture *src_surface, + enum pipe_mpeg12_picture_type picture_type, + /*unsigned num_past_surfaces, + struct pipe_texture *past_surfaces, + unsigned num_future_surfaces, + struct pipe_texture *future_surfaces,*/ + struct pipe_video_rect *src_area, + struct pipe_texture *dst_surface, + struct pipe_video_rect *dst_area, + /*unsigned num_layers, + struct pipe_texture *layers, + struct pipe_video_rect *layer_src_areas, + struct pipe_video_rect *layer_dst_areas,*/ + struct pipe_fence_handle **fence); + +#endif /* vl_compositor_h */ diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c new file mode 100644 index 00000000000..7e73c5ced9f --- /dev/null +++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c @@ -0,0 +1,1662 @@ +#include "vl_mpeg12_mc_renderer.h" +#include +#include +#include +#include +#include +#include +#include +#include "vl_shader_build.h" + +#define DEFAULT_BUF_ALIGNMENT 1 +#define MACROBLOCK_WIDTH 16 +#define MACROBLOCK_HEIGHT 16 +#define BLOCK_WIDTH 8 +#define BLOCK_HEIGHT 8 +#define ZERO_BLOCK_NIL -1.0f +#define ZERO_BLOCK_IS_NIL(zb) ((zb).x < 0.0f) + +struct vertex2f +{ + float x, y; +}; + +struct vertex4f +{ + float x, y, z, w; +}; + +struct vertex_shader_consts +{ + struct vertex4f denorm; +}; + +struct fragment_shader_consts +{ + struct vertex4f multiplier; + struct vertex4f div; +}; + +/* + * Muliplier renormalizes block samples from 16 bits to 12 bits. + * Divider is used when calculating Y % 2 for choosing top or bottom + * field for P or B macroblocks. + * TODO: Use immediates. + */ +static const struct fragment_shader_consts fs_consts = { + {32767.0f / 255.0f, 32767.0f / 255.0f, 32767.0f / 255.0f, 0.0f}, + {0.5f, 2.0f, 0.0f, 0.0f} +}; + +struct vert_stream_0 +{ + struct vertex2f pos; + struct vertex2f luma_tc; + struct vertex2f cb_tc; + struct vertex2f cr_tc; +}; + +enum MACROBLOCK_TYPE +{ + MACROBLOCK_TYPE_INTRA, + MACROBLOCK_TYPE_FWD_FRAME_PRED, + MACROBLOCK_TYPE_FWD_FIELD_PRED, + MACROBLOCK_TYPE_BKWD_FRAME_PRED, + MACROBLOCK_TYPE_BKWD_FIELD_PRED, + MACROBLOCK_TYPE_BI_FRAME_PRED, + MACROBLOCK_TYPE_BI_FIELD_PRED, + + NUM_MACROBLOCK_TYPES +}; + +static void +create_intra_vert_shader(struct vl_mpeg12_mc_renderer *r) +{ + const unsigned max_tokens = 50; + + struct pipe_shader_state vs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned ti; + + assert(r); + + tokens = (struct tgsi_token *) malloc(max_tokens * sizeof(struct tgsi_token)); + *(struct tgsi_version *) &tokens[0] = tgsi_build_version(); + header = (struct tgsi_header *) &tokens[1]; + *header = tgsi_build_header(); + *(struct tgsi_processor *) &tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); + + ti = 3; + + /* + * decl i0 ; Vertex pos + * decl i1 ; Luma texcoords + * decl i2 ; Chroma Cb texcoords + * decl i3 ; Chroma Cr texcoords + */ + for (unsigned i = 0; i < 4; i++) + { + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * decl o0 ; Vertex pos + * decl o1 ; Luma texcoords + * decl o2 ; Chroma Cb texcoords + * decl o3 ; Chroma Cr texcoords + */ + for (unsigned i = 0; i < 4; i++) + { + decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * mov o0, i0 ; Move input vertex pos to output + * mov o1, i1 ; Move input luma texcoords to output + * mov o2, i2 ; Move input chroma Cb texcoords to output + * mov o3, i3 ; Move input chroma Cr texcoords to output + */ + for (unsigned i = 0; i < 4; ++i) + { + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + assert(ti <= max_tokens); + + vs.tokens = tokens; + r->i_vs = r->pipe->create_vs_state(r->pipe, &vs); + free(tokens); +} + +static void +create_intra_frag_shader(struct vl_mpeg12_mc_renderer *r) +{ + const unsigned max_tokens = 100; + + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned ti; + + assert(r); + + tokens = (struct tgsi_token *) malloc(max_tokens * sizeof(struct tgsi_token)); + *(struct tgsi_version *) &tokens[0] = tgsi_build_version(); + header = (struct tgsi_header *) &tokens[1]; + *header = tgsi_build_header(); + *(struct tgsi_processor *) &tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); + + ti = 3; + + /* + * decl i0 ; Luma texcoords + * decl i1 ; Chroma Cb texcoords + * decl i2 ; Chroma Cr texcoords + */ + for (unsigned i = 0; i < 3; ++i) + { + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl t0, t1 */ + decl = vl_decl_temps(0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl s0 ; Sampler for luma texture + * decl s1 ; Sampler for chroma Cb texture + * decl s2 ; Sampler for chroma Cr texture + */ + for (unsigned i = 0; i < 3; ++i) + { + decl = vl_decl_samplers(i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * tex2d t1, i0, s0 ; Read texel from luma texture + * mov t0.x, t1.x ; Move luma sample into .x component + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture + * mov t0.y, t1.x ; Move Cb sample into .y component + * tex2d t1, i2, s2 ; Read texel from chroma Cr texture + * mov t0.z, t1.x ; Move Cr sample into .z component + */ + for (unsigned i = 0; i < 3; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i, TGSI_FILE_SAMPLER, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* mul o0, t0, c0 ; Rescale texel to correct range */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + assert(ti <= max_tokens); + + fs.tokens = tokens; + r->i_fs = r->pipe->create_fs_state(r->pipe, &fs); + free(tokens); +} + +static void +create_frame_pred_vert_shader(struct vl_mpeg12_mc_renderer *r) +{ + const unsigned max_tokens = 100; + + struct pipe_shader_state vs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned ti; + + assert(r); + + tokens = (struct tgsi_token *) malloc(max_tokens * sizeof(struct tgsi_token)); + *(struct tgsi_version *) &tokens[0] = tgsi_build_version(); + header = (struct tgsi_header *) &tokens[1]; + *header = tgsi_build_header(); + *(struct tgsi_processor *) &tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); + + ti = 3; + + /* + * decl i0 ; Vertex pos + * decl i1 ; Luma texcoords + * decl i2 ; Chroma Cb texcoords + * decl i3 ; Chroma Cr texcoords + * decl i4 ; Ref surface top field texcoords + * decl i5 ; Ref surface bottom field texcoords (unused, packed in the same stream) + */ + for (unsigned i = 0; i < 6; i++) + { + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * decl o0 ; Vertex pos + * decl o1 ; Luma texcoords + * decl o2 ; Chroma Cb texcoords + * decl o3 ; Chroma Cr texcoords + * decl o4 ; Ref macroblock texcoords + */ + for (unsigned i = 0; i < 5; i++) + { + decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * mov o0, i0 ; Move input vertex pos to output + * mov o1, i1 ; Move input luma texcoords to output + * mov o2, i2 ; Move input chroma Cb texcoords to output + * mov o3, i3 ; Move input chroma Cr texcoords to output + */ + for (unsigned i = 0; i < 4; ++i) + { + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* add o4, i0, i4 ; Translate vertex pos by motion vec to form ref macroblock texcoords */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 4, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, 4); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + assert(ti <= max_tokens); + + vs.tokens = tokens; + r->p_vs[0] = r->pipe->create_vs_state(r->pipe, &vs); + free(tokens); +} + +static void +create_field_pred_vert_shader(struct vl_mpeg12_mc_renderer *r) +{ + assert(false); +} + +static void +create_frame_pred_frag_shader(struct vl_mpeg12_mc_renderer *r) +{ + const unsigned max_tokens = 100; + + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned ti; + + assert(r); + + tokens = (struct tgsi_token *) malloc(max_tokens * sizeof(struct tgsi_token)); + *(struct tgsi_version *) &tokens[0] = tgsi_build_version(); + header = (struct tgsi_header *) &tokens[1]; + *header = tgsi_build_header(); + *(struct tgsi_processor *) &tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); + + ti = 3; + + /* + * decl i0 ; Luma texcoords + * decl i1 ; Chroma Cb texcoords + * decl i2 ; Chroma Cr texcoords + * decl i3 ; Ref macroblock texcoords + */ + for (unsigned i = 0; i < 4; ++i) + { + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl t0, t1 */ + decl = vl_decl_temps(0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl s0 ; Sampler for luma texture + * decl s1 ; Sampler for chroma Cb texture + * decl s2 ; Sampler for chroma Cr texture + * decl s3 ; Sampler for ref surface texture + */ + for (unsigned i = 0; i < 4; ++i) + { + decl = vl_decl_samplers(i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * tex2d t1, i0, s0 ; Read texel from luma texture + * mov t0.x, t1.x ; Move luma sample into .x component + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture + * mov t0.y, t1.x ; Move Cb sample into .y component + * tex2d t1, i2, s2 ; Read texel from chroma Cr texture + * mov t0.z, t1.x ; Move Cr sample into .z component + */ + for (unsigned i = 0; i < 3; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i, TGSI_FILE_SAMPLER, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* mul t0, t0, c0 ; Rescale texel to correct range */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* tex2d t1, i3, s3 ; Read texel from ref macroblock */ + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 3, TGSI_FILE_SAMPLER, 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* add o0, t0, t1 ; Add ref and differential to form final output */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + assert(ti <= max_tokens); + + fs.tokens = tokens; + r->p_fs[0] = r->pipe->create_fs_state(r->pipe, &fs); + free(tokens); +} + +static void +create_field_pred_frag_shader(struct vl_mpeg12_mc_renderer *r) +{ + assert(false); +} + +static void +create_frame_bi_pred_vert_shader(struct vl_mpeg12_mc_renderer *r) +{ + const unsigned max_tokens = 100; + + struct pipe_shader_state vs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned ti; + + assert(r); + + tokens = (struct tgsi_token *) malloc(max_tokens * sizeof(struct tgsi_token)); + *(struct tgsi_version *) &tokens[0] = tgsi_build_version(); + header = (struct tgsi_header *) &tokens[1]; + *header = tgsi_build_header(); + *(struct tgsi_processor *) &tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header); + + ti = 3; + + /* + * decl i0 ; Vertex pos + * decl i1 ; Luma texcoords + * decl i2 ; Chroma Cb texcoords + * decl i3 ; Chroma Cr texcoords + * decl i4 ; First ref macroblock top field texcoords + * decl i5 ; First ref macroblock bottom field texcoords (unused, packed in the same stream) + * decl i6 ; Second ref macroblock top field texcoords + * decl i7 ; Second ref macroblock bottom field texcoords (unused, packed in the same stream) + */ + for (unsigned i = 0; i < 8; i++) + { + decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * decl o0 ; Vertex pos + * decl o1 ; Luma texcoords + * decl o2 ; Chroma Cb texcoords + * decl o3 ; Chroma Cr texcoords + * decl o4 ; First ref macroblock texcoords + * decl o5 ; Second ref macroblock texcoords + */ + for (unsigned i = 0; i < 6; i++) + { + decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * mov o0, i0 ; Move input vertex pos to output + * mov o1, i1 ; Move input luma texcoords to output + * mov o2, i2 ; Move input chroma Cb texcoords to output + * mov o3, i3 ; Move input chroma Cr texcoords to output + */ + for (unsigned i = 0; i < 4; ++i) + { + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* + * add o4, i0, i4 ; Translate vertex pos by motion vec to form first ref macroblock texcoords + * add o5, i0, i6 ; Translate vertex pos by motion vec to form second ref macroblock texcoords + */ + for (unsigned i = 0; i < 2; ++i) + { + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 4, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, (i + 2) * 2); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + assert(ti <= max_tokens); + + vs.tokens = tokens; + r->b_vs[0] = r->pipe->create_vs_state(r->pipe, &vs); + free(tokens); +} + +static void +create_field_bi_pred_vert_shader(struct vl_mpeg12_mc_renderer *r) +{ + assert(false); +} + +static void +create_frame_bi_pred_frag_shader(struct vl_mpeg12_mc_renderer *r) +{ + const unsigned max_tokens = 100; + + struct pipe_shader_state fs; + struct tgsi_token *tokens; + struct tgsi_header *header; + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + + unsigned ti; + + assert(r); + + tokens = (struct tgsi_token *) malloc(max_tokens * sizeof(struct tgsi_token)); + *(struct tgsi_version *) &tokens[0] = tgsi_build_version(); + header = (struct tgsi_header *) &tokens[1]; + *header = tgsi_build_header(); + *(struct tgsi_processor *) &tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header); + + ti = 3; + + /* + * decl i0 ; Luma texcoords + * decl i1 ; Chroma Cb texcoords + * decl i2 ; Chroma Cr texcoords + * decl i3 ; First ref macroblock texcoords + * decl i4 ; Second ref macroblock texcoords + */ + for (unsigned i = 0; i < 5; ++i) + { + decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm + * decl c1 ; Constant 1/2 in .x channel to use as weight to blend past and future texels + */ + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl o0 ; Fragment color */ + decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* decl t0-t2 */ + decl = vl_decl_temps(0, 2); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + + /* + * decl s0 ; Sampler for luma texture + * decl s1 ; Sampler for chroma Cb texture + * decl s2 ; Sampler for chroma Cr texture + * decl s3 ; Sampler for first ref surface texture + * decl s4 ; Sampler for second ref surface texture + */ + for (unsigned i = 0; i < 5; ++i) + { + decl = vl_decl_samplers(i, i); + ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); + } + + /* + * tex2d t1, i0, s0 ; Read texel from luma texture + * mov t0.x, t1.x ; Move luma sample into .x component + * tex2d t1, i1, s1 ; Read texel from chroma Cb texture + * mov t0.y, t1.x ; Move Cb sample into .y component + * tex2d t1, i2, s2 ; Read texel from chroma Cr texture + * mov t0.z, t1.x ; Move Cr sample into .z component + */ + for (unsigned i = 0; i < 3; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i, TGSI_FILE_SAMPLER, i); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* mul t0, t0, c0 ; Rescale texel to correct range */ + inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* + * tex2d t1, i3, s3 ; Read texel from first ref macroblock + * tex2d t2, i4, s4 ; Read texel from second ref macroblock + */ + for (unsigned i = 0; i < 2; ++i) + { + inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 3, TGSI_FILE_SAMPLER, i + 3); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + } + + /* lerp t1, c1.x, t1, t2 ; Blend past and future texels */ + inst = vl_inst4(TGSI_OPCODE_LRP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2); + inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X; + inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* add o0, t0, t1 ; Add past/future ref and differential to form final output */ + inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + /* end */ + inst = vl_end(); + ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); + + assert(ti <= max_tokens); + + fs.tokens = tokens; + r->b_fs[0] = r->pipe->create_fs_state(r->pipe, &fs); + free(tokens); +} + +static void +create_field_bi_pred_frag_shader(struct vl_mpeg12_mc_renderer *r) +{ + assert(false); +} + +static void +xfer_buffers_map(struct vl_mpeg12_mc_renderer *r) +{ + assert(r); + + for (unsigned i = 0; i < 3; ++i) + { + r->tex_transfer[i] = r->pipe->screen->get_tex_transfer + ( + r->pipe->screen, r->textures.all[i], + 0, 0, 0, PIPE_TRANSFER_WRITE, 0, 0, + r->textures.all[i]->width[0], r->textures.all[i]->height[0] + ); + + r->texels[i] = r->pipe->screen->transfer_map(r->pipe->screen, r->tex_transfer[i]); + } +} + +static void +xfer_buffers_unmap(struct vl_mpeg12_mc_renderer *r) +{ + assert(r); + + for (unsigned i = 0; i < 3; ++i) + { + r->pipe->screen->transfer_unmap(r->pipe->screen, r->tex_transfer[i]); + r->pipe->screen->tex_transfer_destroy(r->tex_transfer[i]); + } +} + +static bool +init_pipe_state(struct vl_mpeg12_mc_renderer *r) +{ + struct pipe_sampler_state sampler; + unsigned filters[5]; + + assert(r); + + r->viewport.scale[0] = r->pot_buffers ? + util_next_power_of_two(r->picture_width) : r->picture_width; + r->viewport.scale[1] = r->pot_buffers ? + util_next_power_of_two(r->picture_height) : r->picture_height; + r->viewport.scale[2] = 1; + r->viewport.scale[3] = 1; + r->viewport.translate[0] = 0; + r->viewport.translate[1] = 0; + r->viewport.translate[2] = 0; + r->viewport.translate[3] = 0; + + r->fb_state.width = r->pot_buffers ? + util_next_power_of_two(r->picture_width) : r->picture_width; + r->fb_state.height = r->pot_buffers ? + util_next_power_of_two(r->picture_height) : r->picture_height; + r->fb_state.nr_cbufs = 1; + r->fb_state.zsbuf = NULL; + + /* Luma filter */ + filters[0] = PIPE_TEX_FILTER_NEAREST; + /* Chroma filters */ + if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_444 || + r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE) + { + filters[1] = PIPE_TEX_FILTER_NEAREST; + filters[2] = PIPE_TEX_FILTER_NEAREST; + } + else + { + filters[1] = PIPE_TEX_FILTER_LINEAR; + filters[2] = PIPE_TEX_FILTER_LINEAR; + } + /* Fwd, bkwd ref filters */ + filters[3] = PIPE_TEX_FILTER_LINEAR; + filters[4] = PIPE_TEX_FILTER_LINEAR; + + for (unsigned i = 0; i < 5; ++i) + { + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.min_img_filter = filters[i]; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler.mag_img_filter = filters[i]; + sampler.compare_mode = PIPE_TEX_COMPARE_NONE; + sampler.compare_func = PIPE_FUNC_ALWAYS; + sampler.normalized_coords = 1; + /*sampler.prefilter = ; */ + /*sampler.shadow_ambient = ; */ + /*sampler.lod_bias = ; */ + sampler.min_lod = 0; + /*sampler.max_lod = ; */ + /*sampler.border_color[i] = ; */ + /*sampler.max_anisotropy = ; */ + r->samplers.all[i] = r->pipe->create_sampler_state(r->pipe, &sampler); + } + + return true; +} + +static void +cleanup_pipe_state(struct vl_mpeg12_mc_renderer *r) +{ + assert(r); + + for (unsigned i = 0; i < 5; ++i) + r->pipe->delete_sampler_state(r->pipe, r->samplers.all[i]); +} + +static bool +init_shaders(struct vl_mpeg12_mc_renderer *r) +{ + assert(r); + + create_intra_vert_shader(r); + create_intra_frag_shader(r); + create_frame_pred_vert_shader(r); + create_frame_pred_frag_shader(r); + create_frame_bi_pred_vert_shader(r); + create_frame_bi_pred_frag_shader(r); + + return true; +} + +static void +cleanup_shaders(struct vl_mpeg12_mc_renderer *r) +{ + assert(r); + + r->pipe->delete_vs_state(r->pipe, r->i_vs); + r->pipe->delete_fs_state(r->pipe, r->i_fs); + r->pipe->delete_vs_state(r->pipe, r->p_vs[0]); + r->pipe->delete_fs_state(r->pipe, r->p_fs[0]); + r->pipe->delete_vs_state(r->pipe, r->b_vs[0]); + r->pipe->delete_fs_state(r->pipe, r->b_fs[0]); +} + +static bool +init_buffers(struct vl_mpeg12_mc_renderer *r) +{ + struct pipe_texture template; + + const unsigned mbw = + align(r->picture_width, MACROBLOCK_WIDTH) / MACROBLOCK_WIDTH; + const unsigned mbh = + align(r->picture_height, MACROBLOCK_HEIGHT) / MACROBLOCK_HEIGHT; + + assert(r); + + r->macroblocks_per_batch = + mbw * (r->bufmode == VL_MPEG12_MC_RENDERER_BUFFER_PICTURE ? mbh : 1); + r->num_macroblocks = 0; + r->macroblock_buf = MALLOC(r->macroblocks_per_batch * sizeof(struct pipe_mpeg12_macroblock)); + + memset(&template, 0, sizeof(struct pipe_texture)); + template.target = PIPE_TEXTURE_2D; + /* TODO: Accomodate HW that can't do this and also for cases when this isn't precise enough */ + template.format = PIPE_FORMAT_R16_SNORM; + template.last_level = 0; + template.width[0] = r->pot_buffers ? + util_next_power_of_two(r->picture_width) : r->picture_width; + template.height[0] = r->pot_buffers ? + util_next_power_of_two(r->picture_height) : r->picture_height; + template.depth[0] = 1; + pf_get_block(template.format, &template.block); + template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_DYNAMIC; + + r->textures.individual.y = r->pipe->screen->texture_create(r->pipe->screen, &template); + + if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) + { + template.width[0] = r->pot_buffers ? + util_next_power_of_two(r->picture_width / 2) : + r->picture_width / 2; + template.height[0] = r->pot_buffers ? + util_next_power_of_two(r->picture_height / 2) : + r->picture_height / 2; + } + else if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) + template.height[0] = r->pot_buffers ? + util_next_power_of_two(r->picture_height / 2) : + r->picture_height / 2; + + r->textures.individual.cb = + r->pipe->screen->texture_create(r->pipe->screen, &template); + r->textures.individual.cr = + r->pipe->screen->texture_create(r->pipe->screen, &template); + + r->vertex_bufs.individual.ycbcr.stride = sizeof(struct vertex2f) * 4; + r->vertex_bufs.individual.ycbcr.max_index = 24 * r->macroblocks_per_batch - 1; + r->vertex_bufs.individual.ycbcr.buffer_offset = 0; + r->vertex_bufs.individual.ycbcr.buffer = pipe_buffer_create + ( + r->pipe->screen, + DEFAULT_BUF_ALIGNMENT, + PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_DISCARD, + sizeof(struct vertex2f) * 4 * 24 * r->macroblocks_per_batch + ); + + for (unsigned i = 1; i < 3; ++i) + { + r->vertex_bufs.all[i].stride = sizeof(struct vertex2f) * 2; + r->vertex_bufs.all[i].max_index = 24 * r->macroblocks_per_batch - 1; + r->vertex_bufs.all[i].buffer_offset = 0; + r->vertex_bufs.all[i].buffer = pipe_buffer_create + ( + r->pipe->screen, + DEFAULT_BUF_ALIGNMENT, + PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_DISCARD, + sizeof(struct vertex2f) * 2 * 24 * r->macroblocks_per_batch + ); + } + + /* Position element */ + r->vertex_elems[0].src_offset = 0; + r->vertex_elems[0].vertex_buffer_index = 0; + r->vertex_elems[0].nr_components = 2; + r->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* Luma, texcoord element */ + r->vertex_elems[1].src_offset = sizeof(struct vertex2f); + r->vertex_elems[1].vertex_buffer_index = 0; + r->vertex_elems[1].nr_components = 2; + r->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* Chroma Cr texcoord element */ + r->vertex_elems[2].src_offset = sizeof(struct vertex2f) * 2; + r->vertex_elems[2].vertex_buffer_index = 0; + r->vertex_elems[2].nr_components = 2; + r->vertex_elems[2].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* Chroma Cb texcoord element */ + r->vertex_elems[3].src_offset = sizeof(struct vertex2f) * 3; + r->vertex_elems[3].vertex_buffer_index = 0; + r->vertex_elems[3].nr_components = 2; + r->vertex_elems[3].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* First ref surface top field texcoord element */ + r->vertex_elems[4].src_offset = 0; + r->vertex_elems[4].vertex_buffer_index = 1; + r->vertex_elems[4].nr_components = 2; + r->vertex_elems[4].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* First ref surface bottom field texcoord element */ + r->vertex_elems[5].src_offset = sizeof(struct vertex2f); + r->vertex_elems[5].vertex_buffer_index = 1; + r->vertex_elems[5].nr_components = 2; + r->vertex_elems[5].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* Second ref surface top field texcoord element */ + r->vertex_elems[6].src_offset = 0; + r->vertex_elems[6].vertex_buffer_index = 2; + r->vertex_elems[6].nr_components = 2; + r->vertex_elems[6].src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* Second ref surface bottom field texcoord element */ + r->vertex_elems[7].src_offset = sizeof(struct vertex2f); + r->vertex_elems[7].vertex_buffer_index = 2; + r->vertex_elems[7].nr_components = 2; + r->vertex_elems[7].src_format = PIPE_FORMAT_R32G32_FLOAT; + + r->vs_const_buf.buffer = pipe_buffer_create + ( + r->pipe->screen, + DEFAULT_BUF_ALIGNMENT, + PIPE_BUFFER_USAGE_CONSTANT | PIPE_BUFFER_USAGE_DISCARD, + sizeof(struct vertex_shader_consts) + ); + + r->fs_const_buf.buffer = pipe_buffer_create + ( + r->pipe->screen, + DEFAULT_BUF_ALIGNMENT, + PIPE_BUFFER_USAGE_CONSTANT, sizeof(struct fragment_shader_consts) + ); + + memcpy + ( + pipe_buffer_map(r->pipe->screen, r->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + &fs_consts, sizeof(struct fragment_shader_consts) + ); + + pipe_buffer_unmap(r->pipe->screen, r->fs_const_buf.buffer); + + return true; +} + +static void +cleanup_buffers(struct vl_mpeg12_mc_renderer *r) +{ + assert(r); + + pipe_buffer_reference(&r->vs_const_buf.buffer, NULL); + pipe_buffer_reference(&r->fs_const_buf.buffer, NULL); + + for (unsigned i = 0; i < 3; ++i) + pipe_buffer_reference(&r->vertex_bufs.all[i].buffer, NULL); + + for (unsigned i = 0; i < 3; ++i) + pipe_texture_reference(&r->textures.all[i], NULL); + + FREE(r->macroblock_buf); +} + +static enum MACROBLOCK_TYPE +get_macroblock_type(struct pipe_mpeg12_macroblock *mb) +{ + assert(mb); + + switch (mb->mb_type) + { + case PIPE_MPEG12_MACROBLOCK_TYPE_INTRA: + return MACROBLOCK_TYPE_INTRA; + case PIPE_MPEG12_MACROBLOCK_TYPE_FWD: + return mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME ? + MACROBLOCK_TYPE_FWD_FRAME_PRED : MACROBLOCK_TYPE_FWD_FIELD_PRED; + case PIPE_MPEG12_MACROBLOCK_TYPE_BKWD: + return mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME ? + MACROBLOCK_TYPE_BKWD_FRAME_PRED : MACROBLOCK_TYPE_BKWD_FIELD_PRED; + case PIPE_MPEG12_MACROBLOCK_TYPE_BI: + return mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME ? + MACROBLOCK_TYPE_BI_FRAME_PRED : MACROBLOCK_TYPE_BI_FIELD_PRED; + default: + assert(0); + } + + /* Unreachable */ + return -1; +} + +/* XXX: One of these days this will have to be killed with fire */ +#define SET_BLOCK(vb, cbp, mbx, mby, unitx, unity, ofsx, ofsy, hx, hy, lm, cbm, crm, use_zb, zb) \ + do { \ + (vb)[0].pos.x = (mbx) * (unitx) + (ofsx); (vb)[0].pos.y = (mby) * (unity) + (ofsy); \ + (vb)[1].pos.x = (mbx) * (unitx) + (ofsx); (vb)[1].pos.y = (mby) * (unity) + (ofsy) + (hy); \ + (vb)[2].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].pos.y = (mby) * (unity) + (ofsy); \ + (vb)[3].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].pos.y = (mby) * (unity) + (ofsy); \ + (vb)[4].pos.x = (mbx) * (unitx) + (ofsx); (vb)[4].pos.y = (mby) * (unity) + (ofsy) + (hy); \ + (vb)[5].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].pos.y = (mby) * (unity) + (ofsy) + (hy); \ + \ + if (!use_zb || (cbp) & (lm)) \ + { \ + (vb)[0].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].luma_tc.y = (mby) * (unity) + (ofsy); \ + (vb)[1].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \ + (vb)[2].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].luma_tc.y = (mby) * (unity) + (ofsy); \ + (vb)[3].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].luma_tc.y = (mby) * (unity) + (ofsy); \ + (vb)[4].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \ + (vb)[5].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \ + } \ + else \ + { \ + (vb)[0].luma_tc.x = (zb)[0].x; (vb)[0].luma_tc.y = (zb)[0].y; \ + (vb)[1].luma_tc.x = (zb)[0].x; (vb)[1].luma_tc.y = (zb)[0].y + (hy); \ + (vb)[2].luma_tc.x = (zb)[0].x + (hx); (vb)[2].luma_tc.y = (zb)[0].y; \ + (vb)[3].luma_tc.x = (zb)[0].x + (hx); (vb)[3].luma_tc.y = (zb)[0].y; \ + (vb)[4].luma_tc.x = (zb)[0].x; (vb)[4].luma_tc.y = (zb)[0].y + (hy); \ + (vb)[5].luma_tc.x = (zb)[0].x + (hx); (vb)[5].luma_tc.y = (zb)[0].y + (hy); \ + } \ + \ + if (!use_zb || (cbp) & (cbm)) \ + { \ + (vb)[0].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].cb_tc.y = (mby) * (unity) + (ofsy); \ + (vb)[1].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \ + (vb)[2].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].cb_tc.y = (mby) * (unity) + (ofsy); \ + (vb)[3].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].cb_tc.y = (mby) * (unity) + (ofsy); \ + (vb)[4].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \ + (vb)[5].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \ + } \ + else \ + { \ + (vb)[0].cb_tc.x = (zb)[1].x; (vb)[0].cb_tc.y = (zb)[1].y; \ + (vb)[1].cb_tc.x = (zb)[1].x; (vb)[1].cb_tc.y = (zb)[1].y + (hy); \ + (vb)[2].cb_tc.x = (zb)[1].x + (hx); (vb)[2].cb_tc.y = (zb)[1].y; \ + (vb)[3].cb_tc.x = (zb)[1].x + (hx); (vb)[3].cb_tc.y = (zb)[1].y; \ + (vb)[4].cb_tc.x = (zb)[1].x; (vb)[4].cb_tc.y = (zb)[1].y + (hy); \ + (vb)[5].cb_tc.x = (zb)[1].x + (hx); (vb)[5].cb_tc.y = (zb)[1].y + (hy); \ + } \ + \ + if (!use_zb || (cbp) & (crm)) \ + { \ + (vb)[0].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].cr_tc.y = (mby) * (unity) + (ofsy); \ + (vb)[1].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \ + (vb)[2].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].cr_tc.y = (mby) * (unity) + (ofsy); \ + (vb)[3].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].cr_tc.y = (mby) * (unity) + (ofsy); \ + (vb)[4].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \ + (vb)[5].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \ + } \ + else \ + { \ + (vb)[0].cr_tc.x = (zb)[2].x; (vb)[0].cr_tc.y = (zb)[2].y; \ + (vb)[1].cr_tc.x = (zb)[2].x; (vb)[1].cr_tc.y = (zb)[2].y + (hy); \ + (vb)[2].cr_tc.x = (zb)[2].x + (hx); (vb)[2].cr_tc.y = (zb)[2].y; \ + (vb)[3].cr_tc.x = (zb)[2].x + (hx); (vb)[3].cr_tc.y = (zb)[2].y; \ + (vb)[4].cr_tc.x = (zb)[2].x; (vb)[4].cr_tc.y = (zb)[2].y + (hy); \ + (vb)[5].cr_tc.x = (zb)[2].x + (hx); (vb)[5].cr_tc.y = (zb)[2].y + (hy); \ + } \ + } while (0) + +static void +gen_macroblock_verts(struct vl_mpeg12_mc_renderer *r, + struct pipe_mpeg12_macroblock *mb, unsigned pos, + struct vert_stream_0 *ycbcr_vb, struct vertex2f **ref_vb) +{ + struct vertex2f mo_vec[2]; + + assert(r); + assert(mb); + assert(ycbcr_vb); + assert(pos < r->macroblocks_per_batch); + + switch (mb->mb_type) + { + case PIPE_MPEG12_MACROBLOCK_TYPE_BI: + { + struct vertex2f *vb; + + assert(ref_vb && ref_vb[1]); + + vb = ref_vb[1] + pos * 2 * 24; + + mo_vec[0].x = mb->pmv[0][1][0] * 0.5f * r->surface_tex_inv_size.x; + mo_vec[0].y = mb->pmv[0][1][1] * 0.5f * r->surface_tex_inv_size.y; + + if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME) + { + for (unsigned i = 0; i < 24 * 2; i += 2) + { + vb[i].x = mo_vec[0].x; + vb[i].y = mo_vec[0].y; + } + } + else + { + mo_vec[1].x = mb->pmv[1][1][0] * 0.5f * r->surface_tex_inv_size.x; + mo_vec[1].y = mb->pmv[1][1][1] * 0.5f * r->surface_tex_inv_size.y; + + for (unsigned i = 0; i < 24 * 2; i += 2) + { + vb[i].x = mo_vec[0].x; + vb[i].y = mo_vec[0].y; + vb[i + 1].x = mo_vec[1].x; + vb[i + 1].y = mo_vec[1].y; + } + } + + /* fall-through */ + } + case PIPE_MPEG12_MACROBLOCK_TYPE_FWD: + case PIPE_MPEG12_MACROBLOCK_TYPE_BKWD: + { + struct vertex2f *vb; + + assert(ref_vb && ref_vb[0]); + + vb = ref_vb[0] + pos * 2 * 24; + + if (mb->mb_type == PIPE_MPEG12_MACROBLOCK_TYPE_BKWD) + { + mo_vec[0].x = mb->pmv[0][1][0] * 0.5f * r->surface_tex_inv_size.x; + mo_vec[0].y = mb->pmv[0][1][1] * 0.5f * r->surface_tex_inv_size.y; + + if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FIELD) + { + mo_vec[1].x = mb->pmv[1][1][0] * 0.5f * r->surface_tex_inv_size.x; + mo_vec[1].y = mb->pmv[1][1][1] * 0.5f * r->surface_tex_inv_size.y; + } + } + else + { + mo_vec[0].x = mb->pmv[0][0][0] * 0.5f * r->surface_tex_inv_size.x; + mo_vec[0].y = mb->pmv[0][0][1] * 0.5f * r->surface_tex_inv_size.y; + + if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FIELD) + { + mo_vec[1].x = mb->pmv[1][0][0] * 0.5f * r->surface_tex_inv_size.x; + mo_vec[1].y = mb->pmv[1][0][1] * 0.5f * r->surface_tex_inv_size.y; + } + } + + if (mb->mb_type == PIPE_MPEG12_MOTION_TYPE_FRAME) + { + for (unsigned i = 0; i < 24 * 2; i += 2) + { + vb[i].x = mo_vec[0].x; + vb[i].y = mo_vec[0].y; + } + } + else + { + for (unsigned i = 0; i < 24 * 2; i += 2) + { + vb[i].x = mo_vec[0].x; + vb[i].y = mo_vec[0].y; + vb[i + 1].x = mo_vec[1].x; + vb[i + 1].y = mo_vec[1].y; + } + } + + /* fall-through */ + } + case PIPE_MPEG12_MACROBLOCK_TYPE_INTRA: + { + const struct vertex2f unit = + { + r->surface_tex_inv_size.x * MACROBLOCK_WIDTH, + r->surface_tex_inv_size.y * MACROBLOCK_HEIGHT + }; + const struct vertex2f half = + { + r->surface_tex_inv_size.x * (MACROBLOCK_WIDTH / 2), + r->surface_tex_inv_size.y * (MACROBLOCK_HEIGHT / 2) + }; + const bool use_zb = r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE; + + struct vert_stream_0 *vb = ycbcr_vb + pos * 24; + + SET_BLOCK(vb, mb->cbp, mb->mbx, mb->mby, + unit.x, unit.y, 0, 0, half.x, half.y, + 32, 2, 1, use_zb, r->zero_block); + + SET_BLOCK(vb + 6, mb->cbp, mb->mbx, mb->mby, + unit.x, unit.y, half.x, 0, half.x, half.y, + 16, 2, 1, use_zb, r->zero_block); + + SET_BLOCK(vb + 12, mb->cbp, mb->mbx, mb->mby, + unit.x, unit.y, 0, half.y, half.x, half.y, + 8, 2, 1, use_zb, r->zero_block); + + SET_BLOCK(vb + 18, mb->cbp, mb->mbx, mb->mby, + unit.x, unit.y, half.x, half.y, half.x, half.y, + 4, 2, 1, use_zb, r->zero_block); + + break; + } + default: + assert(0); + } +} + +static void +gen_macroblock_stream(struct vl_mpeg12_mc_renderer *r, + unsigned *num_macroblocks) +{ + unsigned offset[NUM_MACROBLOCK_TYPES]; + struct vert_stream_0 *ycbcr_vb; + struct vertex2f *ref_vb[2]; + + assert(r); + assert(num_macroblocks); + + for (unsigned i = 0; i < r->num_macroblocks; ++i) + { + enum MACROBLOCK_TYPE mb_type = get_macroblock_type(&r->macroblock_buf[i]); + ++num_macroblocks[mb_type]; + } + + offset[0] = 0; + + for (unsigned i = 1; i < NUM_MACROBLOCK_TYPES; ++i) + offset[i] = offset[i - 1] + num_macroblocks[i - 1]; + + ycbcr_vb = (struct vert_stream_0 *)pipe_buffer_map + ( + r->pipe->screen, + r->vertex_bufs.individual.ycbcr.buffer, + PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD + ); + + for (unsigned i = 0; i < 2; ++i) + ref_vb[i] = (struct vertex2f *)pipe_buffer_map + ( + r->pipe->screen, + r->vertex_bufs.individual.ref[i].buffer, + PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD + ); + + for (unsigned i = 0; i < r->num_macroblocks; ++i) + { + enum MACROBLOCK_TYPE mb_type = get_macroblock_type(&r->macroblock_buf[i]); + + gen_macroblock_verts(r, &r->macroblock_buf[i], offset[mb_type], + ycbcr_vb, ref_vb); + + ++offset[mb_type]; + } + + pipe_buffer_unmap(r->pipe->screen, r->vertex_bufs.individual.ycbcr.buffer); + for (unsigned i = 0; i < 2; ++i) + pipe_buffer_unmap(r->pipe->screen, r->vertex_bufs.individual.ref[i].buffer); +} + +static void +flush(struct vl_mpeg12_mc_renderer *r) +{ + unsigned num_macroblocks[NUM_MACROBLOCK_TYPES] = { 0 }; + unsigned vb_start = 0; + struct vertex_shader_consts *vs_consts; + + assert(r); + assert(r->num_macroblocks == r->macroblocks_per_batch); + + gen_macroblock_stream(r, num_macroblocks); + + r->fb_state.cbufs[0] = r->pipe->screen->get_tex_surface + ( + r->pipe->screen, r->surface, + 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE + ); + + r->pipe->set_framebuffer_state(r->pipe, &r->fb_state); + r->pipe->set_viewport_state(r->pipe, &r->viewport); + + vs_consts = pipe_buffer_map + ( + r->pipe->screen, r->vs_const_buf.buffer, + PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD + ); + + vs_consts->denorm.x = r->surface->width[0]; + vs_consts->denorm.y = r->surface->height[0]; + + pipe_buffer_unmap(r->pipe->screen, r->vs_const_buf.buffer); + + r->pipe->set_constant_buffer(r->pipe, PIPE_SHADER_VERTEX, 0, + &r->vs_const_buf); + r->pipe->set_constant_buffer(r->pipe, PIPE_SHADER_FRAGMENT, 0, + &r->fs_const_buf); + + if (num_macroblocks[MACROBLOCK_TYPE_INTRA] > 0) + { + r->pipe->set_vertex_buffers(r->pipe, 1, r->vertex_bufs.all); + r->pipe->set_vertex_elements(r->pipe, 4, r->vertex_elems); + r->pipe->set_sampler_textures(r->pipe, 3, r->textures.all); + r->pipe->bind_sampler_states(r->pipe, 3, r->samplers.all); + r->pipe->bind_vs_state(r->pipe, r->i_vs); + r->pipe->bind_fs_state(r->pipe, r->i_fs); + + r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start, + num_macroblocks[MACROBLOCK_TYPE_INTRA] * 24); + vb_start += num_macroblocks[MACROBLOCK_TYPE_INTRA] * 24; + } + + if (num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] > 0) + { + r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all); + r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems); + r->textures.individual.ref[0] = r->past; + r->pipe->set_sampler_textures(r->pipe, 4, r->textures.all); + r->pipe->bind_sampler_states(r->pipe, 4, r->samplers.all); + r->pipe->bind_vs_state(r->pipe, r->p_vs[0]); + r->pipe->bind_fs_state(r->pipe, r->p_fs[0]); + + r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start, + num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] * 24); + vb_start += num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] * 24; + } + + if (false /*num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] > 0 */ ) + { + r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all); + r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems); + r->textures.individual.ref[0] = r->past; + r->pipe->set_sampler_textures(r->pipe, 4, r->textures.all); + r->pipe->bind_sampler_states(r->pipe, 4, r->samplers.all); + r->pipe->bind_vs_state(r->pipe, r->p_vs[1]); + r->pipe->bind_fs_state(r->pipe, r->p_fs[1]); + + r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start, + num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] * 24); + vb_start += num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] * 24; + } + + if (num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] > 0) + { + r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all); + r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems); + r->textures.individual.ref[0] = r->future; + r->pipe->set_sampler_textures(r->pipe, 4, r->textures.all); + r->pipe->bind_sampler_states(r->pipe, 4, r->samplers.all); + r->pipe->bind_vs_state(r->pipe, r->p_vs[0]); + r->pipe->bind_fs_state(r->pipe, r->p_fs[0]); + + r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start, + num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] * 24); + vb_start += num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] * 24; + } + + if (false /*num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] > 0 */ ) + { + r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all); + r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems); + r->textures.individual.ref[0] = r->future; + r->pipe->set_sampler_textures(r->pipe, 4, r->textures.all); + r->pipe->bind_sampler_states(r->pipe, 4, r->samplers.all); + r->pipe->bind_vs_state(r->pipe, r->p_vs[1]); + r->pipe->bind_fs_state(r->pipe, r->p_fs[1]); + + r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start, + num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] * 24); + vb_start += num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] * 24; + } + + if (num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] > 0) + { + r->pipe->set_vertex_buffers(r->pipe, 3, r->vertex_bufs.all); + r->pipe->set_vertex_elements(r->pipe, 8, r->vertex_elems); + r->textures.individual.ref[0] = r->past; + r->textures.individual.ref[1] = r->future; + r->pipe->set_sampler_textures(r->pipe, 5, r->textures.all); + r->pipe->bind_sampler_states(r->pipe, 5, r->samplers.all); + r->pipe->bind_vs_state(r->pipe, r->b_vs[0]); + r->pipe->bind_fs_state(r->pipe, r->b_fs[0]); + + r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start, + num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] * 24); + vb_start += num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] * 24; + } + + if (false /*num_macroblocks[MACROBLOCK_TYPE_BI_FIELD_PRED] > 0 */ ) + { + r->pipe->set_vertex_buffers(r->pipe, 3, r->vertex_bufs.all); + r->pipe->set_vertex_elements(r->pipe, 8, r->vertex_elems); + r->textures.individual.ref[0] = r->past; + r->textures.individual.ref[1] = r->future; + r->pipe->set_sampler_textures(r->pipe, 5, r->textures.all); + r->pipe->bind_sampler_states(r->pipe, 5, r->samplers.all); + r->pipe->bind_vs_state(r->pipe, r->b_vs[1]); + r->pipe->bind_fs_state(r->pipe, r->b_fs[1]); + + r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start, + num_macroblocks[MACROBLOCK_TYPE_BI_FIELD_PRED] * 24); + vb_start += num_macroblocks[MACROBLOCK_TYPE_BI_FIELD_PRED] * 24; + } + + r->pipe->flush(r->pipe, PIPE_FLUSH_RENDER_CACHE, r->fence); + pipe_surface_reference(&r->fb_state.cbufs[0], NULL); + + if (r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE) + for (unsigned i = 0; i < 3; ++i) + r->zero_block[i].x = ZERO_BLOCK_NIL; + + r->num_macroblocks = 0; +} + +static void +grab_frame_coded_block(short *src, short *dst, unsigned dst_pitch) +{ + assert(src); + assert(dst); + + for (unsigned y = 0; y < BLOCK_HEIGHT; ++y) + memcpy(dst + y * dst_pitch, src + y * BLOCK_WIDTH, BLOCK_WIDTH * 2); +} + +static void +grab_field_coded_block(short *src, short *dst, unsigned dst_pitch) +{ + assert(src); + assert(dst); + + for (unsigned y = 0; y < BLOCK_HEIGHT; ++y) + memcpy(dst + y * dst_pitch * 2, src + y * BLOCK_WIDTH, BLOCK_WIDTH * 2); +} + +static void +fill_zero_block(short *dst, unsigned dst_pitch) +{ + assert(dst); + + for (unsigned y = 0; y < BLOCK_HEIGHT; ++y) + memset(dst + y * dst_pitch, 0, BLOCK_WIDTH * 2); +} + +static void +grab_blocks(struct vl_mpeg12_mc_renderer *r, unsigned mbx, unsigned mby, + enum pipe_mpeg12_dct_type dct_type, unsigned cbp, short *blocks) +{ + unsigned tex_pitch; + short *texels; + unsigned tb = 0, sb = 0; + unsigned mbpx = mbx * MACROBLOCK_WIDTH, mbpy = mby * MACROBLOCK_HEIGHT; + + assert(r); + assert(blocks); + + tex_pitch = r->tex_transfer[0]->stride / r->tex_transfer[0]->block.size; + texels = r->texels[0] + mbpy * tex_pitch + mbpx; + + for (unsigned y = 0; y < 2; ++y) + { + for (unsigned x = 0; x < 2; ++x, ++tb) + { + if ((cbp >> (5 - tb)) & 1) + { + if (dct_type == PIPE_MPEG12_DCT_TYPE_FRAME) + { + grab_frame_coded_block(blocks + sb * BLOCK_WIDTH * BLOCK_HEIGHT, + texels + y * tex_pitch * BLOCK_WIDTH + + x * BLOCK_WIDTH, tex_pitch); + } + else + { + grab_field_coded_block(blocks + sb * BLOCK_WIDTH * BLOCK_HEIGHT, + texels + y * tex_pitch + x * BLOCK_WIDTH, + tex_pitch); + } + + ++sb; + } + else if (r->eb_handling != VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_NONE) + { + if (r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ALL || + ZERO_BLOCK_IS_NIL(r->zero_block[0])) + { + fill_zero_block(texels + y * tex_pitch * BLOCK_WIDTH + x * BLOCK_WIDTH, tex_pitch); + if (r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE) + { + r->zero_block[0].x = (mbpx + x * 8) * r->surface_tex_inv_size.x; + r->zero_block[0].y = (mbpy + y * 8) * r->surface_tex_inv_size.y; + } + } + } + } + } + + /* TODO: Implement 422, 444 */ + assert(r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420); + + mbpx /= 2; + mbpy /= 2; + + for (tb = 0; tb < 2; ++tb) + { + tex_pitch = r->tex_transfer[tb + 1]->stride / r->tex_transfer[tb + 1]->block.size; + texels = r->texels[tb + 1] + mbpy * tex_pitch + mbpx; + + if ((cbp >> (1 - tb)) & 1) + { + grab_frame_coded_block(blocks + sb * BLOCK_WIDTH * BLOCK_HEIGHT, texels, tex_pitch); + ++sb; + } + else if (r->eb_handling != VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_NONE) + { + if (r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ALL || + ZERO_BLOCK_IS_NIL(r->zero_block[tb + 1])) + { + fill_zero_block(texels, tex_pitch); + if (r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE) + { + r->zero_block[tb + 1].x = (mbpx << 1) * r->surface_tex_inv_size.x; + r->zero_block[tb + 1].y = (mbpy << 1) * r->surface_tex_inv_size.y; + } + } + } + } +} + +static void +grab_macroblock(struct vl_mpeg12_mc_renderer *r, + struct pipe_mpeg12_macroblock *mb) +{ + assert(r); + assert(mb); + assert(r->num_macroblocks < r->macroblocks_per_batch); + + memcpy(&r->macroblock_buf[r->num_macroblocks], mb, + sizeof(struct pipe_mpeg12_macroblock)); + + grab_blocks(r, mb->mbx, mb->mby, mb->dct_type, mb->cbp, mb->blocks); + + ++r->num_macroblocks; +} + +bool +vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer, + struct pipe_context *pipe, + unsigned picture_width, + unsigned picture_height, + enum pipe_video_chroma_format chroma_format, + enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode, + enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling, + bool pot_buffers) +{ + assert(renderer); + assert(pipe); + /* TODO: Implement other policies */ + assert(bufmode == VL_MPEG12_MC_RENDERER_BUFFER_PICTURE); + /* TODO: Implement this */ + /* XXX: XFER_ALL sampling issue at block edges when using bilinear filtering */ + assert(eb_handling != VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_NONE); + /* TODO: Non-pot buffers untested, probably doesn't work without changes to texcoord generation, vert shader, etc */ + assert(pot_buffers); + + memset(renderer, 0, sizeof(struct vl_mpeg12_mc_renderer)); + + renderer->pipe = pipe; + renderer->picture_width = picture_width; + renderer->picture_height = picture_height; + renderer->chroma_format = chroma_format; + renderer->bufmode = bufmode; + renderer->eb_handling = eb_handling; + renderer->pot_buffers = pot_buffers; + + if (!init_pipe_state(renderer)) + return false; + if (!init_shaders(renderer)) + { + cleanup_pipe_state(renderer); + return false; + } + if (!init_buffers(renderer)) + { + cleanup_shaders(renderer); + cleanup_pipe_state(renderer); + return false; + } + + renderer->surface = NULL; + renderer->past = NULL; + renderer->future = NULL; + for (unsigned i = 0; i < 3; ++i) + renderer->zero_block[i].x = ZERO_BLOCK_NIL; + renderer->num_macroblocks = 0; + + xfer_buffers_map(renderer); + + return true; +} + +void +vl_mpeg12_mc_renderer_cleanup(struct vl_mpeg12_mc_renderer *renderer) +{ + assert(renderer); + + xfer_buffers_unmap(renderer); + + cleanup_pipe_state(renderer); + cleanup_shaders(renderer); + cleanup_buffers(renderer); +} + +void +vl_mpeg12_mc_renderer_render_macroblocks(struct vl_mpeg12_mc_renderer + *renderer, + struct pipe_texture *surface, + struct pipe_texture *past, + struct pipe_texture *future, + unsigned num_macroblocks, + struct pipe_mpeg12_macroblock + *mpeg12_macroblocks, + struct pipe_fence_handle **fence) +{ + bool new_surface = false; + + assert(renderer); + assert(surface); + assert(num_macroblocks); + assert(mpeg12_macroblocks); + + if (renderer->surface) + { + if (surface != renderer->surface) + { + if (renderer->num_macroblocks > 0) + { + xfer_buffers_unmap(renderer); + flush(renderer); + } + + new_surface = true; + } + + /* If the surface we're rendering hasn't changed the ref frames shouldn't change. */ + assert(surface != renderer->surface || renderer->past == past); + assert(surface != renderer->surface || renderer->future == future); + } + else + new_surface = true; + + if (new_surface) + { + renderer->surface = surface; + renderer->past = past; + renderer->future = future; + renderer->fence = fence; + renderer->surface_tex_inv_size.x = 1.0f / surface->width[0]; + renderer->surface_tex_inv_size.y = 1.0f / surface->height[0]; + } + + while (num_macroblocks) + { + unsigned left_in_batch = renderer->macroblocks_per_batch - renderer->num_macroblocks; + unsigned num_to_submit = MIN2(num_macroblocks, left_in_batch); + + for (unsigned i = 0; i < num_to_submit; ++i) + { + assert(mpeg12_macroblocks[i].base.codec == PIPE_VIDEO_CODEC_MPEG12); + grab_macroblock(renderer, &mpeg12_macroblocks[i]); + } + + num_macroblocks -= num_to_submit; + + if (renderer->num_macroblocks == renderer->macroblocks_per_batch) + { + xfer_buffers_unmap(renderer); + flush(renderer); + xfer_buffers_map(renderer); + /* Next time we get this surface it may have new ref frames */ + renderer->surface = NULL; + } + } +} diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h new file mode 100644 index 00000000000..dfe0f7a24b8 --- /dev/null +++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h @@ -0,0 +1,93 @@ +#ifndef vl_mpeg12_mc_renderer_h +#define vl_mpeg12_mc_renderer_h + +#include +#include +#include + +struct pipe_context; +struct pipe_video_surface; +struct pipe_macroblock; + +/* A slice is video-width (rounded up to a multiple of macroblock width) x macroblock height */ +enum VL_MPEG12_MC_RENDERER_BUFFER_MODE +{ + VL_MPEG12_MC_RENDERER_BUFFER_SLICE, /* Saves memory at the cost of smaller batches */ + VL_MPEG12_MC_RENDERER_BUFFER_PICTURE /* Larger batches, more memory */ +}; + +enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK +{ + VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ALL, /* Waste of memory bandwidth */ + VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE, /* Can only do point-filtering when interpolating subsampled chroma channels */ + VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_NONE /* Needs conditional texel fetch! */ +}; + +struct vl_mpeg12_mc_renderer +{ + struct pipe_context *pipe; + unsigned picture_width; + unsigned picture_height; + enum pipe_video_chroma_format chroma_format; + enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode; + enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling; + bool pot_buffers; + unsigned macroblocks_per_batch; + + struct pipe_viewport_state viewport; + struct pipe_constant_buffer vs_const_buf; + struct pipe_constant_buffer fs_const_buf; + struct pipe_framebuffer_state fb_state; + struct pipe_vertex_element vertex_elems[8]; + + union + { + void *all[5]; + struct { void *y, *cb, *cr, *ref[2]; } individual; + } samplers; + + void *i_vs, *p_vs[2], *b_vs[2]; + void *i_fs, *p_fs[2], *b_fs[2]; + + union + { + struct pipe_texture *all[5]; + struct { struct pipe_texture *y, *cb, *cr, *ref[2]; } individual; + } textures; + + union + { + struct pipe_vertex_buffer all[3]; + struct { struct pipe_vertex_buffer ycbcr, ref[2]; } individual; + } vertex_bufs; + + struct pipe_texture *surface, *past, *future; + struct pipe_fence_handle **fence; + unsigned num_macroblocks; + struct pipe_mpeg12_macroblock *macroblock_buf; + struct pipe_transfer *tex_transfer[3]; + short *texels[3]; + struct { float x, y; } surface_tex_inv_size; + struct { float x, y; } zero_block[3]; +}; + +bool vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer, + struct pipe_context *pipe, + unsigned picture_width, + unsigned picture_height, + enum pipe_video_chroma_format chroma_format, + enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode, + enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling, + bool pot_buffers); + +void vl_mpeg12_mc_renderer_cleanup(struct vl_mpeg12_mc_renderer *renderer); + +void vl_mpeg12_mc_renderer_render_macroblocks(struct vl_mpeg12_mc_renderer *renderer, + struct pipe_texture *surface, + struct pipe_texture *past, + struct pipe_texture *future, + unsigned num_macroblocks, + struct pipe_mpeg12_macroblock *mpeg12_macroblocks, + struct pipe_fence_handle **fence); + +#endif /* vl_mpeg12_mc_renderer_h */ diff --git a/src/gallium/auxiliary/vl/vl_shader_build.c b/src/gallium/auxiliary/vl/vl_shader_build.c new file mode 100644 index 00000000000..5a4a5ab72cc --- /dev/null +++ b/src/gallium/auxiliary/vl/vl_shader_build.c @@ -0,0 +1,215 @@ +#include "vl_shader_build.h" +#include +#include +#include + +struct tgsi_full_declaration vl_decl_input(unsigned int name, unsigned int index, unsigned int first, unsigned int last) +{ + struct tgsi_full_declaration decl = tgsi_default_full_declaration(); + + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = name; + decl.Semantic.SemanticIndex = index; + decl.DeclarationRange.First = first; + decl.DeclarationRange.Last = last; + + return decl; +} + +struct tgsi_full_declaration vl_decl_interpolated_input +( + unsigned int name, + unsigned int index, + unsigned int first, + unsigned int last, + int interpolation +) +{ + struct tgsi_full_declaration decl = tgsi_default_full_declaration(); + + assert + ( + interpolation == TGSI_INTERPOLATE_CONSTANT || + interpolation == TGSI_INTERPOLATE_LINEAR || + interpolation == TGSI_INTERPOLATE_PERSPECTIVE + ); + + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = name; + decl.Semantic.SemanticIndex = index; + decl.Declaration.Interpolate = interpolation;; + decl.DeclarationRange.First = first; + decl.DeclarationRange.Last = last; + + return decl; +} + +struct tgsi_full_declaration vl_decl_constants(unsigned int name, unsigned int index, unsigned int first, unsigned int last) +{ + struct tgsi_full_declaration decl = tgsi_default_full_declaration(); + + decl.Declaration.File = TGSI_FILE_CONSTANT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = name; + decl.Semantic.SemanticIndex = index; + decl.DeclarationRange.First = first; + decl.DeclarationRange.Last = last; + + return decl; +} + +struct tgsi_full_declaration vl_decl_output(unsigned int name, unsigned int index, unsigned int first, unsigned int last) +{ + struct tgsi_full_declaration decl = tgsi_default_full_declaration(); + + decl.Declaration.File = TGSI_FILE_OUTPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = name; + decl.Semantic.SemanticIndex = index; + decl.DeclarationRange.First = first; + decl.DeclarationRange.Last = last; + + return decl; +} + +struct tgsi_full_declaration vl_decl_temps(unsigned int first, unsigned int last) +{ + struct tgsi_full_declaration decl = tgsi_default_full_declaration(); + + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.DeclarationRange.First = first; + decl.DeclarationRange.Last = last; + + return decl; +} + +struct tgsi_full_declaration vl_decl_samplers(unsigned int first, unsigned int last) +{ + struct tgsi_full_declaration decl = tgsi_default_full_declaration(); + + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_SAMPLER; + decl.DeclarationRange.First = first; + decl.DeclarationRange.Last = last; + + return decl; +} + +struct tgsi_full_instruction vl_inst2 +( + int opcode, + enum tgsi_file_type dst_file, + unsigned int dst_index, + enum tgsi_file_type src_file, + unsigned int src_index +) +{ + struct tgsi_full_instruction inst = tgsi_default_full_instruction(); + + inst.Instruction.Opcode = opcode; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = dst_file; + inst.FullDstRegisters[0].DstRegister.Index = dst_index; + inst.Instruction.NumSrcRegs = 1; + inst.FullSrcRegisters[0].SrcRegister.File = src_file; + inst.FullSrcRegisters[0].SrcRegister.Index = src_index; + + return inst; +} + +struct tgsi_full_instruction vl_inst3 +( + int opcode, + enum tgsi_file_type dst_file, + unsigned int dst_index, + enum tgsi_file_type src1_file, + unsigned int src1_index, + enum tgsi_file_type src2_file, + unsigned int src2_index +) +{ + struct tgsi_full_instruction inst = tgsi_default_full_instruction(); + + inst.Instruction.Opcode = opcode; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = dst_file; + inst.FullDstRegisters[0].DstRegister.Index = dst_index; + inst.Instruction.NumSrcRegs = 2; + inst.FullSrcRegisters[0].SrcRegister.File = src1_file; + inst.FullSrcRegisters[0].SrcRegister.Index = src1_index; + inst.FullSrcRegisters[1].SrcRegister.File = src2_file; + inst.FullSrcRegisters[1].SrcRegister.Index = src2_index; + + return inst; +} + +struct tgsi_full_instruction vl_tex +( + int tex, + enum tgsi_file_type dst_file, + unsigned int dst_index, + enum tgsi_file_type src1_file, + unsigned int src1_index, + enum tgsi_file_type src2_file, + unsigned int src2_index +) +{ + struct tgsi_full_instruction inst = tgsi_default_full_instruction(); + + inst.Instruction.Opcode = TGSI_OPCODE_TEX; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = dst_file; + inst.FullDstRegisters[0].DstRegister.Index = dst_index; + inst.Instruction.NumSrcRegs = 2; + inst.InstructionExtTexture.Texture = tex; + inst.FullSrcRegisters[0].SrcRegister.File = src1_file; + inst.FullSrcRegisters[0].SrcRegister.Index = src1_index; + inst.FullSrcRegisters[1].SrcRegister.File = src2_file; + inst.FullSrcRegisters[1].SrcRegister.Index = src2_index; + + return inst; +} + +struct tgsi_full_instruction vl_inst4 +( + int opcode, + enum tgsi_file_type dst_file, + unsigned int dst_index, + enum tgsi_file_type src1_file, + unsigned int src1_index, + enum tgsi_file_type src2_file, + unsigned int src2_index, + enum tgsi_file_type src3_file, + unsigned int src3_index +) +{ + struct tgsi_full_instruction inst = tgsi_default_full_instruction(); + + inst.Instruction.Opcode = opcode; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = dst_file; + inst.FullDstRegisters[0].DstRegister.Index = dst_index; + inst.Instruction.NumSrcRegs = 3; + inst.FullSrcRegisters[0].SrcRegister.File = src1_file; + inst.FullSrcRegisters[0].SrcRegister.Index = src1_index; + inst.FullSrcRegisters[1].SrcRegister.File = src2_file; + inst.FullSrcRegisters[1].SrcRegister.Index = src2_index; + inst.FullSrcRegisters[2].SrcRegister.File = src3_file; + inst.FullSrcRegisters[2].SrcRegister.Index = src3_index; + + return inst; +} + +struct tgsi_full_instruction vl_end(void) +{ + struct tgsi_full_instruction inst = tgsi_default_full_instruction(); + + inst.Instruction.Opcode = TGSI_OPCODE_END; + inst.Instruction.NumDstRegs = 0; + inst.Instruction.NumSrcRegs = 0; + + return inst; +} diff --git a/src/gallium/auxiliary/vl/vl_shader_build.h b/src/gallium/auxiliary/vl/vl_shader_build.h new file mode 100644 index 00000000000..c6c60b55526 --- /dev/null +++ b/src/gallium/auxiliary/vl/vl_shader_build.h @@ -0,0 +1,61 @@ +#ifndef vl_shader_build_h +#define vl_shader_build_h + +#include + +struct tgsi_full_declaration vl_decl_input(unsigned int name, unsigned int index, unsigned int first, unsigned int last); +struct tgsi_full_declaration vl_decl_interpolated_input +( + unsigned int name, + unsigned int index, + unsigned int first, + unsigned int last, + int interpolation +); +struct tgsi_full_declaration vl_decl_constants(unsigned int name, unsigned int index, unsigned int first, unsigned int last); +struct tgsi_full_declaration vl_decl_output(unsigned int name, unsigned int index, unsigned int first, unsigned int last); +struct tgsi_full_declaration vl_decl_temps(unsigned int first, unsigned int last); +struct tgsi_full_declaration vl_decl_samplers(unsigned int first, unsigned int last); +struct tgsi_full_instruction vl_inst2 +( + int opcode, + enum tgsi_file_type dst_file, + unsigned int dst_index, + enum tgsi_file_type src_file, + unsigned int src_index +); +struct tgsi_full_instruction vl_inst3 +( + int opcode, + enum tgsi_file_type dst_file, + unsigned int dst_index, + enum tgsi_file_type src1_file, + unsigned int src1_index, + enum tgsi_file_type src2_file, + unsigned int src2_index +); +struct tgsi_full_instruction vl_tex +( + int tex, + enum tgsi_file_type dst_file, + unsigned int dst_index, + enum tgsi_file_type src1_file, + unsigned int src1_index, + enum tgsi_file_type src2_file, + unsigned int src2_index +); +struct tgsi_full_instruction vl_inst4 +( + int opcode, + enum tgsi_file_type dst_file, + unsigned int dst_index, + enum tgsi_file_type src1_file, + unsigned int src1_index, + enum tgsi_file_type src2_file, + unsigned int src2_index, + enum tgsi_file_type src3_file, + unsigned int src3_index +); +struct tgsi_full_instruction vl_end(void); + +#endif diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile index 6ab37537628..bcb887a0b26 100644 --- a/src/gallium/drivers/softpipe/Makefile +++ b/src/gallium/drivers/softpipe/Makefile @@ -31,6 +31,7 @@ C_SOURCES = \ sp_tex_sample.c \ sp_tex_tile_cache.c \ sp_tile_cache.c \ - sp_surface.c + sp_surface.c \ + sp_video_context.c include ../../Makefile.template diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript index 950c3d9955b..aac9edf44e6 100644 --- a/src/gallium/drivers/softpipe/SConscript +++ b/src/gallium/drivers/softpipe/SConscript @@ -33,6 +33,7 @@ softpipe = env.ConvenienceLibrary( 'sp_tex_tile_cache.c', 'sp_texture.c', 'sp_tile_cache.c', + 'sp_video_context.c', ]) -Export('softpipe') \ No newline at end of file +Export('softpipe') diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 49b51afda7e..45289380d08 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -381,6 +381,59 @@ softpipe_transfer_unmap(struct pipe_screen *screen, } } +static struct pipe_video_surface* +softpipe_video_surface_create(struct pipe_screen *screen, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height) +{ + struct softpipe_video_surface *sp_vsfc; + struct pipe_texture template; + + assert(screen); + assert(width && height); + + sp_vsfc = CALLOC_STRUCT(softpipe_video_surface); + if (!sp_vsfc) + return NULL; + + pipe_reference_init(&sp_vsfc->base.reference, 1); + sp_vsfc->base.screen = screen; + sp_vsfc->base.chroma_format = chroma_format; + /*sp_vsfc->base.surface_format = PIPE_VIDEO_SURFACE_FORMAT_VUYA;*/ + sp_vsfc->base.width = width; + sp_vsfc->base.height = height; + + memset(&template, 0, sizeof(struct pipe_texture)); + template.target = PIPE_TEXTURE_2D; + template.format = PIPE_FORMAT_X8R8G8B8_UNORM; + template.last_level = 0; + /* vl_mpeg12_mc_renderer expects this when it's initialized with pot_buffers=true */ + template.width[0] = util_next_power_of_two(width); + template.height[0] = util_next_power_of_two(height); + template.depth[0] = 1; + pf_get_block(template.format, &template.block); + template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_RENDER_TARGET; + + sp_vsfc->tex = screen->texture_create(screen, &template); + if (!sp_vsfc->tex) + { + FREE(sp_vsfc); + return NULL; + } + + return &sp_vsfc->base; +} + + +static void +softpipe_video_surface_destroy(struct pipe_video_surface *vsfc) +{ + struct softpipe_video_surface *sp_vsfc = softpipe_video_surface(vsfc); + + pipe_texture_reference(&sp_vsfc->tex, NULL); + FREE(sp_vsfc); +} + void softpipe_init_screen_texture_funcs(struct pipe_screen *screen) @@ -396,6 +449,9 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen) screen->tex_transfer_destroy = softpipe_tex_transfer_destroy; screen->transfer_map = softpipe_transfer_map; screen->transfer_unmap = softpipe_transfer_unmap; + + screen->video_surface_create = softpipe_video_surface_create; + screen->video_surface_destroy = softpipe_video_surface_destroy; } diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h index 2537ab6a40d..2ef64e1e7c3 100644 --- a/src/gallium/drivers/softpipe/sp_texture.h +++ b/src/gallium/drivers/softpipe/sp_texture.h @@ -30,6 +30,7 @@ #include "pipe/p_state.h" +#include "pipe/p_video_state.h" struct pipe_context; @@ -62,6 +63,15 @@ struct softpipe_transfer unsigned long offset; }; +struct softpipe_video_surface +{ + struct pipe_video_surface base; + + /* The data is held here: + */ + struct pipe_texture *tex; +}; + /** cast wrappers */ static INLINE struct softpipe_texture * @@ -76,6 +86,12 @@ softpipe_transfer(struct pipe_transfer *pt) return (struct softpipe_transfer *) pt; } +static INLINE struct softpipe_video_surface * +softpipe_video_surface(struct pipe_video_surface *pvs) +{ + return (struct softpipe_video_surface *) pvs; +} + extern void softpipe_init_screen_texture_funcs(struct pipe_screen *screen); diff --git a/src/gallium/drivers/softpipe/sp_video_context.c b/src/gallium/drivers/softpipe/sp_video_context.c new file mode 100644 index 00000000000..1b47bbede26 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_video_context.c @@ -0,0 +1,273 @@ +#include "sp_video_context.h" +#include +#include +#include "softpipe/sp_winsys.h" +#include "softpipe/sp_texture.h" + +static void +sp_mpeg12_destroy(struct pipe_video_context *vpipe) +{ + struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; + + assert(vpipe); + + /* Asserted in softpipe_delete_fs_state() for some reason */ + ctx->pipe->bind_vs_state(ctx->pipe, NULL); + ctx->pipe->bind_fs_state(ctx->pipe, NULL); + + ctx->pipe->delete_blend_state(ctx->pipe, ctx->blend); + ctx->pipe->delete_rasterizer_state(ctx->pipe, ctx->rast); + ctx->pipe->delete_depth_stencil_alpha_state(ctx->pipe, ctx->dsa); + + pipe_video_surface_reference(&ctx->decode_target, NULL); + vl_compositor_cleanup(&ctx->compositor); + vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer); + ctx->pipe->destroy(ctx->pipe); + + FREE(ctx); +} + +static void +sp_mpeg12_decode_macroblocks(struct pipe_video_context *vpipe, + struct pipe_video_surface *past, + struct pipe_video_surface *future, + unsigned num_macroblocks, + struct pipe_macroblock *macroblocks, + struct pipe_fence_handle **fence) +{ + struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; + struct pipe_mpeg12_macroblock *mpeg12_macroblocks = (struct pipe_mpeg12_macroblock*)macroblocks; + + assert(vpipe); + assert(num_macroblocks); + assert(macroblocks); + assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12); + assert(ctx->decode_target); + + vl_mpeg12_mc_renderer_render_macroblocks(&ctx->mc_renderer, + softpipe_video_surface(ctx->decode_target)->tex, + past ? softpipe_video_surface(past)->tex : NULL, + future ? softpipe_video_surface(future)->tex : NULL, + num_macroblocks, mpeg12_macroblocks, fence); +} + +static void +sp_mpeg12_clear_surface(struct pipe_video_context *vpipe, + unsigned x, unsigned y, + unsigned width, unsigned height, + unsigned value, + struct pipe_surface *surface) +{ + struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; + + assert(vpipe); + assert(surface); + + ctx->pipe->surface_fill(ctx->pipe, surface, x, y, width, height, value); +} + +static void +sp_mpeg12_render_picture(struct pipe_video_context *vpipe, + /*struct pipe_surface *backround, + struct pipe_video_rect *backround_area,*/ + struct pipe_video_surface *src_surface, + enum pipe_mpeg12_picture_type picture_type, + /*unsigned num_past_surfaces, + struct pipe_video_surface *past_surfaces, + unsigned num_future_surfaces, + struct pipe_video_surface *future_surfaces,*/ + struct pipe_video_rect *src_area, + struct pipe_surface *dst_surface, + struct pipe_video_rect *dst_area, + /*unsigned num_layers, + struct pipe_surface *layers, + struct pipe_video_rect *layer_src_areas, + struct pipe_video_rect *layer_dst_areas*/ + struct pipe_fence_handle **fence) +{ + struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; + + assert(vpipe); + assert(src_surface); + assert(src_area); + assert(dst_surface); + assert(dst_area); + + vl_compositor_render(&ctx->compositor, softpipe_video_surface(src_surface)->tex, + picture_type, src_area, dst_surface->texture, dst_area, fence); +} + +static void +sp_mpeg12_set_decode_target(struct pipe_video_context *vpipe, + struct pipe_video_surface *dt) +{ + struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; + + assert(vpipe); + assert(dt); + + pipe_video_surface_reference(&ctx->decode_target, dt); +} + +static bool +init_pipe_state(struct sp_mpeg12_context *ctx) +{ + struct pipe_rasterizer_state rast; + struct pipe_blend_state blend; + struct pipe_depth_stencil_alpha_state dsa; + + assert(ctx); + + rast.flatshade = 1; + rast.flatshade_first = 0; + rast.light_twoside = 0; + rast.front_winding = PIPE_WINDING_CCW; + rast.cull_mode = PIPE_WINDING_CW; + rast.fill_cw = PIPE_POLYGON_MODE_FILL; + rast.fill_ccw = PIPE_POLYGON_MODE_FILL; + rast.offset_cw = 0; + rast.offset_ccw = 0; + rast.scissor = 0; + rast.poly_smooth = 0; + rast.poly_stipple_enable = 0; + rast.point_sprite = 0; + rast.point_size_per_vertex = 0; + rast.multisample = 0; + rast.line_smooth = 0; + rast.line_stipple_enable = 0; + rast.line_stipple_factor = 0; + rast.line_stipple_pattern = 0; + rast.line_last_pixel = 0; + rast.bypass_vs_clip_and_viewport = 0; + rast.line_width = 1; + rast.point_smooth = 0; + rast.point_size = 1; + rast.offset_units = 1; + rast.offset_scale = 1; + /*rast.sprite_coord_mode[i] = ;*/ + ctx->rast = ctx->pipe->create_rasterizer_state(ctx->pipe, &rast); + ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rast); + + blend.blend_enable = 0; + blend.rgb_func = PIPE_BLEND_ADD; + blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rgb_dst_factor = PIPE_BLENDFACTOR_ONE; + blend.alpha_func = PIPE_BLEND_ADD; + blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.alpha_dst_factor = PIPE_BLENDFACTOR_ONE; + blend.logicop_enable = 0; + blend.logicop_func = PIPE_LOGICOP_CLEAR; + /* Needed to allow color writes to FB, even if blending disabled */ + blend.colormask = PIPE_MASK_RGBA; + blend.dither = 0; + ctx->blend = ctx->pipe->create_blend_state(ctx->pipe, &blend); + ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend); + + dsa.depth.enabled = 0; + dsa.depth.writemask = 0; + dsa.depth.func = PIPE_FUNC_ALWAYS; + dsa.depth.occlusion_count = 0; + for (unsigned i = 0; i < 2; ++i) + { + dsa.stencil[i].enabled = 0; + dsa.stencil[i].func = PIPE_FUNC_ALWAYS; + dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP; + dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP; + dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP; + dsa.stencil[i].ref_value = 0; + dsa.stencil[i].valuemask = 0; + dsa.stencil[i].writemask = 0; + } + dsa.alpha.enabled = 0; + dsa.alpha.func = PIPE_FUNC_ALWAYS; + dsa.alpha.ref_value = 0; + ctx->dsa = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &dsa); + ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, ctx->dsa); + + return true; +} + +static struct pipe_video_context * +sp_mpeg12_create(struct pipe_screen *screen, enum pipe_video_profile profile, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height) +{ + struct sp_mpeg12_context *ctx; + + assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12); + + ctx = CALLOC_STRUCT(sp_mpeg12_context); + + if (!ctx) + return NULL; + + ctx->base.profile = profile; + ctx->base.chroma_format = chroma_format; + ctx->base.width = width; + ctx->base.height = height; + + ctx->base.screen = screen; + ctx->base.destroy = sp_mpeg12_destroy; + ctx->base.decode_macroblocks = sp_mpeg12_decode_macroblocks; + ctx->base.clear_surface = sp_mpeg12_clear_surface; + ctx->base.render_picture = sp_mpeg12_render_picture; + ctx->base.set_decode_target = sp_mpeg12_set_decode_target; + + ctx->pipe = softpipe_create(screen); + if (!ctx->pipe) + { + FREE(ctx); + return NULL; + } + + /* TODO: Use slice buffering for softpipe when implemented, no advantage to buffering an entire picture */ + if (!vl_mpeg12_mc_renderer_init(&ctx->mc_renderer, ctx->pipe, + width, height, chroma_format, + VL_MPEG12_MC_RENDERER_BUFFER_PICTURE, + /* TODO: Use XFER_NONE when implemented */ + VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE, + true)) + { + ctx->pipe->destroy(ctx->pipe); + FREE(ctx); + return NULL; + } + + if (!vl_compositor_init(&ctx->compositor, ctx->pipe)) + { + vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer); + ctx->pipe->destroy(ctx->pipe); + FREE(ctx); + return NULL; + } + + if (!init_pipe_state(ctx)) + { + vl_compositor_cleanup(&ctx->compositor); + vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer); + ctx->pipe->destroy(ctx->pipe); + FREE(ctx); + return NULL; + } + + return &ctx->base; +} + +struct pipe_video_context * +sp_video_create(struct pipe_screen *screen, enum pipe_video_profile profile, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height) +{ + assert(screen); + assert(width && height); + + switch (u_reduce_video_profile(profile)) + { + case PIPE_VIDEO_CODEC_MPEG12: + return sp_mpeg12_create(screen, profile, + chroma_format, + width, height); + default: + return NULL; + } +} diff --git a/src/gallium/drivers/softpipe/sp_video_context.h b/src/gallium/drivers/softpipe/sp_video_context.h new file mode 100644 index 00000000000..a70ce9f476a --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_video_context.h @@ -0,0 +1,30 @@ +#ifndef SP_VIDEO_CONTEXT_H +#define SP_VIDEO_CONTEXT_H + +#include +#include +#include + +struct pipe_screen; +struct pipe_context; +struct pipe_video_surface; + +struct sp_mpeg12_context +{ + struct pipe_video_context base; + struct pipe_context *pipe; + struct pipe_video_surface *decode_target; + struct vl_mpeg12_mc_renderer mc_renderer; + struct vl_compositor compositor; + + void *rast; + void *dsa; + void *blend; +}; + +struct pipe_video_context * +sp_video_create(struct pipe_screen *screen, enum pipe_video_profile profile, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height); + +#endif /* SP_VIDEO_CONTEXT_H */ diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index f252d6df00d..1980831dd9d 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -315,6 +315,30 @@ enum pipe_transfer_usage { #define PIPE_REFERENCED_FOR_READ (1 << 0) #define PIPE_REFERENCED_FOR_WRITE (1 << 1) + +enum pipe_video_codec +{ + PIPE_VIDEO_CODEC_MPEG12, /**< MPEG1, MPEG2 */ + PIPE_VIDEO_CODEC_MPEG4, /**< DIVX, XVID */ + PIPE_VIDEO_CODEC_VC1, /**< WMV */ + PIPE_VIDEO_CODEC_MPEG4_AVC /**< H.264 */ +}; + +enum pipe_video_profile +{ + PIPE_VIDEO_PROFILE_MPEG1, + PIPE_VIDEO_PROFILE_MPEG2_SIMPLE, + PIPE_VIDEO_PROFILE_MPEG2_MAIN, + PIPE_VIDEO_PROFILE_MPEG4_SIMPLE, + PIPE_VIDEO_PROFILE_MPEG4_ADVANCED_SIMPLE, + PIPE_VIDEO_PROFILE_VC1_SIMPLE, + PIPE_VIDEO_PROFILE_VC1_MAIN, + PIPE_VIDEO_PROFILE_VC1_ADVANCED, + PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE, + PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN, + PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH +}; + #ifdef __cplusplus } #endif diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index c4469d4a9e9..af230809201 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -613,6 +613,24 @@ pf_has_alpha( enum pipe_format format ) } } +enum pipe_video_chroma_format +{ + PIPE_VIDEO_CHROMA_FORMAT_420, + PIPE_VIDEO_CHROMA_FORMAT_422, + PIPE_VIDEO_CHROMA_FORMAT_444 +}; + +#if 0 +enum pipe_video_surface_format +{ + PIPE_VIDEO_SURFACE_FORMAT_NV12, /**< Planar; Y plane, UV plane */ + PIPE_VIDEO_SURFACE_FORMAT_YV12, /**< Planar; Y plane, U plane, V plane */ + PIPE_VIDEO_SURFACE_FORMAT_YUYV, /**< Interleaved; Y,U,Y,V,Y,U,Y,V */ + PIPE_VIDEO_SURFACE_FORMAT_UYVY, /**< Interleaved; U,Y,V,Y,U,Y,V,Y */ + PIPE_VIDEO_SURFACE_FORMAT_VUYA /**< Packed; A31-24|Y23-16|U15-8|V7-0 */ +}; +#endif + #ifdef __cplusplus } #endif diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index 3f30c52a169..f0a4de5df33 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -53,7 +53,10 @@ extern "C" { struct pipe_fence_handle; struct pipe_winsys; struct pipe_buffer; - +struct pipe_texture; +struct pipe_surface; +struct pipe_video_surface; +struct pipe_transfer; /** @@ -252,6 +255,17 @@ struct pipe_screen { void (*buffer_destroy)( struct pipe_buffer *buf ); + /** + * Create a video surface suitable for use as a decoding target by the + * driver's pipe_video_context. + */ + struct pipe_video_surface* + (*video_surface_create)( struct pipe_screen *screen, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height ); + + void (*video_surface_destroy)( struct pipe_video_surface *vsfc ); + /** * Do any special operations to ensure frontbuffer contents are diff --git a/src/gallium/include/pipe/p_video_context.h b/src/gallium/include/pipe/p_video_context.h new file mode 100644 index 00000000000..937705ac505 --- /dev/null +++ b/src/gallium/include/pipe/p_video_context.h @@ -0,0 +1,92 @@ +#ifndef PIPE_VIDEO_CONTEXT_H +#define PIPE_VIDEO_CONTEXT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +struct pipe_screen; +struct pipe_buffer; +struct pipe_surface; +struct pipe_video_surface; +struct pipe_macroblock; +struct pipe_picture_desc; +struct pipe_fence_handle; + +/** + * Gallium video rendering context + */ +struct pipe_video_context +{ + struct pipe_screen *screen; + enum pipe_video_profile profile; + enum pipe_video_chroma_format chroma_format; + unsigned width; + unsigned height; + + void *priv; /**< context private data (for DRI for example) */ + + void (*destroy)(struct pipe_video_context *vpipe); + + /** + * Picture decoding and displaying + */ + /*@{*/ + void (*decode_bitstream)(struct pipe_video_context *vpipe, + unsigned num_bufs, + struct pipe_buffer **bitstream_buf); + + void (*decode_macroblocks)(struct pipe_video_context *vpipe, + struct pipe_video_surface *past, + struct pipe_video_surface *future, + unsigned num_macroblocks, + struct pipe_macroblock *macroblocks, + struct pipe_fence_handle **fence); + + void (*clear_surface)(struct pipe_video_context *vpipe, + unsigned x, unsigned y, + unsigned width, unsigned height, + unsigned value, + struct pipe_surface *surface); + + void (*render_picture)(struct pipe_video_context *vpipe, + /*struct pipe_surface *backround, + struct pipe_video_rect *backround_area,*/ + struct pipe_video_surface *src_surface, + enum pipe_mpeg12_picture_type picture_type, + /*unsigned num_past_surfaces, + struct pipe_video_surface *past_surfaces, + unsigned num_future_surfaces, + struct pipe_video_surface *future_surfaces,*/ + struct pipe_video_rect *src_area, + struct pipe_surface *dst_surface, + struct pipe_video_rect *dst_area, + /*unsigned num_layers, + struct pipe_texture *layers, + struct pipe_video_rect *layer_src_areas, + struct pipe_video_rect *layer_dst_areas,*/ + struct pipe_fence_handle **fence); + /*@}*/ + + /** + * Parameter-like states (or properties) + */ + /*@{*/ + void (*set_picture_desc)(struct pipe_video_context *vpipe, + const struct pipe_picture_desc *desc); + + void (*set_decode_target)(struct pipe_video_context *vpipe, + struct pipe_video_surface *dt); + + /* TODO: Interface for CSC matrix, scaling modes, post-processing, etc. */ + /*@}*/ +}; + + +#ifdef __cplusplus +} +#endif + +#endif /* PIPE_VIDEO_CONTEXT_H */ diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h new file mode 100644 index 00000000000..a0128fbd48f --- /dev/null +++ b/src/gallium/include/pipe/p_video_state.h @@ -0,0 +1,158 @@ +#ifndef PIPE_VIDEO_STATE_H +#define PIPE_VIDEO_STATE_H + +/* u_reduce_video_profile() needs these */ +#include +#include + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct pipe_video_surface +{ + struct pipe_reference reference; + struct pipe_screen *screen; + enum pipe_video_chroma_format chroma_format; + /*enum pipe_video_surface_format surface_format;*/ + unsigned width; + unsigned height; +}; + +static INLINE void +pipe_video_surface_reference(struct pipe_video_surface **ptr, struct pipe_video_surface *surf) +{ + struct pipe_video_surface *old_surf = *ptr; + + if (pipe_reference((struct pipe_reference **)ptr, &surf->reference)) + old_surf->screen->video_surface_destroy(old_surf); +} + +struct pipe_video_rect +{ + unsigned x, y, w, h; +}; + +static INLINE enum pipe_video_codec +u_reduce_video_profile(enum pipe_video_profile profile) +{ + switch (profile) + { + case PIPE_VIDEO_PROFILE_MPEG1: + case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE: + case PIPE_VIDEO_PROFILE_MPEG2_MAIN: + return PIPE_VIDEO_CODEC_MPEG12; + + case PIPE_VIDEO_PROFILE_MPEG4_SIMPLE: + case PIPE_VIDEO_PROFILE_MPEG4_ADVANCED_SIMPLE: + return PIPE_VIDEO_CODEC_MPEG4; + + case PIPE_VIDEO_PROFILE_VC1_SIMPLE: + case PIPE_VIDEO_PROFILE_VC1_MAIN: + case PIPE_VIDEO_PROFILE_VC1_ADVANCED: + return PIPE_VIDEO_CODEC_VC1; + + case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE: + case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN: + case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH: + return PIPE_VIDEO_CODEC_MPEG4_AVC; + + default: + assert(false); + } + + return -1; +} + +enum pipe_mpeg12_picture_type +{ + PIPE_MPEG12_PICTURE_TYPE_FIELD_TOP, + PIPE_MPEG12_PICTURE_TYPE_FIELD_BOTTOM, + PIPE_MPEG12_PICTURE_TYPE_FRAME +}; + +enum pipe_mpeg12_macroblock_type +{ + PIPE_MPEG12_MACROBLOCK_TYPE_INTRA, + PIPE_MPEG12_MACROBLOCK_TYPE_FWD, + PIPE_MPEG12_MACROBLOCK_TYPE_BKWD, + PIPE_MPEG12_MACROBLOCK_TYPE_BI, + + PIPE_MPEG12_MACROBLOCK_NUM_TYPES +}; + +enum pipe_mpeg12_motion_type +{ + PIPE_MPEG12_MOTION_TYPE_FIELD, + PIPE_MPEG12_MOTION_TYPE_FRAME, + PIPE_MPEG12_MOTION_TYPE_DUALPRIME, + PIPE_MPEG12_MOTION_TYPE_16x8 +}; + +enum pipe_mpeg12_dct_type +{ + PIPE_MPEG12_DCT_TYPE_FIELD, + PIPE_MPEG12_DCT_TYPE_FRAME +}; + +struct pipe_macroblock +{ + enum pipe_video_codec codec; +}; + +struct pipe_mpeg12_macroblock +{ + struct pipe_macroblock base; + + unsigned mbx; + unsigned mby; + enum pipe_mpeg12_macroblock_type mb_type; + enum pipe_mpeg12_motion_type mo_type; + enum pipe_mpeg12_dct_type dct_type; + signed pmv[2][2][2]; + unsigned cbp; + void *blocks; +}; + +#if 0 +struct pipe_picture_desc +{ + enum pipe_video_format format; +}; + +struct pipe_mpeg12_picture_desc +{ + struct pipe_picture_desc base; + + /* TODO: Use bitfields where possible? */ + struct pipe_surface *forward_reference; + struct pipe_surface *backward_reference; + unsigned picture_coding_type; + unsigned fcode; + unsigned intra_dc_precision; + unsigned picture_structure; + unsigned top_field_first; + unsigned frame_pred_frame_dct; + unsigned concealment_motion_vectors; + unsigned q_scale_type; + unsigned intra_vlc_format; + unsigned alternate_scan; + unsigned full_pel_forward_vector; + unsigned full_pel_backward_vector; + struct pipe_buffer *intra_quantizer_matrix; + struct pipe_buffer *non_intra_quantizer_matrix; + struct pipe_buffer *chroma_intra_quantizer_matrix; + struct pipe_buffer *chroma_non_intra_quantizer_matrix; +}; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PIPE_VIDEO_STATE_H */ -- cgit v1.2.3 From d52d51ab8ae1240f77b6c18c3e99be4bf4868037 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sun, 27 Sep 2009 23:14:52 -0400 Subject: g3dvl: Formatting and cleanups. --- src/gallium/auxiliary/vl/vl_bitstream_parser.c | 24 +- src/gallium/auxiliary/vl/vl_compositor.c | 62 ++--- src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c | 216 +++++---------- src/gallium/auxiliary/vl/vl_shader_build.c | 6 +- src/gallium/drivers/softpipe/sp_texture.c | 3 +- src/gallium/drivers/softpipe/sp_video_context.c | 332 +++++++++++------------ src/gallium/drivers/softpipe/sp_video_context.h | 16 +- src/gallium/state_trackers/xorg/xvmc/context.c | 26 +- src/gallium/state_trackers/xorg/xvmc/surface.c | 85 ++---- 9 files changed, 313 insertions(+), 457 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/auxiliary/vl/vl_bitstream_parser.c b/src/gallium/auxiliary/vl/vl_bitstream_parser.c index 356faa13481..7883b95bbe9 100644 --- a/src/gallium/auxiliary/vl/vl_bitstream_parser.c +++ b/src/gallium/auxiliary/vl/vl_bitstream_parser.c @@ -23,12 +23,12 @@ show_bits(unsigned cursor, unsigned how_many_bits, const unsigned *bitstream) assert(bitstream); - if (cur_bit + how_many_bits > sizeof(unsigned) * CHAR_BIT) - { - return grab_bits(cur_bit, sizeof(unsigned) * CHAR_BIT - cur_bit, - bitstream[cur_int]) | - grab_bits(0, cur_bit + how_many_bits - sizeof(unsigned) * CHAR_BIT, - bitstream[cur_int + 1]) << (sizeof(unsigned) * CHAR_BIT - cur_bit); + if (cur_bit + how_many_bits > sizeof(unsigned) * CHAR_BIT) { + unsigned lower = grab_bits(cur_bit, sizeof(unsigned) * CHAR_BIT - cur_bit, + bitstream[cur_int]); + unsigned upper = grab_bits(0, cur_bit + how_many_bits - sizeof(unsigned) * CHAR_BIT, + bitstream[cur_int + 1]) + return lower | upper << (sizeof(unsigned) * CHAR_BIT - cur_bit); } else return grab_bits(cur_bit, how_many_bits, bitstream[cur_int]); @@ -87,16 +87,14 @@ vl_bitstream_parser_show_bits(struct vl_bitstream_parser *parser, cursor = parser->cursor; cur_bitstream = parser->cur_bitstream; - while (1) - { + while (1) { unsigned bits_left = parser->sizes[cur_bitstream] * CHAR_BIT - cursor; unsigned bits_to_show = how_many_bits > bits_left ? bits_left : how_many_bits; bits |= show_bits(cursor, bits_to_show, parser->bitstreams[cur_bitstream]) << shift; - if (how_many_bits > bits_to_show) - { + if (how_many_bits > bits_to_show) { how_many_bits -= bits_to_show; cursor = 0; ++cur_bitstream; @@ -117,8 +115,7 @@ void vl_bitstream_parser_forward(struct vl_bitstream_parser *parser, parser->cursor += how_many_bits; - while (parser->cursor > parser->sizes[parser->cur_bitstream] * CHAR_BIT) - { + while (parser->cursor > parser->sizes[parser->cur_bitstream] * CHAR_BIT) { parser->cursor -= parser->sizes[parser->cur_bitstream++] * CHAR_BIT; assert(parser->cur_bitstream < parser->num_bitstreams); } @@ -134,8 +131,7 @@ void vl_bitstream_parser_rewind(struct vl_bitstream_parser *parser, c = parser->cursor - how_many_bits; - while (c < 0) - { + while (c < 0) { c += parser->sizes[parser->cur_bitstream--] * CHAR_BIT; assert(parser->cur_bitstream < parser->num_bitstreams); } diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c index 0894421c0b8..bca03cd4010 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.c +++ b/src/gallium/auxiliary/vl/vl_compositor.c @@ -162,30 +162,28 @@ create_vert_shader(struct vl_compositor *c) ti = 3; /* - * decl i0 ; Vertex pos - * decl i1 ; Vertex texcoords + * decl i0 ; Vertex pos + * decl i1 ; Vertex texcoords */ - for (unsigned i = 0; i < 2; i++) - { + for (unsigned i = 0; i < 2; i++) { decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } /* - * decl c0 ; Scaling vector to scale vertex pos rect to destination size - * decl c1 ; Translation vector to move vertex pos rect into position - * decl c2 ; Scaling vector to scale texcoord rect to source size - * decl c3 ; Translation vector to move texcoord rect into position + * decl c0 ; Scaling vector to scale vertex pos rect to destination size + * decl c1 ; Translation vector to move vertex pos rect into position + * decl c2 ; Scaling vector to scale texcoord rect to source size + * decl c3 ; Translation vector to move texcoord rect into position */ decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 3); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); /* - * decl o0 ; Vertex pos - * decl o1 ; Vertex texcoords + * decl o0 ; Vertex pos + * decl o1 ; Vertex texcoords */ - for (unsigned i = 0; i < 2; i++) - { + for (unsigned i = 0; i < 2; i++) { decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } @@ -195,11 +193,10 @@ create_vert_shader(struct vl_compositor *c) ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); /* - * mad o0, i0, c0, c1 ; Scale and translate unit output rect to destination size and pos - * mad o1, i1, c2, c3 ; Scale and translate unit texcoord rect to source size and pos + * mad o0, i0, c0, c1 ; Scale and translate unit output rect to destination size and pos + * mad o1, i1, c2, c3 ; Scale and translate unit texcoord rect to source size and pos */ - for (unsigned i = 0; i < 2; ++i) - { + for (unsigned i = 0; i < 2; ++i) { inst = vl_inst4(TGSI_OPCODE_MAD, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i, TGSI_FILE_CONSTANT, i * 2, TGSI_FILE_CONSTANT, i * 2 + 1); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } @@ -239,18 +236,18 @@ create_frag_shader(struct vl_compositor *c) ti = 3; - /* decl i0 ; Texcoords for s0 */ + /* decl i0 ; Texcoords for s0 */ decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, 1, 0, 0, TGSI_INTERPOLATE_LINEAR); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); /* - * decl c0 ; Bias vector for CSC - * decl c1-c4 ; CSC matrix c1-c4 + * decl c0 ; Bias vector for CSC + * decl c1-c4 ; CSC matrix c1-c4 */ decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 4); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - /* decl o0 ; Fragment color */ + /* decl o0 ; Fragment color */ decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); @@ -258,25 +255,24 @@ create_frag_shader(struct vl_compositor *c) decl = vl_decl_temps(0, 0); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - /* decl s0 ; Sampler for tex containing picture to display */ + /* decl s0 ; Sampler for tex containing picture to display */ decl = vl_decl_samplers(0, 0); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); - /* tex2d t0, i0, s0 ; Read src pixel */ + /* tex2d t0, i0, s0 ; Read src pixel */ inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* sub t0, t0, c0 ; Subtract bias vector from pixel */ + /* sub t0, t0, c0 ; Subtract bias vector from pixel */ inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); /* - * dp4 o0.x, t0, c1 ; Multiply pixel by the color conversion matrix + * dp4 o0.x, t0, c1 ; Multiply pixel by the color conversion matrix * dp4 o0.y, t0, c2 * dp4 o0.z, t0, c3 */ - for (unsigned i = 0; i < 3; ++i) - { + for (unsigned i = 0; i < 3; ++i) { inst = vl_inst3(TGSI_OPCODE_DP4, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i + 1); inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); @@ -365,10 +361,10 @@ init_buffers(struct vl_compositor *c) c->vertex_bufs[0].buffer_offset = 0; c->vertex_bufs[0].buffer = pipe_buffer_create ( - c->pipe->screen, - 1, - PIPE_BUFFER_USAGE_VERTEX, - sizeof(struct vertex2f) * 4 + c->pipe->screen, + 1, + PIPE_BUFFER_USAGE_VERTEX, + sizeof(struct vertex2f) * 4 ); memcpy @@ -476,13 +472,11 @@ bool vl_compositor_init(struct vl_compositor *compositor, struct pipe_context *p if (!init_pipe_state(compositor)) return false; - if (!init_shaders(compositor)) - { + if (!init_shaders(compositor)) { cleanup_pipe_state(compositor); return false; } - if (!init_buffers(compositor)) - { + if (!init_buffers(compositor)) { cleanup_shaders(compositor); cleanup_pipe_state(compositor); return false; diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c index 7e73c5ced9f..b728067d79b 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c +++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c @@ -99,8 +99,7 @@ create_intra_vert_shader(struct vl_mpeg12_mc_renderer *r) * decl i2 ; Chroma Cb texcoords * decl i3 ; Chroma Cr texcoords */ - for (unsigned i = 0; i < 4; i++) - { + for (unsigned i = 0; i < 4; i++) { decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } @@ -111,8 +110,7 @@ create_intra_vert_shader(struct vl_mpeg12_mc_renderer *r) * decl o2 ; Chroma Cb texcoords * decl o3 ; Chroma Cr texcoords */ - for (unsigned i = 0; i < 4; i++) - { + for (unsigned i = 0; i < 4; i++) { decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } @@ -123,8 +121,7 @@ create_intra_vert_shader(struct vl_mpeg12_mc_renderer *r) * mov o2, i2 ; Move input chroma Cb texcoords to output * mov o3, i3 ; Move input chroma Cr texcoords to output */ - for (unsigned i = 0; i < 4; ++i) - { + for (unsigned i = 0; i < 4; ++i) { inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } @@ -169,8 +166,7 @@ create_intra_frag_shader(struct vl_mpeg12_mc_renderer *r) * decl i1 ; Chroma Cb texcoords * decl i2 ; Chroma Cr texcoords */ - for (unsigned i = 0; i < 3; ++i) - { + for (unsigned i = 0; i < 3; ++i) { decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } @@ -192,8 +188,7 @@ create_intra_frag_shader(struct vl_mpeg12_mc_renderer *r) * decl s1 ; Sampler for chroma Cb texture * decl s2 ; Sampler for chroma Cr texture */ - for (unsigned i = 0; i < 3; ++i) - { + for (unsigned i = 0; i < 3; ++i) { decl = vl_decl_samplers(i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } @@ -206,8 +201,7 @@ create_intra_frag_shader(struct vl_mpeg12_mc_renderer *r) * tex2d t1, i2, s2 ; Read texel from chroma Cr texture * mov t0.z, t1.x ; Move Cr sample into .z component */ - for (unsigned i = 0; i < 3; ++i) - { + for (unsigned i = 0; i < 3; ++i) { inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i, TGSI_FILE_SAMPLER, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); @@ -266,8 +260,7 @@ create_frame_pred_vert_shader(struct vl_mpeg12_mc_renderer *r) * decl i4 ; Ref surface top field texcoords * decl i5 ; Ref surface bottom field texcoords (unused, packed in the same stream) */ - for (unsigned i = 0; i < 6; i++) - { + for (unsigned i = 0; i < 6; i++) { decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } @@ -279,8 +272,7 @@ create_frame_pred_vert_shader(struct vl_mpeg12_mc_renderer *r) * decl o3 ; Chroma Cr texcoords * decl o4 ; Ref macroblock texcoords */ - for (unsigned i = 0; i < 5; i++) - { + for (unsigned i = 0; i < 5; i++) { decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } @@ -291,8 +283,7 @@ create_frame_pred_vert_shader(struct vl_mpeg12_mc_renderer *r) * mov o2, i2 ; Move input chroma Cb texcoords to output * mov o3, i3 ; Move input chroma Cr texcoords to output */ - for (unsigned i = 0; i < 4; ++i) - { + for (unsigned i = 0; i < 4; ++i) { inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } @@ -348,8 +339,7 @@ create_frame_pred_frag_shader(struct vl_mpeg12_mc_renderer *r) * decl i2 ; Chroma Cr texcoords * decl i3 ; Ref macroblock texcoords */ - for (unsigned i = 0; i < 4; ++i) - { + for (unsigned i = 0; i < 4; ++i) { decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } @@ -372,8 +362,7 @@ create_frame_pred_frag_shader(struct vl_mpeg12_mc_renderer *r) * decl s2 ; Sampler for chroma Cr texture * decl s3 ; Sampler for ref surface texture */ - for (unsigned i = 0; i < 4; ++i) - { + for (unsigned i = 0; i < 4; ++i) { decl = vl_decl_samplers(i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } @@ -386,8 +375,7 @@ create_frame_pred_frag_shader(struct vl_mpeg12_mc_renderer *r) * tex2d t1, i2, s2 ; Read texel from chroma Cr texture * mov t0.z, t1.x ; Move Cr sample into .z component */ - for (unsigned i = 0; i < 3; ++i) - { + for (unsigned i = 0; i < 3; ++i) { inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i, TGSI_FILE_SAMPLER, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); @@ -462,8 +450,7 @@ create_frame_bi_pred_vert_shader(struct vl_mpeg12_mc_renderer *r) * decl i6 ; Second ref macroblock top field texcoords * decl i7 ; Second ref macroblock bottom field texcoords (unused, packed in the same stream) */ - for (unsigned i = 0; i < 8; i++) - { + for (unsigned i = 0; i < 8; i++) { decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } @@ -476,8 +463,7 @@ create_frame_bi_pred_vert_shader(struct vl_mpeg12_mc_renderer *r) * decl o4 ; First ref macroblock texcoords * decl o5 ; Second ref macroblock texcoords */ - for (unsigned i = 0; i < 6; i++) - { + for (unsigned i = 0; i < 6; i++) { decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } @@ -488,8 +474,7 @@ create_frame_bi_pred_vert_shader(struct vl_mpeg12_mc_renderer *r) * mov o2, i2 ; Move input chroma Cb texcoords to output * mov o3, i3 ; Move input chroma Cr texcoords to output */ - for (unsigned i = 0; i < 4; ++i) - { + for (unsigned i = 0; i < 4; ++i) { inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } @@ -498,8 +483,7 @@ create_frame_bi_pred_vert_shader(struct vl_mpeg12_mc_renderer *r) * add o4, i0, i4 ; Translate vertex pos by motion vec to form first ref macroblock texcoords * add o5, i0, i6 ; Translate vertex pos by motion vec to form second ref macroblock texcoords */ - for (unsigned i = 0; i < 2; ++i) - { + for (unsigned i = 0; i < 2; ++i) { inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 4, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, (i + 2) * 2); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } @@ -552,8 +536,7 @@ create_frame_bi_pred_frag_shader(struct vl_mpeg12_mc_renderer *r) * decl i3 ; First ref macroblock texcoords * decl i4 ; Second ref macroblock texcoords */ - for (unsigned i = 0; i < 5; ++i) - { + for (unsigned i = 0; i < 5; ++i) { decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } @@ -580,8 +563,7 @@ create_frame_bi_pred_frag_shader(struct vl_mpeg12_mc_renderer *r) * decl s3 ; Sampler for first ref surface texture * decl s4 ; Sampler for second ref surface texture */ - for (unsigned i = 0; i < 5; ++i) - { + for (unsigned i = 0; i < 5; ++i) { decl = vl_decl_samplers(i, i); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); } @@ -594,8 +576,7 @@ create_frame_bi_pred_frag_shader(struct vl_mpeg12_mc_renderer *r) * tex2d t1, i2, s2 ; Read texel from chroma Cr texture * mov t0.z, t1.x ; Move Cr sample into .z component */ - for (unsigned i = 0; i < 3; ++i) - { + for (unsigned i = 0; i < 3; ++i) { inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i, TGSI_FILE_SAMPLER, i); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); @@ -615,8 +596,7 @@ create_frame_bi_pred_frag_shader(struct vl_mpeg12_mc_renderer *r) * tex2d t1, i3, s3 ; Read texel from first ref macroblock * tex2d t2, i4, s4 ; Read texel from second ref macroblock */ - for (unsigned i = 0; i < 2; ++i) - { + for (unsigned i = 0; i < 2; ++i) { inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 3, TGSI_FILE_SAMPLER, i + 3); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } @@ -655,8 +635,7 @@ xfer_buffers_map(struct vl_mpeg12_mc_renderer *r) { assert(r); - for (unsigned i = 0; i < 3; ++i) - { + for (unsigned i = 0; i < 3; ++i) { r->tex_transfer[i] = r->pipe->screen->get_tex_transfer ( r->pipe->screen, r->textures.all[i], @@ -673,8 +652,7 @@ xfer_buffers_unmap(struct vl_mpeg12_mc_renderer *r) { assert(r); - for (unsigned i = 0; i < 3; ++i) - { + for (unsigned i = 0; i < 3; ++i) { r->pipe->screen->transfer_unmap(r->pipe->screen, r->tex_transfer[i]); r->pipe->screen->tex_transfer_destroy(r->tex_transfer[i]); } @@ -710,13 +688,11 @@ init_pipe_state(struct vl_mpeg12_mc_renderer *r) filters[0] = PIPE_TEX_FILTER_NEAREST; /* Chroma filters */ if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_444 || - r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE) - { + r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE) { filters[1] = PIPE_TEX_FILTER_NEAREST; filters[2] = PIPE_TEX_FILTER_NEAREST; } - else - { + else { filters[1] = PIPE_TEX_FILTER_LINEAR; filters[2] = PIPE_TEX_FILTER_LINEAR; } @@ -724,8 +700,7 @@ init_pipe_state(struct vl_mpeg12_mc_renderer *r) filters[3] = PIPE_TEX_FILTER_LINEAR; filters[4] = PIPE_TEX_FILTER_LINEAR; - for (unsigned i = 0; i < 5; ++i) - { + for (unsigned i = 0; i < 5; ++i) { sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; @@ -817,8 +792,7 @@ init_buffers(struct vl_mpeg12_mc_renderer *r) r->textures.individual.y = r->pipe->screen->texture_create(r->pipe->screen, &template); - if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) - { + if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) { template.width[0] = r->pot_buffers ? util_next_power_of_two(r->picture_width / 2) : r->picture_width / 2; @@ -847,8 +821,7 @@ init_buffers(struct vl_mpeg12_mc_renderer *r) sizeof(struct vertex2f) * 4 * 24 * r->macroblocks_per_batch ); - for (unsigned i = 1; i < 3; ++i) - { + for (unsigned i = 1; i < 3; ++i) { r->vertex_bufs.all[i].stride = sizeof(struct vertex2f) * 2; r->vertex_bufs.all[i].max_index = 24 * r->macroblocks_per_batch - 1; r->vertex_bufs.all[i].buffer_offset = 0; @@ -957,8 +930,7 @@ get_macroblock_type(struct pipe_mpeg12_macroblock *mb) { assert(mb); - switch (mb->mb_type) - { + switch (mb->mb_type) { case PIPE_MPEG12_MACROBLOCK_TYPE_INTRA: return MACROBLOCK_TYPE_INTRA; case PIPE_MPEG12_MACROBLOCK_TYPE_FWD: @@ -1058,8 +1030,7 @@ gen_macroblock_verts(struct vl_mpeg12_mc_renderer *r, assert(ycbcr_vb); assert(pos < r->macroblocks_per_batch); - switch (mb->mb_type) - { + switch (mb->mb_type) { case PIPE_MPEG12_MACROBLOCK_TYPE_BI: { struct vertex2f *vb; @@ -1071,21 +1042,17 @@ gen_macroblock_verts(struct vl_mpeg12_mc_renderer *r, mo_vec[0].x = mb->pmv[0][1][0] * 0.5f * r->surface_tex_inv_size.x; mo_vec[0].y = mb->pmv[0][1][1] * 0.5f * r->surface_tex_inv_size.y; - if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME) - { - for (unsigned i = 0; i < 24 * 2; i += 2) - { + if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME) { + for (unsigned i = 0; i < 24 * 2; i += 2) { vb[i].x = mo_vec[0].x; vb[i].y = mo_vec[0].y; } } - else - { + else { mo_vec[1].x = mb->pmv[1][1][0] * 0.5f * r->surface_tex_inv_size.x; mo_vec[1].y = mb->pmv[1][1][1] * 0.5f * r->surface_tex_inv_size.y; - for (unsigned i = 0; i < 24 * 2; i += 2) - { + for (unsigned i = 0; i < 24 * 2; i += 2) { vb[i].x = mo_vec[0].x; vb[i].y = mo_vec[0].y; vb[i + 1].x = mo_vec[1].x; @@ -1104,41 +1071,33 @@ gen_macroblock_verts(struct vl_mpeg12_mc_renderer *r, vb = ref_vb[0] + pos * 2 * 24; - if (mb->mb_type == PIPE_MPEG12_MACROBLOCK_TYPE_BKWD) - { + if (mb->mb_type == PIPE_MPEG12_MACROBLOCK_TYPE_BKWD) { mo_vec[0].x = mb->pmv[0][1][0] * 0.5f * r->surface_tex_inv_size.x; mo_vec[0].y = mb->pmv[0][1][1] * 0.5f * r->surface_tex_inv_size.y; - if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FIELD) - { + if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FIELD) { mo_vec[1].x = mb->pmv[1][1][0] * 0.5f * r->surface_tex_inv_size.x; mo_vec[1].y = mb->pmv[1][1][1] * 0.5f * r->surface_tex_inv_size.y; } } - else - { + else { mo_vec[0].x = mb->pmv[0][0][0] * 0.5f * r->surface_tex_inv_size.x; mo_vec[0].y = mb->pmv[0][0][1] * 0.5f * r->surface_tex_inv_size.y; - if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FIELD) - { + if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FIELD) { mo_vec[1].x = mb->pmv[1][0][0] * 0.5f * r->surface_tex_inv_size.x; mo_vec[1].y = mb->pmv[1][0][1] * 0.5f * r->surface_tex_inv_size.y; } } - if (mb->mb_type == PIPE_MPEG12_MOTION_TYPE_FRAME) - { - for (unsigned i = 0; i < 24 * 2; i += 2) - { + if (mb->mb_type == PIPE_MPEG12_MOTION_TYPE_FRAME) { + for (unsigned i = 0; i < 24 * 2; i += 2) { vb[i].x = mo_vec[0].x; vb[i].y = mo_vec[0].y; } } - else - { - for (unsigned i = 0; i < 24 * 2; i += 2) - { + else { + for (unsigned i = 0; i < 24 * 2; i += 2) { vb[i].x = mo_vec[0].x; vb[i].y = mo_vec[0].y; vb[i + 1].x = mo_vec[1].x; @@ -1198,8 +1157,7 @@ gen_macroblock_stream(struct vl_mpeg12_mc_renderer *r, assert(r); assert(num_macroblocks); - for (unsigned i = 0; i < r->num_macroblocks; ++i) - { + for (unsigned i = 0; i < r->num_macroblocks; ++i) { enum MACROBLOCK_TYPE mb_type = get_macroblock_type(&r->macroblock_buf[i]); ++num_macroblocks[mb_type]; } @@ -1224,8 +1182,7 @@ gen_macroblock_stream(struct vl_mpeg12_mc_renderer *r, PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD ); - for (unsigned i = 0; i < r->num_macroblocks; ++i) - { + for (unsigned i = 0; i < r->num_macroblocks; ++i) { enum MACROBLOCK_TYPE mb_type = get_macroblock_type(&r->macroblock_buf[i]); gen_macroblock_verts(r, &r->macroblock_buf[i], offset[mb_type], @@ -1276,8 +1233,7 @@ flush(struct vl_mpeg12_mc_renderer *r) r->pipe->set_constant_buffer(r->pipe, PIPE_SHADER_FRAGMENT, 0, &r->fs_const_buf); - if (num_macroblocks[MACROBLOCK_TYPE_INTRA] > 0) - { + if (num_macroblocks[MACROBLOCK_TYPE_INTRA] > 0) { r->pipe->set_vertex_buffers(r->pipe, 1, r->vertex_bufs.all); r->pipe->set_vertex_elements(r->pipe, 4, r->vertex_elems); r->pipe->set_sampler_textures(r->pipe, 3, r->textures.all); @@ -1290,8 +1246,7 @@ flush(struct vl_mpeg12_mc_renderer *r) vb_start += num_macroblocks[MACROBLOCK_TYPE_INTRA] * 24; } - if (num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] > 0) - { + if (num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] > 0) { r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all); r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems); r->textures.individual.ref[0] = r->past; @@ -1305,8 +1260,7 @@ flush(struct vl_mpeg12_mc_renderer *r) vb_start += num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] * 24; } - if (false /*num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] > 0 */ ) - { + if (false /*num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] > 0 */ ) { r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all); r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems); r->textures.individual.ref[0] = r->past; @@ -1320,8 +1274,7 @@ flush(struct vl_mpeg12_mc_renderer *r) vb_start += num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] * 24; } - if (num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] > 0) - { + if (num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] > 0) { r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all); r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems); r->textures.individual.ref[0] = r->future; @@ -1335,8 +1288,7 @@ flush(struct vl_mpeg12_mc_renderer *r) vb_start += num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] * 24; } - if (false /*num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] > 0 */ ) - { + if (false /*num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] > 0 */ ) { r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all); r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems); r->textures.individual.ref[0] = r->future; @@ -1350,8 +1302,7 @@ flush(struct vl_mpeg12_mc_renderer *r) vb_start += num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] * 24; } - if (num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] > 0) - { + if (num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] > 0) { r->pipe->set_vertex_buffers(r->pipe, 3, r->vertex_bufs.all); r->pipe->set_vertex_elements(r->pipe, 8, r->vertex_elems); r->textures.individual.ref[0] = r->past; @@ -1366,8 +1317,7 @@ flush(struct vl_mpeg12_mc_renderer *r) vb_start += num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] * 24; } - if (false /*num_macroblocks[MACROBLOCK_TYPE_BI_FIELD_PRED] > 0 */ ) - { + if (false /*num_macroblocks[MACROBLOCK_TYPE_BI_FIELD_PRED] > 0 */ ) { r->pipe->set_vertex_buffers(r->pipe, 3, r->vertex_bufs.all); r->pipe->set_vertex_elements(r->pipe, 8, r->vertex_elems); r->textures.individual.ref[0] = r->past; @@ -1436,20 +1386,15 @@ grab_blocks(struct vl_mpeg12_mc_renderer *r, unsigned mbx, unsigned mby, tex_pitch = r->tex_transfer[0]->stride / r->tex_transfer[0]->block.size; texels = r->texels[0] + mbpy * tex_pitch + mbpx; - for (unsigned y = 0; y < 2; ++y) - { - for (unsigned x = 0; x < 2; ++x, ++tb) - { - if ((cbp >> (5 - tb)) & 1) - { - if (dct_type == PIPE_MPEG12_DCT_TYPE_FRAME) - { + for (unsigned y = 0; y < 2; ++y) { + for (unsigned x = 0; x < 2; ++x, ++tb) { + if ((cbp >> (5 - tb)) & 1) { + if (dct_type == PIPE_MPEG12_DCT_TYPE_FRAME) { grab_frame_coded_block(blocks + sb * BLOCK_WIDTH * BLOCK_HEIGHT, texels + y * tex_pitch * BLOCK_WIDTH + x * BLOCK_WIDTH, tex_pitch); } - else - { + else { grab_field_coded_block(blocks + sb * BLOCK_WIDTH * BLOCK_HEIGHT, texels + y * tex_pitch + x * BLOCK_WIDTH, tex_pitch); @@ -1457,14 +1402,11 @@ grab_blocks(struct vl_mpeg12_mc_renderer *r, unsigned mbx, unsigned mby, ++sb; } - else if (r->eb_handling != VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_NONE) - { + else if (r->eb_handling != VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_NONE) { if (r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ALL || - ZERO_BLOCK_IS_NIL(r->zero_block[0])) - { + ZERO_BLOCK_IS_NIL(r->zero_block[0])) { fill_zero_block(texels + y * tex_pitch * BLOCK_WIDTH + x * BLOCK_WIDTH, tex_pitch); - if (r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE) - { + if (r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE) { r->zero_block[0].x = (mbpx + x * 8) * r->surface_tex_inv_size.x; r->zero_block[0].y = (mbpy + y * 8) * r->surface_tex_inv_size.y; } @@ -1479,24 +1421,19 @@ grab_blocks(struct vl_mpeg12_mc_renderer *r, unsigned mbx, unsigned mby, mbpx /= 2; mbpy /= 2; - for (tb = 0; tb < 2; ++tb) - { + for (tb = 0; tb < 2; ++tb) { tex_pitch = r->tex_transfer[tb + 1]->stride / r->tex_transfer[tb + 1]->block.size; texels = r->texels[tb + 1] + mbpy * tex_pitch + mbpx; - if ((cbp >> (1 - tb)) & 1) - { + if ((cbp >> (1 - tb)) & 1) { grab_frame_coded_block(blocks + sb * BLOCK_WIDTH * BLOCK_HEIGHT, texels, tex_pitch); ++sb; } - else if (r->eb_handling != VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_NONE) - { + else if (r->eb_handling != VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_NONE) { if (r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ALL || - ZERO_BLOCK_IS_NIL(r->zero_block[tb + 1])) - { + ZERO_BLOCK_IS_NIL(r->zero_block[tb + 1])) { fill_zero_block(texels, tex_pitch); - if (r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE) - { + if (r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE) { r->zero_block[tb + 1].x = (mbpx << 1) * r->surface_tex_inv_size.x; r->zero_block[tb + 1].y = (mbpy << 1) * r->surface_tex_inv_size.y; } @@ -1553,13 +1490,11 @@ vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer, if (!init_pipe_state(renderer)) return false; - if (!init_shaders(renderer)) - { + if (!init_shaders(renderer)) { cleanup_pipe_state(renderer); return false; } - if (!init_buffers(renderer)) - { + if (!init_buffers(renderer)) { cleanup_shaders(renderer); cleanup_pipe_state(renderer); return false; @@ -1607,12 +1542,9 @@ vl_mpeg12_mc_renderer_render_macroblocks(struct vl_mpeg12_mc_renderer assert(num_macroblocks); assert(mpeg12_macroblocks); - if (renderer->surface) - { - if (surface != renderer->surface) - { - if (renderer->num_macroblocks > 0) - { + if (renderer->surface) { + if (surface != renderer->surface) { + if (renderer->num_macroblocks > 0) { xfer_buffers_unmap(renderer); flush(renderer); } @@ -1627,8 +1559,7 @@ vl_mpeg12_mc_renderer_render_macroblocks(struct vl_mpeg12_mc_renderer else new_surface = true; - if (new_surface) - { + if (new_surface) { renderer->surface = surface; renderer->past = past; renderer->future = future; @@ -1637,21 +1568,18 @@ vl_mpeg12_mc_renderer_render_macroblocks(struct vl_mpeg12_mc_renderer renderer->surface_tex_inv_size.y = 1.0f / surface->height[0]; } - while (num_macroblocks) - { + while (num_macroblocks) { unsigned left_in_batch = renderer->macroblocks_per_batch - renderer->num_macroblocks; unsigned num_to_submit = MIN2(num_macroblocks, left_in_batch); - for (unsigned i = 0; i < num_to_submit; ++i) - { + for (unsigned i = 0; i < num_to_submit; ++i) { assert(mpeg12_macroblocks[i].base.codec == PIPE_VIDEO_CODEC_MPEG12); grab_macroblock(renderer, &mpeg12_macroblocks[i]); } num_macroblocks -= num_to_submit; - if (renderer->num_macroblocks == renderer->macroblocks_per_batch) - { + if (renderer->num_macroblocks == renderer->macroblocks_per_batch) { xfer_buffers_unmap(renderer); flush(renderer); xfer_buffers_map(renderer); diff --git a/src/gallium/auxiliary/vl/vl_shader_build.c b/src/gallium/auxiliary/vl/vl_shader_build.c index 5a4a5ab72cc..9ad1e052c6c 100644 --- a/src/gallium/auxiliary/vl/vl_shader_build.c +++ b/src/gallium/auxiliary/vl/vl_shader_build.c @@ -30,9 +30,9 @@ struct tgsi_full_declaration vl_decl_interpolated_input assert ( - interpolation == TGSI_INTERPOLATE_CONSTANT || - interpolation == TGSI_INTERPOLATE_LINEAR || - interpolation == TGSI_INTERPOLATE_PERSPECTIVE + interpolation == TGSI_INTERPOLATE_CONSTANT || + interpolation == TGSI_INTERPOLATE_LINEAR || + interpolation == TGSI_INTERPOLATE_PERSPECTIVE ); decl.Declaration.File = TGSI_FILE_INPUT; diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 45289380d08..1c64d58372d 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -415,8 +415,7 @@ softpipe_video_surface_create(struct pipe_screen *screen, template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_RENDER_TARGET; sp_vsfc->tex = screen->texture_create(screen, &template); - if (!sp_vsfc->tex) - { + if (!sp_vsfc->tex) { FREE(sp_vsfc); return NULL; } diff --git a/src/gallium/drivers/softpipe/sp_video_context.c b/src/gallium/drivers/softpipe/sp_video_context.c index 1b47bbede26..3be33fbbdf8 100644 --- a/src/gallium/drivers/softpipe/sp_video_context.c +++ b/src/gallium/drivers/softpipe/sp_video_context.c @@ -7,24 +7,24 @@ static void sp_mpeg12_destroy(struct pipe_video_context *vpipe) { - struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; + struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; - assert(vpipe); + assert(vpipe); - /* Asserted in softpipe_delete_fs_state() for some reason */ - ctx->pipe->bind_vs_state(ctx->pipe, NULL); - ctx->pipe->bind_fs_state(ctx->pipe, NULL); + /* Asserted in softpipe_delete_fs_state() for some reason */ + ctx->pipe->bind_vs_state(ctx->pipe, NULL); + ctx->pipe->bind_fs_state(ctx->pipe, NULL); - ctx->pipe->delete_blend_state(ctx->pipe, ctx->blend); - ctx->pipe->delete_rasterizer_state(ctx->pipe, ctx->rast); - ctx->pipe->delete_depth_stencil_alpha_state(ctx->pipe, ctx->dsa); + ctx->pipe->delete_blend_state(ctx->pipe, ctx->blend); + ctx->pipe->delete_rasterizer_state(ctx->pipe, ctx->rast); + ctx->pipe->delete_depth_stencil_alpha_state(ctx->pipe, ctx->dsa); - pipe_video_surface_reference(&ctx->decode_target, NULL); - vl_compositor_cleanup(&ctx->compositor); - vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer); - ctx->pipe->destroy(ctx->pipe); + pipe_video_surface_reference(&ctx->decode_target, NULL); + vl_compositor_cleanup(&ctx->compositor); + vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer); + ctx->pipe->destroy(ctx->pipe); - FREE(ctx); + FREE(ctx); } static void @@ -35,20 +35,20 @@ sp_mpeg12_decode_macroblocks(struct pipe_video_context *vpipe, struct pipe_macroblock *macroblocks, struct pipe_fence_handle **fence) { - struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; - struct pipe_mpeg12_macroblock *mpeg12_macroblocks = (struct pipe_mpeg12_macroblock*)macroblocks; + struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; + struct pipe_mpeg12_macroblock *mpeg12_macroblocks = (struct pipe_mpeg12_macroblock*)macroblocks; - assert(vpipe); - assert(num_macroblocks); - assert(macroblocks); - assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12); - assert(ctx->decode_target); + assert(vpipe); + assert(num_macroblocks); + assert(macroblocks); + assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12); + assert(ctx->decode_target); - vl_mpeg12_mc_renderer_render_macroblocks(&ctx->mc_renderer, - softpipe_video_surface(ctx->decode_target)->tex, - past ? softpipe_video_surface(past)->tex : NULL, - future ? softpipe_video_surface(future)->tex : NULL, - num_macroblocks, mpeg12_macroblocks, fence); + vl_mpeg12_mc_renderer_render_macroblocks(&ctx->mc_renderer, + softpipe_video_surface(ctx->decode_target)->tex, + past ? softpipe_video_surface(past)->tex : NULL, + future ? softpipe_video_surface(future)->tex : NULL, + num_macroblocks, mpeg12_macroblocks, fence); } static void @@ -58,12 +58,12 @@ sp_mpeg12_clear_surface(struct pipe_video_context *vpipe, unsigned value, struct pipe_surface *surface) { - struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; + struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; - assert(vpipe); - assert(surface); + assert(vpipe); + assert(surface); - ctx->pipe->surface_fill(ctx->pipe, surface, x, y, width, height, value); + ctx->pipe->surface_fill(ctx->pipe, surface, x, y, width, height, value); } static void @@ -85,106 +85,105 @@ sp_mpeg12_render_picture(struct pipe_video_context *vpipe, struct pipe_video_rect *layer_dst_areas*/ struct pipe_fence_handle **fence) { - struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; + struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; - assert(vpipe); - assert(src_surface); - assert(src_area); - assert(dst_surface); - assert(dst_area); + assert(vpipe); + assert(src_surface); + assert(src_area); + assert(dst_surface); + assert(dst_area); - vl_compositor_render(&ctx->compositor, softpipe_video_surface(src_surface)->tex, - picture_type, src_area, dst_surface->texture, dst_area, fence); + vl_compositor_render(&ctx->compositor, softpipe_video_surface(src_surface)->tex, + picture_type, src_area, dst_surface->texture, dst_area, fence); } static void sp_mpeg12_set_decode_target(struct pipe_video_context *vpipe, struct pipe_video_surface *dt) { - struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; + struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; - assert(vpipe); - assert(dt); + assert(vpipe); + assert(dt); - pipe_video_surface_reference(&ctx->decode_target, dt); + pipe_video_surface_reference(&ctx->decode_target, dt); } static bool init_pipe_state(struct sp_mpeg12_context *ctx) { - struct pipe_rasterizer_state rast; - struct pipe_blend_state blend; - struct pipe_depth_stencil_alpha_state dsa; + struct pipe_rasterizer_state rast; + struct pipe_blend_state blend; + struct pipe_depth_stencil_alpha_state dsa; - assert(ctx); + assert(ctx); - rast.flatshade = 1; - rast.flatshade_first = 0; - rast.light_twoside = 0; - rast.front_winding = PIPE_WINDING_CCW; - rast.cull_mode = PIPE_WINDING_CW; - rast.fill_cw = PIPE_POLYGON_MODE_FILL; - rast.fill_ccw = PIPE_POLYGON_MODE_FILL; - rast.offset_cw = 0; - rast.offset_ccw = 0; - rast.scissor = 0; - rast.poly_smooth = 0; - rast.poly_stipple_enable = 0; - rast.point_sprite = 0; - rast.point_size_per_vertex = 0; - rast.multisample = 0; - rast.line_smooth = 0; - rast.line_stipple_enable = 0; - rast.line_stipple_factor = 0; - rast.line_stipple_pattern = 0; - rast.line_last_pixel = 0; - rast.bypass_vs_clip_and_viewport = 0; - rast.line_width = 1; - rast.point_smooth = 0; - rast.point_size = 1; - rast.offset_units = 1; - rast.offset_scale = 1; - /*rast.sprite_coord_mode[i] = ;*/ - ctx->rast = ctx->pipe->create_rasterizer_state(ctx->pipe, &rast); - ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rast); + rast.flatshade = 1; + rast.flatshade_first = 0; + rast.light_twoside = 0; + rast.front_winding = PIPE_WINDING_CCW; + rast.cull_mode = PIPE_WINDING_CW; + rast.fill_cw = PIPE_POLYGON_MODE_FILL; + rast.fill_ccw = PIPE_POLYGON_MODE_FILL; + rast.offset_cw = 0; + rast.offset_ccw = 0; + rast.scissor = 0; + rast.poly_smooth = 0; + rast.poly_stipple_enable = 0; + rast.point_sprite = 0; + rast.point_size_per_vertex = 0; + rast.multisample = 0; + rast.line_smooth = 0; + rast.line_stipple_enable = 0; + rast.line_stipple_factor = 0; + rast.line_stipple_pattern = 0; + rast.line_last_pixel = 0; + rast.bypass_vs_clip_and_viewport = 0; + rast.line_width = 1; + rast.point_smooth = 0; + rast.point_size = 1; + rast.offset_units = 1; + rast.offset_scale = 1; + /*rast.sprite_coord_mode[i] = ;*/ + ctx->rast = ctx->pipe->create_rasterizer_state(ctx->pipe, &rast); + ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rast); - blend.blend_enable = 0; - blend.rgb_func = PIPE_BLEND_ADD; - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_func = PIPE_BLEND_ADD; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ONE; - blend.logicop_enable = 0; - blend.logicop_func = PIPE_LOGICOP_CLEAR; - /* Needed to allow color writes to FB, even if blending disabled */ - blend.colormask = PIPE_MASK_RGBA; - blend.dither = 0; - ctx->blend = ctx->pipe->create_blend_state(ctx->pipe, &blend); - ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend); + blend.blend_enable = 0; + blend.rgb_func = PIPE_BLEND_ADD; + blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rgb_dst_factor = PIPE_BLENDFACTOR_ONE; + blend.alpha_func = PIPE_BLEND_ADD; + blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.alpha_dst_factor = PIPE_BLENDFACTOR_ONE; + blend.logicop_enable = 0; + blend.logicop_func = PIPE_LOGICOP_CLEAR; + /* Needed to allow color writes to FB, even if blending disabled */ + blend.colormask = PIPE_MASK_RGBA; + blend.dither = 0; + ctx->blend = ctx->pipe->create_blend_state(ctx->pipe, &blend); + ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend); - dsa.depth.enabled = 0; - dsa.depth.writemask = 0; - dsa.depth.func = PIPE_FUNC_ALWAYS; - dsa.depth.occlusion_count = 0; - for (unsigned i = 0; i < 2; ++i) - { - dsa.stencil[i].enabled = 0; - dsa.stencil[i].func = PIPE_FUNC_ALWAYS; - dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[i].ref_value = 0; - dsa.stencil[i].valuemask = 0; - dsa.stencil[i].writemask = 0; - } - dsa.alpha.enabled = 0; - dsa.alpha.func = PIPE_FUNC_ALWAYS; - dsa.alpha.ref_value = 0; - ctx->dsa = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &dsa); - ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, ctx->dsa); + dsa.depth.enabled = 0; + dsa.depth.writemask = 0; + dsa.depth.func = PIPE_FUNC_ALWAYS; + dsa.depth.occlusion_count = 0; + for (unsigned i = 0; i < 2; ++i) { + dsa.stencil[i].enabled = 0; + dsa.stencil[i].func = PIPE_FUNC_ALWAYS; + dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP; + dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP; + dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP; + dsa.stencil[i].ref_value = 0; + dsa.stencil[i].valuemask = 0; + dsa.stencil[i].writemask = 0; + } + dsa.alpha.enabled = 0; + dsa.alpha.func = PIPE_FUNC_ALWAYS; + dsa.alpha.ref_value = 0; + ctx->dsa = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &dsa); + ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, ctx->dsa); - return true; + return true; } static struct pipe_video_context * @@ -192,65 +191,61 @@ sp_mpeg12_create(struct pipe_screen *screen, enum pipe_video_profile profile, enum pipe_video_chroma_format chroma_format, unsigned width, unsigned height) { - struct sp_mpeg12_context *ctx; + struct sp_mpeg12_context *ctx; - assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12); + assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12); - ctx = CALLOC_STRUCT(sp_mpeg12_context); + ctx = CALLOC_STRUCT(sp_mpeg12_context); - if (!ctx) - return NULL; + if (!ctx) + return NULL; - ctx->base.profile = profile; - ctx->base.chroma_format = chroma_format; - ctx->base.width = width; - ctx->base.height = height; + ctx->base.profile = profile; + ctx->base.chroma_format = chroma_format; + ctx->base.width = width; + ctx->base.height = height; - ctx->base.screen = screen; - ctx->base.destroy = sp_mpeg12_destroy; - ctx->base.decode_macroblocks = sp_mpeg12_decode_macroblocks; - ctx->base.clear_surface = sp_mpeg12_clear_surface; - ctx->base.render_picture = sp_mpeg12_render_picture; - ctx->base.set_decode_target = sp_mpeg12_set_decode_target; + ctx->base.screen = screen; + ctx->base.destroy = sp_mpeg12_destroy; + ctx->base.decode_macroblocks = sp_mpeg12_decode_macroblocks; + ctx->base.clear_surface = sp_mpeg12_clear_surface; + ctx->base.render_picture = sp_mpeg12_render_picture; + ctx->base.set_decode_target = sp_mpeg12_set_decode_target; - ctx->pipe = softpipe_create(screen); - if (!ctx->pipe) - { - FREE(ctx); - return NULL; - } + ctx->pipe = softpipe_create(screen); + if (!ctx->pipe) { + FREE(ctx); + return NULL; + } - /* TODO: Use slice buffering for softpipe when implemented, no advantage to buffering an entire picture */ - if (!vl_mpeg12_mc_renderer_init(&ctx->mc_renderer, ctx->pipe, - width, height, chroma_format, - VL_MPEG12_MC_RENDERER_BUFFER_PICTURE, - /* TODO: Use XFER_NONE when implemented */ - VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE, - true)) - { - ctx->pipe->destroy(ctx->pipe); - FREE(ctx); - return NULL; - } + /* TODO: Use slice buffering for softpipe when implemented, no advantage to buffering an entire picture */ + if (!vl_mpeg12_mc_renderer_init(&ctx->mc_renderer, ctx->pipe, + width, height, chroma_format, + VL_MPEG12_MC_RENDERER_BUFFER_PICTURE, + /* TODO: Use XFER_NONE when implemented */ + VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE, + true)) { + ctx->pipe->destroy(ctx->pipe); + FREE(ctx); + return NULL; + } - if (!vl_compositor_init(&ctx->compositor, ctx->pipe)) - { - vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer); - ctx->pipe->destroy(ctx->pipe); - FREE(ctx); - return NULL; - } + if (!vl_compositor_init(&ctx->compositor, ctx->pipe)) { + vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer); + ctx->pipe->destroy(ctx->pipe); + FREE(ctx); + return NULL; + } - if (!init_pipe_state(ctx)) - { - vl_compositor_cleanup(&ctx->compositor); - vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer); - ctx->pipe->destroy(ctx->pipe); - FREE(ctx); - return NULL; - } + if (!init_pipe_state(ctx)) { + vl_compositor_cleanup(&ctx->compositor); + vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer); + ctx->pipe->destroy(ctx->pipe); + FREE(ctx); + return NULL; + } - return &ctx->base; + return &ctx->base; } struct pipe_video_context * @@ -258,16 +253,15 @@ sp_video_create(struct pipe_screen *screen, enum pipe_video_profile profile, enum pipe_video_chroma_format chroma_format, unsigned width, unsigned height) { - assert(screen); - assert(width && height); + assert(screen); + assert(width && height); - switch (u_reduce_video_profile(profile)) - { - case PIPE_VIDEO_CODEC_MPEG12: - return sp_mpeg12_create(screen, profile, - chroma_format, - width, height); - default: - return NULL; - } + switch (u_reduce_video_profile(profile)) { + case PIPE_VIDEO_CODEC_MPEG12: + return sp_mpeg12_create(screen, profile, + chroma_format, + width, height); + default: + return NULL; + } } diff --git a/src/gallium/drivers/softpipe/sp_video_context.h b/src/gallium/drivers/softpipe/sp_video_context.h index a70ce9f476a..2c7691c7cb9 100644 --- a/src/gallium/drivers/softpipe/sp_video_context.h +++ b/src/gallium/drivers/softpipe/sp_video_context.h @@ -11,15 +11,15 @@ struct pipe_video_surface; struct sp_mpeg12_context { - struct pipe_video_context base; - struct pipe_context *pipe; - struct pipe_video_surface *decode_target; - struct vl_mpeg12_mc_renderer mc_renderer; - struct vl_compositor compositor; + struct pipe_video_context base; + struct pipe_context *pipe; + struct pipe_video_surface *decode_target; + struct vl_mpeg12_mc_renderer mc_renderer; + struct vl_compositor compositor; - void *rast; - void *dsa; - void *blend; + void *rast; + void *dsa; + void *blend; }; struct pipe_video_context * diff --git a/src/gallium/state_trackers/xorg/xvmc/context.c b/src/gallium/state_trackers/xorg/xvmc/context.c index 33f47838f51..ff2bd295ece 100644 --- a/src/gallium/state_trackers/xorg/xvmc/context.c +++ b/src/gallium/state_trackers/xorg/xvmc/context.c @@ -28,16 +28,13 @@ static Status Validate(Display *dpy, XvPortID port, int surface_type_id, *found_port = false; - for (unsigned int i = 0; i < XScreenCount(dpy); ++i) - { + for (unsigned int i = 0; i < XScreenCount(dpy); ++i) { ret = XvQueryAdaptors(dpy, XRootWindow(dpy, i), &num_adaptors, &adaptor_info); if (ret != Success) return ret; - for (unsigned int j = 0; j < num_adaptors && !*found_port; ++j) - { - for (unsigned int k = 0; k < adaptor_info[j].num_ports && !*found_port; ++k) - { + for (unsigned int j = 0; j < num_adaptors && !*found_port; ++j) { + for (unsigned int k = 0; k < adaptor_info[j].num_ports && !*found_port; ++k) { XvMCSurfaceInfo *surface_info; if (adaptor_info[j].base_id + k != port) @@ -46,14 +43,12 @@ static Status Validate(Display *dpy, XvPortID port, int surface_type_id, *found_port = true; surface_info = XvMCListSurfaceTypes(dpy, adaptor_info[j].base_id, &num_types); - if (!surface_info) - { + if (!surface_info) { XvFreeAdaptorInfo(adaptor_info); return BadAlloc; } - for (unsigned int l = 0; l < num_types && !found_surface; ++l) - { + for (unsigned int l = 0; l < num_types && !found_surface; ++l) { if (surface_info[l].surface_type_id != surface_type_id) continue; @@ -65,7 +60,7 @@ static Status Validate(Display *dpy, XvPortID port, int surface_type_id, *screen = i; } - XFree(surface_info); + XFree(surface_info); } } @@ -102,8 +97,7 @@ static enum pipe_video_profile ProfileToPipe(int xvmc_profile) static enum pipe_video_chroma_format FormatToPipe(int xvmc_format) { - switch (xvmc_format) - { + switch (xvmc_format) { case XVMC_CHROMA_FORMAT_420: return PIPE_VIDEO_CHROMA_FORMAT_420; case XVMC_CHROMA_FORMAT_422: @@ -148,8 +142,7 @@ Status XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id, /* TODO: Reuse screen if process creates another context */ screen = vl_screen_create(dpy, scrn); - if (!screen) - { + if (!screen) { FREE(context_priv); return BadAlloc; } @@ -157,8 +150,7 @@ Status XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id, vpipe = vl_video_create(screen, ProfileToPipe(mc_type), FormatToPipe(chroma_format), width, height); - if (!vpipe) - { + if (!vpipe) { screen->destroy(screen); FREE(context_priv); return BadAlloc; diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c index 0467c4d07d9..6b7dbf11dcf 100644 --- a/src/gallium/state_trackers/xorg/xvmc/surface.c +++ b/src/gallium/state_trackers/xorg/xvmc/surface.c @@ -24,8 +24,7 @@ static enum pipe_mpeg12_macroblock_type TypeToPipe(int xvmc_mb_type) static enum pipe_mpeg12_picture_type PictureToPipe(int xvmc_pic) { - switch (xvmc_pic) - { + switch (xvmc_pic) { case XVMC_TOP_FIELD: return PIPE_MPEG12_PICTURE_TYPE_FIELD_TOP; case XVMC_BOTTOM_FIELD: @@ -41,8 +40,7 @@ static enum pipe_mpeg12_picture_type PictureToPipe(int xvmc_pic) static enum pipe_mpeg12_motion_type MotionToPipe(int xvmc_motion_type, int xvmc_dct_type) { - switch (xvmc_motion_type) - { + switch (xvmc_motion_type) { case XVMC_PREDICTION_FRAME: return xvmc_dct_type == XVMC_DCT_TYPE_FIELD ? PIPE_MPEG12_MOTION_TYPE_16x8 : PIPE_MPEG12_MOTION_TYPE_FRAME; @@ -66,8 +64,7 @@ CreateOrResizeBackBuffer(struct pipe_video_context *vpipe, unsigned int width, u assert(vpipe); - if (*backbuffer) - { + if (*backbuffer) { if ((*backbuffer)->width != width || (*backbuffer)->height != height) pipe_surface_reference(backbuffer, NULL); else @@ -121,8 +118,7 @@ MacroBlocksToPipe(const XvMCMacroBlockArray *xvmc_macroblocks, xvmc_mb = xvmc_macroblocks->macro_blocks + first_macroblock; - for (i = 0; i < num_macroblocks; ++i) - { + for (i = 0; i < num_macroblocks; ++i) { pipe_macroblocks->base.codec = PIPE_VIDEO_CODEC_MPEG12; pipe_macroblocks->mbx = xvmc_mb->x; pipe_macroblocks->mby = xvmc_mb->y; @@ -171,8 +167,7 @@ Status XvMCCreateSurface(Display *dpy, XvMCContext *context, XvMCSurface *surfac vsfc = vpipe->screen->video_surface_create(vpipe->screen, vpipe->chroma_format, vpipe->width, vpipe->height); - if (!vsfc) - { + if (!vsfc) { FREE(surface_priv); return BadAlloc; } @@ -262,35 +257,21 @@ Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int pictur Status XvMCFlushSurface(Display *dpy, XvMCSurface *surface) { -#if 0 - struct vlSurface *vl_sfc; - - assert(dpy); - - if (!surface) - return XvMCBadSurface; + assert(dpy); - vl_sfc = surface->privData; + if (!surface) + return XvMCBadSurface; - vlSurfaceFlush(vl_sfc); -#endif return Success; } Status XvMCSyncSurface(Display *dpy, XvMCSurface *surface) { -#if 0 - struct vlSurface *vl_sfc; - - assert(dpy); - - if (!surface) - return XvMCBadSurface; + assert(dpy); - vl_sfc = surface->privData; + if (!surface) + return XvMCBadSurface; - vlSurfaceSync(vl_sfc); -#endif return Success; } @@ -359,43 +340,15 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable, Status XvMCGetSurfaceStatus(Display *dpy, XvMCSurface *surface, int *status) { -#if 0 - struct vlSurface *vl_sfc; - enum vlResourceStatus res_status; - - assert(dpy); - - if (!surface) - return XvMCBadSurface; - - assert(status); - - vl_sfc = surface->privData; - - vlSurfaceGetStatus(vl_sfc, &res_status); - - switch (res_status) - { - case vlResourceStatusFree: - { - *status = 0; - break; - } - case vlResourceStatusRendering: - { - *status = XVMC_RENDERING; - break; - } - case vlResourceStatusDisplaying: - { - *status = XVMC_DISPLAYING; - break; - } - default: - assert(0); - } -#endif + assert(dpy); + + if (!surface) + return XvMCBadSurface; + + assert(status); + *status = 0; + return Success; } -- cgit v1.2.3 From 99e1745af9a6a1fe1ebc65b17afb5f1a975348d2 Mon Sep 17 00:00:00 2001 From: Cooper Yuan Date: Mon, 28 Sep 2009 17:55:38 +0800 Subject: r300g: fix r300g cause GPU hang issue. why there are two input position semantic tags is that ureg doesn't set vs input semantic due to commit: 6d8dbd3d1ec888 so use vs input index instead of semantic name. --- src/gallium/drivers/r300/r300_state_derived.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 5026afc8308..02b7ab91076 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -50,12 +50,11 @@ static void r300_vs_tab_routes(struct r300_context* r300, assert(info->num_inputs <= 16); - if (!r300screen->caps->has_tcl) + if (!r300screen->caps->has_tcl || !r300->rs_state->enable_vte) { for (i = 0; i < info->num_inputs; i++) { - switch (info->input_semantic_name[i]) { + switch (r300->vs->code.inputs[i]) { case TGSI_SEMANTIC_POSITION: - assert(pos == FALSE); pos = TRUE; tab[i] = 0; break; -- cgit v1.2.3 From 56870534803982a73019ddd77dab300d146f77c6 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 28 Sep 2009 13:03:03 +0100 Subject: softpipe: Fix MSVC build. --- src/gallium/drivers/softpipe/sp_video_context.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_video_context.c b/src/gallium/drivers/softpipe/sp_video_context.c index 3be33fbbdf8..ccb29726b6a 100644 --- a/src/gallium/drivers/softpipe/sp_video_context.c +++ b/src/gallium/drivers/softpipe/sp_video_context.c @@ -115,6 +115,7 @@ init_pipe_state(struct sp_mpeg12_context *ctx) struct pipe_rasterizer_state rast; struct pipe_blend_state blend; struct pipe_depth_stencil_alpha_state dsa; + unsigned i; assert(ctx); @@ -167,7 +168,7 @@ init_pipe_state(struct sp_mpeg12_context *ctx) dsa.depth.writemask = 0; dsa.depth.func = PIPE_FUNC_ALWAYS; dsa.depth.occlusion_count = 0; - for (unsigned i = 0; i < 2; ++i) { + for (i = 0; i < 2; ++i) { dsa.stencil[i].enabled = 0; dsa.stencil[i].func = PIPE_FUNC_ALWAYS; dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP; -- cgit v1.2.3 From 9871521b302117682afbefa7316a41a1a00485b2 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sun, 27 Sep 2009 10:56:42 -0400 Subject: llvmpipe: Grab a ref when the fb is set. Based on softpipe commit a77226071f6814a53358a5d6caff685889d0e4ec. --- src/gallium/drivers/llvmpipe/lp_context.c | 9 +++++++-- src/gallium/drivers/llvmpipe/lp_state_surface.c | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index a4b2bd8c2ad..202cb8ef439 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -107,11 +107,16 @@ static void llvmpipe_destroy( struct pipe_context *pipe ) if (llvmpipe->draw) draw_destroy( llvmpipe->draw ); - for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { lp_destroy_tile_cache(llvmpipe->cbuf_cache[i]); + pipe_surface_reference(&llvmpipe->framebuffer.cbufs[i], NULL); + } + pipe_surface_reference(&llvmpipe->framebuffer.zsbuf, NULL); - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { lp_destroy_tex_tile_cache(llvmpipe->tex_cache[i]); + pipe_texture_reference(&llvmpipe->texture[i], NULL); + } for (i = 0; i < Elements(llvmpipe->constants); i++) { if (llvmpipe->constants[i].buffer) { diff --git a/src/gallium/drivers/llvmpipe/lp_state_surface.c b/src/gallium/drivers/llvmpipe/lp_state_surface.c index 177a26b7b1f..2c29144c039 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_surface.c +++ b/src/gallium/drivers/llvmpipe/lp_state_surface.c @@ -56,7 +56,7 @@ llvmpipe_set_framebuffer_state(struct pipe_context *pipe, lp_flush_tile_cache(lp->cbuf_cache[i]); /* assign new */ - lp->framebuffer.cbufs[i] = fb->cbufs[i]; + pipe_surface_reference(&lp->framebuffer.cbufs[i], fb->cbufs[i]); /* update cache */ lp_tile_cache_set_surface(lp->cbuf_cache[i], fb->cbufs[i]); @@ -81,7 +81,7 @@ llvmpipe_set_framebuffer_state(struct pipe_context *pipe, } /* assign new */ - lp->framebuffer.zsbuf = fb->zsbuf; + pipe_surface_reference(&lp->framebuffer.zsbuf, fb->zsbuf); /* Tell draw module how deep the Z/depth buffer is */ if (lp->framebuffer.zsbuf) { -- cgit v1.2.3 From 60f3f22a52422b11cc71149a28e24a14a9251205 Mon Sep 17 00:00:00 2001 From: Vinson Lee Date: Tue, 29 Sep 2009 10:38:47 +0100 Subject: i915: Fix MSVC build. --- src/gallium/drivers/i915simple/i915_prim_vbuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index d50201642bd..8a3e466c845 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -198,7 +198,7 @@ i915_vbuf_render_map_vertices(struct vbuf_render *render) struct intel_winsys *iws = i915->iws; if (i915->vbo_flushed) - debug_printf("%s bad vbo flush occured stalling on hw\n", __func__); + debug_printf("%s bad vbo flush occured stalling on hw\n", __FUNCTION__); i915_render->vbo_ptr = iws->buffer_map(iws, i915_render->vbo, TRUE); -- cgit v1.2.3 From 7cda8ea44c2b65265cefa79bd29a4990ac81cee6 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 29 Sep 2009 13:58:58 +0100 Subject: llvmpipe: Emit SSE intrinsics based on runtime cpu capability check. Note that llvmpipe still doesn't run on any processor yet: if you don't have a recent processor with SSE4.1 you will still likely end up hitting a code path for which a generic non-sse4 version is not implemented yet. --- src/gallium/drivers/llvmpipe/lp_bld_arit.c | 72 +++++++++++------------------ src/gallium/drivers/llvmpipe/lp_bld_conv.c | 7 ++- src/gallium/drivers/llvmpipe/lp_bld_logic.c | 6 ++- src/gallium/drivers/llvmpipe/lp_jit.c | 3 ++ 4 files changed, 37 insertions(+), 51 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/llvmpipe/lp_bld_arit.c b/src/gallium/drivers/llvmpipe/lp_bld_arit.c index 31433318a7e..e8c5fa3c2a1 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_arit.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_arit.c @@ -48,6 +48,7 @@ #include "util/u_memory.h" #include "util/u_debug.h" #include "util/u_string.h" +#include "util/u_cpu_detect.h" #include "lp_bld_type.h" #include "lp_bld_const.h" @@ -119,30 +120,28 @@ lp_build_max_simple(struct lp_build_context *bld, /* TODO: optimize the constant case */ -#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) if(type.width * type.length == 128) { if(type.floating) { - if(type.width == 32) + if(type.width == 32 && util_cpu_caps.has_sse) intrinsic = "llvm.x86.sse.max.ps"; - if(type.width == 64) + if(type.width == 64 && util_cpu_caps.has_sse2) intrinsic = "llvm.x86.sse2.max.pd"; } else { - if(type.width == 8 && !type.sign) + if(type.width == 8 && !type.sign && util_cpu_caps.has_sse2) intrinsic = "llvm.x86.sse2.pmaxu.b"; - if(type.width == 8 && type.sign) + if(type.width == 8 && type.sign && util_cpu_caps.has_sse4_1) intrinsic = "llvm.x86.sse41.pmaxsb"; - if(type.width == 16 && !type.sign) + if(type.width == 16 && !type.sign && util_cpu_caps.has_sse4_1) intrinsic = "llvm.x86.sse41.pmaxuw"; - if(type.width == 16 && type.sign) + if(type.width == 16 && type.sign && util_cpu_caps.has_sse2) intrinsic = "llvm.x86.sse2.pmaxs.w"; - if(type.width == 32 && !type.sign) + if(type.width == 32 && !type.sign && util_cpu_caps.has_sse4_1) intrinsic = "llvm.x86.sse41.pmaxud"; - if(type.width == 32 && type.sign) + if(type.width == 32 && type.sign && util_cpu_caps.has_sse4_1) intrinsic = "llvm.x86.sse41.pmaxsd"; } } -#endif if(intrinsic) return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b); @@ -204,15 +203,14 @@ lp_build_add(struct lp_build_context *bld, if(a == bld->one || b == bld->one) return bld->one; -#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) - if(type.width * type.length == 128 && + if(util_cpu_caps.has_sse2 && + type.width * type.length == 128 && !type.floating && !type.fixed) { if(type.width == 8) intrinsic = type.sign ? "llvm.x86.sse2.padds.b" : "llvm.x86.sse2.paddus.b"; if(type.width == 16) intrinsic = type.sign ? "llvm.x86.sse2.padds.w" : "llvm.x86.sse2.paddus.w"; } -#endif if(intrinsic) return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b); @@ -257,15 +255,14 @@ lp_build_sub(struct lp_build_context *bld, if(b == bld->one) return bld->zero; -#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) - if(type.width * type.length == 128 && + if(util_cpu_caps.has_sse2 && + type.width * type.length == 128 && !type.floating && !type.fixed) { if(type.width == 8) intrinsic = type.sign ? "llvm.x86.sse2.psubs.b" : "llvm.x86.sse2.psubus.b"; if(type.width == 16) intrinsic = type.sign ? "llvm.x86.sse2.psubs.w" : "llvm.x86.sse2.psubus.w"; } -#endif if(intrinsic) return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b); @@ -419,8 +416,7 @@ lp_build_mul(struct lp_build_context *bld, return bld->undef; if(!type.floating && !type.fixed && type.norm) { -#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) - if(type.width == 8 && type.length == 16) { + if(util_cpu_caps.has_sse2 && type.width == 8 && type.length == 16) { LLVMTypeRef i16x8 = LLVMVectorType(LLVMInt16Type(), 8); LLVMTypeRef i8x16 = LLVMVectorType(LLVMInt8Type(), 16); static LLVMValueRef ml = NULL; @@ -456,7 +452,6 @@ lp_build_mul(struct lp_build_context *bld, return ab; } -#endif /* FIXME */ assert(0); @@ -493,10 +488,8 @@ lp_build_div(struct lp_build_context *bld, if(LLVMIsConstant(a) && LLVMIsConstant(b)) return LLVMConstFDiv(a, b); -#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) - if(type.width == 32 && type.length == 4) + if(util_cpu_caps.has_sse && type.width == 32 && type.length == 4) return lp_build_mul(bld, a, lp_build_rcp(bld, b)); -#endif return LLVMBuildFDiv(bld->builder, a, b, ""); } @@ -606,8 +599,7 @@ lp_build_abs(struct lp_build_context *bld, return a; } -#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) - if(type.width*type.length == 128) { + if(type.width*type.length == 128 && util_cpu_caps.has_ssse3) { switch(type.width) { case 8: return lp_build_intrinsic_unary(bld->builder, "llvm.x86.ssse3.pabs.b.128", vec_type, a); @@ -617,7 +609,6 @@ lp_build_abs(struct lp_build_context *bld, return lp_build_intrinsic_unary(bld->builder, "llvm.x86.ssse3.pabs.d.128", vec_type, a); } } -#endif return lp_build_max(bld, a, LLVMBuildNeg(bld->builder, a, "")); } @@ -710,9 +701,8 @@ lp_build_round(struct lp_build_context *bld, assert(type.floating); -#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) - return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_NEAREST); -#endif + if(util_cpu_caps.has_sse4_1) + return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_NEAREST); /* FIXME */ assert(0); @@ -728,9 +718,8 @@ lp_build_floor(struct lp_build_context *bld, assert(type.floating); -#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) - return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_FLOOR); -#endif + if(util_cpu_caps.has_sse4_1) + return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_FLOOR); /* FIXME */ assert(0); @@ -746,9 +735,8 @@ lp_build_ceil(struct lp_build_context *bld, assert(type.floating); -#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) - return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_CEIL); -#endif + if(util_cpu_caps.has_sse4_1) + return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_CEIL); /* FIXME */ assert(0); @@ -764,9 +752,8 @@ lp_build_trunc(struct lp_build_context *bld, assert(type.floating); -#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) - return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_TRUNCATE); -#endif + if(util_cpu_caps.has_sse4_1) + return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_TRUNCATE); /* FIXME */ assert(0); @@ -837,11 +824,9 @@ lp_build_rcp(struct lp_build_context *bld, if(LLVMIsConstant(a)) return LLVMConstFDiv(bld->one, a); - /* XXX: is this really necessary? */ -#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) - if(type.width == 32 && type.length == 4) + if(util_cpu_caps.has_sse && type.width == 32 && type.length == 4) + /* FIXME: improve precision */ return lp_build_intrinsic_unary(bld->builder, "llvm.x86.sse.rcp.ps", lp_build_vec_type(type), a); -#endif return LLVMBuildFDiv(bld->builder, bld->one, a, ""); } @@ -858,11 +843,8 @@ lp_build_rsqrt(struct lp_build_context *bld, assert(type.floating); - /* XXX: is this really necessary? */ -#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) - if(type.width == 32 && type.length == 4) + if(util_cpu_caps.has_sse && type.width == 32 && type.length == 4) return lp_build_intrinsic_unary(bld->builder, "llvm.x86.sse.rsqrt.ps", lp_build_vec_type(type), a); -#endif return lp_build_rcp(bld, lp_build_sqrt(bld, a)); } diff --git a/src/gallium/drivers/llvmpipe/lp_bld_conv.c b/src/gallium/drivers/llvmpipe/lp_bld_conv.c index 186cac70f62..20c8710214b 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_conv.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_conv.c @@ -63,6 +63,7 @@ #include "util/u_debug.h" #include "util/u_math.h" +#include "util/u_cpu_detect.h" #include "lp_bld_type.h" #include "lp_bld_const.h" @@ -334,8 +335,7 @@ lp_build_pack2(LLVMBuilderRef builder, assert(!src_type.floating); assert(!dst_type.floating); -#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) - if(src_type.width * src_type.length == 128) { + if(util_cpu_caps.has_sse2 && src_type.width * src_type.length == 128) { /* All X86 non-interleaved pack instructions all take signed inputs and * saturate them, so saturate beforehand. */ if(!src_type.sign && !clamped) { @@ -349,7 +349,7 @@ lp_build_pack2(LLVMBuilderRef builder, switch(src_type.width) { case 32: - if(dst_type.sign) + if(dst_type.sign || !util_cpu_caps.has_sse4_1) res = lp_build_intrinsic_binary(builder, "llvm.x86.sse2.packssdw.128", src_vec_type, lo, hi); else /* PACKUSDW is the only instrinsic with a consistent signature */ @@ -372,7 +372,6 @@ lp_build_pack2(LLVMBuilderRef builder, res = LLVMBuildBitCast(builder, res, dst_vec_type, ""); return res; } -#endif lo = LLVMBuildBitCast(builder, lo, dst_vec_type, ""); hi = LLVMBuildBitCast(builder, hi, dst_vec_type, ""); diff --git a/src/gallium/drivers/llvmpipe/lp_bld_logic.c b/src/gallium/drivers/llvmpipe/lp_bld_logic.c index 6b6f8207697..db22a8028a6 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_logic.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_logic.c @@ -33,6 +33,8 @@ */ +#include "util/u_cpu_detect.h" + #include "lp_bld_type.h" #include "lp_bld_const.h" #include "lp_bld_intr.h" @@ -65,7 +67,7 @@ lp_build_cmp(struct lp_build_context *bld, #if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) if(type.width * type.length == 128) { - if(type.floating) { + if(type.floating && util_cpu_caps.has_sse) { LLVMValueRef args[3]; unsigned cc; boolean swap; @@ -114,7 +116,7 @@ lp_build_cmp(struct lp_build_context *bld, res = LLVMBuildBitCast(bld->builder, res, int_vec_type, ""); return res; } - else { + else if(util_cpu_caps.has_sse2) { static const struct { unsigned swap:1; unsigned eq:1; diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c index f7111c1e5cf..5d2cf01e5bc 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.c +++ b/src/gallium/drivers/llvmpipe/lp_jit.c @@ -36,6 +36,7 @@ #include #include "util/u_memory.h" +#include "util/u_cpu_detect.h" #include "lp_screen.h" #include "lp_bld_intr.h" #include "lp_jit.h" @@ -147,6 +148,8 @@ lp_jit_screen_init(struct llvmpipe_screen *screen) { char *error = NULL; + util_cpu_detect(); + #ifdef LLVM_NATIVE_ARCH LLVMLinkInJIT(); LLVMInitializeNativeTarget(); -- cgit v1.2.3 From fbddc75aa2f6542117783b8024f9ebd2f0309e1f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 29 Sep 2009 08:21:54 -0600 Subject: softpipe: Grab a ref when the fb is set. Nasty bug when the surface is freed and another is allocated right on top of it. The next time we set the fb state SP thinks it's the same surface and doesn't flush, and when the flush eventually happens the surface belongs to a completely different texture. (cherry picked from commit a77226071f6814a53358a5d6caff685889d0e4ec) Conflicts: src/gallium/drivers/softpipe/sp_context.c --- src/gallium/drivers/softpipe/sp_context.c | 9 +++++++-- src/gallium/drivers/softpipe/sp_state_surface.c | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 86df320ea8a..b4650c0dc58 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -105,12 +105,17 @@ static void softpipe_destroy( struct pipe_context *pipe ) softpipe->quad[i].output->destroy( softpipe->quad[i].output ); } - for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { sp_destroy_tile_cache(softpipe->cbuf_cache[i]); + pipe_surface_reference(&softpipe->framebuffer.cbufs[i], NULL); + } sp_destroy_tile_cache(softpipe->zsbuf_cache); + pipe_surface_reference(&softpipe->framebuffer.zsbuf, NULL); - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { sp_destroy_tile_cache(softpipe->tex_cache[i]); + pipe_texture_reference(&softpipe->texture[i], NULL); + } for (i = 0; i < Elements(softpipe->constants); i++) { if (softpipe->constants[i].buffer) { diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c index 7c06d864a75..181bff8f75c 100644 --- a/src/gallium/drivers/softpipe/sp_state_surface.c +++ b/src/gallium/drivers/softpipe/sp_state_surface.c @@ -56,7 +56,7 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, sp_flush_tile_cache(sp, sp->cbuf_cache[i]); /* assign new */ - sp->framebuffer.cbufs[i] = fb->cbufs[i]; + pipe_surface_reference(&sp->framebuffer.cbufs[i], fb->cbufs[i]); /* update cache */ sp_tile_cache_set_surface(sp->cbuf_cache[i], fb->cbufs[i]); @@ -71,7 +71,7 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, sp_flush_tile_cache(sp, sp->zsbuf_cache); /* assign new */ - sp->framebuffer.zsbuf = fb->zsbuf; + pipe_surface_reference(&sp->framebuffer.zsbuf, fb->zsbuf); /* update cache */ sp_tile_cache_set_surface(sp->zsbuf_cache, fb->zsbuf); -- cgit v1.2.3 From 564df9dc5f6335eb8dc68f3c69cf054d2142663c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 29 Sep 2009 08:50:56 -0600 Subject: softpipe: initialize the clear_flags bitvector in sp_create_tile_cache() This silences tons of valgrind warnings in programs that don't call glClear(), such as progs/demos/gamma. --- src/gallium/drivers/softpipe/sp_tile_cache.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 461cbb9f953..5f7864e6714 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -130,6 +130,11 @@ sp_create_tile_cache( struct pipe_screen *screen ) tc->entries[pos].x = tc->entries[pos].y = -1; } + +#if TILE_CLEAR_OPTIMIZATION + /* set flags to indicate all the tiles are cleared */ + memset(tc->clear_flags, 255, sizeof(tc->clear_flags)); +#endif } return tc; } -- cgit v1.2.3 From 741c40a232637c933c9273bbdef905397e54bc94 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 29 Sep 2009 16:59:13 +0100 Subject: llvmpipe: Implement non SSE4.1 versions of floor and round. --- src/gallium/drivers/llvmpipe/lp_bld_arit.c | 177 +++++++++++++++++++---- src/gallium/drivers/llvmpipe/lp_bld_arit.h | 13 +- src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c | 4 +- 3 files changed, 159 insertions(+), 35 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/llvmpipe/lp_bld_arit.c b/src/gallium/drivers/llvmpipe/lp_bld_arit.c index e8c5fa3c2a1..f878706ad1e 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_arit.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_arit.c @@ -675,6 +675,8 @@ lp_build_round_sse41(struct lp_build_context *bld, assert(type.floating); assert(type.width*type.length == 128); + assert(lp_check_value(type, a)); + assert(util_cpu_caps.has_sse4_1); switch(type.width) { case 32: @@ -693,6 +695,28 @@ lp_build_round_sse41(struct lp_build_context *bld, } +LLVMValueRef +lp_build_trunc(struct lp_build_context *bld, + LLVMValueRef a) +{ + const struct lp_type type = bld->type; + + assert(type.floating); + assert(lp_check_value(type, a)); + + if(util_cpu_caps.has_sse4_1) + return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_TRUNCATE); + else { + LLVMTypeRef vec_type = lp_build_vec_type(type); + LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); + LLVMValueRef res; + res = LLVMBuildFPToSI(bld->builder, a, int_vec_type, ""); + res = LLVMBuildSIToFP(bld->builder, res, vec_type, ""); + return res; + } +} + + LLVMValueRef lp_build_round(struct lp_build_context *bld, LLVMValueRef a) @@ -700,13 +724,17 @@ lp_build_round(struct lp_build_context *bld, const struct lp_type type = bld->type; assert(type.floating); + assert(lp_check_value(type, a)); if(util_cpu_caps.has_sse4_1) return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_NEAREST); - - /* FIXME */ - assert(0); - return bld->undef; + else { + LLVMTypeRef vec_type = lp_build_vec_type(type); + LLVMValueRef res; + res = lp_build_iround(bld, a); + res = LLVMBuildSIToFP(bld->builder, res, vec_type, ""); + return res; + } } @@ -720,10 +748,13 @@ lp_build_floor(struct lp_build_context *bld, if(util_cpu_caps.has_sse4_1) return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_FLOOR); - - /* FIXME */ - assert(0); - return bld->undef; + else { + LLVMTypeRef vec_type = lp_build_vec_type(type); + LLVMValueRef res; + res = lp_build_ifloor(bld, a); + res = LLVMBuildSIToFP(bld->builder, res, vec_type, ""); + return res; + } } @@ -734,47 +765,74 @@ lp_build_ceil(struct lp_build_context *bld, const struct lp_type type = bld->type; assert(type.floating); + assert(lp_check_value(type, a)); if(util_cpu_caps.has_sse4_1) return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_CEIL); - - /* FIXME */ - assert(0); - return bld->undef; + else { + LLVMTypeRef vec_type = lp_build_vec_type(type); + LLVMValueRef res; + res = lp_build_iceil(bld, a); + res = LLVMBuildSIToFP(bld->builder, res, vec_type, ""); + return res; + } } +/** + * Convert to integer, through whichever rounding method that's fastest, + * typically truncating to zero. + */ LLVMValueRef -lp_build_trunc(struct lp_build_context *bld, - LLVMValueRef a) +lp_build_itrunc(struct lp_build_context *bld, + LLVMValueRef a) { const struct lp_type type = bld->type; + LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); assert(type.floating); + assert(lp_check_value(type, a)); - if(util_cpu_caps.has_sse4_1) - return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_TRUNCATE); - - /* FIXME */ - assert(0); - return bld->undef; + return LLVMBuildFPToSI(bld->builder, a, int_vec_type, ""); } -/** - * Convert to integer, through whichever rounding method that's fastest, - * typically truncating to zero. - */ LLVMValueRef -lp_build_int(struct lp_build_context *bld, - LLVMValueRef a) +lp_build_iround(struct lp_build_context *bld, + LLVMValueRef a) { const struct lp_type type = bld->type; LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); + LLVMValueRef res; assert(type.floating); + assert(lp_check_value(type, a)); - return LLVMBuildFPToSI(bld->builder, a, int_vec_type, ""); + if(util_cpu_caps.has_sse4_1) { + res = lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_NEAREST); + } + else { + LLVMTypeRef vec_type = lp_build_vec_type(type); + LLVMValueRef mask = lp_build_int_const_scalar(type, (unsigned long long)1 << (type.width - 1)); + LLVMValueRef sign; + LLVMValueRef half; + + /* get sign bit */ + sign = LLVMBuildBitCast(bld->builder, a, int_vec_type, ""); + sign = LLVMBuildAnd(bld->builder, sign, mask, ""); + + /* sign * 0.5 */ + half = lp_build_const_scalar(type, 0.5); + half = LLVMBuildBitCast(bld->builder, half, int_vec_type, ""); + half = LLVMBuildOr(bld->builder, sign, half, ""); + half = LLVMBuildBitCast(bld->builder, half, vec_type, ""); + + res = LLVMBuildAdd(bld->builder, a, half, ""); + } + + res = LLVMBuildFPToSI(bld->builder, res, int_vec_type, ""); + + return res; } @@ -782,9 +840,68 @@ LLVMValueRef lp_build_ifloor(struct lp_build_context *bld, LLVMValueRef a) { - a = lp_build_floor(bld, a); - a = lp_build_int(bld, a); - return a; + const struct lp_type type = bld->type; + LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); + LLVMValueRef res; + + assert(type.floating); + assert(lp_check_value(type, a)); + + if(util_cpu_caps.has_sse4_1) { + res = lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_FLOOR); + } + else { + /* Take the sign bit and add it to 1 constant */ + LLVMTypeRef vec_type = lp_build_vec_type(type); + unsigned mantissa = lp_mantissa(type); + LLVMValueRef mask = lp_build_int_const_scalar(type, (unsigned long long)1 << (type.width - 1)); + LLVMValueRef sign; + LLVMValueRef offset; + + /* sign = a < 0 ? ~0 : 0 */ + sign = LLVMBuildBitCast(bld->builder, a, int_vec_type, ""); + sign = LLVMBuildAnd(bld->builder, sign, mask, ""); + sign = LLVMBuildAShr(bld->builder, sign, lp_build_int_const_scalar(type, type.width - 1), ""); + + /* offset = -0.99999(9)f */ + offset = lp_build_const_scalar(type, -(double)(((unsigned long long)1 << mantissa) - 1)/((unsigned long long)1 << mantissa)); + offset = LLVMConstBitCast(offset, int_vec_type); + + /* offset = a < 0 ? -0.99999(9)f : 0.0f */ + offset = LLVMBuildAnd(bld->builder, offset, sign, ""); + offset = LLVMBuildBitCast(bld->builder, offset, vec_type, ""); + + res = LLVMBuildAdd(bld->builder, a, offset, ""); + } + + res = LLVMBuildFPToSI(bld->builder, res, int_vec_type, ""); + + return res; +} + + +LLVMValueRef +lp_build_iceil(struct lp_build_context *bld, + LLVMValueRef a) +{ + const struct lp_type type = bld->type; + LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); + LLVMValueRef res; + + assert(type.floating); + assert(lp_check_value(type, a)); + + if(util_cpu_caps.has_sse4_1) { + res = lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_CEIL); + } + else { + assert(0); + res = bld->undef; + } + + res = LLVMBuildFPToSI(bld->builder, res, int_vec_type, ""); + + return res; } diff --git a/src/gallium/drivers/llvmpipe/lp_bld_arit.h b/src/gallium/drivers/llvmpipe/lp_bld_arit.h index d68a97c4b87..095a8e1cabe 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_arit.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_arit.h @@ -126,11 +126,18 @@ lp_build_trunc(struct lp_build_context *bld, LLVMValueRef a); LLVMValueRef -lp_build_int(struct lp_build_context *bld, - LLVMValueRef a); +lp_build_ifloor(struct lp_build_context *bld, + LLVMValueRef a); +LLVMValueRef +lp_build_iceil(struct lp_build_context *bld, + LLVMValueRef a); LLVMValueRef -lp_build_ifloor(struct lp_build_context *bld, +lp_build_iround(struct lp_build_context *bld, + LLVMValueRef a); + +LLVMValueRef +lp_build_itrunc(struct lp_build_context *bld, LLVMValueRef a); LLVMValueRef diff --git a/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c index 8ca1be6f1be..1a47ca32d2d 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c @@ -274,8 +274,8 @@ lp_build_sample_2d_linear_soa(struct lp_build_sample_context *bld, s_fpart = lp_build_sub(&bld->coord_bld, s, s_ipart); t_fpart = lp_build_sub(&bld->coord_bld, t, t_ipart); - x0 = lp_build_int(&bld->coord_bld, s_ipart); - y0 = lp_build_int(&bld->coord_bld, t_ipart); + x0 = lp_build_itrunc(&bld->coord_bld, s_ipart); + y0 = lp_build_itrunc(&bld->coord_bld, t_ipart); x0 = lp_build_sample_wrap(bld, x0, width, bld->static_state->pot_width, bld->static_state->wrap_s); y0 = lp_build_sample_wrap(bld, y0, height, bld->static_state->pot_height, bld->static_state->wrap_t); -- cgit v1.2.3 From 754f48871c3be671031d9a495fc96a42b71da349 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 29 Sep 2009 17:21:34 +0100 Subject: llvmpipe: Runtime cpu checks for lp_build_min_simple too. --- src/gallium/drivers/llvmpipe/lp_bld_arit.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/llvmpipe/lp_bld_arit.c b/src/gallium/drivers/llvmpipe/lp_bld_arit.c index f878706ad1e..d27ef0de041 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_arit.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_arit.c @@ -54,6 +54,7 @@ #include "lp_bld_const.h" #include "lp_bld_intr.h" #include "lp_bld_logic.h" +#include "lp_bld_debug.h" #include "lp_bld_arit.h" @@ -72,30 +73,28 @@ lp_build_min_simple(struct lp_build_context *bld, /* TODO: optimize the constant case */ -#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) if(type.width * type.length == 128) { if(type.floating) { - if(type.width == 32) + if(type.width == 32 && util_cpu_caps.has_sse) intrinsic = "llvm.x86.sse.min.ps"; - if(type.width == 64) + if(type.width == 64 && util_cpu_caps.has_sse2) intrinsic = "llvm.x86.sse2.min.pd"; } else { - if(type.width == 8 && !type.sign) + if(type.width == 8 && !type.sign && util_cpu_caps.has_sse2) intrinsic = "llvm.x86.sse2.pminu.b"; - if(type.width == 8 && type.sign) + if(type.width == 8 && type.sign && util_cpu_caps.has_sse4_1) intrinsic = "llvm.x86.sse41.pminsb"; - if(type.width == 16 && !type.sign) + if(type.width == 16 && !type.sign && util_cpu_caps.has_sse4_1) intrinsic = "llvm.x86.sse41.pminuw"; - if(type.width == 16 && type.sign) + if(type.width == 16 && type.sign && util_cpu_caps.has_sse2) intrinsic = "llvm.x86.sse2.pmins.w"; - if(type.width == 32 && !type.sign) + if(type.width == 32 && !type.sign && util_cpu_caps.has_sse4_1) intrinsic = "llvm.x86.sse41.pminud"; - if(type.width == 32 && type.sign) + if(type.width == 32 && type.sign && util_cpu_caps.has_sse4_1) intrinsic = "llvm.x86.sse41.pminsd"; } } -#endif if(intrinsic) return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b); -- cgit v1.2.3 From a02ecdf8c2fc5783a4bc82e8cd9d36f0dec7ccec Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 29 Sep 2009 17:22:39 +0100 Subject: llvmpipe: First verify LLVM IR, only then run optimizing passes. --- src/gallium/drivers/llvmpipe/lp_state_fs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 9faed5a0b18..d5ce6993c5d 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -582,6 +582,11 @@ generate_fragment(struct llvmpipe_context *lp, * Translate the LLVM IR into machine code. */ + if(LLVMVerifyFunction(variant->function, LLVMPrintMessageAction)) { + LLVMDumpValue(variant->function); + abort(); + } + LLVMRunFunctionPassManager(screen->pass, variant->function); #ifdef DEBUG @@ -589,11 +594,6 @@ generate_fragment(struct llvmpipe_context *lp, debug_printf("\n"); #endif - if(LLVMVerifyFunction(variant->function, LLVMPrintMessageAction)) { - LLVMDumpValue(variant->function); - abort(); - } - variant->jit_function = (lp_jit_frag_func)LLVMGetPointerToGlobal(screen->engine, variant->function); #ifdef DEBUG -- cgit v1.2.3 From baddcbc5225e12052b3bc8c07a8b65243d76574d Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 29 Sep 2009 17:26:20 +0100 Subject: llvmpipe: Workaround for bug in llvm 2.5. The combination of fptosi and sitofp (necessary for trunc/floor/ceil/round implementation) somehow becomes invalid code. Skip the instruction combining pass when SSE4.1 is not available. --- src/gallium/drivers/llvmpipe/lp_jit.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c index 5d2cf01e5bc..1126bf90b96 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.c +++ b/src/gallium/drivers/llvmpipe/lp_jit.c @@ -150,6 +150,12 @@ lp_jit_screen_init(struct llvmpipe_screen *screen) util_cpu_detect(); +#if 0 + /* For simulating less capable machines */ + util_cpu_caps.has_sse3 = 0; + util_cpu_caps.has_sse4_1 = 0; +#endif + #ifdef LLVM_NATIVE_ARCH LLVMLinkInJIT(); LLVMInitializeNativeTarget(); @@ -171,8 +177,15 @@ lp_jit_screen_init(struct llvmpipe_screen *screen) LLVMAddTargetData(screen->target, screen->pass); /* These are the passes currently listed in llvm-c/Transforms/Scalar.h, * but there are more on SVN. */ + /* TODO: Add more passes */ LLVMAddConstantPropagationPass(screen->pass); - LLVMAddInstructionCombiningPass(screen->pass); + if(util_cpu_caps.has_sse4_1) { + /* FIXME: There is a bug in this pass, whereby the combination of fptosi + * and sitofp (necessary for trunc/floor/ceil/round implementation) + * somehow becomes invalid code. + */ + LLVMAddInstructionCombiningPass(screen->pass); + } LLVMAddPromoteMemoryToRegisterPass(screen->pass); LLVMAddGVNPass(screen->pass); LLVMAddCFGSimplificationPass(screen->pass); -- cgit v1.2.3 From 4456006ba626890172289111403e469f49106e18 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 Oct 2009 14:34:23 +0100 Subject: gallium: remove depth.occlusion_count flag This was redundant as drivers can just keep track of whether they are inside a begin/end query pair. We want to add more query types later and also support nested queries, none of which map well onto a flag like this. No driver appeared to be using the flag. --- src/gallium/drivers/llvmpipe/lp_bld_depth.c | 3 --- src/gallium/drivers/llvmpipe/lp_state_fs.c | 1 - src/gallium/drivers/softpipe/sp_video_context.c | 1 - src/gallium/include/pipe/p_state.h | 1 - src/gallium/state_trackers/g3dvl/vl_context.c | 1 - src/mesa/state_tracker/st_atom_depth.c | 4 ---- 6 files changed, 11 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.c b/src/gallium/drivers/llvmpipe/lp_bld_depth.c index 21c665c4d4c..98ec1cb1b9d 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_depth.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_depth.c @@ -210,7 +210,4 @@ lp_build_depth_test(LLVMBuilderRef builder, dst = lp_build_select(&bld, z_bitmask, src, dst); LLVMBuildStore(builder, dst, dst_ptr); } - - /* FIXME */ - assert(!state->occlusion_count); } diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index d5ce6993c5d..b00be0cc32a 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -401,7 +401,6 @@ generate_fragment(struct llvmpipe_context *lp, if(key->depth.enabled) { debug_printf("depth.func = %s\n", debug_dump_func(key->depth.func, TRUE)); debug_printf("depth.writemask = %u\n", key->depth.writemask); - debug_printf("depth.occlusion_count = %u\n", key->depth.occlusion_count); } if(key->alpha.enabled) { debug_printf("alpha.func = %s\n", debug_dump_func(key->alpha.func, TRUE)); diff --git a/src/gallium/drivers/softpipe/sp_video_context.c b/src/gallium/drivers/softpipe/sp_video_context.c index ccb29726b6a..7e9136d8e09 100644 --- a/src/gallium/drivers/softpipe/sp_video_context.c +++ b/src/gallium/drivers/softpipe/sp_video_context.c @@ -167,7 +167,6 @@ init_pipe_state(struct sp_mpeg12_context *ctx) dsa.depth.enabled = 0; dsa.depth.writemask = 0; dsa.depth.func = PIPE_FUNC_ALWAYS; - dsa.depth.occlusion_count = 0; for (i = 0; i < 2; ++i) { dsa.stencil[i].enabled = 0; dsa.stencil[i].func = PIPE_FUNC_ALWAYS; diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index b59d6b7ae32..287b424e4ac 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -197,7 +197,6 @@ struct pipe_depth_state unsigned enabled:1; /**< depth test enabled? */ unsigned writemask:1; /**< allow depth buffer writes? */ unsigned func:3; /**< depth test func (PIPE_FUNC_x) */ - unsigned occlusion_count:1; /**< do occlusion counting? */ }; diff --git a/src/gallium/state_trackers/g3dvl/vl_context.c b/src/gallium/state_trackers/g3dvl/vl_context.c index 5cfd233c4c1..cfbf618d742 100644 --- a/src/gallium/state_trackers/g3dvl/vl_context.c +++ b/src/gallium/state_trackers/g3dvl/vl_context.c @@ -69,7 +69,6 @@ static int vlInitCommon(struct vlContext *context) dsa.depth.enabled = 0; dsa.depth.writemask = 0; dsa.depth.func = PIPE_FUNC_ALWAYS; - dsa.depth.occlusion_count = 0; for (i = 0; i < 2; ++i) { dsa.stencil[i].enabled = 0; diff --git a/src/mesa/state_tracker/st_atom_depth.c b/src/mesa/state_tracker/st_atom_depth.c index 0aa128f9479..88b80a07fc9 100644 --- a/src/mesa/state_tracker/st_atom_depth.c +++ b/src/mesa/state_tracker/st_atom_depth.c @@ -104,10 +104,6 @@ update_depth_stencil_alpha(struct st_context *st) dsa->depth.func = st_compare_func_to_pipe(ctx->Depth.Func); } - if (ctx->Query.CurrentOcclusionObject && - ctx->Query.CurrentOcclusionObject->Active) - dsa->depth.occlusion_count = 1; - if (ctx->Stencil.Enabled && ctx->DrawBuffer->Visual.stencilBits > 0) { dsa->stencil[0].enabled = 1; dsa->stencil[0].func = st_compare_func_to_pipe(ctx->Stencil.Function[0]); -- cgit v1.2.3 From 0b466c8705c9000c347760b5daafdf31c291736d Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Wed, 30 Sep 2009 10:14:38 -0700 Subject: util: Enable sockets on BSD I think this should be safe for all of the BSDs. Signed-off-by: Robert Noland Signed-off-by: Brian Paul --- src/gallium/auxiliary/util/u_network.c | 6 +++--- src/gallium/auxiliary/util/u_network.h | 2 +- src/gallium/drivers/trace/tr_rbug.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/auxiliary/util/u_network.c b/src/gallium/auxiliary/util/u_network.c index bc4b7584067..6269c72e121 100644 --- a/src/gallium/auxiliary/util/u_network.c +++ b/src/gallium/auxiliary/util/u_network.c @@ -6,7 +6,7 @@ #if defined(PIPE_SUBSYSTEM_WINDOWS_USER) # include # include -#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) +#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_BSD) # include # include # include @@ -54,7 +54,7 @@ u_socket_close(int s) if (s < 0) return; -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_BSD) shutdown(s, SHUT_RDWR); close(s); #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) @@ -169,7 +169,7 @@ u_socket_listen_on_port(uint16_t portnum) void u_socket_block(int s, boolean block) { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_BSD) int old = fcntl(s, F_GETFL, 0); if (old == -1) return; diff --git a/src/gallium/auxiliary/util/u_network.h b/src/gallium/auxiliary/util/u_network.h index 8c778f492ca..0aa898b9676 100644 --- a/src/gallium/auxiliary/util/u_network.h +++ b/src/gallium/auxiliary/util/u_network.h @@ -6,7 +6,7 @@ #if defined(PIPE_SUBSYSTEM_WINDOWS_USER) # define PIPE_HAVE_SOCKETS -#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) +#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_BSD) # define PIPE_HAVE_SOCKETS #endif diff --git a/src/gallium/drivers/trace/tr_rbug.c b/src/gallium/drivers/trace/tr_rbug.c index e85ac15edca..81e0a6f3b00 100644 --- a/src/gallium/drivers/trace/tr_rbug.c +++ b/src/gallium/drivers/trace/tr_rbug.c @@ -44,7 +44,7 @@ #if defined(PIPE_SUBSYSTEM_WINDOWS_USER) # define sleep Sleep -#elif defined(PIPE_OS_LINUX) +#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) void usleep(int); # define sleep usleep #else -- cgit v1.2.3 From e00da1476fcdf8e5877fc1e62118080f5c4193f0 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Thu, 1 Oct 2009 21:53:17 -0400 Subject: g3dvl: Color space conv interface & vl impl. Interface is pipe_video_context::set_csc_matrix(). vl_csc.h defines some helpers to generate CSC matrices based on one of the color standard and a user defined ProcAmp (brightness, contrast, saturation, hue). --- src/gallium/auxiliary/vl/Makefile | 1 + src/gallium/auxiliary/vl/SConscript | 1 + src/gallium/auxiliary/vl/vl_compositor.c | 139 ++++-------------- src/gallium/auxiliary/vl/vl_compositor.h | 2 + src/gallium/auxiliary/vl/vl_csc.c | 179 ++++++++++++++++++++++++ src/gallium/auxiliary/vl/vl_csc.h | 26 ++++ src/gallium/drivers/softpipe/sp_video_context.c | 10 ++ src/gallium/include/pipe/p_video_context.h | 4 +- 8 files changed, 249 insertions(+), 113 deletions(-) create mode 100644 src/gallium/auxiliary/vl/vl_csc.c create mode 100644 src/gallium/auxiliary/vl/vl_csc.h (limited to 'src/gallium/drivers') diff --git a/src/gallium/auxiliary/vl/Makefile b/src/gallium/auxiliary/vl/Makefile index 71bfb937ad7..4314c1e8d69 100644 --- a/src/gallium/auxiliary/vl/Makefile +++ b/src/gallium/auxiliary/vl/Makefile @@ -7,6 +7,7 @@ C_SOURCES = \ vl_bitstream_parser.c \ vl_mpeg12_mc_renderer.c \ vl_compositor.c \ + vl_csc.c \ vl_shader_build.c include ../../Makefile.template diff --git a/src/gallium/auxiliary/vl/SConscript b/src/gallium/auxiliary/vl/SConscript index eb50940c359..aed69f5efed 100644 --- a/src/gallium/auxiliary/vl/SConscript +++ b/src/gallium/auxiliary/vl/SConscript @@ -6,6 +6,7 @@ vl = env.ConvenienceLibrary( 'vl_bitstream_parser.c', 'vl_mpeg12_mc_renderer.c', 'vl_compositor.c', + 'vl_csc.c', 'vl_shader_build.c', ]) diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c index 6431da66110..5d3458afd27 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.c +++ b/src/gallium/auxiliary/vl/vl_compositor.c @@ -5,6 +5,7 @@ #include #include #include +#include "vl_csc.h" #include "vl_shader_build.h" struct vertex2f @@ -27,7 +28,6 @@ struct vertex_shader_consts struct fragment_shader_consts { - struct vertex4f bias; float matrix[16]; }; @@ -49,94 +49,6 @@ static const struct vertex2f surface_verts[4] = */ static const struct vertex2f *surface_texcoords = surface_verts; -/* - * Identity color conversion constants, for debugging - */ -static const struct fragment_shader_consts identity = -{ - { - 0.0f, 0.0f, 0.0f, 0.0f - }, - { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - } -}; - -/* - * Converts ITU-R BT.601 YCbCr pixels to RGB pixels where: - * Y is in [16,235], Cb and Cr are in [16,240] - * R, G, and B are in [16,235] - */ -static const struct fragment_shader_consts bt_601 = -{ - { - 0.0f, 0.501960784f, 0.501960784f, 0.0f - }, - { - 1.0f, 0.0f, 1.371f, 0.0f, - 1.0f, -0.336f, -0.698f, 0.0f, - 1.0f, 1.732f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - } -}; - -/* - * Converts ITU-R BT.601 YCbCr pixels to RGB pixels where: - * Y is in [16,235], Cb and Cr are in [16,240] - * R, G, and B are in [0,255] - */ -static const struct fragment_shader_consts bt_601_full = -{ - { - 0.062745098f, 0.501960784f, 0.501960784f, 0.0f - }, - { - 1.164f, 0.0f, 1.596f, 0.0f, - 1.164f, -0.391f, -0.813f, 0.0f, - 1.164f, 2.018f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - } -}; - -/* - * Converts ITU-R BT.709 YCbCr pixels to RGB pixels where: - * Y is in [16,235], Cb and Cr are in [16,240] - * R, G, and B are in [16,235] - */ -static const struct fragment_shader_consts bt_709 = -{ - { - 0.0f, 0.501960784f, 0.501960784f, 0.0f - }, - { - 1.0f, 0.0f, 1.540f, 0.0f, - 1.0f, -0.183f, -0.459f, 0.0f, - 1.0f, 1.816f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - } -}; - -/* - * Converts ITU-R BT.709 YCbCr pixels to RGB pixels where: - * Y is in [16,235], Cb and Cr are in [16,240] - * R, G, and B are in [0,255] - */ -const struct fragment_shader_consts bt_709_full = -{ - { - 0.062745098f, 0.501960784f, 0.501960784f, 0.0f - }, - { - 1.164f, 0.0f, 1.793f, 0.0f, - 1.164f, -0.213f, -0.534f, 0.0f, - 1.164f, 2.115f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - } -}; - static void create_vert_shader(struct vl_compositor *c) { @@ -245,10 +157,9 @@ create_frag_shader(struct vl_compositor *c) ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); /* - * decl c0 ; Bias vector for CSC - * decl c1-c4 ; CSC matrix c1-c4 + * decl c0-c3 ; CSC matrix c0-c3 */ - decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 4); + decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 3); ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti); /* decl o0 ; Fragment color */ @@ -267,17 +178,14 @@ create_frag_shader(struct vl_compositor *c) inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, 0); ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* sub t0, t0, c0 ; Subtract bias vector from pixel */ - inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0); - ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); - /* - * dp4 o0.x, t0, c1 ; Multiply pixel by the color conversion matrix - * dp4 o0.y, t0, c2 - * dp4 o0.z, t0, c3 + * dp4 o0.x, t0, c0 ; Multiply pixel by the color conversion matrix + * dp4 o0.y, t0, c1 + * dp4 o0.z, t0, c2 + * dp4 o0.w, t0, c3 */ - for (i = 0; i < 3; ++i) { - inst = vl_inst3(TGSI_OPCODE_DP4, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i + 1); + for (i = 0; i < 4; ++i) { + inst = vl_inst3(TGSI_OPCODE_DP4, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i); inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i; ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti); } @@ -352,6 +260,8 @@ static void cleanup_shaders(struct vl_compositor *c) static bool init_buffers(struct vl_compositor *c) { + struct fragment_shader_consts fsc; + assert(c); /* @@ -438,18 +348,9 @@ init_buffers(struct vl_compositor *c) sizeof(struct fragment_shader_consts) ); - /* - * TODO: Refactor this into a seperate function, - * allow changing the CSC matrix at runtime to switch between regular & full versions - */ - memcpy - ( - pipe_buffer_map(c->pipe->screen, c->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE), - &bt_601_full, - sizeof(struct fragment_shader_consts) - ); + vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_IDENTITY, NULL, true, fsc.matrix); - pipe_buffer_unmap(c->pipe->screen, c->fs_const_buf.buffer); + vl_compositor_set_csc_matrix(c, fsc.matrix); return true; } @@ -588,3 +489,17 @@ void vl_compositor_render(struct vl_compositor *compositor, pipe_surface_reference(&compositor->fb_state.cbufs[0], NULL); } + +void vl_compositor_set_csc_matrix(struct vl_compositor *compositor, const float *mat) +{ + assert(compositor); + + memcpy + ( + pipe_buffer_map(compositor->pipe->screen, compositor->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + mat, + sizeof(struct fragment_shader_consts) + ); + + pipe_buffer_unmap(compositor->pipe->screen, compositor->fs_const_buf.buffer); +} diff --git a/src/gallium/auxiliary/vl/vl_compositor.h b/src/gallium/auxiliary/vl/vl_compositor.h index 19ad66d9c61..975ea00bde0 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.h +++ b/src/gallium/auxiliary/vl/vl_compositor.h @@ -44,4 +44,6 @@ void vl_compositor_render(struct vl_compositor *compositor, struct pipe_video_rect *layer_dst_areas,*/ struct pipe_fence_handle **fence); +void vl_compositor_set_csc_matrix(struct vl_compositor *compositor, const float *mat); + #endif /* vl_compositor_h */ diff --git a/src/gallium/auxiliary/vl/vl_csc.c b/src/gallium/auxiliary/vl/vl_csc.c new file mode 100644 index 00000000000..828cebe4ed4 --- /dev/null +++ b/src/gallium/auxiliary/vl/vl_csc.c @@ -0,0 +1,179 @@ +#include "vl_csc.h" +#include +#include + +/* + * Color space conversion formulas + * + * To convert YCbCr to RGB, + * vec4 ycbcr, rgb + * mat44 csc + * rgb = csc * ycbcr + * + * To calculate the color space conversion matrix csc with ProcAmp adjustments, + * mat44 csc, cstd, procamp, bias + * csc = cstd * (procamp * bias) + * + * Where cstd is a matrix corresponding to one of the color standards (BT.601, BT.709, etc) + * adjusted for the kind of YCbCr -> RGB mapping wanted (1:1, full), + * bias is a matrix corresponding to the kind of YCbCr -> RGB mapping wanted (1:1, full) + * + * To calculate procamp, + * mat44 procamp, hue, saturation, brightness, contrast + * procamp = brightness * (saturation * (contrast * hue)) + * Alternatively, + * procamp = saturation * (brightness * (contrast * hue)) + * + * contrast + * [ c, 0, 0, 0] + * [ 0, c, 0, 0] + * [ 0, 0, c, 0] + * [ 0, 0, 0, 1] + * + * brightness + * [ 1, 0, 0, b] + * [ 0, 1, 0, 0] + * [ 0, 0, 1, 0] + * [ 0, 0, 0, 1] + * + * saturation + * [ 1, 0, 0, 0] + * [ 0, s, 0, 0] + * [ 0, 0, s, 0] + * [ 0, 0, 0, 1] + * + * hue + * [ 1, 0, 0, 0] + * [ 0, cos(h), sin(h), 0] + * [ 0, -sin(h), cos(h), 0] + * [ 0, 0, 0, 1] + * + * procamp + * [ c, 0, 0, b] + * [ 0, c*s*cos(h), c*s*sin(h), 0] + * [ 0, -c*s*sin(h), c*s*cos(h), 0] + * [ 0, 0, 0, 1] + * + * bias + * [ 1, 0, 0, ybias] + * [ 0, 1, 0, cbbias] + * [ 0, 0, 1, crbias] + * [ 0, 0, 0, 1] + * + * csc + * [ c*cstd[ 0], c*cstd[ 1]*s*cos(h) - c*cstd[ 2]*s*sin(h), c*cstd[ 2]*s*cos(h) + c*cstd[ 1]*s*sin(h), cstd[ 3] + cstd[ 0]*(b + c*ybias) + cstd[ 1]*(c*cbbias*s*cos(h) + c*crbias*s*sin(h)) + cstd[ 2]*(c*crbias*s*cos(h) - c*cbbias*s*sin(h))] + * [ c*cstd[ 4], c*cstd[ 5]*s*cos(h) - c*cstd[ 6]*s*sin(h), c*cstd[ 6]*s*cos(h) + c*cstd[ 5]*s*sin(h), cstd[ 7] + cstd[ 4]*(b + c*ybias) + cstd[ 5]*(c*cbbias*s*cos(h) + c*crbias*s*sin(h)) + cstd[ 6]*(c*crbias*s*cos(h) - c*cbbias*s*sin(h))] + * [ c*cstd[ 8], c*cstd[ 9]*s*cos(h) - c*cstd[10]*s*sin(h), c*cstd[10]*s*cos(h) + c*cstd[ 9]*s*sin(h), cstd[11] + cstd[ 8]*(b + c*ybias) + cstd[ 9]*(c*cbbias*s*cos(h) + c*crbias*s*sin(h)) + cstd[10]*(c*crbias*s*cos(h) - c*cbbias*s*sin(h))] + * [ c*cstd[12], c*cstd[13]*s*cos(h) - c*cstd[14]*s*sin(h), c*cstd[14]*s*cos(h) + c*cstd[13]*s*sin(h), cstd[15] + cstd[12]*(b + c*ybias) + cstd[13]*(c*cbbias*s*cos(h) + c*crbias*s*sin(h)) + cstd[14]*(c*crbias*s*cos(h) - c*cbbias*s*sin(h))] + */ + +/* + * Converts ITU-R BT.601 YCbCr pixels to RGB pixels where: + * Y is in [16,235], Cb and Cr are in [16,240] + * R, G, and B are in [16,235] + */ +static const float bt_601[16] = +{ + 1.0f, 0.0f, 1.371f, 0.0f, + 1.0f, -0.336f, -0.698f, 0.0f, + 1.0f, 1.732f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f +}; + +/* + * Converts ITU-R BT.601 YCbCr pixels to RGB pixels where: + * Y is in [16,235], Cb and Cr are in [16,240] + * R, G, and B are in [0,255] + */ +static const float bt_601_full[16] = +{ + 1.164f, 0.0f, 1.596f, 0.0f, + 1.164f, -0.391f, -0.813f, 0.0f, + 1.164f, 2.018f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f +}; + +/* + * Converts ITU-R BT.709 YCbCr pixels to RGB pixels where: + * Y is in [16,235], Cb and Cr are in [16,240] + * R, G, and B are in [16,235] + */ +static const float bt_709[16] = +{ + 1.0f, 0.0f, 1.540f, 0.0f, + 1.0f, -0.183f, -0.459f, 0.0f, + 1.0f, 1.816f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f +}; + +/* + * Converts ITU-R BT.709 YCbCr pixels to RGB pixels where: + * Y is in [16,235], Cb and Cr are in [16,240] + * R, G, and B are in [0,255] + */ +static const float bt_709_full[16] = +{ + 1.164f, 0.0f, 1.793f, 0.0f, + 1.164f, -0.213f, -0.534f, 0.0f, + 1.164f, 2.115f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f +}; + +static const float identity[16] = +{ + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f +}; + +void vl_csc_get_matrix(enum VL_CSC_COLOR_STANDARD cs, + struct vl_procamp *procamp, + bool full_range, + float *matrix) +{ + float ybias = full_range ? -16.0f/255.0f : 0.0f; + float cbbias = -128.0f/255.0f; + float crbias = -128.0f/255.0f; + float c = procamp ? procamp->contrast : 1.0f; + float s = procamp ? procamp->saturation : 1.0f; + float b = procamp ? procamp->brightness : 0.0f; + float h = procamp ? procamp->hue : 0.0f; + const float *cstd; + + assert(matrix); + + switch (cs) { + case VL_CSC_COLOR_STANDARD_BT_601: + cstd = full_range ? &bt_601_full[0] : &bt_601[0]; + break; + case VL_CSC_COLOR_STANDARD_BT_709: + cstd = full_range ? &bt_709_full[0] : &bt_709[0]; + break; + case VL_CSC_COLOR_STANDARD_IDENTITY: + default: + assert(cs == VL_CSC_COLOR_STANDARD_IDENTITY); + memcpy(matrix, &identity[0], sizeof(float) * 16); + return; + } + + matrix[ 0] = c*cstd[ 0]; + matrix[ 1] = c*cstd[ 1]*s*cosf(h) - c*cstd[ 2]*s*sinf(h); + matrix[ 2] = c*cstd[ 2]*s*cosf(h) + c*cstd[ 1]*s*sinf(h); + matrix[ 3] = cstd[ 3] + cstd[ 0]*(b + c*ybias) + cstd[ 1]*(c*cbbias*s*cosf(h) + c*crbias*s*sinf(h)) + cstd[ 2]*(c*crbias*s*cosf(h) - c*cbbias*s*sinf(h)); + + matrix[ 4] = c*cstd[ 4]; + matrix[ 5] = c*cstd[ 5]*s*cosf(h) - c*cstd[ 6]*s*sinf(h); + matrix[ 6] = c*cstd[ 6]*s*cosf(h) + c*cstd[ 5]*s*sinf(h); + matrix[ 7] = cstd[ 7] + cstd[ 4]*(b + c*ybias) + cstd[ 5]*(c*cbbias*s*cosf(h) + c*crbias*s*sinf(h)) + cstd[ 6]*(c*crbias*s*cosf(h) - c*cbbias*s*sinf(h)); + + matrix[ 8] = c*cstd[ 8]; + matrix[ 9] = c*cstd[ 9]*s*cosf(h) - c*cstd[10]*s*sinf(h); + matrix[10] = c*cstd[10]*s*cosf(h) + c*cstd[ 9]*s*sinf(h); + matrix[11] = cstd[11] + cstd[ 8]*(b + c*ybias) + cstd[ 9]*(c*cbbias*s*cosf(h) + c*crbias*s*sinf(h)) + cstd[10]*(c*crbias*s*cosf(h) - c*cbbias*s*sinf(h)); + + matrix[12] = c*cstd[12]; + matrix[13] = c*cstd[13]*s*cos(h) - c*cstd[14]*s*sin(h); + matrix[14] = c*cstd[14]*s*cos(h) + c*cstd[13]*s*sin(h); + matrix[15] = cstd[15] + cstd[12]*(b + c*ybias) + cstd[13]*(c*cbbias*s*cos(h) + c*crbias*s*sin(h)) + cstd[14]*(c*crbias*s*cos(h) - c*cbbias*s*sin(h)); +} diff --git a/src/gallium/auxiliary/vl/vl_csc.h b/src/gallium/auxiliary/vl/vl_csc.h new file mode 100644 index 00000000000..c3b87d279cf --- /dev/null +++ b/src/gallium/auxiliary/vl/vl_csc.h @@ -0,0 +1,26 @@ +#ifndef vl_csc_h +#define vl_csc_h + +#include + +struct vl_procamp +{ + float brightness; + float contrast; + float saturation; + float hue; +}; + +enum VL_CSC_COLOR_STANDARD +{ + VL_CSC_COLOR_STANDARD_IDENTITY, + VL_CSC_COLOR_STANDARD_BT_601, + VL_CSC_COLOR_STANDARD_BT_709 +}; + +void vl_csc_get_matrix(enum VL_CSC_COLOR_STANDARD cs, + struct vl_procamp *procamp, + bool full_range, + float *matrix); + +#endif /* vl_csc_h */ diff --git a/src/gallium/drivers/softpipe/sp_video_context.c b/src/gallium/drivers/softpipe/sp_video_context.c index 7e9136d8e09..00b4b7d5606 100644 --- a/src/gallium/drivers/softpipe/sp_video_context.c +++ b/src/gallium/drivers/softpipe/sp_video_context.c @@ -109,6 +109,15 @@ sp_mpeg12_set_decode_target(struct pipe_video_context *vpipe, pipe_video_surface_reference(&ctx->decode_target, dt); } +static void sp_mpeg12_set_csc_matrix(struct pipe_video_context *vpipe, const float *mat) +{ + struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; + + assert(vpipe); + + vl_compositor_set_csc_matrix(&ctx->compositor, mat); +} + static bool init_pipe_state(struct sp_mpeg12_context *ctx) { @@ -211,6 +220,7 @@ sp_mpeg12_create(struct pipe_screen *screen, enum pipe_video_profile profile, ctx->base.clear_surface = sp_mpeg12_clear_surface; ctx->base.render_picture = sp_mpeg12_render_picture; ctx->base.set_decode_target = sp_mpeg12_set_decode_target; + ctx->base.set_csc_matrix = sp_mpeg12_set_csc_matrix; ctx->pipe = softpipe_create(screen); if (!ctx->pipe) { diff --git a/src/gallium/include/pipe/p_video_context.h b/src/gallium/include/pipe/p_video_context.h index 937705ac505..4d125fa4d59 100644 --- a/src/gallium/include/pipe/p_video_context.h +++ b/src/gallium/include/pipe/p_video_context.h @@ -80,7 +80,9 @@ struct pipe_video_context void (*set_decode_target)(struct pipe_video_context *vpipe, struct pipe_video_surface *dt); - /* TODO: Interface for CSC matrix, scaling modes, post-processing, etc. */ + void (*set_csc_matrix)(struct pipe_video_context *vpipe, const float *mat); + + /* TODO: Interface for scaling modes, post-processing, etc. */ /*@}*/ }; -- cgit v1.2.3 From fcb595c04f9ee275eae49b7bb7c61246671f5ce2 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Thu, 1 Oct 2009 22:16:10 -0400 Subject: g3dvl: Copyright blocks. --- src/gallium/auxiliary/vl/vl_bitstream_parser.c | 27 ++++++++++++++++++++++ src/gallium/auxiliary/vl/vl_bitstream_parser.h | 27 ++++++++++++++++++++++ src/gallium/auxiliary/vl/vl_compositor.c | 27 ++++++++++++++++++++++ src/gallium/auxiliary/vl/vl_compositor.h | 27 ++++++++++++++++++++++ src/gallium/auxiliary/vl/vl_csc.c | 27 ++++++++++++++++++++++ src/gallium/auxiliary/vl/vl_csc.h | 27 ++++++++++++++++++++++ src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c | 27 ++++++++++++++++++++++ src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h | 27 ++++++++++++++++++++++ src/gallium/auxiliary/vl/vl_shader_build.c | 27 ++++++++++++++++++++++ src/gallium/auxiliary/vl/vl_shader_build.h | 27 ++++++++++++++++++++++ src/gallium/drivers/softpipe/sp_video_context.c | 27 ++++++++++++++++++++++ src/gallium/drivers/softpipe/sp_video_context.h | 27 ++++++++++++++++++++++ src/gallium/include/pipe/p_video_context.h | 27 ++++++++++++++++++++++ src/gallium/include/pipe/p_video_state.h | 27 ++++++++++++++++++++++ src/gallium/state_trackers/xorg/xvmc/attributes.c | 27 ++++++++++++++++++++++ src/gallium/state_trackers/xorg/xvmc/block.c | 27 ++++++++++++++++++++++ src/gallium/state_trackers/xorg/xvmc/context.c | 27 ++++++++++++++++++++++ src/gallium/state_trackers/xorg/xvmc/subpicture.c | 27 ++++++++++++++++++++++ src/gallium/state_trackers/xorg/xvmc/surface.c | 27 ++++++++++++++++++++++ .../state_trackers/xorg/xvmc/tests/test_blocks.c | 27 ++++++++++++++++++++++ .../state_trackers/xorg/xvmc/tests/test_context.c | 27 ++++++++++++++++++++++ .../xorg/xvmc/tests/test_rendering.c | 27 ++++++++++++++++++++++ .../state_trackers/xorg/xvmc/tests/test_surface.c | 27 ++++++++++++++++++++++ .../state_trackers/xorg/xvmc/tests/testlib.c | 27 ++++++++++++++++++++++ .../state_trackers/xorg/xvmc/tests/testlib.h | 27 ++++++++++++++++++++++ .../state_trackers/xorg/xvmc/tests/xvmc_bench.c | 27 ++++++++++++++++++++++ .../state_trackers/xorg/xvmc/xvmc_private.h | 27 ++++++++++++++++++++++ src/gallium/winsys/g3dvl/vl_winsys.h | 27 ++++++++++++++++++++++ src/gallium/winsys/g3dvl/xlib/xsp_winsys.c | 27 ++++++++++++++++++++++ 29 files changed, 783 insertions(+) (limited to 'src/gallium/drivers') diff --git a/src/gallium/auxiliary/vl/vl_bitstream_parser.c b/src/gallium/auxiliary/vl/vl_bitstream_parser.c index 45826bad45a..3193ea5f41c 100644 --- a/src/gallium/auxiliary/vl/vl_bitstream_parser.c +++ b/src/gallium/auxiliary/vl/vl_bitstream_parser.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #include "vl_bitstream_parser.h" #include #include diff --git a/src/gallium/auxiliary/vl/vl_bitstream_parser.h b/src/gallium/auxiliary/vl/vl_bitstream_parser.h index 91ebaab45b9..30ec743fa75 100644 --- a/src/gallium/auxiliary/vl/vl_bitstream_parser.h +++ b/src/gallium/auxiliary/vl/vl_bitstream_parser.h @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #ifndef vl_bitstream_parser_h #define vl_bitstream_parser_h diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c index 5d3458afd27..b36dbeb2088 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.c +++ b/src/gallium/auxiliary/vl/vl_compositor.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #include "vl_compositor.h" #include #include diff --git a/src/gallium/auxiliary/vl/vl_compositor.h b/src/gallium/auxiliary/vl/vl_compositor.h index 975ea00bde0..17e2afd3539 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.h +++ b/src/gallium/auxiliary/vl/vl_compositor.h @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #ifndef vl_compositor_h #define vl_compositor_h diff --git a/src/gallium/auxiliary/vl/vl_csc.c b/src/gallium/auxiliary/vl/vl_csc.c index 828cebe4ed4..5ecc43a5fa3 100644 --- a/src/gallium/auxiliary/vl/vl_csc.c +++ b/src/gallium/auxiliary/vl/vl_csc.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #include "vl_csc.h" #include #include diff --git a/src/gallium/auxiliary/vl/vl_csc.h b/src/gallium/auxiliary/vl/vl_csc.h index c3b87d279cf..722ca35f339 100644 --- a/src/gallium/auxiliary/vl/vl_csc.h +++ b/src/gallium/auxiliary/vl/vl_csc.h @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #ifndef vl_csc_h #define vl_csc_h diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c index 9b69f2956c1..6b3614821cc 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c +++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #include "vl_mpeg12_mc_renderer.h" #include #include diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h index 0c2f6796646..5d2c1273ee3 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h +++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #ifndef vl_mpeg12_mc_renderer_h #define vl_mpeg12_mc_renderer_h diff --git a/src/gallium/auxiliary/vl/vl_shader_build.c b/src/gallium/auxiliary/vl/vl_shader_build.c index 9ad1e052c6c..faa20a903cd 100644 --- a/src/gallium/auxiliary/vl/vl_shader_build.c +++ b/src/gallium/auxiliary/vl/vl_shader_build.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #include "vl_shader_build.h" #include #include diff --git a/src/gallium/auxiliary/vl/vl_shader_build.h b/src/gallium/auxiliary/vl/vl_shader_build.h index c6c60b55526..5da71f8e136 100644 --- a/src/gallium/auxiliary/vl/vl_shader_build.h +++ b/src/gallium/auxiliary/vl/vl_shader_build.h @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #ifndef vl_shader_build_h #define vl_shader_build_h diff --git a/src/gallium/drivers/softpipe/sp_video_context.c b/src/gallium/drivers/softpipe/sp_video_context.c index 00b4b7d5606..cae2d3efc58 100644 --- a/src/gallium/drivers/softpipe/sp_video_context.c +++ b/src/gallium/drivers/softpipe/sp_video_context.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #include "sp_video_context.h" #include #include diff --git a/src/gallium/drivers/softpipe/sp_video_context.h b/src/gallium/drivers/softpipe/sp_video_context.h index 2c7691c7cb9..ccbd1ffe4c8 100644 --- a/src/gallium/drivers/softpipe/sp_video_context.h +++ b/src/gallium/drivers/softpipe/sp_video_context.h @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #ifndef SP_VIDEO_CONTEXT_H #define SP_VIDEO_CONTEXT_H diff --git a/src/gallium/include/pipe/p_video_context.h b/src/gallium/include/pipe/p_video_context.h index 4d125fa4d59..6ae31418fa8 100644 --- a/src/gallium/include/pipe/p_video_context.h +++ b/src/gallium/include/pipe/p_video_context.h @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #ifndef PIPE_VIDEO_CONTEXT_H #define PIPE_VIDEO_CONTEXT_H diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index 2a7422bf04c..4da26d608cf 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #ifndef PIPE_VIDEO_STATE_H #define PIPE_VIDEO_STATE_H diff --git a/src/gallium/state_trackers/xorg/xvmc/attributes.c b/src/gallium/state_trackers/xorg/xvmc/attributes.c index 638da0b5775..79a67838e6e 100644 --- a/src/gallium/state_trackers/xorg/xvmc/attributes.c +++ b/src/gallium/state_trackers/xorg/xvmc/attributes.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #include #include #include diff --git a/src/gallium/state_trackers/xorg/xvmc/block.c b/src/gallium/state_trackers/xorg/xvmc/block.c index 78fddfb79e0..5102375fcf8 100644 --- a/src/gallium/state_trackers/xorg/xvmc/block.c +++ b/src/gallium/state_trackers/xorg/xvmc/block.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #include #include #include diff --git a/src/gallium/state_trackers/xorg/xvmc/context.c b/src/gallium/state_trackers/xorg/xvmc/context.c index a002a7c8443..942692d1bb9 100644 --- a/src/gallium/state_trackers/xorg/xvmc/context.c +++ b/src/gallium/state_trackers/xorg/xvmc/context.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #include #include #include diff --git a/src/gallium/state_trackers/xorg/xvmc/subpicture.c b/src/gallium/state_trackers/xorg/xvmc/subpicture.c index 78ba618f5ab..69898d5fcd3 100644 --- a/src/gallium/state_trackers/xorg/xvmc/subpicture.c +++ b/src/gallium/state_trackers/xorg/xvmc/subpicture.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #include #include #include diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c index 6b7dbf11dcf..bf9038f356e 100644 --- a/src/gallium/state_trackers/xorg/xvmc/surface.c +++ b/src/gallium/state_trackers/xorg/xvmc/surface.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #include #include #include diff --git a/src/gallium/state_trackers/xorg/xvmc/tests/test_blocks.c b/src/gallium/state_trackers/xorg/xvmc/tests/test_blocks.c index dc80adfa652..994e3ca4d14 100644 --- a/src/gallium/state_trackers/xorg/xvmc/tests/test_blocks.c +++ b/src/gallium/state_trackers/xorg/xvmc/tests/test_blocks.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #include #include #include "testlib.h" diff --git a/src/gallium/state_trackers/xorg/xvmc/tests/test_context.c b/src/gallium/state_trackers/xorg/xvmc/tests/test_context.c index 53f7449cd0b..3da957c9330 100644 --- a/src/gallium/state_trackers/xorg/xvmc/tests/test_context.c +++ b/src/gallium/state_trackers/xorg/xvmc/tests/test_context.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #include #include #include "testlib.h" diff --git a/src/gallium/state_trackers/xorg/xvmc/tests/test_rendering.c b/src/gallium/state_trackers/xorg/xvmc/tests/test_rendering.c index 6d720dfcdca..6058783a798 100644 --- a/src/gallium/state_trackers/xorg/xvmc/tests/test_rendering.c +++ b/src/gallium/state_trackers/xorg/xvmc/tests/test_rendering.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #include #include #include diff --git a/src/gallium/state_trackers/xorg/xvmc/tests/test_surface.c b/src/gallium/state_trackers/xorg/xvmc/tests/test_surface.c index 06948201ac9..b65eb265c0a 100644 --- a/src/gallium/state_trackers/xorg/xvmc/tests/test_surface.c +++ b/src/gallium/state_trackers/xorg/xvmc/tests/test_surface.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #include #include #include "testlib.h" diff --git a/src/gallium/state_trackers/xorg/xvmc/tests/testlib.c b/src/gallium/state_trackers/xorg/xvmc/tests/testlib.c index 59a03ca813f..142c09bb590 100644 --- a/src/gallium/state_trackers/xorg/xvmc/tests/testlib.c +++ b/src/gallium/state_trackers/xorg/xvmc/tests/testlib.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #include "testlib.h" #include diff --git a/src/gallium/state_trackers/xorg/xvmc/tests/testlib.h b/src/gallium/state_trackers/xorg/xvmc/tests/testlib.h index af71ad74e17..0438e52928b 100644 --- a/src/gallium/state_trackers/xorg/xvmc/tests/testlib.h +++ b/src/gallium/state_trackers/xorg/xvmc/tests/testlib.h @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #ifndef testlib_h #define testlib_h diff --git a/src/gallium/state_trackers/xorg/xvmc/tests/xvmc_bench.c b/src/gallium/state_trackers/xorg/xvmc/tests/xvmc_bench.c index 97adcfc58a8..bf94d856234 100644 --- a/src/gallium/state_trackers/xorg/xvmc/tests/xvmc_bench.c +++ b/src/gallium/state_trackers/xorg/xvmc/tests/xvmc_bench.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #include #include #include diff --git a/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h b/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h index 1e3dd561c66..42337631ca1 100644 --- a/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h +++ b/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #ifndef xvmc_private_h #define xvmc_private_h diff --git a/src/gallium/winsys/g3dvl/vl_winsys.h b/src/gallium/winsys/g3dvl/vl_winsys.h index 4f7a2433612..22119f95595 100644 --- a/src/gallium/winsys/g3dvl/vl_winsys.h +++ b/src/gallium/winsys/g3dvl/vl_winsys.h @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #ifndef vl_winsys_h #define vl_winsys_h diff --git a/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c index 37eee79c5d3..0faad544d1e 100644 --- a/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #include #include #include -- cgit v1.2.3 From 47e41b024e325f69ed514e551a6824afa58f1db6 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Fri, 2 Oct 2009 18:13:26 +0200 Subject: gallium: Preparations for adding more PIPE_TRANSFER_* usage flags. Always test for PIPE_TRANSFER_READ/WRITE using the bit-wise and operator, and add a pipe_transfer_buffer_flags() helper for getting the buffer usage flags corresponding to them. --- src/gallium/auxiliary/util/u_tile.c | 4 ++-- src/gallium/drivers/cell/ppu/cell_texture.c | 18 ++++----------- src/gallium/drivers/i915simple/i915_texture.c | 2 +- src/gallium/drivers/llvmpipe/lp_texture.c | 14 +++--------- src/gallium/drivers/nv04/nv04_transfer.c | 26 +++++----------------- src/gallium/drivers/nv10/nv10_transfer.c | 26 +++++----------------- src/gallium/drivers/nv20/nv20_transfer.c | 26 +++++----------------- src/gallium/drivers/nv30/nv30_transfer.c | 26 +++++----------------- src/gallium/drivers/nv40/nv40_transfer.c | 26 +++++----------------- src/gallium/drivers/nv50/nv50_transfer.c | 4 ++-- src/gallium/drivers/r300/r300_screen.c | 11 ++------- src/gallium/drivers/softpipe/sp_texture.c | 15 +++---------- src/gallium/drivers/trace/tr_screen.c | 2 +- src/gallium/include/pipe/p_inlines.h | 16 +++++++++++++ .../state_trackers/python/retrace/interpreter.py | 2 +- src/gallium/state_trackers/vega/st_inlines.h | 3 +-- src/mesa/state_tracker/st_cb_accum.c | 2 +- src/mesa/state_tracker/st_texture.c | 3 +-- 18 files changed, 63 insertions(+), 163 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c index 0d6489c26e4..8a22f584bee 100644 --- a/src/gallium/auxiliary/util/u_tile.c +++ b/src/gallium/auxiliary/util/u_tile.c @@ -1452,7 +1452,7 @@ pipe_put_tile_z(struct pipe_transfer *pt, case PIPE_FORMAT_S8Z24_UNORM: { uint *pDest = (uint *) (map + y * pt->stride + x*4); - assert(pt->usage == PIPE_TRANSFER_READ_WRITE); + assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 32-bit Z to 24-bit Z, preserve stencil */ @@ -1479,7 +1479,7 @@ pipe_put_tile_z(struct pipe_transfer *pt, case PIPE_FORMAT_Z24S8_UNORM: { uint *pDest = (uint *) (map + y * pt->stride + x*4); - assert(pt->usage == PIPE_TRANSFER_READ_WRITE); + assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 32-bit Z to 24-bit Z, preserve stencil */ diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index 6a63a0e6ced..ae4c61efb3b 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -389,22 +389,14 @@ cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer) const uint texWidth = pt->width[level]; const uint texHeight = pt->height[level]; const uint stride = ct->stride[level]; - unsigned flags = 0x0; unsigned size; assert(transfer->texture); - if (transfer->usage != PIPE_TRANSFER_READ) { - flags |= PIPE_BUFFER_USAGE_CPU_WRITE; - } - - if (transfer->usage != PIPE_TRANSFER_WRITE) { - flags |= PIPE_BUFFER_USAGE_CPU_READ; - } - if (!ct->mapped) { /* map now */ - ct->mapped = pipe_buffer_map(screen, ct->buffer, flags); + ct->mapped = pipe_buffer_map(screen, ct->buffer, + pipe_transfer_buffer_flags(transfer)); } /* @@ -417,8 +409,7 @@ cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer) if (!ctrans->map) return NULL; /* out of memory */ - if (transfer->usage == PIPE_TRANSFER_READ || - transfer->usage == PIPE_TRANSFER_READ_WRITE) { + if (transfer->usage & PIPE_TRANSFER_READ) { /* need to untwiddle the texture to make a linear version */ const uint bpp = pf_get_size(ct->base.format); if (bpp == 4) { @@ -459,8 +450,7 @@ cell_transfer_unmap(struct pipe_screen *screen, PIPE_BUFFER_USAGE_CPU_READ); } - if (transfer->usage == PIPE_TRANSFER_WRITE || - transfer->usage == PIPE_TRANSFER_READ_WRITE) { + if (transfer->usage & PIPE_TRANSFER_WRITE) { /* The user wrote new texture data into the mapped buffer. * We need to convert the new linear data into the twiddled/tiled format. */ diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 15ccc1fc73b..286c9ace8e5 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -859,7 +859,7 @@ i915_transfer_map(struct pipe_screen *screen, char *map; boolean write = FALSE; - if (transfer->usage != PIPE_TRANSFER_READ) + if (transfer->usage & PIPE_TRANSFER_WRITE) write = TRUE; map = iws->buffer_map(iws, tex->buffer, write); diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 724d4378336..08f0950d475 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -353,17 +353,9 @@ llvmpipe_transfer_map( struct pipe_screen *_screen, if(lpt->dt) { struct llvmpipe_winsys *winsys = screen->winsys; - unsigned flags = 0; - if (transfer->usage != PIPE_TRANSFER_READ) { - flags |= PIPE_BUFFER_USAGE_CPU_WRITE; - } - - if (transfer->usage != PIPE_TRANSFER_WRITE) { - flags |= PIPE_BUFFER_USAGE_CPU_READ; - } - - map = winsys->displaytarget_map(winsys, lpt->dt, flags); + map = winsys->displaytarget_map(winsys, lpt->dt, + pipe_transfer_buffer_flags(transfer)); if (map == NULL) return NULL; } @@ -373,7 +365,7 @@ llvmpipe_transfer_map( struct pipe_screen *_screen, /* May want to different things here depending on read/write nature * of the map: */ - if (transfer->texture && transfer->usage != PIPE_TRANSFER_READ) + if (transfer->texture && (transfer->usage & PIPE_TRANSFER_WRITE)) { /* Do something to notify sharing contexts of a texture change. * In llvmpipe, that would mean flushing the texture cache. diff --git a/src/gallium/drivers/nv04/nv04_transfer.c b/src/gallium/drivers/nv04/nv04_transfer.c index 854b855d64a..6618660743d 100644 --- a/src/gallium/drivers/nv04/nv04_transfer.c +++ b/src/gallium/drivers/nv04/nv04_transfer.c @@ -13,22 +13,6 @@ struct nv04_transfer { bool direct; }; -static unsigned nv04_usage_tx_to_buf(unsigned tx_usage) -{ - switch (tx_usage) { - case PIPE_TRANSFER_READ: - return PIPE_BUFFER_USAGE_CPU_READ; - case PIPE_TRANSFER_WRITE: - return PIPE_BUFFER_USAGE_CPU_WRITE; - case PIPE_TRANSFER_READ_WRITE: - return PIPE_BUFFER_USAGE_CPU_READ_WRITE; - default: - assert(0); - } - - return -1; -} - static void nv04_compatible_transfer_tex(struct pipe_texture *pt, unsigned level, struct pipe_texture *template) @@ -86,7 +70,7 @@ nv04_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, tx->direct = true; tx->surface = pscreen->get_tex_surface(pscreen, pt, 0, 0, 0, - nv04_usage_tx_to_buf(usage)); + pipe_transfer_buffer_flags(&tx->base)); return &tx->base; } @@ -103,7 +87,7 @@ nv04_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, tx->surface = pscreen->get_tex_surface(pscreen, tx_tex, face, level, zslice, - nv04_usage_tx_to_buf(usage)); + pipe_transfer_buffer_flags(&tx->base)); pipe_texture_reference(&tx_tex, NULL); @@ -114,7 +98,7 @@ nv04_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, return NULL; } - if (usage != PIPE_TRANSFER_WRITE) { + if (usage & PIPE_TRANSFER_READ) { struct nv04_screen *nvscreen = nv04_screen(pscreen); struct pipe_surface *src; @@ -140,7 +124,7 @@ nv04_transfer_del(struct pipe_transfer *ptx) { struct nv04_transfer *tx = (struct nv04_transfer *)ptx; - if (!tx->direct && ptx->usage != PIPE_TRANSFER_READ) { + if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) { struct pipe_screen *pscreen = ptx->texture->screen; struct nv04_screen *nvscreen = nv04_screen(pscreen); struct pipe_surface *dst; @@ -170,7 +154,7 @@ nv04_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx) struct nv04_surface *ns = (struct nv04_surface *)tx->surface; struct nv04_miptree *mt = (struct nv04_miptree *)tx->surface->texture; void *map = pipe_buffer_map(pscreen, mt->buffer, - nv04_usage_tx_to_buf(ptx->usage)); + pipe_transfer_buffer_flags(ptx)); return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * ptx->block.size; diff --git a/src/gallium/drivers/nv10/nv10_transfer.c b/src/gallium/drivers/nv10/nv10_transfer.c index c06b8d34c72..8feb85e4bda 100644 --- a/src/gallium/drivers/nv10/nv10_transfer.c +++ b/src/gallium/drivers/nv10/nv10_transfer.c @@ -13,22 +13,6 @@ struct nv10_transfer { bool direct; }; -static unsigned nv10_usage_tx_to_buf(unsigned tx_usage) -{ - switch (tx_usage) { - case PIPE_TRANSFER_READ: - return PIPE_BUFFER_USAGE_CPU_READ; - case PIPE_TRANSFER_WRITE: - return PIPE_BUFFER_USAGE_CPU_WRITE; - case PIPE_TRANSFER_READ_WRITE: - return PIPE_BUFFER_USAGE_CPU_READ_WRITE; - default: - assert(0); - } - - return -1; -} - static void nv10_compatible_transfer_tex(struct pipe_texture *pt, unsigned level, struct pipe_texture *template) @@ -86,7 +70,7 @@ nv10_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, tx->direct = true; tx->surface = pscreen->get_tex_surface(pscreen, pt, 0, 0, 0, - nv10_usage_tx_to_buf(usage)); + pipe_transfer_buffer_flags(&tx->base)); return &tx->base; } @@ -103,7 +87,7 @@ nv10_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, tx->surface = pscreen->get_tex_surface(pscreen, tx_tex, face, level, zslice, - nv10_usage_tx_to_buf(usage)); + pipe_transfer_buffer_flags(&tx->base)); pipe_texture_reference(&tx_tex, NULL); @@ -114,7 +98,7 @@ nv10_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, return NULL; } - if (usage != PIPE_TRANSFER_WRITE) { + if (usage & PIPE_TRANSFER_READ) { struct nv10_screen *nvscreen = nv10_screen(pscreen); struct pipe_surface *src; @@ -140,7 +124,7 @@ nv10_transfer_del(struct pipe_transfer *ptx) { struct nv10_transfer *tx = (struct nv10_transfer *)ptx; - if (!tx->direct && ptx->usage != PIPE_TRANSFER_READ) { + if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) { struct pipe_screen *pscreen = ptx->texture->screen; struct nv10_screen *nvscreen = nv10_screen(pscreen); struct pipe_surface *dst; @@ -170,7 +154,7 @@ nv10_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx) struct nv04_surface *ns = (struct nv04_surface *)tx->surface; struct nv10_miptree *mt = (struct nv10_miptree *)tx->surface->texture; void *map = pipe_buffer_map(pscreen, mt->buffer, - nv10_usage_tx_to_buf(ptx->usage)); + pipe_transfer_buffer_flags(ptx)); return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * ptx->block.size; diff --git a/src/gallium/drivers/nv20/nv20_transfer.c b/src/gallium/drivers/nv20/nv20_transfer.c index 5018995596c..81b4f1a9177 100644 --- a/src/gallium/drivers/nv20/nv20_transfer.c +++ b/src/gallium/drivers/nv20/nv20_transfer.c @@ -13,22 +13,6 @@ struct nv20_transfer { bool direct; }; -static unsigned nv20_usage_tx_to_buf(unsigned tx_usage) -{ - switch (tx_usage) { - case PIPE_TRANSFER_READ: - return PIPE_BUFFER_USAGE_CPU_READ; - case PIPE_TRANSFER_WRITE: - return PIPE_BUFFER_USAGE_CPU_WRITE; - case PIPE_TRANSFER_READ_WRITE: - return PIPE_BUFFER_USAGE_CPU_READ_WRITE; - default: - assert(0); - } - - return -1; -} - static void nv20_compatible_transfer_tex(struct pipe_texture *pt, unsigned level, struct pipe_texture *template) @@ -86,7 +70,7 @@ nv20_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, tx->direct = true; tx->surface = pscreen->get_tex_surface(pscreen, pt, 0, 0, 0, - nv20_usage_tx_to_buf(usage)); + pipe_transfer_buffer_flags(&tx->base)); return &tx->base; } @@ -103,7 +87,7 @@ nv20_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, tx->surface = pscreen->get_tex_surface(pscreen, tx_tex, face, level, zslice, - nv20_usage_tx_to_buf(usage)); + pipe_transfer_buffer_flags(&tx->base)); pipe_texture_reference(&tx_tex, NULL); @@ -114,7 +98,7 @@ nv20_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, return NULL; } - if (usage != PIPE_TRANSFER_WRITE) { + if (usage & PIPE_TRANSFER_READ) { struct nv20_screen *nvscreen = nv20_screen(pscreen); struct pipe_surface *src; @@ -140,7 +124,7 @@ nv20_transfer_del(struct pipe_transfer *ptx) { struct nv20_transfer *tx = (struct nv20_transfer *)ptx; - if (!tx->direct && ptx->usage != PIPE_TRANSFER_READ) { + if (!tx->direct && (ptx->usage = PIPE_TRANSFER_WRITE)) { struct pipe_screen *pscreen = ptx->texture->screen; struct nv20_screen *nvscreen = nv20_screen(pscreen); struct pipe_surface *dst; @@ -170,7 +154,7 @@ nv20_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx) struct nv04_surface *ns = (struct nv04_surface *)tx->surface; struct nv20_miptree *mt = (struct nv20_miptree *)tx->surface->texture; void *map = pipe_buffer_map(pscreen, mt->buffer, - nv20_usage_tx_to_buf(ptx->usage)); + pipe_transfer_buffer_flags(ptx)); return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * ptx->block.size; diff --git a/src/gallium/drivers/nv30/nv30_transfer.c b/src/gallium/drivers/nv30/nv30_transfer.c index 23675718781..98011decf7c 100644 --- a/src/gallium/drivers/nv30/nv30_transfer.c +++ b/src/gallium/drivers/nv30/nv30_transfer.c @@ -13,22 +13,6 @@ struct nv30_transfer { bool direct; }; -static unsigned nv30_usage_tx_to_buf(unsigned tx_usage) -{ - switch (tx_usage) { - case PIPE_TRANSFER_READ: - return PIPE_BUFFER_USAGE_CPU_READ; - case PIPE_TRANSFER_WRITE: - return PIPE_BUFFER_USAGE_CPU_WRITE; - case PIPE_TRANSFER_READ_WRITE: - return PIPE_BUFFER_USAGE_CPU_READ_WRITE; - default: - assert(0); - } - - return -1; -} - static void nv30_compatible_transfer_tex(struct pipe_texture *pt, unsigned level, struct pipe_texture *template) @@ -86,7 +70,7 @@ nv30_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, tx->direct = true; tx->surface = pscreen->get_tex_surface(pscreen, pt, face, level, zslice, - nv30_usage_tx_to_buf(usage)); + pipe_transfer_buffer_flags(&tx->base)); return &tx->base; } @@ -103,7 +87,7 @@ nv30_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, tx->surface = pscreen->get_tex_surface(pscreen, tx_tex, 0, 0, 0, - nv30_usage_tx_to_buf(usage)); + pipe_transfer_buffer_flags(&tx->base)); pipe_texture_reference(&tx_tex, NULL); @@ -114,7 +98,7 @@ nv30_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, return NULL; } - if (usage != PIPE_TRANSFER_WRITE) { + if (usage & PIPE_TRANSFER_READ) { struct nv30_screen *nvscreen = nv30_screen(pscreen); struct pipe_surface *src; @@ -140,7 +124,7 @@ nv30_transfer_del(struct pipe_transfer *ptx) { struct nv30_transfer *tx = (struct nv30_transfer *)ptx; - if (!tx->direct && ptx->usage != PIPE_TRANSFER_READ) { + if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) { struct pipe_screen *pscreen = ptx->texture->screen; struct nv30_screen *nvscreen = nv30_screen(pscreen); struct pipe_surface *dst; @@ -170,7 +154,7 @@ nv30_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx) struct nv04_surface *ns = (struct nv04_surface *)tx->surface; struct nv30_miptree *mt = (struct nv30_miptree *)tx->surface->texture; void *map = pipe_buffer_map(pscreen, mt->buffer, - nv30_usage_tx_to_buf(ptx->usage)); + pipe_transfer_buffer_flags(ptx)); return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * ptx->block.size; diff --git a/src/gallium/drivers/nv40/nv40_transfer.c b/src/gallium/drivers/nv40/nv40_transfer.c index 6d92ac3db9c..92caee6f382 100644 --- a/src/gallium/drivers/nv40/nv40_transfer.c +++ b/src/gallium/drivers/nv40/nv40_transfer.c @@ -13,22 +13,6 @@ struct nv40_transfer { bool direct; }; -static unsigned nv40_usage_tx_to_buf(unsigned tx_usage) -{ - switch (tx_usage) { - case PIPE_TRANSFER_READ: - return PIPE_BUFFER_USAGE_CPU_READ; - case PIPE_TRANSFER_WRITE: - return PIPE_BUFFER_USAGE_CPU_WRITE; - case PIPE_TRANSFER_READ_WRITE: - return PIPE_BUFFER_USAGE_CPU_READ_WRITE; - default: - assert(0); - } - - return -1; -} - static void nv40_compatible_transfer_tex(struct pipe_texture *pt, unsigned level, struct pipe_texture *template) @@ -86,7 +70,7 @@ nv40_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, tx->direct = true; tx->surface = pscreen->get_tex_surface(pscreen, pt, face, level, zslice, - nv40_usage_tx_to_buf(usage)); + pipe_transfer_buffer_flags(&tx->base)); return &tx->base; } @@ -103,7 +87,7 @@ nv40_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, tx->surface = pscreen->get_tex_surface(pscreen, tx_tex, 0, 0, 0, - nv40_usage_tx_to_buf(usage)); + pipe_transfer_buffer_flags(&tx->base)); pipe_texture_reference(&tx_tex, NULL); @@ -114,7 +98,7 @@ nv40_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, return NULL; } - if (usage != PIPE_TRANSFER_WRITE) { + if (usage & PIPE_TRANSFER_READ) { struct nv40_screen *nvscreen = nv40_screen(pscreen); struct pipe_surface *src; @@ -140,7 +124,7 @@ nv40_transfer_del(struct pipe_transfer *ptx) { struct nv40_transfer *tx = (struct nv40_transfer *)ptx; - if (!tx->direct && ptx->usage != PIPE_TRANSFER_READ) { + if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) { struct pipe_screen *pscreen = ptx->texture->screen; struct nv40_screen *nvscreen = nv40_screen(pscreen); struct pipe_surface *dst; @@ -170,7 +154,7 @@ nv40_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx) struct nv04_surface *ns = (struct nv04_surface *)tx->surface; struct nv40_miptree *mt = (struct nv40_miptree *)tx->surface->texture; void *map = pipe_buffer_map(pscreen, mt->buffer, - nv40_usage_tx_to_buf(ptx->usage)); + pipe_transfer_buffer_flags(ptx)); return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * ptx->block.size; diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c index bb7731855cd..9c289026bbb 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -161,7 +161,7 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, return NULL; } - if (usage != PIPE_TRANSFER_WRITE) { + if (usage & PIPE_TRANSFER_READ) { nv50_transfer_rect_m2mf(pscreen, mt->base.bo, tx->level_offset, tx->level_pitch, tx->level_tiling, x, y, @@ -183,7 +183,7 @@ nv50_transfer_del(struct pipe_transfer *ptx) struct nv50_transfer *tx = (struct nv50_transfer *)ptx; struct nv50_miptree *mt = nv50_miptree(ptx->texture); - if (ptx->usage != PIPE_TRANSFER_READ) { + if (ptx->usage & PIPE_TRANSFER_WRITE) { struct pipe_screen *pscreen = ptx->texture->screen; nv50_transfer_rect_m2mf(pscreen, tx->bo, 0, tx->base.stride, tx->bo->tile_mode, 0, 0, diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 8296d56840f..f2659ca61f7 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -345,16 +345,9 @@ static void* r300_transfer_map(struct pipe_screen* screen, { struct r300_texture* tex = (struct r300_texture*)transfer->texture; char* map; - unsigned flags = 0; - if (transfer->usage != PIPE_TRANSFER_WRITE) { - flags |= PIPE_BUFFER_USAGE_CPU_READ; - } - if (transfer->usage != PIPE_TRANSFER_READ) { - flags |= PIPE_BUFFER_USAGE_CPU_WRITE; - } - - map = pipe_buffer_map(screen, tex->buffer, flags); + map = pipe_buffer_map(screen, tex->buffer, + pipe_transfer_buffer_flags(transfer)); if (!map) { return NULL; diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 1c64d58372d..2e6c43c7ef2 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -329,27 +329,18 @@ softpipe_transfer_map( struct pipe_screen *screen, { ubyte *map, *xfer_map; struct softpipe_texture *spt; - unsigned flags = 0; assert(transfer->texture); spt = softpipe_texture(transfer->texture); - if (transfer->usage != PIPE_TRANSFER_READ) { - flags |= PIPE_BUFFER_USAGE_CPU_WRITE; - } - - if (transfer->usage != PIPE_TRANSFER_WRITE) { - flags |= PIPE_BUFFER_USAGE_CPU_READ; - } - - map = pipe_buffer_map(screen, spt->buffer, flags); + map = pipe_buffer_map(screen, spt->buffer, pipe_transfer_buffer_flags(transfer)); if (map == NULL) return NULL; /* May want to different things here depending on read/write nature * of the map: */ - if (transfer->texture && transfer->usage != PIPE_TRANSFER_READ) { + if (transfer->texture && (transfer->usage & PIPE_TRANSFER_WRITE)) { /* Do something to notify sharing contexts of a texture change. * In softpipe, that would mean flushing the texture cache. */ @@ -375,7 +366,7 @@ softpipe_transfer_unmap(struct pipe_screen *screen, pipe_buffer_unmap( screen, spt->buffer ); - if (transfer->usage != PIPE_TRANSFER_READ) { + if (transfer->usage & PIPE_TRANSFER_WRITE) { /* Mark the texture as dirty to expire the tile caches. */ spt->timestamp++; } diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index 26f1c04594f..ab605c7fc87 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -403,7 +403,7 @@ trace_screen_transfer_map(struct pipe_screen *_screen, map = screen->transfer_map(screen, transfer); if(map) { - if(transfer->usage != PIPE_TRANSFER_READ) { + if(transfer->usage & PIPE_TRANSFER_WRITE) { assert(!tr_trans->map); tr_trans->map = map; } diff --git a/src/gallium/include/pipe/p_inlines.h b/src/gallium/include/pipe/p_inlines.h index 30a4aaf4093..5fbd62a03d2 100644 --- a/src/gallium/include/pipe/p_inlines.h +++ b/src/gallium/include/pipe/p_inlines.h @@ -176,6 +176,22 @@ pipe_transfer_destroy( struct pipe_transfer *transf ) screen->tex_transfer_destroy(transf); } +static INLINE unsigned +pipe_transfer_buffer_flags( struct pipe_transfer *transf ) +{ + switch (transf->usage & PIPE_TRANSFER_READ_WRITE) { + case PIPE_TRANSFER_READ_WRITE: + return PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE; + case PIPE_TRANSFER_READ: + return PIPE_BUFFER_USAGE_CPU_READ; + case PIPE_TRANSFER_WRITE: + return PIPE_BUFFER_USAGE_CPU_WRITE; + default: + debug_assert(0); + return 0; + } +} + #ifdef __cplusplus } #endif diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py index 6f0bd6ae52a..f4ed2fde4dc 100755 --- a/src/gallium/state_trackers/python/retrace/interpreter.py +++ b/src/gallium/state_trackers/python/retrace/interpreter.py @@ -314,7 +314,7 @@ class Screen(Object): if texture is None: return None transfer = Transfer(texture.get_surface(face, level, zslice), x, y, w, h) - if transfer and usage != gallium.PIPE_TRANSFER_WRITE: + if transfer and usage & gallium.PIPE_TRANSFER_READ if self.interpreter.options.all: self.interpreter.present(transfer.surface, 'transf_read', x, y, w, h) return transfer diff --git a/src/gallium/state_trackers/vega/st_inlines.h b/src/gallium/state_trackers/vega/st_inlines.h index 1f331dfcdb7..610755e0636 100644 --- a/src/gallium/state_trackers/vega/st_inlines.h +++ b/src/gallium/state_trackers/vega/st_inlines.h @@ -57,8 +57,7 @@ st_cond_flush_get_tex_transfer(struct vg_context *st, pipe->is_texture_referenced(pipe, pt, face, level); if (referenced && ((referenced & PIPE_REFERENCED_FOR_WRITE) || - usage == PIPE_TRANSFER_WRITE || - usage == PIPE_TRANSFER_READ_WRITE)) + (usage & PIPE_TRANSFER_WRITE))) vgFlush(); return screen->get_tex_transfer(screen, pt, face, level, zslice, usage, diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index 95181578f63..3d1d0f71d53 100644 --- a/src/mesa/state_tracker/st_cb_accum.c +++ b/src/mesa/state_tracker/st_cb_accum.c @@ -241,7 +241,7 @@ accum_return(GLcontext *ctx, GLfloat value, xpos, ypos, width, height); - if (usage != PIPE_TRANSFER_WRITE) + if (usage & PIPE_TRANSFER_READ) pipe_get_tile_rgba(color_trans, 0, 0, width, height, buf); switch (acc_strb->format) { diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index bbc2830e694..ba8d1e8cc16 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -577,7 +577,6 @@ st_teximage_flush_before_map(struct st_context *st, pipe->is_texture_referenced(pipe, pt, face, level); if (referenced && ((referenced & PIPE_REFERENCED_FOR_WRITE) || - usage == PIPE_TRANSFER_WRITE || - usage == PIPE_TRANSFER_READ_WRITE)) + (usage & PIPE_TRANSFER_WRITE))) st_flush(st, PIPE_FLUSH_RENDER_CACHE, NULL); } -- cgit v1.2.3 From 751aa58e01bd2b4f35aa0e1477d77a0dc5490f39 Mon Sep 17 00:00:00 2001 From: Nicolai Hähnle Date: Sat, 3 Oct 2009 17:24:04 +0200 Subject: r300g: Reset vbo_offset after allocation of a new buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes the glxgears bug, among other things. Signed-off-by: Nicolai Hähnle --- src/gallium/drivers/r300/r300_render.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 16f64040129..69d162324a9 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -79,13 +79,14 @@ static boolean r300_render_allocate_vertices(struct vbuf_render* render, struct pipe_screen* screen = r300->context.screen; size_t size = (size_t)vertex_size * (size_t)count; - if (size + r300render->vbo_offset > r300render->vbo_size) + if (size + r300render->vbo_offset > r300render->vbo_size) { pipe_buffer_reference(&r300->vbo, NULL); r300render->vbo = pipe_buffer_create(screen, 64, PIPE_BUFFER_USAGE_VERTEX, R300_MAX_VBO_SIZE); + r300render->vbo_offset = 0; r300render->vbo_size = R300_MAX_VBO_SIZE; } @@ -118,7 +119,7 @@ static void r300_render_unmap_vertices(struct vbuf_render* render, OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, max); END_CS; - r300render->vbo_max_used = MAX2(r300render->vbo_max_used, + r300render->vbo_max_used = MAX2(r300render->vbo_max_used, r300render->vertex_size * (max + 1)); pipe_buffer_unmap(screen, r300render->vbo); } -- cgit v1.2.3 From 26df8af4fe4173eb52132dc63ee789b80a7a4db2 Mon Sep 17 00:00:00 2001 From: Nicolai Hähnle Date: Sat, 3 Oct 2009 17:49:16 +0200 Subject: r300g: Remove an unnecessarily created pipe buffer (and thus fix a leak) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nicolai Hähnle --- src/gallium/drivers/r300/r300_render.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 69d162324a9..ca44e0f6615 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -223,13 +223,6 @@ static void r300_render_draw(struct vbuf_render* render, r300_prepare_render(r300render, count); - /* Send our indices into an index buffer. */ - index_buffer = pipe_buffer_create(screen, 64, PIPE_BUFFER_USAGE_VERTEX, - count * 2); - if (!index_buffer) { - return; - } - BEGIN_CS(2 + (count+1)/2); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (count+1)/2); OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | -- cgit v1.2.3 From 81e5188f66248424d54fcf1d85a81510694bd472 Mon Sep 17 00:00:00 2001 From: Nicolai Hähnle Date: Sat, 3 Oct 2009 19:20:31 +0200 Subject: r300g: Do not abort on fragment program compiler error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nicolai Hähnle --- src/gallium/drivers/r300/r300_fs.c | 11 ++++++++--- src/gallium/drivers/r300/r300_fs.h | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src/gallium/drivers') diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c index a0e848a59ac..546ad545a53 100644 --- a/src/gallium/drivers/r300/r300_fs.c +++ b/src/gallium/drivers/r300/r300_fs.c @@ -126,9 +126,14 @@ void r300_translate_fragment_shader(struct r300_context* r300, /* Invoke the compiler */ r3xx_compile_fragment_program(&compiler); if (compiler.Base.Error) { - /* Todo: Fail gracefully */ - fprintf(stderr, "r300 FP: Compiler error\n"); - abort(); + /* Todo: Fallback to software rendering gracefully? */ + fprintf(stderr, "r300 FP: Compiler error: %s\n", compiler.Base.ErrorMsg); + + if (compiler.is_r500) { + memcpy(compiler.code, &r5xx_passthrough_fragment_shader, sizeof(r5xx_passthrough_fragment_shader)); + } else { + memcpy(compiler.code, &r3xx_passthrough_fragment_shader, sizeof(r3xx_passthrough_fragment_shader)); + } } /* And, finally... */ diff --git a/src/gallium/drivers/r300/r300_fs.h b/src/gallium/drivers/r300/r300_fs.h index 9fab7894024..967e9f697e9 100644 --- a/src/gallium/drivers/r300/r300_fs.h +++ b/src/gallium/drivers/r300/r300_fs.h @@ -48,4 +48,4 @@ struct r300_fragment_shader { void r300_translate_fragment_shader(struct r300_context* r300, struct r300_fragment_shader* fs); - #endif /* R300_FS_H */ +#endif /* R300_FS_H */ -- cgit v1.2.3