diff --git a/Source/Engine/Graphics/Textures/GPUTexture.cpp b/Source/Engine/Graphics/Textures/GPUTexture.cpp index a49b97070..bc5424223 100644 --- a/Source/Engine/Graphics/Textures/GPUTexture.cpp +++ b/Source/Engine/Graphics/Textures/GPUTexture.cpp @@ -813,5 +813,5 @@ void GPUTexture::SetResidentMipLevels(int32 count) if (_residentMipLevels == count || !IsRegularTexture()) return; _residentMipLevels = count; - onResidentMipsChanged(); + OnResidentMipsChanged(); } diff --git a/Source/Engine/Graphics/Textures/GPUTexture.h b/Source/Engine/Graphics/Textures/GPUTexture.h index 28007196d..a51d4418b 100644 --- a/Source/Engine/Graphics/Textures/GPUTexture.h +++ b/Source/Engine/Graphics/Textures/GPUTexture.h @@ -567,12 +567,12 @@ public: /// Sets the number of resident mipmap levels in the texture (already uploaded to the GPU). /// API_PROPERTY() void SetResidentMipLevels(int32 count); - + protected: virtual bool OnInit() = 0; uint64 calculateMemoryUsage() const; - virtual void onResidentMipsChanged() = 0; + virtual void OnResidentMipsChanged() = 0; public: diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUTextureDX11.cpp b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUTextureDX11.cpp index f5e071f68..8927f9435 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUTextureDX11.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUTextureDX11.cpp @@ -109,37 +109,37 @@ bool GPUTextureDX11::OnInit() return false; } -void GPUTextureDX11::onResidentMipsChanged() +void GPUTextureDX11::OnResidentMipsChanged() { - // We support changing resident mip maps only for regular textures (render targets and depth buffers don't use that feature at all) - ASSERT(IsRegularTexture() && _handlesPerSlice.Count() == 1); - ASSERT(!IsVolume()); - - // Fill description + const int32 firstMipIndex = MipLevels() - ResidentMipLevels(); + const int32 mipLevels = ResidentMipLevels(); D3D11_SHADER_RESOURCE_VIEW_DESC srDesc; srDesc.Format = _dxgiFormatSRV; if (IsCubeMap()) { srDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; - srDesc.TextureCube.MostDetailedMip = MipLevels() - ResidentMipLevels(); - srDesc.TextureCube.MipLevels = ResidentMipLevels(); + srDesc.TextureCube.MostDetailedMip = firstMipIndex; + srDesc.TextureCube.MipLevels = mipLevels; + } + else if (IsVolume()) + { + srDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + srDesc.Texture3D.MostDetailedMip = firstMipIndex; + srDesc.Texture3D.MipLevels = mipLevels; } else { srDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srDesc.Texture2D.MostDetailedMip = MipLevels() - ResidentMipLevels(); - srDesc.Texture2D.MipLevels = ResidentMipLevels(); + srDesc.Texture2D.MostDetailedMip = firstMipIndex; + srDesc.Texture2D.MipLevels = mipLevels; } - - // Create new view ID3D11ShaderResourceView* srView; VALIDATE_DIRECTX_RESULT(_device->GetDevice()->CreateShaderResourceView(_resource, &srDesc, &srView)); - - // Change view - if (_handlesPerSlice[0].GetParent() == nullptr) - _handlesPerSlice[0].Init(this, nullptr, srView, nullptr, nullptr, Format(), MultiSampleLevel()); + GPUTextureViewDX11& view = IsVolume() ? _handleVolume : _handlesPerSlice[0]; + if (view.GetParent() == nullptr) + view.Init(this, nullptr, srView, nullptr, nullptr, Format(), MultiSampleLevel()); else - _handlesPerSlice[0].SetSRV(srView); + view.SetSRV(srView); } void GPUTextureDX11::OnReleaseGPU() diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUTextureDX11.h b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUTextureDX11.h index 51bdff1d4..b40bee48d 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUTextureDX11.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUTextureDX11.h @@ -277,7 +277,7 @@ protected: // [GPUTexture] bool OnInit() override; - void onResidentMipsChanged() override; + void OnResidentMipsChanged() override; void OnReleaseGPU() override; }; diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUTextureDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUTextureDX12.cpp index 1bba5880d..5945257e8 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUTextureDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUTextureDX12.cpp @@ -208,36 +208,39 @@ bool GPUTextureDX12::OnInit() return false; } -void GPUTextureDX12::onResidentMipsChanged() +void GPUTextureDX12::OnResidentMipsChanged() { - // We support changing resident mip maps only for regular textures (render targets and depth buffers don't use that feature at all) - ASSERT(IsRegularTexture() && _handlesPerSlice.Count() == 1); - ASSERT(!IsVolume()); - - // Fill description + const int32 firstMipIndex = MipLevels() - ResidentMipLevels(); + const int32 mipLevels = ResidentMipLevels(); D3D12_SHADER_RESOURCE_VIEW_DESC srDesc; srDesc.Format = _dxgiFormatSRV; srDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; if (IsCubeMap()) { srDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE; - srDesc.TextureCube.MostDetailedMip = MipLevels() - ResidentMipLevels(); - srDesc.TextureCube.MipLevels = ResidentMipLevels(); + srDesc.TextureCube.MostDetailedMip = firstMipIndex; + srDesc.TextureCube.MipLevels = mipLevels; srDesc.TextureCube.ResourceMinLODClamp = 0; } + else if (IsVolume()) + { + srDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D; + srDesc.Texture3D.MostDetailedMip = firstMipIndex; + srDesc.Texture3D.MipLevels = mipLevels; + srDesc.Texture3D.ResourceMinLODClamp = 0; + } else { srDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; - srDesc.Texture2D.MostDetailedMip = MipLevels() - ResidentMipLevels(); - srDesc.Texture2D.MipLevels = ResidentMipLevels(); + srDesc.Texture2D.MostDetailedMip = firstMipIndex; + srDesc.Texture2D.MipLevels = mipLevels; srDesc.Texture2D.PlaneSlice = 0; srDesc.Texture2D.ResourceMinLODClamp = 0; } - - // Change view - if (_handlesPerSlice[0].GetParent() == nullptr) - _handlesPerSlice[0].Init(this, _device, this, Format(), MultiSampleLevel()); - _handlesPerSlice[0].SetSRV(srDesc); + GPUTextureViewDX12& view = IsVolume() ? _handleVolume : _handlesPerSlice[0]; + if (view.GetParent() == nullptr) + view.Init(this, _device, this, Format(), MultiSampleLevel()); + view.SetSRV(srDesc); } void GPUTextureDX12::OnReleaseGPU() diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUTextureDX12.h b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUTextureDX12.h index c91471846..db274c91a 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUTextureDX12.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUTextureDX12.h @@ -216,7 +216,7 @@ protected: // [GPUTexture] bool OnInit() override; - void onResidentMipsChanged() override; + void OnResidentMipsChanged() override; void OnReleaseGPU() override; }; diff --git a/Source/Engine/GraphicsDevice/Null/GPUTextureNull.h b/Source/Engine/GraphicsDevice/Null/GPUTextureNull.h index abfd5aaaf..81b3c22d7 100644 --- a/Source/Engine/GraphicsDevice/Null/GPUTextureNull.h +++ b/Source/Engine/GraphicsDevice/Null/GPUTextureNull.h @@ -57,7 +57,7 @@ protected: return false; } - void onResidentMipsChanged() override + void OnResidentMipsChanged() override { } }; diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUTextureVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUTextureVulkan.cpp index be8f26255..eb4466ab8 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUTextureVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUTextureVulkan.cpp @@ -425,29 +425,19 @@ void GPUTextureVulkan::initHandles() } } -void GPUTextureVulkan::onResidentMipsChanged() +void GPUTextureVulkan::OnResidentMipsChanged() { - // We support changing resident mip maps only for regular textures (render targets and depth buffers don't use that feature at all) - ASSERT(IsRegularTexture() && _handlesPerSlice.Count() == 1); - ASSERT(!IsVolume()); - - // Change view - auto& handle = _handlesPerSlice[0]; - handle.Release(); + // Update view VkExtent3D extent; extent.width = Width(); extent.height = Height(); extent.depth = Depth(); const int32 firstMipIndex = MipLevels() - ResidentMipLevels(); const int32 mipLevels = ResidentMipLevels(); - if (IsCubeMap()) - { - handle.Init(_device, this, _image, mipLevels, Format(), MultiSampleLevel(), extent, VK_IMAGE_VIEW_TYPE_CUBE, mipLevels, firstMipIndex, ArraySize()); - } - else - { - handle.Init(_device, this, _image, mipLevels, Format(), MultiSampleLevel(), extent, VK_IMAGE_VIEW_TYPE_2D, mipLevels, firstMipIndex, ArraySize()); - } + const VkImageViewType viewType = IsVolume() ? VK_IMAGE_VIEW_TYPE_3D : (IsCubeMap() ? VK_IMAGE_VIEW_TYPE_CUBE : VK_IMAGE_VIEW_TYPE_2D); + GPUTextureViewVulkan& view = IsVolume() ? _handleVolume : _handlesPerSlice[0]; + view.Release(); + view.Init(_device, this, _image, mipLevels, Format(), MultiSampleLevel(), extent, viewType, mipLevels, firstMipIndex, ArraySize()); } void GPUTextureVulkan::OnReleaseGPU() diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUTextureVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/GPUTextureVulkan.h index aec0ed428..fcbbd2c01 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUTextureVulkan.h +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUTextureVulkan.h @@ -182,7 +182,7 @@ protected: // [GPUTexture] bool OnInit() override; - void onResidentMipsChanged() override; + void OnResidentMipsChanged() override; void OnReleaseGPU() override; }; diff --git a/Source/Engine/Renderer/GlobalSignDistanceFieldPass.cpp b/Source/Engine/Renderer/GlobalSignDistanceFieldPass.cpp index 0557421e5..c4df8e611 100644 --- a/Source/Engine/Renderer/GlobalSignDistanceFieldPass.cpp +++ b/Source/Engine/Renderer/GlobalSignDistanceFieldPass.cpp @@ -688,7 +688,7 @@ void GlobalSignDistanceFieldPass::RenderDebug(RenderContext& renderContext, GPUC void GlobalSignDistanceFieldPass::RasterizeModelSDF(Actor* actor, const ModelBase::SDFData& sdf, const Matrix& localToWorld, const BoundingBox& objectBounds) { - if (!sdf.Texture) + if (!sdf.Texture || sdf.Texture->ResidentMipLevels() == 0) return; // Setup object data diff --git a/Source/Engine/Tools/ModelTool/ModelTool.cpp b/Source/Engine/Tools/ModelTool/ModelTool.cpp index 36aaf0b15..8a4cd9a91 100644 --- a/Source/Engine/Tools/ModelTool/ModelTool.cpp +++ b/Source/Engine/Tools/ModelTool/ModelTool.cpp @@ -123,7 +123,7 @@ bool ModelTool::GenerateModelSDF(Model* inputModel, ModelData* modelData, float *(uint8*)ptr = (uint8)v; }; } - GPUTextureDescription textureDesc = GPUTextureDescription::New3D(resolution.X, resolution.Y, resolution.Z, format, GPUTextureFlags::ShaderResource | GPUTextureFlags::UnorderedAccess, mipCount); + GPUTextureDescription textureDesc = GPUTextureDescription::New3D(resolution.X, resolution.Y, resolution.Z, format, GPUTextureFlags::ShaderResource, mipCount); if (outputSDF) { *outputSDF = sdf;