diff options
Diffstat (limited to 'src/gallium/drivers/softpipe')
20 files changed, 354 insertions, 214 deletions
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index b5d30bc6fc..f3489c1c79 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -129,6 +129,10 @@ softpipe_destroy( struct pipe_context *pipe ) } } + for (i = 0; i < softpipe->num_vertex_buffers; i++) { + pipe_resource_reference(&softpipe->vertex_buffer[i].buffer, NULL); + } + tgsi_exec_machine_destroy(softpipe->fs_machine); FREE( softpipe ); @@ -145,15 +149,15 @@ softpipe_destroy( struct pipe_context *pipe ) */ static unsigned int softpipe_is_resource_referenced( struct pipe_context *pipe, - struct pipe_resource *texture, - unsigned face, unsigned level) + struct pipe_resource *texture, + unsigned level, int layer) { struct softpipe_context *softpipe = softpipe_context( pipe ); unsigned i; if (texture->target == PIPE_BUFFER) return PIPE_UNREFERENCED; - + /* check if any of the bound drawing surfaces are this texture */ if (softpipe->dirty_render_cache) { for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) { diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 9361a3df09..903574b7e1 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -154,9 +154,9 @@ struct softpipe_context { /** TGSI exec things */ struct { - struct sp_sampler_varient *geom_samplers_list[PIPE_MAX_GEOMETRY_SAMPLERS]; - struct sp_sampler_varient *vert_samplers_list[PIPE_MAX_VERTEX_SAMPLERS]; - struct sp_sampler_varient *frag_samplers_list[PIPE_MAX_SAMPLERS]; + struct sp_sampler_variant *geom_samplers_list[PIPE_MAX_GEOMETRY_SAMPLERS]; + struct sp_sampler_variant *vert_samplers_list[PIPE_MAX_VERTEX_SAMPLERS]; + struct sp_sampler_variant *frag_samplers_list[PIPE_MAX_SAMPLERS]; } tgsi; struct tgsi_exec_machine *fs_machine; @@ -192,7 +192,7 @@ softpipe_context( struct pipe_context *pipe ) } void -softpipe_reset_sampler_varients(struct softpipe_context *softpipe); +softpipe_reset_sampler_variants(struct softpipe_context *softpipe); struct pipe_context * softpipe_create_context( struct pipe_screen *, void *priv ); diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index 1071011db0..4258395063 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -120,8 +120,8 @@ softpipe_flush( struct pipe_context *pipe, boolean softpipe_flush_resource(struct pipe_context *pipe, struct pipe_resource *texture, - unsigned face, unsigned level, + int layer, unsigned flush_flags, boolean read_only, boolean cpu_access, @@ -129,7 +129,7 @@ softpipe_flush_resource(struct pipe_context *pipe, { unsigned referenced; - referenced = pipe->is_resource_referenced(pipe, texture, face, level); + referenced = pipe->is_resource_referenced(pipe, texture, level, layer); if ((referenced & PIPE_REFERENCED_FOR_WRITE) || ((referenced & PIPE_REFERENCED_FOR_READ) && !read_only)) { diff --git a/src/gallium/drivers/softpipe/sp_flush.h b/src/gallium/drivers/softpipe/sp_flush.h index cb97482a71..22a5ceeb9e 100644 --- a/src/gallium/drivers/softpipe/sp_flush.h +++ b/src/gallium/drivers/softpipe/sp_flush.h @@ -40,8 +40,8 @@ softpipe_flush(struct pipe_context *pipe, unsigned flags, boolean softpipe_flush_resource(struct pipe_context *pipe, struct pipe_resource *texture, - unsigned face, unsigned level, + int layer, unsigned flush_flags, boolean read_only, boolean cpu_access, diff --git a/src/gallium/drivers/softpipe/sp_limits.h b/src/gallium/drivers/softpipe/sp_limits.h new file mode 100644 index 0000000000..a7a24c98d5 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_limits.h @@ -0,0 +1,42 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * 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 THE AUTHORS 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_LIMITS_H +#define SP_LIMITS_H + + + +#define SP_MAX_TEXTURE_2D_LEVELS 15 /* 16K x 16K */ +#define SP_MAX_TEXTURE_3D_LEVELS 9 /* 512 x 512 x 512 */ + + +/** Max surface size */ +#define MAX_WIDTH (1 << (SP_MAX_TEXTURE_2D_LEVELS - 1)) +#define MAX_HEIGHT (1 << (SP_MAX_TEXTURE_2D_LEVELS - 1)) + + +#endif /* SP_LIMITS_H */ diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index 6af1b2d061..76cfc0bf51 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -35,6 +35,7 @@ #include "util/u_memory.h" #include "util/u_format.h" #include "sp_context.h" +#include "sp_state.h" #include "sp_quad.h" #include "sp_tile_cache.h" #include "sp_quad_pipe.h" @@ -794,6 +795,9 @@ blend_fallback(struct quad_stage *qs, struct softpipe_context *softpipe = qs->softpipe; const struct pipe_blend_state *blend = softpipe->blend; unsigned cbuf; + boolean write_all; + + write_all = softpipe->fs->color0_writes_all_cbufs; for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) { @@ -806,15 +810,19 @@ blend_fallback(struct quad_stage *qs, quads[0]->input.y0); boolean has_dst_alpha = util_format_has_alpha(softpipe->framebuffer.cbufs[cbuf]->format); - uint q, i, j; + uint q, i, j, qbuf; + + qbuf = write_all ? 0 : cbuf; for (q = 0; q < nr; q++) { struct quad_header *quad = quads[q]; - float (*quadColor)[4] = quad->output.color[cbuf]; + float (*quadColor)[4]; const int itx = (quad->input.x0 & (TILE_SIZE-1)); const int ity = (quad->input.y0 & (TILE_SIZE-1)); - /* get/swizzle dest colors + quadColor = quad->output.color[qbuf]; + + /* get/swizzle dest colors */ for (j = 0; j < QUAD_SIZE; j++) { int x = itx + (j & 1); diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 9b54babdfb..e19f2e6fc7 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -268,12 +268,13 @@ softpipe_destroy_screen( struct pipe_screen *screen ) */ static void softpipe_flush_frontbuffer(struct pipe_screen *_screen, - struct pipe_surface *surface, + struct pipe_resource *resource, + unsigned level, unsigned layer, void *context_private) { struct softpipe_screen *screen = softpipe_screen(_screen); struct sw_winsys *winsys = screen->winsys; - struct softpipe_resource *texture = softpipe_resource(surface->texture); + struct softpipe_resource *texture = softpipe_resource(resource); assert(texture->dt); if (texture->dt) diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 525bf23734..bb19f8cff2 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -74,7 +74,7 @@ struct sp_fragment_shader { boolean origin_lower_left; /**< fragment shader uses lower left position origin? */ boolean pixel_center_integer; /**< fragment shader uses integer pixel center? */ - + boolean color0_writes_all_cbufs; /**< fragment shader writes color0 to all bound cbufs */ void (*prepare)( const struct sp_fragment_shader *shader, struct tgsi_exec_machine *machine, struct tgsi_sampler **samplers); diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 3ba4d934fd..bf4c12701a 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -197,7 +197,7 @@ update_tgsi_samplers( struct softpipe_context *softpipe ) { unsigned i; - softpipe_reset_sampler_varients( softpipe ); + softpipe_reset_sampler_variants( softpipe ); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { struct softpipe_tex_tile_cache *tc = 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 b59fbc33ed..cfa211b60a 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -43,8 +43,8 @@ struct sp_sampler { struct pipe_sampler_state base; - struct sp_sampler_varient *varients; - struct sp_sampler_varient *current; + struct sp_sampler_variant *variants; + struct sp_sampler_variant *current; }; static struct sp_sampler *sp_sampler( struct pipe_sampler_state *sampler ) @@ -60,7 +60,7 @@ softpipe_create_sampler_state(struct pipe_context *pipe, struct sp_sampler *sp_sampler = CALLOC_STRUCT(sp_sampler); sp_sampler->base = *sampler; - sp_sampler->varients = NULL; + sp_sampler->variants = NULL; return (void *)sp_sampler; } @@ -277,23 +277,24 @@ softpipe_set_geometry_sampler_views(struct pipe_context *pipe, /** - * Find/create an sp_sampler_varient object for sampling the given texture, + * Find/create an sp_sampler_variant 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 + * variant for multiple texture units because the sampler variant contains * the texture object pointer. If the texture object pointer were stored - * somewhere outside the sampler varient, we could re-use samplers for + * somewhere outside the sampler variant, we could re-use samplers for * multiple texture units. */ -static struct sp_sampler_varient * -get_sampler_varient( unsigned unit, +static struct sp_sampler_variant * +get_sampler_variant( unsigned unit, struct sp_sampler *sampler, + struct pipe_sampler_view *view, struct pipe_resource *resource, unsigned processor ) { struct softpipe_resource *sp_texture = softpipe_resource(resource); - struct sp_sampler_varient *v = NULL; + struct sp_sampler_variant *v = NULL; union sp_sampler_key key; /* if this fails, widen the key.unit field and update this assertion */ @@ -303,6 +304,10 @@ get_sampler_varient( unsigned unit, key.bits.is_pot = sp_texture->pot; key.bits.processor = processor; key.bits.unit = unit; + key.bits.swizzle_r = view->swizzle_r; + key.bits.swizzle_g = view->swizzle_g; + key.bits.swizzle_b = view->swizzle_b; + key.bits.swizzle_a = view->swizzle_a; key.bits.pad = 0; if (sampler->current && @@ -311,14 +316,14 @@ get_sampler_varient( unsigned unit, } if (v == NULL) { - for (v = sampler->varients; v; v = v->next) + for (v = sampler->variants; 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; + v = sp_create_sampler_variant( &sampler->base, key ); + v->next = sampler->variants; + sampler->variants = v; } } @@ -328,7 +333,7 @@ get_sampler_varient( unsigned unit, void -softpipe_reset_sampler_varients(struct softpipe_context *softpipe) +softpipe_reset_sampler_variants(struct softpipe_context *softpipe) { int i; @@ -345,12 +350,13 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe) } softpipe->tgsi.vert_samplers_list[i] = - get_sampler_varient( i, + get_sampler_variant( i, sp_sampler(softpipe->vertex_samplers[i]), + softpipe->vertex_sampler_views[i], texture, TGSI_PROCESSOR_VERTEX ); - sp_sampler_varient_bind_texture( softpipe->tgsi.vert_samplers_list[i], + sp_sampler_variant_bind_texture( softpipe->tgsi.vert_samplers_list[i], softpipe->vertex_tex_cache[i], texture ); } @@ -366,13 +372,14 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe) } softpipe->tgsi.geom_samplers_list[i] = - get_sampler_varient( + get_sampler_variant( i, sp_sampler(softpipe->geometry_samplers[i]), + softpipe->geometry_sampler_views[i], texture, TGSI_PROCESSOR_GEOMETRY ); - sp_sampler_varient_bind_texture( + sp_sampler_variant_bind_texture( softpipe->tgsi.geom_samplers_list[i], softpipe->geometry_tex_cache[i], texture ); @@ -389,12 +396,13 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe) } softpipe->tgsi.frag_samplers_list[i] = - get_sampler_varient( i, + get_sampler_variant( i, sp_sampler(softpipe->sampler[i]), + softpipe->sampler_views[i], texture, TGSI_PROCESSOR_FRAGMENT ); - sp_sampler_varient_bind_texture( softpipe->tgsi.frag_samplers_list[i], + sp_sampler_variant_bind_texture( softpipe->tgsi.frag_samplers_list[i], softpipe->tex_cache[i], texture ); } @@ -406,11 +414,11 @@ 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; + struct sp_sampler_variant *v, *tmp; - for (v = sp_sampler->varients; v; v = tmp) { + for (v = sp_sampler->variants; v; v = tmp) { tmp = v->next; - sp_sampler_varient_destroy(v); + sp_sampler_variant_destroy(v); } FREE( sampler ); diff --git a/src/gallium/drivers/softpipe/sp_state_shader.c b/src/gallium/drivers/softpipe/sp_state_shader.c index 7fff338cce..66ddc56572 100644 --- a/src/gallium/drivers/softpipe/sp_state_shader.c +++ b/src/gallium/drivers/softpipe/sp_state_shader.c @@ -78,6 +78,8 @@ softpipe_create_fs_state(struct pipe_context *pipe, state->origin_lower_left = state->info.properties[i].data[0]; else if (state->info.properties[i].name == TGSI_PROPERTY_FS_COORD_PIXEL_CENTER) state->pixel_center_integer = state->info.properties[i].data[0]; + else if (state->info.properties[i].name == TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS) + state->color0_writes_all_cbufs = state->info.properties[i].data[0]; } return state; diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c index 7d8055f2ba..5f4d661abd 100644 --- a/src/gallium/drivers/softpipe/sp_state_vertex.c +++ b/src/gallium/drivers/softpipe/sp_state_vertex.c @@ -33,6 +33,7 @@ #include "sp_state.h" #include "util/u_memory.h" +#include "util/u_inlines.h" #include "draw/draw_context.h" @@ -84,8 +85,9 @@ softpipe_set_vertex_buffers(struct pipe_context *pipe, assert(count <= PIPE_MAX_ATTRIBS); - memcpy(softpipe->vertex_buffer, buffers, count * sizeof(buffers[0])); - softpipe->num_vertex_buffers = count; + util_copy_vertex_buffers(softpipe->vertex_buffer, + &softpipe->num_vertex_buffers, + buffers, count); softpipe->dirty |= SP_NEW_VERTEX; diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 2eac4c7a82..cbc40d4b44 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -545,7 +545,7 @@ wrap_linear_unorm_clamp_to_edge(const float s[4], unsigned size, * derivatives w.r.t X and Y, then compute lambda (level of detail). */ static float -compute_lambda_1d(const struct sp_sampler_varient *samp, +compute_lambda_1d(const struct sp_sampler_variant *samp, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE]) @@ -560,7 +560,7 @@ compute_lambda_1d(const struct sp_sampler_varient *samp, static float -compute_lambda_2d(const struct sp_sampler_varient *samp, +compute_lambda_2d(const struct sp_sampler_variant *samp, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE]) @@ -579,7 +579,7 @@ compute_lambda_2d(const struct sp_sampler_varient *samp, static float -compute_lambda_3d(const struct sp_sampler_varient *samp, +compute_lambda_3d(const struct sp_sampler_variant *samp, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE]) @@ -608,7 +608,7 @@ compute_lambda_3d(const struct sp_sampler_varient *samp, * Since there aren't derivatives to use, just return 0. */ static float -compute_lambda_vert(const struct sp_sampler_varient *samp, +compute_lambda_vert(const struct sp_sampler_variant *samp, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE]) @@ -634,7 +634,7 @@ compute_lambda_vert(const struct sp_sampler_varient *samp, static INLINE const float * -get_texel_2d_no_border(const struct sp_sampler_varient *samp, +get_texel_2d_no_border(const struct sp_sampler_variant *samp, union tex_tile_address addr, int x, int y) { const struct softpipe_tex_cached_tile *tile; @@ -651,7 +651,7 @@ get_texel_2d_no_border(const struct sp_sampler_varient *samp, static INLINE const float * -get_texel_2d(const struct sp_sampler_varient *samp, +get_texel_2d(const struct sp_sampler_variant *samp, union tex_tile_address addr, int x, int y) { const struct pipe_resource *texture = samp->texture; @@ -659,8 +659,7 @@ get_texel_2d(const struct sp_sampler_varient *samp, if (x < 0 || x >= (int) u_minify(texture->width0, level) || y < 0 || y >= (int) u_minify(texture->height0, level)) { - return sp_tex_tile_cache_border_color(samp->cache, - samp->sampler->border_color); + return samp->sampler->border_color; } else { return get_texel_2d_no_border( samp, addr, x, y ); @@ -671,7 +670,7 @@ get_texel_2d(const struct sp_sampler_varient *samp, /* 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, +get_texel_quad_2d_no_border_single_tile(const struct sp_sampler_variant *samp, union tex_tile_address addr, unsigned x, unsigned y, const float *out[4]) @@ -695,7 +694,7 @@ get_texel_quad_2d_no_border_single_tile(const struct sp_sampler_varient *samp, /* Gather a quad of potentially non-adjacent texels: */ static INLINE void -get_texel_quad_2d_no_border(const struct sp_sampler_varient *samp, +get_texel_quad_2d_no_border(const struct sp_sampler_variant *samp, union tex_tile_address addr, int x0, int y0, int x1, int y1, @@ -710,7 +709,7 @@ get_texel_quad_2d_no_border(const struct sp_sampler_varient *samp, /* Can involve a lot of unnecessary checks for border color: */ static INLINE void -get_texel_quad_2d(const struct sp_sampler_varient *samp, +get_texel_quad_2d(const struct sp_sampler_variant *samp, union tex_tile_address addr, int x0, int y0, int x1, int y1, @@ -724,10 +723,10 @@ get_texel_quad_2d(const struct sp_sampler_varient *samp, -/* 3d varients: +/* 3d variants: */ static INLINE const float * -get_texel_3d_no_border(const struct sp_sampler_varient *samp, +get_texel_3d_no_border(const struct sp_sampler_variant *samp, union tex_tile_address addr, int x, int y, int z) { const struct softpipe_tex_cached_tile *tile; @@ -745,7 +744,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, +get_texel_3d(const struct sp_sampler_variant *samp, union tex_tile_address addr, int x, int y, int z) { const struct pipe_resource *texture = samp->texture; @@ -754,8 +753,7 @@ get_texel_3d(const struct sp_sampler_varient *samp, if (x < 0 || x >= (int) u_minify(texture->width0, level) || y < 0 || y >= (int) u_minify(texture->height0, level) || z < 0 || z >= (int) u_minify(texture->depth0, level)) { - return sp_tex_tile_cache_border_color(samp->cache, - samp->sampler->border_color); + return samp->sampler->border_color; } else { return get_texel_3d_no_border( samp, addr, x, y, z ); @@ -800,7 +798,7 @@ img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler, enum tgsi_sampler_control control, float rgba[NUM_CHANNELS][QUAD_SIZE]) { - const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); unsigned j; unsigned level = samp->level; unsigned xpot = pot_level_size(samp->xpot, level); @@ -863,7 +861,7 @@ img_filter_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler, enum tgsi_sampler_control control, float rgba[NUM_CHANNELS][QUAD_SIZE]) { - const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); unsigned j; unsigned level = samp->level; unsigned xpot = pot_level_size(samp->xpot, level); @@ -907,7 +905,7 @@ img_filter_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler, enum tgsi_sampler_control control, float rgba[NUM_CHANNELS][QUAD_SIZE]) { - const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); unsigned j; unsigned level = samp->level; unsigned xpot = pot_level_size(samp->xpot, level); @@ -960,7 +958,7 @@ img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler, enum tgsi_sampler_control control, float rgba[NUM_CHANNELS][QUAD_SIZE]) { - const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->texture; unsigned level0, j; int width; @@ -1000,7 +998,7 @@ img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler, enum tgsi_sampler_control control, float rgba[NUM_CHANNELS][QUAD_SIZE]) { - const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->texture; unsigned level0, j; int width, height; @@ -1052,7 +1050,7 @@ img_filter_cube_nearest(struct tgsi_sampler *tgsi_sampler, enum tgsi_sampler_control control, float rgba[NUM_CHANNELS][QUAD_SIZE]) { - const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->texture; const unsigned *faces = samp->faces; /* zero when not cube-mapping */ unsigned level0, j; @@ -1096,7 +1094,7 @@ img_filter_3d_nearest(struct tgsi_sampler *tgsi_sampler, enum tgsi_sampler_control control, float rgba[NUM_CHANNELS][QUAD_SIZE]) { - const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->texture; unsigned level0, j; int width, height, depth; @@ -1138,7 +1136,7 @@ img_filter_1d_linear(struct tgsi_sampler *tgsi_sampler, enum tgsi_sampler_control control, float rgba[NUM_CHANNELS][QUAD_SIZE]) { - const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->texture; unsigned level0, j; int width; @@ -1178,7 +1176,7 @@ img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler, enum tgsi_sampler_control control, float rgba[NUM_CHANNELS][QUAD_SIZE]) { - const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->texture; unsigned level0, j; int width, height; @@ -1225,7 +1223,7 @@ img_filter_cube_linear(struct tgsi_sampler *tgsi_sampler, enum tgsi_sampler_control control, float rgba[NUM_CHANNELS][QUAD_SIZE]) { - const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->texture; const unsigned *faces = samp->faces; /* zero when not cube-mapping */ unsigned level0, j; @@ -1274,7 +1272,7 @@ img_filter_3d_linear(struct tgsi_sampler *tgsi_sampler, enum tgsi_sampler_control control, float rgba[NUM_CHANNELS][QUAD_SIZE]) { - const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->texture; unsigned level0, j; int width, height, depth; @@ -1350,7 +1348,7 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler, enum tgsi_sampler_control control, float rgba[NUM_CHANNELS][QUAD_SIZE]) { - struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->texture; int level0; float lambda; @@ -1417,7 +1415,7 @@ mip_filter_nearest(struct tgsi_sampler *tgsi_sampler, enum tgsi_sampler_control control, float rgba[NUM_CHANNELS][QUAD_SIZE]) { - struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->texture; float lambda; float lod[QUAD_SIZE]; @@ -1460,7 +1458,7 @@ mip_filter_none(struct tgsi_sampler *tgsi_sampler, enum tgsi_sampler_control control, float rgba[NUM_CHANNELS][QUAD_SIZE]) { - struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); float lambda; float lod[QUAD_SIZE]; @@ -1501,7 +1499,7 @@ mip_filter_linear_2d_linear_repeat_POT( enum tgsi_sampler_control control, float rgba[NUM_CHANNELS][QUAD_SIZE]) { - struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_resource *texture = samp->texture; int level0; float lambda; @@ -1569,7 +1567,7 @@ sample_compare(struct tgsi_sampler *tgsi_sampler, enum tgsi_sampler_control control, float rgba[NUM_CHANNELS][QUAD_SIZE]) { - struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); const struct pipe_sampler_state *sampler = samp->sampler; int j, k0, k1, k2, k3; float val; @@ -1656,7 +1654,7 @@ sample_cube(struct tgsi_sampler *tgsi_sampler, enum tgsi_sampler_control control, float rgba[NUM_CHANNELS][QUAD_SIZE]) { - struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); + struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); unsigned j; float ssss[4], tttt[4]; @@ -1731,6 +1729,86 @@ sample_cube(struct tgsi_sampler *tgsi_sampler, } +static void +sample_swizzle(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + const float c0[QUAD_SIZE], + enum tgsi_sampler_control control, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); + float rgba_temp[NUM_CHANNELS][QUAD_SIZE]; + const unsigned swizzle_r = samp->key.bits.swizzle_r; + const unsigned swizzle_g = samp->key.bits.swizzle_g; + const unsigned swizzle_b = samp->key.bits.swizzle_b; + const unsigned swizzle_a = samp->key.bits.swizzle_a; + unsigned j; + + samp->sample_target(tgsi_sampler, s, t, p, c0, control, rgba_temp); + + switch (swizzle_r) { + case PIPE_SWIZZLE_ZERO: + for (j = 0; j < 4; j++) + rgba[0][j] = 0.0f; + break; + case PIPE_SWIZZLE_ONE: + for (j = 0; j < 4; j++) + rgba[0][j] = 1.0f; + break; + default: + assert(swizzle_r < 4); + for (j = 0; j < 4; j++) + rgba[0][j] = rgba_temp[swizzle_r][j]; + } + + switch (swizzle_g) { + case PIPE_SWIZZLE_ZERO: + for (j = 0; j < 4; j++) + rgba[1][j] = 0.0f; + break; + case PIPE_SWIZZLE_ONE: + for (j = 0; j < 4; j++) + rgba[1][j] = 1.0f; + break; + default: + assert(swizzle_g < 4); + for (j = 0; j < 4; j++) + rgba[1][j] = rgba_temp[swizzle_g][j]; + } + + switch (swizzle_b) { + case PIPE_SWIZZLE_ZERO: + for (j = 0; j < 4; j++) + rgba[2][j] = 0.0f; + break; + case PIPE_SWIZZLE_ONE: + for (j = 0; j < 4; j++) + rgba[2][j] = 1.0f; + break; + default: + assert(swizzle_b < 4); + for (j = 0; j < 4; j++) + rgba[2][j] = rgba_temp[swizzle_b][j]; + } + + switch (swizzle_a) { + case PIPE_SWIZZLE_ZERO: + for (j = 0; j < 4; j++) + rgba[3][j] = 0.0f; + break; + case PIPE_SWIZZLE_ONE: + for (j = 0; j < 4; j++) + rgba[3][j] = 1.0f; + break; + default: + assert(swizzle_a < 4); + for (j = 0; j < 4; j++) + rgba[3][j] = rgba_temp[swizzle_a][j]; + } +} + static wrap_nearest_func get_nearest_unorm_wrap(unsigned mode) @@ -1909,10 +1987,10 @@ get_img_filter(const union sp_sampler_key key, /** - * Bind the given texture object and texture cache to the sampler varient. + * Bind the given texture object and texture cache to the sampler variant. */ void -sp_sampler_varient_bind_texture( struct sp_sampler_varient *samp, +sp_sampler_variant_bind_texture( struct sp_sampler_variant *samp, struct softpipe_tex_tile_cache *tex_cache, const struct pipe_resource *texture ) { @@ -1927,20 +2005,20 @@ sp_sampler_varient_bind_texture( struct sp_sampler_varient *samp, void -sp_sampler_varient_destroy( struct sp_sampler_varient *samp ) +sp_sampler_variant_destroy( struct sp_sampler_variant *samp ) { FREE(samp); } /** - * Create a sampler varient for a given set of non-orthogonal state. + * Create a sampler variant for a given set of non-orthogonal state. */ -struct sp_sampler_varient * -sp_create_sampler_varient( const struct pipe_sampler_state *sampler, +struct sp_sampler_variant * +sp_create_sampler_variant( const struct pipe_sampler_state *sampler, const union sp_sampler_key key ) { - struct sp_sampler_varient *samp = CALLOC_STRUCT(sp_sampler_varient); + struct sp_sampler_variant *samp = CALLOC_STRUCT(sp_sampler_variant); if (!samp) return NULL; @@ -2015,7 +2093,7 @@ sp_create_sampler_varient( const struct pipe_sampler_state *sampler, } if (key.bits.target == PIPE_TEXTURE_CUBE) { - samp->base.get_samples = sample_cube; + samp->sample_target = sample_cube; } else { samp->faces[0] = 0; @@ -2026,7 +2104,17 @@ sp_create_sampler_varient( const struct pipe_sampler_state *sampler, /* Skip cube face determination by promoting the compare * function pointer: */ - samp->base.get_samples = samp->compare; + samp->sample_target = samp->compare; + } + + if (key.bits.swizzle_r != PIPE_SWIZZLE_RED || + key.bits.swizzle_g != PIPE_SWIZZLE_GREEN || + key.bits.swizzle_b != PIPE_SWIZZLE_BLUE || + key.bits.swizzle_a != PIPE_SWIZZLE_ALPHA) { + samp->base.get_samples = sample_swizzle; + } + else { + samp->base.get_samples = samp->sample_target; } return samp; diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h index 6114acf737..ed99006ab0 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.h +++ b/src/gallium/drivers/softpipe/sp_tex_sample.h @@ -32,7 +32,7 @@ #include "tgsi/tgsi_exec.h" -struct sp_sampler_varient; +struct sp_sampler_variant; typedef void (*wrap_nearest_func)(const float s[4], unsigned size, @@ -44,7 +44,7 @@ typedef void (*wrap_linear_func)(const float s[4], int icoord1[4], float w[4]); -typedef float (*compute_lambda_func)(const struct sp_sampler_varient *sampler, +typedef float (*compute_lambda_func)(const struct sp_sampler_variant *sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE]); @@ -64,7 +64,11 @@ union sp_sampler_key { unsigned is_pot:1; unsigned processor:2; unsigned unit:4; - unsigned pad:22; + unsigned swizzle_r:3; + unsigned swizzle_g:3; + unsigned swizzle_b:3; + unsigned swizzle_a:3; + unsigned pad:10; } bits; unsigned value; }; @@ -72,7 +76,7 @@ union sp_sampler_key { /** * Subclass of tgsi_sampler */ -struct sp_sampler_varient +struct sp_sampler_variant { struct tgsi_sampler base; /**< base class */ @@ -113,32 +117,33 @@ struct sp_sampler_varient filter_func mip_filter; filter_func compare; + filter_func sample_target; /* Linked list: */ - struct sp_sampler_varient *next; + struct sp_sampler_variant *next; }; struct sp_sampler; -/* Create a sampler varient for a given set of non-orthogonal state. Currently the +/* Create a sampler variant for a given set of non-orthogonal state. Currently the */ -struct sp_sampler_varient * -sp_create_sampler_varient( const struct pipe_sampler_state *sampler, +struct sp_sampler_variant * +sp_create_sampler_variant( const struct pipe_sampler_state *sampler, const union sp_sampler_key key ); -void sp_sampler_varient_bind_texture( struct sp_sampler_varient *varient, +void sp_sampler_variant_bind_texture( struct sp_sampler_variant *variant, struct softpipe_tex_tile_cache *tex_cache, const struct pipe_resource *tex ); -void sp_sampler_varient_destroy( struct sp_sampler_varient * ); +void sp_sampler_variant_destroy( struct sp_sampler_variant * ); -static INLINE struct sp_sampler_varient * -sp_sampler_varient(const struct tgsi_sampler *sampler) +static INLINE struct sp_sampler_variant * +sp_sampler_variant(const struct tgsi_sampler *sampler) { - return (struct sp_sampler_varient *) sampler; + return (struct sp_sampler_variant *) sampler; } extern void diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c index e817c0c8cf..e42015ad49 100644 --- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c @@ -48,6 +48,9 @@ sp_create_tex_tile_cache( struct pipe_context *pipe ) struct softpipe_tex_tile_cache *tc; uint pos; + /* make sure max texture size works */ + assert((TILE_SIZE << TEX_ADDR_BITS) >= (1 << (SP_MAX_TEXTURE_2D_LEVELS-1))); + tc = CALLOC_STRUCT( softpipe_tex_tile_cache ); if (tc) { tc->pipe = pipe; @@ -260,15 +263,14 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc, } tc->tex_trans = - pipe_get_transfer(tc->pipe, tc->texture, - addr.bits.face, - addr.bits.level, - addr.bits.z, - PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED, - 0, 0, - u_minify(tc->texture->width0, addr.bits.level), - u_minify(tc->texture->height0, addr.bits.level)); - + pipe_get_transfer(tc->pipe, tc->texture, + addr.bits.level, + addr.bits.face + addr.bits.z, + PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED, + 0, 0, + u_minify(tc->texture->width0, addr.bits.level), + u_minify(tc->texture->height0, addr.bits.level)); + tc->tex_trans_map = tc->pipe->transfer_map(tc->pipe, tc->tex_trans); tc->tex_face = addr.bits.face; @@ -276,45 +278,26 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc, tc->tex_z = addr.bits.z; } - /* get tile from the transfer (view into texture) */ + /* get tile from the transfer (view into texture) + * Note we're using the swizzle version of this fuction only because + * we need to pass the texture cache's format explicitly. + */ pipe_get_tile_swizzle(tc->pipe, tc->tex_trans, addr.bits.x * TILE_SIZE, addr.bits.y * TILE_SIZE, TILE_SIZE, TILE_SIZE, - tc->swizzle_r, - tc->swizzle_g, - tc->swizzle_b, - tc->swizzle_a, + PIPE_SWIZZLE_RED, + PIPE_SWIZZLE_GREEN, + PIPE_SWIZZLE_BLUE, + PIPE_SWIZZLE_ALPHA, tc->format, (float *) tile->data.color); + tile->addr = addr; } tc->last_tile = tile; return tile; } - - - -/** - * Return the swizzled border color. - */ -const float * -sp_tex_tile_cache_border_color(struct softpipe_tex_tile_cache *tc, - const float border_color[4]) -{ - float rgba01[6]; - - COPY_4V(rgba01, border_color); - rgba01[PIPE_SWIZZLE_ZERO] = 0.0f; - rgba01[PIPE_SWIZZLE_ONE] = 1.0f; - - tc->swz_border_color[0] = rgba01[tc->swizzle_r]; - tc->swz_border_color[1] = rgba01[tc->swizzle_g]; - tc->swz_border_color[2] = rgba01[tc->swizzle_b]; - tc->swz_border_color[3] = rgba01[tc->swizzle_a]; - - return tc->swz_border_color; -} diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h index 05f25133da..2220955b71 100644 --- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h @@ -30,6 +30,7 @@ #include "pipe/p_compiler.h" +#include "sp_limits.h" struct softpipe_context; @@ -39,22 +40,26 @@ struct softpipe_tex_tile_cache; /** * Cache tile size (width and height). This needs to be a power of two. */ -#define TILE_SIZE 64 +#define TILE_SIZE_LOG2 6 +#define TILE_SIZE (1 << TILE_SIZE_LOG2) -/* If we need to support > 4096, just expand this to be a 64 bit - * union, or consider tiling in Z as well. +#define TEX_ADDR_BITS (SP_MAX_TEXTURE_2D_LEVELS - 1 - TILE_SIZE_LOG2) +#define TEX_Z_BITS (SP_MAX_TEXTURE_2D_LEVELS - 1) + +/** + * Texture tile address as a union for fast compares. */ 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 x:TEX_ADDR_BITS; /* 16K / TILE_SIZE */ + unsigned y:TEX_ADDR_BITS; /* 16K / TILE_SIZE */ + unsigned z:TEX_Z_BITS; /* 16K -- z not tiled */ unsigned face:3; unsigned level:4; unsigned invalid:1; } bits; - unsigned value; + uint64_t value; }; @@ -90,8 +95,6 @@ struct softpipe_tex_tile_cache unsigned format; struct softpipe_tex_cached_tile *last_tile; /**< most recently retrieved tile */ - - float swz_border_color[4]; /**< swizzled border color */ }; @@ -126,10 +129,10 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc, static INLINE union tex_tile_address tex_tile_address( unsigned x, - unsigned y, - unsigned z, - unsigned face, - unsigned level ) + unsigned y, + unsigned z, + unsigned face, + unsigned level ) { union tex_tile_address addr; @@ -139,7 +142,7 @@ tex_tile_address( unsigned x, addr.bits.z = z; addr.bits.face = face; addr.bits.level = level; - + return addr; } @@ -156,10 +159,5 @@ sp_get_cached_tile_tex(struct softpipe_tex_tile_cache *tc, } -const float * -sp_tex_tile_cache_border_color(struct softpipe_tex_tile_cache *tc, - const float border_color[4]); - - #endif /* SP_TEX_TILE_CACHE_H */ diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 4e6123fbd0..509d9982b1 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -220,23 +220,18 @@ softpipe_resource_get_handle(struct pipe_screen *screen, */ static unsigned sp_get_tex_image_offset(const struct softpipe_resource *spr, - unsigned level, unsigned face, unsigned zslice) + unsigned level, unsigned layer) { const unsigned hgt = u_minify(spr->base.height0, level); const unsigned nblocksy = util_format_get_nblocksy(spr->base.format, hgt); unsigned offset = spr->level_offset[level]; - if (spr->base.target == PIPE_TEXTURE_CUBE) { - assert(zslice == 0); - offset += face * nblocksy * spr->stride[level]; - } - else if (spr->base.target == PIPE_TEXTURE_3D) { - assert(face == 0); - offset += zslice * nblocksy * spr->stride[level]; + if (spr->base.target == PIPE_TEXTURE_CUBE || + spr->base.target == PIPE_TEXTURE_3D) { + offset += layer * nblocksy * spr->stride[level]; } else { - assert(face == 0); - assert(zslice == 0); + assert(layer == 0); } return offset; @@ -247,39 +242,40 @@ sp_get_tex_image_offset(const struct softpipe_resource *spr, * Get a pipe_surface "view" into a texture resource. */ static struct pipe_surface * -softpipe_get_tex_surface(struct pipe_screen *screen, - struct pipe_resource *pt, - unsigned face, unsigned level, unsigned zslice, - unsigned usage) +softpipe_create_surface(struct pipe_context *pipe, + struct pipe_resource *pt, + const struct pipe_surface *surf_tmpl) { - struct softpipe_resource *spr = softpipe_resource(pt); struct pipe_surface *ps; + unsigned level = surf_tmpl->u.tex.level; assert(level <= pt->last_level); + assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer); ps = CALLOC_STRUCT(pipe_surface); if (ps) { pipe_reference_init(&ps->reference, 1); pipe_resource_reference(&ps->texture, pt); - ps->format = pt->format; + ps->context = pipe; + ps->format = surf_tmpl->format; ps->width = u_minify(pt->width0, level); ps->height = u_minify(pt->height0, level); - ps->offset = sp_get_tex_image_offset(spr, level, face, zslice); - ps->usage = usage; + ps->usage = surf_tmpl->usage; - ps->face = face; - ps->level = level; - ps->zslice = zslice; + ps->u.tex.level = level; + ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer; + ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer; } return ps; } /** - * Free a pipe_surface which was created with softpipe_get_tex_surface(). + * Free a pipe_surface which was created with softpipe_create_surface(). */ static void -softpipe_tex_surface_destroy(struct pipe_surface *surf) +softpipe_surface_destroy(struct pipe_context *pipe, + struct pipe_surface *surf) { /* Effectively do the texture_update work here - if texture images * needed post-processing to put them into hardware layout, this is @@ -302,21 +298,21 @@ softpipe_tex_surface_destroy(struct pipe_surface *surf) */ static struct pipe_transfer * softpipe_get_transfer(struct pipe_context *pipe, - struct pipe_resource *resource, - struct pipe_subresource sr, - unsigned usage, - const struct pipe_box *box) + struct pipe_resource *resource, + unsigned level, + unsigned usage, + const struct pipe_box *box) { struct softpipe_resource *spr = softpipe_resource(resource); struct softpipe_transfer *spt; assert(resource); - assert(sr.level <= resource->last_level); + assert(level <= resource->last_level); /* make sure the requested region is in the image bounds */ - assert(box->x + box->width <= u_minify(resource->width0, sr.level)); - assert(box->y + box->height <= u_minify(resource->height0, sr.level)); - assert(box->z + box->depth <= u_minify(resource->depth0, sr.level)); + assert(box->x + box->width <= u_minify(resource->width0, level)); + assert(box->y + box->height <= u_minify(resource->height0, level)); + assert(box->z + box->depth <= (u_minify(resource->depth0, level) + resource->array_size - 1)); /* * Transfers, like other pipe operations, must happen in order, so flush the @@ -326,7 +322,7 @@ softpipe_get_transfer(struct pipe_context *pipe, boolean read_only = !(usage & PIPE_TRANSFER_WRITE); boolean do_not_block = !!(usage & PIPE_TRANSFER_DONTBLOCK); if (!softpipe_flush_resource(pipe, resource, - sr.face, sr.level, + level, box->depth > 1 ? -1 : box->z, 0, /* flush_flags */ read_only, TRUE, /* cpu_access */ @@ -343,21 +339,21 @@ softpipe_get_transfer(struct pipe_context *pipe, if (spt) { struct pipe_transfer *pt = &spt->base; enum pipe_format format = resource->format; - const unsigned hgt = u_minify(spr->base.height0, sr.level); + const unsigned hgt = u_minify(spr->base.height0, level); const unsigned nblocksy = util_format_get_nblocksy(format, hgt); pipe_resource_reference(&pt->resource, resource); - pt->sr = sr; + pt->level = level; pt->usage = usage; pt->box = *box; - pt->stride = spr->stride[sr.level]; - pt->slice_stride = pt->stride * nblocksy; + pt->stride = spr->stride[level]; + pt->layer_stride = pt->stride * nblocksy; - spt->offset = sp_get_tex_image_offset(spr, sr.level, sr.face, box->z); + spt->offset = sp_get_tex_image_offset(spr, level, box->z); spt->offset += - box->y / util_format_get_blockheight(format) * spt->base.stride + - box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); + box->y / util_format_get_blockheight(format) * spt->base.stride + + box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); return pt; } @@ -454,6 +450,7 @@ softpipe_user_buffer_create(struct pipe_screen *screen, spr->base.width0 = bytes; spr->base.height0 = 1; spr->base.depth0 = 1; + spr->base.array_size = 1; spr->userBuffer = TRUE; spr->data = ptr; @@ -471,6 +468,9 @@ softpipe_init_texture_funcs(struct pipe_context *pipe) pipe->transfer_flush_region = u_default_transfer_flush_region; pipe->transfer_inline_write = u_default_transfer_inline_write; + + pipe->create_surface = softpipe_create_surface; + pipe->surface_destroy = softpipe_surface_destroy; } @@ -483,6 +483,4 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen) screen->resource_get_handle = softpipe_resource_get_handle; screen->user_buffer_create = softpipe_user_buffer_create; - screen->get_tex_surface = softpipe_get_tex_surface; - screen->tex_surface_destroy = softpipe_tex_surface_destroy; } diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h index 6b205dc532..5603110eeb 100644 --- a/src/gallium/drivers/softpipe/sp_texture.h +++ b/src/gallium/drivers/softpipe/sp_texture.h @@ -30,10 +30,7 @@ #include "pipe/p_state.h" - - -#define SP_MAX_TEXTURE_2D_LEVELS 13 /* 4K x 4K */ -#define SP_MAX_TEXTURE_3D_LEVELS 9 /* 512 x 512 x 512 */ +#include "sp_limits.h" struct pipe_context; diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index aa76b8aa1e..480860af63 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -92,6 +92,10 @@ sp_create_tile_cache( struct pipe_context *pipe ) maxTexSize = 1 << (maxLevels - 1); assert(MAX_WIDTH >= maxTexSize); + assert(sizeof(union tile_address) == 4); + + assert((TILE_SIZE << TILE_ADDR_BITS) >= MAX_WIDTH); + tc = CALLOC_STRUCT( softpipe_tile_cache ); if (tc) { tc->pipe = pipe; @@ -170,11 +174,11 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, tc->surface = ps; if (ps) { - tc->transfer = pipe_get_transfer(pipe, ps->texture, ps->face, - ps->level, ps->zslice, - PIPE_TRANSFER_READ_WRITE | - PIPE_TRANSFER_UNSYNCHRONIZED, - 0, 0, ps->width, ps->height); + tc->transfer = pipe_get_transfer(pipe, ps->texture, + ps->u.tex.level, ps->u.tex.first_layer, + PIPE_TRANSFER_READ_WRITE | + PIPE_TRANSFER_UNSYNCHRONIZED, + 0, 0, ps->width, ps->height); tc->depth_stencil = (ps->format == PIPE_FORMAT_Z24_UNORM_S8_USCALED || ps->format == PIPE_FORMAT_Z24X8_UNORM || diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h index 4151a47c32..68140b1d2f 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tile_cache.h @@ -30,6 +30,7 @@ #include "pipe/p_compiler.h" +#include "sp_texture.h" struct softpipe_tile_cache; @@ -38,18 +39,22 @@ struct softpipe_tile_cache; /** * Cache tile size (width and height). This needs to be a power of two. */ -#define TILE_SIZE 64 +#define TILE_SIZE_LOG2 6 +#define TILE_SIZE (1 << TILE_SIZE_LOG2) -/* If we need to support > 4096, just expand this to be a 64 bit - * union, or consider tiling in Z as well. +#define TILE_ADDR_BITS (SP_MAX_TEXTURE_2D_LEVELS - 1 - TILE_SIZE_LOG2) + + +/** + * Surface tile address as a union for fast compares. */ union tile_address { struct { - unsigned x:6; /* 4096 / TILE_SIZE */ - unsigned y:6; /* 4096 / TILE_SIZE */ + unsigned x:TILE_ADDR_BITS; /* 16K / TILE_SIZE */ + unsigned y:TILE_ADDR_BITS; /* 16K / TILE_SIZE */ unsigned invalid:1; - unsigned pad:19; + unsigned pad:15; } bits; unsigned value; }; @@ -70,11 +75,6 @@ struct softpipe_cached_tile #define NUM_ENTRIES 50 -/** XXX move these */ -#define MAX_WIDTH 4096 -#define MAX_HEIGHT 4096 - - struct softpipe_tile_cache { struct pipe_context *pipe; |