diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index ed498b63a..386cf29d0 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -38,7 +38,7 @@ namespace dxvk { throw e; } - CreateInitialViews(); + CreateSampleView(0); if (!IsManaged()) { m_size = m_image->memSize(); @@ -292,18 +292,6 @@ namespace dxvk { } - void D3D9CommonTexture::RecreateSampledView(UINT Lod) { - // This will be a no-op for SYSTEMMEM types given we - // don't expose the cap to allow texturing with them. - if (unlikely(m_mapMode == D3D9_COMMON_TEXTURE_MAP_MODE_SYSTEMMEM)) - return; - - const D3D9_VK_FORMAT_MAPPING formatInfo = m_device->LookupFormat(m_desc.Format); - - m_views.Sample = CreateColorViewPair(formatInfo, AllLayers, VK_IMAGE_USAGE_SAMPLED_BIT, Lod); - } - - BOOL D3D9CommonTexture::DetermineShadowState() const { static std::array blacklist = { D3D9Format::INTZ, D3D9Format::DF16, D3D9Format::DF24 @@ -427,15 +415,14 @@ namespace dxvk { Rc D3D9CommonTexture::CreateView( - D3D9_VK_FORMAT_MAPPING FormatInfo, UINT Layer, - VkImageUsageFlags UsageFlags, UINT Lod, - BOOL Srgb) { + VkImageUsageFlags UsageFlags, + bool Srgb) { DxvkImageViewCreateInfo viewInfo; - viewInfo.format = PickSRGB(FormatInfo.FormatColor, FormatInfo.FormatSrgb, Srgb); + viewInfo.format = PickSRGB(m_mapping.FormatColor, m_mapping.FormatSrgb, Srgb); viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask; - viewInfo.swizzle = FormatInfo.Swizzle; + viewInfo.swizzle = m_mapping.Swizzle; viewInfo.usage = UsageFlags; viewInfo.type = GetImageViewTypeFromResourceType(m_type, Layer); viewInfo.minLevel = Lod; @@ -462,46 +449,14 @@ namespace dxvk { } - D3D9ColorView D3D9CommonTexture::CreateColorViewPair( - D3D9_VK_FORMAT_MAPPING FormatInfo, - UINT Layer, - VkImageUsageFlags UsageFlags, - UINT Lod) { - D3D9ColorView pair; - pair.Color = CreateView(FormatInfo, Layer, UsageFlags, Lod, FALSE); + void D3D9CommonTexture::CreateSampleView(UINT Lod) { + // This will be a no-op for SYSTEMMEM types given we + // don't expose the cap to allow texturing with them. + if (unlikely(m_mapMode == D3D9_COMMON_TEXTURE_MAP_MODE_SYSTEMMEM)) + return; - if (FormatInfo.FormatSrgb != VK_FORMAT_UNDEFINED) - pair.Srgb = CreateView(FormatInfo, Layer, UsageFlags, Lod, TRUE); - else - pair.Srgb = pair.Color; - - return pair; - } - - - void D3D9CommonTexture::CreateInitialViews() { - const D3D9_VK_FORMAT_MAPPING formatInfo = m_device->LookupFormat(m_desc.Format); - - m_views.Sample = CreateColorViewPair(formatInfo, AllLayers, VK_IMAGE_USAGE_SAMPLED_BIT, 0); - - for (uint32_t i = 0; i < m_desc.ArraySize; i++) { - for (uint32_t j = 0; j < m_desc.MipLevels; j++) - m_views.SubresourceSample[i][j] = CreateColorViewPair(formatInfo, i, VK_IMAGE_USAGE_SAMPLED_BIT, j); - } - - if (m_desc.Usage & D3DUSAGE_RENDERTARGET) { - for (uint32_t i = 0; i < m_desc.ArraySize; i++) { - for (uint32_t j = 0; j < m_desc.MipLevels; j++) - m_views.SubresourceRenderTarget[i][j] = CreateColorViewPair(formatInfo, i, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, j); - } - } - - if (m_desc.Usage & D3DUSAGE_DEPTHSTENCIL) { - for (uint32_t i = 0; i < m_desc.ArraySize; i++) { - for (uint32_t j = 0; j < m_desc.MipLevels; j++) - m_views.SubresourceDepth[i][j] = CreateView(formatInfo, i, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, j, FALSE); - } - } + m_sampleView.Color = CreateView(AllLayers, Lod, VK_IMAGE_USAGE_SAMPLED_BIT, false); + m_sampleView.Srgb = CreateView(AllLayers, Lod, VK_IMAGE_USAGE_SAMPLED_BIT, true); } diff --git a/src/d3d9/d3d9_common_texture.h b/src/d3d9/d3d9_common_texture.h index 5f1ed3529..e08ff64b5 100644 --- a/src/d3d9/d3d9_common_texture.h +++ b/src/d3d9/d3d9_common_texture.h @@ -43,7 +43,11 @@ namespace dxvk { }; struct D3D9ColorView { - inline Rc Pick(bool Srgb) const { + inline Rc& Pick(bool Srgb) { + return Srgb ? this->Srgb : this->Color; + } + + inline const Rc& Pick(bool Srgb) const { return Srgb ? this->Srgb : this->Color; } @@ -290,20 +294,12 @@ namespace dxvk { return m_desc.Usage & D3DUSAGE_AUTOGENMIPMAP; } - /** - * \brief Autogen Mipmap - * \returns Whether the texture is to have automatic mip generation - */ - const D3D9ViewSet& GetViews() const { - return m_views; - } - /** * \brief Recreate main image view * Recreates the main view of the sampler w/ a specific LOD. * SetLOD only works on MANAGED textures so this is A-okay. */ - void RecreateSampledView(UINT Lod); + void CreateSampleView(UINT Lod); /** * \brief Extent @@ -323,7 +319,7 @@ namespace dxvk { } bool MarkHazardous() { - return std::exchange(m_views.Hazardous, true); + return std::exchange(m_hazardous, true); } D3DRESOURCETYPE GetType() { @@ -337,6 +333,32 @@ namespace dxvk { bool SetDirty(UINT Subresource, bool value) { return std::exchange(m_dirty[Subresource], value); } void MarkAllDirty() { for (uint32_t i = 0; i < m_dirty.size(); i++) m_dirty[i] = true; } + const D3D9ColorView& GetSampleView() const { + return m_sampleView; + } + + VkImageLayout DetermineRenderTargetLayout() const { + return m_image != nullptr && + m_image->info().tiling == VK_IMAGE_TILING_OPTIMAL && + !m_hazardous + ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL + : VK_IMAGE_LAYOUT_GENERAL; + } + + VkImageLayout DetermineDepthStencilLayout() const { + return m_image != nullptr && + m_image->info().tiling == VK_IMAGE_TILING_OPTIMAL && + !m_hazardous + ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL + : VK_IMAGE_LAYOUT_GENERAL; + } + + Rc CreateView( + UINT Layer, + UINT Lod, + VkImageUsageFlags UsageFlags, + bool Srgb); + private: D3D9DeviceEx* m_device; @@ -352,8 +374,6 @@ namespace dxvk { DxvkBufferSliceHandle> m_mappedSlices; D3D9SubresourceArray m_lockFlags; - D3D9ViewSet m_views; - D3D9_VK_FORMAT_MAPPING m_mapping; VkExtent3D m_adjustedExtent; @@ -364,6 +384,10 @@ namespace dxvk { bool m_systemmemModified = false; + bool m_hazardous = false; + + D3D9ColorView m_sampleView; + D3D9SubresourceArray< bool> m_locked = { }; @@ -412,20 +436,6 @@ namespace dxvk { static constexpr UINT AllLayers = UINT32_MAX; - Rc CreateView( - D3D9_VK_FORMAT_MAPPING FormatInfo, - UINT Layer, - VkImageUsageFlags UsageFlags, - UINT Lod, - BOOL Srgb); - - D3D9ColorView CreateColorViewPair( - D3D9_VK_FORMAT_MAPPING FormatInfo, - UINT Layer, - VkImageUsageFlags UsageFlags, - UINT Lod); - - void CreateInitialViews(); }; } \ No newline at end of file diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index d7f72ea41..3f9c47a0f 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -4068,7 +4068,7 @@ namespace dxvk { void D3D9DeviceEx::GenerateMips( D3D9CommonTexture* pResource) { EmitCs([ - cImageView = pResource->GetViews().Sample.Color + cImageView = pResource->GetSampleView().Color ] (DxvkContext* ctx) { ctx->generateMipmaps(cImageView); }); @@ -4844,7 +4844,7 @@ namespace dxvk { if (likely(sampleCount == VK_SAMPLE_COUNT_FLAG_BITS_MAX_ENUM || sampleCount == dsImageInfo.sampleCount)) { attachments.depth = { m_state.depthStencil->GetDepthStencilView(), - m_state.depthStencil->GetDepthLayout() }; + m_state.depthStencil->GetDepthStencilLayout() }; } } @@ -5292,7 +5292,7 @@ namespace dxvk { cColorSlot = colorSlot, cDepthSlot = depthSlot, cDepth = commonTex->IsShadow(), - cImageView = commonTex->GetViews().Sample.Pick(srgb) + cImageView = commonTex->GetSampleView().Pick(srgb) ](DxvkContext* ctx) { ctx->bindResourceView(cColorSlot, !cDepth ? cImageView : nullptr, nullptr); ctx->bindResourceView(cDepthSlot, cDepth ? cImageView : nullptr, nullptr); diff --git a/src/d3d9/d3d9_subresource.h b/src/d3d9/d3d9_subresource.h index c7a1611e1..ed18baf93 100644 --- a/src/d3d9/d3d9_subresource.h +++ b/src/d3d9/d3d9_subresource.h @@ -66,23 +66,38 @@ namespace dxvk { } Rc GetImageView(bool Srgb) { - return m_texture->GetViews().SubresourceSample[m_face][m_mipLevel].Pick(Srgb); + Rc& view = m_sampleView.Pick(Srgb); + + if (unlikely(view == nullptr)) + view = m_texture->CreateView(m_face, m_mipLevel, VK_IMAGE_USAGE_SAMPLED_BIT, Srgb); + + return view; } Rc GetRenderTargetView(bool Srgb) { - return m_texture->GetViews().SubresourceRenderTarget[m_face][m_mipLevel].Pick(Srgb); + Rc& view = m_renderTargetView.Pick(Srgb); + + if (unlikely(view == nullptr)) + view = m_texture->CreateView(m_face, m_mipLevel, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, Srgb); + + return view; } - VkImageLayout GetRenderTargetLayout() { - return m_texture->GetViews().GetRTLayout(); + VkImageLayout GetRenderTargetLayout() const { + return m_texture->DetermineRenderTargetLayout(); } Rc GetDepthStencilView() { - return m_texture->GetViews().SubresourceDepth[m_face][m_mipLevel]; + Rc& view = m_depthStencilView; + + if (unlikely(view == nullptr)) + view = m_texture->CreateView(m_face, m_mipLevel, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, false); + + return view; } - VkImageLayout GetDepthLayout() { - return m_texture->GetViews().GetDepthLayout(); + VkImageLayout GetDepthStencilLayout() const { + return m_texture->DetermineDepthStencilLayout(); } bool IsNull() { @@ -101,6 +116,10 @@ namespace dxvk { UINT m_face; UINT m_mipLevel; + D3D9ColorView m_sampleView; + D3D9ColorView m_renderTargetView; + Rc m_depthStencilView; + }; } \ No newline at end of file diff --git a/src/d3d9/d3d9_texture.h b/src/d3d9/d3d9_texture.h index 8c6c8c116..187b19acd 100644 --- a/src/d3d9/d3d9_texture.h +++ b/src/d3d9/d3d9_texture.h @@ -59,7 +59,7 @@ namespace dxvk { DWORD oldLod = m_lod; m_lod = LODNew; - m_texture.RecreateSampledView(LODNew); + m_texture.CreateSampleView(LODNew); if (this->GetPrivateRefCount() > 0) this->m_parent->MarkSamplersDirty();