* 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 = NULL;
D3DSURFACE_DESC sfdesc;
+ void *p;
HRESULT hr;
DBG("This=%p pParams=%p EdgeLength=%u Levels=%u Usage=%d "
This, pParams, EdgeLength, Levels, Usage,
Format, Pool, pSharedHandle);
- user_assert(!(Usage & D3DUSAGE_AUTOGENMIPMAP) ||
- (Pool != D3DPOOL_SYSTEMMEM && Levels <= 1), D3DERR_INVALIDCALL);
+ user_assert(EdgeLength, D3DERR_INVALIDCALL);
+ /* user_assert(!pSharedHandle || Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); */
user_assert(!pSharedHandle, D3DERR_INVALIDCALL); /* TODO */
+ user_assert(!(Usage & D3DUSAGE_AUTOGENMIPMAP) ||
+ (Pool != D3DPOOL_SYSTEMMEM && Levels <= 1), D3DERR_INVALIDCALL);
+
if (Usage & D3DUSAGE_AUTOGENMIPMAP)
Levels = 0;
if (pf == PIPE_FORMAT_NONE)
return D3DERR_INVALIDCALL;
- /* We support ATI1 and ATI2 hacks only for 2D textures */
- if (Format == D3DFMT_ATI1 || Format == D3DFMT_ATI2)
- return D3DERR_INVALIDCALL;
+ if (compressed_format(Format)) {
+ const unsigned w = util_format_get_blockwidth(pf);
+ const unsigned h = util_format_get_blockheight(pf);
+
+ user_assert(!(EdgeLength % w) && !(EdgeLength % h), D3DERR_INVALIDCALL);
+ }
info->screen = pParams->device->screen;
info->target = PIPE_TEXTURE_CUBE;
PIPE_BIND_TRANSFER_READ |
PIPE_BIND_TRANSFER_WRITE;
}
+ if (Usage & D3DUSAGE_SOFTWAREPROCESSING)
+ 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 = align_malloc(6 * face_size, 32);
+ if (!This->managed_buffer)
+ return E_OUTOFMEMORY;
+ }
This->surfaces = CALLOC(6 * (info->last_level + 1), sizeof(*This->surfaces));
if (!This->surfaces)
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 */
+
+ for (i = 0; i < 6; ++i) {
+ /* Textures start initially dirty */
+ This->dirty_rect[i].width = EdgeLength;
+ This->dirty_rect[i].height = EdgeLength;
This->dirty_rect[i].depth = 1;
+ }
return D3D_OK;
}
FREE(This->surfaces);
}
+ if (This->managed_buffer)
+ align_free(This->managed_buffer);
+
NineBaseTexture9_dtor(&This->base);
}
user_assert(FaceType < 6, D3DERR_INVALIDCALL);
if (This->base.base.pool != D3DPOOL_MANAGED) {
- if (This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP)
+ if (This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP) {
This->base.dirty_mip = TRUE;
+ BASETEX_REGISTER_UPDATE(&This->base);
+ }
return D3D_OK;
}
- This->base.dirty = TRUE;
- BASETEX_REGISTER_UPDATE(&This->base);
+ if (This->base.base.pool == D3DPOOL_MANAGED) {
+ This->base.managed.dirty = TRUE;
+ BASETEX_REGISTER_UPDATE(&This->base);
+ }
if (!pDirtyRect) {
u_box_origin_2d(This->base.base.info.width0,
rect_to_pipe_box_clamp(&box, pDirtyRect);
u_box_union_2d(&This->dirty_rect[FaceType], &This->dirty_rect[FaceType],
&box);
+ (void) u_box_clip_2d(&This->dirty_rect[FaceType],
+ &This->dirty_rect[FaceType],
+ This->base.base.info.width0,
+ This->base.base.info.height0);
}
return D3D_OK;
}