summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers/nine/texture9.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/state_trackers/nine/texture9.c')
-rw-r--r--src/gallium/state_trackers/nine/texture9.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/src/gallium/state_trackers/nine/texture9.c b/src/gallium/state_trackers/nine/texture9.c
index 78a632f54ba..536d631af4c 100644
--- a/src/gallium/state_trackers/nine/texture9.c
+++ b/src/gallium/state_trackers/nine/texture9.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 "surface9.h"
#include "texture9.h"
@@ -48,10 +50,11 @@ NineTexture9_ctor( struct NineTexture9 *This,
struct pipe_resource *info = &This->base.base.info;
struct pipe_resource *resource;
enum pipe_format pf;
+ unsigned *level_offsets;
unsigned l;
D3DSURFACE_DESC sfdesc;
HRESULT hr;
- void *user_buffer = NULL;
+ void *user_buffer = NULL, *user_buffer_for_level;
DBG("(%p) Width=%u Height=%u Levels=%u Usage=%s Format=%s Pool=%s "
"pSharedHandle=%p\n", This, Width, Height, Levels,
@@ -138,6 +141,19 @@ NineTexture9_ctor( struct NineTexture9 *This,
if (pSharedHandle && *pSharedHandle) { /* Pool == D3DPOOL_SYSTEMMEM */
user_buffer = (void *)*pSharedHandle;
+ level_offsets = alloca(sizeof(unsigned) * (info->last_level + 1));
+ (void) nine_format_get_size_and_offsets(pf, level_offsets,
+ Width, Height,
+ info->last_level);
+ } else if (Pool != D3DPOOL_DEFAULT) {
+ level_offsets = alloca(sizeof(unsigned) * (info->last_level + 1));
+ user_buffer = MALLOC(
+ nine_format_get_size_and_offsets(pf, level_offsets,
+ Width, Height,
+ info->last_level));
+ This->managed_buffer = user_buffer;
+ if (!This->managed_buffer)
+ return E_OUTOFMEMORY;
}
This->surfaces = CALLOC(info->last_level + 1, sizeof(*This->surfaces));
@@ -168,9 +184,13 @@ NineTexture9_ctor( struct NineTexture9 *This,
for (l = 0; l <= info->last_level; ++l) {
sfdesc.Width = u_minify(Width, l);
sfdesc.Height = u_minify(Height, l);
+ /* Some apps expect the memory to be allocated in
+ * continous blocks */
+ user_buffer_for_level = user_buffer ? user_buffer +
+ level_offsets[l] : NULL;
hr = NineSurface9_new(This->base.base.base.device, NineUnknown(This),
- resource, user_buffer,
+ resource, user_buffer_for_level,
D3DRTYPE_TEXTURE, l, 0,
&sfdesc, &This->surfaces[l]);
if (FAILED(hr))
@@ -198,6 +218,9 @@ NineTexture9_dtor( struct NineTexture9 *This )
FREE(This->surfaces);
}
+ if (This->managed_buffer)
+ FREE(This->managed_buffer);
+
NineBaseTexture9_dtor(&This->base);
}