{
struct NineSurface9 *dst = NineSurface9(pDestinationSurface);
struct NineSurface9 *src = NineSurface9(pSourceSurface);
+ int copy_width, copy_height;
+ RECT destRect;
DBG("This=%p pSourceSurface=%p pDestinationSurface=%p "
"pSourceRect=%p pDestPoint=%p\n", This,
if (pDestPoint)
DBG("pDestPoint = (%u,%u)\n", pDestPoint->x, pDestPoint->y);
+ user_assert(dst && src, D3DERR_INVALIDCALL);
+
user_assert(dst->base.pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL);
user_assert(src->base.pool == D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL);
user_assert(dst->desc.MultiSampleType == D3DMULTISAMPLE_NONE, D3DERR_INVALIDCALL);
user_assert(src->desc.MultiSampleType == D3DMULTISAMPLE_NONE, D3DERR_INVALIDCALL);
- return NineSurface9_CopySurface(dst, src, pDestPoint, pSourceRect);
+ user_assert(!src->lock_count, D3DERR_INVALIDCALL);
+ user_assert(!dst->lock_count, D3DERR_INVALIDCALL);
+
+ user_assert(dst->desc.Format == src->desc.Format, D3DERR_INVALIDCALL);
+ user_assert(!depth_stencil_format(dst->desc.Format), D3DERR_INVALIDCALL);
+
+ if (pSourceRect) {
+ copy_width = pSourceRect->right - pSourceRect->left;
+ copy_height = pSourceRect->bottom - pSourceRect->top;
+
+ user_assert(pSourceRect->left >= 0 &&
+ copy_width > 0 &&
+ pSourceRect->right <= src->desc.Width &&
+ pSourceRect->top >= 0 &&
+ copy_height > 0 &&
+ pSourceRect->bottom <= src->desc.Height,
+ D3DERR_INVALIDCALL);
+ } else {
+ copy_width = src->desc.Width;
+ copy_height = src->desc.Height;
+ }
+
+ destRect.right = copy_width;
+ destRect.bottom = copy_height;
+
+ if (pDestPoint) {
+ user_assert(pDestPoint->x >= 0 && pDestPoint->y >= 0,
+ D3DERR_INVALIDCALL);
+ destRect.right += pDestPoint->x;
+ destRect.bottom += pDestPoint->y;
+ }
+
+ user_assert(destRect.right <= dst->desc.Width &&
+ destRect.bottom <= dst->desc.Height,
+ D3DERR_INVALIDCALL);
+
+ if (compressed_format(dst->desc.Format)) {
+ const unsigned w = util_format_get_blockwidth(dst->base.info.format);
+ const unsigned h = util_format_get_blockheight(dst->base.info.format);
+
+ if (pDestPoint) {
+ user_assert(!(pDestPoint->x % w) && !(pDestPoint->y % h),
+ D3DERR_INVALIDCALL);
+ }
+
+ if (pSourceRect) {
+ user_assert(!(pSourceRect->left % w) && !(pSourceRect->top % h),
+ D3DERR_INVALIDCALL);
+ }
+ if (!(copy_width == src->desc.Width &&
+ copy_width == dst->desc.Width &&
+ copy_height == src->desc.Height &&
+ copy_height == dst->desc.Height)) {
+ user_assert(!(copy_width % w) && !(copy_height % h),
+ D3DERR_INVALIDCALL);
+ }
+ }
+
+ NineSurface9_CopyMemToDefault(dst, src, pDestPoint, pSourceRect);
+
+ return D3D_OK;
}
HRESULT WINAPI
struct NineTexture9 *src = NineTexture9(srcb);
for (l = 0; l <= last_level; ++l, ++m)
- NineSurface9_CopySurface(dst->surfaces[l],
- src->surfaces[m], NULL, NULL);
+ NineSurface9_CopyMemToDefault(dst->surfaces[l],
+ src->surfaces[m], NULL, NULL);
} else
if (dstb->base.type == D3DRTYPE_CUBETEXTURE) {
struct NineCubeTexture9 *dst = NineCubeTexture9(dstb);
/* GPUs usually have them stored as arrays of mip-mapped 2D textures. */
for (z = 0; z < 6; ++z) {
for (l = 0; l <= last_level; ++l, ++m) {
- NineSurface9_CopySurface(dst->surfaces[l * 6 + z],
- src->surfaces[m * 6 + z], NULL, NULL);
+ NineSurface9_CopyMemToDefault(dst->surfaces[l * 6 + z],
+ src->surfaces[m * 6 + z], NULL, NULL);
}
m -= l;
}
user_assert(dst->desc.MultiSampleType < 2, D3DERR_INVALIDCALL);
user_assert(src->desc.MultiSampleType < 2, D3DERR_INVALIDCALL);
- return NineSurface9_CopySurface(dst, src, NULL, NULL);
+ user_assert(src->desc.Width == dst->desc.Width, D3DERR_INVALIDCALL);
+ user_assert(src->desc.Height == dst->desc.Height, D3DERR_INVALIDCALL);
+
+ NineSurface9_CopyDefaultToMem(dst, src);
+
+ return D3D_OK;
}
HRESULT WINAPI
(void *)NineSurface9_ReleaseDC
};
-HRESULT
-NineSurface9_CopySurface( struct NineSurface9 *This,
- struct NineSurface9 *From,
- const POINT *pDestPoint,
- const RECT *pSourceRect )
+/* When this function is called, we have already checked
+ * The copy regions fit the surfaces */
+void
+NineSurface9_CopyMemToDefault( struct NineSurface9 *This,
+ struct NineSurface9 *From,
+ const POINT *pDestPoint,
+ const RECT *pSourceRect )
{
struct pipe_context *pipe = This->pipe;
struct pipe_resource *r_dst = This->base.resource;
- struct pipe_resource *r_src = From->base.resource;
- struct pipe_transfer *transfer;
- struct pipe_box src_box;
struct pipe_box dst_box;
- uint8_t *p_dst;
const uint8_t *p_src;
+ int src_x, src_y, dst_x, dst_y, copy_width, copy_height;
- DBG("This=%p From=%p pDestPoint=%p pSourceRect=%p\n",
- This, From, pDestPoint, pSourceRect);
-
- assert(This->base.pool != D3DPOOL_MANAGED &&
- From->base.pool != D3DPOOL_MANAGED);
+ assert(This->base.pool == D3DPOOL_DEFAULT &&
+ From->base.pool == D3DPOOL_SYSTEMMEM);
- user_assert(This->desc.Format == From->desc.Format, D3DERR_INVALIDCALL);
+ if (pDestPoint) {
+ dst_x = pDestPoint->x;
+ dst_y = pDestPoint->y;
+ } else {
+ dst_x = 0;
+ dst_y = 0;
+ }
- dst_box.x = pDestPoint ? pDestPoint->x : 0;
- dst_box.y = pDestPoint ? pDestPoint->y : 0;
+ if (pSourceRect) {
+ src_x = pSourceRect->left;
+ src_y = pSourceRect->top;
+ copy_width = pSourceRect->right - pSourceRect->left;
+ copy_height = pSourceRect->bottom - pSourceRect->top;
+ } else {
+ src_x = 0;
+ src_y = 0;
+ copy_width = From->desc.Width;
+ copy_height = From->desc.Height;
+ }
- user_assert(dst_box.x >= 0 &&
- dst_box.y >= 0, D3DERR_INVALIDCALL);
+ u_box_2d_zslice(dst_x, dst_y, This->layer,
+ copy_width, copy_height, &dst_box);
- dst_box.z = This->layer;
- src_box.z = From->layer;
+ p_src = NineSurface9_GetSystemMemPointer(From, src_x, src_y);
- dst_box.depth = 1;
- src_box.depth = 1;
+ pipe->transfer_inline_write(pipe, r_dst, This->level,
+ 0, /* WRITE|DISCARD are implicit */
+ &dst_box, p_src, From->stride, 0);
- if (pSourceRect) {
- /* make sure it doesn't range outside the source surface */
- user_assert(pSourceRect->left >= 0 &&
- pSourceRect->right <= From->desc.Width &&
- pSourceRect->top >= 0 &&
- pSourceRect->bottom <= From->desc.Height,
- D3DERR_INVALIDCALL);
- if (rect_to_pipe_box_xy_only_clamp(&src_box, pSourceRect))
- return D3D_OK;
- } else {
- src_box.x = 0;
- src_box.y = 0;
- src_box.width = From->desc.Width;
- src_box.height = From->desc.Height;
- }
+ NineSurface9_MarkContainerDirty(This);
+}
- /* limits */
- dst_box.width = This->desc.Width - dst_box.x;
- dst_box.height = This->desc.Height - dst_box.y;
+void
+NineSurface9_CopyDefaultToMem( struct NineSurface9 *This,
+ struct NineSurface9 *From )
+{
+ struct pipe_context *pipe = This->pipe;
+ struct pipe_resource *r_src = From->base.resource;
+ struct pipe_transfer *transfer;
+ struct pipe_box src_box;
+ uint8_t *p_dst;
+ const uint8_t *p_src;
- user_assert(src_box.width <= dst_box.width &&
- src_box.height <= dst_box.height, D3DERR_INVALIDCALL);
+ assert(This->base.pool == D3DPOOL_SYSTEMMEM &&
+ From->base.pool == D3DPOOL_DEFAULT);
- dst_box.width = src_box.width;
- dst_box.height = src_box.height;
+ assert(This->desc.Width == From->desc.Width);
+ assert(This->desc.Height == From->desc.Height);
- /* check source block align for compressed textures */
- if (util_format_is_compressed(From->base.info.format) &&
- ((src_box.width != From->desc.Width) ||
- (src_box.height != From->desc.Height))) {
- const unsigned w = util_format_get_blockwidth(From->base.info.format);
- const unsigned h = util_format_get_blockheight(From->base.info.format);
- user_assert(!(src_box.width % w) &&
- !(src_box.height % h),
- D3DERR_INVALIDCALL);
- }
+ u_box_origin_2d(This->desc.Width, This->desc.Height, &src_box);
+ src_box.z = From->layer;
- /* check destination block align for compressed textures */
- if (util_format_is_compressed(This->base.info.format) &&
- ((dst_box.width != This->desc.Width) ||
- (dst_box.height != This->desc.Height) ||
- dst_box.x != 0 ||
- dst_box.y != 0)) {
- const unsigned w = util_format_get_blockwidth(This->base.info.format);
- const unsigned h = util_format_get_blockheight(This->base.info.format);
- user_assert(!(dst_box.x % w) && !(dst_box.width % w) &&
- !(dst_box.y % h) && !(dst_box.height % h),
- D3DERR_INVALIDCALL);
- }
+ p_src = pipe->transfer_map(pipe, r_src, From->level,
+ PIPE_TRANSFER_READ,
+ &src_box, &transfer);
+ p_dst = NineSurface9_GetSystemMemPointer(This, 0, 0);
- if (r_dst && r_src) {
- pipe->resource_copy_region(pipe,
- r_dst, This->level,
- dst_box.x, dst_box.y, dst_box.z,
- r_src, From->level,
- &src_box);
- } else
- if (r_dst) {
- p_src = NineSurface9_GetSystemMemPointer(From, src_box.x, src_box.y);
-
- pipe->transfer_inline_write(pipe, r_dst, This->level,
- 0, /* WRITE|DISCARD are implicit */
- &dst_box, p_src, From->stride, 0);
- } else
- if (r_src) {
- p_dst = NineSurface9_GetSystemMemPointer(This, 0, 0);
-
- p_src = pipe->transfer_map(pipe, r_src, From->level,
- PIPE_TRANSFER_READ,
- &src_box, &transfer);
- if (!p_src)
- return D3DERR_DRIVERINTERNALERROR;
-
- util_copy_rect(p_dst, This->base.info.format,
- This->stride, dst_box.x, dst_box.y,
- dst_box.width, dst_box.height,
- p_src,
- transfer->stride, src_box.x, src_box.y);
-
- pipe->transfer_unmap(pipe, transfer);
- } else {
- p_dst = NineSurface9_GetSystemMemPointer(This, 0, 0);
- p_src = NineSurface9_GetSystemMemPointer(From, 0, 0);
-
- util_copy_rect(p_dst, This->base.info.format,
- This->stride, dst_box.x, dst_box.y,
- dst_box.width, dst_box.height,
- p_src,
- From->stride, src_box.x, src_box.y);
- }
+ assert (p_src && p_dst);
- if (This->base.pool == D3DPOOL_DEFAULT)
- NineSurface9_MarkContainerDirty(This);
- if (!r_dst && This->base.resource)
- NineSurface9_AddDirtyRect(This, &dst_box);
+ util_copy_rect(p_dst, This->base.info.format,
+ This->stride, 0, 0,
+ This->desc.Width, This->desc.Height,
+ p_src,
+ transfer->stride, 0, 0);
- return D3D_OK;
+ pipe->transfer_unmap(pipe, transfer);
}
+
/* Gladly, rendering to a MANAGED surface is not permitted, so we will
* never have to do the reverse, i.e. download the surface.
*/