From 6d50148742512606f2abd76a2dcef6c87a5c7471 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 29 Nov 2012 04:08:32 +0100 Subject: [PATCH] llvmpipe: support array textures MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This adds array (1d,2d) texture support to llvmpipe. Though probably should do something about 1d array textures requiring gobs of memory (this issue is not strictly limited to arrays but it is probably worse there). Initial code by Jakob Bornecrantz Reviewed-by: José Fonseca --- src/gallium/drivers/llvmpipe/lp_limits.h | 1 + src/gallium/drivers/llvmpipe/lp_screen.c | 6 ++++-- src/gallium/drivers/llvmpipe/lp_setup.c | 8 +++++++- src/gallium/drivers/llvmpipe/lp_state_sampler.c | 10 +++++++++- src/gallium/drivers/llvmpipe/lp_texture.c | 12 ++++++++++-- src/gallium/drivers/llvmpipe/lp_texture.h | 2 +- 6 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_limits.h b/src/gallium/drivers/llvmpipe/lp_limits.h index 3be24d6d648..bb8f20820d0 100644 --- a/src/gallium/drivers/llvmpipe/lp_limits.h +++ b/src/gallium/drivers/llvmpipe/lp_limits.h @@ -47,6 +47,7 @@ #define LP_MAX_TEXTURE_2D_LEVELS 14 /* 8K x 8K for now */ #define LP_MAX_TEXTURE_3D_LEVELS 11 /* 1K x 1K x 1K for now */ #define LP_MAX_TEXTURE_CUBE_LEVELS 13 /* 4K x 4K for now */ +#define LP_MAX_TEXTURE_ARRAY_LAYERS 512 /* 8K x 512 / 8K x 8K x 512 */ /** This must be the larger of LP_MAX_TEXTURE_2D/3D_LEVELS */ diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 375692ec6d9..3f207d713af 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -139,6 +139,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) return LP_MAX_TEXTURE_3D_LEVELS; case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: return LP_MAX_TEXTURE_CUBE_LEVELS; + case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: + return LP_MAX_TEXTURE_ARRAY_LAYERS; case PIPE_CAP_BLEND_EQUATION_SEPARATE: return 1; case PIPE_CAP_INDEP_BLEND_ENABLE: @@ -155,8 +157,6 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) return 1; case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: return 1; - case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: - return 0; case PIPE_CAP_DEPTH_CLIP_DISABLE: return 0; case PIPE_CAP_SHADER_STENCIL_EXPORT: @@ -305,7 +305,9 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen, 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/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index a06acb27b83..84defc65054 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -653,10 +653,16 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup, jit_tex = &setup->fs.current.jit_context.textures[i]; jit_tex->width = tex->width0; jit_tex->height = tex->height0; - jit_tex->depth = tex->depth0; jit_tex->first_level = view->u.tex.first_level; jit_tex->last_level = tex->last_level; + if (tex->target == PIPE_TEXTURE_3D) { + jit_tex->depth = tex->depth0; + } + else { + jit_tex->depth = tex->array_size; + } + /* We're referencing the texture's internal data, so save a * reference to it. */ diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c index 58fac3f54d4..e7429cc35a1 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c +++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c @@ -268,6 +268,14 @@ llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp, if (view) { struct pipe_resource *tex = view->texture; struct llvmpipe_resource *lp_tex = llvmpipe_resource(tex); + unsigned num_layers; + + if (tex->target == PIPE_TEXTURE_3D) { + num_layers = tex->depth0; + } + else { + num_layers = tex->array_size; + } /* We're referencing the texture's internal data, so save a * reference to it. @@ -315,7 +323,7 @@ llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp, draw_set_mapped_texture(lp->draw, PIPE_SHADER_VERTEX, i, - tex->width0, tex->height0, tex->depth0, + tex->width0, tex->height0, num_layers, view->u.tex.first_level, tex->last_level, addr, row_stride, img_stride, mip_offsets); diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 39d646964e4..f4d2cb6c5d0 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -67,7 +67,9 @@ resource_is_texture(const struct pipe_resource *resource) case PIPE_BUFFER: return FALSE; case PIPE_TEXTURE_1D: + case PIPE_TEXTURE_1D_ARRAY: case PIPE_TEXTURE_2D: + case PIPE_TEXTURE_2D_ARRAY: case PIPE_TEXTURE_RECT: case PIPE_TEXTURE_3D: case PIPE_TEXTURE_CUBE: @@ -114,6 +116,7 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen, unsigned height = pt->height0; unsigned depth = pt->depth0; uint64_t total_size = 0; + unsigned layers = pt->array_size; assert(LP_MAX_TEXTURE_2D_LEVELS <= LP_MAX_TEXTURE_LEVELS); assert(LP_MAX_TEXTURE_3D_LEVELS <= LP_MAX_TEXTURE_LEVELS); @@ -126,6 +129,8 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen, /* For non-compressed formats we need to align the texture size * to the tile size to facilitate render-to-texture. + * XXX this blows up 1d/1d array textures by unreasonable + * amount (factor 64), probably should do something about it. */ if (util_format_is_compressed(pt->format)) alignment = 1; @@ -157,7 +162,7 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen, lpr->tiles_per_image[level] = width_t * height_t; } - /* Number of 3D image slices or cube faces */ + /* Number of 3D image slices, cube faces or texture array layers */ { unsigned num_slices; @@ -165,6 +170,9 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen, num_slices = 6; else if (lpr->base.target == PIPE_TEXTURE_3D) num_slices = depth; + else if (lpr->base.target == PIPE_TEXTURE_1D_ARRAY || + lpr->base.target == PIPE_TEXTURE_2D_ARRAY) + num_slices = layers; else num_slices = 1; @@ -820,7 +828,7 @@ llvmpipe_user_buffer_create(struct pipe_screen *screen, /** * Compute size (in bytes) need to store a texture image / mipmap level, - * for just one cube face or one 3D texture slice + * for just one cube face, one array layer or one 3D texture slice */ static unsigned tex_image_face_size(const struct llvmpipe_resource *lpr, unsigned level, diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h index c2f2ee8d22b..97a5547bd89 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.h +++ b/src/gallium/drivers/llvmpipe/lp_texture.h @@ -88,7 +88,7 @@ struct llvmpipe_resource /** Row stride in bytes */ unsigned row_stride[LP_MAX_TEXTURE_LEVELS]; - /** Image stride (for cube maps or 3D textures) in bytes */ + /** Image stride (for cube maps, array or 3D textures) in bytes */ unsigned img_stride[LP_MAX_TEXTURE_LEVELS]; unsigned tiles_per_row[LP_MAX_TEXTURE_LEVELS]; unsigned tiles_per_image[LP_MAX_TEXTURE_LEVELS]; -- 2.30.2