From 0f1dcb42a7c77493ea0f968b3c5e9d82b3940a80 Mon Sep 17 00:00:00 2001 From: PatrickvL Date: Sun, 23 Apr 2017 23:40:42 +0100 Subject: [PATCH 1/6] Removed unused g_dwCurrentPaletteSize --- src/CxbxKrnl/EmuD3D8.cpp | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/CxbxKrnl/EmuD3D8.cpp b/src/CxbxKrnl/EmuD3D8.cpp index 83903e7b2..7d5598046 100644 --- a/src/CxbxKrnl/EmuD3D8.cpp +++ b/src/CxbxKrnl/EmuD3D8.cpp @@ -142,8 +142,6 @@ static DWORD g_VertexShaderSlots[136]; // cached palette pointer static PVOID g_pCurrentPalette[TEXTURE_STAGES] = { nullptr, nullptr, nullptr, nullptr }; -// cached palette size -static DWORD g_dwCurrentPaletteSize[TEXTURE_STAGES] = { -1, -1, -1, -1 }; static XTL::X_VERTEXSHADERCONSTANTMODE g_VertexShaderConstantMode = X_VSCM_192; @@ -5212,7 +5210,6 @@ HRESULT WINAPI XTL::EMUPATCH(D3DResource_Register) } g_pCurrentPalette[TextureStage] = pBase; - g_dwCurrentPaletteSize[TextureStage] = dwSize; pResource->Data = (DWORD)pBase; } @@ -8485,15 +8482,9 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_SetPalette) // g_pD3DDevice9->SetCurrentTexturePalette(Stage, Stage); if (Stage < TEXTURE_STAGES) - { // Cache palette data and size g_pCurrentPalette[Stage] = GetDataFromXboxResource(pPalette); - if (g_pCurrentPalette[Stage] != NULL) - g_dwCurrentPaletteSize[Stage] = g_MemoryManager.QueryAllocationSize((LPVOID)g_pCurrentPalette[Stage]); - else { - g_dwCurrentPaletteSize[Stage] = 0; - } - } + return D3D_OK; } From c384bcea328bfe1b09b29d341720d0c019407473 Mon Sep 17 00:00:00 2001 From: PatrickvL Date: Sat, 29 Apr 2017 00:40:38 +0100 Subject: [PATCH 2/6] Fixed a surface-detection bug in D3DResource_AddRef --- src/CxbxKrnl/EmuD3D8.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/CxbxKrnl/EmuD3D8.cpp b/src/CxbxKrnl/EmuD3D8.cpp index 7d5598046..448dbfaf6 100644 --- a/src/CxbxKrnl/EmuD3D8.cpp +++ b/src/CxbxKrnl/EmuD3D8.cpp @@ -248,6 +248,14 @@ inline DWORD GetXboxResourceType(const XTL::X_D3DResource *pXboxResource) return pXboxResource->Common & X_D3DCOMMON_TYPE_MASK; } +inline XTL::X_D3DFORMAT GetXboxPixelContainerFormat(const XTL::X_D3DPixelContainer *pXboxPixelContainer) +{ + // Don't pass in unassigned Xbox pixel container + assert(pXboxPixelContainer != NULL); + + return (XTL::X_D3DFORMAT)((pXboxPixelContainer->Format & X_D3DFORMAT_FORMAT_MASK) >> X_D3DFORMAT_FORMAT_SHIFT); +} + XTL::IDirect3DResource8 *GetHostResource(XTL::X_D3DResource *pXboxResource) { if ((pXboxResource->Data & X_D3DRESOURCE_DATA_FLAG_SPECIAL) == X_D3DRESOURCE_DATA_FLAG_SPECIAL) // Was X_D3DRESOURCE_DATA_YUV_SURFACE @@ -1422,7 +1430,7 @@ static void EmuUnswizzleTextureStages() if(pPixelContainer == NULL || !(pPixelContainer->Common & X_D3DCOMMON_ISLOCKED)) return; - XTL::X_D3DFORMAT XBFormat = (XTL::X_D3DFORMAT)((pPixelContainer->Format & X_D3DFORMAT_FORMAT_MASK) >> X_D3DFORMAT_FORMAT_SHIFT); + XTL::X_D3DFORMAT XBFormat = GetXboxPixelContainerFormat(pPixelContainer); if(!XTL::EmuXBFormatIsSwizzled(XBFormat)) return; @@ -4694,7 +4702,7 @@ HRESULT WINAPI XTL::EMUPATCH(D3DResource_Register) X_D3DPixelContainer *pPixelContainer = (X_D3DPixelContainer*)pResource; - X_D3DFORMAT X_Format = (X_D3DFORMAT)((pPixelContainer->Format & X_D3DFORMAT_FORMAT_MASK) >> X_D3DFORMAT_FORMAT_SHIFT); + X_D3DFORMAT X_Format = GetXboxPixelContainerFormat(pPixelContainer); D3DFORMAT PCFormat = EmuXB2PC_D3DFormat(X_Format); D3DFORMAT CacheFormat = (XTL::D3DFORMAT)0; // TODO: check for dimensions From 36efdb60bcba9fe269c533bf386547533ad2e1fa Mon Sep 17 00:00:00 2001 From: PatrickvL Date: Sat, 29 Apr 2017 00:45:59 +0100 Subject: [PATCH 3/6] Introduced and used IsSpecialXboxResource --- src/CxbxKrnl/EmuD3D8.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/CxbxKrnl/EmuD3D8.cpp b/src/CxbxKrnl/EmuD3D8.cpp index 448dbfaf6..ba9684ce4 100644 --- a/src/CxbxKrnl/EmuD3D8.cpp +++ b/src/CxbxKrnl/EmuD3D8.cpp @@ -256,9 +256,20 @@ inline XTL::X_D3DFORMAT GetXboxPixelContainerFormat(const XTL::X_D3DPixelContain return (XTL::X_D3DFORMAT)((pXboxPixelContainer->Format & X_D3DFORMAT_FORMAT_MASK) >> X_D3DFORMAT_FORMAT_SHIFT); } +inline boolean IsSpecialXboxResource(const XTL::X_D3DResource *pXboxResource) +{ + // Don't pass in unassigned Xbox resources + assert(pXboxResource != NULL); + + return ((pXboxResource->Data & X_D3DRESOURCE_DATA_FLAG_SPECIAL) == X_D3DRESOURCE_DATA_FLAG_SPECIAL); +} + XTL::IDirect3DResource8 *GetHostResource(XTL::X_D3DResource *pXboxResource) { - if ((pXboxResource->Data & X_D3DRESOURCE_DATA_FLAG_SPECIAL) == X_D3DRESOURCE_DATA_FLAG_SPECIAL) // Was X_D3DRESOURCE_DATA_YUV_SURFACE + if (pXboxResource == NULL) + return nullptr; + + if (IsSpecialXboxResource(pXboxResource)) // Was X_D3DRESOURCE_DATA_YUV_SURFACE return nullptr; if (pXboxResource->Lock == X_D3DRESOURCE_LOCK_PALETTE) @@ -353,7 +364,7 @@ void *GetDataFromXboxResource(XTL::X_D3DResource *pXboxResource) if (pData == NULL) return nullptr; - if ((pXboxResource->Data & X_D3DRESOURCE_DATA_FLAG_SPECIAL) == X_D3DRESOURCE_DATA_FLAG_SPECIAL) + if (IsSpecialXboxResource(pXboxResource)) { switch (pData) { case X_D3DRESOURCE_DATA_BACK_BUFFER: @@ -1373,7 +1384,7 @@ static void EmuVerifyResourceIsRegistered(XTL::X_D3DResource *pResource) return; // Already "Registered" implicitly - if((pResource->Data & X_D3DRESOURCE_DATA_FLAG_SPECIAL) == X_D3DRESOURCE_DATA_FLAG_SPECIAL) + if(IsSpecialXboxResource(pResource)) return; if (std::find(g_RegisteredResources.begin(), g_RegisteredResources.end(), pResource->Data) != g_RegisteredResources.end()) { From 3d199d434e40daed4788df52ce16cd5a4ca36bee Mon Sep 17 00:00:00 2001 From: PatrickvL Date: Tue, 25 Apr 2017 16:52:53 +0100 Subject: [PATCH 4/6] Added IsResourceTypeGPUReadable This can be used to determine if resource Data adddresses need the MM_SYSTEM_PHYSICAL_MAP bit set or cleared --- src/CxbxKrnl/EmuD3D8.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/CxbxKrnl/EmuD3D8.cpp b/src/CxbxKrnl/EmuD3D8.cpp index ba9684ce4..da8abcc1b 100644 --- a/src/CxbxKrnl/EmuD3D8.cpp +++ b/src/CxbxKrnl/EmuD3D8.cpp @@ -264,6 +264,32 @@ inline boolean IsSpecialXboxResource(const XTL::X_D3DResource *pXboxResource) return ((pXboxResource->Data & X_D3DRESOURCE_DATA_FLAG_SPECIAL) == X_D3DRESOURCE_DATA_FLAG_SPECIAL); } +inline boolean IsResourceTypeGPUReadable(const DWORD ResourceType) +{ + switch (ResourceType) { + case X_D3DCOMMON_TYPE_VERTEXBUFFER: + return true; + case X_D3DCOMMON_TYPE_INDEXBUFFER: + /// assert(false); // Index buffers are not allowed to be registered + break; + case X_D3DCOMMON_TYPE_PUSHBUFFER: + return false; + case X_D3DCOMMON_TYPE_PALETTE: + return true; + case X_D3DCOMMON_TYPE_TEXTURE: + return true; + case X_D3DCOMMON_TYPE_SURFACE: + return true; + case X_D3DCOMMON_TYPE_FIXUP: + // assert(false); // Fixup's are not allowed to be registered + break; + default: + CxbxKrnlCleanup("Unhandled resource type"); + } + + return false; +} + XTL::IDirect3DResource8 *GetHostResource(XTL::X_D3DResource *pXboxResource) { if (pXboxResource == NULL) From ed00dc1c292cad4d1dff807c961cebbcecb1533c Mon Sep 17 00:00:00 2001 From: PatrickvL Date: Mon, 8 May 2017 08:24:23 +0200 Subject: [PATCH 5/6] Applied GetXboxResourceType two more times --- src/CxbxKrnl/EmuD3D8.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CxbxKrnl/EmuD3D8.cpp b/src/CxbxKrnl/EmuD3D8.cpp index 30751a9d5..616dd7ef7 100644 --- a/src/CxbxKrnl/EmuD3D8.cpp +++ b/src/CxbxKrnl/EmuD3D8.cpp @@ -5225,7 +5225,7 @@ ULONG WINAPI XTL::EMUPATCH(D3DResource_AddRef) ULONG uRet = (++(pThis->Common)) & X_D3DCOMMON_REFCOUNT_MASK; // Index buffers don't have a native resource assigned - if ((pThis->Common & X_D3DCOMMON_TYPE_MASK) != X_D3DCOMMON_TYPE_INDEXBUFFER) { + if (GetXboxResourceType(pThis) != X_D3DCOMMON_TYPE_INDEXBUFFER) { EmuVerifyResourceIsRegistered(pThis); // If this is the first reference on a surface @@ -5281,7 +5281,7 @@ ULONG WINAPI XTL::EMUPATCH(D3DResource_Release) } EMUPATCH(D3DDevice_EnableOverlay)(FALSE); - } else if ((pThis->Common & X_D3DCOMMON_TYPE_MASK) == X_D3DCOMMON_TYPE_INDEXBUFFER) { + } else if (GetXboxResourceType(pThis) == X_D3DCOMMON_TYPE_INDEXBUFFER) { if ((pThis->Common & X_D3DCOMMON_REFCOUNT_MASK) == 1) { CxbxRemoveIndexBuffer((PWORD)GetDataFromXboxResource(pThis)); } From dcbe0a71aee0d758d53a5042534422b1d87e7142 Mon Sep 17 00:00:00 2001 From: PatrickvL Date: Mon, 8 May 2017 08:46:27 +0200 Subject: [PATCH 6/6] Check for X_D3DFMT_YUY2 before other formats --- src/CxbxKrnl/EmuD3D8.cpp | 156 ++++++++++++++++++--------------------- 1 file changed, 70 insertions(+), 86 deletions(-) diff --git a/src/CxbxKrnl/EmuD3D8.cpp b/src/CxbxKrnl/EmuD3D8.cpp index 616dd7ef7..7abfcfc6b 100644 --- a/src/CxbxKrnl/EmuD3D8.cpp +++ b/src/CxbxKrnl/EmuD3D8.cpp @@ -3330,44 +3330,7 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateTexture) // Get Bytes Per Pixel, for correct Pitch calculation : DWORD dwBPP = EmuXBFormatBytesPerPixel(Format); - UINT Pitch = RoundUp(Width, 64) * dwBPP; // TODO : RoundUp only for (X_)D3DFMT_YUY2? - - // Convert Format (Xbox->PC) - D3DFORMAT PCFormat = EmuXB2PC_D3DFormat(Format); - - // TODO: HACK: Devices that don't support this should somehow emulate it! - //* This is OK on my GeForce FX 5600 - if(PCFormat == D3DFMT_D16) - { - EmuWarning("D3DFMT_D16 is an unsupported texture format!"); - PCFormat = D3DFMT_R5G6B5; - } - //* - else if(PCFormat == D3DFMT_P8) - { - EmuWarning("D3DFMT_P8 is an unsupported texture format!"); - PCFormat = D3DFMT_L8; - } - //*/ - //* This is OK on my GeForce FX 5600 - else if(PCFormat == D3DFMT_D24S8) - { - EmuWarning("D3DFMT_D24S8 is an unsupported texture format!"); - PCFormat = D3DFMT_X8R8G8B8; // TODO : Use D3DFMT_A8R8G8B8? - }//*/ - else if(PCFormat == D3DFMT_YUY2) - { - // cache the overlay size - g_dwOverlayW = Width; - g_dwOverlayH = Height; - g_dwOverlayP = Pitch; - } - // TODO: HACK: This texture format fails on some newer hardware - else if(PCFormat == D3DFMT_X1R5G5B5) - { - EmuWarning("D3DFMT_X1R5G5B5 -> D3DFMT_R5G6B5"); - PCFormat = D3DFMT_R5G6B5; - } + UINT Pitch = RoundUp(Width, 64) * dwBPP; // TODO : RoundUp only for X_D3DFMT_YUY2? HRESULT hRet; @@ -3375,9 +3338,14 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateTexture) IDirect3DTexture8 *pHostTexture = nullptr; DWORD Texture_Data; - if(PCFormat == D3DFMT_YUY2) + if(Format == X_D3DFMT_YUY2) { - // If YUY2 is not supported in hardware, we'll actually mark this as a special fake texture + // cache the overlay size + g_dwOverlayW = Width; + g_dwOverlayH = Height; + g_dwOverlayP = Pitch; + + // If YUY2 is not supported in hardware, we'll actually mark this as a special fake texture Texture_Data = X_D3DRESOURCE_DATA_YUV_SURFACE; pTexture->Lock = (DWORD)g_MemoryManager.Allocate(g_dwOverlayP * g_dwOverlayH); @@ -3387,6 +3355,36 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateTexture) } else { + // Convert Format (Xbox->PC) + D3DFORMAT PCFormat = EmuXB2PC_D3DFormat(Format); + + // TODO: HACK: Devices that don't support this should somehow emulate it! + //* This is OK on my GeForce FX 5600 + if(PCFormat == D3DFMT_D16) + { + EmuWarning("D3DFMT_D16 is an unsupported texture format!"); + PCFormat = D3DFMT_R5G6B5; + } + //* + else if(PCFormat == D3DFMT_P8) + { + EmuWarning("D3DFMT_P8 is an unsupported texture format!"); + PCFormat = D3DFMT_L8; + } + //*/ + //* This is OK on my GeForce FX 5600 + else if(PCFormat == D3DFMT_D24S8) + { + EmuWarning("D3DFMT_D24S8 is an unsupported texture format!"); + PCFormat = D3DFMT_X8R8G8B8; // TODO : Use D3DFMT_A8R8G8B8? + }//*/ + // TODO: HACK: This texture format fails on some newer hardware + else if(PCFormat == D3DFMT_X1R5G5B5) + { + EmuWarning("D3DFMT_X1R5G5B5 -> D3DFMT_R5G6B5"); + PCFormat = D3DFMT_R5G6B5; + } + DWORD PCUsage = Usage & (D3DUSAGE_RENDERTARGET); // DWORD PCUsage = Usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL); D3DPOOL PCPool = D3DPOOL_MANAGED; @@ -3487,39 +3485,17 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVolumeTexture) ");\n", Width, Height, Depth, Levels, Usage, Format, Pool, ppVolumeTexture); - // Convert Format (Xbox->PC) - D3DFORMAT PCFormat = EmuXB2PC_D3DFormat(Format); + *ppVolumeTexture = EmuNewD3DVolumeTexture(); - // TODO: HACK: Devices that don't support this should somehow emulate it! - if(PCFormat == D3DFMT_D16) - { - EmuWarning("D3DFMT_D16 is an unsupported texture format!"); - PCFormat = D3DFMT_X8R8G8B8; // TODO : Use D3DFMT_R5G6B5 ? - } - else if(PCFormat == D3DFMT_P8) - { - EmuWarning("D3DFMT_P8 is an unsupported texture format!"); - PCFormat = D3DFMT_L8; - } - else if(PCFormat == D3DFMT_D24S8) - { - EmuWarning("D3DFMT_D24S8 is an unsupported texture format!"); - PCFormat = D3DFMT_X8R8G8B8; // TODO : Use D3DFMT_A8R8G8B8? - } - else if(PCFormat == D3DFMT_YUY2) + HRESULT hRet; + + if(Format == X_D3DFMT_YUY2) { // cache the overlay size g_dwOverlayW = Width; g_dwOverlayH = Height; g_dwOverlayP = RoundUp(g_dwOverlayW, 64)*2; - } - *ppVolumeTexture = EmuNewD3DVolumeTexture(); - - HRESULT hRet; - - if(PCFormat == D3DFMT_YUY2) - { // If YUY2 is not supported in hardware, we'll actually mark this as a special fake texture (*ppVolumeTexture)->Data = X_D3DRESOURCE_DATA_YUV_SURFACE; (*ppVolumeTexture)->Lock = (DWORD)g_MemoryManager.Allocate(g_dwOverlayP * g_dwOverlayH); @@ -3533,7 +3509,27 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVolumeTexture) } else { - EmuAdjustPower2(&Width, &Height); + // Convert Format (Xbox->PC) + D3DFORMAT PCFormat = EmuXB2PC_D3DFormat(Format); + + // TODO: HACK: Devices that don't support this should somehow emulate it! + if (PCFormat == D3DFMT_D16) + { + EmuWarning("D3DFMT_D16 is an unsupported texture format!"); + PCFormat = D3DFMT_X8R8G8B8; // TODO : Use D3DFMT_R5G6B5 ? + } + else if (PCFormat == D3DFMT_P8) + { + EmuWarning("D3DFMT_P8 is an unsupported texture format!"); + PCFormat = D3DFMT_L8; + } + else if (PCFormat == D3DFMT_D24S8) + { + EmuWarning("D3DFMT_D24S8 is an unsupported texture format!"); + PCFormat = D3DFMT_X8R8G8B8; // TODO : Use D3DFMT_A8R8G8B8? + } + + EmuAdjustPower2(&Width, &Height); XTL::IDirect3DVolumeTexture8 *pHostVolumeTexture = nullptr; @@ -3582,6 +3578,11 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateCubeTexture) ");\n", EdgeLength, Levels, Usage, Format, Pool, ppCubeTexture); + if(Format == X_D3DFMT_YUY2) + { + CxbxKrnlCleanup("YUV not supported for cube textures"); + } + // Convert Format (Xbox->PC) D3DFORMAT PCFormat = EmuXB2PC_D3DFormat(Format); @@ -3601,11 +3602,7 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateCubeTexture) EmuWarning("D3DFMT_D24S8 is an unsupported texture format!"); PCFormat = D3DFMT_X8R8G8B8; // TODO : Use D3DFMT_A8R8G8B8? } - else if(PCFormat == D3DFMT_YUY2) - { - CxbxKrnlCleanup("YUV not supported for cube textures"); - } - + *ppCubeTexture = EmuNewD3DCubeTexture(); XTL::IDirect3DCubeTexture8 *pHostCubeTexture = nullptr; @@ -4758,28 +4755,15 @@ HRESULT WINAPI XTL::EMUPATCH(D3DResource_Register) if(X_Format == X_D3DFMT_YUY2) { - // // cache the overlay size - // - g_dwOverlayW = dwWidth; g_dwOverlayH = dwHeight; g_dwOverlayP = RoundUp(g_dwOverlayW, 64) * dwBPP; - // - // create texture resource - // - // If YUY2 is not supported in hardware, we'll actually mark this as a special fake texture - // TODO : Do we actually need to set these? - pPixelContainer->Common = X_D3DCOMMON_TYPE_TEXTURE | 1; // Set refcount to 1 + // Note : This is the only change to the pResource argument passed into D3DResource_Register ! pPixelContainer->Data = X_D3DRESOURCE_DATA_YUV_SURFACE; pPixelContainer->Lock = (DWORD)g_MemoryManager.Allocate(g_dwOverlayP * g_dwOverlayH); - pPixelContainer->Format = (X_D3DFMT_YUY2 << X_D3DFORMAT_FORMAT_SHIFT); - - pPixelContainer->Size = (g_dwOverlayW & X_D3DSIZE_WIDTH_MASK); - pPixelContainer->Size |= (g_dwOverlayH << X_D3DSIZE_HEIGHT_SHIFT) & X_D3DSIZE_HEIGHT_MASK; - pPixelContainer->Size |= (g_dwOverlayP << X_D3DSIZE_PITCH_SHIFT) & X_D3DSIZE_PITCH_MASK; } else {