From 8b7295f2815842331e9d12489bf0517b3f272334 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 20 Jul 2019 14:28:45 +1000 Subject: [PATCH] llvmpipe: bind vertex/geometry shader images Reviewed-by: Roland Scheidegger --- src/gallium/drivers/llvmpipe/lp_draw_arrays.c | 7 ++ src/gallium/drivers/llvmpipe/lp_state.h | 9 ++ .../drivers/llvmpipe/lp_state_sampler.c | 110 ++++++++++++++++++ 3 files changed, 126 insertions(+) diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c index 3ce3d478290..01f3cf3cdfc 100644 --- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c @@ -105,6 +105,13 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) llvmpipe_prepare_geometry_sampling(lp, lp->num_sampler_views[PIPE_SHADER_GEOMETRY], lp->sampler_views[PIPE_SHADER_GEOMETRY]); + + llvmpipe_prepare_vertex_images(lp, + lp->num_images[PIPE_SHADER_VERTEX], + lp->images[PIPE_SHADER_VERTEX]); + llvmpipe_prepare_geometry_images(lp, + lp->num_images[PIPE_SHADER_GEOMETRY], + lp->images[PIPE_SHADER_GEOMETRY]); if (lp->gs && lp->gs->no_tokens) { /* we have an empty geometry shader with stream output, so attach the stream output info to the current vertex shader */ diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h index 753f596a858..ea6542735a5 100644 --- a/src/gallium/drivers/llvmpipe/lp_state.h +++ b/src/gallium/drivers/llvmpipe/lp_state.h @@ -137,4 +137,13 @@ llvmpipe_prepare_geometry_sampling(struct llvmpipe_context *ctx, unsigned num, struct pipe_sampler_view **views); +void +llvmpipe_prepare_vertex_images(struct llvmpipe_context *lp, + unsigned num, + struct pipe_image_view *views); + +void +llvmpipe_prepare_geometry_images(struct llvmpipe_context *lp, + unsigned num, + struct pipe_image_view *views); #endif diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c index 72823e4c84a..fface0c783e 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c +++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c @@ -356,6 +356,116 @@ llvmpipe_prepare_geometry_sampling(struct llvmpipe_context *lp, prepare_shader_sampling(lp, num, views, PIPE_SHADER_GEOMETRY); } +static void +prepare_shader_images( + struct llvmpipe_context *lp, + unsigned num, + struct pipe_image_view *views, + enum pipe_shader_type shader_type) +{ + + unsigned i; + uint32_t row_stride; + uint32_t img_stride; + const void *addr; + + assert(num <= PIPE_MAX_SHADER_SAMPLER_VIEWS); + if (!num) + return; + + for (i = 0; i < num; i++) { + struct pipe_image_view *view = i < num ? &views[i] : NULL; + + if (view) { + struct pipe_resource *img = view->resource; + struct llvmpipe_resource *lp_img = llvmpipe_resource(img); + if (!img) + continue; + + unsigned width0 = img->width0; + unsigned num_layers = img->depth0; + + if (!lp_img->dt) { + /* regular texture - setup array of mipmap level offsets */ + struct pipe_resource *res = view->resource; + + if (llvmpipe_resource_is_texture(res)) { + uint32_t mip_offset = lp_img->mip_offsets[view->u.tex.level]; + addr = lp_img->tex_data; + + if (img->target == PIPE_TEXTURE_1D_ARRAY || + img->target == PIPE_TEXTURE_2D_ARRAY || + img->target == PIPE_TEXTURE_3D || + img->target == PIPE_TEXTURE_CUBE || + img->target == PIPE_TEXTURE_CUBE_ARRAY) { + num_layers = view->u.tex.last_layer - view->u.tex.first_layer + 1; + assert(view->u.tex.first_layer <= view->u.tex.last_layer); + mip_offset += view->u.tex.first_layer * lp_img->img_stride[view->u.tex.level]; + } + + row_stride = lp_img->row_stride[view->u.tex.level]; + img_stride = lp_img->img_stride[view->u.tex.level]; + addr = (uint8_t *)addr + mip_offset; + } + else { + unsigned view_blocksize = util_format_get_blocksize(view->format); + addr = lp_img->data; + /* probably don't really need to fill that out */ + row_stride = 0; + img_stride = 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 llvmpipe_screen *screen = llvmpipe_screen(img->screen); + struct sw_winsys *winsys = screen->winsys; + addr = winsys->displaytarget_map(winsys, lp_img->dt, + PIPE_TRANSFER_READ); + row_stride = lp_img->row_stride[0]; + img_stride = lp_img->img_stride[0]; + assert(addr); + } + draw_set_mapped_image(lp->draw, + shader_type, + i, + width0, img->height0, num_layers, + addr, + row_stride, img_stride); + } + } +} + + +/** + * Called whenever we're about to draw (no dirty flag, FIXME?). + */ +void +llvmpipe_prepare_vertex_images(struct llvmpipe_context *lp, + unsigned num, + struct pipe_image_view *views) +{ + prepare_shader_images(lp, num, views, PIPE_SHADER_VERTEX); +} + + +/** + * Called whenever we're about to draw (no dirty flag, FIXME?). + */ +void +llvmpipe_prepare_geometry_images(struct llvmpipe_context *lp, + unsigned num, + struct pipe_image_view *views) +{ + prepare_shader_images(lp, num, views, PIPE_SHADER_GEOMETRY); +} void llvmpipe_init_sampler_funcs(struct llvmpipe_context *llvmpipe) -- 2.30.2