D3D9: Fixed blit and read back.

This commit is contained in:
Branimir Karadžić 2015-10-22 21:30:55 -07:00
parent f7130318c0
commit 0c0542b2e6
2 changed files with 258 additions and 48 deletions

View file

@ -534,8 +534,8 @@ namespace bgfx { namespace d3d9
| BGFX_CAPS_FRAGMENT_DEPTH | BGFX_CAPS_FRAGMENT_DEPTH
| BGFX_CAPS_SWAP_CHAIN | BGFX_CAPS_SWAP_CHAIN
| ( (UINT16_MAX < m_caps.MaxVertexIndex) ? BGFX_CAPS_INDEX32 : 0) | ( (UINT16_MAX < m_caps.MaxVertexIndex) ? BGFX_CAPS_INDEX32 : 0)
// | ( (m_caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) ? BGFX_CAPS_TEXTURE_BLIT : 0) | ( (m_caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) ? BGFX_CAPS_TEXTURE_BLIT : 0)
// | BGFX_CAPS_TEXTURE_READ_BACK | BGFX_CAPS_TEXTURE_READ_BACK
); );
g_caps.maxTextureSize = uint16_t(bx::uint32_min(m_caps.MaxTextureWidth, m_caps.MaxTextureHeight) ); g_caps.maxTextureSize = uint16_t(bx::uint32_min(m_caps.MaxTextureWidth, m_caps.MaxTextureHeight) );
// g_caps.maxVertexIndex = m_caps.MaxVertexIndex; // g_caps.maxVertexIndex = m_caps.MaxVertexIndex;
@ -581,7 +581,9 @@ namespace bgfx { namespace d3d9
for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii) for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii)
{ {
uint8_t support = SUCCEEDED(m_d3d9->CheckDeviceFormat(m_adapter uint8_t support = 0;
support |= SUCCEEDED(m_d3d9->CheckDeviceFormat(m_adapter
, m_deviceType , m_deviceType
, adapterFormat , adapterFormat
, 0 , 0
@ -2324,25 +2326,31 @@ namespace bgfx { namespace d3d9
void TextureD3D9::createTexture(uint32_t _width, uint32_t _height, uint8_t _numMips) void TextureD3D9::createTexture(uint32_t _width, uint32_t _height, uint8_t _numMips)
{ {
m_type = Texture2D; m_type = Texture2D;
const TextureFormat::Enum fmt = (TextureFormat::Enum)m_textureFormat; const TextureFormat::Enum fmt = (TextureFormat::Enum)m_textureFormat;
DWORD usage = 0; DWORD usage = 0;
D3DPOOL pool = s_renderD3D9->m_pool; D3DPOOL pool = D3DPOOL_DEFAULT;
const bool renderTarget = 0 != (m_flags&BGFX_TEXTURE_RT_MASK); const bool renderTarget = 0 != (m_flags&BGFX_TEXTURE_RT_MASK);
const bool blit = 0 != (m_flags&BGFX_TEXTURE_BLIT_DST); const bool blit = 0 != (m_flags&BGFX_TEXTURE_BLIT_DST);
const bool readBack = 0 != (m_flags&BGFX_TEXTURE_READ_BACK);
if (isDepth(fmt) ) if (isDepth(fmt) )
{ {
usage = D3DUSAGE_DEPTHSTENCIL; usage = D3DUSAGE_DEPTHSTENCIL;
pool = D3DPOOL_DEFAULT; }
else if (readBack)
{
usage = 0;
pool = D3DPOOL_SYSTEMMEM;
} }
else if (renderTarget || blit) else if (renderTarget || blit)
{ {
usage = D3DUSAGE_RENDERTARGET; usage = D3DUSAGE_RENDERTARGET;
pool = D3DPOOL_DEFAULT;
} }
IDirect3DDevice9* device = s_renderD3D9->m_device;
if (renderTarget) if (renderTarget)
{ {
uint32_t msaaQuality = ( (m_flags&BGFX_TEXTURE_RT_MSAA_MASK)>>BGFX_TEXTURE_RT_MSAA_SHIFT); uint32_t msaaQuality = ( (m_flags&BGFX_TEXTURE_RT_MSAA_MASK)>>BGFX_TEXTURE_RT_MSAA_SHIFT);
@ -2357,7 +2365,7 @@ namespace bgfx { namespace d3d9
if (isDepth(fmt) ) if (isDepth(fmt) )
{ {
DX_CHECK(s_renderD3D9->m_device->CreateDepthStencilSurface( DX_CHECK(device->CreateDepthStencilSurface(
m_width m_width
, m_height , m_height
, s_textureFormat[m_textureFormat].m_fmt , s_textureFormat[m_textureFormat].m_fmt
@ -2370,7 +2378,7 @@ namespace bgfx { namespace d3d9
} }
else else
{ {
DX_CHECK(s_renderD3D9->m_device->CreateRenderTarget( DX_CHECK(device->CreateRenderTarget(
m_width m_width
, m_height , m_height
, s_textureFormat[m_textureFormat].m_fmt , s_textureFormat[m_textureFormat].m_fmt
@ -2391,7 +2399,7 @@ namespace bgfx { namespace d3d9
} }
} }
DX_CHECK(s_renderD3D9->m_device->CreateTexture(_width DX_CHECK(device->CreateTexture(_width
, _height , _height
, _numMips , _numMips
, usage , usage
@ -2401,6 +2409,57 @@ namespace bgfx { namespace d3d9
, NULL , NULL
) ); ) );
if (!renderTarget
&& !readBack)
{
if (NULL == m_staging)
{
DX_CHECK(device->CreateTexture(_width
, _height
, _numMips
, 0
, s_textureFormat[fmt].m_fmt
, D3DPOOL_SYSTEMMEM
, &m_staging2d
, NULL
) );
}
else
{
const ImageBlockInfo& blockInfo = getBlockInfo(fmt);
const uint32_t blockWidth = blockInfo.blockWidth;
const uint32_t blockHeight = blockInfo.blockHeight;
for (uint8_t lod = 0, num = _numMips; lod < num; ++lod)
{
if ( (m_width >>lod) < blockWidth
|| (m_height>>lod) < blockHeight)
{
break;
}
uint32_t mipWidth = bx::uint32_max(blockWidth, ( ( (m_width >>lod) + blockWidth - 1) / blockWidth )*blockWidth);
uint32_t mipHeight = bx::uint32_max(blockHeight, ( ( (m_height>>lod) + blockHeight - 1) / blockHeight)*blockHeight);
IDirect3DSurface9* srcSurface;
DX_CHECK(m_staging2d->GetSurfaceLevel(lod, &srcSurface) );
IDirect3DSurface9* dstSurface = getSurface(0, lod);
RECT srcRect = { LONG(0), LONG(0), LONG(mipWidth), LONG(mipHeight) };
POINT dstPoint = { LONG(0), LONG(0) };
DX_CHECK(device->UpdateSurface(srcSurface
, &srcRect
, dstSurface
, &dstPoint
) );
srcSurface->Release();
dstSurface->Release();
}
}
}
BGFX_FATAL(NULL != m_texture2d, Fatal::UnableToCreateTexture, "Failed to create texture (size: %dx%d, mips: %d, fmt: %d)." BGFX_FATAL(NULL != m_texture2d, Fatal::UnableToCreateTexture, "Failed to create texture (size: %dx%d, mips: %d, fmt: %d)."
, _width , _width
, _height , _height
@ -2414,17 +2473,37 @@ namespace bgfx { namespace d3d9
m_type = Texture3D; m_type = Texture3D;
const TextureFormat::Enum fmt = (TextureFormat::Enum)m_textureFormat; const TextureFormat::Enum fmt = (TextureFormat::Enum)m_textureFormat;
DX_CHECK(s_renderD3D9->m_device->CreateVolumeTexture(_width IDirect3DDevice9* device = s_renderD3D9->m_device;
DX_CHECK(device->CreateVolumeTexture(_width
, _height , _height
, _depth , _depth
, _numMips , _numMips
, 0 , 0
, s_textureFormat[fmt].m_fmt , s_textureFormat[fmt].m_fmt
, s_renderD3D9->m_pool , D3DPOOL_DEFAULT
, &m_texture3d , &m_texture3d
, NULL , NULL
) ); ) );
if (NULL == m_staging)
{
DX_CHECK(device->CreateVolumeTexture(_width
, _height
, _depth
, _numMips
, 0
, s_textureFormat[fmt].m_fmt
, D3DPOOL_SYSTEMMEM
, &m_staging3d
, NULL
) );
}
else
{
DX_CHECK(m_texture3d->AddDirtyBox(NULL) );
DX_CHECK(device->UpdateTexture(m_staging3d, m_texture3d) );
}
BGFX_FATAL(NULL != m_texture3d, Fatal::UnableToCreateTexture, "Failed to create volume texture (size: %dx%dx%d, mips: %d, fmt: %s)." BGFX_FATAL(NULL != m_texture3d, Fatal::UnableToCreateTexture, "Failed to create volume texture (size: %dx%dx%d, mips: %d, fmt: %s)."
, _width , _width
, _height , _height
@ -2440,30 +2519,80 @@ namespace bgfx { namespace d3d9
const TextureFormat::Enum fmt = (TextureFormat::Enum)m_textureFormat; const TextureFormat::Enum fmt = (TextureFormat::Enum)m_textureFormat;
DWORD usage = 0; DWORD usage = 0;
D3DPOOL pool = s_renderD3D9->m_pool;
const bool renderTarget = 0 != (m_flags&BGFX_TEXTURE_RT_MASK); const bool renderTarget = 0 != (m_flags&BGFX_TEXTURE_RT_MASK);
const bool blit = 0 != (m_flags&BGFX_TEXTURE_BLIT_DST); const bool blit = 0 != (m_flags&BGFX_TEXTURE_BLIT_DST);
if (isDepth(fmt) ) if (isDepth(fmt) )
{ {
usage = D3DUSAGE_DEPTHSTENCIL; usage = D3DUSAGE_DEPTHSTENCIL;
pool = D3DPOOL_DEFAULT;
} }
else if (renderTarget || blit) else if (renderTarget || blit)
{ {
usage = D3DUSAGE_RENDERTARGET; usage = D3DUSAGE_RENDERTARGET;
pool = D3DPOOL_DEFAULT;
} }
DX_CHECK(s_renderD3D9->m_device->CreateCubeTexture(_edge IDirect3DDevice9* device = s_renderD3D9->m_device;
DX_CHECK(device->CreateCubeTexture(_edge
, _numMips , _numMips
, usage , usage
, s_textureFormat[fmt].m_fmt , s_textureFormat[fmt].m_fmt
, pool , D3DPOOL_DEFAULT
, &m_textureCube , &m_textureCube
, NULL , NULL
) ); ) );
if (!renderTarget)
{
if (NULL == m_staging)
{
DX_CHECK(device->CreateCubeTexture(_edge
, _numMips
, 0
, s_textureFormat[fmt].m_fmt
, D3DPOOL_SYSTEMMEM
, &m_stagingCube
, NULL
) );
}
else
{
const ImageBlockInfo& blockInfo = getBlockInfo(fmt);
const uint32_t blockWidth = blockInfo.blockWidth;
const uint32_t blockHeight = blockInfo.blockHeight;
for (uint8_t side = 0, numSides = 6; side < numSides; ++side)
{
for (uint8_t lod = 0, num = _numMips; lod < num; ++lod)
{
if ( (m_width >>lod) < blockWidth
|| (m_height>>lod) < blockHeight)
{
break;
}
uint32_t mipWidth = bx::uint32_max(blockWidth, ( ( (m_width >>lod) + blockWidth - 1) / blockWidth )*blockWidth);
uint32_t mipHeight = bx::uint32_max(blockHeight, ( ( (m_height>>lod) + blockHeight - 1) / blockHeight)*blockHeight);
IDirect3DSurface9* srcSurface;
DX_CHECK(m_stagingCube->GetCubeMapSurface(D3DCUBEMAP_FACES(side), lod, &srcSurface) );
IDirect3DSurface9* dstSurface = getSurface(side, lod);
RECT srcRect = { LONG(0), LONG(0), LONG(mipWidth), LONG(mipHeight) };
POINT dstPoint = { LONG(0), LONG(0) };
DX_CHECK(device->UpdateSurface(srcSurface
, &srcRect
, dstSurface
, &dstPoint
) );
srcSurface->Release();
dstSurface->Release();
}
}
}
}
BGFX_FATAL(NULL != m_textureCube, Fatal::UnableToCreateTexture, "Failed to create cube texture (edge: %d, mips: %d, fmt: %s)." BGFX_FATAL(NULL != m_textureCube, Fatal::UnableToCreateTexture, "Failed to create cube texture (edge: %d, mips: %d, fmt: %s)."
, _edge , _edge
, _numMips , _numMips
@ -2486,11 +2615,11 @@ namespace bgfx { namespace d3d9
rect.top = _rect->m_y; rect.top = _rect->m_y;
rect.right = rect.left + _rect->m_width; rect.right = rect.left + _rect->m_width;
rect.bottom = rect.top + _rect->m_height; rect.bottom = rect.top + _rect->m_height;
DX_CHECK(m_texture2d->LockRect(_lod, &lockedRect, &rect, 0) ); DX_CHECK(m_staging2d->LockRect(_lod, &lockedRect, &rect, 0) );
} }
else else
{ {
DX_CHECK(m_texture2d->LockRect(_lod, &lockedRect, NULL, 0) ); DX_CHECK(m_staging2d->LockRect(_lod, &lockedRect, NULL, 0) );
} }
_pitch = lockedRect.Pitch; _pitch = lockedRect.Pitch;
@ -2501,8 +2630,8 @@ namespace bgfx { namespace d3d9
case Texture3D: case Texture3D:
{ {
D3DLOCKED_BOX box; D3DLOCKED_BOX box;
DX_CHECK(m_texture3d->LockBox(_lod, &box, NULL, 0) ); DX_CHECK(m_staging3d->LockBox(_lod, &box, NULL, 0) );
_pitch = box.RowPitch; _pitch = box.RowPitch;
_slicePitch = box.SlicePitch; _slicePitch = box.SlicePitch;
return (uint8_t*)box.pBits; return (uint8_t*)box.pBits;
} }
@ -2514,15 +2643,15 @@ namespace bgfx { namespace d3d9
if (NULL != _rect) if (NULL != _rect)
{ {
RECT rect; RECT rect;
rect.left = _rect->m_x; rect.left = _rect->m_x;
rect.top = _rect->m_y; rect.top = _rect->m_y;
rect.right = rect.left + _rect->m_width; rect.right = rect.left + _rect->m_width;
rect.bottom = rect.top + _rect->m_height; rect.bottom = rect.top + _rect->m_height;
DX_CHECK(m_textureCube->LockRect(D3DCUBEMAP_FACES(_side), _lod, &lockedRect, &rect, 0) ); DX_CHECK(m_stagingCube->LockRect(D3DCUBEMAP_FACES(_side), _lod, &lockedRect, &rect, 0) );
} }
else else
{ {
DX_CHECK(m_textureCube->LockRect(D3DCUBEMAP_FACES(_side), _lod, &lockedRect, NULL, 0) ); DX_CHECK(m_stagingCube->LockRect(D3DCUBEMAP_FACES(_side), _lod, &lockedRect, NULL, 0) );
} }
_pitch = lockedRect.Pitch; _pitch = lockedRect.Pitch;
@ -2532,7 +2661,7 @@ namespace bgfx { namespace d3d9
} }
BX_CHECK(false, "You should not be here."); BX_CHECK(false, "You should not be here.");
_pitch = 0; _pitch = 0;
_slicePitch = 0; _slicePitch = 0;
return NULL; return NULL;
} }
@ -2543,19 +2672,61 @@ namespace bgfx { namespace d3d9
{ {
case Texture2D: case Texture2D:
{ {
DX_CHECK(m_texture2d->UnlockRect(_lod) ); DX_CHECK(m_staging2d->UnlockRect(_lod) );
IDirect3DSurface9* srcSurface;
DX_CHECK(m_staging2d->GetSurfaceLevel(0, &srcSurface) );
IDirect3DSurface9* dstSurface = getSurface(0, _lod);
const ImageBlockInfo& blockInfo = getBlockInfo(TextureFormat::Enum(m_textureFormat) );
uint32_t mipWidth = bx::uint32_max(blockInfo.blockWidth, m_width >>_lod);
uint32_t mipHeight = bx::uint32_max(blockInfo.blockHeight, m_height>>_lod);
RECT srcRect = { LONG(0), LONG(0), LONG(mipWidth), LONG(mipHeight) };
POINT dstPoint = { LONG(0), LONG(0) };
s_renderD3D9->m_device->UpdateSurface(srcSurface
, &srcRect
, dstSurface
, &dstPoint
);
srcSurface->Release();
dstSurface->Release();
} }
return; return;
case Texture3D: case Texture3D:
{ {
DX_CHECK(m_texture3d->UnlockBox(_lod) ); DX_CHECK(m_staging3d->UnlockBox(_lod) );
DX_CHECK(m_texture3d->AddDirtyBox(NULL) );
DX_CHECK(s_renderD3D9->m_device->UpdateTexture(m_staging3d, m_texture3d) );
} }
return; return;
case TextureCube: case TextureCube:
{ {
DX_CHECK(m_textureCube->UnlockRect(D3DCUBEMAP_FACES(_side), _lod) ); DX_CHECK(m_stagingCube->UnlockRect(D3DCUBEMAP_FACES(_side), _lod) );
IDirect3DSurface9* srcSurface;
DX_CHECK(m_stagingCube->GetCubeMapSurface(D3DCUBEMAP_FACES(_side), _lod, &srcSurface) );
IDirect3DSurface9* dstSurface = getSurface(_side, _lod);
const ImageBlockInfo& blockInfo = getBlockInfo(TextureFormat::Enum(m_textureFormat) );
uint32_t mipWidth = bx::uint32_max(blockInfo.blockWidth, m_width >>_lod);
uint32_t mipHeight = bx::uint32_max(blockInfo.blockHeight, m_height>>_lod);
RECT srcRect = { LONG(0), LONG(0), LONG(mipWidth), LONG(mipHeight) };
POINT dstPoint = { LONG(0), LONG(0) };
DX_CHECK(s_renderD3D9->m_device->UpdateSurface(srcSurface
, &srcRect
, dstSurface
, &dstPoint
) );
srcSurface->Release();
dstSurface->Release();
} }
return; return;
} }
@ -2570,9 +2741,9 @@ namespace bgfx { namespace d3d9
case Texture2D: case Texture2D:
{ {
RECT rect; RECT rect;
rect.left = _rect.m_x; rect.left = _rect.m_x;
rect.top = _rect.m_y; rect.top = _rect.m_y;
rect.right = rect.left + _rect.m_width; rect.right = rect.left + _rect.m_width;
rect.bottom = rect.top + _rect.m_height; rect.bottom = rect.top + _rect.m_height;
DX_CHECK(m_texture2d->AddDirtyRect(&rect) ); DX_CHECK(m_texture2d->AddDirtyRect(&rect) );
} }
@ -2581,12 +2752,12 @@ namespace bgfx { namespace d3d9
case Texture3D: case Texture3D:
{ {
D3DBOX box; D3DBOX box;
box.Left = _rect.m_x; box.Left = _rect.m_x;
box.Top = _rect.m_y; box.Top = _rect.m_y;
box.Right = box.Left + _rect.m_width; box.Right = box.Left + _rect.m_width;
box.Bottom = box.Top + _rect.m_height; box.Bottom = box.Top + _rect.m_height;
box.Front = _z; box.Front = _z;
box.Back = box.Front + _depth; box.Back = box.Front + _depth;
DX_CHECK(m_texture3d->AddDirtyBox(&box) ); DX_CHECK(m_texture3d->AddDirtyBox(&box) );
} }
return; return;
@ -2594,9 +2765,9 @@ namespace bgfx { namespace d3d9
case TextureCube: case TextureCube:
{ {
RECT rect; RECT rect;
rect.left = _rect.m_x; rect.left = _rect.m_x;
rect.top = _rect.m_y; rect.top = _rect.m_y;
rect.right = rect.left + _rect.m_width; rect.right = rect.left + _rect.m_width;
rect.bottom = rect.top + _rect.m_height; rect.bottom = rect.top + _rect.m_height;
DX_CHECK(m_textureCube->AddDirtyRect(D3DCUBEMAP_FACES(_side), &rect) ); DX_CHECK(m_textureCube->AddDirtyRect(D3DCUBEMAP_FACES(_side), &rect) );
} }
@ -2865,8 +3036,7 @@ namespace bgfx { namespace d3d9
void TextureD3D9::preReset() void TextureD3D9::preReset()
{ {
TextureFormat::Enum fmt = (TextureFormat::Enum)m_textureFormat; TextureFormat::Enum fmt = (TextureFormat::Enum)m_textureFormat;
if (TextureFormat::Unknown != fmt if (TextureFormat::Unknown != fmt)
&& (isDepth(fmt) || !!(m_flags&(BGFX_TEXTURE_RT_MASK|BGFX_TEXTURE_BLIT_DST) ) ) )
{ {
DX_RELEASE(m_ptr, 0); DX_RELEASE(m_ptr, 0);
DX_RELEASE(m_surface, 0); DX_RELEASE(m_surface, 0);
@ -2876,10 +3046,23 @@ namespace bgfx { namespace d3d9
void TextureD3D9::postReset() void TextureD3D9::postReset()
{ {
TextureFormat::Enum fmt = (TextureFormat::Enum)m_textureFormat; TextureFormat::Enum fmt = (TextureFormat::Enum)m_textureFormat;
if (TextureFormat::Unknown != fmt if (TextureFormat::Unknown != fmt)
&& (isDepth(fmt) || !!(m_flags&(BGFX_TEXTURE_RT_MASK|BGFX_TEXTURE_BLIT_DST)) ) )
{ {
createTexture(m_width, m_height, m_numMips); switch (m_type)
{
default:
case Texture2D:
createTexture(m_width, m_height, m_numMips);
break;
case Texture3D:
createVolumeTexture(m_width, m_height, m_depth, m_numMips);
break;
case TextureCube:
createCubeTexture(m_width, m_numMips);
break;
}
} }
} }
@ -3393,14 +3576,31 @@ namespace bgfx { namespace d3d9
IDirect3DSurface9* srcSurface = src.getSurface(uint8_t(blit.m_srcZ), blit.m_srcMip); IDirect3DSurface9* srcSurface = src.getSurface(uint8_t(blit.m_srcZ), blit.m_srcMip);
IDirect3DSurface9* dstSurface = dst.getSurface(uint8_t(blit.m_dstZ), blit.m_dstMip); IDirect3DSurface9* dstSurface = dst.getSurface(uint8_t(blit.m_dstZ), blit.m_dstMip);
// UpdateSurface (pool src: SYSTEMMEM, dst: DEFAULT)
// s/d T RTT RT
// T y y y
// RTT - - -
// RT - - -
//
// StretchRect (pool src and dst must be DEFAULT)
// s/d T RTT RT
// T - y y
// RTT - y y
// RT - y y
//
// GetRenderTargetData (dst must be SYSTEMMEM)
HRESULT hr = m_device->StretchRect(srcSurface HRESULT hr = m_device->StretchRect(srcSurface
, &srcRect , &srcRect
, dstSurface , dstSurface
, &dstRect , &dstRect
, D3DTEXF_NONE , D3DTEXF_NONE
); );
BX_WARN(SUCCEEDED(hr), "StretchRect failed %x.", hr); if (FAILED(hr) )
BX_UNUSED(hr); {
hr = m_device->GetRenderTargetData(srcSurface, dstSurface);
BX_WARN(SUCCEEDED(hr), "StretchRect and GetRenderTargetData failed %x.", hr);
}
srcSurface->Release(); srcSurface->Release();
dstSurface->Release(); dstSurface->Release();

View file

@ -310,6 +310,7 @@ namespace bgfx { namespace d3d9
TextureD3D9() TextureD3D9()
: m_ptr(NULL) : m_ptr(NULL)
, m_surface(NULL) , m_surface(NULL)
, m_staging(NULL)
, m_textureFormat(TextureFormat::Unknown) , m_textureFormat(TextureFormat::Unknown)
{ {
} }
@ -329,6 +330,7 @@ namespace bgfx { namespace d3d9
{ {
DX_RELEASE(m_ptr, 0); DX_RELEASE(m_ptr, 0);
DX_RELEASE(m_surface, 0); DX_RELEASE(m_surface, 0);
DX_RELEASE(m_staging, 0);
m_textureFormat = TextureFormat::Unknown; m_textureFormat = TextureFormat::Unknown;
} }
@ -350,6 +352,14 @@ namespace bgfx { namespace d3d9
}; };
IDirect3DSurface9* m_surface; IDirect3DSurface9* m_surface;
union
{
IDirect3DBaseTexture9* m_staging;
IDirect3DTexture9* m_staging2d;
IDirect3DVolumeTexture9* m_staging3d;
IDirect3DCubeTexture9* m_stagingCube;
};
uint32_t m_flags; uint32_t m_flags;
uint32_t m_width; uint32_t m_width;
uint32_t m_height; uint32_t m_height;