#pragma once #include "d3d9_resource.h" #include "d3d9_common_texture.h" namespace dxvk { template class D3D9Subresource : public D3D9Resource { public: D3D9Subresource( D3D9DeviceEx* pDevice, D3D9CommonTexture* pTexture, UINT Face, UINT MipLevel, IDirect3DBaseTexture9* pContainer) : D3D9Resource ( pDevice ) , m_container ( pContainer ) , m_texture ( pTexture ) , m_face ( Face ) , m_mipLevel ( MipLevel ) , m_isSrgbCompatible ( pTexture->IsSrgbCompatible() ) { } ~D3D9Subresource() { // We own the texture! if (m_container == nullptr) delete m_texture; } ULONG STDMETHODCALLTYPE AddRef() final { if (m_container != nullptr) return m_container->AddRef(); return D3D9Resource::AddRef(); } ULONG STDMETHODCALLTYPE Release() final { if (m_container != nullptr) return m_container->Release(); return D3D9Resource::Release(); } HRESULT STDMETHODCALLTYPE GetContainer(REFIID riid, void** ppContainer) final { if (m_container != nullptr) return m_container->QueryInterface(riid, ppContainer); return this->GetDevice()->QueryInterface(riid, ppContainer); } D3D9CommonTexture* GetCommonTexture() { return m_texture; } UINT GetFace() const { return m_face; } UINT GetMipLevel() const { return m_mipLevel; } UINT GetSubresource() const { return m_texture->CalcSubresource(m_face, m_mipLevel); } Rc GetImageView(bool Srgb) { Srgb &= m_isSrgbCompatible; Rc& view = m_sampleView.Pick(Srgb); if (unlikely(view == nullptr && !IsNull())) view = m_texture->CreateView(m_face, m_mipLevel, VK_IMAGE_USAGE_SAMPLED_BIT, Srgb); return view; } Rc GetRenderTargetView(bool Srgb) { Srgb &= m_isSrgbCompatible; Rc& view = m_renderTargetView.Pick(Srgb); if (unlikely(view == nullptr && !IsNull())) view = m_texture->CreateView(m_face, m_mipLevel, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, Srgb); return view; } VkImageLayout GetRenderTargetLayout() const { return m_texture->DetermineRenderTargetLayout(); } Rc GetDepthStencilView() { Rc& view = m_depthStencilView; if (unlikely(view == nullptr && !IsNull())) view = m_texture->CreateView(m_face, m_mipLevel, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, false); return view; } VkImageLayout GetDepthStencilLayout() const { return m_texture->DetermineDepthStencilLayout(); } bool IsNull() { return m_texture->Desc()->Format == D3D9Format::NULL_FORMAT; } IDirect3DBaseTexture9* GetBaseTexture() { return m_container; } protected: IDirect3DBaseTexture9* m_container; D3D9CommonTexture* m_texture; UINT m_face; UINT m_mipLevel; bool m_isSrgbCompatible; D3D9ColorView m_sampleView; D3D9ColorView m_renderTargetView; Rc m_depthStencilView; }; }