diff options
Diffstat (limited to 'src/gallium/state_trackers/nine/texture9.c')
-rw-r--r-- | src/gallium/state_trackers/nine/texture9.c | 27 |
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); } |