Ahh wrong patch sent again. This one is unchanged. Roland
Am 28.08.2014 18:17, schrieb srol...@vmware.com: > From: Roland Scheidegger <srol...@vmware.com> > > Pretty trivial, just fill in the offsets and such. The implementation > is near 100% copy and paste from llvmpipe. Should be useful for debugging. > > No piglit change when not using SOFTPIPE_USE_LLVM=1. > Now that it can do the same tests with and without using llvm for vs/gs, > with llvm more pass, the only things failing only with llvm seems to be > edgeflags tests and vs/gs-pow-float-float (and for the latter I'm not > convinced the zero tolerance it requires is somehow mandated by glsl). > --- > src/gallium/drivers/llvmpipe/lp_setup.c | 2 +- > src/gallium/drivers/llvmpipe/lp_state_sampler.c | 2 +- > src/gallium/drivers/softpipe/sp_context.h | 2 + > src/gallium/drivers/softpipe/sp_draw_arrays.c | 15 +++ > src/gallium/drivers/softpipe/sp_screen.c | 18 +-- > src/gallium/drivers/softpipe/sp_state.h | 15 +++ > src/gallium/drivers/softpipe/sp_state_sampler.c | 156 > ++++++++++++++++++++++++ > src/gallium/drivers/softpipe/sp_texture.c | 34 +++--- > src/gallium/drivers/softpipe/sp_texture.h | 1 + > 9 files changed, 209 insertions(+), 36 deletions(-) > > diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c > b/src/gallium/drivers/llvmpipe/lp_setup.c > index e85c4ca..7d0c8cc 100644 > --- a/src/gallium/drivers/llvmpipe/lp_setup.c > +++ b/src/gallium/drivers/llvmpipe/lp_setup.c > @@ -873,7 +873,7 @@ lp_setup_set_fragment_sampler_views(struct > lp_setup_context *setup, > /* probably don't really need to fill that out */ > jit_tex->mip_offsets[0] = 0; > jit_tex->row_stride[0] = 0; > - jit_tex->row_stride[0] = 0; > + jit_tex->img_stride[0] = 0; > > /* everything specified in number of elements here. */ > jit_tex->width = view->u.buf.last_element - > view->u.buf.first_element + 1; > diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c > b/src/gallium/drivers/llvmpipe/lp_state_sampler.c > index 0180e99..21da629 100644 > --- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c > +++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c > @@ -266,7 +266,7 @@ prepare_shader_sampling( > /* probably don't really need to fill that out */ > mip_offsets[0] = 0; > row_stride[0] = 0; > - row_stride[0] = 0; > + img_stride[0] = 0; > > /* everything specified in number of elements here. */ > width0 = view->u.buf.last_element - view->u.buf.first_element > + 1; > diff --git a/src/gallium/drivers/softpipe/sp_context.h > b/src/gallium/drivers/softpipe/sp_context.h > index aac35f7..50a7336 100644 > --- a/src/gallium/drivers/softpipe/sp_context.h > +++ b/src/gallium/drivers/softpipe/sp_context.h > @@ -85,6 +85,8 @@ struct softpipe_context { > struct pipe_viewport_state viewport; > struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; > struct pipe_index_buffer index_buffer; > + struct pipe_resource *mapped_vs_tex[PIPE_MAX_SHADER_SAMPLER_VIEWS]; > + struct pipe_resource *mapped_gs_tex[PIPE_MAX_SHADER_SAMPLER_VIEWS]; > > struct draw_so_target *so_targets[PIPE_MAX_SO_BUFFERS]; > unsigned num_so_targets; > diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c > b/src/gallium/drivers/softpipe/sp_draw_arrays.c > index b75c10f..03fcf64 100644 > --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c > +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c > @@ -41,6 +41,7 @@ > #include "sp_query.h" > #include "sp_state.h" > #include "sp_texture.h" > +#include "sp_screen.h" > > #include "draw/draw_context.h" > > @@ -123,6 +124,15 @@ softpipe_draw_vbo(struct pipe_context *pipe, > draw_set_mapped_so_targets(draw, sp->num_so_targets, > sp->so_targets); > > + if (softpipe_screen(sp->pipe.screen)->use_llvm) { > + softpipe_prepare_vertex_sampling(sp, > + > sp->num_sampler_views[PIPE_SHADER_VERTEX], > + > sp->sampler_views[PIPE_SHADER_VERTEX]); > + softpipe_prepare_geometry_sampling(sp, > + > sp->num_sampler_views[PIPE_SHADER_GEOMETRY], > + > sp->sampler_views[PIPE_SHADER_GEOMETRY]); > + } > + > if (sp->gs && !sp->gs->shader.tokens) { > /* we have an empty geometry shader with stream output, so > attach the stream output info to the current vertex shader */ > @@ -146,6 +156,11 @@ softpipe_draw_vbo(struct pipe_context *pipe, > > draw_set_mapped_so_targets(draw, 0, NULL); > > + if (softpipe_screen(sp->pipe.screen)->use_llvm) { > + softpipe_cleanup_vertex_sampling(sp); > + softpipe_cleanup_geometry_sampling(sp); > + } > + > /* > * TODO: Flush only when a user vertex/index buffer is present > * (or even better, modify draw module to do this > diff --git a/src/gallium/drivers/softpipe/sp_screen.c > b/src/gallium/drivers/softpipe/sp_screen.c > index be9a6c8..e86a4d4 100644 > --- a/src/gallium/drivers/softpipe/sp_screen.c > +++ b/src/gallium/drivers/softpipe/sp_screen.c > @@ -240,20 +240,10 @@ softpipe_get_shader_param(struct pipe_screen *screen, > unsigned shader, enum pipe > return tgsi_exec_get_shader_param(param); > case PIPE_SHADER_VERTEX: > case PIPE_SHADER_GEOMETRY: > - switch (param) { > - case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: > - case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: > - if (sp_screen->use_llvm) > - /* Softpipe doesn't yet know how to tell draw/llvm about > textures */ > - return 0; > - else > - return PIPE_MAX_SAMPLERS; > - default: > - if (sp_screen->use_llvm) > - return draw_get_shader_param(shader, param); > - else > - return draw_get_shader_param_no_llvm(shader, param); > - } > + if (sp_screen->use_llvm) > + return draw_get_shader_param(shader, param); > + else > + return draw_get_shader_param_no_llvm(shader, param); > default: > return 0; > } > diff --git a/src/gallium/drivers/softpipe/sp_state.h > b/src/gallium/drivers/softpipe/sp_state.h > index 775a1f5..c35534c 100644 > --- a/src/gallium/drivers/softpipe/sp_state.h > +++ b/src/gallium/drivers/softpipe/sp_state.h > @@ -192,5 +192,20 @@ softpipe_find_fs_variant(struct softpipe_context > *softpipe, > struct sp_fragment_shader *fs, > const struct sp_fragment_shader_variant_key *key); > > +void > +softpipe_prepare_vertex_sampling(struct softpipe_context *ctx, > + unsigned num, > + struct pipe_sampler_view **views); > +void > +softpipe_cleanup_vertex_sampling(struct softpipe_context *ctx); > + > + > +void > +softpipe_prepare_geometry_sampling(struct softpipe_context *ctx, > + unsigned num, > + struct pipe_sampler_view **views); > +void > +softpipe_cleanup_geometry_sampling(struct softpipe_context *ctx); > + > > #endif > diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c > b/src/gallium/drivers/softpipe/sp_state_sampler.c > index e512418..e56fb5b 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" > > > /** > @@ -159,6 +162,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, > + unsigned 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 < PIPE_MAX_SHADER_SAMPLER_VIEWS; i++) { > + struct pipe_sampler_view *view = i < num ? views[i] : NULL; > + > + 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 */ > + struct pipe_resource *res = view->texture; > + int j; > + > + if (res->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 (res->target == PIPE_TEXTURE_1D_ARRAY || > + res->target == PIPE_TEXTURE_2D_ARRAY || > + res->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 (res->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.last_element - view->u.buf.first_element > + 1; > + addr = (uint8_t *)addr + view->u.buf.first_element * > + view_blocksize; > + assert(view->u.buf.first_element <= view->u.buf.last_element); > + assert(view->u.buf.last_element * view_blocksize < > 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 < Elements(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 < Elements(ctx->mapped_gs_tex); i++) { > + pipe_resource_reference(&ctx->mapped_gs_tex[i], NULL); > + } > +} > + > + > void > softpipe_init_sampler_funcs(struct pipe_context *pipe) > { > diff --git a/src/gallium/drivers/softpipe/sp_texture.c > b/src/gallium/drivers/softpipe/sp_texture.c > index 6538e46..c2df71e 100644 > --- a/src/gallium/drivers/softpipe/sp_texture.c > +++ b/src/gallium/drivers/softpipe/sp_texture.c > @@ -63,7 +63,9 @@ softpipe_resource_layout(struct pipe_screen *screen, > uint64_t buffer_size = 0; > > for (level = 0; level <= pt->last_level; level++) { > - unsigned slices; > + unsigned slices, nblocksy; > + > + nblocksy = util_format_get_nblocksy(pt->format, height); > > if (pt->target == PIPE_TEXTURE_CUBE) > slices = 6; > @@ -76,8 +78,15 @@ softpipe_resource_layout(struct pipe_screen *screen, > > spr->level_offset[level] = buffer_size; > > - buffer_size += (uint64_t) util_format_get_nblocksy(pt->format, height) > * > - slices * spr->stride[level]; > + /* if row_stride * height > SP_MAX_TEXTURE_SIZE */ > + if ((uint64_t)spr->stride[level] * nblocksy > SP_MAX_TEXTURE_SIZE) { > + /* image too large */ > + return FALSE; > + } > + > + spr->img_stride[level] = spr->stride[level] * nblocksy; > + > + buffer_size += (uint64_t) spr->img_stride[level] * slices; > > width = u_minify(width, 1); > height = u_minify(height, 1); > @@ -253,22 +262,9 @@ static unsigned > sp_get_tex_image_offset(const struct softpipe_resource *spr, > 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 || > - spr->base.target == PIPE_TEXTURE_CUBE_ARRAY || > - 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); > - } > + offset += layer * spr->img_stride[level]; > > return offset; > } > @@ -354,8 +350,6 @@ softpipe_transfer_map(struct pipe_context *pipe, > struct softpipe_transfer *spt; > struct pipe_transfer *pt; > enum pipe_format format = resource->format; > - const unsigned hgt = u_minify(spr->base.height0, level); > - const unsigned nblocksy = util_format_get_nblocksy(format, hgt); > uint8_t *map; > > assert(resource); > @@ -414,7 +408,7 @@ softpipe_transfer_map(struct pipe_context *pipe, > pt->usage = usage; > pt->box = *box; > pt->stride = spr->stride[level]; > - pt->layer_stride = pt->stride * nblocksy; > + pt->layer_stride = spr->img_stride[level]; > > spt->offset = sp_get_tex_image_offset(spr, level, box->z); > > diff --git a/src/gallium/drivers/softpipe/sp_texture.h > b/src/gallium/drivers/softpipe/sp_texture.h > index 90f35e1..1701bf5 100644 > --- a/src/gallium/drivers/softpipe/sp_texture.h > +++ b/src/gallium/drivers/softpipe/sp_texture.h > @@ -47,6 +47,7 @@ struct softpipe_resource > > unsigned long level_offset[SP_MAX_TEXTURE_2D_LEVELS]; > unsigned stride[SP_MAX_TEXTURE_2D_LEVELS]; > + unsigned img_stride[SP_MAX_TEXTURE_2D_LEVELS]; > > /** > * Display target, only valid for PIPE_TEXTURE_2D with the > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev