Update to the latest Vulkan SDK 1.4.350
Update Vulkan API to `1.2` on Windows Update Vulkan API to `1.1` on Android
This commit is contained in:
@@ -3,7 +3,7 @@ description: Downloads and installs Vulkan SDK.
|
||||
inputs:
|
||||
vulkan-version:
|
||||
description: 'Vulkan SDK release version (e.g. 1.2.198.1).'
|
||||
default: '1.3.290.0'
|
||||
default: '1.4.350.0'
|
||||
required: false
|
||||
runs:
|
||||
using: "composite"
|
||||
|
||||
@@ -433,6 +433,7 @@ bool ProcessShaderBase(CookAssetsStep::AssetCookData& data, ShaderAssetBase* ass
|
||||
options.GenerateDebugData = data.Cache.Settings.Global.ShadersGenerateDebugData;
|
||||
options.TreatWarningsAsErrors = false;
|
||||
options.Output = &cacheStream;
|
||||
options.Platform = data.Data.Tools->GetPlatform();
|
||||
Array<String> includes;
|
||||
|
||||
#define COMPILE_PROFILE(profile, cacheChunk) \
|
||||
@@ -535,7 +536,6 @@ bool ProcessShaderBase(CookAssetsStep::AssetCookData& data, ShaderAssetBase* ass
|
||||
#if PLATFORM_TOOLS_XBOX_SCARLETT
|
||||
case BuildPlatform::XboxScarlett:
|
||||
{
|
||||
options.Platform = PlatformType::XboxScarlett;
|
||||
const char* platformDefineName = "PLATFORM_XBOX_SCARLETT";
|
||||
COMPILE_PROFILE(DirectX_SM6, SHADER_FILE_CHUNK_INTERNAL_D3D_SM6_CACHE);
|
||||
break;
|
||||
|
||||
@@ -264,10 +264,13 @@ bool ShaderAssetBase::LoadShaderCache(ShaderCacheResult& result)
|
||||
auto& platformDefine = options.Macros.AddOne();
|
||||
#if PLATFORM_WINDOWS
|
||||
platformDefine.Name = "PLATFORM_WINDOWS";
|
||||
options.Platform = PlatformType::Windows;
|
||||
#elif PLATFORM_LINUX
|
||||
platformDefine.Name = "PLATFORM_LINUX";
|
||||
options.Platform = PlatformType::Linux;
|
||||
#elif PLATFORM_MAC
|
||||
platformDefine.Name = "PLATFORM_MAC";
|
||||
options.Platform = PlatformType::Mac;
|
||||
#else
|
||||
#error "Unknown platform."
|
||||
#endif
|
||||
|
||||
@@ -188,6 +188,7 @@ bool ShaderCacheManagerService::Init()
|
||||
int32 ShaderCacheVersion = -1;
|
||||
int32 MaterialGraphVersion = -1;
|
||||
int32 ParticleGraphVersion = -1;
|
||||
int32 Platform = -1;
|
||||
union
|
||||
{
|
||||
struct
|
||||
@@ -210,6 +211,7 @@ bool ShaderCacheManagerService::Init()
|
||||
ShaderCacheVersion = GPU_SHADER_CACHE_VERSION;
|
||||
MaterialGraphVersion = MATERIAL_GRAPH_VERSION;
|
||||
ParticleGraphVersion = PARTICLE_GPU_GRAPH_VERSION;
|
||||
Platform = (int32)PLATFORM_TYPE;
|
||||
Flags = 0;
|
||||
#if USE_EDITOR
|
||||
ShaderDebug = CommandLine::Options.ShaderDebug.IsTrue();
|
||||
@@ -235,6 +237,7 @@ bool ShaderCacheManagerService::Init()
|
||||
|| cacheVersion.ShaderCacheVersion != cacheVersionDefault.ShaderCacheVersion
|
||||
|| cacheVersion.MaterialGraphVersion != cacheVersionDefault.MaterialGraphVersion
|
||||
|| cacheVersion.ParticleGraphVersion != cacheVersionDefault.ParticleGraphVersion
|
||||
|| cacheVersion.Platform != cacheVersionDefault.Platform
|
||||
|| cacheVersion.Flags != cacheVersionDefault.Flags
|
||||
)
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ void AndroidVulkanPlatform::GetInstanceExtensions(Array<const char*>& extensions
|
||||
extensions.Add(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
void AndroidVulkanPlatform::GetDeviceExtensions(Array<const char*>& extensions, Array<const char*>& layers)
|
||||
void AndroidVulkanPlatform::GetDeviceExtensions(Array<const char*>& extensions)
|
||||
{
|
||||
extensions.Add(VK_KHR_SURFACE_EXTENSION_NAME);
|
||||
extensions.Add(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
|
||||
#if GRAPHICS_API_VULKAN && PLATFORM_ANDROID
|
||||
|
||||
// Android has 99.4% of Vulkan 1.1 and API level 29 (Android 10.0)
|
||||
#define VULKAN_API_VERSION VK_API_VERSION_1_1
|
||||
|
||||
// Support more backbuffers in case driver decides to use more
|
||||
#define VULKAN_BACK_BUFFERS_COUNT_MAX 8
|
||||
|
||||
@@ -16,7 +19,7 @@ class AndroidVulkanPlatform : public VulkanPlatformBase
|
||||
{
|
||||
public:
|
||||
static void GetInstanceExtensions(Array<const char*>& extensions, Array<const char*>& layers);
|
||||
static void GetDeviceExtensions(Array<const char*>& extensions, Array<const char*>& layers);
|
||||
static void GetDeviceExtensions(Array<const char*>& extensions);
|
||||
static void CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* surface);
|
||||
};
|
||||
|
||||
|
||||
@@ -210,7 +210,11 @@ void GPUContextVulkan::AddImageBarrier(GPUTextureViewVulkan* handle, VkImageLayo
|
||||
range.baseMipLevel = 0;
|
||||
range.levelCount = mipLevels;
|
||||
range.baseArrayLayer = 0;
|
||||
#if VK_KHR_maintenance1
|
||||
range.layerCount = VK_REMAINING_ARRAY_LAYERS; // maintenance9 could be enabled for per-layer masking
|
||||
#else
|
||||
range.layerCount = handle->Owner->ArraySlices;
|
||||
#endif
|
||||
AddImageBarrier(handle->Image, srcLayout, dstLayout, range, handle);
|
||||
state.SetResourceState(dstLayout);
|
||||
}
|
||||
@@ -229,6 +233,10 @@ void GPUContextVulkan::AddImageBarrier(GPUTextureViewVulkan* handle, VkImageLayo
|
||||
range.levelCount = 1;
|
||||
range.baseArrayLayer = i / mipLevels;
|
||||
range.layerCount = 1;
|
||||
#if VK_KHR_maintenance1
|
||||
if (handle->Owner->ArraySlices == 1)
|
||||
range.layerCount = VK_REMAINING_ARRAY_LAYERS; // maintenance9 could be enabled for per-layer masking
|
||||
#endif
|
||||
AddImageBarrier(handle->Image, srcLayout, dstLayout, range, handle);
|
||||
state.SetSubresourceState(i, dstLayout);
|
||||
}
|
||||
@@ -264,6 +272,10 @@ void GPUContextVulkan::AddImageBarrier(GPUTextureVulkan* texture, int32 mipSlice
|
||||
range.levelCount = 1;
|
||||
range.baseArrayLayer = arraySlice;
|
||||
range.layerCount = 1;
|
||||
#if VK_KHR_maintenance1
|
||||
if (texture->IsVolume())
|
||||
range.layerCount = VK_REMAINING_ARRAY_LAYERS; // maintenance9 could be enabled for per-layer masking
|
||||
#endif
|
||||
AddImageBarrier(texture->GetHandle(), srcLayout, dstLayout, range, nullptr);
|
||||
state.SetSubresourceState(subresourceIndex, dstLayout);
|
||||
}
|
||||
@@ -285,6 +297,10 @@ void GPUContextVulkan::AddImageBarrier(GPUTextureVulkan* texture, VkImageLayout
|
||||
range.levelCount = texture->MipLevels();
|
||||
range.baseArrayLayer = 0;
|
||||
range.layerCount = texture->ArraySize();
|
||||
#if VK_KHR_maintenance1
|
||||
if (texture->IsVolume())
|
||||
range.layerCount = VK_REMAINING_ARRAY_LAYERS; // maintenance9 could be enabled for per-layer masking
|
||||
#endif
|
||||
AddImageBarrier(texture->GetHandle(), srcLayout, dstLayout, range, nullptr);
|
||||
state.SetResourceState(dstLayout);
|
||||
}
|
||||
@@ -431,7 +447,7 @@ void GPUContextVulkan::BeginRenderPass()
|
||||
PendingClear clear;
|
||||
for (int32 i = 0; i < GPU_MAX_RT_BINDED; i++)
|
||||
{
|
||||
auto handle = _rtHandles[i];
|
||||
auto handle = _rtTargets[i];
|
||||
if (handle)
|
||||
{
|
||||
layout.RTVsFormats[i] = handle->GetFormat();
|
||||
@@ -490,7 +506,7 @@ void GPUContextVulkan::BeginRenderPass()
|
||||
}
|
||||
else
|
||||
{
|
||||
handle = _rtHandles[0];
|
||||
handle = _rtTargets[0];
|
||||
#if !BUILD_RELEASE
|
||||
if (!handle)
|
||||
{
|
||||
@@ -507,9 +523,8 @@ void GPUContextVulkan::BeginRenderPass()
|
||||
layout.Layers = handle->Layers;
|
||||
|
||||
// Clear textures that are not bind to the render pass
|
||||
for (auto& e : _pendingClears)
|
||||
ManualClear(e);
|
||||
_pendingClears.Clear();
|
||||
if (_pendingClears.HasItems())
|
||||
FlushManualClears();
|
||||
|
||||
// Get or create objects
|
||||
auto renderPass = _device->GetOrCreateRenderPass(layout);
|
||||
@@ -569,6 +584,17 @@ void GPUContextVulkan::ManualClear(const PendingClear& clear)
|
||||
}
|
||||
}
|
||||
|
||||
void GPUContextVulkan::FlushManualClears()
|
||||
{
|
||||
// Batch barriers
|
||||
for (auto& clear : _pendingClears)
|
||||
AddImageBarrier(clear.View, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
for (auto& clear : _pendingClears)
|
||||
ManualClear(clear);
|
||||
_pendingClears.Clear();
|
||||
}
|
||||
|
||||
void GPUContextVulkan::UpdateDescriptorSets(const SpirvShaderDescriptorInfo& descriptorInfo, DescriptorSetWriterVulkan& dsWriter, bool& needsWrite)
|
||||
{
|
||||
for (uint32 i = 0; i < descriptorInfo.DescriptorTypesCount; i++)
|
||||
@@ -736,6 +762,27 @@ void GPUContextVulkan::OnDrawCall()
|
||||
ASSERT(pipelineState && pipelineState->IsValid());
|
||||
const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer();
|
||||
|
||||
// Flush pending image clears before binding descriptors but skip ones that are going to be used as render targets
|
||||
// (they will be cleared in the render pass with proper loadOp and without extra barriers)
|
||||
if (_pendingClears.HasItems())
|
||||
{
|
||||
auto rtHandles = ToSpan(_rtHandles, ARRAY_COUNT(_rtHandles));
|
||||
for (auto& clear : _pendingClears)
|
||||
{
|
||||
if (!SpanContains(rtHandles, clear.View))
|
||||
AddImageBarrier(clear.View, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
}
|
||||
for (int32 i = 0; i < _pendingClears.Count(); i++)
|
||||
{
|
||||
auto& clear = _pendingClears.Get()[i];
|
||||
if (!SpanContains(rtHandles, clear.View))
|
||||
{
|
||||
ManualClear(clear);
|
||||
_pendingClears.RemoveAtKeepOrder(i--);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// End previous render pass if render targets layout was modified
|
||||
if (_rtDirtyFlag && cmdBuffer->IsInsideRenderPass())
|
||||
EndRenderPass();
|
||||
@@ -837,7 +884,6 @@ void GPUContextVulkan::FrameBegin()
|
||||
_currentState = nullptr;
|
||||
_currentCompute = nullptr;
|
||||
_vertexLayout = nullptr;
|
||||
_rtDepth = nullptr;
|
||||
Platform::MemoryClear(_rtHandles, sizeof(_rtHandles));
|
||||
Platform::MemoryClear(_cbHandles, sizeof(_cbHandles));
|
||||
Platform::MemoryClear(_srHandles, sizeof(_srHandles));
|
||||
@@ -918,6 +964,17 @@ bool GPUContextVulkan::IsDepthBufferBinded()
|
||||
|
||||
void GPUContextVulkan::Clear(GPUTextureView* rt, const Color& color)
|
||||
{
|
||||
for (auto& e : _pendingClears)
|
||||
{
|
||||
if (e.View == rt)
|
||||
{
|
||||
// Use existing slot
|
||||
Platform::MemoryCopy(e.Value.color.float32, color.Raw, sizeof(color.Raw));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add a new entry
|
||||
auto& clear = _pendingClears.AddOne();
|
||||
clear.View = (GPUTextureViewVulkan*)rt;
|
||||
Platform::MemoryCopy(clear.Value.color.float32, color.Raw, sizeof(color.Raw));
|
||||
@@ -925,6 +982,18 @@ void GPUContextVulkan::Clear(GPUTextureView* rt, const Color& color)
|
||||
|
||||
void GPUContextVulkan::ClearDepth(GPUTextureView* depthBuffer, float depthValue, uint8 stencilValue)
|
||||
{
|
||||
for (auto& e : _pendingClears)
|
||||
{
|
||||
if (e.View == depthBuffer)
|
||||
{
|
||||
// Use existing slot
|
||||
e.Value.depthStencil.depth = depthValue;
|
||||
e.Value.depthStencil.stencil = stencilValue;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add a new entry
|
||||
auto& clear = _pendingClears.AddOne();
|
||||
clear.View = (GPUTextureViewVulkan*)depthBuffer;
|
||||
clear.Value.depthStencil.depth = depthValue;
|
||||
@@ -1001,7 +1070,6 @@ void GPUContextVulkan::ResetRenderTarget()
|
||||
_rtDirtyFlag = true;
|
||||
_psDirtyFlag = true;
|
||||
_rtCount = 0;
|
||||
_rtDepth = nullptr;
|
||||
Platform::MemoryClear(_rtHandles, sizeof(_rtHandles));
|
||||
|
||||
const auto cmdBuffer = _cmdBufferManager->GetActiveCmdBuffer();
|
||||
@@ -1014,13 +1082,13 @@ void GPUContextVulkan::SetRenderTarget(GPUTextureView* rt)
|
||||
{
|
||||
const auto rtVulkan = static_cast<GPUTextureViewVulkan*>(rt);
|
||||
|
||||
if (_rtDepth != nullptr || _rtCount != 1 || _rtHandles[0] != rtVulkan)
|
||||
if (_rtDepth != nullptr || _rtCount != 1 || _rtTargets[0] != rtVulkan)
|
||||
{
|
||||
_rtDirtyFlag = true;
|
||||
_psDirtyFlag = true;
|
||||
_rtCount = 1;
|
||||
_rtDepth = nullptr;
|
||||
_rtHandles[0] = rtVulkan;
|
||||
_rtTargets[0] = rtVulkan;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1030,13 +1098,13 @@ void GPUContextVulkan::SetRenderTarget(GPUTextureView* depthBuffer, GPUTextureVi
|
||||
const auto depthBufferVulkan = static_cast<GPUTextureViewVulkan*>(depthBuffer);
|
||||
const auto rtCount = rtVulkan ? 1 : 0;
|
||||
|
||||
if (_rtDepth != depthBufferVulkan || _rtCount != rtCount || _rtHandles[0] != rtVulkan)
|
||||
if (_rtDepth != depthBufferVulkan || _rtCount != rtCount || _rtTargets[0] != rtVulkan)
|
||||
{
|
||||
_rtDirtyFlag = true;
|
||||
_psDirtyFlag = true;
|
||||
_rtCount = rtCount;
|
||||
_rtDepth = depthBufferVulkan;
|
||||
_rtHandles[0] = rtVulkan;
|
||||
_rtTargets[0] = rtVulkan;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1053,13 +1121,13 @@ void GPUContextVulkan::SetRenderTarget(GPUTextureView* depthBuffer, const Span<G
|
||||
}
|
||||
const int32 rtvsSize = sizeof(GPUTextureViewVulkan*) * rts.Length();
|
||||
|
||||
if (_rtDepth != depthBufferVulkan || _rtCount != rts.Length() || Platform::MemoryCompare(_rtHandles, rtvs, rtvsSize) != 0)
|
||||
if (_rtDepth != depthBufferVulkan || _rtCount != rts.Length() || Platform::MemoryCompare(_rtTargets, rtvs, rtvsSize) != 0)
|
||||
{
|
||||
_rtDirtyFlag = true;
|
||||
_psDirtyFlag = true;
|
||||
_rtCount = rts.Length();
|
||||
_rtDepth = depthBufferVulkan;
|
||||
Platform::MemoryCopy(_rtHandles, rtvs, rtvsSize);
|
||||
Platform::MemoryCopy(_rtTargets, rtvs, rtvsSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1486,11 +1554,7 @@ void GPUContextVulkan::FlushState()
|
||||
if (cmdBuffer->IsInsideRenderPass())
|
||||
EndRenderPass();
|
||||
|
||||
// Flush pending clears
|
||||
for (auto& clear : _pendingClears)
|
||||
ManualClear(clear);
|
||||
_pendingClears.Clear();
|
||||
|
||||
FlushManualClears();
|
||||
FlushBarriers();
|
||||
}
|
||||
|
||||
@@ -2012,7 +2076,7 @@ void GPUContextVulkan::BeginDrawPass(GPUDrawPass& pass)
|
||||
_drawPassCanClear = true;
|
||||
_rtCount = pass.RenderTargetsCount;
|
||||
_rtDepth = (GPUTextureViewVulkan*)pass.DepthBuffer;
|
||||
Platform::MemoryCopy(_rtHandles, pass.RenderTargets, pass.RenderTargetsCount * sizeof(void*));
|
||||
Platform::MemoryCopy(_rtTargets, pass.RenderTargets, pass.RenderTargetsCount * sizeof(void*));
|
||||
}
|
||||
|
||||
void GPUContextVulkan::EndDrawPass()
|
||||
|
||||
@@ -96,8 +96,15 @@ private:
|
||||
GPUPipelineStateVulkan* _currentState;
|
||||
GPUShaderProgramCSVulkan* _currentCompute;
|
||||
GPUVertexLayoutVulkan* _vertexLayout;
|
||||
GPUTextureViewVulkan* _rtDepth;
|
||||
GPUTextureViewVulkan* _rtHandles[GPU_MAX_RT_BINDED];
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
GPUTextureViewVulkan* _rtDepth;
|
||||
GPUTextureViewVulkan* _rtTargets[GPU_MAX_RT_BINDED];
|
||||
};
|
||||
GPUTextureViewVulkan* _rtHandles[GPU_MAX_RT_BINDED + 1];
|
||||
};
|
||||
DescriptorOwnerResourceVulkan* _cbHandles[GPU_MAX_CB_BINDED];
|
||||
DescriptorOwnerResourceVulkan* _srHandles[GPU_MAX_SR_BINDED];
|
||||
DescriptorOwnerResourceVulkan* _uaHandles[GPU_MAX_UA_BINDED];
|
||||
@@ -157,6 +164,7 @@ public:
|
||||
private:
|
||||
bool FindClear(const GPUTextureViewVulkan* view, PendingClear& clear);
|
||||
void ManualClear(const PendingClear& clear);
|
||||
void FlushManualClears();
|
||||
void UpdateDescriptorSets(const struct SpirvShaderDescriptorInfo& descriptorInfo, class DescriptorSetWriterVulkan& dsWriter, bool& needsWrite);
|
||||
void UpdateDescriptorSets(ComputePipelineStateVulkan* pipelineState);
|
||||
void OnDrawCall();
|
||||
|
||||
@@ -434,7 +434,7 @@ void GPUDeviceVulkan::GetInstanceLayersAndExtensions(Array<const char*>& outInst
|
||||
}
|
||||
}
|
||||
|
||||
void GPUDeviceVulkan::GetDeviceExtensionsAndLayers(VkPhysicalDevice gpu, Array<const char*>& outDeviceExtensions, Array<const char*>& outDeviceLayers)
|
||||
void GPUDeviceVulkan::GetDeviceExtensions(VkPhysicalDevice gpu, Array<const char*>& outDeviceExtensions)
|
||||
{
|
||||
Array<LayerExtension> deviceLayerExtensions;
|
||||
deviceLayerExtensions.AddDefault(1);
|
||||
@@ -495,70 +495,19 @@ void GPUDeviceVulkan::GetDeviceExtensionsAndLayers(VkPhysicalDevice gpu, Array<c
|
||||
{
|
||||
IsDebugToolAttached = true;
|
||||
}
|
||||
#if VULKAN_USE_DEBUG_LAYER
|
||||
bool hasKhronosStandardValidationLayer = false, hasLunargStandardValidationLayer = false;
|
||||
#if VULKAN_USE_KHRONOS_STANDARD_VALIDATION
|
||||
const char* vkLayerKhronosValidation = "VK_LAYER_KHRONOS_validation";
|
||||
hasKhronosStandardValidationLayer = ContainsLayer(deviceLayerExtensions, vkLayerKhronosValidation);
|
||||
if (hasKhronosStandardValidationLayer && _debugLayer)
|
||||
{
|
||||
outDeviceLayers.Add(vkLayerKhronosValidation);
|
||||
}
|
||||
#endif
|
||||
#if VULKAN_USE_LUNARG_STANDARD_VALIDATION
|
||||
if (!hasKhronosStandardValidationLayer && _debugLayer)
|
||||
{
|
||||
const char* vkLayerLunargStandardValidation = "VK_LAYER_LUNARG_standard_validation";
|
||||
hasLunargStandardValidationLayer = ContainsLayer(deviceLayerExtensions, vkLayerLunargStandardValidation);
|
||||
if (hasLunargStandardValidationLayer)
|
||||
{
|
||||
outDeviceLayers.Add(vkLayerLunargStandardValidation);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!hasKhronosStandardValidationLayer && !hasLunargStandardValidationLayer && _debugLayer)
|
||||
{
|
||||
for (uint32 i = 0; GValidationLayers[i] != nullptr; i++)
|
||||
{
|
||||
const char* validationLayer = GValidationLayers[i];
|
||||
if (ContainsLayer(deviceLayerExtensions, validationLayer))
|
||||
{
|
||||
outDeviceLayers.Add(validationLayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Find all extensions
|
||||
Array<const char*> availableExtensions;
|
||||
availableExtensions.Resize(deviceLayerExtensions[0].Extensions.Count());
|
||||
for (int32 i = 0; i < deviceLayerExtensions[0].Extensions.Count(); i++)
|
||||
{
|
||||
for (int32 i = 0; i < deviceLayerExtensions[0].Extensions.Count(); i++)
|
||||
{
|
||||
availableExtensions.Add(deviceLayerExtensions[0].Extensions[i].extensionName);
|
||||
}
|
||||
|
||||
for (int32 layerIndex = 0; layerIndex < outDeviceLayers.Count(); layerIndex++)
|
||||
{
|
||||
int32 findLayerIndex;
|
||||
for (findLayerIndex = 1; findLayerIndex < deviceLayerExtensions.Count(); findLayerIndex++)
|
||||
{
|
||||
if (!StringUtils::Compare(deviceLayerExtensions[findLayerIndex].Layer.layerName, outDeviceLayers[layerIndex]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (findLayerIndex < deviceLayerExtensions.Count())
|
||||
{
|
||||
deviceLayerExtensions[findLayerIndex].GetExtensions(availableExtensions);
|
||||
}
|
||||
}
|
||||
availableExtensions[i] = deviceLayerExtensions[0].Extensions[i].extensionName;
|
||||
}
|
||||
TrimDuplicates(availableExtensions);
|
||||
|
||||
// Pick extensions to use
|
||||
Array<const char*> platformExtensions;
|
||||
VulkanPlatform::GetDeviceExtensions(platformExtensions, outDeviceLayers);
|
||||
VulkanPlatform::GetDeviceExtensions(platformExtensions);
|
||||
for (const char* extension : platformExtensions)
|
||||
{
|
||||
if (ListContains(availableExtensions, extension))
|
||||
@@ -583,15 +532,6 @@ void GPUDeviceVulkan::GetDeviceExtensionsAndLayers(VkPhysicalDevice gpu, Array<c
|
||||
LOG(Info, "- {0}", String(extension));
|
||||
}
|
||||
}
|
||||
|
||||
if (outDeviceLayers.HasItems())
|
||||
{
|
||||
LOG(Info, "Using device layers:");
|
||||
for (const char* layer : outDeviceLayers)
|
||||
{
|
||||
LOG(Info, "- {0}", String(layer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GPUDeviceVulkan::ParseOptionalDeviceExtensions(const Array<const char*>& deviceExtensions)
|
||||
|
||||
@@ -130,6 +130,11 @@ static VKAPI_ATTR VkBool32 VKAPI_PTR DebugReportFunction(VkDebugReportFlagsEXT m
|
||||
|
||||
#if VK_EXT_debug_utils
|
||||
|
||||
#if GPU_ENABLE_DEBUG_LAYER
|
||||
#include "Engine/Threading/ThreadLocal.h"
|
||||
extern ThreadLocal<const GPUShaderProgramInitializer*> CurrentVulkanShaderLoading;
|
||||
#endif
|
||||
|
||||
static VKAPI_ATTR VkBool32 VKAPI_PTR DebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT msgSeverity, VkDebugUtilsMessageTypeFlagsEXT msgType, const VkDebugUtilsMessengerCallbackDataEXT* callbackData, void* userData)
|
||||
{
|
||||
// Ignore some errors
|
||||
@@ -149,6 +154,7 @@ static VKAPI_ATTR VkBool32 VKAPI_PTR DebugUtilsCallback(VkDebugUtilsMessageSever
|
||||
case -1539028524: // SortedIndices is null so Vulkan backend sets it to default R32_SFLOAT format which is not good for UINT format of the buffer
|
||||
case -1810835948: // SortedIndices is null so Vulkan backend sets it to default R32_SFLOAT format which is not good for UINT format of the buffer
|
||||
case -1621360350: // VkFramebufferCreateInfo attachment #0 has a layer count (1) smaller than the corresponding framebuffer layer count (64). The Vulkan spec states: If flags does not include VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, each element of pAttachments that is used as an input, color, resolve, or depth/stencil attachment by renderPass must have been created with a VkImageViewCreateInfo::subresourceRange.layerCount greater than or equal to layers
|
||||
case -1744492148: // pCreateInfos[0] Inside [VK_SHADER_STAGE_FRAGMENT_BIT], it writes to [Output variable, Location 3], but there is no VkSubpassDescription::pColorAttachments[3] and this write is unused.
|
||||
return VK_FALSE;
|
||||
}
|
||||
break;
|
||||
@@ -158,6 +164,7 @@ static VKAPI_ATTR VkBool32 VKAPI_PTR DebugUtilsCallback(VkDebugUtilsMessageSever
|
||||
case 0: // Vertex shader writes to output location 0.0 which is not consumed by fragment shader
|
||||
case 558591440: // preTransform doesn't match the currentTransform returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR, the presentation engine will transform the image content as part of the presentation operation. TODO: implement preTransform for Android to improve swapchain presentation performance
|
||||
case 101294395: // Vertex shader writes to output location 0.0 which is not consumed by fragment shader
|
||||
case -937765618: // pCreateInfos[0] (SPIR-V Interface) [VK_SHADER_STAGE_VERTEX_BIT] has an Output value declared at Location 1 Component 0, but there is no corresponding Input declared in [VK_SHADER_STAGE_FRAGMENT_BIT].
|
||||
return VK_FALSE;
|
||||
}
|
||||
break;
|
||||
@@ -240,10 +247,14 @@ static VKAPI_ATTR VkBool32 VKAPI_PTR DebugUtilsCallback(VkDebugUtilsMessageSever
|
||||
LOG(Info, "[Vulkan] {0} {1}:{2} {3}", type, severity, callbackData->messageIdNumber, message);
|
||||
}
|
||||
|
||||
#if !BUILD_RELEASE
|
||||
#if GPU_ENABLE_DEBUG_LAYER
|
||||
if (GPUDevice::Instance)
|
||||
{
|
||||
if (auto* context = (GPUContextVulkan*)GPUDevice::Instance->GetMainContext())
|
||||
if (auto* shaderInitializer = CurrentVulkanShaderLoading.Get())
|
||||
{
|
||||
LOG(Warning, "[Vulkan] Error during loading shader '{}' from '{}'", String(shaderInitializer->Name), String(shaderInitializer->Owner->GetName()));
|
||||
}
|
||||
else if (auto* context = (GPUContextVulkan*)GPUDevice::Instance->GetMainContext())
|
||||
{
|
||||
if (auto* state = (GPUPipelineStateVulkan*)context->GetState())
|
||||
{
|
||||
@@ -999,13 +1010,13 @@ GPUDeviceVulkan::GPUDeviceVulkan(ShaderProfile shaderProfile, GPUAdapterVulkan*
|
||||
GPUDevice* GPUDeviceVulkan::Create()
|
||||
{
|
||||
#if !USE_EDITOR && (PLATFORM_WINDOWS || PLATFORM_LINUX)
|
||||
auto settings = PlatformSettings::Get();
|
||||
if (!settings->SupportVulkan)
|
||||
{
|
||||
// Skip if there is no support
|
||||
LOG(Warning, "Cannot use Vulkan (support disabled).");
|
||||
return nullptr;
|
||||
}
|
||||
auto settings = PlatformSettings::Get();
|
||||
if (!settings->SupportVulkan)
|
||||
{
|
||||
// Skip if there is no support
|
||||
LOG(Warning, "Cannot use Vulkan (support disabled).");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
VkResult result;
|
||||
@@ -1225,10 +1236,19 @@ GPUDevice* GPUDeviceVulkan::Create()
|
||||
}
|
||||
}
|
||||
}
|
||||
ASSERT(adapters[selectedAdapterIndex].IsValid());
|
||||
GPUAdapterVulkan& selectedAdapter = adapters[selectedAdapterIndex];
|
||||
ASSERT(selectedAdapter.IsValid());
|
||||
if (VK_VERSION_MAJOR(selectedAdapter.GpuProps.apiVersion) < VK_VERSION_MAJOR(VULKAN_API_VERSION) || VK_VERSION_MINOR(selectedAdapter.GpuProps.apiVersion) < VK_VERSION_MINOR(VULKAN_API_VERSION))
|
||||
{
|
||||
#if PLATFORM_DESKTOP
|
||||
LOG(Fatal, "Failed to use GPU '{}' with Vulkan API {}.{} which is lower than required {}.{}.\nCheck your video driver version for update to the latest one.", selectedAdapter.Description, VK_VERSION_MAJOR(selectedAdapter.GpuProps.apiVersion), VK_VERSION_MINOR(selectedAdapter.GpuProps.apiVersion), VK_VERSION_MAJOR(VULKAN_API_VERSION), VK_VERSION_MINOR(VULKAN_API_VERSION));
|
||||
#else
|
||||
LOG(Fatal, "Failed to use GPU '{}' with Vulkan API {}.{} which is lower than required {}.{}.\nCheck your system for updates.", selectedAdapter.Description, VK_VERSION_MAJOR(selectedAdapter.GpuProps.apiVersion), VK_VERSION_MINOR(selectedAdapter.GpuProps.apiVersion), VK_VERSION_MAJOR(VULKAN_API_VERSION), VK_VERSION_MINOR(VULKAN_API_VERSION));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Create device
|
||||
auto device = New<GPUDeviceVulkan>(ShaderProfile::Vulkan_SM5, New<GPUAdapterVulkan>(adapters[selectedAdapterIndex]));
|
||||
auto device = New<GPUDeviceVulkan>(ShaderProfile::Vulkan_SM5, New<GPUAdapterVulkan>(selectedAdapter));
|
||||
if (device->Init())
|
||||
{
|
||||
LOG(Warning, "Graphics Device init failed");
|
||||
@@ -1616,8 +1636,7 @@ bool GPUDeviceVulkan::Init()
|
||||
|
||||
// Get extensions and layers
|
||||
Array<const char*> deviceExtensions;
|
||||
Array<const char*> validationLayers;
|
||||
GetDeviceExtensionsAndLayers(gpu, deviceExtensions, validationLayers);
|
||||
GetDeviceExtensions(gpu, deviceExtensions);
|
||||
ParseOptionalDeviceExtensions(deviceExtensions);
|
||||
|
||||
// Setup device info
|
||||
@@ -1625,8 +1644,6 @@ bool GPUDeviceVulkan::Init()
|
||||
RenderToolsVulkan::ZeroStruct(deviceInfo, VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
|
||||
deviceInfo.enabledExtensionCount = deviceExtensions.Count();
|
||||
deviceInfo.ppEnabledExtensionNames = deviceExtensions.Get();
|
||||
deviceInfo.enabledLayerCount = validationLayers.Count();
|
||||
deviceInfo.ppEnabledLayerNames = deviceInfo.enabledLayerCount > 0 ? validationLayers.Get() : nullptr;
|
||||
|
||||
// Setup queues info
|
||||
Array<VkDeviceQueueCreateInfo> queueFamilyInfos;
|
||||
@@ -1769,7 +1786,7 @@ bool GPUDeviceVulkan::Init()
|
||||
limits.HasInstancing = true;
|
||||
limits.HasVolumeTextureRendering = true;
|
||||
limits.HasDrawIndirect = PhysicalDeviceLimits.maxDrawIndirectCount >= 1;
|
||||
limits.HasAppendConsumeBuffers = false; // TODO: add Append Consume buffers support for Vulkan
|
||||
limits.HasAppendConsumeBuffers = false;
|
||||
limits.HasDepthClip = PhysicalDeviceFeatures.depthClamp;
|
||||
limits.HasDepthBounds = PhysicalDeviceFeatures.depthBounds;
|
||||
limits.HasDepthAsSRV = true;
|
||||
@@ -1877,7 +1894,9 @@ bool GPUDeviceVulkan::Init()
|
||||
// Initialize memory allocator
|
||||
{
|
||||
VmaVulkanFunctions vulkanFunctions;
|
||||
Platform::MemoryClear(&vulkanFunctions, sizeof(vulkanFunctions));
|
||||
#define INIT_FUNC(name) vulkanFunctions.name = name
|
||||
#define INIT_FUNC_EXTENSION(name, extension) vulkanFunctions.name = name; if (!vulkanFunctions.name) vulkanFunctions.name = extension
|
||||
INIT_FUNC(vkGetPhysicalDeviceProperties);
|
||||
INIT_FUNC(vkGetPhysicalDeviceMemoryProperties);
|
||||
INIT_FUNC(vkAllocateMemory);
|
||||
@@ -1895,16 +1914,28 @@ bool GPUDeviceVulkan::Init()
|
||||
INIT_FUNC(vkCreateImage);
|
||||
INIT_FUNC(vkDestroyImage);
|
||||
INIT_FUNC(vkCmdCopyBuffer);
|
||||
#if VMA_DEDICATED_ALLOCATION
|
||||
#if PLATFORM_SWITCH
|
||||
vulkanFunctions.vkGetBufferMemoryRequirements2KHR = vkGetBufferMemoryRequirements2;
|
||||
vulkanFunctions.vkGetImageMemoryRequirements2KHR = vkGetImageMemoryRequirements2;
|
||||
#else
|
||||
INIT_FUNC(vkGetBufferMemoryRequirements2KHR);
|
||||
INIT_FUNC(vkGetImageMemoryRequirements2KHR);
|
||||
#if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000
|
||||
INIT_FUNC_EXTENSION(vkGetBufferMemoryRequirements2KHR, vkGetBufferMemoryRequirements2);
|
||||
INIT_FUNC_EXTENSION(vkGetImageMemoryRequirements2KHR, vkGetImageMemoryRequirements2);
|
||||
#endif
|
||||
#if VMA_BIND_MEMORY2 || VMA_VULKAN_VERSION >= 1001000
|
||||
INIT_FUNC_EXTENSION(vkBindBufferMemory2KHR, vkBindBufferMemory2);
|
||||
INIT_FUNC_EXTENSION(vkBindImageMemory2KHR, vkBindImageMemory2);
|
||||
#endif
|
||||
#if VMA_MEMORY_BUDGET || VMA_VULKAN_VERSION >= 1001000
|
||||
INIT_FUNC_EXTENSION(vkGetPhysicalDeviceMemoryProperties2KHR, vkGetPhysicalDeviceMemoryProperties2);
|
||||
#endif
|
||||
#if VMA_KHR_MAINTENANCE4 || VMA_VULKAN_VERSION >= 1003000
|
||||
INIT_FUNC_EXTENSION(vkGetDeviceBufferMemoryRequirements, vkGetDeviceBufferMemoryRequirementsKHR);
|
||||
INIT_FUNC_EXTENSION(vkGetDeviceImageMemoryRequirements, vkGetDeviceImageMemoryRequirementsKHR);
|
||||
#endif
|
||||
#endif
|
||||
#undef INIT_FUNC
|
||||
#undef INIT_FUNC_EXTENSION
|
||||
VmaAllocatorCreateInfo allocatorInfo = {};
|
||||
allocatorInfo.vulkanApiVersion = VULKAN_API_VERSION;
|
||||
allocatorInfo.physicalDevice = gpu;
|
||||
|
||||
@@ -396,7 +396,7 @@ public:
|
||||
|
||||
private:
|
||||
static void GetInstanceLayersAndExtensions(Array<const char*>& outInstanceExtensions, Array<const char*>& outInstanceLayers, bool& outDebugUtils, bool useDebugLayer = false);
|
||||
void GetDeviceExtensionsAndLayers(VkPhysicalDevice gpu, Array<const char*>& outDeviceExtensions, Array<const char*>& outDeviceLayers);
|
||||
void GetDeviceExtensions(VkPhysicalDevice gpu, Array<const char*>& outDeviceExtensions);
|
||||
static void ParseOptionalDeviceExtensions(const Array<const char*>& deviceExtensions);
|
||||
|
||||
public:
|
||||
|
||||
@@ -101,6 +101,11 @@ void UniformBufferUploaderVulkan::OnReleaseGPU()
|
||||
}
|
||||
}
|
||||
|
||||
#if GPU_ENABLE_DEBUG_LAYER
|
||||
#include "Engine/Threading/ThreadLocal.h"
|
||||
ThreadLocal<const GPUShaderProgramInitializer*> CurrentVulkanShaderLoading;
|
||||
#endif
|
||||
|
||||
GPUShaderProgram* GPUShaderVulkan::CreateGPUShaderProgram(ShaderStage type, const GPUShaderProgramInitializer& initializer, Span<byte> bytecode, MemoryReadStream& stream)
|
||||
{
|
||||
// Extract the SPIR-V shader header from the cache
|
||||
@@ -146,8 +151,14 @@ GPUShaderProgram* GPUShaderVulkan::CreateGPUShaderProgram(ShaderStage type, cons
|
||||
validationInfo.validationCache = _device->ValidationCache;
|
||||
createInfo.pNext = &validationInfo;
|
||||
}
|
||||
#endif
|
||||
#if GPU_ENABLE_DEBUG_LAYER
|
||||
CurrentVulkanShaderLoading = &initializer;
|
||||
#endif
|
||||
VALIDATE_VULKAN_RESULT(vkCreateShaderModule(_device->Device, &createInfo, nullptr, &shaderModule));
|
||||
#if GPU_ENABLE_DEBUG_LAYER
|
||||
CurrentVulkanShaderLoading = nullptr;
|
||||
#endif
|
||||
#if GPU_ENABLE_RESOURCE_NAMING
|
||||
VK_SET_DEBUG_NAME(_device, shaderModule, VK_OBJECT_TYPE_SHADER_MODULE, initializer.Name.GetText());
|
||||
#endif
|
||||
|
||||
@@ -94,6 +94,11 @@ void GPUTextureViewVulkan::Init(GPUDeviceVulkan* device, ResourceOwnerVulkan* ow
|
||||
}
|
||||
|
||||
VALIDATE_VULKAN_RESULT(vkCreateImageView(device->Device, &Info, nullptr, &View));
|
||||
|
||||
#if VK_KHR_maintenance1
|
||||
if (arraySize == 1 && extent.depth > 1)
|
||||
range.layerCount = VK_REMAINING_ARRAY_LAYERS; // without maintenance9 for per-layer masking all layers need to be enabled with a special value
|
||||
#endif
|
||||
}
|
||||
|
||||
VkImageView GPUTextureViewVulkan::GetFramebufferView()
|
||||
@@ -119,6 +124,7 @@ VkImageView GPUTextureViewVulkan::GetFramebufferView()
|
||||
// Use an additional view for that case with modified level count to 1.
|
||||
VkImageViewCreateInfo createInfo = Info;
|
||||
createInfo.subresourceRange.levelCount = 1;
|
||||
createInfo.subresourceRange.layerCount = 1;
|
||||
VALIDATE_VULKAN_RESULT(vkCreateImageView(Device->Device, &createInfo, nullptr, &ViewFramebuffer));
|
||||
}
|
||||
else
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
static void GetDeviceExtensions(Array<const char*>& extensions, Array<const char*>& layers)
|
||||
static void GetDeviceExtensions(Array<const char*>& extensions)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#if GRAPHICS_API_VULKAN && PLATFORM_WIN32
|
||||
|
||||
#define VULKAN_API_VERSION VK_API_VERSION_1_2
|
||||
#define VULKAN_USE_PLATFORM_WIN32_KHR 1
|
||||
#define VULKAN_USE_PLATFORM_WIN32_KHX 1
|
||||
#define VULKAN_USE_CREATE_WIN32_SURFACE 1
|
||||
|
||||
@@ -189,12 +189,9 @@ void GBufferPass::Fill(RenderContext& renderContext, GPUTexture* lightBuffer)
|
||||
context->Clear(renderContext.Buffers->GBuffer3->View(), Color::Transparent);
|
||||
}
|
||||
|
||||
// Ensure to have valid data
|
||||
// Skip when resources are not loaded yet
|
||||
if (checkIfSkipPass())
|
||||
{
|
||||
// Resources are missing. Do not perform rendering.
|
||||
return;
|
||||
}
|
||||
|
||||
#if USE_EDITOR
|
||||
// Special debug drawing
|
||||
|
||||
@@ -945,13 +945,45 @@ bool ShaderCompilerVulkan::OnCompileBegin()
|
||||
|
||||
void ShaderCompilerVulkan::InitParsing(ShaderCompilationContext* context, glslang::TShader& shader)
|
||||
{
|
||||
// Pick Vulkan version based on target platform
|
||||
// Based on: https://docs.vulkan.org/guide/latest/versions.html#_spir_v
|
||||
glslang::EShTargetClientVersion targetVulkan;
|
||||
glslang::EShTargetLanguageVersion targetLang;
|
||||
switch (context->Options->Platform)
|
||||
{
|
||||
case PlatformType::Windows:
|
||||
// TODO: update glslang and try Vulkan 1.2 with SPIR-V 1.5
|
||||
targetVulkan = glslang::EShTargetVulkan_1_1;
|
||||
targetLang = glslang::EShTargetSpv_1_2;
|
||||
break;
|
||||
case PlatformType::Android:
|
||||
targetVulkan = glslang::EShTargetVulkan_1_1;
|
||||
targetLang = glslang::EShTargetSpv_1_2;
|
||||
break;
|
||||
case PlatformType::Switch:
|
||||
// TODO: update glslang and try Vulkan 1.3 with SPIR-V 1.6
|
||||
targetVulkan = glslang::EShTargetVulkan_1_1;
|
||||
targetLang = glslang::EShTargetSpv_1_2;
|
||||
break;
|
||||
case PlatformType::Mac:
|
||||
case PlatformType::iOS:
|
||||
// TODO: update glslang and try Vulkan 1.4 with SPIR-V 1.6
|
||||
targetVulkan = glslang::EShTargetVulkan_1_1;
|
||||
targetLang = glslang::EShTargetSpv_1_2;
|
||||
break;
|
||||
default:
|
||||
targetVulkan = glslang::EShTargetVulkan_1_0;
|
||||
targetLang = glslang::EShTargetSpv_1_0;
|
||||
break;
|
||||
}
|
||||
|
||||
shader.setInvertY(true);
|
||||
//shader.setAutoMapLocations(true);
|
||||
//shader.setAutoMapBindings(true);
|
||||
//shader.setShiftBinding(glslang::TResourceType::EResUav, 500);
|
||||
shader.setHlslIoMapping(true);
|
||||
shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_0);
|
||||
shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_0);
|
||||
shader.setEnvClient(glslang::EShClientVulkan, targetVulkan);
|
||||
shader.setEnvTarget(glslang::EShTargetSpv, targetLang);
|
||||
}
|
||||
|
||||
void ShaderCompilerVulkan::InitCodegen(ShaderCompilationContext* context, glslang::SpvOptions& spvOptions)
|
||||
|
||||
@@ -54,6 +54,12 @@ public:
|
||||
GetBucket().Value = value;
|
||||
}
|
||||
|
||||
FORCE_INLINE ThreadLocal& operator=(const T& value)
|
||||
{
|
||||
GetBucket().Value = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
int32 Count() const
|
||||
{
|
||||
int32 result = 0;
|
||||
|
||||
Reference in New Issue
Block a user