Commit 359ea624 authored by Joshua Ashton's avatar Joshua Ashton 🐸

[d3d9] Refactor texture class.

parent 34ae0df0
......@@ -723,7 +723,7 @@ namespace dxup {
d3d9Desc.Usage = Usage;
if (Type == D3DRTYPE_CUBETEXTURE)
*ppTexture = ref(new Direct3DCubeTexture9(singletonSurface, this, resource, d3d9Desc));
*ppTexture = ref(new Direct3DCubeTexture9(this, resource, d3d9Desc));
else
*ppTexture = ref(new Direct3DTexture9(singletonSurface, this, resource, d3d9Desc));
......@@ -768,7 +768,7 @@ namespace dxup {
D3D9ResourceDesc d3d9Desc;
d3d9Desc.Pool = Pool;
d3d9Desc.FVF = FVF;
d3d9Desc.FVF = FVF;https://www.youtube.com/watch?v=Zsu0RGeJkQg&t=907s
d3d9Desc.Usage = Usage;
*ppVertexBuffer = ref(new Direct3DVertexBuffer9(this, resource, d3d9Desc));
......
#include "d3d9_texture.h"
#include "d3d9_device.h"
namespace dxup {
// Direct3DTexture9
Direct3DTexture9::Direct3DTexture9(bool singletonSurface, Direct3DDevice9Ex* device, DXUPResource* resource, const D3D9ResourceDesc& desc)
: Direct3DTexture9Base{ device, resource, desc }
, m_singletonSurface{ singletonSurface } {
m_surfaces.reserve(resource->GetSubresources());
for (UINT mip = 0; mip < resource->GetMips(); mip++) {
Direct3DSurface9* surface = new Direct3DSurface9(singletonSurface, 0, mip, device, this, resource, desc);
if (!singletonSurface)
surface->AddRefPrivate();
m_surfaces.push_back(surface);
}
}
Direct3DTexture9::~Direct3DTexture9() {
if (!m_singletonSurface) {
for (IDirect3DSurface9* surface : m_surfaces) {
Direct3DSurface9* internalSurface = reinterpret_cast<Direct3DSurface9*>(surface);
internalSurface->ReleasePrivate();
}
}
}
HRESULT STDMETHODCALLTYPE Direct3DTexture9::GetLevelDesc(UINT Level, D3DSURFACE_DESC *pDesc) {
CriticalSection(this->GetD3D9Device());
if (Level >= m_surfaces.size())
return log::d3derr(D3DERR_INVALIDCALL, "GetLevelDesc: level out of bounds.");
return m_surfaces[Level]->GetDesc(pDesc);
}
HRESULT STDMETHODCALLTYPE Direct3DTexture9::GetSurfaceLevel(UINT Level, IDirect3DSurface9** ppSurfaceLevel) {
CriticalSection(this->GetD3D9Device());
UINT subresource = D3D11CalcSubresource(Level, 0, this->GetDXUPResource()->GetMips());
InitReturnPtr(ppSurfaceLevel);
if (subresource >= m_surfaces.size())
return log::d3derr(D3DERR_INVALIDCALL, "GetSurfaceLevel: subresource out of bounds (Level = %d).", Level);
if (ppSurfaceLevel == nullptr)
return log::d3derr(D3DERR_INVALIDCALL, "GetSurfaceLevel: ppSurfaceLevel was nullptr.");
*ppSurfaceLevel = ref(m_surfaces[subresource]);
return D3D_OK;
}
HRESULT STDMETHODCALLTYPE Direct3DTexture9::LockRect(UINT Level, D3DLOCKED_RECT* pLockedRect, const RECT* pRect, DWORD Flags) {
CriticalSection(this->GetD3D9Device());
UINT subresource = D3D11CalcSubresource(Level, 0, this->GetDXUPResource()->GetMips());
if (subresource >= m_surfaces.size())
return log::d3derr(D3DERR_INVALIDCALL, "LockRect: subresource out of bounds (Level = %d).", Level);
return m_surfaces[subresource]->LockRect(pLockedRect, pRect, Flags);
}
HRESULT STDMETHODCALLTYPE Direct3DTexture9::UnlockRect(UINT Level) {
CriticalSection(this->GetD3D9Device());
UINT subresource = D3D11CalcSubresource(Level, 0, this->GetDXUPResource()->GetMips());
if (subresource >= m_surfaces.size())
return log::d3derr(D3DERR_INVALIDCALL, "UnlockRect: subresource out of bounds (Level = %d).", Level);
return m_surfaces[subresource]->UnlockRect();
}
HRESULT STDMETHODCALLTYPE Direct3DTexture9::AddDirtyRect(const RECT* pDirtyRect) {
CriticalSection(this->GetD3D9Device());
log::stub("Direct3DTexture9::AddDirtyRect");
return D3D_OK;
}
inline bool Direct3DTexture9::IsFakeSurface() {
return m_singletonSurface;
}
// Direct3DCubeTexture9
Direct3DCubeTexture9::Direct3DCubeTexture9(Direct3DDevice9Ex* device, DXUPResource* resource, const D3D9ResourceDesc& desc)
: Direct3DCubeTexture9Base{ device, resource, desc } {
m_surfaces.reserve(resource->GetSubresources());
// This should allow us to match D3D11CalcSubresource.
for (UINT slice = 0; slice < 6; slice++) {
for (UINT mip = 0; mip < resource->GetMips(); mip++) {
Direct3DSurface9* surface = new Direct3DSurface9(false, slice, mip, device, this, resource, desc);
surface->AddRefPrivate();
m_surfaces.push_back(surface);
}
}
}
Direct3DCubeTexture9::~Direct3DCubeTexture9() {
for (IDirect3DSurface9* surface : m_surfaces) {
Direct3DSurface9* internalSurface = reinterpret_cast<Direct3DSurface9*>(surface);
internalSurface->ReleasePrivate();
}
}
HRESULT STDMETHODCALLTYPE Direct3DCubeTexture9::GetLevelDesc(UINT Level, D3DSURFACE_DESC *pDesc) {
CriticalSection(this->GetD3D9Device());
if (Level >= m_surfaces.size())
return log::d3derr(D3DERR_INVALIDCALL, "GetLevelDesc: level out of bounds.");
return m_surfaces[Level]->GetDesc(pDesc);
}
HRESULT STDMETHODCALLTYPE Direct3DCubeTexture9::GetCubeMapSurface(D3DCUBEMAP_FACES FaceType, UINT Level, IDirect3DSurface9** ppCubeMapSurface) {
CriticalSection(this->GetD3D9Device());
UINT subresource = D3D11CalcSubresource(Level, (UINT)FaceType, this->GetDXUPResource()->GetMips());
InitReturnPtr(ppCubeMapSurface);
if (subresource >= m_surfaces.size())
return log::d3derr(D3DERR_INVALIDCALL, "GetCubeMapSurface: subresource out of bounds (FaceType = %d, Level = %d).", FaceType, Level);
if (ppCubeMapSurface == nullptr)
return log::d3derr(D3DERR_INVALIDCALL, "GetCubeMapSurface: ppCubeMapSurface was nullptr.");
*ppCubeMapSurface = ref(m_surfaces[subresource]);
return D3D_OK;
}
HRESULT STDMETHODCALLTYPE Direct3DCubeTexture9::LockRect(D3DCUBEMAP_FACES FaceType, UINT Level, D3DLOCKED_RECT* pLockedRect, const RECT* pRect, DWORD Flags) {
CriticalSection(this->GetD3D9Device());
UINT subresource = D3D11CalcSubresource(Level, FaceType, this->GetDXUPResource()->GetMips());
if (subresource >= m_surfaces.size())
return log::d3derr(D3DERR_INVALIDCALL, "LockRect: subresource out of bounds (Level = %d).", Level);
return m_surfaces[subresource]->LockRect(pLockedRect, pRect, Flags);
}
HRESULT STDMETHODCALLTYPE Direct3DCubeTexture9::UnlockRect(D3DCUBEMAP_FACES FaceType, UINT Level) {
CriticalSection(this->GetD3D9Device());
UINT subresource = D3D11CalcSubresource(Level, (UINT)FaceType, this->GetDXUPResource()->GetMips());
if (subresource >= m_surfaces.size())
return log::d3derr(D3DERR_INVALIDCALL, "UnlockRect: subresource out of bounds (FaceType = %d, Level = %d).", FaceType, Level);
return m_surfaces[subresource]->UnlockRect();
}
HRESULT STDMETHODCALLTYPE Direct3DCubeTexture9::AddDirtyRect(D3DCUBEMAP_FACES FaceType, const RECT* pDirtyRect) {
CriticalSection(this->GetD3D9Device());
log::stub("Direct3DCubeTexture9::AddDirtyRect");
return D3D_OK;
}
}
\ No newline at end of file
......@@ -7,39 +7,13 @@
namespace dxup {
const D3DCUBEMAP_FACES Face0 = (D3DCUBEMAP_FACES)0;
template <D3DRESOURCETYPE ResourceType, uint32_t slices, typename ID3D9BaseType>
class Direct3DGeneric2DTexture9 : public Direct3DResource9<ResourceType, ID3D9BaseType> {
template <D3DRESOURCETYPE ResourceType, typename ID3D9BaseType>
class Direct3DBaseTexture9 : public Direct3DResource9<ResourceType, ID3D9BaseType> {
public:
Direct3DGeneric2DTexture9(bool singletonSurface, Direct3DDevice9Ex* device, DXUPResource* resource, const D3D9ResourceDesc& desc)
: Direct3DResource9<ResourceType, ID3D9BaseType>{ device, resource, desc }
, m_singletonSurface{ singletonSurface } {
m_surfaces.reserve(resource->GetSubresources());
// This should allow us to match D3D11CalcSubresource.
for (UINT slice = 0; slice < resource->GetSlices(); slice++) {
for (UINT mip = 0; mip < resource->GetMips(); mip++) {
Direct3DSurface9* surface = new Direct3DSurface9(singletonSurface, slice, mip, device, this, resource, desc);
if (!singletonSurface)
surface->AddRefPrivate();
m_surfaces.push_back(surface);
}
}
}
~Direct3DGeneric2DTexture9() {
if (!m_singletonSurface) {
for (IDirect3DSurface9* surface : m_surfaces) {
Direct3DSurface9* internalSurface = reinterpret_cast<Direct3DSurface9*>(surface);
internalSurface->ReleasePrivate();
}
}
}
Direct3DBaseTexture9(Direct3DDevice9Ex* pDevice, DXUPResource* resource, const D3D9ResourceDesc& d3d9Desc)
: Direct3DResource9<ResourceType, ID3D9BaseType>{ pDevice, resource, d3d9Desc } {}
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObj) {
InitReturnPtr(ppvObj);
......@@ -47,7 +21,7 @@ namespace dxup {
if (ppvObj == nullptr)
return E_POINTER;
if (riid == __uuidof(ID3D9BaseType) || riid == __uuidof(IDirect3DResource9) || riid == __uuidof(IUnknown)) {
if (riid == __uuidof(ID3D9BaseType) || riid == __uuidof(IDirect3DBaseTexture9) || riid == __uuidof(IDirect3DResource9) || riid == __uuidof(IUnknown)) {
*ppvObj = ref(this);
return D3D_OK;
}
......@@ -59,67 +33,6 @@ namespace dxup {
return (DWORD)this->GetDXUPResource()->GetMips();
}
HRESULT STDMETHODCALLTYPE GetLevelDesc(UINT Level, D3DSURFACE_DESC *pDesc) {
if (Level >= m_surfaces.size())
return log::d3derr(D3DERR_INVALIDCALL, "GetLevelDesc: level out of bounds.");
return m_surfaces[Level]->GetDesc(pDesc);
}
HRESULT STDMETHODCALLTYPE GetCubeMapSurface(D3DCUBEMAP_FACES FaceType, UINT Level, IDirect3DSurface9** ppCubeMapSurface) {
UINT subresource = D3D11CalcSubresource(Level, (UINT)FaceType, this->GetDXUPResource()->GetMips());
InitReturnPtr(ppCubeMapSurface);
if (subresource >= m_surfaces.size())
return log::d3derr(D3DERR_INVALIDCALL, "GetCubeMapSurface: subresource out of bounds (FaceType = %d, Level = %d).", FaceType, Level);
if (ppCubeMapSurface == nullptr)
return log::d3derr(D3DERR_INVALIDCALL, "GetCubeMapSurface: ppCubeMapSurface was nullptr.");
*ppCubeMapSurface = ref(m_surfaces[subresource]);
return D3D_OK;
}
HRESULT STDMETHODCALLTYPE GetSurfaceLevel(UINT Level, IDirect3DSurface9** ppSurfaceLevel) {
return this->GetCubeMapSurface((D3DCUBEMAP_FACES)0, Level, ppSurfaceLevel);
}
HRESULT STDMETHODCALLTYPE LockRect(D3DCUBEMAP_FACES FaceType, UINT Level, D3DLOCKED_RECT* pLockedRect, const RECT* pRect, DWORD Flags) {
UINT subresource = D3D11CalcSubresource(Level, (UINT)FaceType, this->GetDXUPResource()->GetMips());
if (subresource >= m_surfaces.size())
return log::d3derr(D3DERR_INVALIDCALL, "LockRect: subresource out of bounds (FaceType = %d, Level = %d).", FaceType, Level);
return m_surfaces[subresource]->LockRect(pLockedRect, pRect, Flags);
}
HRESULT STDMETHODCALLTYPE LockRect(UINT Level, D3DLOCKED_RECT* pLockedRect, const RECT* pRect, DWORD Flags) {
return this->LockRect(Face0, Level, pLockedRect, pRect, Flags);
}
HRESULT STDMETHODCALLTYPE UnlockRect(D3DCUBEMAP_FACES FaceType, UINT Level) {
UINT subresource = D3D11CalcSubresource(Level, (UINT)FaceType, this->GetDXUPResource()->GetMips());
if (subresource >= m_surfaces.size())
return log::d3derr(D3DERR_INVALIDCALL, "UnlockRect: subresource out of bounds (FaceType = %d, Level = %d).", FaceType, Level);
return m_surfaces[subresource]->UnlockRect();
}
HRESULT STDMETHODCALLTYPE UnlockRect(UINT Level) {
return this->UnlockRect(Face0, Level);
}
HRESULT STDMETHODCALLTYPE AddDirtyRect(D3DCUBEMAP_FACES FaceType, const RECT* pDirtyRect) {
log::stub("Direct3DTexture9::AddDirtyRect");
return D3D_OK;
}
HRESULT STDMETHODCALLTYPE AddDirtyRect(const RECT* pDirtyRect) {
return this->AddDirtyRect(Face0, pDirtyRect);
}
void STDMETHODCALLTYPE GenerateMipSubLevels() {
if (this->GetDXUPResource()->GetSRV(false) != nullptr)
......@@ -128,10 +41,6 @@ namespace dxup {
log::warn("GenerateMipSubLevels called on a texture with no SRV.");
}
inline bool IsFakeSurface() {
return m_singletonSurface;
}
DWORD STDMETHODCALLTYPE SetLOD(DWORD LODNew) override {
log::stub("Direct3DBaseTexture9::SetLOD");
return 0;
......@@ -150,11 +59,48 @@ namespace dxup {
return D3DTEXF_ANISOTROPIC;
}
};
using Direct3DTexture9Base = Direct3DBaseTexture9<D3DRTYPE_TEXTURE, IDirect3DTexture9>;
class Direct3DTexture9 final : public Direct3DTexture9Base {
public:
Direct3DTexture9(bool singletonSurface, Direct3DDevice9Ex* device, DXUPResource* resource, const D3D9ResourceDesc& desc);
~Direct3DTexture9();
HRESULT STDMETHODCALLTYPE GetLevelDesc(UINT Level, D3DSURFACE_DESC *pDesc) override;
HRESULT STDMETHODCALLTYPE GetSurfaceLevel(UINT Level, IDirect3DSurface9** ppSurfaceLevel) override;
HRESULT STDMETHODCALLTYPE LockRect(UINT Level, D3DLOCKED_RECT* pLockedRect, const RECT* pRect, DWORD Flags) override;
HRESULT STDMETHODCALLTYPE UnlockRect(UINT Level) override;
HRESULT STDMETHODCALLTYPE AddDirtyRect(const RECT* pDirtyRect) override;
bool IsFakeSurface();
private:
bool m_singletonSurface;
std::vector<IDirect3DSurface9*> m_surfaces;
};
using Direct3DTexture9 = Direct3DGeneric2DTexture9<D3DRTYPE_TEXTURE, 1, IDirect3DTexture9>;
using Direct3DCubeTexture9 = Direct3DGeneric2DTexture9<D3DRTYPE_CUBETEXTURE, 6, IDirect3DCubeTexture9>;
using Direct3DCubeTexture9Base = Direct3DBaseTexture9<D3DRTYPE_CUBETEXTURE, IDirect3DCubeTexture9>;
class Direct3DCubeTexture9 final : public Direct3DCubeTexture9Base {
public:
Direct3DCubeTexture9(Direct3DDevice9Ex* device, DXUPResource* resource, const D3D9ResourceDesc& desc);
~Direct3DCubeTexture9();
HRESULT STDMETHODCALLTYPE GetLevelDesc(UINT Level, D3DSURFACE_DESC *pDesc) override;
HRESULT STDMETHODCALLTYPE GetCubeMapSurface(D3DCUBEMAP_FACES FaceType, UINT Level, IDirect3DSurface9** ppCubeMapSurface) override;
HRESULT STDMETHODCALLTYPE LockRect(D3DCUBEMAP_FACES FaceType, UINT Level, D3DLOCKED_RECT* pLockedRect, const RECT* pRect, DWORD Flags) override;
HRESULT STDMETHODCALLTYPE UnlockRect(D3DCUBEMAP_FACES FaceType, UINT Level) override;
HRESULT STDMETHODCALLTYPE AddDirtyRect(D3DCUBEMAP_FACES FaceType, const RECT* pDirtyRect) override;
private:
std::vector<IDirect3DSurface9*> m_surfaces;
};
}
\ No newline at end of file
......@@ -12,7 +12,8 @@ d3d9_main_src = [
'd3d9_state_cache.cpp',
'd3d9_state.cpp',
'd3d9_renderer.cpp',
'd3d11_dynamic_buffer.cpp'
'd3d11_dynamic_buffer.cpp',
'd3d9_texture.cpp'
]
d3d9_deps = [ lib_d3d11, lib_dxgi, lib_shlwapi, util_dep, dx9asm_dep ]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment