diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index eba73107..6d3d1da7 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -98,8 +98,15 @@ namespace dxvk { const D3D11_TEXTURE1D_DESC* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData, ID3D11Texture1D** ppTexture1D) { - Logger::err("D3D11Device::CreateTexture1D: Not implemented"); - return E_NOTIMPL; + if (ppTexture1D != nullptr) { + const Com texture + = new D3D11Texture1D(this, pDesc); + + this->InitTexture(texture->GetDXVKImage(), pInitialData); + *ppTexture1D = texture.ref(); + } + + return S_OK; } @@ -111,7 +118,7 @@ namespace dxvk { const Com texture = new D3D11Texture2D(this, pDesc); - this->InitTexture(texture.ptr(), pInitialData); + this->InitTexture(texture->GetDXVKImage(), pInitialData); *ppTexture2D = texture.ref(); } @@ -123,8 +130,15 @@ namespace dxvk { const D3D11_TEXTURE3D_DESC* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData, ID3D11Texture3D** ppTexture3D) { - Logger::err("D3D11Device::CreateTexture3D: Not implemented"); - return E_NOTIMPL; + if (ppTexture3D != nullptr) { + const Com texture + = new D3D11Texture3D(this, pDesc); + + this->InitTexture(texture->GetDXVKImage(), pInitialData); + *ppTexture3D = texture.ref(); + } + + return S_OK; } @@ -1176,13 +1190,12 @@ namespace dxvk { void D3D11Device::InitTexture( - D3D11Texture2D* pImage, + const Rc& image, const D3D11_SUBRESOURCE_DATA* pInitialData) { std::lock_guard lock(m_resourceInitMutex);; m_resourceInitContext->beginRecording( m_dxvkDevice->createCommandList()); - const Rc image = pImage->GetDXVKImage(); const DxvkFormatInfo* formatInfo = imageFormatInfo(image->info().format); if (pInitialData != nullptr) { diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index 0ccbd47f..84892283 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -272,7 +272,7 @@ namespace dxvk { const D3D11_SUBRESOURCE_DATA* pInitialData); void InitTexture( - D3D11Texture2D* pImage, + const Rc& image, const D3D11_SUBRESOURCE_DATA* pInitialData); HRESULT GetShaderResourceViewDescFromResource( diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index 47f63a2d..b6b6534e 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -3,6 +3,15 @@ namespace dxvk { + /** + * \brief Retrieves format mode from bind flags + * + * Uses the bind flags to determine whether a resource + * needs to be created with a color format or a depth + * format, even if the DXGI format is typeless. + * \param [in] BindFlags Image bind flags + * \returns Format mode + */ static DxgiFormatMode GetFormatModeFromBindFlags(UINT BindFlags) { if (BindFlags & D3D11_BIND_RENDER_TARGET) return DxgiFormatMode::Color; @@ -14,6 +23,151 @@ namespace dxvk { } + /** + * \brief Fills in image info stage and access flags + * + * \param [in] pDevice Target device + * \param [in] BindFLags Resource bind flags + * \param [in] CPUAccessFlags CPU access flags + * \param [in] MiscFlags Additional usage info + * \param [out] pImageInfo DXVK image create info + */ + static void GetImageStagesAndAccessFlags( + const D3D11Device* pDevice, + UINT BindFlags, + UINT CPUAccessFlags, + UINT MiscFlags, + DxvkImageCreateInfo* pImageInfo) { + + if (BindFlags & D3D11_BIND_SHADER_RESOURCE) { + pImageInfo->usage |= VK_IMAGE_USAGE_SAMPLED_BIT; + pImageInfo->stages |= pDevice->GetEnabledShaderStages(); + pImageInfo->access |= VK_ACCESS_SHADER_READ_BIT; + } + + if (BindFlags & D3D11_BIND_RENDER_TARGET) { + pImageInfo->usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + pImageInfo->stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + pImageInfo->access |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT + | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + } + + if (BindFlags & D3D11_BIND_DEPTH_STENCIL) { + pImageInfo->usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + pImageInfo->stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT + | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + pImageInfo->access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT + | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + } + + if (BindFlags & D3D11_BIND_UNORDERED_ACCESS) { + pImageInfo->usage |= VK_IMAGE_USAGE_STORAGE_BIT; + pImageInfo->stages |= pDevice->GetEnabledShaderStages(); + pImageInfo->access |= VK_ACCESS_SHADER_READ_BIT + | VK_ACCESS_SHADER_WRITE_BIT; + } + + if (CPUAccessFlags != 0) { + pImageInfo->tiling = VK_IMAGE_TILING_LINEAR; + pImageInfo->stages |= VK_PIPELINE_STAGE_HOST_BIT; + + if (CPUAccessFlags & D3D11_CPU_ACCESS_WRITE) + pImageInfo->access |= VK_ACCESS_HOST_WRITE_BIT; + + if (CPUAccessFlags & D3D11_CPU_ACCESS_READ) + pImageInfo->access |= VK_ACCESS_HOST_READ_BIT; + } + + if (MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE) + pImageInfo->flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; + + if (pImageInfo->mipLevels == 0) + pImageInfo->mipLevels = util::computeMipLevelCount(pImageInfo->extent); + } + + + D3D11Texture1D::D3D11Texture1D( + D3D11Device* pDevice, + const D3D11_TEXTURE1D_DESC* pDesc) + : m_device (pDevice), + m_formatMode(GetFormatModeFromBindFlags(pDesc->BindFlags)), + m_desc (*pDesc) { + + DxvkImageCreateInfo info; + info.type = VK_IMAGE_TYPE_1D; + info.format = pDevice->LookupFormat(pDesc->Format, m_formatMode).format; + info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; + info.sampleCount = VK_SAMPLE_COUNT_1_BIT; + info.extent.width = pDesc->Width; + info.extent.height = 1; + info.extent.depth = 1; + info.numLayers = pDesc->ArraySize; + info.mipLevels = pDesc->MipLevels; + info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT + | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT; + info.access = VK_ACCESS_TRANSFER_READ_BIT + | VK_ACCESS_TRANSFER_WRITE_BIT; + info.tiling = VK_IMAGE_TILING_OPTIMAL; + info.layout = VK_IMAGE_LAYOUT_GENERAL; + + GetImageStagesAndAccessFlags( + pDevice, + pDesc->BindFlags, + pDesc->CPUAccessFlags, + pDesc->MiscFlags, + &info); + + m_image = pDevice->GetDXVKDevice()->createImage( + info, GetMemoryFlagsForUsage(pDesc->Usage)); + } + + /////////////////////////////////////////// + // D 3 D 1 1 T E X T U R E 1 D + D3D11Texture1D::~D3D11Texture1D() { + + } + + + HRESULT STDMETHODCALLTYPE D3D11Texture1D::QueryInterface(REFIID riid, void** ppvObject) { + COM_QUERY_IFACE(riid, ppvObject, IUnknown); + COM_QUERY_IFACE(riid, ppvObject, ID3D11DeviceChild); + COM_QUERY_IFACE(riid, ppvObject, ID3D11Resource); + COM_QUERY_IFACE(riid, ppvObject, ID3D11Texture1D); + + Logger::warn("D3D11Texture1D::QueryInterface: Unknown interface query"); + return E_NOINTERFACE; + } + + + void STDMETHODCALLTYPE D3D11Texture1D::GetDevice(ID3D11Device** ppDevice) { + *ppDevice = m_device.ref(); + } + + + void STDMETHODCALLTYPE D3D11Texture1D::GetType(D3D11_RESOURCE_DIMENSION *pResourceDimension) { + *pResourceDimension = D3D11_RESOURCE_DIMENSION_TEXTURE1D; + } + + + UINT STDMETHODCALLTYPE D3D11Texture1D::GetEvictionPriority() { + Logger::warn("D3D11Texture1D::GetEvictionPriority: Stub"); + return DXGI_RESOURCE_PRIORITY_NORMAL; + } + + + void STDMETHODCALLTYPE D3D11Texture1D::SetEvictionPriority(UINT EvictionPriority) { + Logger::warn("D3D11Texture1D::SetEvictionPriority: Stub"); + } + + + void STDMETHODCALLTYPE D3D11Texture1D::GetDesc(D3D11_TEXTURE1D_DESC *pDesc) { + *pDesc = m_desc; + } + + + /////////////////////////////////////////// + // D 3 D 1 1 T E X T U R E 2 D D3D11Texture2D::D3D11Texture2D( D3D11Device* pDevice, const D3D11_TEXTURE2D_DESC* pDesc) @@ -23,8 +177,7 @@ namespace dxvk { DxvkImageCreateInfo info; info.type = VK_IMAGE_TYPE_2D; - info.format = pDevice->LookupFormat( - pDesc->Format, m_formatMode).format; + info.format = pDevice->LookupFormat(pDesc->Format, m_formatMode).format; info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; info.sampleCount = VK_SAMPLE_COUNT_1_BIT; info.extent.width = pDesc->Width; @@ -43,50 +196,12 @@ namespace dxvk { if (FAILED(GetSampleCount(pDesc->SampleDesc.Count, &info.sampleCount))) throw DxvkError(str::format("D3D11: Invalid sample count: ", pDesc->SampleDesc.Count)); - if (pDesc->BindFlags & D3D11_BIND_SHADER_RESOURCE) { - info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT; - info.stages |= pDevice->GetEnabledShaderStages(); - info.access |= VK_ACCESS_SHADER_READ_BIT; - } - - if (pDesc->BindFlags & D3D11_BIND_RENDER_TARGET) { - info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - info.stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - info.access |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT - | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - } - - if (pDesc->BindFlags & D3D11_BIND_DEPTH_STENCIL) { - info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; - info.stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT - | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; - info.access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT - | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - } - - if (pDesc->BindFlags & D3D11_BIND_UNORDERED_ACCESS) { - info.usage |= VK_IMAGE_USAGE_STORAGE_BIT; - info.stages |= pDevice->GetEnabledShaderStages(); - info.access |= VK_ACCESS_SHADER_READ_BIT - | VK_ACCESS_SHADER_WRITE_BIT; - } - - if (pDesc->CPUAccessFlags != 0) { - info.tiling = VK_IMAGE_TILING_LINEAR; - info.stages |= VK_PIPELINE_STAGE_HOST_BIT; - - if (pDesc->CPUAccessFlags & D3D11_CPU_ACCESS_WRITE) - info.access |= VK_ACCESS_HOST_WRITE_BIT; - - if (pDesc->CPUAccessFlags & D3D11_CPU_ACCESS_READ) - info.access |= VK_ACCESS_HOST_READ_BIT; - } - - if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE) - info.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; - - if (pDesc->MipLevels == 0) - info.mipLevels = util::computeMipLevelCount(info.extent); + GetImageStagesAndAccessFlags( + pDevice, + pDesc->BindFlags, + pDesc->CPUAccessFlags, + pDesc->MiscFlags, + &info); m_image = pDevice->GetDXVKDevice()->createImage( info, GetMemoryFlagsForUsage(pDesc->Usage)); @@ -135,6 +250,88 @@ namespace dxvk { } + /////////////////////////////////////////// + // D 3 D 1 1 T E X T U R E 2 D + D3D11Texture3D::D3D11Texture3D( + D3D11Device* pDevice, + const D3D11_TEXTURE3D_DESC* pDesc) + : m_device (pDevice), + m_formatMode(GetFormatModeFromBindFlags(pDesc->BindFlags)), + m_desc (*pDesc) { + + DxvkImageCreateInfo info; + info.type = VK_IMAGE_TYPE_3D; + info.format = pDevice->LookupFormat(pDesc->Format, m_formatMode).format; + info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT + | VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR; + info.sampleCount = VK_SAMPLE_COUNT_1_BIT; + info.extent.width = pDesc->Width; + info.extent.height = pDesc->Height; + info.extent.depth = pDesc->Depth; + info.numLayers = 1; + info.mipLevels = pDesc->MipLevels; + info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT + | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT; + info.access = VK_ACCESS_TRANSFER_READ_BIT + | VK_ACCESS_TRANSFER_WRITE_BIT; + info.tiling = VK_IMAGE_TILING_OPTIMAL; + info.layout = VK_IMAGE_LAYOUT_GENERAL; + + GetImageStagesAndAccessFlags( + pDevice, + pDesc->BindFlags, + pDesc->CPUAccessFlags, + pDesc->MiscFlags, + &info); + + m_image = pDevice->GetDXVKDevice()->createImage( + info, GetMemoryFlagsForUsage(pDesc->Usage)); + } + + + D3D11Texture3D::~D3D11Texture3D() { + + } + + + HRESULT STDMETHODCALLTYPE D3D11Texture3D::QueryInterface(REFIID riid, void** ppvObject) { + COM_QUERY_IFACE(riid, ppvObject, IUnknown); + COM_QUERY_IFACE(riid, ppvObject, ID3D11DeviceChild); + COM_QUERY_IFACE(riid, ppvObject, ID3D11Resource); + COM_QUERY_IFACE(riid, ppvObject, ID3D11Texture3D); + + Logger::warn("D3D11Texture3D::QueryInterface: Unknown interface query"); + return E_NOINTERFACE; + } + + + void STDMETHODCALLTYPE D3D11Texture3D::GetDevice(ID3D11Device** ppDevice) { + *ppDevice = m_device.ref(); + } + + + void STDMETHODCALLTYPE D3D11Texture3D::GetType(D3D11_RESOURCE_DIMENSION *pResourceDimension) { + *pResourceDimension = D3D11_RESOURCE_DIMENSION_TEXTURE3D; + } + + + UINT STDMETHODCALLTYPE D3D11Texture3D::GetEvictionPriority() { + Logger::warn("D3D11Texture3D::GetEvictionPriority: Stub"); + return DXGI_RESOURCE_PRIORITY_NORMAL; + } + + + void STDMETHODCALLTYPE D3D11Texture3D::SetEvictionPriority(UINT EvictionPriority) { + Logger::warn("D3D11Texture3D::SetEvictionPriority: Stub"); + } + + + void STDMETHODCALLTYPE D3D11Texture3D::GetDesc(D3D11_TEXTURE3D_DESC *pDesc) { + *pDesc = m_desc; + } + + HRESULT GetCommonTextureInfo( ID3D11Resource* pResource, @@ -143,12 +340,24 @@ namespace dxvk { pResource->GetType(&dimension); switch (dimension) { + case D3D11_RESOURCE_DIMENSION_TEXTURE1D: { + auto tex = static_cast(pResource); + pTextureInfo->formatMode = tex->GetFormatMode(); + pTextureInfo->image = tex->GetDXVKImage(); + } return S_OK; + case D3D11_RESOURCE_DIMENSION_TEXTURE2D: { auto tex = static_cast(pResource); pTextureInfo->formatMode = tex->GetFormatMode(); pTextureInfo->image = tex->GetDXVKImage(); } return S_OK; + case D3D11_RESOURCE_DIMENSION_TEXTURE3D: { + auto tex = static_cast(pResource); + pTextureInfo->formatMode = tex->GetFormatMode(); + pTextureInfo->image = tex->GetDXVKImage(); + } return S_OK; + default: return E_INVALIDARG; } diff --git a/src/d3d11/d3d11_texture.h b/src/d3d11/d3d11_texture.h index f7b1ffd4..377e40a3 100644 --- a/src/d3d11/d3d11_texture.h +++ b/src/d3d11/d3d11_texture.h @@ -9,6 +9,55 @@ namespace dxvk { class D3D11Device; + /////////////////////////////////////////// + // D 3 D 1 1 T E X T U R E 1 D + class D3D11Texture1D : public D3D11DeviceChild { + + public: + + D3D11Texture1D( + D3D11Device* pDevice, + const D3D11_TEXTURE1D_DESC* pDesc); + + ~D3D11Texture1D(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject) final; + + void STDMETHODCALLTYPE GetDevice( + ID3D11Device **ppDevice) final; + + void STDMETHODCALLTYPE GetType( + D3D11_RESOURCE_DIMENSION *pResourceDimension) final; + + UINT STDMETHODCALLTYPE GetEvictionPriority() final; + + void STDMETHODCALLTYPE SetEvictionPriority(UINT EvictionPriority) final; + + void STDMETHODCALLTYPE GetDesc( + D3D11_TEXTURE1D_DESC *pDesc) final; + + DxgiFormatMode GetFormatMode() const { + return m_formatMode; + } + + Rc GetDXVKImage() const { + return m_image; + } + + private: + + Com m_device; + DxgiFormatMode m_formatMode; + D3D11_TEXTURE1D_DESC m_desc; + Rc m_image; + + }; + + + /////////////////////////////////////////// + // D 3 D 1 1 T E X T U R E 2 D class D3D11Texture2D : public D3D11DeviceChild { public: @@ -54,6 +103,53 @@ namespace dxvk { }; + /////////////////////////////////////////// + // D 3 D 1 1 T E X T U R E 3 D + class D3D11Texture3D : public D3D11DeviceChild { + + public: + + D3D11Texture3D( + D3D11Device* pDevice, + const D3D11_TEXTURE3D_DESC* pDesc); + + ~D3D11Texture3D(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject) final; + + void STDMETHODCALLTYPE GetDevice( + ID3D11Device **ppDevice) final; + + void STDMETHODCALLTYPE GetType( + D3D11_RESOURCE_DIMENSION *pResourceDimension) final; + + UINT STDMETHODCALLTYPE GetEvictionPriority() final; + + void STDMETHODCALLTYPE SetEvictionPriority(UINT EvictionPriority) final; + + void STDMETHODCALLTYPE GetDesc( + D3D11_TEXTURE3D_DESC *pDesc) final; + + DxgiFormatMode GetFormatMode() const { + return m_formatMode; + } + + Rc GetDXVKImage() const { + return m_image; + } + + private: + + Com m_device; + DxgiFormatMode m_formatMode; + D3D11_TEXTURE3D_DESC m_desc; + Rc m_image; + + }; + + /** * \brief Common texture info * @@ -74,7 +170,7 @@ namespace dxvk { * \returns E_INVALIDARG if the resource is not a texture */ HRESULT GetCommonTextureInfo( - ID3D11Resource* pResource, - D3D11TextureInfo* pTextureInfo); + ID3D11Resource* pResource, + D3D11TextureInfo* pTextureInfo); }