[Mesa-dev] [PATCH v2] st/nine: Rework texture data allocation
Some applications assume the memory for multilevel textures is allocated per continuous blocks. This patch implements that behaviour. v2: cache offsets Signed-off-by: Axel Davy axel.d...@ens.fr --- src/gallium/state_trackers/nine/cubetexture9.c | 46 ++- src/gallium/state_trackers/nine/cubetexture9.h | 1 + src/gallium/state_trackers/nine/nine_pipe.h| 41 + src/gallium/state_trackers/nine/surface9.c | 51 ++ src/gallium/state_trackers/nine/surface9.h | 1 - src/gallium/state_trackers/nine/texture9.c | 27 +- src/gallium/state_trackers/nine/texture9.h | 1 + 7 files changed, 131 insertions(+), 37 deletions(-) diff --git a/src/gallium/state_trackers/nine/cubetexture9.c b/src/gallium/state_trackers/nine/cubetexture9.c index d81cc70..f64764c 100644 --- a/src/gallium/state_trackers/nine/cubetexture9.c +++ b/src/gallium/state_trackers/nine/cubetexture9.c @@ -20,6 +20,8 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include c99_alloca.h + #include device9.h #include cubetexture9.h #include nine_helpers.h @@ -40,8 +42,10 @@ NineCubeTexture9_ctor( struct NineCubeTexture9 *This, struct pipe_resource *info = This-base.base.info; struct pipe_screen *screen = pParams-device-screen; enum pipe_format pf; -unsigned i; +unsigned i, l, f, offset, face_size = 0; +unsigned *level_offsets; D3DSURFACE_DESC sfdesc; +void *p; HRESULT hr; DBG(This=%p pParams=%p EdgeLength=%u Levels=%u Usage=%d @@ -97,6 +101,16 @@ NineCubeTexture9_ctor( struct NineCubeTexture9 *This, DBG(Application asked for Software Vertex Processing, but this is unimplemented\n); +if (Pool != D3DPOOL_DEFAULT) { +level_offsets = alloca(sizeof(unsigned) * (info-last_level + 1)); +face_size = nine_format_get_size_and_offsets(pf, level_offsets, + EdgeLength, EdgeLength, + info-last_level); +This-managed_buffer = MALLOC(6 * face_size); +if (!This-managed_buffer) +return E_OUTOFMEMORY; +} + This-surfaces = CALLOC(6 * (info-last_level + 1), sizeof(*This-surfaces)); if (!This-surfaces) return E_OUTOFMEMORY; @@ -117,16 +131,25 @@ NineCubeTexture9_ctor( struct NineCubeTexture9 *This, sfdesc.Pool = Pool; sfdesc.MultiSampleType = D3DMULTISAMPLE_NONE; sfdesc.MultiSampleQuality = 0; -for (i = 0; i (info-last_level + 1) * 6; ++i) { -sfdesc.Width = sfdesc.Height = u_minify(EdgeLength, i / 6); - -hr = NineSurface9_new(This-base.base.base.device, NineUnknown(This), - This-base.base.resource, NULL, D3DRTYPE_CUBETEXTURE, - i / 6, i % 6, - sfdesc, This-surfaces[i]); -if (FAILED(hr)) -return hr; +/* We allocate the memory for the surfaces as continous blocks. + * This is the expected behaviour, however we haven't tested for + * cube textures in which order the faces/levels should be in memory + */ +for (f = 0; f 6; f++) { +offset = f * face_size; +for (l = 0; l = info-last_level; l++) { +sfdesc.Width = sfdesc.Height = u_minify(EdgeLength, l); +p = This-managed_buffer ? This-managed_buffer + offset + +level_offsets[l] : NULL; + +hr = NineSurface9_new(This-base.base.base.device, NineUnknown(This), + This-base.base.resource, p, D3DRTYPE_CUBETEXTURE, + l, f, sfdesc, This-surfaces[f + 6 * l]); +if (FAILED(hr)) +return hr; +} } + for (i = 0; i 6; ++i) /* width = 0 means empty, depth stays 1 */ This-dirty_rect[i].depth = 1; @@ -146,6 +169,9 @@ NineCubeTexture9_dtor( struct NineCubeTexture9 *This ) FREE(This-surfaces); } +if (This-managed_buffer) +FREE(This-managed_buffer); + NineBaseTexture9_dtor(This-base); } diff --git a/src/gallium/state_trackers/nine/cubetexture9.h b/src/gallium/state_trackers/nine/cubetexture9.h index e8594d3..ee7e275 100644 --- a/src/gallium/state_trackers/nine/cubetexture9.h +++ b/src/gallium/state_trackers/nine/cubetexture9.h @@ -31,6 +31,7 @@ struct NineCubeTexture9 struct NineBaseTexture9 base; struct NineSurface9 **surfaces; struct pipe_box dirty_rect[6]; /* covers all mip levels */ +uint8_t *managed_buffer; }; static INLINE struct NineCubeTexture9 * NineCubeTexture9( void *data ) diff --git a/src/gallium/state_trackers/nine/nine_pipe.h b/src/gallium/state_trackers/nine/nine_pipe.h index b8e728e..1b88612 100644 --- a/src/gallium/state_trackers/nine/nine_pipe.h +++ b/src/gallium/state_trackers/nine/nine_pipe.h @@
Re: [Mesa-dev] [PATCH v2] st/nine: Rework texture data allocation
On Mon, Apr 27, 2015 at 1:39 PM, Axel Davy axel.d...@ens.fr wrote: Some applications assume the memory for multilevel textures is allocated per continuous blocks. This patch implements that behaviour. v2: cache offsets Thanks, this is much nicer IMO. Reviewed-by: Ilia Mirkin imir...@alum.mit.edu Signed-off-by: Axel Davy axel.d...@ens.fr --- src/gallium/state_trackers/nine/cubetexture9.c | 46 ++- src/gallium/state_trackers/nine/cubetexture9.h | 1 + src/gallium/state_trackers/nine/nine_pipe.h| 41 + src/gallium/state_trackers/nine/surface9.c | 51 ++ src/gallium/state_trackers/nine/surface9.h | 1 - src/gallium/state_trackers/nine/texture9.c | 27 +- src/gallium/state_trackers/nine/texture9.h | 1 + 7 files changed, 131 insertions(+), 37 deletions(-) diff --git a/src/gallium/state_trackers/nine/cubetexture9.c b/src/gallium/state_trackers/nine/cubetexture9.c index d81cc70..f64764c 100644 --- a/src/gallium/state_trackers/nine/cubetexture9.c +++ b/src/gallium/state_trackers/nine/cubetexture9.c @@ -20,6 +20,8 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include c99_alloca.h + #include device9.h #include cubetexture9.h #include nine_helpers.h @@ -40,8 +42,10 @@ NineCubeTexture9_ctor( struct NineCubeTexture9 *This, struct pipe_resource *info = This-base.base.info; struct pipe_screen *screen = pParams-device-screen; enum pipe_format pf; -unsigned i; +unsigned i, l, f, offset, face_size = 0; +unsigned *level_offsets; D3DSURFACE_DESC sfdesc; +void *p; HRESULT hr; DBG(This=%p pParams=%p EdgeLength=%u Levels=%u Usage=%d @@ -97,6 +101,16 @@ NineCubeTexture9_ctor( struct NineCubeTexture9 *This, DBG(Application asked for Software Vertex Processing, but this is unimplemented\n); +if (Pool != D3DPOOL_DEFAULT) { +level_offsets = alloca(sizeof(unsigned) * (info-last_level + 1)); +face_size = nine_format_get_size_and_offsets(pf, level_offsets, + EdgeLength, EdgeLength, + info-last_level); +This-managed_buffer = MALLOC(6 * face_size); +if (!This-managed_buffer) +return E_OUTOFMEMORY; +} + This-surfaces = CALLOC(6 * (info-last_level + 1), sizeof(*This-surfaces)); if (!This-surfaces) return E_OUTOFMEMORY; @@ -117,16 +131,25 @@ NineCubeTexture9_ctor( struct NineCubeTexture9 *This, sfdesc.Pool = Pool; sfdesc.MultiSampleType = D3DMULTISAMPLE_NONE; sfdesc.MultiSampleQuality = 0; -for (i = 0; i (info-last_level + 1) * 6; ++i) { -sfdesc.Width = sfdesc.Height = u_minify(EdgeLength, i / 6); - -hr = NineSurface9_new(This-base.base.base.device, NineUnknown(This), - This-base.base.resource, NULL, D3DRTYPE_CUBETEXTURE, - i / 6, i % 6, - sfdesc, This-surfaces[i]); -if (FAILED(hr)) -return hr; +/* We allocate the memory for the surfaces as continous blocks. + * This is the expected behaviour, however we haven't tested for + * cube textures in which order the faces/levels should be in memory + */ +for (f = 0; f 6; f++) { +offset = f * face_size; +for (l = 0; l = info-last_level; l++) { +sfdesc.Width = sfdesc.Height = u_minify(EdgeLength, l); +p = This-managed_buffer ? This-managed_buffer + offset + +level_offsets[l] : NULL; + +hr = NineSurface9_new(This-base.base.base.device, NineUnknown(This), + This-base.base.resource, p, D3DRTYPE_CUBETEXTURE, + l, f, sfdesc, This-surfaces[f + 6 * l]); +if (FAILED(hr)) +return hr; +} } + for (i = 0; i 6; ++i) /* width = 0 means empty, depth stays 1 */ This-dirty_rect[i].depth = 1; @@ -146,6 +169,9 @@ NineCubeTexture9_dtor( struct NineCubeTexture9 *This ) FREE(This-surfaces); } +if (This-managed_buffer) +FREE(This-managed_buffer); + NineBaseTexture9_dtor(This-base); } diff --git a/src/gallium/state_trackers/nine/cubetexture9.h b/src/gallium/state_trackers/nine/cubetexture9.h index e8594d3..ee7e275 100644 --- a/src/gallium/state_trackers/nine/cubetexture9.h +++ b/src/gallium/state_trackers/nine/cubetexture9.h @@ -31,6 +31,7 @@ struct NineCubeTexture9 struct NineBaseTexture9 base; struct NineSurface9 **surfaces; struct pipe_box dirty_rect[6]; /* covers all mip levels */ +uint8_t *managed_buffer; }; static INLINE struct NineCubeTexture9 *