mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 00:49:04 +02:00
st/nine: Split NineSurface9_CopySurface
NineSurface9_CopySurface was supporting more cases than what we needed, and doing checks that were innapropriate for some NineSurface9_CopySurface use cases. This patch splits it into two for the two use cases, and moves the checks to the caller. This patch also adds a few checks to NineDevice9_UpdateSurface Signed-off-by: Axel Davy <axel.davy@ens.fr>
This commit is contained in:
parent
3f36ad732c
commit
bc42c29013
5 changed files with 173 additions and 129 deletions
|
|
@ -1185,6 +1185,8 @@ NineDevice9_UpdateSurface( struct NineDevice9 *This,
|
|||
{
|
||||
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,
|
||||
|
|
@ -1196,13 +1198,75 @@ NineDevice9_UpdateSurface( struct NineDevice9 *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
|
||||
|
|
@ -1267,8 +1331,8 @@ NineDevice9_UpdateTexture( struct NineDevice9 *This,
|
|||
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);
|
||||
|
|
@ -1278,8 +1342,8 @@ NineDevice9_UpdateTexture( struct NineDevice9 *This,
|
|||
/* 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;
|
||||
}
|
||||
|
|
@ -1320,7 +1384,12 @@ NineDevice9_GetRenderTargetData( struct NineDevice9 *This,
|
|||
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
|
||||
|
|
|
|||
|
|
@ -164,6 +164,23 @@ pipe_to_d3d9_format(enum pipe_format format)
|
|||
return nine_pipe_to_d3d9_format_map[format];
|
||||
}
|
||||
|
||||
/* ATI1 and ATI2 are not officially compressed in d3d9 */
|
||||
static inline boolean
|
||||
compressed_format( D3DFORMAT fmt )
|
||||
{
|
||||
switch (fmt) {
|
||||
case D3DFMT_DXT1:
|
||||
case D3DFMT_DXT2:
|
||||
case D3DFMT_DXT3:
|
||||
case D3DFMT_DXT4:
|
||||
case D3DFMT_DXT5:
|
||||
return TRUE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static inline boolean
|
||||
depth_stencil_format( D3DFORMAT fmt )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -463,140 +463,92 @@ IDirect3DSurface9Vtbl NineSurface9_vtable = {
|
|||
(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_box dst_box;
|
||||
const uint8_t *p_src;
|
||||
int src_x, src_y, dst_x, dst_y, copy_width, copy_height;
|
||||
|
||||
assert(This->base.pool == D3DPOOL_DEFAULT &&
|
||||
From->base.pool == D3DPOOL_SYSTEMMEM);
|
||||
|
||||
if (pDestPoint) {
|
||||
dst_x = pDestPoint->x;
|
||||
dst_y = pDestPoint->y;
|
||||
} else {
|
||||
dst_x = 0;
|
||||
dst_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;
|
||||
}
|
||||
|
||||
u_box_2d_zslice(dst_x, dst_y, This->layer,
|
||||
copy_width, copy_height, &dst_box);
|
||||
|
||||
p_src = NineSurface9_GetSystemMemPointer(From, src_x, src_y);
|
||||
|
||||
pipe->transfer_inline_write(pipe, r_dst, This->level,
|
||||
0, /* WRITE|DISCARD are implicit */
|
||||
&dst_box, p_src, From->stride, 0);
|
||||
|
||||
NineSurface9_MarkContainerDirty(This);
|
||||
}
|
||||
|
||||
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;
|
||||
struct pipe_box dst_box;
|
||||
uint8_t *p_dst;
|
||||
const uint8_t *p_src;
|
||||
|
||||
DBG("This=%p From=%p pDestPoint=%p pSourceRect=%p\n",
|
||||
This, From, pDestPoint, pSourceRect);
|
||||
assert(This->base.pool == D3DPOOL_SYSTEMMEM &&
|
||||
From->base.pool == D3DPOOL_DEFAULT);
|
||||
|
||||
assert(This->base.pool != D3DPOOL_MANAGED &&
|
||||
From->base.pool != D3DPOOL_MANAGED);
|
||||
assert(This->desc.Width == From->desc.Width);
|
||||
assert(This->desc.Height == From->desc.Height);
|
||||
|
||||
user_assert(This->desc.Format == From->desc.Format, D3DERR_INVALIDCALL);
|
||||
|
||||
dst_box.x = pDestPoint ? pDestPoint->x : 0;
|
||||
dst_box.y = pDestPoint ? pDestPoint->y : 0;
|
||||
|
||||
user_assert(dst_box.x >= 0 &&
|
||||
dst_box.y >= 0, D3DERR_INVALIDCALL);
|
||||
|
||||
dst_box.z = This->layer;
|
||||
u_box_origin_2d(This->desc.Width, This->desc.Height, &src_box);
|
||||
src_box.z = From->layer;
|
||||
|
||||
dst_box.depth = 1;
|
||||
src_box.depth = 1;
|
||||
p_src = pipe->transfer_map(pipe, r_src, From->level,
|
||||
PIPE_TRANSFER_READ,
|
||||
&src_box, &transfer);
|
||||
p_dst = NineSurface9_GetSystemMemPointer(This, 0, 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;
|
||||
}
|
||||
assert (p_src && p_dst);
|
||||
|
||||
/* limits */
|
||||
dst_box.width = This->desc.Width - dst_box.x;
|
||||
dst_box.height = This->desc.Height - dst_box.y;
|
||||
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);
|
||||
|
||||
user_assert(src_box.width <= dst_box.width &&
|
||||
src_box.height <= dst_box.height, D3DERR_INVALIDCALL);
|
||||
|
||||
dst_box.width = src_box.width;
|
||||
dst_box.height = src_box.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);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (This->base.pool == D3DPOOL_DEFAULT)
|
||||
NineSurface9_MarkContainerDirty(This);
|
||||
if (!r_dst && This->base.resource)
|
||||
NineSurface9_AddDirtyRect(This, &dst_box);
|
||||
|
||||
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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -125,11 +125,15 @@ HRESULT
|
|||
NineSurface9_UploadSelf( struct NineSurface9 *This,
|
||||
const struct pipe_box *damaged );
|
||||
|
||||
HRESULT
|
||||
NineSurface9_CopySurface( struct NineSurface9 *This,
|
||||
struct NineSurface9 *From,
|
||||
const POINT *pDestPoint,
|
||||
const RECT *pSourceRect );
|
||||
void
|
||||
NineSurface9_CopyMemToDefault( struct NineSurface9 *This,
|
||||
struct NineSurface9 *From,
|
||||
const POINT *pDestPoint,
|
||||
const RECT *pSourceRect );
|
||||
|
||||
void
|
||||
NineSurface9_CopyDefaultToMem( struct NineSurface9 *This,
|
||||
struct NineSurface9 *From );
|
||||
|
||||
static inline boolean
|
||||
NineSurface9_IsOffscreenPlain (struct NineSurface9 *This )
|
||||
|
|
|
|||
|
|
@ -859,6 +859,8 @@ NineSwapChain9_GetFrontBufferData( struct NineSwapChain9 *This,
|
|||
DBG("GetFrontBufferData: This=%p pDestSurface=%p\n",
|
||||
This, pDestSurface);
|
||||
|
||||
user_assert(dest_surface->base.pool == D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL);
|
||||
|
||||
width = dest_surface->desc.Width;
|
||||
height = dest_surface->desc.Height;
|
||||
|
||||
|
|
@ -873,7 +875,7 @@ NineSwapChain9_GetFrontBufferData( struct NineSwapChain9 *This,
|
|||
desc.MultiSampleQuality = 0;
|
||||
desc.Width = width;
|
||||
desc.Height = height;
|
||||
/* NineSurface9_CopySurface needs same format. */
|
||||
/* NineSurface9_CopyDefaultToMem needs same format. */
|
||||
desc.Format = dest_surface->desc.Format;
|
||||
desc.Usage = D3DUSAGE_RENDERTARGET;
|
||||
hr = NineSurface9_new(pDevice, NineUnknown(This), temp_resource, NULL, 0,
|
||||
|
|
@ -886,7 +888,7 @@ NineSwapChain9_GetFrontBufferData( struct NineSwapChain9 *This,
|
|||
|
||||
ID3DPresent_FrontBufferCopy(This->present, temp_handle);
|
||||
|
||||
NineSurface9_CopySurface(dest_surface, temp_surface, NULL, NULL);
|
||||
NineSurface9_CopyDefaultToMem(dest_surface, temp_surface);
|
||||
|
||||
ID3DPresent_DestroyD3DWindowBuffer(This->present, temp_handle);
|
||||
NineUnknown_Destroy(NineUnknown(temp_surface));
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue