* 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"
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 "
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;
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;
FREE(This->surfaces);
}
+ if (This->managed_buffer)
+ FREE(This->managed_buffer);
+
NineBaseTexture9_dtor(&This->base);
}
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 )
}
}
+static INLINE unsigned nine_format_get_stride(enum pipe_format format,
+ unsigned width)
+{
+ unsigned stride = util_format_get_stride(format, width);
+
+ return align(stride, 4);
+}
+
+static INLINE unsigned nine_format_get_level_alloc_size(enum pipe_format format,
+ unsigned width,
+ unsigned height,
+ unsigned level)
+{
+ unsigned w, h, size;
+
+ w = u_minify(width, level);
+ h = u_minify(height, level);
+ size = nine_format_get_stride(format, w) *
+ util_format_get_nblocksy(format, h);
+ return size;
+}
+
+static INLINE unsigned nine_format_get_size_and_offsets(enum pipe_format format,
+ unsigned *offsets,
+ unsigned width,
+ unsigned height,
+ unsigned last_level)
+{
+ unsigned l, w, h, size = 0;
+
+ for (l = 0; l <= last_level; ++l) {
+ w = u_minify(width, l);
+ h = u_minify(height, l);
+ offsets[l] = size;
+ size += nine_format_get_stride(format, w) *
+ util_format_get_nblocksy(format, h);
+ }
+
+ return size;
+}
+
#endif /* _NINE_PIPE_H_ */
user_assert(!(pDesc->Usage & D3DUSAGE_DYNAMIC) ||
(pDesc->Pool != D3DPOOL_MANAGED), D3DERR_INVALIDCALL);
- assert(pResource ||
- pDesc->Pool != D3DPOOL_DEFAULT || pDesc->Format == D3DFMT_NULL);
+ assert(pResource || (user_buffer && pDesc->Pool != D3DPOOL_DEFAULT) ||
+ (!pContainer && pDesc->Pool != D3DPOOL_DEFAULT) ||
+ pDesc->Format == D3DFMT_NULL);
assert(!pResource || !user_buffer);
+ assert(!user_buffer || pDesc->Pool != D3DPOOL_DEFAULT);
+ /* The only way we can have !pContainer is being created
+ * from create_zs_or_rt_surface with params 0 0 0 */
+ assert(pContainer || (Level == 0 && Layer == 0 && TextureType == 0));
+
+ This->data = (uint8_t *)user_buffer;
This->base.info.screen = pParams->device->screen;
This->base.info.target = PIPE_TEXTURE_2D;
if (pDesc->Usage & D3DUSAGE_DEPTHSTENCIL)
This->base.info.bind |= PIPE_BIND_DEPTH_STENCIL;
+ /* Ram buffer with no parent. Has to allocate the resource itself */
+ if (!pResource && !pContainer) {
+ assert(!user_buffer);
+ This->data = MALLOC(
+ nine_format_get_level_alloc_size(This->base.info.format,
+ pDesc->Width,
+ pDesc->Height,
+ 0));
+ if (!This->data)
+ return E_OUTOFMEMORY;
+ }
+
if (pDesc->Pool == D3DPOOL_SYSTEMMEM) {
This->base.info.usage = PIPE_USAGE_STAGING;
- This->data = (uint8_t *)user_buffer; /* this is *pSharedHandle */
assert(!pResource);
} else {
if (pResource && (pDesc->Usage & D3DUSAGE_DYNAMIC))
This->layer = Layer;
This->desc = *pDesc;
- This->stride = util_format_get_stride(This->base.info.format, pDesc->Width);
- This->stride = align(This->stride, 4);
-
- if (!pResource && !This->data) {
- const unsigned size = This->stride *
- util_format_get_nblocksy(This->base.info.format, This->desc.Height);
+ This->stride = nine_format_get_stride(This->base.info.format, pDesc->Width);
- DBG("(%p(This=%p),level=%u) Allocating 0x%x bytes of system memory.\n",
- This->base.base.container, This, This->level, size);
-
- This->data = (uint8_t *)MALLOC(size);
- if (!This->data)
- return E_OUTOFMEMORY;
- This->manage_data = TRUE;
- } else {
- if (pResource && NineSurface9_IsOffscreenPlain(This))
- pResource->flags |= NINE_RESOURCE_FLAG_LOCKABLE; /* why setting this flag there ? too late ? should be before NineResource9_ctor call perhaps ? */
- }
+ if (pResource && NineSurface9_IsOffscreenPlain(This))
+ pResource->flags |= NINE_RESOURCE_FLAG_LOCKABLE;
NineSurface9_Dump(This);
pipe_surface_reference(&This->surface[0], NULL);
pipe_surface_reference(&This->surface[1], NULL);
- /* release allocated system memory for non-D3DPOOL_DEFAULT resources */
- if (This->manage_data && This->data)
+ /* Release system memory when we have to manage it (no parent) */
+ if (!This->base.base.container && This->data)
FREE(This->data);
NineResource9_dtor(&This->base);
}
This->desc.Height = This->base.info.height0 = resource->height0;
This->desc.MultiSampleType = This->base.info.nr_samples = resource->nr_samples;
- This->stride = util_format_get_stride(This->base.info.format,
+ This->stride = nine_format_get_stride(This->base.info.format,
This->desc.Width);
- This->stride = align(This->stride, 4);
pipe_surface_reference(&This->surface[0], NULL);
pipe_surface_reference(&This->surface[1], NULL);
D3DSURFACE_DESC desc;
uint8_t *data; /* system memory backing */
- boolean manage_data;
unsigned stride; /* for system memory backing */
/* wine doesn't even use these, 2 will be enough */
* 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"
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,
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));
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))
FREE(This->surfaces);
}
+ if (This->managed_buffer)
+ FREE(This->managed_buffer);
+
NineBaseTexture9_dtor(&This->base);
}
struct NineBaseTexture9 base;
struct NineSurface9 **surfaces;
struct pipe_box dirty_rect; /* covers all mip levels */
+ uint8_t *managed_buffer;
};
static INLINE struct NineTexture9 *
NineTexture9( void *data )