diff --git a/src/common/rendering/vulkan/renderer/vk_renderbuffers.cpp b/src/common/rendering/vulkan/renderer/vk_renderbuffers.cpp index e3217076de..34e44096d5 100644 --- a/src/common/rendering/vulkan/renderer/vk_renderbuffers.cpp +++ b/src/common/rendering/vulkan/renderer/vk_renderbuffers.cpp @@ -212,13 +212,18 @@ void VkRenderBuffers::CreateSceneNormal(int width, int height, VkSampleCountFlag ImageBuilder builder; builder.setSize(width, height); builder.setSamples(samples); - builder.setFormat(VK_FORMAT_A2R10G10B10_UNORM_PACK32); + builder.setFormat(SceneNormalFormat); builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); + if (!builder.isFormatSupported(fb->device, VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) + { + SceneNormalFormat = VK_FORMAT_R8G8B8A8_UNORM; + builder.setFormat(SceneNormalFormat); + } SceneNormal.Image = builder.create(fb->device); SceneNormal.Image->SetDebugName("VkRenderBuffers.SceneNormal"); ImageViewBuilder viewbuilder; - viewbuilder.setImage(SceneNormal.Image.get(), VK_FORMAT_A2R10G10B10_UNORM_PACK32); + viewbuilder.setImage(SceneNormal.Image.get(), SceneNormalFormat); SceneNormal.View = viewbuilder.create(fb->device); SceneNormal.View->SetDebugName("VkRenderBuffers.SceneNormalView"); } diff --git a/src/common/rendering/vulkan/renderer/vk_renderbuffers.h b/src/common/rendering/vulkan/renderer/vk_renderbuffers.h index b1df96b021..92ad9c5beb 100644 --- a/src/common/rendering/vulkan/renderer/vk_renderbuffers.h +++ b/src/common/rendering/vulkan/renderer/vk_renderbuffers.h @@ -24,6 +24,7 @@ public: VkTextureImage SceneFog; VkFormat SceneDepthStencilFormat = VK_FORMAT_D24_UNORM_S8_UINT; + VkFormat SceneNormalFormat = VK_FORMAT_A2R10G10B10_UNORM_PACK32; static const int NumPipelineImages = 2; VkTextureImage PipelineImage[NumPipelineImages]; diff --git a/src/common/rendering/vulkan/renderer/vk_renderpass.cpp b/src/common/rendering/vulkan/renderer/vk_renderpass.cpp index 2e0973c087..44c325ecfe 100644 --- a/src/common/rendering/vulkan/renderer/vk_renderpass.cpp +++ b/src/common/rendering/vulkan/renderer/vk_renderpass.cpp @@ -281,7 +281,7 @@ std::unique_ptr VkRenderPassSetup::CreateRenderPass(int clearT { auto buffers = GetVulkanFrameBuffer()->GetBuffers(); - VkFormat drawBufferFormats[] = { VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_A2R10G10B10_UNORM_PACK32 }; + VkFormat drawBufferFormats[] = { VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R8G8B8A8_UNORM, buffers->SceneNormalFormat }; RenderPassBuilder builder; @@ -420,7 +420,8 @@ std::unique_ptr VkRenderPassSetup::CreatePipeline(const VkPipeli builder.setTopology(vktopology[key.DrawType]); builder.setDepthStencilEnable(key.DepthTest, key.DepthWrite, key.StencilTest); builder.setDepthFunc(depthfunc2vk[key.DepthFunc]); - builder.setDepthClampEnable(key.DepthClamp); + if (fb->device->UsedDeviceFeatures.depthClamp) + builder.setDepthClampEnable(key.DepthClamp); builder.setDepthBias(key.DepthBias, 0.0f, 0.0f, 0.0f); // Note: CCW and CW is intentionally swapped here because the vulkan and opengl coordinate systems differ. diff --git a/src/common/rendering/vulkan/system/vk_builders.h b/src/common/rendering/vulkan/system/vk_builders.h index 5f0e3c0fc5..343313bbd1 100644 --- a/src/common/rendering/vulkan/system/vk_builders.h +++ b/src/common/rendering/vulkan/system/vk_builders.h @@ -45,7 +45,7 @@ public: void setMemoryType(VkMemoryPropertyFlags requiredFlags, VkMemoryPropertyFlags preferredFlags, uint32_t memoryTypeBits = 0); void setLinearTiling(); - bool isFormatSupported(VulkanDevice *device); + bool isFormatSupported(VulkanDevice *device, VkFormatFeatureFlags bufferFeatures = 0); std::unique_ptr create(VulkanDevice *device, VkDeviceSize* allocatedBytes = nullptr); std::unique_ptr tryCreate(VulkanDevice *device); @@ -410,7 +410,7 @@ inline void ImageBuilder::setMemoryType(VkMemoryPropertyFlags requiredFlags, VkM allocInfo.memoryTypeBits = memoryTypeBits; } -inline bool ImageBuilder::isFormatSupported(VulkanDevice *device) +inline bool ImageBuilder::isFormatSupported(VulkanDevice *device, VkFormatFeatureFlags bufferFeatures) { VkImageFormatProperties properties = { }; VkResult result = vkGetPhysicalDeviceImageFormatProperties(device->PhysicalDevice.Device, imageInfo.format, imageInfo.imageType, imageInfo.tiling, imageInfo.usage, imageInfo.flags, &properties); @@ -421,6 +421,13 @@ inline bool ImageBuilder::isFormatSupported(VulkanDevice *device) if (imageInfo.mipLevels > properties.maxMipLevels) return false; if (imageInfo.arrayLayers > properties.maxArrayLayers) return false; if ((imageInfo.samples & properties.sampleCounts) != imageInfo.samples) return false; + if (bufferFeatures != 0) + { + VkFormatProperties formatProperties = { }; + vkGetPhysicalDeviceFormatProperties(device->PhysicalDevice.Device, imageInfo.format, &formatProperties); + if ((formatProperties.bufferFeatures & bufferFeatures) != bufferFeatures) + return false; + } return true; } diff --git a/src/common/rendering/vulkan/system/vk_device.cpp b/src/common/rendering/vulkan/system/vk_device.cpp index 8fc6e8949d..2e7ca9aad7 100644 --- a/src/common/rendering/vulkan/system/vk_device.cpp +++ b/src/common/rendering/vulkan/system/vk_device.cpp @@ -108,8 +108,7 @@ bool VulkanDevice::CheckRequiredFeatures(const VkPhysicalDeviceFeatures &f) { return f.samplerAnisotropy == VK_TRUE && - f.fragmentStoresAndAtomics == VK_TRUE && - f.depthClamp == VK_TRUE; + f.fragmentStoresAndAtomics == VK_TRUE; } void VulkanDevice::SelectPhysicalDevice()