Add high precision filtering extension
This lets users specify the level of sampling precision they want.
Chromium needs this to pass WebGL tests with SWANGLE.
Bug: b/146423360
Bug: b/154620295
Change-Id: I83575823b5909d836c3d4c02803ba7909ce08935
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/42268
Tested-by: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
diff --git a/include/vulkan/vk_google_filtering_precision.h b/include/vulkan/vk_google_filtering_precision.h
new file mode 100644
index 0000000..65e3bcf
--- /dev/null
+++ b/include/vulkan/vk_google_filtering_precision.h
@@ -0,0 +1,41 @@
+// Copyright 2020 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "vulkan_core.h"
+
+// THIS FILE SHOULD BE DELETED IF VK_GOOGLE_sampler_filtering_precision IS EVER ADDED TO THE VULKAN HEADERS
+#ifdef VK_GOOGLE_sampler_filtering_precision
+#error "VK_GOOGLE_sampler_filtering_precision is already defined in the Vulkan headers, you can delete this file"
+#endif
+
+static constexpr VkStructureType VK_STRUCTURE_TYPE_SAMPLER_FILTERING_PRECISION_GOOGLE = static_cast<VkStructureType>(1000264000);
+
+#define VK_GOOGLE_sampler_filtering_precisions 1
+#define VK_GOOGLE_SAMPLER_FILTERING_PRECISION_SPEC_VERSION 1
+#define VK_GOOGLE_SAMPLER_FILTERING_PRECISION_EXTENSION_NAME "VK_GOOGLE_sampler_filtering_precision"
+
+typedef enum VkSamplerFilteringPrecisionModeGOOGLE {
+ VK_SAMPLER_FILTERING_PRECISION_MODE_LOW_GOOGLE = 0,
+ VK_SAMPLER_FILTERING_PRECISION_MODE_HIGH_GOOGLE = 1,
+ VK_SAMPLER_FILTERING_PRECISION_MODE_BEGIN_RANGE_GOOGLE = VK_SAMPLER_FILTERING_PRECISION_MODE_LOW_GOOGLE,
+ VK_SAMPLER_FILTERING_PRECISION_MODE_END_RANGE_GOOGLE = VK_SAMPLER_FILTERING_PRECISION_MODE_HIGH_GOOGLE,
+ VK_SAMPLER_FILTERING_PRECISION_MODE_RANGE_SIZE_GOOGLE = (VK_SAMPLER_FILTERING_PRECISION_MODE_HIGH_GOOGLE - VK_SAMPLER_FILTERING_PRECISION_MODE_LOW_GOOGLE + 1),
+ VK_SAMPLER_FILTERING_PRECISION_MODE_MAX_ENUM_GOOGLE = 0x7FFFFFFF
+} VkSamplerFilteringPrecisionModeGOOGLE;
+
+typedef struct VkSamplerFilteringPrecisionGOOGLE {
+ VkStructureType sType;
+ const void* pNext;
+ VkSamplerFilteringPrecisionModeGOOGLE samplerFilteringPrecisionMode;
+} VkSamplerFilteringPrecisionGOOGLE;
diff --git a/src/Pipeline/SpirvShaderSampling.cpp b/src/Pipeline/SpirvShaderSampling.cpp
index 590fc11..d1d845c 100644
--- a/src/Pipeline/SpirvShaderSampling.cpp
+++ b/src/Pipeline/SpirvShaderSampling.cpp
@@ -56,7 +56,6 @@
samplerState.mipmapFilter = convertMipmapMode(sampler);
samplerState.swizzle = imageDescriptor->swizzle;
samplerState.gatherComponent = instruction.gatherComponent;
- samplerState.highPrecisionFiltering = false;
samplerState.largeTexture = (imageDescriptor->extent.width > SHRT_MAX) ||
(imageDescriptor->extent.height > SHRT_MAX) ||
(imageDescriptor->extent.depth > SHRT_MAX);
@@ -67,6 +66,7 @@
samplerState.border = sampler->borderColor;
samplerState.mipmapFilter = convertMipmapMode(sampler);
+ samplerState.highPrecisionFiltering = (sampler->filteringPrecision == VK_SAMPLER_FILTERING_PRECISION_MODE_HIGH_GOOGLE);
samplerState.compareEnable = (sampler->compareEnable != VK_FALSE);
samplerState.compareOp = sampler->compareOp;
diff --git a/src/Vulkan/VkSampler.cpp b/src/Vulkan/VkSampler.cpp
index 11cb00e..d64a4d5 100644
--- a/src/Vulkan/VkSampler.cpp
+++ b/src/Vulkan/VkSampler.cpp
@@ -16,7 +16,7 @@
namespace vk {
-SamplerState::SamplerState(const VkSamplerCreateInfo *pCreateInfo, const vk::SamplerYcbcrConversion *ycbcrConversion)
+SamplerState::SamplerState(const VkSamplerCreateInfo *pCreateInfo, const vk::SamplerYcbcrConversion *ycbcrConversion, VkSamplerFilteringPrecisionModeGOOGLE filteringPrecision)
: Memset(this, 0)
, magFilter(pCreateInfo->magFilter)
, minFilter(pCreateInfo->minFilter)
@@ -33,6 +33,7 @@
, maxLod(ClampLod(pCreateInfo->maxLod))
, borderColor(pCreateInfo->borderColor)
, unnormalizedCoordinates(pCreateInfo->unnormalizedCoordinates)
+ , filteringPrecision(filteringPrecision)
{
if(ycbcrConversion)
{
diff --git a/src/Vulkan/VkSampler.hpp b/src/Vulkan/VkSampler.hpp
index d2f51ac..f713ed2 100644
--- a/src/Vulkan/VkSampler.hpp
+++ b/src/Vulkan/VkSampler.hpp
@@ -26,7 +26,7 @@
struct SamplerState : sw::Memset<SamplerState>
{
- SamplerState(const VkSamplerCreateInfo *pCreateInfo, const vk::SamplerYcbcrConversion *ycbcrConversion);
+ SamplerState(const VkSamplerCreateInfo *pCreateInfo, const vk::SamplerYcbcrConversion *ycbcrConversion, VkSamplerFilteringPrecisionModeGOOGLE filteringPrecision);
// Prevents accessing mipmap levels out of range.
static float ClampLod(float lod)
@@ -51,6 +51,7 @@
const VkBool32 unnormalizedCoordinates = VK_FALSE;
VkSamplerYcbcrModelConversion ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
+ const VkSamplerFilteringPrecisionModeGOOGLE filteringPrecision = VK_SAMPLER_FILTERING_PRECISION_MODE_LOW_GOOGLE;
bool studioSwing = false; // Narrow range
bool swappedChroma = false; // Cb/Cr components in reverse order
};
diff --git a/src/Vulkan/VkStringify.cpp b/src/Vulkan/VkStringify.cpp
index a8247f3..6551b76 100644
--- a/src/Vulkan/VkStringify.cpp
+++ b/src/Vulkan/VkStringify.cpp
@@ -17,6 +17,7 @@
#include "System/Debug.hpp"
#include "vulkan/vk_ext_provoking_vertex.h"
+#include "vulkan/vk_google_filtering_precision.h"
#include <iostream>
#include <map>
@@ -452,6 +453,7 @@
INSERT_ELEMENT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT),
INSERT_ELEMENT(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT),
INSERT_ELEMENT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT),
+ INSERT_ELEMENT(VK_STRUCTURE_TYPE_SAMPLER_FILTERING_PRECISION_GOOGLE),
INSERT_ELEMENT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT),
INSERT_ELEMENT(VK_STRUCTURE_TYPE_MAX_ENUM)
# undef INSERT_ELEMENT
diff --git a/src/Vulkan/VulkanPlatform.hpp b/src/Vulkan/VulkanPlatform.hpp
index a220865..317cf14 100644
--- a/src/Vulkan/VulkanPlatform.hpp
+++ b/src/Vulkan/VulkanPlatform.hpp
@@ -50,6 +50,7 @@
template class VkNonDispatchableHandle<object##Ptr>;
#include <vulkan/vk_ext_provoking_vertex.h>
+#include <vulkan/vk_google_filtering_precision.h>
#include <vulkan/vulkan.h>
#ifdef Bool
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index 07e9b0a..c911ef4 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -379,6 +379,7 @@
{ VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME, VK_FUCHSIA_EXTERNAL_MEMORY_SPEC_VERSION },
#endif
{ VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME, VK_EXT_PROVOKING_VERTEX_SPEC_VERSION },
+ { VK_GOOGLE_SAMPLER_FILTERING_PRECISION_EXTENSION_NAME, VK_GOOGLE_SAMPLER_FILTERING_PRECISION_SPEC_VERSION },
};
VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance)
@@ -1922,10 +1923,11 @@
const VkBaseInStructure *extensionCreateInfo = reinterpret_cast<const VkBaseInStructure *>(pCreateInfo->pNext);
const vk::SamplerYcbcrConversion *ycbcrConversion = nullptr;
+ VkSamplerFilteringPrecisionModeGOOGLE filteringPrecision = VK_SAMPLER_FILTERING_PRECISION_MODE_LOW_GOOGLE;
while(extensionCreateInfo)
{
- switch(extensionCreateInfo->sType)
+ switch(static_cast<long>(extensionCreateInfo->sType))
{
case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO:
{
@@ -1933,6 +1935,13 @@
ycbcrConversion = vk::Cast(samplerYcbcrConversionInfo->conversion);
}
break;
+ case VK_STRUCTURE_TYPE_SAMPLER_FILTERING_PRECISION_GOOGLE:
+ {
+ const VkSamplerFilteringPrecisionGOOGLE *filteringInfo =
+ reinterpret_cast<const VkSamplerFilteringPrecisionGOOGLE *>(extensionCreateInfo);
+ filteringPrecision = filteringInfo->samplerFilteringPrecisionMode;
+ }
+ break;
default:
LOG_TRAP("pCreateInfo->pNext sType = %s", vk::Stringify(extensionCreateInfo->sType).c_str());
break;
@@ -1941,7 +1950,7 @@
extensionCreateInfo = extensionCreateInfo->pNext;
}
- vk::SamplerState samplerState(pCreateInfo, ycbcrConversion);
+ vk::SamplerState samplerState(pCreateInfo, ycbcrConversion, filteringPrecision);
uint32_t samplerID = vk::Cast(device)->indexSampler(samplerState);
VkResult result = vk::Sampler::Create(pAllocator, pCreateInfo, pSampler, samplerState, samplerID);