1
0
mirror of https://github.com/EduApps-CDG/OpenDX synced 2024-12-30 09:45:37 +01:00

[d3d9] Don't expose surfaces for autogenned mips

This commit is contained in:
Joshua Ashton 2020-05-26 13:11:24 +01:00
parent a35df1c3b1
commit 4c1deabcd3
4 changed files with 50 additions and 48 deletions

View File

@ -55,6 +55,11 @@ namespace dxvk {
if (m_mapMode == D3D9_COMMON_TEXTURE_MAP_MODE_SYSTEMMEM) if (m_mapMode == D3D9_COMMON_TEXTURE_MAP_MODE_SYSTEMMEM)
CreateBuffers(); CreateBuffers();
m_exposedMipLevels = m_desc.MipLevels;
if (m_desc.Usage & D3DUSAGE_AUTOGENMIPMAP)
m_exposedMipLevels = 1;
} }

View File

@ -354,6 +354,8 @@ namespace dxvk {
bool NeedsAnyUpload() { return m_needsUpload.any(); } bool NeedsAnyUpload() { return m_needsUpload.any(); }
void ClearNeedsUpload() { return m_needsUpload.clearAll(); } void ClearNeedsUpload() { return m_needsUpload.clearAll(); }
DWORD ExposedMipLevels() { return m_exposedMipLevels; }
private: private:
D3D9DeviceEx* m_device; D3D9DeviceEx* m_device;
@ -391,6 +393,8 @@ namespace dxvk {
D3D9SubresourceBitset m_uploading = { }; D3D9SubresourceBitset m_uploading = { };
D3D9SubresourceBitset m_needsUpload = { }; D3D9SubresourceBitset m_needsUpload = { };
DWORD m_exposedMipLevels = 0;
/** /**
* \brief Mip level * \brief Mip level
* \returns Size of packed mip level in bytes * \returns Size of packed mip level in bytes

View File

@ -38,41 +38,43 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE D3D9Texture2D::GetLevelDesc(UINT Level, D3DSURFACE_DESC *pDesc) { HRESULT STDMETHODCALLTYPE D3D9Texture2D::GetLevelDesc(UINT Level, D3DSURFACE_DESC *pDesc) {
auto* surface = GetSubresource(Level); if (unlikely(Level >= m_texture.ExposedMipLevels()))
if (surface == nullptr)
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
return surface->GetDesc(pDesc); return GetSubresource(Level)->GetDesc(pDesc);
} }
HRESULT STDMETHODCALLTYPE D3D9Texture2D::GetSurfaceLevel(UINT Level, IDirect3DSurface9** ppSurfaceLevel) { HRESULT STDMETHODCALLTYPE D3D9Texture2D::GetSurfaceLevel(UINT Level, IDirect3DSurface9** ppSurfaceLevel) {
InitReturnPtr(ppSurfaceLevel); InitReturnPtr(ppSurfaceLevel);
auto* surface = GetSubresource(Level);
if (ppSurfaceLevel == nullptr || surface == nullptr) if (unlikely(Level >= m_texture.ExposedMipLevels()))
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
*ppSurfaceLevel = ref(surface); if (unlikely(ppSurfaceLevel == nullptr))
return D3DERR_INVALIDCALL;
*ppSurfaceLevel = ref(GetSubresource(Level));
return D3D_OK; return D3D_OK;
} }
HRESULT STDMETHODCALLTYPE D3D9Texture2D::LockRect(UINT Level, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) { HRESULT STDMETHODCALLTYPE D3D9Texture2D::LockRect(UINT Level, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) {
auto* surface = GetSubresource(Level); if (unlikely(Level >= m_texture.ExposedMipLevels()))
if (surface == nullptr || pLockedRect == nullptr)
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
return surface->LockRect(pLockedRect, pRect, Flags); if (unlikely(pLockedRect == nullptr))
return D3DERR_INVALIDCALL;
return GetSubresource(Level)->LockRect(pLockedRect, pRect, Flags);
} }
HRESULT STDMETHODCALLTYPE D3D9Texture2D::UnlockRect(UINT Level) { HRESULT STDMETHODCALLTYPE D3D9Texture2D::UnlockRect(UINT Level) {
auto* surface = GetSubresource(Level); if (unlikely(Level >= m_texture.ExposedMipLevels()))
if (surface == nullptr)
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
return surface->UnlockRect(); return GetSubresource(Level)->UnlockRect();
} }
@ -116,41 +118,43 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE D3D9Texture3D::GetLevelDesc(UINT Level, D3DVOLUME_DESC *pDesc) { HRESULT STDMETHODCALLTYPE D3D9Texture3D::GetLevelDesc(UINT Level, D3DVOLUME_DESC *pDesc) {
auto* volume = GetSubresource(Level); if (unlikely(Level >= m_texture.ExposedMipLevels()))
if (volume == nullptr)
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
return volume->GetDesc(pDesc); return GetSubresource(Level)->GetDesc(pDesc);
} }
HRESULT STDMETHODCALLTYPE D3D9Texture3D::GetVolumeLevel(UINT Level, IDirect3DVolume9** ppVolumeLevel) { HRESULT STDMETHODCALLTYPE D3D9Texture3D::GetVolumeLevel(UINT Level, IDirect3DVolume9** ppVolumeLevel) {
InitReturnPtr(ppVolumeLevel); InitReturnPtr(ppVolumeLevel);
auto* volume = GetSubresource(Level);
if (ppVolumeLevel == nullptr || volume == nullptr) if (unlikely(Level >= m_texture.ExposedMipLevels()))
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
*ppVolumeLevel = ref(volume); if (unlikely(ppVolumeLevel == nullptr))
return D3DERR_INVALIDCALL;
*ppVolumeLevel = ref(GetSubresource(Level));
return D3D_OK; return D3D_OK;
} }
HRESULT STDMETHODCALLTYPE D3D9Texture3D::LockBox(UINT Level, D3DLOCKED_BOX* pLockedBox, CONST D3DBOX* pBox, DWORD Flags) { HRESULT STDMETHODCALLTYPE D3D9Texture3D::LockBox(UINT Level, D3DLOCKED_BOX* pLockedBox, CONST D3DBOX* pBox, DWORD Flags) {
auto* volume = GetSubresource(Level); if (unlikely(Level >= m_texture.ExposedMipLevels()))
if (volume == nullptr || pLockedBox == nullptr)
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
return volume->LockBox(pLockedBox, pBox, Flags); if (unlikely(pLockedBox == nullptr))
return D3DERR_INVALIDCALL;
return GetSubresource(Level)->LockBox(pLockedBox, pBox, Flags);
} }
HRESULT STDMETHODCALLTYPE D3D9Texture3D::UnlockBox(UINT Level) { HRESULT STDMETHODCALLTYPE D3D9Texture3D::UnlockBox(UINT Level) {
auto* volume = GetSubresource(Level); if (unlikely(Level >= m_texture.ExposedMipLevels()))
if (volume == nullptr)
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
return volume->UnlockBox(); return GetSubresource(Level)->UnlockBox();
} }
@ -194,51 +198,43 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE D3D9TextureCube::GetLevelDesc(UINT Level, D3DSURFACE_DESC *pDesc) { HRESULT STDMETHODCALLTYPE D3D9TextureCube::GetLevelDesc(UINT Level, D3DSURFACE_DESC *pDesc) {
auto* surface = GetSubresource(Level); if (unlikely(Level >= m_texture.ExposedMipLevels()))
if (surface == nullptr)
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
return surface->GetDesc(pDesc); return GetSubresource(Level)->GetDesc(pDesc);
} }
HRESULT STDMETHODCALLTYPE D3D9TextureCube::GetCubeMapSurface(D3DCUBEMAP_FACES Face, UINT Level, IDirect3DSurface9** ppSurfaceLevel) { HRESULT STDMETHODCALLTYPE D3D9TextureCube::GetCubeMapSurface(D3DCUBEMAP_FACES Face, UINT Level, IDirect3DSurface9** ppSurfaceLevel) {
InitReturnPtr(ppSurfaceLevel); InitReturnPtr(ppSurfaceLevel);
if (Level >= m_texture.Desc()->MipLevels) if (unlikely(Level >= m_texture.ExposedMipLevels() || Face >= D3DCUBEMAP_FACES(6)))
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
auto* surface = GetSubresource( if (unlikely(ppSurfaceLevel == nullptr))
m_texture.CalcSubresource(UINT(Face), Level));
if (ppSurfaceLevel == nullptr || surface == nullptr)
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
*ppSurfaceLevel = ref(surface); *ppSurfaceLevel = ref(GetSubresource(m_texture.CalcSubresource(UINT(Face), Level)));
return D3D_OK; return D3D_OK;
} }
HRESULT STDMETHODCALLTYPE D3D9TextureCube::LockRect(D3DCUBEMAP_FACES Face, UINT Level, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) { HRESULT STDMETHODCALLTYPE D3D9TextureCube::LockRect(D3DCUBEMAP_FACES Face, UINT Level, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) {
auto* surface = GetSubresource( if (unlikely(Face > D3DCUBEMAP_FACE_NEGATIVE_Z || Level >= m_texture.ExposedMipLevels()))
m_texture.CalcSubresource(UINT(Face), Level));
if (surface == nullptr || pLockedRect == nullptr)
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
return surface->LockRect(pLockedRect, pRect, Flags); if (unlikely(pLockedRect == nullptr))
return D3DERR_INVALIDCALL;
return GetSubresource(m_texture.CalcSubresource(UINT(Face), Level))->LockRect(pLockedRect, pRect, Flags);
} }
HRESULT STDMETHODCALLTYPE D3D9TextureCube::UnlockRect(D3DCUBEMAP_FACES Face, UINT Level) { HRESULT STDMETHODCALLTYPE D3D9TextureCube::UnlockRect(D3DCUBEMAP_FACES Face, UINT Level) {
auto* surface = GetSubresource( if (unlikely(Face > D3DCUBEMAP_FACE_NEGATIVE_Z || Level >= m_texture.ExposedMipLevels()))
m_texture.CalcSubresource(UINT(Face), Level));
if (surface == nullptr)
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
return surface->UnlockRect(); return GetSubresource(m_texture.CalcSubresource(UINT(Face), Level))->UnlockRect();
} }

View File

@ -71,7 +71,7 @@ namespace dxvk {
} }
DWORD STDMETHODCALLTYPE GetLevelCount() final { DWORD STDMETHODCALLTYPE GetLevelCount() final {
return m_texture.Desc()->MipLevels; return m_texture.ExposedMipLevels();
} }
HRESULT STDMETHODCALLTYPE SetAutoGenFilterType(D3DTEXTUREFILTERTYPE FilterType) final { HRESULT STDMETHODCALLTYPE SetAutoGenFilterType(D3DTEXTUREFILTERTYPE FilterType) final {
@ -93,9 +93,6 @@ namespace dxvk {
} }
SubresourceType* GetSubresource(UINT Subresource) { SubresourceType* GetSubresource(UINT Subresource) {
if (unlikely(Subresource >= m_subresources.size()))
return nullptr;
return reinterpret_cast<SubresourceType*>(&m_subresources[Subresource]); return reinterpret_cast<SubresourceType*>(&m_subresources[Subresource]);
} }