@@ -145,6 +145,11 @@ MaterialShader* MaterialShader::CreateDummy(MemoryReadStream& shaderCacheStream,
|
||||
return material;
|
||||
}
|
||||
|
||||
GPUShader* MaterialShader::GetShader() const
|
||||
{
|
||||
return _shader;
|
||||
}
|
||||
|
||||
const MaterialInfo& MaterialShader::GetInfo() const
|
||||
{
|
||||
return _info;
|
||||
|
||||
@@ -100,6 +100,8 @@ public:
|
||||
/// <returns>The created and loaded material or null if failed.</returns>
|
||||
static MaterialShader* CreateDummy(MemoryReadStream& shaderCacheStream, const MaterialInfo& info);
|
||||
|
||||
GPUShader* GetShader() const;
|
||||
|
||||
/// <summary>
|
||||
/// Clears the loaded data.
|
||||
/// </summary>
|
||||
|
||||
@@ -82,6 +82,9 @@ bool GPUShader::Create(MemoryReadStream& stream)
|
||||
int32 shadersCount;
|
||||
stream.ReadInt32(&shadersCount);
|
||||
GPUShaderProgramInitializer initializer;
|
||||
#if !BUILD_RELEASE
|
||||
initializer.Owner = this;
|
||||
#endif
|
||||
for (int32 i = 0; i < shadersCount; i++)
|
||||
{
|
||||
const ShaderStage type = static_cast<ShaderStage>(stream.ReadByte());
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include "Engine/Core/Types/String.h"
|
||||
#include "Config.h"
|
||||
|
||||
class GPUShader;
|
||||
|
||||
/// <summary>
|
||||
/// The shader program metadata container. Contains description about resources used by the shader.
|
||||
/// </summary>
|
||||
@@ -37,6 +39,9 @@ struct GPUShaderProgramInitializer
|
||||
StringAnsi Name;
|
||||
ShaderBindings Bindings;
|
||||
ShaderFlags Flags;
|
||||
#if !BUILD_RELEASE
|
||||
GPUShader* Owner;
|
||||
#endif
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -49,12 +54,18 @@ protected:
|
||||
StringAnsi _name;
|
||||
ShaderBindings _bindings;
|
||||
ShaderFlags _flags;
|
||||
#if !BUILD_RELEASE
|
||||
GPUShader* _owner;
|
||||
#endif
|
||||
|
||||
void Init(const GPUShaderProgramInitializer& initializer)
|
||||
{
|
||||
_name = initializer.Name;
|
||||
_bindings = initializer.Bindings;
|
||||
_flags = initializer.Flags;
|
||||
#if !BUILD_RELEASE
|
||||
_owner = initializer.Owner;
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -69,9 +80,8 @@ public:
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Gets name of the shader program
|
||||
/// Gets name of the shader program.
|
||||
/// </summary>
|
||||
/// <returns>Name</returns>
|
||||
FORCE_INLINE const StringAnsi& GetName() const
|
||||
{
|
||||
return _name;
|
||||
@@ -80,7 +90,6 @@ public:
|
||||
/// <summary>
|
||||
/// Gets the shader resource bindings.
|
||||
/// </summary>
|
||||
/// <returns>The bindings.</returns>
|
||||
FORCE_INLINE const ShaderBindings& GetBindings() const
|
||||
{
|
||||
return _bindings;
|
||||
@@ -89,7 +98,6 @@ public:
|
||||
/// <summary>
|
||||
/// Gets the shader flags.
|
||||
/// </summary>
|
||||
/// <returns>The flags.</returns>
|
||||
FORCE_INLINE ShaderFlags GetFlags() const
|
||||
{
|
||||
return _flags;
|
||||
@@ -98,21 +106,18 @@ public:
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Gets shader program stage type
|
||||
/// Gets shader program stage type.
|
||||
/// </summary>
|
||||
/// <returns>Shader Stage type</returns>
|
||||
virtual ShaderStage GetStage() const = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets buffer handle (platform dependent)
|
||||
/// Gets buffer handle (platform dependent).
|
||||
/// </summary>
|
||||
/// <returns>Handle</returns>
|
||||
virtual void* GetBufferHandle() const = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets buffer size (in bytes)
|
||||
/// Gets buffer size (in bytes).
|
||||
/// </summary>
|
||||
/// <returns>Size of the buffer in bytes</returns>
|
||||
virtual uint32 GetBufferSize() const = 0;
|
||||
};
|
||||
|
||||
@@ -124,15 +129,13 @@ class GPUShaderProgramVS : public GPUShaderProgram
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Gets input layout description handle (platform dependent)
|
||||
/// Gets input layout description handle (platform dependent).
|
||||
/// </summary>
|
||||
/// <returns>Input layout</returns>
|
||||
virtual void* GetInputLayout() const = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets input layout description size (in bytes)
|
||||
/// Gets input layout description size (in bytes).
|
||||
/// </summary>
|
||||
/// <returns>Input layout description size in bytes</returns>
|
||||
virtual byte GetInputLayoutSize() const = 0;
|
||||
|
||||
public:
|
||||
|
||||
@@ -346,7 +346,6 @@ void GPUContextVulkan::BeginRenderPass()
|
||||
{
|
||||
layout.RTVsFormats[i] = handle->GetFormat();
|
||||
framebufferKey.Attachments[i] = handle->GetFramebufferView();
|
||||
|
||||
AddImageBarrier(handle, handle->LayoutRTV);
|
||||
}
|
||||
else
|
||||
@@ -355,36 +354,31 @@ void GPUContextVulkan::BeginRenderPass()
|
||||
framebufferKey.Attachments[i] = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
GPUTextureViewVulkan* handle;
|
||||
if (_rtDepth)
|
||||
{
|
||||
auto handle = _rtDepth;
|
||||
layout.MSAA = handle->GetMSAA();
|
||||
layout.Extent = handle->Extent;
|
||||
handle = _rtDepth;
|
||||
layout.ReadDepth = true; // TODO: use proper depthStencilAccess flags
|
||||
layout.WriteDepth = handle->LayoutRTV == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; // TODO: do it in a proper way
|
||||
framebufferKey.AttachmentCount++;
|
||||
framebufferKey.Attachments[_rtCount] = handle->GetFramebufferView();
|
||||
|
||||
AddImageBarrier(handle, handle->LayoutRTV);
|
||||
}
|
||||
else if (_rtHandles[0])
|
||||
{
|
||||
layout.MSAA = _rtHandles[0]->GetMSAA();
|
||||
layout.Extent = _rtHandles[0]->Extent;
|
||||
layout.ReadDepth = false;
|
||||
layout.WriteDepth = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No depth or render target binded?
|
||||
CRASH;
|
||||
handle = _rtHandles[0];
|
||||
layout.ReadDepth = false;
|
||||
layout.WriteDepth = false;
|
||||
}
|
||||
layout.MSAA = handle->GetMSAA();
|
||||
layout.Extent.width = handle->Extent.width;
|
||||
layout.Extent.height = handle->Extent.height;
|
||||
layout.Layers = handle->Layers;
|
||||
|
||||
// Get or create objects
|
||||
auto renderPass = _device->GetOrCreateRenderPass(layout);
|
||||
framebufferKey.RenderPass = renderPass;
|
||||
uint32 layers = 1; // TODO: support rendering to many layers (eg. texture array)
|
||||
auto framebuffer = _device->GetOrCreateFramebuffer(framebufferKey, layout.Extent, layers);
|
||||
auto framebuffer = _device->GetOrCreateFramebuffer(framebufferKey, layout.Extent, layout.Layers);
|
||||
_renderPass = renderPass;
|
||||
|
||||
FlushBarriers();
|
||||
@@ -519,7 +513,7 @@ void GPUContextVulkan::UpdateDescriptorSets(const SpirvShaderDescriptorInfo& des
|
||||
}
|
||||
default:
|
||||
// Unknown or invalid descriptor type
|
||||
CRASH;
|
||||
CRASH;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,6 @@ static VKAPI_ATTR VkBool32 VKAPI_PTR DebugReportFunction(VkDebugReportFlagsEXT m
|
||||
if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT)
|
||||
{
|
||||
msgPrefix = TEXT("ERROR");
|
||||
|
||||
if (!StringUtils::Compare(layerPrefix, "SC"))
|
||||
{
|
||||
if (msgCode == 3)
|
||||
@@ -79,7 +78,6 @@ static VKAPI_ATTR VkBool32 VKAPI_PTR DebugReportFunction(VkDebugReportFlagsEXT m
|
||||
else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT)
|
||||
{
|
||||
msgPrefix = TEXT("WARN");
|
||||
|
||||
if (!StringUtils::Compare(layerPrefix, "SC"))
|
||||
{
|
||||
if (msgCode == 2)
|
||||
@@ -92,7 +90,6 @@ static VKAPI_ATTR VkBool32 VKAPI_PTR DebugReportFunction(VkDebugReportFlagsEXT m
|
||||
else if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)
|
||||
{
|
||||
msgPrefix = TEXT("PERF");
|
||||
|
||||
if (!StringUtils::Compare(layerPrefix, "SC"))
|
||||
{
|
||||
if (msgCode == 2)
|
||||
@@ -118,14 +115,8 @@ static VKAPI_ATTR VkBool32 VKAPI_PTR DebugReportFunction(VkDebugReportFlagsEXT m
|
||||
{
|
||||
msgPrefix = TEXT("DEBUG");
|
||||
}
|
||||
else
|
||||
{
|
||||
CRASH;
|
||||
}
|
||||
|
||||
// Send info
|
||||
LOG(Info, "[Vulkan] {0}:{1}:{2} {3}", msgPrefix, String(layerPrefix), msgCode, String(msg));
|
||||
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
@@ -147,6 +138,9 @@ static VKAPI_ATTR VkBool32 VKAPI_PTR DebugUtilsCallback(VkDebugUtilsMessageSever
|
||||
case 5: // SPIR-V module not valid: MemoryBarrier: Vulkan specification requires Memory Semantics to have one of the following bits set: Acquire, Release, AcquireRelease or SequentiallyConsistent
|
||||
case -1666394502: // After query pool creation, each query must be reset before it is used. Queries must also be reset between uses.
|
||||
case 602160055: // Attachment 4 not written by fragment shader; undefined values will be written to attachment. TODO: investigate it for PS_GBuffer shader from Deferred material with USE_LIGHTMAP=1
|
||||
case 7060244: // Image Operand Offset can only be used with OpImage*Gather operations
|
||||
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
|
||||
return VK_FALSE;
|
||||
}
|
||||
break;
|
||||
@@ -214,15 +208,10 @@ static VKAPI_ATTR VkBool32 VKAPI_PTR DebugUtilsCallback(VkDebugUtilsMessageSever
|
||||
type = TEXT("Perf");
|
||||
}
|
||||
|
||||
// Send info
|
||||
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));
|
||||
}
|
||||
|
||||
return VK_FALSE;
|
||||
}
|
||||
@@ -440,10 +429,11 @@ uint32 GetHash(const RenderTargetLayoutVulkan& key)
|
||||
CombineHash(hash, (uint32)key.WriteDepth);
|
||||
CombineHash(hash, (uint32)key.DepthFormat * 93473262);
|
||||
CombineHash(hash, key.RTsCount * 136);
|
||||
CombineHash(hash, key.Extent.width);
|
||||
CombineHash(hash, key.Extent.height);
|
||||
CombineHash(hash, key.Layers);
|
||||
for (int32 i = 0; i < ARRAY_COUNT(key.RTVsFormats); i++)
|
||||
{
|
||||
CombineHash(hash, (uint32)key.RTVsFormats[i]);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
@@ -452,13 +442,11 @@ uint32 GetHash(const FramebufferVulkan::Key& key)
|
||||
uint32 hash = (int32)(intptr)key.RenderPass;
|
||||
CombineHash(hash, (uint32)key.AttachmentCount * 136);
|
||||
for (int32 i = 0; i < ARRAY_COUNT(key.Attachments); i++)
|
||||
{
|
||||
CombineHash(hash, (uint32)(intptr)key.Attachments[i]);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
FramebufferVulkan::FramebufferVulkan(GPUDeviceVulkan* device, Key& key, VkExtent3D& extent, uint32 layers)
|
||||
FramebufferVulkan::FramebufferVulkan(GPUDeviceVulkan* device, Key& key, VkExtent2D& extent, uint32 layers)
|
||||
: _device(device)
|
||||
, _handle(VK_NULL_HANDLE)
|
||||
, Extent(extent)
|
||||
@@ -1271,33 +1259,23 @@ GPUDeviceVulkan::~GPUDeviceVulkan()
|
||||
|
||||
RenderPassVulkan* GPUDeviceVulkan::GetOrCreateRenderPass(RenderTargetLayoutVulkan& layout)
|
||||
{
|
||||
// Try reuse cached version
|
||||
RenderPassVulkan* renderPass;
|
||||
if (_renderPasses.TryGet(layout, renderPass))
|
||||
{
|
||||
return renderPass;
|
||||
}
|
||||
|
||||
PROFILE_CPU_NAMED("Create Render Pass");
|
||||
|
||||
// Create object and cache it
|
||||
renderPass = New<RenderPassVulkan>(this, layout);
|
||||
_renderPasses.Add(layout, renderPass);
|
||||
return renderPass;
|
||||
}
|
||||
|
||||
FramebufferVulkan* GPUDeviceVulkan::GetOrCreateFramebuffer(FramebufferVulkan::Key& key, VkExtent3D& extent, uint32 layers)
|
||||
FramebufferVulkan* GPUDeviceVulkan::GetOrCreateFramebuffer(FramebufferVulkan::Key& key, VkExtent2D& extent, uint32 layers)
|
||||
{
|
||||
// Try reuse cached version
|
||||
FramebufferVulkan* framebuffer;
|
||||
if (_framebuffers.TryGet(key, framebuffer))
|
||||
{
|
||||
return framebuffer;
|
||||
}
|
||||
|
||||
PROFILE_CPU_NAMED("Create Framebuffer");
|
||||
|
||||
// Create object and cache it
|
||||
framebuffer = New<FramebufferVulkan>(this, key, extent, layers);
|
||||
_framebuffers.Add(key, framebuffer);
|
||||
return framebuffer;
|
||||
@@ -1305,16 +1283,11 @@ FramebufferVulkan* GPUDeviceVulkan::GetOrCreateFramebuffer(FramebufferVulkan::Ke
|
||||
|
||||
PipelineLayoutVulkan* GPUDeviceVulkan::GetOrCreateLayout(DescriptorSetLayoutInfoVulkan& key)
|
||||
{
|
||||
// Try reuse cached version
|
||||
PipelineLayoutVulkan* layout;
|
||||
if (_layouts.TryGet(key, layout))
|
||||
{
|
||||
return layout;
|
||||
}
|
||||
|
||||
PROFILE_CPU_NAMED("Create Pipeline Layout");
|
||||
|
||||
// Create object and cache it
|
||||
layout = New<PipelineLayoutVulkan>(this, key);
|
||||
_layouts.Add(key, layout);
|
||||
return layout;
|
||||
@@ -1698,7 +1671,11 @@ bool GPUDeviceVulkan::Init()
|
||||
auto& limits = Limits;
|
||||
limits.HasCompute = GetShaderProfile() == ShaderProfile::Vulkan_SM5 && PhysicalDeviceLimits.maxComputeWorkGroupCount[0] >= GPU_MAX_CS_DISPATCH_THREAD_GROUPS && PhysicalDeviceLimits.maxComputeWorkGroupCount[1] >= GPU_MAX_CS_DISPATCH_THREAD_GROUPS;
|
||||
limits.HasTessellation = !!PhysicalDeviceFeatures.tessellationShader && PhysicalDeviceLimits.maxBoundDescriptorSets > (uint32_t)DescriptorSet::Domain;
|
||||
limits.HasGeometryShaders = false; // TODO: add geometry shaders support for Vulkan
|
||||
#if PLATFORM_ANDROID
|
||||
limits.HasGeometryShaders = false; // Don't even try GS on mobile
|
||||
#else
|
||||
limits.HasGeometryShaders = !!PhysicalDeviceFeatures.geometryShader;
|
||||
#endif
|
||||
limits.HasInstancing = true;
|
||||
limits.HasVolumeTextureRendering = true;
|
||||
limits.HasDrawIndirect = PhysicalDeviceLimits.maxDrawIndirectCount >= 1;
|
||||
|
||||
@@ -237,13 +237,14 @@ public:
|
||||
bool WriteDepth;
|
||||
PixelFormat DepthFormat;
|
||||
PixelFormat RTVsFormats[GPU_MAX_RT_BINDED];
|
||||
VkExtent3D Extent;
|
||||
VkExtent2D Extent;
|
||||
uint32 Layers;
|
||||
|
||||
public:
|
||||
|
||||
bool operator==(const RenderTargetLayoutVulkan& other) const
|
||||
{
|
||||
return Platform::MemoryCompare((void*)this, &other, sizeof(RenderTargetLayoutVulkan)) == 0;
|
||||
return Platform::MemoryCompare(this, &other, sizeof(RenderTargetLayoutVulkan)) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -263,7 +264,7 @@ public:
|
||||
|
||||
bool operator==(const Key& other) const
|
||||
{
|
||||
return Platform::MemoryCompare((void*)this, &other, sizeof(Key)) == 0;
|
||||
return Platform::MemoryCompare(this, &other, sizeof(Key)) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -274,13 +275,13 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
FramebufferVulkan(GPUDeviceVulkan* device, Key& key, VkExtent3D& extent, uint32 layers);
|
||||
FramebufferVulkan(GPUDeviceVulkan* device, Key& key, VkExtent2D& extent, uint32 layers);
|
||||
~FramebufferVulkan();
|
||||
|
||||
public:
|
||||
|
||||
VkImageView Attachments[GPU_MAX_RT_BINDED + 1];
|
||||
VkExtent3D Extent;
|
||||
VkExtent2D Extent;
|
||||
uint32 Layers;
|
||||
|
||||
public:
|
||||
@@ -498,8 +499,6 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
// Create new graphics device (returns Vulkan if failed)
|
||||
// @returns Created device or Vulkan
|
||||
static GPUDevice* Create();
|
||||
|
||||
/// <summary>
|
||||
@@ -685,7 +684,7 @@ public:
|
||||
}
|
||||
|
||||
RenderPassVulkan* GetOrCreateRenderPass(RenderTargetLayoutVulkan& layout);
|
||||
FramebufferVulkan* GetOrCreateFramebuffer(FramebufferVulkan::Key& key, VkExtent3D& extent, uint32 layers);
|
||||
FramebufferVulkan* GetOrCreateFramebuffer(FramebufferVulkan::Key& key, VkExtent2D& extent, uint32 layers);
|
||||
PipelineLayoutVulkan* GetOrCreateLayout(DescriptorSetLayoutInfoVulkan& key);
|
||||
void OnImageViewDestroy(VkImageView imageView);
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ void GPUTextureViewVulkan::Init(GPUDeviceVulkan* device, ResourceOwnerVulkan* ow
|
||||
Extent.width = Math::Max<uint32_t>(1, extent.width >> firstMipIndex);
|
||||
Extent.height = Math::Max<uint32_t>(1, extent.height >> firstMipIndex);
|
||||
Extent.depth = Math::Max<uint32_t>(1, extent.depth >> firstMipIndex);
|
||||
Layers = arraySize;
|
||||
|
||||
RenderToolsVulkan::ZeroStruct(Info, VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO);
|
||||
Info.image = image;
|
||||
@@ -74,16 +75,30 @@ VkImageView GPUTextureViewVulkan::GetFramebufferView()
|
||||
if (ViewFramebuffer)
|
||||
return ViewFramebuffer;
|
||||
|
||||
if (Info.subresourceRange.levelCount == 1)
|
||||
return View;
|
||||
|
||||
// Special case:
|
||||
// Render Target Handle can be created for full texture including its mip maps but framebuffer image view can use only a single surface
|
||||
// Use an additional view for that case with modified level count to 1.
|
||||
|
||||
VkImageViewCreateInfo createInfo = Info;
|
||||
createInfo.subresourceRange.levelCount = 1;
|
||||
VALIDATE_VULKAN_RESULT(vkCreateImageView(Device->Device, &createInfo, nullptr, &ViewFramebuffer));
|
||||
if (Info.viewType == VK_IMAGE_VIEW_TYPE_3D)
|
||||
{
|
||||
// Special case:
|
||||
// Render Target Handle to a 3D Volume texture.
|
||||
// Use it as Texture2D Array with layers.
|
||||
VkImageViewCreateInfo createInfo = Info;
|
||||
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||
createInfo.subresourceRange.layerCount = Extent.depth;
|
||||
Layers = Extent.depth;
|
||||
VALIDATE_VULKAN_RESULT(vkCreateImageView(Device->Device, &createInfo, nullptr, &ViewFramebuffer));
|
||||
}
|
||||
else if (Info.subresourceRange.levelCount != 1)
|
||||
{
|
||||
// Special case:
|
||||
// Render Target Handle can be created for full texture including its mip maps but framebuffer image view can use only a single surface
|
||||
// Use an additional view for that case with modified level count to 1.
|
||||
VkImageViewCreateInfo createInfo = Info;
|
||||
createInfo.subresourceRange.levelCount = 1;
|
||||
VALIDATE_VULKAN_RESULT(vkCreateImageView(Device->Device, &createInfo, nullptr, &ViewFramebuffer));
|
||||
}
|
||||
else
|
||||
{
|
||||
ViewFramebuffer = View;
|
||||
}
|
||||
|
||||
return ViewFramebuffer;
|
||||
}
|
||||
@@ -92,15 +107,15 @@ void GPUTextureViewVulkan::Release()
|
||||
{
|
||||
if (View != VK_NULL_HANDLE)
|
||||
{
|
||||
Device->OnImageViewDestroy(View);
|
||||
Device->DeferredDeletionQueue.EnqueueResource(DeferredDeletionQueueVulkan::Type::ImageView, View);
|
||||
|
||||
if (ViewFramebuffer != VK_NULL_HANDLE)
|
||||
if (ViewFramebuffer != View && ViewFramebuffer != VK_NULL_HANDLE)
|
||||
{
|
||||
Device->OnImageViewDestroy(ViewFramebuffer);
|
||||
Device->DeferredDeletionQueue.EnqueueResource(DeferredDeletionQueueVulkan::Type::ImageView, ViewFramebuffer);
|
||||
}
|
||||
|
||||
Device->OnImageViewDestroy(View);
|
||||
Device->DeferredDeletionQueue.EnqueueResource(DeferredDeletionQueueVulkan::Type::ImageView, View);
|
||||
|
||||
View = VK_NULL_HANDLE;
|
||||
ViewFramebuffer = VK_NULL_HANDLE;
|
||||
|
||||
@@ -236,32 +251,20 @@ bool GPUTextureVulkan::OnInit()
|
||||
imageInfo.extent.depth = Depth();
|
||||
imageInfo.flags = IsCubeMap() ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
|
||||
if (IsSRGB())
|
||||
{
|
||||
imageInfo.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
|
||||
}
|
||||
#if VK_KHR_maintenance1
|
||||
if (_device->OptionalDeviceExtensions.HasKHRMaintenance1 && imageInfo.imageType == VK_IMAGE_TYPE_3D)
|
||||
{
|
||||
imageInfo.flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR;
|
||||
}
|
||||
#endif
|
||||
imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
if (useSRV)
|
||||
{
|
||||
imageInfo.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
}
|
||||
if (useDSV)
|
||||
{
|
||||
imageInfo.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
}
|
||||
if (useRTV)
|
||||
{
|
||||
imageInfo.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
}
|
||||
if (useUAV)
|
||||
{
|
||||
imageInfo.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
|
||||
}
|
||||
imageInfo.tiling = optimalTiling ? VK_IMAGE_TILING_OPTIMAL : VK_IMAGE_TILING_LINEAR;
|
||||
imageInfo.samples = (VkSampleCountFlagBits)MultiSampleLevel();
|
||||
// TODO: set initialLayout to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL for IsRegularTexture() ???
|
||||
|
||||
@@ -51,6 +51,7 @@ public:
|
||||
VkImageView View = VK_NULL_HANDLE;
|
||||
VkImageView ViewFramebuffer = VK_NULL_HANDLE;
|
||||
VkExtent3D Extent;
|
||||
uint32 Layers;
|
||||
VkImageViewCreateInfo Info;
|
||||
int32 SubresourceIndex;
|
||||
VkImageLayout LayoutRTV;
|
||||
|
||||
@@ -695,7 +695,7 @@ DRAW:
|
||||
if (drawCall.InstanceCount == 0)
|
||||
{
|
||||
// No support for batching indirect draw calls
|
||||
ASSERT(batch.BatchSize == 1);
|
||||
ASSERT_LOW_LAYER(batch.BatchSize == 1);
|
||||
|
||||
context->BindVB(ToSpan(vb, vbCount), vbOffsets);
|
||||
context->DrawIndexedInstancedIndirect(drawCall.Draw.IndirectArgsBuffer, drawCall.Draw.IndirectArgsOffset);
|
||||
|
||||
Reference in New Issue
Block a user