Files
UnrealEngine/Engine/Source/Runtime/VulkanRHI/Private/VulkanSRV.cpp
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

119 lines
4.1 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "VulkanRHIPrivate.h"
#include "VulkanContext.h"
static VkImageViewType GetVkImageViewTypeForDimensionSRV(FRHIViewDesc::EDimension DescDimension, VkImageViewType TextureViewType)
{
switch (DescDimension)
{
case FRHIViewDesc::EDimension::Texture2D: return VK_IMAGE_VIEW_TYPE_2D;
case FRHIViewDesc::EDimension::Texture2DArray: return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
case FRHIViewDesc::EDimension::Texture3D: return VK_IMAGE_VIEW_TYPE_3D;
case FRHIViewDesc::EDimension::TextureCube: return VK_IMAGE_VIEW_TYPE_CUBE;
case FRHIViewDesc::EDimension::TextureCubeArray: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
case FRHIViewDesc::EDimension::Unknown: return TextureViewType;
default: break;
}
checkf(false, TEXT("Unknown texture dimension value!"));
return VK_IMAGE_VIEW_TYPE_MAX_ENUM;
}
FVulkanShaderResourceView::FVulkanShaderResourceView(FRHICommandListBase& RHICmdList, FVulkanDevice& InDevice, FRHIViewableResource* InResource, FRHIViewDesc const& InViewDesc)
: FRHIShaderResourceView(InResource, InViewDesc)
, FVulkanLinkedView(InDevice, GetVkDescriptorTypeForViewDesc(InViewDesc))
{
RHICmdList.EnqueueLambda([this](FRHICommandListBase&)
{
LinkHead(GetBaseResource()->LinkedViews);
UpdateView({});
});
RHICmdList.RHIThreadFence(true);
}
FVulkanViewableResource* FVulkanShaderResourceView::GetBaseResource() const
{
if (IsBuffer())
{
return ResourceCast(GetBuffer());
}
return ResourceCast(GetTexture());
}
void FVulkanShaderResourceView::UpdateView(const FVulkanContextArray& Contexts)
{
#if VULKAN_ENABLE_AGGRESSIVE_STATS
SCOPE_CYCLE_COUNTER(STAT_VulkanSRVUpdateTime);
#endif
Invalidate();
if (IsBuffer())
{
FVulkanBuffer* Buffer = ResourceCast(GetBuffer());
auto const Info = ViewDesc.Buffer.SRV.GetViewInfo(Buffer);
if (!Info.bNullView)
{
switch (Info.BufferType)
{
case FRHIViewDesc::EBufferType::Raw:
case FRHIViewDesc::EBufferType::Structured:
InitAsStructuredBufferView(Contexts, Buffer, Info.OffsetInBytes, Info.SizeInBytes);
break;
case FRHIViewDesc::EBufferType::Typed:
check(VKHasAllFlags(Buffer->GetBufferUsageFlags(), VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT));
InitAsTypedBufferView(Contexts, Buffer, Info.Format, Info.OffsetInBytes, Info.SizeInBytes);
break;
case FRHIViewDesc::EBufferType::AccelerationStructure:
InitAsAccelerationStructureView(Contexts, Buffer, Info.OffsetInBytes, Info.SizeInBytes);
break;
default:
checkNoEntry();
break;
}
}
}
else
{
FVulkanTexture* Texture = ResourceCast(GetTexture());
auto const Info = ViewDesc.Texture.SRV.GetViewInfo(Texture);
uint32 ArrayFirst = Info.ArrayRange.First;
uint32 ArrayNum = Info.ArrayRange.Num;
if (Info.Dimension == FRHIViewDesc::EDimension::TextureCube || Info.Dimension == FRHIViewDesc::EDimension::TextureCubeArray)
{
ArrayFirst *= 6;
ArrayNum *= 6;
checkf((ArrayFirst + ArrayNum) <= Texture->GetNumberOfArrayLevels(), TEXT("View extends beyond original cube texture level count!"));
}
// Remove storage bit from usage flags for SRVs
const VkImageUsageFlags ImageUsageFlags = Texture->ImageUsageFlags & ~VK_IMAGE_USAGE_STORAGE_BIT;
FVulkanTextureViewDesc VulkanViewDesc;
VulkanViewDesc.ViewType = GetVkImageViewTypeForDimensionSRV(Info.Dimension, Texture->GetViewType());
VulkanViewDesc.AspectFlags = Texture->GetPartialAspectMask();
VulkanViewDesc.UEFormat = Info.Format;
VulkanViewDesc.Format = UEToVkTextureFormat(Info.Format, Info.bSRGB);
VulkanViewDesc.FirstMip = Info.MipRange.First;
VulkanViewDesc.NumMips = Info.MipRange.Num;
VulkanViewDesc.ArraySliceIndex = ArrayFirst;
VulkanViewDesc.NumArraySlices = ArrayNum;
VulkanViewDesc.bUseIdentitySwizzle = false;
VulkanViewDesc.ImageUsageFlags = ImageUsageFlags;
InitAsTextureView(Contexts, Texture->Image, VulkanViewDesc);
}
}
FShaderResourceViewRHIRef FVulkanDynamicRHI::RHICreateShaderResourceView(class FRHICommandListBase& RHICmdList, FRHIViewableResource* Resource, FRHIViewDesc const& ViewDesc)
{
return new FVulkanShaderResourceView(RHICmdList, *Device, Resource, ViewDesc);
}