X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fsoftpipe%2Fsp_state_sampler.c;h=fda638dcea1ce1aa4e38b54446e37acdd14bb10f;hb=2e94cb66933fd7b130011b53b47e0816eb8a76d5;hp=e51241892e1c0739da545f6ad24f2ab736588510;hpb=61a3e9936cec3a2d061c7500c3acaf10d426cee5;p=mesa.git diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index e51241892e1..fda638dcea1 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -31,6 +31,7 @@ #include "util/u_memory.h" #include "util/u_inlines.h" +#include "util/u_format.h" #include "draw/draw_context.h" @@ -39,6 +40,8 @@ #include "sp_texture.h" #include "sp_tex_sample.h" #include "sp_tex_tile_cache.h" +#include "sp_screen.h" +#include "state_tracker/sw_winsys.h" /** @@ -46,7 +49,7 @@ */ static void softpipe_bind_sampler_states(struct pipe_context *pipe, - unsigned shader, + enum pipe_shader_type shader, unsigned start, unsigned num, void **samplers) @@ -55,7 +58,7 @@ softpipe_bind_sampler_states(struct pipe_context *pipe, unsigned i; assert(shader < PIPE_SHADER_TYPES); - assert(start + num <= Elements(softpipe->samplers[shader])); + assert(start + num <= ARRAY_SIZE(softpipe->samplers[shader])); draw_flush(softpipe->draw); @@ -94,7 +97,7 @@ softpipe_sampler_view_destroy(struct pipe_context *pipe, void softpipe_set_sampler_views(struct pipe_context *pipe, - unsigned shader, + enum pipe_shader_type shader, unsigned start, unsigned num, struct pipe_sampler_view **views) @@ -103,7 +106,7 @@ softpipe_set_sampler_views(struct pipe_context *pipe, uint i; assert(shader < PIPE_SHADER_TYPES); - assert(start + num <= Elements(softpipe->sampler_views[shader])); + assert(start + num <= ARRAY_SIZE(softpipe->sampler_views[shader])); draw_flush(softpipe->draw); @@ -124,6 +127,7 @@ softpipe_set_sampler_views(struct pipe_context *pipe, if (sp_sviewsrc) { memcpy(sp_sviewdst, sp_sviewsrc, sizeof(*sp_sviewsrc)); sp_sviewdst->compute_lambda = softpipe_get_lambda_func(&sp_sviewdst->base, shader); + sp_sviewdst->compute_lambda_from_grad = softpipe_get_lambda_from_grad_func(&sp_sviewdst->base, shader); sp_sviewdst->cache = softpipe->tex_cache[shader][start + i]; } else { @@ -159,6 +163,159 @@ softpipe_delete_sampler_state(struct pipe_context *pipe, } +static void +prepare_shader_sampling( + struct softpipe_context *sp, + unsigned num, + struct pipe_sampler_view **views, + enum pipe_shader_type shader_type, + struct pipe_resource *mapped_tex[PIPE_MAX_SHADER_SAMPLER_VIEWS]) +{ + + unsigned i; + uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS]; + uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS]; + uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS]; + const void *addr; + + assert(num <= PIPE_MAX_SHADER_SAMPLER_VIEWS); + if (!num) + return; + + for (i = 0; i < num; i++) { + struct pipe_sampler_view *view = views[i]; + + if (view) { + struct pipe_resource *tex = view->texture; + struct softpipe_resource *sp_tex = softpipe_resource(tex); + unsigned width0 = tex->width0; + unsigned num_layers = tex->depth0; + unsigned first_level = 0; + unsigned last_level = 0; + + /* We're referencing the texture's internal data, so save a + * reference to it. + */ + pipe_resource_reference(&mapped_tex[i], tex); + + if (!sp_tex->dt) { + /* regular texture - setup array of mipmap level offsets */ + ASSERTED struct pipe_resource *res = view->texture; + int j; + + if (view->target != PIPE_BUFFER) { + first_level = view->u.tex.first_level; + last_level = view->u.tex.last_level; + assert(first_level <= last_level); + assert(last_level <= res->last_level); + addr = sp_tex->data; + + for (j = first_level; j <= last_level; j++) { + mip_offsets[j] = sp_tex->level_offset[j]; + row_stride[j] = sp_tex->stride[j]; + img_stride[j] = sp_tex->img_stride[j]; + } + if (tex->target == PIPE_TEXTURE_1D_ARRAY || + tex->target == PIPE_TEXTURE_2D_ARRAY || + tex->target == PIPE_TEXTURE_CUBE || + tex->target == PIPE_TEXTURE_CUBE_ARRAY) { + num_layers = view->u.tex.last_layer - view->u.tex.first_layer + 1; + for (j = first_level; j <= last_level; j++) { + mip_offsets[j] += view->u.tex.first_layer * + sp_tex->img_stride[j]; + } + if (view->target == PIPE_TEXTURE_CUBE || + view->target == PIPE_TEXTURE_CUBE_ARRAY) { + assert(num_layers % 6 == 0); + } + assert(view->u.tex.first_layer <= view->u.tex.last_layer); + assert(view->u.tex.last_layer < res->array_size); + } + } + else { + unsigned view_blocksize = util_format_get_blocksize(view->format); + addr = sp_tex->data; + /* probably don't really need to fill that out */ + mip_offsets[0] = 0; + row_stride[0] = 0; + img_stride[0] = 0; + + /* everything specified in number of elements here. */ + width0 = view->u.buf.size / view_blocksize; + addr = (uint8_t *)addr + view->u.buf.offset; + assert(view->u.buf.offset + view->u.buf.size <= res->width0); + } + } + else { + /* display target texture/surface */ + /* + * XXX: Where should this be unmapped? + */ + struct softpipe_screen *screen = softpipe_screen(tex->screen); + struct sw_winsys *winsys = screen->winsys; + addr = winsys->displaytarget_map(winsys, sp_tex->dt, + PIPE_TRANSFER_READ); + row_stride[0] = sp_tex->stride[0]; + img_stride[0] = sp_tex->img_stride[0]; + mip_offsets[0] = 0; + assert(addr); + } + draw_set_mapped_texture(sp->draw, + shader_type, + i, + width0, tex->height0, num_layers, + first_level, last_level, + addr, + row_stride, img_stride, mip_offsets); + } + } +} + + +/** + * Called during state validation when SP_NEW_TEXTURE is set. + */ +void +softpipe_prepare_vertex_sampling(struct softpipe_context *sp, + unsigned num, + struct pipe_sampler_view **views) +{ + prepare_shader_sampling(sp, num, views, PIPE_SHADER_VERTEX, + sp->mapped_vs_tex); +} + +void +softpipe_cleanup_vertex_sampling(struct softpipe_context *ctx) +{ + unsigned i; + for (i = 0; i < ARRAY_SIZE(ctx->mapped_vs_tex); i++) { + pipe_resource_reference(&ctx->mapped_vs_tex[i], NULL); + } +} + + +/** + * Called during state validation when SP_NEW_TEXTURE is set. + */ +void +softpipe_prepare_geometry_sampling(struct softpipe_context *sp, + unsigned num, + struct pipe_sampler_view **views) +{ + prepare_shader_sampling(sp, num, views, PIPE_SHADER_GEOMETRY, + sp->mapped_gs_tex); +} + +void +softpipe_cleanup_geometry_sampling(struct softpipe_context *ctx) +{ + unsigned i; + for (i = 0; i < ARRAY_SIZE(ctx->mapped_gs_tex); i++) { + pipe_resource_reference(&ctx->mapped_gs_tex[i], NULL); + } +} + + void softpipe_init_sampler_funcs(struct pipe_context *pipe) {