summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers/nine/cubetexture9.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/state_trackers/nine/cubetexture9.c')
-rw-r--r--src/gallium/state_trackers/nine/cubetexture9.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/src/gallium/state_trackers/nine/cubetexture9.c b/src/gallium/state_trackers/nine/cubetexture9.c
index d81cc70f659..f64764c6733 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);
}