[vulkan] add native cubic filtering
This commit is contained in:
parent
be9a415157
commit
7fba0cae84
5 changed files with 41 additions and 4 deletions
|
@ -5,9 +5,10 @@
|
||||||
|
|
||||||
layout(binding = 0) uniform sampler2D color_texture;
|
layout(binding = 0) uniform sampler2D color_texture;
|
||||||
|
|
||||||
// More accurate sRGB to linear conversion
|
// Even more accurate sRGB to linear conversion
|
||||||
|
// https://entropymine.com/imageworsener/srgbformula/
|
||||||
float srgbToLinear(float srgb) {
|
float srgbToLinear(float srgb) {
|
||||||
if (srgb <= 0.04045) {
|
if (srgb <= 0.0404482362771082f) { //assumes it's >= 0
|
||||||
return srgb / 12.92;
|
return srgb / 12.92;
|
||||||
} else {
|
} else {
|
||||||
return pow((srgb + 0.055) / 1.055, 2.4);
|
return pow((srgb + 0.055) / 1.055, 2.4);
|
||||||
|
|
|
@ -46,8 +46,12 @@ std::unique_ptr<WindowAdaptPass> MakeBilinear(const Device& device, VkFormat fra
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<WindowAdaptPass> MakeBicubic(const Device& device, VkFormat frame_format) {
|
std::unique_ptr<WindowAdaptPass> MakeBicubic(const Device& device, VkFormat frame_format) {
|
||||||
|
// No need for handrolled shader -- if the VK impl can do it for us ;)
|
||||||
|
if (device.IsExtFilterCubicSupported())
|
||||||
|
return std::make_unique<WindowAdaptPass>(device, frame_format, CreateCubicSampler(device),
|
||||||
|
BuildShader(device, VULKAN_PRESENT_FRAG_SPV));
|
||||||
return std::make_unique<WindowAdaptPass>(device, frame_format, CreateBilinearSampler(device),
|
return std::make_unique<WindowAdaptPass>(device, frame_format, CreateBilinearSampler(device),
|
||||||
BuildShader(device, PRESENT_BICUBIC_FRAG_SPV));
|
BuildShader(device, PRESENT_BICUBIC_FRAG_SPV));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<WindowAdaptPass> MakeGaussian(const Device& device, VkFormat frame_format) {
|
std::unique_ptr<WindowAdaptPass> MakeGaussian(const Device& device, VkFormat frame_format) {
|
||||||
|
|
|
@ -621,6 +621,31 @@ vk::Sampler CreateNearestNeighborSampler(const Device& device) {
|
||||||
return device.GetLogical().CreateSampler(ci_nn);
|
return device.GetLogical().CreateSampler(ci_nn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vk::Sampler CreateCubicSampler(const Device& device) {
|
||||||
|
const VkSamplerCreateInfo ci_nn{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.flags = 0,
|
||||||
|
.magFilter = VK_FILTER_CUBIC_EXT,
|
||||||
|
.minFilter = VK_FILTER_CUBIC_EXT,
|
||||||
|
.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST,
|
||||||
|
.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
|
||||||
|
.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
|
||||||
|
.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
|
||||||
|
.mipLodBias = 0.0f,
|
||||||
|
.anisotropyEnable = VK_FALSE,
|
||||||
|
.maxAnisotropy = 0.0f,
|
||||||
|
.compareEnable = VK_FALSE,
|
||||||
|
.compareOp = VK_COMPARE_OP_NEVER,
|
||||||
|
.minLod = 0.0f,
|
||||||
|
.maxLod = 0.0f,
|
||||||
|
.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK,
|
||||||
|
.unnormalizedCoordinates = VK_FALSE,
|
||||||
|
};
|
||||||
|
|
||||||
|
return device.GetLogical().CreateSampler(ci_nn);
|
||||||
|
}
|
||||||
|
|
||||||
void ClearColorImage(vk::CommandBuffer& cmdbuf, VkImage image) {
|
void ClearColorImage(vk::CommandBuffer& cmdbuf, VkImage image) {
|
||||||
static constexpr std::array<VkImageSubresourceRange, 1> subresources{{{
|
static constexpr std::array<VkImageSubresourceRange, 1> subresources{{{
|
||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
|
|
@ -54,6 +54,7 @@ VkWriteDescriptorSet CreateWriteDescriptorSet(std::vector<VkDescriptorImageInfo>
|
||||||
VkDescriptorSet set, u32 binding);
|
VkDescriptorSet set, u32 binding);
|
||||||
vk::Sampler CreateBilinearSampler(const Device& device);
|
vk::Sampler CreateBilinearSampler(const Device& device);
|
||||||
vk::Sampler CreateNearestNeighborSampler(const Device& device);
|
vk::Sampler CreateNearestNeighborSampler(const Device& device);
|
||||||
|
vk::Sampler CreateCubicSampler(const Device& device);
|
||||||
|
|
||||||
void BeginRenderPass(vk::CommandBuffer& cmdbuf, VkRenderPass render_pass, VkFramebuffer framebuffer,
|
void BeginRenderPass(vk::CommandBuffer& cmdbuf, VkRenderPass render_pass, VkFramebuffer framebuffer,
|
||||||
VkExtent2D extent);
|
VkExtent2D extent);
|
||||||
|
|
|
@ -85,7 +85,8 @@ VK_DEFINE_HANDLE(VmaAllocator)
|
||||||
EXTENSION(NV, GEOMETRY_SHADER_PASSTHROUGH, geometry_shader_passthrough) \
|
EXTENSION(NV, GEOMETRY_SHADER_PASSTHROUGH, geometry_shader_passthrough) \
|
||||||
EXTENSION(NV, VIEWPORT_ARRAY2, viewport_array2) \
|
EXTENSION(NV, VIEWPORT_ARRAY2, viewport_array2) \
|
||||||
EXTENSION(NV, VIEWPORT_SWIZZLE, viewport_swizzle) \
|
EXTENSION(NV, VIEWPORT_SWIZZLE, viewport_swizzle) \
|
||||||
EXTENSION(EXT, DESCRIPTOR_INDEXING, descriptor_indexing)
|
EXTENSION(EXT, DESCRIPTOR_INDEXING, descriptor_indexing) \
|
||||||
|
EXTENSION(EXT, FILTER_CUBIC, filter_cubic)
|
||||||
|
|
||||||
// Define extensions which must be supported.
|
// Define extensions which must be supported.
|
||||||
#define FOR_EACH_VK_MANDATORY_EXTENSION(EXTENSION_NAME) \
|
#define FOR_EACH_VK_MANDATORY_EXTENSION(EXTENSION_NAME) \
|
||||||
|
@ -549,6 +550,11 @@ public:
|
||||||
return dynamic_state3_enables;
|
return dynamic_state3_enables;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the device supports VK_EXT_filter_cubic
|
||||||
|
bool IsExtFilterCubicSupported() const {
|
||||||
|
return extensions.filter_cubic;
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if the device supports VK_EXT_line_rasterization.
|
/// Returns true if the device supports VK_EXT_line_rasterization.
|
||||||
bool IsExtLineRasterizationSupported() const {
|
bool IsExtLineRasterizationSupported() const {
|
||||||
return extensions.line_rasterization;
|
return extensions.line_rasterization;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue