Merge remote-tracking branch 'origin/gi' into large-worlds
# Conflicts: # Source/Engine/Core/Math/Vector3.h
This commit is contained in:
@@ -732,7 +732,9 @@ void GPUContextDX11::UpdateTexture(GPUTexture* texture, int32 arrayIndex, int32
|
||||
auto textureDX11 = static_cast<GPUTextureDX11*>(texture);
|
||||
|
||||
const int32 subresourceIndex = RenderToolsDX::CalcSubresourceIndex(mipIndex, arrayIndex, texture->MipLevels());
|
||||
const uint32 depthPitch = texture->IsVolume() ? slicePitch / texture->Depth() : slicePitch;
|
||||
uint32 depthPitch = slicePitch;
|
||||
if (texture->IsVolume())
|
||||
depthPitch /= Math::Max(1, texture->Depth() >> mipIndex);
|
||||
_context->UpdateSubresource(textureDX11->GetResource(), subresourceIndex, nullptr, data, (UINT)rowPitch, (UINT)depthPitch);
|
||||
|
||||
//D3D11_MAPPED_SUBRESOURCE mapped;
|
||||
|
||||
@@ -518,12 +518,12 @@ bool GPUDeviceDX11::Init()
|
||||
dsDesc.FrontFace = defaultStencilOp;
|
||||
dsDesc.BackFace = defaultStencilOp;
|
||||
int32 index;
|
||||
#define CREATE_DEPTH_STENCIL_STATE(depthTextEnable, depthWrite) \
|
||||
dsDesc.DepthEnable = depthTextEnable; \
|
||||
#define CREATE_DEPTH_STENCIL_STATE(depthEnable, depthWrite) \
|
||||
dsDesc.DepthEnable = depthEnable; \
|
||||
dsDesc.DepthWriteMask = depthWrite ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; \
|
||||
for(int32 depthFunc = 1; depthFunc <= 8; depthFunc++) { \
|
||||
dsDesc.DepthFunc = (D3D11_COMPARISON_FUNC)depthFunc; \
|
||||
index = (int32)depthFunc + (depthTextEnable ? 0 : 9) + (depthWrite ? 0 : 18); \
|
||||
index = (int32)depthFunc + (depthEnable ? 0 : 9) + (depthWrite ? 0 : 18); \
|
||||
HRESULT result = _device->CreateDepthStencilState(&dsDesc, &DepthStencilStates[index]); \
|
||||
LOG_DIRECTX_RESULT_WITH_RETURN(result); }
|
||||
CREATE_DEPTH_STENCIL_STATE(false, false);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -277,7 +277,7 @@ protected:
|
||||
|
||||
// [GPUTexture]
|
||||
bool OnInit() override;
|
||||
void onResidentMipsChanged() override;
|
||||
void OnResidentMipsChanged() override;
|
||||
void OnReleaseGPU() override;
|
||||
};
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -216,7 +216,7 @@ protected:
|
||||
|
||||
// [GPUTexture]
|
||||
bool OnInit() override;
|
||||
void onResidentMipsChanged() override;
|
||||
void OnResidentMipsChanged() override;
|
||||
void OnReleaseGPU() override;
|
||||
};
|
||||
|
||||
|
||||
@@ -90,29 +90,30 @@ bool UploadBufferDX12::UploadTexture(GPUContextDX12* context, ID3D12Resource* te
|
||||
_device->GetDevice()->GetCopyableFootprints(&resourceDesc, subresourceIndex, 1, 0, &footprint, &numRows, &rowPitchAligned, &mipSizeAligned);
|
||||
rowPitchAligned = footprint.Footprint.RowPitch;
|
||||
mipSizeAligned = rowPitchAligned * footprint.Footprint.Height;
|
||||
const uint32 numSlices = resourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? Math::Max(1, resourceDesc.DepthOrArraySize >> mipIndex) : 1;
|
||||
const uint64 sliceSizeAligned = numSlices * mipSizeAligned;
|
||||
|
||||
// Allocate data
|
||||
const DynamicAllocation allocation = Allocate(mipSizeAligned, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
|
||||
if (allocation.Size != mipSizeAligned)
|
||||
const DynamicAllocation allocation = Allocate(sliceSizeAligned, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
|
||||
if (allocation.Size != sliceSizeAligned)
|
||||
return true;
|
||||
|
||||
// Check if can copy rows at once
|
||||
byte* ptr = (byte*)srcData;
|
||||
ASSERT(srcSlicePitch <= mipSizeAligned);
|
||||
if (srcRowPitch == rowPitchAligned)
|
||||
ASSERT(srcSlicePitch <= sliceSizeAligned);
|
||||
if (srcSlicePitch == sliceSizeAligned)
|
||||
{
|
||||
// Copy data at once
|
||||
Platform::MemoryCopy(allocation.CPUAddress, ptr, srcSlicePitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use per row copy
|
||||
// Copy data per-row
|
||||
byte* dst = static_cast<byte*>(allocation.CPUAddress);
|
||||
ASSERT(srcRowPitch <= rowPitchAligned);
|
||||
for (uint32 i = 0; i < numRows; i++)
|
||||
const uint32 numCopies = numSlices * numRows;
|
||||
for (uint32 i = 0; i < numCopies; i++)
|
||||
{
|
||||
Platform::MemoryCopy(dst, ptr, srcRowPitch);
|
||||
|
||||
dst += rowPitchAligned;
|
||||
ptr += srcRowPitch;
|
||||
}
|
||||
|
||||
@@ -141,9 +141,8 @@ struct DynamicAllocation
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if allocation is invalid
|
||||
/// Returns true if allocation is invalid.
|
||||
/// </summary>
|
||||
/// <returns>True if allocation in invalid</returns>
|
||||
bool IsInvalid() const
|
||||
{
|
||||
return CPUAddress == nullptr || Size == 0 || Page == nullptr;
|
||||
|
||||
@@ -212,16 +212,17 @@ namespace RenderToolsDX
|
||||
if (errorCode == DXGI_ERROR_DEVICE_REMOVED || errorCode == DXGI_ERROR_DEVICE_RESET || errorCode == DXGI_ERROR_DRIVER_INTERNAL_ERROR)
|
||||
{
|
||||
HRESULT reason = S_OK;
|
||||
const RendererType rendererType = GPUDevice::Instance ? GPUDevice::Instance->GetRendererType() : RendererType::Unknown;
|
||||
#if GRAPHICS_API_DIRECTX12
|
||||
if (GPUDevice::Instance->GetRendererType() == RendererType::DirectX12)
|
||||
if (rendererType == RendererType::DirectX12)
|
||||
{
|
||||
reason = ((ID3D12Device*)GPUDevice::Instance->GetNativePtr())->GetDeviceRemovedReason();
|
||||
}
|
||||
#endif
|
||||
#if GRAPHICS_API_DIRECTX11
|
||||
if (GPUDevice::Instance->GetRendererType() == RendererType::DirectX11 ||
|
||||
GPUDevice::Instance->GetRendererType() == RendererType::DirectX10_1 ||
|
||||
GPUDevice::Instance->GetRendererType() == RendererType::DirectX10)
|
||||
if (rendererType == RendererType::DirectX11 ||
|
||||
rendererType == RendererType::DirectX10_1 ||
|
||||
rendererType == RendererType::DirectX10)
|
||||
{
|
||||
reason = ((ID3D11Device*)GPUDevice::Instance->GetNativePtr())->GetDeviceRemovedReason();
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ protected:
|
||||
return false;
|
||||
}
|
||||
|
||||
void onResidentMipsChanged() override
|
||||
void OnResidentMipsChanged() override
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "GPUDeviceVulkan.h"
|
||||
#include "RenderToolsVulkan.h"
|
||||
#include "GPUContextVulkan.h"
|
||||
#include "GPUAdapterVulkan.h"
|
||||
#include "CmdBufferVulkan.h"
|
||||
#include "Engine/Threading/Threading.h"
|
||||
#include "Engine/Engine/Engine.h"
|
||||
@@ -30,39 +29,48 @@ void DescriptorSetLayoutInfoVulkan::CacheTypesUsageID()
|
||||
_typesUsageID = id;
|
||||
}
|
||||
|
||||
void DescriptorSetLayoutInfoVulkan::AddDescriptor(int32 descriptorSetIndex, const VkDescriptorSetLayoutBinding& descriptor)
|
||||
{
|
||||
_layoutTypes[descriptor.descriptorType]++;
|
||||
|
||||
if (descriptorSetIndex >= _setLayouts.Count())
|
||||
{
|
||||
_setLayouts.Resize(descriptorSetIndex + 1);
|
||||
}
|
||||
|
||||
SetLayout& descSetLayout = _setLayouts[descriptorSetIndex];
|
||||
descSetLayout.LayoutBindings.Add(descriptor);
|
||||
|
||||
_hash = Crc::MemCrc32(&descriptor, sizeof(descriptor), _hash);
|
||||
}
|
||||
|
||||
void DescriptorSetLayoutInfoVulkan::AddBindingsForStage(VkShaderStageFlagBits stageFlags, DescriptorSet::Stage descSet, const SpirvShaderDescriptorInfo* descriptorInfo)
|
||||
{
|
||||
const int32 descriptorSetIndex = (int32)descSet;
|
||||
const int32 descriptorSetIndex = descSet;
|
||||
if (descriptorSetIndex >= _setLayouts.Count())
|
||||
_setLayouts.Resize(descriptorSetIndex + 1);
|
||||
SetLayout& descSetLayout = _setLayouts[descriptorSetIndex];
|
||||
|
||||
VkDescriptorSetLayoutBinding binding;
|
||||
binding.descriptorCount = 1;
|
||||
binding.stageFlags = stageFlags;
|
||||
binding.pImmutableSamplers = nullptr;
|
||||
|
||||
for (uint32 descriptorIndex = 0; descriptorIndex < descriptorInfo->DescriptorTypesCount; descriptorIndex++)
|
||||
{
|
||||
auto& descriptor = descriptorInfo->DescriptorTypes[descriptorIndex];
|
||||
binding.binding = descriptorIndex;
|
||||
binding.descriptorType = descriptor.DescriptorType;
|
||||
AddDescriptor(descriptorSetIndex, binding);
|
||||
binding.descriptorCount = descriptor.Count;
|
||||
|
||||
_layoutTypes[binding.descriptorType]++;
|
||||
descSetLayout.LayoutBindings.Add(binding);
|
||||
_hash = Crc::MemCrc32(&binding, sizeof(binding), _hash);
|
||||
}
|
||||
}
|
||||
|
||||
bool DescriptorSetLayoutInfoVulkan::operator==(const DescriptorSetLayoutInfoVulkan& other) const
|
||||
{
|
||||
if (other._setLayouts.Count() != _setLayouts.Count())
|
||||
return false;
|
||||
if (other._typesUsageID != _typesUsageID)
|
||||
return false;
|
||||
|
||||
for (int32 index = 0; index < other._setLayouts.Count(); index++)
|
||||
{
|
||||
const int32 bindingsCount = _setLayouts[index].LayoutBindings.Count();
|
||||
if (other._setLayouts[index].LayoutBindings.Count() != bindingsCount)
|
||||
return false;
|
||||
if (bindingsCount != 0 && Platform::MemoryCompare(other._setLayouts[index].LayoutBindings.Get(), _setLayouts[index].LayoutBindings.Get(), bindingsCount * sizeof(VkDescriptorSetLayoutBinding)))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DescriptorSetLayoutVulkan::DescriptorSetLayoutVulkan(GPUDeviceVulkan* device)
|
||||
: _device(device)
|
||||
{
|
||||
@@ -370,20 +378,20 @@ PipelineLayoutVulkan::~PipelineLayoutVulkan()
|
||||
}
|
||||
}
|
||||
|
||||
uint32 DescriptorSetWriterVulkan::SetupDescriptorWrites(const SpirvShaderDescriptorInfo& info, VkWriteDescriptorSet* writeDescriptors, VkDescriptorImageInfo* imageInfo, VkDescriptorBufferInfo* bufferInfo, uint8* bindingToDynamicOffset)
|
||||
uint32 DescriptorSetWriterVulkan::SetupDescriptorWrites(const SpirvShaderDescriptorInfo& info, VkWriteDescriptorSet* writeDescriptors, VkDescriptorImageInfo* imageInfo, VkDescriptorBufferInfo* bufferInfo, VkBufferView* texelBufferView, uint8* bindingToDynamicOffset)
|
||||
{
|
||||
ASSERT(info.DescriptorTypesCount <= 64);
|
||||
ASSERT(info.DescriptorTypesCount <= SpirvShaderDescriptorInfo::MaxDescriptors);
|
||||
WriteDescriptors = writeDescriptors;
|
||||
WritesCount = info.DescriptorTypesCount;
|
||||
BindingToDynamicOffset = bindingToDynamicOffset;
|
||||
|
||||
uint32 dynamicOffsetIndex = 0;
|
||||
for (uint32 i = 0; i < info.DescriptorTypesCount; i++)
|
||||
{
|
||||
const auto& descriptor = info.DescriptorTypes[i];
|
||||
writeDescriptors->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
writeDescriptors->dstBinding = i;
|
||||
writeDescriptors->descriptorCount = 1;
|
||||
writeDescriptors->descriptorType = info.DescriptorTypes[i].DescriptorType;
|
||||
writeDescriptors->descriptorCount = descriptor.Count;
|
||||
writeDescriptors->descriptorType = descriptor.DescriptorType;
|
||||
|
||||
switch (writeDescriptors->descriptorType)
|
||||
{
|
||||
@@ -394,25 +402,28 @@ uint32 DescriptorSetWriterVulkan::SetupDescriptorWrites(const SpirvShaderDescrip
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
||||
writeDescriptors->pBufferInfo = bufferInfo++;
|
||||
writeDescriptors->pBufferInfo = bufferInfo;
|
||||
bufferInfo += descriptor.Count;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
||||
writeDescriptors->pImageInfo = imageInfo++;
|
||||
writeDescriptors->pImageInfo = imageInfo;
|
||||
imageInfo += descriptor.Count;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
||||
writeDescriptors->pTexelBufferView = texelBufferView;
|
||||
texelBufferView += descriptor.Count;
|
||||
break;
|
||||
default:
|
||||
CRASH;
|
||||
CRASH;
|
||||
break;
|
||||
}
|
||||
|
||||
writeDescriptors++;
|
||||
}
|
||||
|
||||
return dynamicOffsetIndex;
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,6 @@ protected:
|
||||
uint32 _typesUsageID = ~0;
|
||||
|
||||
void CacheTypesUsageID();
|
||||
void AddDescriptor(int32 descriptorSetIndex, const VkDescriptorSetLayoutBinding& descriptor);
|
||||
|
||||
public:
|
||||
|
||||
@@ -138,11 +137,6 @@ public:
|
||||
return _setLayouts;
|
||||
}
|
||||
|
||||
inline const uint32* GetLayoutTypes() const
|
||||
{
|
||||
return _layoutTypes;
|
||||
}
|
||||
|
||||
inline uint32 GetTypesUsageID() const
|
||||
{
|
||||
return _typesUsageID;
|
||||
@@ -160,25 +154,7 @@ public:
|
||||
_setLayouts = info._setLayouts;
|
||||
}
|
||||
|
||||
inline bool operator ==(const DescriptorSetLayoutInfoVulkan& other) const
|
||||
{
|
||||
if (other._setLayouts.Count() != _setLayouts.Count())
|
||||
return false;
|
||||
if (other._typesUsageID != _typesUsageID)
|
||||
return false;
|
||||
|
||||
for (int32 index = 0; index < other._setLayouts.Count(); index++)
|
||||
{
|
||||
const int32 bindingsCount = _setLayouts[index].LayoutBindings.Count();
|
||||
if (other._setLayouts[index].LayoutBindings.Count() != bindingsCount)
|
||||
return false;
|
||||
|
||||
if (bindingsCount != 0 && Platform::MemoryCompare(other._setLayouts[index].LayoutBindings.Get(), _setLayouts[index].LayoutBindings.Get(), bindingsCount * sizeof(VkDescriptorSetLayoutBinding)))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool operator==(const DescriptorSetLayoutInfoVulkan& other) const;
|
||||
|
||||
friend inline uint32 GetHash(const DescriptorSetLayoutInfoVulkan& key)
|
||||
{
|
||||
@@ -413,6 +389,7 @@ struct DescriptorSetWriteContainerVulkan
|
||||
{
|
||||
Array<VkDescriptorImageInfo> DescriptorImageInfo;
|
||||
Array<VkDescriptorBufferInfo> DescriptorBufferInfo;
|
||||
Array<VkBufferView> DescriptorTexelBufferView;
|
||||
Array<VkWriteDescriptorSet> DescriptorWrites;
|
||||
Array<byte> BindingToDynamicOffset;
|
||||
|
||||
@@ -420,6 +397,7 @@ struct DescriptorSetWriteContainerVulkan
|
||||
{
|
||||
DescriptorImageInfo.Resize(0);
|
||||
DescriptorBufferInfo.Resize(0);
|
||||
DescriptorTexelBufferView.Resize(0);
|
||||
DescriptorWrites.Resize(0);
|
||||
BindingToDynamicOffset.Resize(0);
|
||||
}
|
||||
@@ -436,26 +414,24 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
uint32 SetupDescriptorWrites(const SpirvShaderDescriptorInfo& info, VkWriteDescriptorSet* writeDescriptors, VkDescriptorImageInfo* imageInfo, VkDescriptorBufferInfo* bufferInfo, byte* bindingToDynamicOffset);
|
||||
uint32 SetupDescriptorWrites(const SpirvShaderDescriptorInfo& info, VkWriteDescriptorSet* writeDescriptors, VkDescriptorImageInfo* imageInfo, VkDescriptorBufferInfo* bufferInfo, VkBufferView* texelBufferView, byte* bindingToDynamicOffset);
|
||||
|
||||
bool WriteUniformBuffer(uint32 descriptorIndex, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range) const
|
||||
bool WriteUniformBuffer(uint32 descriptorIndex, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range, uint32 index = 0) const
|
||||
{
|
||||
ASSERT(descriptorIndex < WritesCount);
|
||||
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
VkDescriptorBufferInfo* bufferInfo = const_cast<VkDescriptorBufferInfo*>(WriteDescriptors[descriptorIndex].pBufferInfo);
|
||||
ASSERT(bufferInfo);
|
||||
auto* bufferInfo = const_cast<VkDescriptorBufferInfo*>(WriteDescriptors[descriptorIndex].pBufferInfo + index);
|
||||
bool edited = DescriptorSet::CopyAndReturnNotEqual(bufferInfo->buffer, buffer);
|
||||
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->offset, offset);
|
||||
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->range, range);
|
||||
return edited;
|
||||
}
|
||||
|
||||
bool WriteDynamicUniformBuffer(uint32 descriptorIndex, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range, uint32 dynamicOffset) const
|
||||
bool WriteDynamicUniformBuffer(uint32 descriptorIndex, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range, uint32 dynamicOffset, uint32 index = 0) const
|
||||
{
|
||||
ASSERT(descriptorIndex < WritesCount);
|
||||
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC);
|
||||
VkDescriptorBufferInfo* bufferInfo = const_cast<VkDescriptorBufferInfo*>(WriteDescriptors[descriptorIndex].pBufferInfo);
|
||||
ASSERT(bufferInfo);
|
||||
auto* bufferInfo = const_cast<VkDescriptorBufferInfo*>(WriteDescriptors[descriptorIndex].pBufferInfo + index);
|
||||
bool edited = DescriptorSet::CopyAndReturnNotEqual(bufferInfo->buffer, buffer);
|
||||
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->offset, offset);
|
||||
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->range, range);
|
||||
@@ -464,63 +440,61 @@ public:
|
||||
return edited;
|
||||
}
|
||||
|
||||
bool WriteSampler(uint32 descriptorIndex, VkSampler sampler) const
|
||||
bool WriteSampler(uint32 descriptorIndex, VkSampler sampler, uint32 index = 0) const
|
||||
{
|
||||
ASSERT(descriptorIndex < WritesCount);
|
||||
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
|
||||
VkDescriptorImageInfo* imageInfo = const_cast<VkDescriptorImageInfo*>(WriteDescriptors[descriptorIndex].pImageInfo);
|
||||
ASSERT(imageInfo);
|
||||
auto* imageInfo = const_cast<VkDescriptorImageInfo*>(WriteDescriptors[descriptorIndex].pImageInfo + index);
|
||||
bool edited = DescriptorSet::CopyAndReturnNotEqual(imageInfo->sampler, sampler);
|
||||
return edited;
|
||||
}
|
||||
|
||||
bool WriteImage(uint32 descriptorIndex, VkImageView imageView, VkImageLayout layout) const
|
||||
bool WriteImage(uint32 descriptorIndex, VkImageView imageView, VkImageLayout layout, uint32 index = 0) const
|
||||
{
|
||||
ASSERT(descriptorIndex < WritesCount);
|
||||
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
|
||||
VkDescriptorImageInfo* imageInfo = const_cast<VkDescriptorImageInfo*>(WriteDescriptors[descriptorIndex].pImageInfo);
|
||||
ASSERT(imageInfo);
|
||||
auto* imageInfo = const_cast<VkDescriptorImageInfo*>(WriteDescriptors[descriptorIndex].pImageInfo + index);
|
||||
bool edited = DescriptorSet::CopyAndReturnNotEqual(imageInfo->imageView, imageView);
|
||||
edited |= DescriptorSet::CopyAndReturnNotEqual(imageInfo->imageLayout, layout);
|
||||
return edited;
|
||||
}
|
||||
|
||||
bool WriteStorageImage(uint32 descriptorIndex, VkImageView imageView, VkImageLayout layout) const
|
||||
bool WriteStorageImage(uint32 descriptorIndex, VkImageView imageView, VkImageLayout layout, uint32 index = 0) const
|
||||
{
|
||||
ASSERT(descriptorIndex < WritesCount);
|
||||
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
|
||||
VkDescriptorImageInfo* imageInfo = const_cast<VkDescriptorImageInfo*>(WriteDescriptors[descriptorIndex].pImageInfo);
|
||||
ASSERT(imageInfo);
|
||||
auto* imageInfo = const_cast<VkDescriptorImageInfo*>(WriteDescriptors[descriptorIndex].pImageInfo + index);
|
||||
bool edited = DescriptorSet::CopyAndReturnNotEqual(imageInfo->imageView, imageView);
|
||||
edited |= DescriptorSet::CopyAndReturnNotEqual(imageInfo->imageLayout, layout);
|
||||
return edited;
|
||||
}
|
||||
|
||||
bool WriteStorageTexelBuffer(uint32 descriptorIndex, const VkBufferView* bufferView) const
|
||||
bool WriteStorageTexelBuffer(uint32 descriptorIndex, VkBufferView bufferView, uint32 index = 0) const
|
||||
{
|
||||
ASSERT(descriptorIndex < WritesCount);
|
||||
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
|
||||
WriteDescriptors[descriptorIndex].pTexelBufferView = bufferView;
|
||||
auto* bufferInfo = const_cast<VkBufferView*>(WriteDescriptors[descriptorIndex].pTexelBufferView + index);
|
||||
*bufferInfo = bufferView;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteStorageBuffer(uint32 descriptorIndex, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range) const
|
||||
bool WriteStorageBuffer(uint32 descriptorIndex, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range, uint32 index = 0) const
|
||||
{
|
||||
ASSERT(descriptorIndex < WritesCount);
|
||||
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC);
|
||||
VkDescriptorBufferInfo* bufferInfo = const_cast<VkDescriptorBufferInfo*>(WriteDescriptors[descriptorIndex].pBufferInfo);
|
||||
ASSERT(bufferInfo);
|
||||
auto* bufferInfo = const_cast<VkDescriptorBufferInfo*>(WriteDescriptors[descriptorIndex].pBufferInfo + index);
|
||||
bool edited = DescriptorSet::CopyAndReturnNotEqual(bufferInfo->buffer, buffer);
|
||||
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->offset, offset);
|
||||
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->range, range);
|
||||
return edited;
|
||||
}
|
||||
|
||||
bool WriteUniformTexelBuffer(uint32 descriptorIndex, const VkBufferView* view) const
|
||||
bool WriteUniformTexelBuffer(uint32 descriptorIndex, VkBufferView view, uint32 index = 0) const
|
||||
{
|
||||
ASSERT(descriptorIndex < WritesCount);
|
||||
ASSERT(WriteDescriptors[descriptorIndex].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER);
|
||||
return DescriptorSet::CopyAndReturnNotEqual(WriteDescriptors[descriptorIndex].pTexelBufferView, view);
|
||||
auto* bufferInfo = const_cast<VkBufferView*>(WriteDescriptors[descriptorIndex].pTexelBufferView + index);
|
||||
return DescriptorSet::CopyAndReturnNotEqual(*bufferInfo, view);
|
||||
}
|
||||
|
||||
void SetDescriptorSet(VkDescriptorSet descriptorSet) const
|
||||
|
||||
@@ -44,10 +44,10 @@ void GPUBufferViewVulkan::Release()
|
||||
#endif
|
||||
}
|
||||
|
||||
void GPUBufferViewVulkan::DescriptorAsUniformTexelBuffer(GPUContextVulkan* context, const VkBufferView*& bufferView)
|
||||
void GPUBufferViewVulkan::DescriptorAsUniformTexelBuffer(GPUContextVulkan* context, VkBufferView& bufferView)
|
||||
{
|
||||
ASSERT_LOW_LAYER(View != VK_NULL_HANDLE);
|
||||
bufferView = &View;
|
||||
bufferView = View;
|
||||
context->AddBufferBarrier(Owner, VK_ACCESS_SHADER_READ_BIT);
|
||||
}
|
||||
|
||||
@@ -60,10 +60,10 @@ void GPUBufferViewVulkan::DescriptorAsStorageBuffer(GPUContextVulkan* context, V
|
||||
context->AddBufferBarrier(Owner, VK_ACCESS_SHADER_READ_BIT);
|
||||
}
|
||||
|
||||
void GPUBufferViewVulkan::DescriptorAsStorageTexelBuffer(GPUContextVulkan* context, const VkBufferView*& bufferView)
|
||||
void GPUBufferViewVulkan::DescriptorAsStorageTexelBuffer(GPUContextVulkan* context, VkBufferView& bufferView)
|
||||
{
|
||||
ASSERT_LOW_LAYER(View != VK_NULL_HANDLE);
|
||||
bufferView = &View;
|
||||
bufferView = View;
|
||||
context->AddBufferBarrier(Owner, VK_ACCESS_SHADER_READ_BIT);
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ bool GPUBufferVulkan::OnInit()
|
||||
bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
if (useSRV && !(_desc.Flags & GPUBufferFlags::Structured))
|
||||
bufferInfo.usage |= VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
|
||||
if (useUAV || _desc.Flags & GPUBufferFlags::RawBuffer)
|
||||
if (useUAV || _desc.Flags & GPUBufferFlags::RawBuffer || _desc.Flags & GPUBufferFlags::Structured)
|
||||
bufferInfo.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||
if (useUAV && useSRV)
|
||||
bufferInfo.usage |= VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
|
||||
|
||||
@@ -48,9 +48,9 @@ public:
|
||||
}
|
||||
|
||||
// [DescriptorOwnerResourceVulkan]
|
||||
void DescriptorAsUniformTexelBuffer(GPUContextVulkan* context, const VkBufferView*& bufferView) override;
|
||||
void DescriptorAsUniformTexelBuffer(GPUContextVulkan* context, VkBufferView& bufferView) override;
|
||||
void DescriptorAsStorageBuffer(GPUContextVulkan* context, VkBuffer& buffer, VkDeviceSize& offset, VkDeviceSize& range) override;
|
||||
void DescriptorAsStorageTexelBuffer(GPUContextVulkan* context, const VkBufferView*& bufferView) override;
|
||||
void DescriptorAsStorageTexelBuffer(GPUContextVulkan* context, VkBufferView& bufferView) override;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -444,117 +444,122 @@ void GPUContextVulkan::UpdateDescriptorSets(const SpirvShaderDescriptorInfo& des
|
||||
const auto& descriptor = descriptorInfo.DescriptorTypes[i];
|
||||
const int32 descriptorIndex = descriptor.Binding;
|
||||
DescriptorOwnerResourceVulkan** handles = _handles[(int32)descriptor.BindingType];
|
||||
|
||||
switch (descriptor.DescriptorType)
|
||||
for (uint32 index = 0; index < descriptor.Count; index++)
|
||||
{
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||
{
|
||||
// Sampler
|
||||
const VkSampler sampler = _samplerHandles[descriptor.Slot];
|
||||
ASSERT(sampler);
|
||||
needsWrite |= dsWriter.WriteSampler(descriptorIndex, sampler);
|
||||
break;
|
||||
}
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
{
|
||||
// Shader Resource (Texture)
|
||||
auto handle = (GPUTextureViewVulkan*)handles[descriptor.Slot];
|
||||
if (!handle)
|
||||
const int32 slot = descriptor.Slot + index;
|
||||
switch (descriptor.DescriptorType)
|
||||
{
|
||||
const auto dummy = _device->HelperResources.GetDummyTexture(descriptor.ResourceType);
|
||||
switch (descriptor.ResourceType)
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||
{
|
||||
// Sampler
|
||||
const VkSampler sampler = _samplerHandles[slot];
|
||||
ASSERT(sampler);
|
||||
needsWrite |= dsWriter.WriteSampler(descriptorIndex, sampler, index);
|
||||
break;
|
||||
}
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
{
|
||||
// Shader Resource (Texture)
|
||||
auto handle = (GPUTextureViewVulkan*)handles[slot];
|
||||
if (!handle)
|
||||
{
|
||||
case SpirvShaderResourceType::Texture1D:
|
||||
case SpirvShaderResourceType::Texture2D:
|
||||
handle = static_cast<GPUTextureViewVulkan*>(dummy->View(0));
|
||||
break;
|
||||
case SpirvShaderResourceType::Texture3D:
|
||||
handle = static_cast<GPUTextureViewVulkan*>(dummy->ViewVolume());
|
||||
break;
|
||||
case SpirvShaderResourceType::TextureCube:
|
||||
case SpirvShaderResourceType::Texture1DArray:
|
||||
case SpirvShaderResourceType::Texture2DArray:
|
||||
handle = static_cast<GPUTextureViewVulkan*>(dummy->ViewArray());
|
||||
break;
|
||||
const auto dummy = _device->HelperResources.GetDummyTexture(descriptor.ResourceType);
|
||||
switch (descriptor.ResourceType)
|
||||
{
|
||||
case SpirvShaderResourceType::Texture1D:
|
||||
case SpirvShaderResourceType::Texture2D:
|
||||
handle = static_cast<GPUTextureViewVulkan*>(dummy->View(0));
|
||||
break;
|
||||
case SpirvShaderResourceType::Texture3D:
|
||||
handle = static_cast<GPUTextureViewVulkan*>(dummy->ViewVolume());
|
||||
break;
|
||||
case SpirvShaderResourceType::TextureCube:
|
||||
case SpirvShaderResourceType::Texture1DArray:
|
||||
case SpirvShaderResourceType::Texture2DArray:
|
||||
handle = static_cast<GPUTextureViewVulkan*>(dummy->ViewArray());
|
||||
break;
|
||||
}
|
||||
}
|
||||
VkImageView imageView;
|
||||
VkImageLayout layout;
|
||||
handle->DescriptorAsImage(this, imageView, layout);
|
||||
ASSERT(imageView != VK_NULL_HANDLE);
|
||||
needsWrite |= dsWriter.WriteImage(descriptorIndex, imageView, layout, index);
|
||||
break;
|
||||
}
|
||||
VkImageView imageView;
|
||||
VkImageLayout layout;
|
||||
handle->DescriptorAsImage(this, imageView, layout);
|
||||
ASSERT(imageView != VK_NULL_HANDLE);
|
||||
needsWrite |= dsWriter.WriteImage(descriptorIndex, imageView, layout);
|
||||
break;
|
||||
}
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
||||
{
|
||||
// Shader Resource (Buffer)
|
||||
auto sr = handles[descriptor.Slot];
|
||||
if (!sr)
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
||||
{
|
||||
const auto dummy = _device->HelperResources.GetDummyBuffer();
|
||||
sr = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr();
|
||||
// Shader Resource (Buffer)
|
||||
auto sr = handles[slot];
|
||||
if (!sr)
|
||||
{
|
||||
const auto dummy = _device->HelperResources.GetDummyBuffer();
|
||||
sr = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr();
|
||||
}
|
||||
VkBufferView bufferView;
|
||||
sr->DescriptorAsUniformTexelBuffer(this, bufferView);
|
||||
ASSERT(bufferView != VK_NULL_HANDLE);
|
||||
needsWrite |= dsWriter.WriteUniformTexelBuffer(descriptorIndex, bufferView, index);
|
||||
break;
|
||||
}
|
||||
const VkBufferView* bufferView;
|
||||
sr->DescriptorAsUniformTexelBuffer(this, bufferView);
|
||||
needsWrite |= dsWriter.WriteUniformTexelBuffer(descriptorIndex, bufferView);
|
||||
break;
|
||||
}
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
||||
{
|
||||
// Unordered Access (Texture)
|
||||
auto ua = handles[descriptor.Slot];
|
||||
ASSERT(ua);
|
||||
VkImageView imageView;
|
||||
VkImageLayout layout;
|
||||
ua->DescriptorAsStorageImage(this, imageView, layout);
|
||||
needsWrite |= dsWriter.WriteStorageImage(descriptorIndex, imageView, layout);
|
||||
break;
|
||||
}
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
||||
{
|
||||
// Unordered Access (Buffer)
|
||||
auto ua = handles[descriptor.Slot];
|
||||
if (!ua)
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
||||
{
|
||||
const auto dummy = _device->HelperResources.GetDummyBuffer();
|
||||
ua = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr();
|
||||
// Unordered Access (Texture)
|
||||
auto ua = handles[slot];
|
||||
ASSERT(ua);
|
||||
VkImageView imageView;
|
||||
VkImageLayout layout;
|
||||
ua->DescriptorAsStorageImage(this, imageView, layout);
|
||||
needsWrite |= dsWriter.WriteStorageImage(descriptorIndex, imageView, layout, index);
|
||||
break;
|
||||
}
|
||||
VkBuffer buffer;
|
||||
VkDeviceSize offset, range;
|
||||
ua->DescriptorAsStorageBuffer(this, buffer, offset, range);
|
||||
needsWrite |= dsWriter.WriteStorageBuffer(descriptorIndex, buffer, offset, range);
|
||||
break;
|
||||
}
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
||||
{
|
||||
// Unordered Access (Buffer)
|
||||
auto ua = handles[descriptor.Slot];
|
||||
if (!ua)
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
||||
{
|
||||
const auto dummy = _device->HelperResources.GetDummyBuffer();
|
||||
ua = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr();
|
||||
// Unordered Access (Buffer)
|
||||
auto ua = handles[slot];
|
||||
if (!ua)
|
||||
{
|
||||
const auto dummy = _device->HelperResources.GetDummyBuffer();
|
||||
ua = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr();
|
||||
}
|
||||
VkBuffer buffer;
|
||||
VkDeviceSize offset, range;
|
||||
ua->DescriptorAsStorageBuffer(this, buffer, offset, range);
|
||||
needsWrite |= dsWriter.WriteStorageBuffer(descriptorIndex, buffer, offset, range, index);
|
||||
break;
|
||||
}
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
||||
{
|
||||
// Unordered Access (Buffer)
|
||||
auto ua = handles[slot];
|
||||
if (!ua)
|
||||
{
|
||||
const auto dummy = _device->HelperResources.GetDummyBuffer();
|
||||
ua = (DescriptorOwnerResourceVulkan*)dummy->View()->GetNativePtr();
|
||||
}
|
||||
VkBufferView bufferView;
|
||||
ua->DescriptorAsStorageTexelBuffer(this, bufferView);
|
||||
ASSERT(bufferView != VK_NULL_HANDLE);
|
||||
needsWrite |= dsWriter.WriteStorageTexelBuffer(descriptorIndex, bufferView, index);
|
||||
break;
|
||||
}
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
||||
{
|
||||
// Constant Buffer
|
||||
auto cb = handles[slot];
|
||||
ASSERT(cb);
|
||||
VkBuffer buffer;
|
||||
VkDeviceSize offset, range;
|
||||
uint32 dynamicOffset;
|
||||
cb->DescriptorAsDynamicUniformBuffer(this, buffer, offset, range, dynamicOffset);
|
||||
needsWrite |= dsWriter.WriteDynamicUniformBuffer(descriptorIndex, buffer, offset, range, dynamicOffset, index);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// Unknown or invalid descriptor type
|
||||
CRASH;
|
||||
break;
|
||||
}
|
||||
const VkBufferView* bufferView;
|
||||
ua->DescriptorAsStorageTexelBuffer(this, bufferView);
|
||||
needsWrite |= dsWriter.WriteStorageTexelBuffer(descriptorIndex, bufferView);
|
||||
break;
|
||||
}
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
||||
{
|
||||
// Constant Buffer
|
||||
auto cb = handles[descriptor.Slot];
|
||||
ASSERT(cb);
|
||||
VkBuffer buffer;
|
||||
VkDeviceSize offset, range;
|
||||
uint32 dynamicOffset;
|
||||
cb->DescriptorAsDynamicUniformBuffer(this, buffer, offset, range, dynamicOffset);
|
||||
needsWrite |= dsWriter.WriteDynamicUniformBuffer(descriptorIndex, buffer, offset, range, dynamicOffset);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// Unknown or invalid descriptor type
|
||||
CRASH;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1102,6 +1107,10 @@ void GPUContextVulkan::Dispatch(GPUShaderProgramCS* shader, uint32 threadGroupCo
|
||||
vkCmdDispatch(cmdBuffer->GetHandle(), threadGroupCountX, threadGroupCountY, threadGroupCountZ);
|
||||
RENDER_STAT_DISPATCH_CALL();
|
||||
|
||||
// Place a barrier between dispatches, so that UAVs can be read+write in subsequent passes
|
||||
// TODO: optimize it by moving inputs/outputs into higher-layer so eg. Global SDF can manually optimize it
|
||||
vkCmdPipelineBarrier(cmdBuffer->GetHandle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 0, nullptr);
|
||||
|
||||
#if VK_ENABLE_BARRIERS_DEBUG
|
||||
LOG(Warning, "Dispatch");
|
||||
#endif
|
||||
@@ -1136,6 +1145,10 @@ void GPUContextVulkan::DispatchIndirect(GPUShaderProgramCS* shader, GPUBuffer* b
|
||||
vkCmdDispatchIndirect(cmdBuffer->GetHandle(), bufferForArgsVulkan->GetHandle(), offsetForArgs);
|
||||
RENDER_STAT_DISPATCH_CALL();
|
||||
|
||||
// Place a barrier between dispatches, so that UAVs can be read+write in subsequent passes
|
||||
// TODO: optimize it by moving inputs/outputs into higher-layer so eg. Global SDF can manually optimize it
|
||||
vkCmdPipelineBarrier(cmdBuffer->GetHandle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 0, nullptr);
|
||||
|
||||
#if VK_ENABLE_BARRIERS_DEBUG
|
||||
LOG(Warning, "DispatchIndirect");
|
||||
#endif
|
||||
@@ -1494,7 +1507,7 @@ void GPUContextVulkan::CopyResource(GPUResource* dstResource, GPUResource* srcRe
|
||||
ASSERT(bufferCopy.size == dstBufferVulkan->GetSize());
|
||||
vkCmdCopyBuffer(cmdBuffer->GetHandle(), srcBufferVulkan->GetHandle(), dstBufferVulkan->GetHandle(), 1, &bufferCopy);
|
||||
}
|
||||
// Texture -> Texture
|
||||
// Texture -> Texture
|
||||
else if (srcType == GPUResource::ObjectType::Texture && dstType == GPUResource::ObjectType::Texture)
|
||||
{
|
||||
if (dstTextureVulkan->IsStaging())
|
||||
@@ -1505,7 +1518,7 @@ void GPUContextVulkan::CopyResource(GPUResource* dstResource, GPUResource* srcRe
|
||||
ASSERT(dstTextureVulkan->StagingBuffer && srcTextureVulkan->StagingBuffer);
|
||||
CopyResource(dstTextureVulkan->StagingBuffer, srcTextureVulkan->StagingBuffer);
|
||||
}
|
||||
// Texture -> Staging Texture
|
||||
// Texture -> Staging Texture
|
||||
else
|
||||
{
|
||||
// Transition resources
|
||||
@@ -1635,7 +1648,7 @@ void GPUContextVulkan::CopySubresource(GPUResource* dstResource, uint32 dstSubre
|
||||
ASSERT(bufferCopy.size == dstBufferVulkan->GetSize());
|
||||
vkCmdCopyBuffer(cmdBuffer->GetHandle(), srcBufferVulkan->GetHandle(), dstBufferVulkan->GetHandle(), 1, &bufferCopy);
|
||||
}
|
||||
// Texture -> Texture
|
||||
// Texture -> Texture
|
||||
else if (srcType == GPUResource::ObjectType::Texture && dstType == GPUResource::ObjectType::Texture)
|
||||
{
|
||||
const int32 dstMipMaps = dstTextureVulkan->MipLevels();
|
||||
@@ -1653,7 +1666,7 @@ void GPUContextVulkan::CopySubresource(GPUResource* dstResource, uint32 dstSubre
|
||||
ASSERT(dstTextureVulkan->StagingBuffer && srcTextureVulkan->StagingBuffer);
|
||||
CopyResource(dstTextureVulkan->StagingBuffer, srcTextureVulkan->StagingBuffer);
|
||||
}
|
||||
// Texture -> Staging Texture
|
||||
// Texture -> Staging Texture
|
||||
else
|
||||
{
|
||||
// Transition resources
|
||||
|
||||
@@ -209,11 +209,22 @@ static VKAPI_ATTR VkBool32 VKAPI_PTR DebugUtilsCallback(VkDebugUtilsMessageSever
|
||||
type = TEXT("Perf");
|
||||
}
|
||||
|
||||
if (callbackData->pMessageIdName)
|
||||
LOG(Info, "[Vulkan] {0} {1}:{2}({3}) {4}", type, severity, callbackData->messageIdNumber, String(callbackData->pMessageIdName), String(callbackData->pMessage));
|
||||
else
|
||||
LOG(Info, "[Vulkan] {0} {1}:{2} {3}", type, severity, callbackData->messageIdNumber, String(callbackData->pMessage));
|
||||
// Fix invalid characters in hex values (bug in Debug Layer)
|
||||
char* handleStart = (char*)StringUtils::FindIgnoreCase(callbackData->pMessage, "0x");
|
||||
while (handleStart != nullptr)
|
||||
{
|
||||
while (*handleStart != ' ' && *handleStart != 0)
|
||||
*handleStart++ = Math::Clamp<char>(*handleStart, '0', 'z');
|
||||
if (*handleStart == 0)
|
||||
break;
|
||||
handleStart = (char*)StringUtils::FindIgnoreCase(handleStart, "0x");
|
||||
}
|
||||
|
||||
const String message(callbackData->pMessage);
|
||||
if (callbackData->pMessageIdName)
|
||||
LOG(Info, "[Vulkan] {0} {1}:{2}({3}) {4}", type, severity, callbackData->messageIdNumber, String(callbackData->pMessageIdName), message);
|
||||
else
|
||||
LOG(Info, "[Vulkan] {0} {1}:{2} {3}", type, severity, callbackData->messageIdNumber, message);
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -782,7 +782,7 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="context">The GPU context. Can be used to add memory barriers to the pipeline before binding the descriptor to the pipeline.</param>
|
||||
/// <param name="bufferView">The buffer view.</param>
|
||||
virtual void DescriptorAsUniformTexelBuffer(GPUContextVulkan* context, const VkBufferView*& bufferView)
|
||||
virtual void DescriptorAsUniformTexelBuffer(GPUContextVulkan* context, VkBufferView& bufferView)
|
||||
{
|
||||
CRASH;
|
||||
}
|
||||
@@ -804,7 +804,7 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="context">The GPU context. Can be used to add memory barriers to the pipeline before binding the descriptor to the pipeline.</param>
|
||||
/// <param name="bufferView">The buffer view.</param>
|
||||
virtual void DescriptorAsStorageTexelBuffer(GPUContextVulkan* context, const VkBufferView*& bufferView)
|
||||
virtual void DescriptorAsStorageTexelBuffer(GPUContextVulkan* context, VkBufferView& bufferView)
|
||||
{
|
||||
CRASH;
|
||||
}
|
||||
|
||||
@@ -51,9 +51,11 @@ ComputePipelineStateVulkan* GPUShaderProgramCSVulkan::GetOrCreateState()
|
||||
uint32 dynamicOffsetsCount = 0;
|
||||
if (DescriptorInfo.DescriptorTypesCount != 0)
|
||||
{
|
||||
// TODO: merge into a single allocation
|
||||
_pipelineState->DSWriteContainer.DescriptorWrites.AddZeroed(DescriptorInfo.DescriptorTypesCount);
|
||||
_pipelineState->DSWriteContainer.DescriptorImageInfo.AddZeroed(DescriptorInfo.ImageInfosCount);
|
||||
_pipelineState->DSWriteContainer.DescriptorBufferInfo.AddZeroed(DescriptorInfo.BufferInfosCount);
|
||||
_pipelineState->DSWriteContainer.DescriptorTexelBufferView.AddZeroed(DescriptorInfo.TexelBufferViewsCount);
|
||||
|
||||
ASSERT(DescriptorInfo.DescriptorTypesCount < 255);
|
||||
_pipelineState->DSWriteContainer.BindingToDynamicOffset.AddDefault(DescriptorInfo.DescriptorTypesCount);
|
||||
@@ -62,9 +64,10 @@ ComputePipelineStateVulkan* GPUShaderProgramCSVulkan::GetOrCreateState()
|
||||
VkWriteDescriptorSet* currentDescriptorWrite = _pipelineState->DSWriteContainer.DescriptorWrites.Get();
|
||||
VkDescriptorImageInfo* currentImageInfo = _pipelineState->DSWriteContainer.DescriptorImageInfo.Get();
|
||||
VkDescriptorBufferInfo* currentBufferInfo = _pipelineState->DSWriteContainer.DescriptorBufferInfo.Get();
|
||||
VkBufferView* currentTexelBufferView = _pipelineState->DSWriteContainer.DescriptorTexelBufferView.Get();
|
||||
uint8* currentBindingToDynamicOffsetMap = _pipelineState->DSWriteContainer.BindingToDynamicOffset.Get();
|
||||
|
||||
dynamicOffsetsCount = _pipelineState->DSWriter.SetupDescriptorWrites(DescriptorInfo, currentDescriptorWrite, currentImageInfo, currentBufferInfo, currentBindingToDynamicOffsetMap);
|
||||
dynamicOffsetsCount = _pipelineState->DSWriter.SetupDescriptorWrites(DescriptorInfo, currentDescriptorWrite, currentImageInfo, currentBufferInfo, currentTexelBufferView, currentBindingToDynamicOffsetMap);
|
||||
}
|
||||
|
||||
_pipelineState->DynamicOffsets.AddZeroed(dynamicOffsetsCount);
|
||||
@@ -337,9 +340,11 @@ bool GPUPipelineStateVulkan::Init(const Description& desc)
|
||||
if (descriptor == nullptr || descriptor->DescriptorTypesCount == 0)
|
||||
continue;
|
||||
|
||||
// TODO: merge into a single allocation for a whole PSO
|
||||
DSWriteContainer.DescriptorWrites.AddZeroed(descriptor->DescriptorTypesCount);
|
||||
DSWriteContainer.DescriptorImageInfo.AddZeroed(descriptor->ImageInfosCount);
|
||||
DSWriteContainer.DescriptorBufferInfo.AddZeroed(descriptor->BufferInfosCount);
|
||||
DSWriteContainer.DescriptorTexelBufferView.AddZeroed(descriptor->TexelBufferViewsCount);
|
||||
|
||||
ASSERT(descriptor->DescriptorTypesCount < 255);
|
||||
DSWriteContainer.BindingToDynamicOffset.AddDefault(descriptor->DescriptorTypesCount);
|
||||
@@ -349,6 +354,7 @@ bool GPUPipelineStateVulkan::Init(const Description& desc)
|
||||
VkWriteDescriptorSet* currentDescriptorWrite = DSWriteContainer.DescriptorWrites.Get();
|
||||
VkDescriptorImageInfo* currentImageInfo = DSWriteContainer.DescriptorImageInfo.Get();
|
||||
VkDescriptorBufferInfo* currentBufferInfo = DSWriteContainer.DescriptorBufferInfo.Get();
|
||||
VkBufferView* currentTexelBufferView = DSWriteContainer.DescriptorTexelBufferView.Get();
|
||||
byte* currentBindingToDynamicOffsetMap = DSWriteContainer.BindingToDynamicOffset.Get();
|
||||
uint32 dynamicOffsetsStart[DescriptorSet::GraphicsStagesCount];
|
||||
uint32 dynamicOffsetsCount = 0;
|
||||
@@ -360,12 +366,13 @@ bool GPUPipelineStateVulkan::Init(const Description& desc)
|
||||
if (descriptor == nullptr || descriptor->DescriptorTypesCount == 0)
|
||||
continue;
|
||||
|
||||
const uint32 numDynamicOffsets = DSWriter[stage].SetupDescriptorWrites(*descriptor, currentDescriptorWrite, currentImageInfo, currentBufferInfo, currentBindingToDynamicOffsetMap);
|
||||
const uint32 numDynamicOffsets = DSWriter[stage].SetupDescriptorWrites(*descriptor, currentDescriptorWrite, currentImageInfo, currentBufferInfo, currentTexelBufferView, currentBindingToDynamicOffsetMap);
|
||||
dynamicOffsetsCount += numDynamicOffsets;
|
||||
|
||||
currentDescriptorWrite += descriptor->DescriptorTypesCount;
|
||||
currentImageInfo += descriptor->ImageInfosCount;
|
||||
currentBufferInfo += descriptor->BufferInfosCount;
|
||||
currentTexelBufferView += descriptor->TexelBufferViewsCount;
|
||||
currentBindingToDynamicOffsetMap += descriptor->DescriptorTypesCount;
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -182,7 +182,7 @@ protected:
|
||||
|
||||
// [GPUTexture]
|
||||
bool OnInit() override;
|
||||
void onResidentMipsChanged() override;
|
||||
void OnResidentMipsChanged() override;
|
||||
void OnReleaseGPU() override;
|
||||
};
|
||||
|
||||
|
||||
@@ -94,10 +94,16 @@ struct SpirvShaderDescriptorInfo
|
||||
/// The resource type.
|
||||
/// </summary>
|
||||
SpirvShaderResourceType ResourceType;
|
||||
|
||||
/// <summary>
|
||||
/// The amount of slots used by the descriptor (eg. array of textures size).
|
||||
/// </summary>
|
||||
uint32 Count;
|
||||
};
|
||||
|
||||
uint16 ImageInfosCount;
|
||||
uint16 BufferInfosCount;
|
||||
uint32 TexelBufferViewsCount;
|
||||
uint32 DescriptorTypesCount;
|
||||
Descriptor DescriptorTypes[MaxDescriptors];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user