blob: 3733dbc1242d50c772df2883af60c88ce3f88580 [file] [log] [blame]
/*
* Copyright 2023 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/gpu/graphite/vk/VulkanSamplerYcbcrConversion.h"
#include "include/gpu/graphite/vk/VulkanGraphiteTypes.h"
#include "src/gpu/graphite/vk/VulkanCaps.h"
#include "src/gpu/graphite/vk/VulkanGraphiteUtilsPriv.h"
#include "src/gpu/graphite/vk/VulkanSharedContext.h"
namespace skgpu::graphite {
sk_sp<VulkanSamplerYcbcrConversion> VulkanSamplerYcbcrConversion::Make(
const VulkanSharedContext* context,
const VulkanYcbcrConversionInfo& conversionInfo) {
if (!context->vulkanCaps().supportsYcbcrConversion()) {
return nullptr;
}
VkSamplerYcbcrConversionCreateInfo ycbcrCreateInfo;
skgpu::SetupSamplerYcbcrConversionInfo(&ycbcrCreateInfo, conversionInfo);
#ifdef SK_BUILD_FOR_ANDROID
VkExternalFormatANDROID externalFormat;
if (conversionInfo.fExternalFormat) {
// Format must not be specified for external images.
SkASSERT(conversionInfo.fFormat == VK_FORMAT_UNDEFINED);
externalFormat.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID;
externalFormat.pNext = nullptr;
externalFormat.externalFormat = conversionInfo.fExternalFormat;
SkASSERT(ycbcrCreateInfo.pNext == nullptr);
ycbcrCreateInfo.pNext = &externalFormat;
}
#else
// External images are supported only on Android.
SkASSERT(!conversionInfo.fExternalFormat);
#endif
if (!conversionInfo.fExternalFormat) {
SkASSERT(conversionInfo.fFormat != VK_FORMAT_UNDEFINED);
}
VkSamplerYcbcrConversion conversion;
VkResult result;
VULKAN_CALL_RESULT(context->interface(), result,
CreateSamplerYcbcrConversion(context->device(),
&ycbcrCreateInfo,
nullptr,
&conversion));
if (result != VK_SUCCESS) {
return nullptr;
}
return sk_sp<VulkanSamplerYcbcrConversion>(
new VulkanSamplerYcbcrConversion(context, conversion));
}
GraphiteResourceKey VulkanSamplerYcbcrConversion::MakeYcbcrConversionKey(
const VulkanSharedContext* context, const VulkanYcbcrConversionInfo& info) {
static const ResourceType kType = GraphiteResourceKey::GenerateResourceType();
// One uint32 for Vkformat, two for external format, and one to house all ycbcr information
static const int num32DataCnt = 4;
GraphiteResourceKey key;
GraphiteResourceKey::Builder builder(&key, kType, num32DataCnt, Shareable::kYes);
SkASSERT(info.fYcbcrModel < (1u << 7));
SkASSERT(info.fYcbcrRange < (1u << 1));
SkASSERT(info.fXChromaOffset < (1u << 1));
SkASSERT(info.fYChromaOffset < (1u << 1));
SkASSERT(info.fChromaFilter < (1u << 1));
SkASSERT(info.fForceExplicitReconstruction < (1u << 7));
builder[0] = info.fFormat;
builder[1] = (uint32_t)(info.fExternalFormat << 32);
builder[2] = (uint32_t)info.fExternalFormat;
builder[3] = (static_cast<uint32_t>(info.fYcbcrModel ) << 0) |
(static_cast<uint32_t>(info.fYcbcrRange ) << 8) |
(static_cast<uint32_t>(info.fXChromaOffset ) << 9) |
(static_cast<uint32_t>(info.fYChromaOffset ) << 10) |
(static_cast<uint32_t>(info.fChromaFilter ) << 11) |
(static_cast<uint32_t>(info.fForceExplicitReconstruction) << 12) ;
builder.finish();
return key;
}
VulkanSamplerYcbcrConversion::VulkanSamplerYcbcrConversion(
const VulkanSharedContext* context, VkSamplerYcbcrConversion ycbcrConversion)
: Resource(context,
Ownership::kOwned,
skgpu::Budgeted::kNo,
/*gpuMemorySize=*/0,
/*label=*/"VulkanSamplerYcbcrConversion")
, fYcbcrConversion (ycbcrConversion) {}
void VulkanSamplerYcbcrConversion::freeGpuData() {
auto sharedContext = static_cast<const VulkanSharedContext*>(this->sharedContext());
SkASSERT(fYcbcrConversion != VK_NULL_HANDLE);
VULKAN_CALL(sharedContext->interface(),
DestroySamplerYcbcrConversion(sharedContext->device(), fYcbcrConversion, nullptr));
}
} // namespace skgpu::graphite