[Mesa-dev] [PATCH v2] st/nine: Rework texture data allocation

2015-04-27 Thread Axel Davy
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

2015-04-27 Thread Ilia Mirkin
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 *