Commit 6b63c80e by Nicolas Capens Committed by Nicolas Capens

Implement VkSamplerYcbcrConversion object

Implement the vk::SamplerYcbcrConversion object and pass it to the vk::Sampler and vk::ImageView constructors if present as an VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO extension struct value. Bug: b/132437008 Tests: dEQP-VK.*ycbcr* Change-Id: I16b03dc37920dd1eee7de80a370f8f7386dc4cea Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31614 Presubmit-Ready: Nicolas Capens <nicolascapens@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com>
parent e2f5da4b
......@@ -19,10 +19,7 @@ namespace
{
VkComponentMapping ResolveComponentMapping(VkComponentMapping m, vk::Format format)
{
if (m.r == VK_COMPONENT_SWIZZLE_IDENTITY) m.r = VK_COMPONENT_SWIZZLE_R;
if (m.g == VK_COMPONENT_SWIZZLE_IDENTITY) m.g = VK_COMPONENT_SWIZZLE_G;
if (m.b == VK_COMPONENT_SWIZZLE_IDENTITY) m.b = VK_COMPONENT_SWIZZLE_B;
if (m.a == VK_COMPONENT_SWIZZLE_IDENTITY) m.a = VK_COMPONENT_SWIZZLE_A;
m = vk::ResolveIdentityMapping(m);
// Replace non-present components with zero/one swizzles so that the sampler
// will give us correct interactions between channel replacement and texel replacement,
......@@ -58,10 +55,11 @@ namespace vk
std::atomic<uint32_t> ImageView::nextID(1);
ImageView::ImageView(const VkImageViewCreateInfo* pCreateInfo, void* mem) :
ImageView::ImageView(const VkImageViewCreateInfo* pCreateInfo, void* mem, const vk::SamplerYcbcrConversion *ycbcrConversion) :
image(Cast(pCreateInfo->image)), viewType(pCreateInfo->viewType), format(pCreateInfo->format),
components(ResolveComponentMapping(pCreateInfo->components, format)),
subresourceRange(ResolveRemainingLevelsLayers(pCreateInfo->subresourceRange, image))
subresourceRange(ResolveRemainingLevelsLayers(pCreateInfo->subresourceRange, image)),
ycbcrConversion(ycbcrConversion)
{
}
......
......@@ -24,6 +24,7 @@
namespace vk
{
class SamplerYcbcrConversion;
class ImageView : public Object<ImageView, VkImageView>
{
......@@ -33,7 +34,7 @@ public:
// SAMPLING: Image used for texture sampling
enum Usage { RAW, SAMPLING };
ImageView(const VkImageViewCreateInfo* pCreateInfo, void* mem);
ImageView(const VkImageViewCreateInfo* pCreateInfo, void* mem, const vk::SamplerYcbcrConversion *ycbcrConversion);
void destroy(const VkAllocationCallbacks* pAllocator);
static size_t ComputeRequiredAllocationSize(const VkImageViewCreateInfo* pCreateInfo);
......@@ -72,6 +73,7 @@ public:
size_t getImageSizeInBytes() const { return image->getMemoryRequirements().size; }
const uint32_t id = nextID++;
private:
static std::atomic<uint32_t> nextID;
friend class BufferView; // ImageView/BufferView share the ID space above.
......@@ -84,8 +86,21 @@ private:
const Format format;
const VkComponentMapping components = {};
const VkImageSubresourceRange subresourceRange = {};
const vk::SamplerYcbcrConversion *ycbcrConversion = nullptr;
};
// TODO(b/132437008): Also used by SamplerYcbcrConversion. Move somewhere centrally?
inline VkComponentMapping ResolveIdentityMapping(VkComponentMapping m)
{
return {
(m.r == VK_COMPONENT_SWIZZLE_IDENTITY) ? VK_COMPONENT_SWIZZLE_R : m.r,
(m.g == VK_COMPONENT_SWIZZLE_IDENTITY) ? VK_COMPONENT_SWIZZLE_G : m.g,
(m.b == VK_COMPONENT_SWIZZLE_IDENTITY) ? VK_COMPONENT_SWIZZLE_B : m.b,
(m.a == VK_COMPONENT_SWIZZLE_IDENTITY) ? VK_COMPONENT_SWIZZLE_A : m.a,
};
}
static inline ImageView* Cast(VkImageView object)
{
return reinterpret_cast<ImageView*>(object.get());
......
......@@ -16,6 +16,7 @@
#define VK_SAMPLER_HPP_
#include "VkDevice.hpp"
#include "VkImageView.hpp" // For ResolveIdentityMapping()
#include "Device/Config.hpp"
#include "System/Math.hpp"
......@@ -27,7 +28,7 @@ namespace vk
class Sampler : public Object<Sampler, VkSampler>
{
public:
Sampler(const VkSamplerCreateInfo* pCreateInfo, void* mem) :
Sampler(const VkSamplerCreateInfo* pCreateInfo, void* mem, const vk::SamplerYcbcrConversion *ycbcrConversion) :
magFilter(pCreateInfo->magFilter),
minFilter(pCreateInfo->minFilter),
mipmapMode(pCreateInfo->mipmapMode),
......@@ -42,7 +43,8 @@ public:
minLod(ClampLod(pCreateInfo->minLod)),
maxLod(ClampLod(pCreateInfo->maxLod)),
borderColor(pCreateInfo->borderColor),
unnormalizedCoordinates(pCreateInfo->unnormalizedCoordinates)
unnormalizedCoordinates(pCreateInfo->unnormalizedCoordinates),
ycbcrConversion(ycbcrConversion)
{
}
......@@ -74,15 +76,54 @@ public:
const VkBorderColor borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
const VkBool32 unnormalizedCoordinates = VK_FALSE;
const vk::SamplerYcbcrConversion *ycbcrConversion = nullptr;
private:
static std::atomic<uint32_t> nextID;
};
class SamplerYcbcrConversion : public Object<SamplerYcbcrConversion, VkSamplerYcbcrConversion>
{
public:
SamplerYcbcrConversion(const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, void* mem) :
format(pCreateInfo->format),
ycbcrModel(pCreateInfo->ycbcrModel),
ycbcrRange(pCreateInfo->ycbcrRange),
components(ResolveIdentityMapping(pCreateInfo->components)),
xChromaOffset(pCreateInfo->xChromaOffset),
yChromaOffset(pCreateInfo->yChromaOffset),
chromaFilter(pCreateInfo->chromaFilter),
forceExplicitReconstruction(pCreateInfo->forceExplicitReconstruction)
{
}
~SamplerYcbcrConversion() = default;
static size_t ComputeRequiredAllocationSize(const VkSamplerYcbcrConversionCreateInfo* pCreateInfo)
{
return 0;
}
const VkFormat format = VK_FORMAT_UNDEFINED;
const VkSamplerYcbcrModelConversion ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
const VkSamplerYcbcrRange ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
const VkComponentMapping components = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
const VkChromaLocation xChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN;
const VkChromaLocation yChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN;
const VkFilter chromaFilter = VK_FILTER_NEAREST;
const VkBool32 forceExplicitReconstruction = VK_FALSE;
};
static inline Sampler* Cast(VkSampler object)
{
return reinterpret_cast<Sampler*>(object.get());
}
static inline SamplerYcbcrConversion* Cast(VkSamplerYcbcrConversion object)
{
return reinterpret_cast<SamplerYcbcrConversion*>(object.get());
}
} // namespace vk
#endif // VK_SAMPLER_HPP_
\ No newline at end of file
......@@ -443,7 +443,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, c
break;
default:
// "the [driver] must skip over, without processing (other than reading the sType and pNext members) any structures in the chain with sType values not defined by [supported extenions]"
UNIMPLEMENTED("extensionCreateInfo->sType"); // TODO(b/119321052): UNIMPLEMENTED() should be used only for features that must still be implemented. Use a more informational macro here.
UNIMPLEMENTED("extensionCreateInfo->sType %d", int(extensionCreateInfo->sType)); // TODO(b/119321052): UNIMPLEMENTED() should be used only for features that must still be implemented. Use a more informational macro here.
break;
}
......@@ -1045,6 +1045,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView(VkDevice device, const VkImageV
}
const VkBaseInStructure* extensionCreateInfo = reinterpret_cast<const VkBaseInStructure*>(pCreateInfo->pNext);
const vk::SamplerYcbcrConversion *ycbcrConversion = nullptr;
while(extensionCreateInfo)
{
......@@ -1058,8 +1059,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView(VkDevice device, const VkImageV
break;
case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO:
{
const VkSamplerYcbcrConversionInfo* ycbcrConversionInfo = reinterpret_cast<const VkSamplerYcbcrConversionInfo*>(extensionCreateInfo);
if(ycbcrConversionInfo->conversion != VK_NULL_HANDLE)
const VkSamplerYcbcrConversionInfo* samplerYcbcrConversionInfo = reinterpret_cast<const VkSamplerYcbcrConversionInfo*>(extensionCreateInfo);
ycbcrConversion = vk::Cast(samplerYcbcrConversionInfo->conversion);
if(ycbcrConversion != VK_NULL_HANDLE)
{
ASSERT((pCreateInfo->components.r == VK_COMPONENT_SWIZZLE_IDENTITY) &&
(pCreateInfo->components.g == VK_COMPONENT_SWIZZLE_IDENTITY) &&
......@@ -1069,14 +1072,14 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView(VkDevice device, const VkImageV
}
break;
default:
UNIMPLEMENTED("extensionCreateInfo->sType");
UNIMPLEMENTED("extensionCreateInfo->sType %d", int(extensionCreateInfo->sType));
break;
}
extensionCreateInfo = extensionCreateInfo->pNext;
}
return vk::ImageView::Create(pAllocator, pCreateInfo, pView);
return vk::ImageView::Create(pAllocator, pCreateInfo, pView, ycbcrConversion);
}
VKAPI_ATTR void VKAPI_CALL vkDestroyImageView(VkDevice device, VkImageView imageView, const VkAllocationCallbacks* pAllocator)
......@@ -1245,12 +1248,33 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler(VkDevice device, const VkSamplerC
TRACE("(VkDevice device = %p, const VkSamplerCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkSampler* pSampler = %p)",
device, pCreateInfo, pAllocator, pSampler);
if(pCreateInfo->pNext || pCreateInfo->flags)
if(pCreateInfo->flags)
{
UNIMPLEMENTED("pCreateInfo->pNext || pCreateInfo->flags");
}
return vk::Sampler::Create(pAllocator, pCreateInfo, pSampler);
const VkBaseInStructure* extensionCreateInfo = reinterpret_cast<const VkBaseInStructure*>(pCreateInfo->pNext);
const vk::SamplerYcbcrConversion *ycbcrConversion = nullptr;
while(extensionCreateInfo)
{
switch(extensionCreateInfo->sType)
{
case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO:
{
const VkSamplerYcbcrConversionInfo* samplerYcbcrConversionInfo = reinterpret_cast<const VkSamplerYcbcrConversionInfo*>(extensionCreateInfo);
ycbcrConversion = vk::Cast(samplerYcbcrConversionInfo->conversion);
}
break;
default:
UNIMPLEMENTED("extensionCreateInfo->sType %d", int(extensionCreateInfo->sType));
break;
}
extensionCreateInfo = extensionCreateInfo->pNext;
}
return vk::Sampler::Create(pAllocator, pCreateInfo, pSampler, ycbcrConversion);
}
VKAPI_ATTR void VKAPI_CALL vkDestroySampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks* pAllocator)
......@@ -1276,7 +1300,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorSetLayout(VkDevice device, cons
ASSERT(!vk::Cast(device)->hasExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME));
break;
default:
UNIMPLEMENTED("extensionCreateInfo->sType");
UNIMPLEMENTED("extensionCreateInfo->sType %d", int(extensionCreateInfo->sType));
break;
}
......@@ -1466,7 +1490,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(VkDevice device, const VkRende
}
break;
default:
UNIMPLEMENTED("extensionCreateInfo->sType");
UNIMPLEMENTED("extensionCreateInfo->sType %d", int(extensionCreateInfo->sType));
break;
}
......@@ -2432,15 +2456,23 @@ VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue2(VkDevice device, const VkDeviceQueu
VKAPI_ATTR VkResult VKAPI_CALL vkCreateSamplerYcbcrConversion(VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion)
{
TRACE("()");
UNIMPLEMENTED("vkCreateSamplerYcbcrConversion");
return VK_SUCCESS;
TRACE("(VkDevice device = %p, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkSamplerYcbcrConversion* pYcbcrConversion = %p)",
device, pCreateInfo, pAllocator, pYcbcrConversion);
if(pCreateInfo->pNext)
{
UNIMPLEMENTED("pCreateInfo->pNext");
}
return vk::SamplerYcbcrConversion::Create(pAllocator, pCreateInfo, pYcbcrConversion);
}
VKAPI_ATTR void VKAPI_CALL vkDestroySamplerYcbcrConversion(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks* pAllocator)
{
TRACE("()");
UNIMPLEMENTED("vkDestroySamplerYcbcrConversion");
TRACE("(VkDevice device = %p, VkSamplerYcbcrConversion ycbcrConversion = %p, const VkAllocationCallbacks* pAllocator = %p)",
device, ycbcrConversion.get(), pAllocator);
vk::destroy(ycbcrConversion, pAllocator);
}
VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorUpdateTemplate(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment