D3D : Determine texture dimensions via already existing tooling functions. This fixes the bump texture in BumpEarth XDK sample.

Also split up texture-format support array into 6 versions : texture vs surface, and normal vs render-target vs depth-stencil.
This commit is contained in:
patrickvl 2018-04-04 16:16:58 +02:00
parent 87e77493c6
commit fc25603ee4
1 changed files with 112 additions and 112 deletions

View File

@ -92,7 +92,12 @@ static void UpdateCurrentMSpFAndFPS(); // Used for benchmarking/fps count
// Static Variable(s)
static HMONITOR g_hMonitor = NULL; // Handle to DirectDraw monitor
static bool g_bSupportsTextureFormat[XTL::X_D3DFMT_LIN_R8G8B8A8 + 1] = { false };// Does device support texture format?
static bool g_bSupportsFormatTexture[XTL::X_D3DFMT_LIN_R8G8B8A8 + 1] = { false }; // Does device support texture format?
static bool g_bSupportsFormatTextureRenderTarget[XTL::X_D3DFMT_LIN_R8G8B8A8 + 1] = { false };// Does device support texture format?
static bool g_bSupportsFormatTextureDepthStencil[XTL::X_D3DFMT_LIN_R8G8B8A8 + 1] = { false };// Does device support texture format?
static bool g_bSupportsFormatSurface[XTL::X_D3DFMT_LIN_R8G8B8A8 + 1] = { false };// Does device support surface format?
static bool g_bSupportsFormatSurfaceRenderTarget[XTL::X_D3DFMT_LIN_R8G8B8A8 + 1] = { false };// Does device support surface format?
static bool g_bSupportsFormatSurfaceDepthStencil[XTL::X_D3DFMT_LIN_R8G8B8A8 + 1] = { false };// Does device support surface format?
static XTL::LPDIRECTDRAW7 g_pDD7 = NULL; // DirectDraw7
static XTL::DDCAPS g_DriverCaps = { 0 };
static DWORD g_dwOverlayW = 640; // Cached Overlay Width
@ -1911,13 +1916,39 @@ static DWORD WINAPI EmuCreateDeviceProxy(LPVOID)
if (!XTL::EmuXBFormatRequiresConversionToARGB((XTL::X_D3DFORMAT)X_Format)) {
// Convert the Xbox format into host format (without warning, thanks to the above restriction)
XTL::D3DFORMAT PCFormat = XTL::EmuXB2PC_D3DFormat((XTL::X_D3DFORMAT)X_Format);
// Index g_bSupportsTextureFormat with Xbox D3DFormat, because host FourCC codes are too big to be used as indices
g_bSupportsTextureFormat[X_Format] = (PCFormat != XTL::D3DFMT_UNKNOWN) &&
// Ask the Direct3D device if this format is supported (for textures, that is)
(D3D_OK == g_pD3D8->CheckDeviceFormat(
g_EmuCDPD.Adapter, g_EmuCDPD.DeviceType,
g_EmuCDPD.HostPresentationParameters.BackBufferFormat, 0,
XTL::D3DRTYPE_TEXTURE, PCFormat));
if (PCFormat != XTL::D3DFMT_UNKNOWN) {
// Index with Xbox D3DFormat, because host FourCC codes are too big to be used as indices
g_bSupportsFormatTexture[X_Format] =
(D3D_OK == g_pD3D8->CheckDeviceFormat(
g_EmuCDPD.Adapter, g_EmuCDPD.DeviceType,
g_EmuCDPD.HostPresentationParameters.BackBufferFormat, 0,
XTL::D3DRTYPE_TEXTURE, PCFormat));
g_bSupportsFormatTextureRenderTarget[X_Format] =
(D3D_OK == g_pD3D8->CheckDeviceFormat(
g_EmuCDPD.Adapter, g_EmuCDPD.DeviceType,
g_EmuCDPD.HostPresentationParameters.BackBufferFormat, D3DUSAGE_RENDERTARGET,
XTL::D3DRTYPE_TEXTURE, PCFormat));
g_bSupportsFormatTextureDepthStencil[X_Format] =
(D3D_OK == g_pD3D8->CheckDeviceFormat(
g_EmuCDPD.Adapter, g_EmuCDPD.DeviceType,
g_EmuCDPD.HostPresentationParameters.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL,
XTL::D3DRTYPE_TEXTURE, PCFormat));
g_bSupportsFormatSurface[X_Format] =
(D3D_OK == g_pD3D8->CheckDeviceFormat(
g_EmuCDPD.Adapter, g_EmuCDPD.DeviceType,
g_EmuCDPD.HostPresentationParameters.BackBufferFormat, 0,
XTL::D3DRTYPE_SURFACE, PCFormat));
g_bSupportsFormatSurfaceRenderTarget[X_Format] =
(D3D_OK == g_pD3D8->CheckDeviceFormat(
g_EmuCDPD.Adapter, g_EmuCDPD.DeviceType,
g_EmuCDPD.HostPresentationParameters.BackBufferFormat, D3DUSAGE_RENDERTARGET,
XTL::D3DRTYPE_SURFACE, PCFormat));
g_bSupportsFormatSurfaceDepthStencil[X_Format] =
(D3D_OK == g_pD3D8->CheckDeviceFormat(
g_EmuCDPD.Adapter, g_EmuCDPD.DeviceType,
g_EmuCDPD.HostPresentationParameters.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL,
XTL::D3DRTYPE_SURFACE, PCFormat));
}
}
}
@ -1987,10 +2018,10 @@ static DWORD WINAPI EmuCreateDeviceProxy(LPVOID)
}
// Warn if CheckDeviceFormat didn't report this format
if (!g_bSupportsTextureFormat[X_Format]) {
if (!g_bSupportsFormatTexture[X_Format]) {
EmuWarning("EmuD3D8: FourCC format %.4s not previously detected via CheckDeviceFormat()! Enabling it.", (char *)&(lpCodes[v]));
// TODO : If this warning never shows, detecting FourCC's could be removed entirely. For now, enable the format :
g_bSupportsTextureFormat[X_Format] = true;
g_bSupportsFormatTexture[X_Format] = true;
}
}
@ -4172,12 +4203,13 @@ void CreateHostResource(XTL::X_D3DResource *pThis, int TextureStage, DWORD dwSiz
X_D3DPixelContainer *pPixelContainer = (X_D3DPixelContainer*)pResource;
X_D3DFORMAT X_Format = GetXboxPixelContainerFormat(pPixelContainer);
D3DFORMAT PCFormat = EmuXB2PC_D3DFormat(X_Format);
D3DFORMAT CacheFormat = (XTL::D3DFORMAT)0;
XTL::D3DFORMAT PCFormat = EmuXB2PC_D3DFormat(X_Format);
bool bConvertToARGB = false;
// TODO: check for dimensions
D3DRESOURCETYPE RType = (dwCommonType == X_D3DCOMMON_TYPE_SURFACE) ? D3DRTYPE_SURFACE : D3DRTYPE_TEXTURE;
X_D3DRESOURCETYPE XboxResourceType = GetXboxD3DResourceType(pResource);
DWORD Usage = 0;
bool *pbSupportedFormats = g_bSupportsFormatTexture;
if (pPixelContainer == g_pCachedDepthStencil) {
if (!EmuXBFormatIsDepthBuffer(X_Format))
@ -4192,127 +4224,95 @@ void CreateHostResource(XTL::X_D3DResource *pThis, int TextureStage, DWORD dwSiz
Usage = D3DUSAGE_RENDERTARGET;
}
if (D3D_OK != g_pD3D8->CheckDeviceFormat(
g_EmuCDPD.Adapter, g_EmuCDPD.DeviceType,
g_EmuCDPD.HostPresentationParameters.BackBufferFormat,
Usage, RType, PCFormat)) {
switch (XboxResourceType) {
case X_D3DRTYPE_SURFACE:
if (Usage & D3DUSAGE_RENDERTARGET) {
pbSupportedFormats = g_bSupportsFormatSurfaceRenderTarget;
} else if (Usage & D3DUSAGE_DEPTHSTENCIL) {
pbSupportedFormats = g_bSupportsFormatSurfaceDepthStencil;
}
else {
pbSupportedFormats = g_bSupportsFormatSurface;
}
break;
case X_D3DRTYPE_VOLUME: break; // TODO : Complete
case X_D3DRTYPE_TEXTURE:
if (Usage & D3DUSAGE_RENDERTARGET) {
pbSupportedFormats = g_bSupportsFormatTextureRenderTarget;
}
else if (Usage & D3DUSAGE_DEPTHSTENCIL) {
pbSupportedFormats = g_bSupportsFormatTextureDepthStencil;
}
else {
pbSupportedFormats = g_bSupportsFormatTexture;
}
break;
case X_D3DRTYPE_CUBETEXTURE:
break; // TODO : Complete
case X_D3DRTYPE_VOLUMETEXTURE:
break; // TODO : Complete
}
if (EmuXBFormatRequiresConversionToARGB(X_Format)) {
bConvertToARGB = true;
PCFormat = D3DFMT_A8R8G8B8; // ARGB
}
else
if (!pbSupportedFormats[X_Format]) {
// TODO: HACK: Temporary?
if (X_Format == X_D3DFMT_LIN_D24S8)
switch (X_Format) {
case X_D3DFMT_LIN_D24S8:
{
/*CxbxKrnlCleanup*/EmuWarning("D3DFMT_LIN_D24S8 not yet supported!");
X_Format = X_D3DFMT_LIN_A8R8G8B8;
PCFormat = D3DFMT_A8R8G8B8;
break;
}
if (X_Format == X_D3DFMT_LIN_D16)
case X_D3DFMT_LIN_D16:
{
// Test case : Turok (when entering menu)
/*CxbxKrnlCleanup*/EmuWarning("D3DFMT_LIN_D16 not yet supported!");
X_Format = X_D3DFMT_LIN_R5G6B5;
PCFormat = D3DFMT_R5G6B5;
break;
}
// TODO: HACK: Since I have trouble with this texture format on modern hardware,
// Let's try using some 16-bit format instead...
if (X_Format == X_D3DFMT_X1R5G5B5)
case X_D3DFMT_X1R5G5B5:
{
// Test case : JSRF (after loading)
CacheFormat = PCFormat; // Save this for later
bConvertToARGB = true;
PCFormat = D3DFMT_A8R8G8B8; // ARGB
break;
}
// Detect formats that must be converted to ARGB
if (EmuXBFormatCanBeConvertedToARGB(X_Format)) {
CacheFormat = PCFormat; // Save this for later
PCFormat = D3DFMT_A8R8G8B8; // ARGB
default:
// Detect formats that must be converted to ARGB
if (EmuXBFormatCanBeConvertedToARGB(X_Format)) {
bConvertToARGB = true;
PCFormat = D3DFMT_A8R8G8B8; // ARGB
}
else {
/*CxbxKrnlCleanup*/EmuWarning("Encountered a completely incompatible format!");
}
}
}
DWORD dwWidth, dwHeight, dwBPP, dwDepth = 1, dwPitch = 0, dwMipMapLevels = 1;
BOOL bSwizzled = EmuXBFormatIsSwizzled(X_Format), bCompressed = FALSE, dwCompressedSize = 0;
BOOL bCubemap = pPixelContainer->Format & X_D3DFORMAT_CUBEMAP;
UINT dwWidth, dwHeight, dwBPP, dwDepth = 1, dwPitch, dwMipMapLevels, uiSize;
bool bSwizzled = EmuXBFormatIsSwizzled(X_Format);
bool bCompressed = EmuXBFormatIsCompressed(X_Format);
bool bCubemap = pPixelContainer->Format & X_D3DFORMAT_CUBEMAP;
dwBPP = EmuXBFormatBytesPerPixel(X_Format);
// Interpret Width/Height/BPP
if(X_Format == X_D3DFMT_X8R8G8B8 || X_Format == X_D3DFMT_A8R8G8B8
|| X_Format == X_D3DFMT_A8B8G8R8)
{
// Swizzled 32 Bit
dwWidth = 1 << ((pPixelContainer->Format & X_D3DFORMAT_USIZE_MASK) >> X_D3DFORMAT_USIZE_SHIFT);
dwHeight = 1 << ((pPixelContainer->Format & X_D3DFORMAT_VSIZE_MASK) >> X_D3DFORMAT_VSIZE_SHIFT);
// Interpret Width/Height/BPP
CxbxGetPixelContainerMeasures(pPixelContainer, 0, &dwWidth, &dwHeight, &dwPitch, &uiSize);
if (pPixelContainer->Size == 0) {
dwMipMapLevels = (pPixelContainer->Format & X_D3DFORMAT_MIPMAP_MASK) >> X_D3DFORMAT_MIPMAP_SHIFT;
dwDepth = 1;// HACK? 1 << ((pPixelContainer->Format & X_D3DFORMAT_PSIZE_MASK) >> X_D3DFORMAT_PSIZE_SHIFT);
dwPitch = dwWidth * dwBPP;
}
else if(X_Format == X_D3DFMT_R5G6B5 || X_Format == X_D3DFMT_A4R4G4B4
|| X_Format == X_D3DFMT_A1R5G5B5 || X_Format == X_D3DFMT_X1R5G5B5
|| X_Format == X_D3DFMT_G8B8 || X_Format == X_D3DFMT_A8L8)
{
// Swizzled 16 Bit
dwWidth = 1 << ((pPixelContainer->Format & X_D3DFORMAT_USIZE_MASK) >> X_D3DFORMAT_USIZE_SHIFT);
dwHeight = 1 << ((pPixelContainer->Format & X_D3DFORMAT_VSIZE_MASK) >> X_D3DFORMAT_VSIZE_SHIFT);
dwMipMapLevels = (pPixelContainer->Format & X_D3DFORMAT_MIPMAP_MASK) >> X_D3DFORMAT_MIPMAP_SHIFT;
dwDepth = 1;// HACK? 1 << ((pPixelContainer->Format & X_D3DFORMAT_PSIZE_MASK) >> X_D3DFORMAT_PSIZE_SHIFT);
dwPitch = dwWidth * dwBPP;
}
else if(X_Format == X_D3DFMT_L8 || X_Format == X_D3DFMT_P8
|| X_Format == X_D3DFMT_AL8
|| X_Format == X_D3DFMT_A8)
{
// Swizzled 8 Bit
dwWidth = 1 << ((pPixelContainer->Format & X_D3DFORMAT_USIZE_MASK) >> X_D3DFORMAT_USIZE_SHIFT);
dwHeight = 1 << ((pPixelContainer->Format & X_D3DFORMAT_VSIZE_MASK) >> X_D3DFORMAT_VSIZE_SHIFT);
dwMipMapLevels = (pPixelContainer->Format & X_D3DFORMAT_MIPMAP_MASK) >> X_D3DFORMAT_MIPMAP_SHIFT;
dwDepth = 1;// HACK? 1 << ((pPixelContainer->Format & X_D3DFORMAT_PSIZE_MASK) >> X_D3DFORMAT_PSIZE_SHIFT);
dwPitch = dwWidth * dwBPP;
}
else if(X_Format == X_D3DFMT_LIN_X8R8G8B8 || X_Format == X_D3DFMT_LIN_A8R8G8B8
|| X_Format == X_D3DFMT_LIN_D24S8 || X_Format == X_D3DFMT_LIN_A8B8G8R8)
{
// Linear 32 Bit
dwWidth = (pPixelContainer->Size & X_D3DSIZE_WIDTH_MASK) + 1;
dwHeight = ((pPixelContainer->Size & X_D3DSIZE_HEIGHT_MASK) >> X_D3DSIZE_HEIGHT_SHIFT) + 1;
dwPitch = (((pPixelContainer->Size & X_D3DSIZE_PITCH_MASK) >> X_D3DSIZE_PITCH_SHIFT)+1)*64;
}
else if(X_Format == X_D3DFMT_LIN_R5G6B5 || X_Format == X_D3DFMT_LIN_D16
|| X_Format == X_D3DFMT_LIN_A4R4G4B4 || X_Format == X_D3DFMT_LIN_A1R5G5B5
|| X_Format == X_D3DFMT_LIN_X1R5G5B5 )
{
// Linear 16 Bit
dwWidth = (pPixelContainer->Size & X_D3DSIZE_WIDTH_MASK) + 1;
dwHeight = ((pPixelContainer->Size & X_D3DSIZE_HEIGHT_MASK) >> X_D3DSIZE_HEIGHT_SHIFT) + 1;
dwPitch = (((pPixelContainer->Size & X_D3DSIZE_PITCH_MASK) >> X_D3DSIZE_PITCH_SHIFT)+1)*64;
}
else if(X_Format == X_D3DFMT_DXT1 || X_Format == X_D3DFMT_DXT3 || X_Format == X_D3DFMT_DXT5)
{
bCompressed = TRUE;
// Compressed
dwWidth = 1 << ((pPixelContainer->Format & X_D3DFORMAT_USIZE_MASK) >> X_D3DFORMAT_USIZE_SHIFT);
dwHeight = 1 << ((pPixelContainer->Format & X_D3DFORMAT_VSIZE_MASK) >> X_D3DFORMAT_VSIZE_SHIFT);
dwDepth = 1 << ((pPixelContainer->Format & X_D3DFORMAT_PSIZE_MASK) >> X_D3DFORMAT_PSIZE_SHIFT);
dwMipMapLevels = (pPixelContainer->Format & X_D3DFORMAT_MIPMAP_MASK) >> X_D3DFORMAT_MIPMAP_SHIFT;
// D3DFMT_DXT2...D3DFMT_DXT5 : 128bits per block/per 16 texels
dwCompressedSize = dwWidth*dwHeight;
if(X_Format == X_D3DFMT_DXT1) // D3DFMT_DXT1 : 64bits per block/per 16 texels
dwCompressedSize /= 2;
}
else if(X_Format == X_D3DFMT_YUY2)
{
// Linear 32 Bit
dwWidth = (pPixelContainer->Size & X_D3DSIZE_WIDTH_MASK) + 1;
dwHeight = ((pPixelContainer->Size & X_D3DSIZE_HEIGHT_MASK) >> X_D3DSIZE_HEIGHT_SHIFT) + 1;
dwPitch = (((pPixelContainer->Size & X_D3DSIZE_PITCH_MASK) >> X_D3DSIZE_PITCH_SHIFT)+1)*64;
}
else
{
// Unhandled format: Guess reasonable values, show a warning and continue
EmuWarning("0x%.08X is not a supported format!\n", X_Format);
dwWidth = (pPixelContainer->Size & X_D3DSIZE_WIDTH_MASK) + 1;
dwHeight = ((pPixelContainer->Size & X_D3DSIZE_HEIGHT_MASK) >> X_D3DSIZE_HEIGHT_SHIFT) + 1;
dwPitch = (((pPixelContainer->Size & X_D3DSIZE_PITCH_MASK) >> X_D3DSIZE_PITCH_SHIFT) + 1) * 64;
}
else {
dwMipMapLevels = 1;
}
if(bSwizzled || bCompressed)
{
@ -4443,7 +4443,7 @@ void CreateHostResource(XTL::X_D3DResource *pThis, int TextureStage, DWORD dwSiz
DEBUG_D3DRESULT(hRet, "g_pD3DDevice8->CreateTexture(D3DFMT_A8R8G8B8)");
if (hRet == D3D_OK) {
// Okay, now this works, make sure the texture gets converted
CacheFormat = PCFormat;
bConvertToARGB = true;
PCFormat = D3DFMT_A8R8G8B8;
}
}
@ -4514,7 +4514,7 @@ void CreateHostResource(XTL::X_D3DResource *pThis, int TextureStage, DWORD dwSiz
{
// TODO: Fix or handle this situation..?
}
else if (CacheFormat != 0) // Do we need to convert to ARGB?
else if (bConvertToARGB) // Do we need to convert to ARGB?
{
DbgPrintf("Unsupported texture format, expanding to D3DFMT_A8R8G8B8");
@ -4551,9 +4551,9 @@ void CreateHostResource(XTL::X_D3DResource *pThis, int TextureStage, DWORD dwSiz
{
// NOTE: compressed size is (dwWidth/2)*(dwHeight/2)/2, so each level divides by 4
memcpy(LockedRect.pBits, pSrc + dwCompressedOffset, dwCompressedSize >> (level * 2));
memcpy(LockedRect.pBits, pSrc + dwCompressedOffset, uiSize >> (level * 2));
dwCompressedOffset += (dwCompressedSize >> (level * 2));
dwCompressedOffset += (uiSize >> (level * 2));
}
else
{