D3DDevice_CreateTexture uses XGSetTextureHeader now (instead of the other way around)

Also better determination of Texture fields.
This commit is contained in:
PatrickvL 2017-01-23 17:56:27 +01:00
parent 6eec6e7671
commit 23f060fc47
2 changed files with 56 additions and 88 deletions

View File

@ -2992,8 +2992,6 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateTexture)
X_D3DTexture **ppTexture
)
{
DbgPrintf("EmuD3D8: EmuD3DDevice_CreateTexture\n"
"(\n"
" Width : 0x%.08X\n"
@ -3006,6 +3004,12 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateTexture)
");\n",
Width, Height, Levels, Usage, Format, Pool, ppTexture);
// Get Bytes Per Pixel, for correct Pitch calculation :
DWORD dwBPP = 2; // Default, in case nothing is set
/*ignore result*/EmuXBFormatIsSwizzled(Format, &dwBPP);
UINT Pitch = RoundUp(Width, 64) * dwBPP; // TODO : RoundUp only for (X_)D3DFMT_YUY2?
// Convert Format (Xbox->PC)
D3DFORMAT PCFormat = EmuXB2PC_D3DFormat(Format);
@ -3034,33 +3038,28 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateTexture)
// cache the overlay size
g_dwOverlayW = Width;
g_dwOverlayH = Height;
g_dwOverlayP = RoundUp(g_dwOverlayW, 64)*2;
g_dwOverlayP = Pitch;
}
HRESULT hRet;
X_D3DTexture *pTexture = new X_D3DTexture();
DWORD Texture_Data;
if(PCFormat == D3DFMT_YUY2)
{
DWORD dwSize = g_dwOverlayP*g_dwOverlayH;
DWORD dwPtr = (DWORD)CxbxMalloc(dwSize + sizeof(DWORD));
DWORD *pRefCount = (DWORD*)(dwPtr + dwSize);
// initialize ref count
*pRefCount = 1;
// If YUY2 is not supported in hardware, we'll actually mark this as a special fake texture (set highest bit)
*ppTexture = new X_D3DTexture();
Texture_Data = X_D3DRESOURCE_DATA_FLAG_SPECIAL | X_D3DRESOURCE_DATA_FLAG_YUVSURF;
pTexture->Lock = dwPtr;
(*ppTexture)->Data = X_D3DRESOURCE_DATA_FLAG_SPECIAL | X_D3DRESOURCE_DATA_FLAG_YUVSURF;
(*ppTexture)->Lock = dwPtr;
(*ppTexture)->Format = 0x24;
(*ppTexture)->Size = (g_dwOverlayW & X_D3DSIZE_WIDTH_MASK);
(*ppTexture)->Size |= (g_dwOverlayH << X_D3DSIZE_HEIGHT_SHIFT);
(*ppTexture)->Size |= (g_dwOverlayP << X_D3DSIZE_PITCH_SHIFT);
g_YuvSurface = (X_D3DSurface*)*ppTexture;
g_YuvSurface = (X_D3DSurface*)pTexture;
hRet = D3D_OK;
}
@ -3084,8 +3083,6 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateTexture)
// EmuAdjustPower2(&Width, &Height);
*ppTexture = new X_D3DTexture();
// if(Usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL))
if(Usage & (D3DUSAGE_RENDERTARGET))
{
@ -3096,18 +3093,16 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateTexture)
(
Width, Height, Levels,
PCUsage, // TODO: Xbox Allows a border to be drawn (maybe hack this in software ;[)
PCFormat, PCPool, &((*ppTexture)->EmuTexture8)
PCFormat, PCPool, &(pTexture->EmuTexture8)
);
if(FAILED(hRet))
{
EmuWarning("CreateTexture Failed!");
(*ppTexture)->Data = 0xBEADBEAD;
Texture_Data = 0xBEADBEAD;
}
else
{
D3DLOCKED_RECT LockedRect;
/**
* Note: If CreateTexture() called with D3DPOOL_DEFAULT then unable to Lock.
* It will cause an Error with the DirectX Debug runtime.
@ -3117,20 +3112,21 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateTexture)
* D3DUSAGE_DEPTHSTENCIL
* that can only be used with D3DPOOL_DEFAULT per MSDN.
*/
(*ppTexture)->EmuTexture8->LockRect(0, &LockedRect, NULL, NULL);
D3DLOCKED_RECT LockedRect;
(*ppTexture)->Data = (DWORD)LockedRect.pBits;
(*ppTexture)->Format = Format << X_D3DFORMAT_FORMAT_SHIFT;
g_DataToTexture.insert((*ppTexture)->Data, *ppTexture);
(*ppTexture)->EmuTexture8->UnlockRect(0);
pTexture->EmuTexture8->LockRect(0, &LockedRect, NULL, NULL);
Texture_Data = (DWORD)LockedRect.pBits;
g_DataToTexture.insert(Texture_Data, pTexture);
pTexture->EmuTexture8->UnlockRect(0);
}
DbgPrintf("EmuD3D8: Created Texture : 0x%.08X (0x%.08X)\n", *ppTexture, (*ppTexture)->EmuTexture8);
}
// Set all X_D3DTexture members (except Lock)
XTL::EMUPATCH(XGSetTextureHeader)(Width, Height, Levels, Usage, Format, Pool, pTexture, Texture_Data, Pitch);
DbgPrintf("EmuD3D8: Created Texture : 0x%.08X (0x%.08X)\n", pTexture, pTexture->EmuTexture8);
*ppTexture = pTexture;
return hRet;
}
@ -3150,8 +3146,6 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVolumeTexture)
X_D3DVolumeTexture **ppVolumeTexture
)
{
DbgPrintf("EmuD3D8: EmuD3DDevice_CreateVolumeTexture\n"
"(\n"
" Width : 0x%.08X\n"
@ -3198,7 +3192,6 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVolumeTexture)
{
DWORD dwSize = g_dwOverlayP*g_dwOverlayH;
DWORD dwPtr = (DWORD)CxbxMalloc(dwSize + sizeof(DWORD));
DWORD *pRefCount = (DWORD*)(dwPtr + dwSize);
// initialize ref count
@ -3234,8 +3227,6 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVolumeTexture)
DbgPrintf("EmuD3D8: Created Volume Texture : 0x%.08X (0x%.08X)\n", *ppVolumeTexture, (*ppVolumeTexture)->EmuVolumeTexture8);
}
return hRet;
}
@ -3252,8 +3243,6 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateCubeTexture)
X_D3DCubeTexture **ppCubeTexture
)
{
DbgPrintf("EmuD3D8: EmuD3DDevice_CreateCubeTexture\n"
"(\n"
" EdgeLength : 0x%.08X\n"
@ -4596,7 +4585,7 @@ HRESULT WINAPI XTL::EMUPATCH(D3DResource_Register)
g_dwOverlayW = dwWidth;
g_dwOverlayH = dwHeight;
g_dwOverlayP = RoundUp(g_dwOverlayW, 64)*2;
g_dwOverlayP = RoundUp(g_dwOverlayW, 64) * dwBPP;
//
// create texture resource
@ -5047,8 +5036,6 @@ ULONG WINAPI XTL::EMUPATCH(D3DResource_Release)
X_D3DResource *pThis
)
{
DbgPrintf("EmuD3D8: EmuIDirect3DResource8_Release\n"
"(\n"
" pThis : 0x%.08X\n"
@ -5062,8 +5049,6 @@ ULONG WINAPI XTL::EMUPATCH(D3DResource_Release)
{
EmuWarning("NULL texture!");
return 0;
}
@ -5087,10 +5072,8 @@ ULONG WINAPI XTL::EMUPATCH(D3DResource_Release)
// free memory associated with this special resource handle
CxbxFree((PVOID)dwPtr);
}
EMUPATCH(D3DDevice_EnableOverlay)(FALSE);
}
else
{
@ -5101,7 +5084,7 @@ ULONG WINAPI XTL::EMUPATCH(D3DResource_Release)
delete[] (PVOID)pThis->Data;
uRet = --pThis->Lock;
}
else if(pResource8 != 0)
else if(pResource8 != nullptr)
{
for(int v=0;v<16;v++)
{
@ -5117,7 +5100,6 @@ ULONG WINAPI XTL::EMUPATCH(D3DResource_Release)
#endif
uRet = pResource8->Release();
if(uRet == 0)
{
DbgPrintf("EmuIDirect3DResource8_Release : Cleaned up a Resource!\n");
@ -5137,9 +5119,6 @@ ULONG WINAPI XTL::EMUPATCH(D3DResource_Release)
pThis->Common = (pThis->Common & ~X_D3DCOMMON_REFCOUNT_MASK) | ((pThis->Common & X_D3DCOMMON_REFCOUNT_MASK) - 1);
}
return uRet;
}

View File

@ -241,62 +241,51 @@ VOID WINAPI XTL::EMUPATCH(XGSetTextureHeader)
LOG_FUNC_ARG(Width)
LOG_FUNC_ARG(Height)
LOG_FUNC_ARG(Levels)
LOG_FUNC_ARG(Usage)
LOG_FUNC_ARG(Usage) // TODO : How to embed this?
LOG_FUNC_ARG(Format)
LOG_FUNC_ARG(Pool)
LOG_FUNC_ARG(Pool) // TODO : How to embed this?
LOG_FUNC_ARG(pTexture)
LOG_FUNC_ARG(Data)
LOG_FUNC_ARG(Pitch)
LOG_FUNC_END;
// NOTES: This function simply creates a texture that needs to be registered
// via EMUPATCH(D3DDevice_Register) afterwards. So, do I just create the texture via
// EMUPATCH(D3DDevice_CreateTexture), or just fill in the interface and let
// EMUPATCH(D3DDevice_Register) do the rest? Trial and error.
X_D3DTexture* pTempTexture = NULL;
DWORD l2w; _BitScanReverse(&l2w, Width); // Untested (no test-case known)
DWORD l2h; _BitScanReverse(&l2h, Height); // Note : _BitScanReverse is a MSVC intrinsic. For GCC use __builtin_clz
/*if( Data != 0 )
CxbxKrnlCleanup( "Data != 0 (XGSetTextureHeader)" );
if( Pitch != 0 )
CxbxKrnlCleanup( "Pitch != 0 (XGSetTextureHeader)" );*/
// Generate a temporary texture and fill in the necessary fields within
// the X_D3DTexture interface (lazy, I know).
pTempTexture = (X_D3DTexture*) XTL::EMUPATCH(D3DDevice_CreateTexture2)(Width, Height, 0, Levels, Usage, Format,
XTL::D3DRTYPE_TEXTURE);
pTexture->Common = X_D3DCOMMON_TYPE_TEXTURE + 1; // Set refcount to 1
pTexture->Data = Data;
// Note : Do NOT touch pTexture->Lock, as callers can have set it already !
pTexture->Data = pTempTexture->Data;
pTexture->Common = X_D3DCOMMON_TYPE_TEXTURE; //pTempTexture->Common;
// pTexture->Format = pTempTexture->Format;
pTexture->Lock = pTempTexture->Lock; // 0;
pTexture->Size = pTempTexture->Size;
// Width or Height both a power of two?
DWORD l2w; _BitScanReverse(&l2w, Width); // MSVC intrinsic; GCC has __builtin_clz
DWORD l2h; _BitScanReverse(&l2h, Height);
if (((1 << l2w) == Width) && ((1 << l2h) == Height)) {
Width = Height = Pitch = 1; // When setting Format, clear Size field
} else {
l2w = l2h = 0; // When setting Size, clear D3DFORMAT_USIZE and VSIZE
}
XTL::EMUPATCH(D3DResource_Release)(pTempTexture);
// TODO : Must these be set using Usage / Pool / something else?
const int Dimensions = 2;
const int Depth = 1;
// Manually fill in Format parameters
/*pTexture->Format |= ( ( ( Width >> 1 ) & 0xF ) << X_D3DFORMAT_USIZE_SHIFT ) | // Width
( ( ( Height>> 1 ) & 0xF ) << X_D3DFORMAT_VSIZE_SHIFT ) | // Height
( ( ( Levels ) & 0xF ) << X_D3DFORMAT_MIPMAP_SHIFT ) | // Mip Levels
// ( ( ( ((DWORD)Format)) & 0xFF ) << X_D3DFORMAT_FORMAT_SHIFT ) | // Format (Already set)
( ( ( 2 ) & 0xF ) << X_D3DFORMAT_DIMENSION_SHIFT ); // Dimensions
*/
pTexture->Format |= ( ( l2w & 0xF ) << X_D3DFORMAT_USIZE_SHIFT );
pTexture->Format |= ( ( l2h & 0xF ) << X_D3DFORMAT_VSIZE_SHIFT );
pTexture->Format |= ( ( Levels & 0xF ) << X_D3DFORMAT_MIPMAP_SHIFT );
pTexture->Format |= ( ( ( ((DWORD)Format)) & 0xFF ) << X_D3DFORMAT_FORMAT_SHIFT );
pTexture->Format |= ( ( 2 & 0xF ) << X_D3DFORMAT_DIMENSION_SHIFT );
// D3DCOLOR_XRGB(
DbgPrintf( "pTexture->Format:= 0x%.08X\n", pTexture->Format );
pTexture->Format = 0
| ((Dimensions << X_D3DFORMAT_DIMENSION_SHIFT) & X_D3DFORMAT_DIMENSION_MASK)
| (((DWORD)Format << X_D3DFORMAT_FORMAT_SHIFT) & X_D3DFORMAT_FORMAT_MASK)
| ((Levels << X_D3DFORMAT_MIPMAP_SHIFT) & X_D3DFORMAT_MIPMAP_MASK)
| ((l2w << X_D3DFORMAT_USIZE_SHIFT) & X_D3DFORMAT_USIZE_MASK)
| ((l2h << X_D3DFORMAT_VSIZE_SHIFT) & X_D3DFORMAT_VSIZE_MASK)
| ((Depth << X_D3DFORMAT_PSIZE_SHIFT) & X_D3DFORMAT_PSIZE_MASK)
;
pTexture->Size = 0
| (((Width - 1) /*X_D3DSIZE_WIDTH_SHIFT*/) & X_D3DSIZE_WIDTH_MASK)
| (((Height - 1) << X_D3DSIZE_HEIGHT_SHIFT) & X_D3DSIZE_HEIGHT_MASK)
| (((Pitch - 1) << X_D3DSIZE_PITCH_SHIFT) & X_D3DSIZE_PITCH_MASK);
}
// ******************************************************************