diff options
Diffstat (limited to 'src/gallium/drivers/softpipe')
19 files changed, 716 insertions, 337 deletions
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index e935ce6d21..ce22f64622 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -91,10 +91,17 @@ softpipe_destroy( struct pipe_context *pipe ) if (softpipe->draw) draw_destroy( softpipe->draw ); - softpipe->quad.shade->destroy( softpipe->quad.shade ); - softpipe->quad.depth_test->destroy( softpipe->quad.depth_test ); - softpipe->quad.blend->destroy( softpipe->quad.blend ); - softpipe->quad.pstipple->destroy( softpipe->quad.pstipple ); + if (softpipe->quad.shade) + softpipe->quad.shade->destroy( softpipe->quad.shade ); + + if (softpipe->quad.depth_test) + softpipe->quad.depth_test->destroy( softpipe->quad.depth_test ); + + if (softpipe->quad.blend) + softpipe->quad.blend->destroy( softpipe->quad.blend ); + + if (softpipe->quad.pstipple) + softpipe->quad.pstipple->destroy( softpipe->quad.pstipple ); for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { sp_destroy_tile_cache(softpipe->cbuf_cache[i]); @@ -105,8 +112,8 @@ softpipe_destroy( struct pipe_context *pipe ) pipe_surface_reference(&softpipe->framebuffer.zsbuf, NULL); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - sp_destroy_tex_tile_cache(softpipe->tex_cache[i]); - pipe_sampler_view_reference(&softpipe->sampler_views[i], NULL); + sp_destroy_tex_tile_cache(softpipe->fragment_tex_cache[i]); + pipe_sampler_view_reference(&softpipe->fragment_sampler_views[i], NULL); } for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { @@ -129,6 +136,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 ); @@ -137,13 +148,13 @@ softpipe_destroy( struct pipe_context *pipe ) /** * if (the texture is being used as a framebuffer surface) - * return PIPE_REFERENCED_FOR_WRITE + * return SP_REFERENCED_FOR_WRITE * else if (the texture is a bound texture source) - * return PIPE_REFERENCED_FOR_READ + * return SP_REFERENCED_FOR_READ * else - * return PIPE_UNREFERENCED + * return SP_UNREFERENCED */ -static unsigned int +unsigned int softpipe_is_resource_referenced( struct pipe_context *pipe, struct pipe_resource *texture, unsigned level, int layer) @@ -152,40 +163,40 @@ softpipe_is_resource_referenced( struct pipe_context *pipe, unsigned i; if (texture->target == PIPE_BUFFER) - return PIPE_UNREFERENCED; + return SP_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++) { if (softpipe->framebuffer.cbufs[i] && softpipe->framebuffer.cbufs[i]->texture == texture) { - return PIPE_REFERENCED_FOR_WRITE; + return SP_REFERENCED_FOR_WRITE; } } if (softpipe->framebuffer.zsbuf && softpipe->framebuffer.zsbuf->texture == texture) { - return PIPE_REFERENCED_FOR_WRITE; + return SP_REFERENCED_FOR_WRITE; } } /* check if any of the tex_cache textures are this texture */ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - if (softpipe->tex_cache[i] && - softpipe->tex_cache[i]->texture == texture) - return PIPE_REFERENCED_FOR_READ; + if (softpipe->fragment_tex_cache[i] && + softpipe->fragment_tex_cache[i]->texture == texture) + return SP_REFERENCED_FOR_READ; } for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { if (softpipe->vertex_tex_cache[i] && softpipe->vertex_tex_cache[i]->texture == texture) - return PIPE_REFERENCED_FOR_READ; + return SP_REFERENCED_FOR_READ; } for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) { if (softpipe->geometry_tex_cache[i] && softpipe->geometry_tex_cache[i]->texture == texture) - return PIPE_REFERENCED_FOR_READ; + return SP_REFERENCED_FOR_READ; } - return PIPE_UNREFERENCED; + return SP_UNREFERENCED; } @@ -219,7 +230,7 @@ softpipe_create_context( struct pipe_screen *screen, softpipe->use_sse = FALSE; #endif - softpipe->dump_fs = debug_get_bool_option( "GALLIUM_DUMP_FS", FALSE ); + softpipe->dump_fs = debug_get_bool_option( "SOFTPIPE_DUMP_FS", FALSE ); softpipe->dump_gs = debug_get_bool_option( "SOFTPIPE_DUMP_GS", FALSE ); softpipe->pipe.winsys = NULL; @@ -244,9 +255,7 @@ softpipe_create_context( struct pipe_screen *screen, softpipe->pipe.draw_stream_output = softpipe_draw_stream_output; softpipe->pipe.clear = softpipe_clear; - softpipe->pipe.flush = softpipe_flush; - - softpipe->pipe.is_resource_referenced = softpipe_is_resource_referenced; + softpipe->pipe.flush = softpipe_flush_wrapped; softpipe->pipe.render_condition = softpipe_render_condition; @@ -258,13 +267,22 @@ softpipe_create_context( struct pipe_screen *screen, softpipe->cbuf_cache[i] = sp_create_tile_cache( &softpipe->pipe ); softpipe->zsbuf_cache = sp_create_tile_cache( &softpipe->pipe ); - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - softpipe->tex_cache[i] = sp_create_tex_tile_cache( &softpipe->pipe ); + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + softpipe->fragment_tex_cache[i] = sp_create_tex_tile_cache( &softpipe->pipe ); + if (!softpipe->fragment_tex_cache[i]) + goto fail; + } + for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { softpipe->vertex_tex_cache[i] = sp_create_tex_tile_cache( &softpipe->pipe ); + if (!softpipe->vertex_tex_cache[i]) + goto fail; } + for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) { softpipe->geometry_tex_cache[i] = sp_create_tex_tile_cache( &softpipe->pipe ); + if (!softpipe->geometry_tex_cache[i]) + goto fail; } softpipe->fs_machine = tgsi_exec_machine_create(); @@ -295,7 +313,7 @@ softpipe_create_context( struct pipe_screen *screen, (struct tgsi_sampler **) softpipe->tgsi.geom_samplers_list); - if (debug_get_bool_option( "SP_NO_RAST", FALSE )) + if (debug_get_bool_option( "SOFTPIPE_NO_RAST", FALSE )) softpipe->no_rast = TRUE; softpipe->vbuf_backend = sp_create_vbuf_backend(softpipe); diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 9361a3df09..a572ee8cf0 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -58,7 +58,7 @@ struct softpipe_context { /** Constant state objects */ struct pipe_blend_state *blend; - struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_state *fragment_samplers[PIPE_MAX_SAMPLERS]; struct pipe_sampler_state *vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS]; struct pipe_sampler_state *geometry_samplers[PIPE_MAX_GEOMETRY_SAMPLERS]; struct pipe_depth_stencil_alpha_state *depth_stencil; @@ -77,7 +77,7 @@ struct softpipe_context { struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; - struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS]; struct pipe_sampler_view *geometry_sampler_views[PIPE_MAX_GEOMETRY_SAMPLERS]; struct pipe_viewport_state viewport; @@ -91,8 +91,8 @@ struct softpipe_context { } so_target; struct pipe_query_data_so_statistics so_stats; - unsigned num_samplers; - unsigned num_sampler_views; + unsigned num_fragment_samplers; + unsigned num_fragment_sampler_views; unsigned num_vertex_samplers; unsigned num_vertex_sampler_views; unsigned num_geometry_samplers; @@ -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; @@ -174,7 +174,7 @@ struct softpipe_context { struct softpipe_tile_cache *zsbuf_cache; unsigned tex_timestamp; - struct softpipe_tex_tile_cache *tex_cache[PIPE_MAX_SAMPLERS]; + struct softpipe_tex_tile_cache *fragment_tex_cache[PIPE_MAX_SAMPLERS]; struct softpipe_tex_tile_cache *vertex_tex_cache[PIPE_MAX_VERTEX_SAMPLERS]; struct softpipe_tex_tile_cache *geometry_tex_cache[PIPE_MAX_GEOMETRY_SAMPLERS]; @@ -192,10 +192,19 @@ 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 ); +#define SP_UNREFERENCED 0 +#define SP_REFERENCED_FOR_READ (1 << 0) +#define SP_REFERENCED_FOR_WRITE (1 << 1) + +unsigned int +softpipe_is_resource_referenced( struct pipe_context *pipe, + struct pipe_resource *texture, + unsigned level, int layer); + #endif /* SP_CONTEXT_H */ diff --git a/src/gallium/drivers/softpipe/sp_fence.c b/src/gallium/drivers/softpipe/sp_fence.c index 66c5214113..7b79a0df4e 100644 --- a/src/gallium/drivers/softpipe/sp_fence.c +++ b/src/gallium/drivers/softpipe/sp_fence.c @@ -41,23 +41,22 @@ softpipe_fence_reference(struct pipe_screen *screen, } -static int +static boolean softpipe_fence_signalled(struct pipe_screen *screen, - struct pipe_fence_handle *fence, - unsigned flags) + struct pipe_fence_handle *fence) { assert(!fence); - return 0; + return TRUE; } -static int +static boolean softpipe_fence_finish(struct pipe_screen *screen, struct pipe_fence_handle *fence, - unsigned flags) + uint64_t timeout) { assert(!fence); - return 0; + return TRUE; } diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index 3a09ee8b4f..b7f283bf27 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -42,7 +42,7 @@ void softpipe_flush( struct pipe_context *pipe, - unsigned flags, + unsigned flags, struct pipe_fence_handle **fence ) { struct softpipe_context *softpipe = softpipe_context(pipe); @@ -50,9 +50,9 @@ softpipe_flush( struct pipe_context *pipe, draw_flush(softpipe->draw); - if (1 || (flags & PIPE_FLUSH_TEXTURE_CACHE)) { - for (i = 0; i < softpipe->num_sampler_views; i++) { - sp_flush_tex_tile_cache(softpipe->tex_cache[i]); + if (1 || (flags & SP_FLUSH_TEXTURE_CACHE)) { + for (i = 0; i < softpipe->num_fragment_sampler_views; i++) { + sp_flush_tex_tile_cache(softpipe->fragment_tex_cache[i]); } for (i = 0; i < softpipe->num_vertex_sampler_views; i++) { sp_flush_tex_tile_cache(softpipe->vertex_tex_cache[i]); @@ -62,34 +62,27 @@ softpipe_flush( struct pipe_context *pipe, } } - 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]); - - /* Need this call for hardware buffers before swapbuffers. - * - * there should probably be another/different flush-type function - * that's called before swapbuffers because we don't always want - * 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; - } + /* 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); + + softpipe->dirty_render_cache = FALSE; + + /* Need this call for hardware buffers before swapbuffers. + * + * there should probably be another/different flush-type function + * that's called before swapbuffers because we don't always want + * to unmap surfaces when flushing. + */ + softpipe_unmap_transfers(softpipe); /* Enable to dump BMPs of the color/depth buffers each frame */ #if 0 @@ -108,6 +101,13 @@ softpipe_flush( struct pipe_context *pipe, *fence = NULL; } +void +softpipe_flush_wrapped( struct pipe_context *pipe, + struct pipe_fence_handle **fence ) +{ + softpipe_flush(pipe, SP_FLUSH_TEXTURE_CACHE, fence); +} + /** * Flush context if necessary. @@ -129,21 +129,18 @@ softpipe_flush_resource(struct pipe_context *pipe, { unsigned referenced; - referenced = pipe->is_resource_referenced(pipe, texture, level, layer); + referenced = softpipe_is_resource_referenced(pipe, texture, level, layer); - if ((referenced & PIPE_REFERENCED_FOR_WRITE) || - ((referenced & PIPE_REFERENCED_FOR_READ) && !read_only)) { + if ((referenced & SP_REFERENCED_FOR_WRITE) || + ((referenced & SP_REFERENCED_FOR_READ) && !read_only)) { /* * TODO: The semantics of these flush flags are too obtuse. They should * disappear and the pipe driver should just ensure that all visible * side-effects happen when they need to happen. */ - if (referenced & PIPE_REFERENCED_FOR_WRITE) - flush_flags |= PIPE_FLUSH_RENDER_CACHE; - - if (referenced & PIPE_REFERENCED_FOR_READ) - flush_flags |= PIPE_FLUSH_TEXTURE_CACHE; + if (referenced & SP_REFERENCED_FOR_READ) + flush_flags |= SP_FLUSH_TEXTURE_CACHE; if (cpu_access) { /* @@ -155,14 +152,15 @@ softpipe_flush_resource(struct pipe_context *pipe, if (do_not_block) return FALSE; - pipe->flush(pipe, flush_flags, &fence); + softpipe_flush(pipe, flush_flags, &fence); if (fence) { /* * This is for illustrative purposes only, as softpipe does not * have fences. */ - pipe->screen->fence_finish(pipe->screen, fence, 0); + pipe->screen->fence_finish(pipe->screen, fence, + PIPE_TIMEOUT_INFINITE); pipe->screen->fence_reference(pipe->screen, &fence, NULL); } } else { @@ -170,7 +168,7 @@ softpipe_flush_resource(struct pipe_context *pipe, * Just flush. */ - pipe->flush(pipe, flush_flags, NULL); + softpipe_flush(pipe, flush_flags, NULL); } } diff --git a/src/gallium/drivers/softpipe/sp_flush.h b/src/gallium/drivers/softpipe/sp_flush.h index 22a5ceeb9e..ab01c249ab 100644 --- a/src/gallium/drivers/softpipe/sp_flush.h +++ b/src/gallium/drivers/softpipe/sp_flush.h @@ -33,10 +33,17 @@ struct pipe_context; struct pipe_fence_handle; +#define SP_FLUSH_TEXTURE_CACHE 0x2 + void -softpipe_flush(struct pipe_context *pipe, unsigned flags, +softpipe_flush(struct pipe_context *pipe, + unsigned flags, struct pipe_fence_handle **fence); +void +softpipe_flush_wrapped( struct pipe_context *pipe, + struct pipe_fence_handle **fence ); + boolean softpipe_flush_resource(struct pipe_context *pipe, struct pipe_resource *texture, 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 cbdea19af4..48aabc18da 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -123,6 +123,11 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) return 0; case PIPE_CAP_SHADER_STENCIL_EXPORT: return 1; + case PIPE_CAP_TGSI_INSTANCEID: + case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: + return 1; + case PIPE_CAP_ARRAY_TEXTURES: + return 1; default: return 0; } @@ -175,15 +180,16 @@ softpipe_is_format_supported( struct pipe_screen *screen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned bind, - unsigned geom_flags ) + unsigned bind) { struct sw_winsys *winsys = softpipe_screen(screen)->winsys; const struct util_format_description *format_desc; assert(target == PIPE_BUFFER || target == PIPE_TEXTURE_1D || + target == PIPE_TEXTURE_1D_ARRAY || target == PIPE_TEXTURE_2D || + target == PIPE_TEXTURE_2D_ARRAY || target == PIPE_TEXTURE_RECT || target == PIPE_TEXTURE_3D || target == PIPE_TEXTURE_CUBE); diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 5d727dc00d..0ce28f4c6e 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -575,7 +575,7 @@ setup_fragcoord_coeff(struct setup_context *setup, uint slot) setup->coef[slot].dady[0] = 0.0; /*Y*/ setup->coef[slot].a0[1] = - (spfs->origin_lower_left ? setup->softpipe->framebuffer.height : 0) + (spfs->origin_lower_left ? setup->softpipe->framebuffer.height-1 : 0) + (spfs->pixel_center_integer ? 0.0 : 0.5); setup->coef[slot].dadx[1] = 0.0; setup->coef[slot].dady[1] = spfs->origin_lower_left ? -1.0 : 1.0; 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..f9590eb0b2 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -197,11 +197,11 @@ 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]; - if (tc->texture) { + struct softpipe_tex_tile_cache *tc = softpipe->fragment_tex_cache[i]; + if (tc && tc->texture) { struct softpipe_resource *spt = softpipe_resource(tc->texture); if (spt->timestamp != tc->timestamp) { sp_tex_tile_cache_validate_texture( tc ); @@ -216,7 +216,7 @@ update_tgsi_samplers( struct softpipe_context *softpipe ) for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { struct softpipe_tex_tile_cache *tc = softpipe->vertex_tex_cache[i]; - if (tc->texture) { + if (tc && tc->texture) { struct softpipe_resource *spt = softpipe_resource(tc->texture); if (spt->timestamp != tc->timestamp) { @@ -229,7 +229,7 @@ update_tgsi_samplers( struct softpipe_context *softpipe ) for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) { struct softpipe_tex_tile_cache *tc = softpipe->geometry_tex_cache[i]; - if (tc->texture) { + if (tc && tc->texture) { struct softpipe_resource *spt = softpipe_resource(tc->texture); if (spt->timestamp != tc->timestamp) { diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index b59fbc33ed..60331bc497 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,15 +60,15 @@ 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; } static void -softpipe_bind_sampler_states(struct pipe_context *pipe, - unsigned num, void **sampler) +softpipe_bind_fragment_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) { struct softpipe_context *softpipe = softpipe_context(pipe); unsigned i; @@ -76,18 +76,18 @@ softpipe_bind_sampler_states(struct pipe_context *pipe, assert(num <= PIPE_MAX_SAMPLERS); /* Check for no-op */ - if (num == softpipe->num_samplers && - !memcmp(softpipe->sampler, sampler, num * sizeof(void *))) + if (num == softpipe->num_fragment_samplers && + !memcmp(softpipe->fragment_samplers, sampler, num * sizeof(void *))) return; draw_flush(softpipe->draw); for (i = 0; i < num; ++i) - softpipe->sampler[i] = sampler[i]; + softpipe->fragment_samplers[i] = sampler[i]; for (i = num; i < PIPE_MAX_SAMPLERS; ++i) - softpipe->sampler[i] = NULL; + softpipe->fragment_samplers[i] = NULL; - softpipe->num_samplers = num; + softpipe->num_fragment_samplers = num; softpipe->dirty |= SP_NEW_SAMPLER; } @@ -181,9 +181,9 @@ softpipe_sampler_view_destroy(struct pipe_context *pipe, static void -softpipe_set_sampler_views(struct pipe_context *pipe, - unsigned num, - struct pipe_sampler_view **views) +softpipe_set_fragment_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) { struct softpipe_context *softpipe = softpipe_context(pipe); uint i; @@ -191,8 +191,9 @@ softpipe_set_sampler_views(struct pipe_context *pipe, assert(num <= PIPE_MAX_SAMPLERS); /* Check for no-op */ - if (num == softpipe->num_sampler_views && - !memcmp(softpipe->sampler_views, views, num * sizeof(struct pipe_sampler_view *))) + if (num == softpipe->num_fragment_sampler_views && + !memcmp(softpipe->fragment_sampler_views, views, + num * sizeof(struct pipe_sampler_view *))) return; draw_flush(softpipe->draw); @@ -200,11 +201,11 @@ softpipe_set_sampler_views(struct pipe_context *pipe, for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { struct pipe_sampler_view *view = i < num ? views[i] : NULL; - pipe_sampler_view_reference(&softpipe->sampler_views[i], view); - sp_tex_tile_cache_set_sampler_view(softpipe->tex_cache[i], view); + pipe_sampler_view_reference(&softpipe->fragment_sampler_views[i], view); + sp_tex_tile_cache_set_sampler_view(softpipe->fragment_tex_cache[i], view); } - softpipe->num_sampler_views = num; + softpipe->num_fragment_sampler_views = num; softpipe->dirty |= SP_NEW_TEXTURE; } @@ -277,23 +278,23 @@ 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_resource *resource, + struct pipe_sampler_view *view, unsigned processor ) { - struct softpipe_resource *sp_texture = softpipe_resource(resource); - struct sp_sampler_varient *v = NULL; + struct softpipe_resource *sp_texture = softpipe_resource(view->texture); + 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; @@ -338,65 +343,47 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe) */ for (i = 0; i <= softpipe->vs->max_sampler; i++) { if (softpipe->vertex_samplers[i]) { - struct pipe_resource *texture = NULL; - - if (softpipe->vertex_sampler_views[i]) { - texture = softpipe->vertex_sampler_views[i]->texture; - } - softpipe->tgsi.vert_samplers_list[i] = - get_sampler_varient( i, + get_sampler_variant( i, sp_sampler(softpipe->vertex_samplers[i]), - texture, + softpipe->vertex_sampler_views[i], TGSI_PROCESSOR_VERTEX ); - sp_sampler_varient_bind_texture( softpipe->tgsi.vert_samplers_list[i], - softpipe->vertex_tex_cache[i], - texture ); + sp_sampler_variant_bind_view( softpipe->tgsi.vert_samplers_list[i], + softpipe->vertex_tex_cache[i], + softpipe->vertex_sampler_views[i] ); } } if (softpipe->gs) { for (i = 0; i <= softpipe->gs->max_sampler; i++) { if (softpipe->geometry_samplers[i]) { - struct pipe_resource *texture = NULL; - - if (softpipe->geometry_sampler_views[i]) { - texture = softpipe->geometry_sampler_views[i]->texture; - } - softpipe->tgsi.geom_samplers_list[i] = - get_sampler_varient( + get_sampler_variant( i, sp_sampler(softpipe->geometry_samplers[i]), - texture, + softpipe->geometry_sampler_views[i], TGSI_PROCESSOR_GEOMETRY ); - sp_sampler_varient_bind_texture( + sp_sampler_variant_bind_view( softpipe->tgsi.geom_samplers_list[i], softpipe->geometry_tex_cache[i], - texture ); + softpipe->geometry_sampler_views[i] ); } } } for (i = 0; i <= softpipe->fs->info.file_max[TGSI_FILE_SAMPLER]; i++) { - if (softpipe->sampler[i]) { - struct pipe_resource *texture = NULL; - - if (softpipe->sampler_views[i]) { - texture = softpipe->sampler_views[i]->texture; - } - + if (softpipe->fragment_samplers[i]) { softpipe->tgsi.frag_samplers_list[i] = - get_sampler_varient( i, - sp_sampler(softpipe->sampler[i]), - texture, + get_sampler_variant( i, + sp_sampler(softpipe->fragment_samplers[i]), + softpipe->fragment_sampler_views[i], TGSI_PROCESSOR_FRAGMENT ); - sp_sampler_varient_bind_texture( softpipe->tgsi.frag_samplers_list[i], - softpipe->tex_cache[i], - texture ); + sp_sampler_variant_bind_view( softpipe->tgsi.frag_samplers_list[i], + softpipe->fragment_tex_cache[i], + softpipe->fragment_sampler_views[i] ); } } } @@ -406,11 +393,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 ); @@ -421,12 +408,12 @@ void softpipe_init_sampler_funcs(struct pipe_context *pipe) { pipe->create_sampler_state = softpipe_create_sampler_state; - pipe->bind_fragment_sampler_states = softpipe_bind_sampler_states; + pipe->bind_fragment_sampler_states = softpipe_bind_fragment_sampler_states; pipe->bind_vertex_sampler_states = softpipe_bind_vertex_sampler_states; pipe->bind_geometry_sampler_states = softpipe_bind_geometry_sampler_states; pipe->delete_sampler_state = softpipe_delete_sampler_state; - pipe->set_fragment_sampler_views = softpipe_set_sampler_views; + pipe->set_fragment_sampler_views = softpipe_set_fragment_sampler_views; pipe->set_vertex_sampler_views = softpipe_set_vertex_sampler_views; pipe->set_geometry_sampler_views = softpipe_set_geometry_sampler_views; diff --git a/src/gallium/drivers/softpipe/sp_state_shader.c b/src/gallium/drivers/softpipe/sp_state_shader.c index 7fff338cce..3dec5de3cc 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; @@ -89,8 +91,6 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs) { struct softpipe_context *softpipe = softpipe_context(pipe); - draw_flush(softpipe->draw); - if (softpipe->fs == fs) return; diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c index 7d8055f2ba..aa0b333c7a 100644 --- a/src/gallium/drivers/softpipe/sp_state_vertex.c +++ b/src/gallium/drivers/softpipe/sp_state_vertex.c @@ -33,6 +33,8 @@ #include "sp_state.h" #include "util/u_memory.h" +#include "util/u_inlines.h" +#include "util/u_transfer.h" #include "draw/draw_context.h" @@ -84,8 +86,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; @@ -117,4 +120,5 @@ softpipe_init_vertex_funcs(struct pipe_context *pipe) pipe->set_vertex_buffers = softpipe_set_vertex_buffers; pipe->set_index_buffer = softpipe_set_index_buffer; + pipe->redefine_user_buffer = u_default_redefine_user_buffer; } diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 2eac4c7a82..c09ce19559 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -539,18 +539,31 @@ wrap_linear_unorm_clamp_to_edge(const float s[4], unsigned size, } +/** + * Do coordinate to array index conversion. For array textures. + */ +static INLINE void +wrap_array_layer(const float coord[4], unsigned size, int layer[4]) +{ + uint ch; + for (ch = 0; ch < 4; ch++) { + int c = util_ifloor(coord[ch] + 0.5F); + layer[ch] = CLAMP(c, 0, size - 1); + } +} + /** * Examine the quad's texture coordinates to compute the partial * 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]) { - const struct pipe_resource *texture = samp->texture; + const struct pipe_resource *texture = samp->view->texture; 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->width0; @@ -560,12 +573,12 @@ 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]) { - const struct pipe_resource *texture = samp->texture; + const struct pipe_resource *texture = samp->view->texture; 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]); @@ -579,12 +592,12 @@ 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]) { - const struct pipe_resource *texture = samp->texture; + const struct pipe_resource *texture = samp->view->texture; 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]); @@ -608,7 +621,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 +647,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,16 +664,15 @@ 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; + const struct pipe_resource *texture = samp->view->texture; unsigned level = addr.bits.level; 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 +683,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 +707,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 +722,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 +736,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,17 +757,16 @@ 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; + const struct pipe_resource *texture = samp->view->texture; unsigned level = addr.bits.level; 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 ); @@ -763,6 +774,43 @@ get_texel_3d(const struct sp_sampler_varient *samp, } +/* Get texel pointer for 1D array texture */ +static INLINE const float * +get_texel_1d_array(const struct sp_sampler_variant *samp, + union tex_tile_address addr, int x, int y) +{ + const struct pipe_resource *texture = samp->view->texture; + unsigned level = addr.bits.level; + + if (x < 0 || x >= (int) u_minify(texture->width0, level)) { + return samp->sampler->border_color; + } + else { + return get_texel_2d_no_border(samp, addr, x, y); + } +} + + +/* Get texel pointer for 2D array texture */ +static INLINE const float * +get_texel_2d_array(const struct sp_sampler_variant *samp, + union tex_tile_address addr, int x, int y, int layer) +{ + const struct pipe_resource *texture = samp->view->texture; + unsigned level = addr.bits.level; + + assert(layer < texture->array_size); + + if (x < 0 || x >= (int) u_minify(texture->width0, level) || + y < 0 || y >= (int) u_minify(texture->height0, level)) { + return samp->sampler->border_color; + } + else { + return get_texel_3d_no_border(samp, addr, x, y, layer); + } +} + + /** * Given the logbase2 of a mipmap's base level size and a mipmap level, * return the size (in texels) of that mipmap level. @@ -800,7 +848,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 +911,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 +955,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,8 +1008,8 @@ 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 pipe_resource *texture = samp->texture; + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); + const struct pipe_resource *texture = samp->view->texture; unsigned level0, j; int width; int x[4]; @@ -992,6 +1040,47 @@ img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler, static void +img_filter_1d_array_nearest(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]) +{ + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); + const struct pipe_resource *texture = samp->view->texture; + unsigned level0, j; + int width; + int x[4], layer[4]; + union tex_tile_address addr; + + level0 = samp->level; + width = u_minify(texture->width0, level0); + + assert(width > 0); + + addr.value = 0; + addr.bits.level = samp->level; + + samp->nearest_texcoord_s(s, width, x); + wrap_array_layer(t, texture->array_size, layer); + + for (j = 0; j < QUAD_SIZE; j++) { + const float *out = get_texel_1d_array(samp, addr, x[j], layer[j]); + int c; + for (c = 0; c < 4; c++) { + rgba[c][j] = out[c]; + } + } + + if (DEBUG_TEX) { + print_sample(__FUNCTION__, rgba); + } +} + + +static void img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], @@ -1000,8 +1089,8 @@ 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 pipe_resource *texture = samp->texture; + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); + const struct pipe_resource *texture = samp->view->texture; unsigned level0, j; int width, height; int x[4], y[4]; @@ -1035,6 +1124,50 @@ img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler, } +static void +img_filter_2d_array_nearest(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]) +{ + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); + const struct pipe_resource *texture = samp->view->texture; + unsigned level0, j; + int width, height; + int x[4], y[4], layer[4]; + union tex_tile_address addr; + + level0 = samp->level; + width = u_minify(texture->width0, level0); + height = u_minify(texture->height0, level0); + + assert(width > 0); + assert(height > 0); + + addr.value = 0; + addr.bits.level = samp->level; + + samp->nearest_texcoord_s(s, width, x); + samp->nearest_texcoord_t(t, height, y); + wrap_array_layer(p, texture->array_size, layer); + + for (j = 0; j < QUAD_SIZE; j++) { + const float *out = get_texel_2d_array(samp, addr, x[j], y[j], layer[j]); + int c; + for (c = 0; c < 4; c++) { + rgba[c][j] = out[c]; + } + } + + if (DEBUG_TEX) { + print_sample(__FUNCTION__, rgba); + } +} + + static INLINE union tex_tile_address face(union tex_tile_address addr, unsigned face ) { @@ -1052,8 +1185,8 @@ 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 pipe_resource *texture = samp->texture; + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); + const struct pipe_resource *texture = samp->view->texture; const unsigned *faces = samp->faces; /* zero when not cube-mapping */ unsigned level0, j; int width, height; @@ -1096,8 +1229,8 @@ 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 pipe_resource *texture = samp->texture; + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); + const struct pipe_resource *texture = samp->view->texture; unsigned level0, j; int width, height, depth; int x[4], y[4], z[4]; @@ -1138,8 +1271,8 @@ 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 pipe_resource *texture = samp->texture; + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); + const struct pipe_resource *texture = samp->view->texture; unsigned level0, j; int width; int x0[4], x1[4]; @@ -1170,6 +1303,47 @@ img_filter_1d_linear(struct tgsi_sampler *tgsi_sampler, static void +img_filter_1d_array_linear(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]) +{ + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); + const struct pipe_resource *texture = samp->view->texture; + unsigned level0, j; + int width; + int x0[4], x1[4], layer[4]; + float xw[4]; /* weights */ + union tex_tile_address addr; + + level0 = samp->level; + width = u_minify(texture->width0, level0); + + assert(width > 0); + + addr.value = 0; + addr.bits.level = samp->level; + + samp->linear_texcoord_s(s, width, x0, x1, xw); + wrap_array_layer(t, texture->array_size, layer); + + for (j = 0; j < QUAD_SIZE; j++) { + const float *tx0 = get_texel_1d_array(samp, addr, x0[j], layer[j]); + const float *tx1 = get_texel_1d_array(samp, addr, x1[j], layer[j]); + int c; + + /* interpolate R, G, B, A */ + for (c = 0; c < 4; c++) { + 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], const float t[QUAD_SIZE], @@ -1178,8 +1352,8 @@ 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 pipe_resource *texture = samp->texture; + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); + const struct pipe_resource *texture = samp->view->texture; unsigned level0, j; int width, height; int x0[4], y0[4], x1[4], y1[4]; @@ -1217,6 +1391,54 @@ img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler, static void +img_filter_2d_array_linear(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]) +{ + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); + const struct pipe_resource *texture = samp->view->texture; + unsigned level0, j; + int width, height; + int x0[4], y0[4], x1[4], y1[4], layer[4]; + float xw[4], yw[4]; /* weights */ + union tex_tile_address addr; + + level0 = samp->level; + width = u_minify(texture->width0, level0); + height = u_minify(texture->height0, level0); + + assert(width > 0); + assert(height > 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); + wrap_array_layer(p, texture->array_size, layer); + + for (j = 0; j < QUAD_SIZE; j++) { + const float *tx0 = get_texel_2d_array(samp, addr, x0[j], y0[j], layer[j]); + const float *tx1 = get_texel_2d_array(samp, addr, x1[j], y0[j], layer[j]); + const float *tx2 = get_texel_2d_array(samp, addr, x0[j], y1[j], layer[j]); + const float *tx3 = get_texel_2d_array(samp, addr, x1[j], y1[j], layer[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_cube_linear(struct tgsi_sampler *tgsi_sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], @@ -1225,8 +1447,8 @@ 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 pipe_resource *texture = samp->texture; + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); + const struct pipe_resource *texture = samp->view->texture; const unsigned *faces = samp->faces; /* zero when not cube-mapping */ unsigned level0, j; int width, height; @@ -1274,8 +1496,8 @@ 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 pipe_resource *texture = samp->texture; + const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); + const struct pipe_resource *texture = samp->view->texture; unsigned level0, j; int width, height, depth; int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4]; @@ -1350,8 +1572,8 @@ 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); - const struct pipe_resource *texture = samp->texture; + struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); + const struct pipe_resource *texture = samp->view->texture; int level0; float lambda; float lod[QUAD_SIZE]; @@ -1417,8 +1639,8 @@ 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); - const struct pipe_resource *texture = samp->texture; + struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); + const struct pipe_resource *texture = samp->view->texture; float lambda; float lod[QUAD_SIZE]; @@ -1460,7 +1682,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,8 +1723,8 @@ 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); - const struct pipe_resource *texture = samp->texture; + struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); + const struct pipe_resource *texture = samp->view->texture; int level0; float lambda; float lod[QUAD_SIZE]; @@ -1569,10 +1791,11 @@ 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; + float pc0, pc1, pc2, pc3; samp->mip_filter(tgsi_sampler, s, t, p, c0, control, rgba); @@ -1582,43 +1805,48 @@ sample_compare(struct tgsi_sampler *tgsi_sampler, * RGBA channels. We look at the red channel here. */ + pc0 = CLAMP(p[0], 0.0F, 1.0F); + pc1 = CLAMP(p[1], 0.0F, 1.0F); + pc2 = CLAMP(p[2], 0.0F, 1.0F); + pc3 = CLAMP(p[3], 0.0F, 1.0F); + /* 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]; + k0 = pc0 < rgba[0][0]; + k1 = pc1 < rgba[0][1]; + k2 = pc2 < rgba[0][2]; + k3 = pc3 < 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]; + k0 = pc0 <= rgba[0][0]; + k1 = pc1 <= rgba[0][1]; + k2 = pc2 <= rgba[0][2]; + k3 = pc3 <= 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]; + k0 = pc0 > rgba[0][0]; + k1 = pc1 > rgba[0][1]; + k2 = pc2 > rgba[0][2]; + k3 = pc3 > 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]; + k0 = pc0 >= rgba[0][0]; + k1 = pc1 >= rgba[0][1]; + k2 = pc2 >= rgba[0][2]; + k3 = pc3 >= 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]; + k0 = pc0 == rgba[0][0]; + k1 = pc1 == rgba[0][1]; + k2 = pc2 == rgba[0][2]; + k3 = pc3 == 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]; + k0 = pc0 != rgba[0][0]; + k1 = pc1 != rgba[0][1]; + k2 = pc2 != rgba[0][2]; + k3 = pc3 != rgba[0][3]; break; case PIPE_FUNC_ALWAYS: k0 = k1 = k2 = k3 = 1; @@ -1656,7 +1884,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 +1959,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) @@ -1828,8 +2136,10 @@ get_lambda_func(const union sp_sampler_key key) switch (key.bits.target) { case PIPE_TEXTURE_1D: + case PIPE_TEXTURE_1D_ARRAY: return compute_lambda_1d; case PIPE_TEXTURE_2D: + case PIPE_TEXTURE_2D_ARRAY: case PIPE_TEXTURE_RECT: case PIPE_TEXTURE_CUBE: return compute_lambda_2d; @@ -1854,6 +2164,12 @@ get_img_filter(const union sp_sampler_key key, else return img_filter_1d_linear; break; + case PIPE_TEXTURE_1D_ARRAY: + if (filter == PIPE_TEX_FILTER_NEAREST) + return img_filter_1d_array_nearest; + else + return img_filter_1d_array_linear; + break; case PIPE_TEXTURE_2D: case PIPE_TEXTURE_RECT: /* Try for fast path: @@ -1889,6 +2205,12 @@ get_img_filter(const union sp_sampler_key key, else return img_filter_2d_linear; break; + case PIPE_TEXTURE_2D_ARRAY: + if (filter == PIPE_TEX_FILTER_NEAREST) + return img_filter_2d_array_nearest; + else + return img_filter_2d_array_linear; + break; case PIPE_TEXTURE_CUBE: if (filter == PIPE_TEX_FILTER_NEAREST) return img_filter_cube_nearest; @@ -1909,16 +2231,17 @@ 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, - struct softpipe_tex_tile_cache *tex_cache, - const struct pipe_resource *texture ) +sp_sampler_variant_bind_view( struct sp_sampler_variant *samp, + struct softpipe_tex_tile_cache *tex_cache, + const struct pipe_sampler_view *view ) { const struct pipe_sampler_state *sampler = samp->sampler; + const struct pipe_resource *texture = view->texture; - samp->texture = texture; + samp->view = view; samp->cache = tex_cache; samp->xpot = util_unsigned_logbase2( texture->width0 ); samp->ypot = util_unsigned_logbase2( texture->height0 ); @@ -1927,20 +2250,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 +2338,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 +2349,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..f0b867edc6 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 */ @@ -85,7 +89,7 @@ struct sp_sampler_varient /* Currently bound texture: */ - const struct pipe_resource *texture; + const struct pipe_sampler_view *view; struct softpipe_tex_tile_cache *cache; unsigned processor; @@ -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, - struct softpipe_tex_tile_cache *tex_cache, - const struct pipe_resource *tex ); +void sp_sampler_variant_bind_view( struct sp_sampler_variant *variant, + struct softpipe_tex_tile_cache *tex_cache, + const struct pipe_sampler_view *view ); -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 1393164150..e589ee7c84 100644 --- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c @@ -251,6 +251,7 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc, tc->tex_level != addr.bits.level || tc->tex_z != addr.bits.z) { /* get new transfer (view into texture) */ + unsigned width, height, layer; if (tc->tex_trans) { if (tc->tex_trans_map) { @@ -262,14 +263,22 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc, tc->tex_trans = NULL; } + width = u_minify(tc->texture->width0, addr.bits.level); + if (tc->texture->target == PIPE_TEXTURE_1D_ARRAY) { + height = tc->texture->array_size; + layer = 0; + } + else { + height = u_minify(tc->texture->height0, addr.bits.level); + layer = addr.bits.face + addr.bits.z; + } + tc->tex_trans = pipe_get_transfer(tc->pipe, tc->texture, addr.bits.level, - addr.bits.face + addr.bits.z, + layer, PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED, - 0, 0, - u_minify(tc->texture->width0, addr.bits.level), - u_minify(tc->texture->height0, addr.bits.level)); + 0, 0, width, height); tc->tex_trans_map = tc->pipe->transfer_map(tc->pipe, tc->tex_trans); @@ -278,45 +287,21 @@ 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) */ - 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, - tc->format, - (float *) tile->data.color); + /* Get tile from the transfer (view into texture), explicitly passing + * the image format. + */ + pipe_get_tile_rgba_format(tc->pipe, + tc->tex_trans, + addr.bits.x * TILE_SIZE, + addr.bits.y * TILE_SIZE, + TILE_SIZE, + TILE_SIZE, + 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 e0b66bf3f7..9bced37990 100644 --- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h @@ -92,11 +92,9 @@ struct softpipe_tex_tile_cache unsigned swizzle_g; unsigned swizzle_b; unsigned swizzle_a; - unsigned format; + enum pipe_format format; struct softpipe_tex_cached_tile *last_tile; /**< most recently retrieved tile */ - - float swz_border_color[4]; /**< swizzled border color */ }; @@ -161,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 509d9982b1..95374c34ec 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -62,13 +62,21 @@ softpipe_resource_layout(struct pipe_screen *screen, unsigned buffer_size = 0; for (level = 0; level <= pt->last_level; level++) { + unsigned slices; + + if (pt->target == PIPE_TEXTURE_CUBE) + slices = 6; + else if (pt->target == PIPE_TEXTURE_3D) + slices = depth; + else + slices = pt->array_size; + spr->stride[level] = util_format_get_stride(pt->format, width); spr->level_offset[level] = buffer_size; buffer_size += (util_format_get_nblocksy(pt->format, height) * - ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * - spr->stride[level]); + slices * spr->stride[level]); width = u_minify(width, 1); height = u_minify(height, 1); @@ -227,9 +235,13 @@ sp_get_tex_image_offset(const struct softpipe_resource *spr, unsigned offset = spr->level_offset[level]; if (spr->base.target == PIPE_TEXTURE_CUBE || - spr->base.target == PIPE_TEXTURE_3D) { + spr->base.target == PIPE_TEXTURE_3D || + spr->base.target == PIPE_TEXTURE_2D_ARRAY) { offset += layer * nblocksy * spr->stride[level]; } + else if (spr->base.target == PIPE_TEXTURE_1D_ARRAY) { + offset += layer * spr->stride[level]; + } else { assert(layer == 0); } @@ -292,7 +304,7 @@ softpipe_surface_destroy(struct pipe_context *pipe, * a resource object. * \param pipe rendering context * \param resource the resource to transfer in/out of - * \param sr indicates cube face or 3D texture slice + * \param level which mipmap level * \param usage bitmask of PIPE_TRANSFER_x flags * \param box the 1D/2D/3D region of interest */ @@ -311,8 +323,21 @@ softpipe_get_transfer(struct pipe_context *pipe, /* make sure the requested region is in the image bounds */ 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)); + if (resource->target == PIPE_TEXTURE_1D_ARRAY) { + assert(box->y + box->height <= resource->array_size); + } + else { + assert(box->y + box->height <= u_minify(resource->height0, level)); + if (resource->target == PIPE_TEXTURE_2D_ARRAY) { + assert(box->z + box->depth <= resource->array_size); + } + else if (resource->target == PIPE_TEXTURE_CUBE) { + assert(box->z < 6); + } + else { + assert(box->z + box->depth <= (u_minify(resource->depth0, level))); + } + } /* * Transfers, like other pipe operations, must happen in order, so flush the diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 480860af63..60870b8bee 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -357,11 +357,12 @@ sp_flush_tile(struct softpipe_tile_cache* tc, unsigned pos) tc->entries[pos]->data.depth32, 0/*STRIDE*/); } else { - pipe_put_tile_rgba(tc->pipe, tc->transfer, - tc->tile_addrs[pos].bits.x * TILE_SIZE, - tc->tile_addrs[pos].bits.y * TILE_SIZE, - TILE_SIZE, TILE_SIZE, - (float *) tc->entries[pos]->data.color); + pipe_put_tile_rgba_format(tc->pipe, tc->transfer, + tc->tile_addrs[pos].bits.x * TILE_SIZE, + tc->tile_addrs[pos].bits.y * TILE_SIZE, + TILE_SIZE, TILE_SIZE, + tc->surface->format, + (float *) tc->entries[pos]->data.color); } tc->tile_addrs[pos].bits.invalid = 1; /* mark as empty */ } @@ -468,11 +469,12 @@ sp_find_cached_tile(struct softpipe_tile_cache *tc, tile->data.depth32, 0/*STRIDE*/); } else { - pipe_put_tile_rgba(tc->pipe, pt, - tc->tile_addrs[pos].bits.x * TILE_SIZE, - tc->tile_addrs[pos].bits.y * TILE_SIZE, - TILE_SIZE, TILE_SIZE, - (float *) tile->data.color); + pipe_put_tile_rgba_format(tc->pipe, pt, + tc->tile_addrs[pos].bits.x * TILE_SIZE, + tc->tile_addrs[pos].bits.y * TILE_SIZE, + TILE_SIZE, TILE_SIZE, + tc->surface->format, + (float *) tile->data.color); } } |