GrVkSamplerYcbcrConversion.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. * Copyright 2018 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "src/gpu/vk/GrVkSamplerYcbcrConversion.h"
  8. #include "src/gpu/vk/GrVkGpu.h"
  9. GrVkSamplerYcbcrConversion* GrVkSamplerYcbcrConversion::Create(
  10. const GrVkGpu* gpu, const GrVkYcbcrConversionInfo& info) {
  11. if (!gpu->vkCaps().supportsYcbcrConversion()) {
  12. return nullptr;
  13. }
  14. // We only support creating ycbcr conversion for external formats;
  15. SkASSERT(info.fExternalFormat);
  16. #ifdef SK_DEBUG
  17. const VkFormatFeatureFlags& featureFlags = info.fExternalFormatFeatures;
  18. if (info.fXChromaOffset == VK_CHROMA_LOCATION_MIDPOINT ||
  19. info.fYChromaOffset == VK_CHROMA_LOCATION_MIDPOINT) {
  20. SkASSERT(featureFlags & VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT);
  21. }
  22. if (info.fXChromaOffset == VK_CHROMA_LOCATION_COSITED_EVEN ||
  23. info.fYChromaOffset == VK_CHROMA_LOCATION_COSITED_EVEN) {
  24. SkASSERT(featureFlags & VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT);
  25. }
  26. if (info.fChromaFilter == VK_FILTER_LINEAR) {
  27. SkASSERT(featureFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT);
  28. }
  29. if (info.fForceExplicitReconstruction) {
  30. SkASSERT(featureFlags &
  31. VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT);
  32. }
  33. #endif
  34. #ifdef SK_BUILD_FOR_ANDROID
  35. VkExternalFormatANDROID externalFormat;
  36. externalFormat.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID;
  37. externalFormat.pNext = nullptr;
  38. externalFormat.externalFormat = info.fExternalFormat;
  39. VkSamplerYcbcrConversionCreateInfo ycbcrCreateInfo;
  40. memset(&ycbcrCreateInfo, 0, sizeof(VkSamplerYcbcrConversionCreateInfo));
  41. ycbcrCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO;
  42. ycbcrCreateInfo.pNext = &externalFormat;
  43. ycbcrCreateInfo.format = VK_FORMAT_UNDEFINED;
  44. ycbcrCreateInfo.ycbcrModel = info.fYcbcrModel;
  45. ycbcrCreateInfo.ycbcrRange = info.fYcbcrRange;
  46. // Componets is ignored for external format conversions;
  47. // ycbcrCreateInfo.components = {0, 0, 0, 0};
  48. ycbcrCreateInfo.xChromaOffset = info.fXChromaOffset;
  49. ycbcrCreateInfo.yChromaOffset = info.fYChromaOffset;
  50. ycbcrCreateInfo.chromaFilter = info.fChromaFilter;
  51. ycbcrCreateInfo.forceExplicitReconstruction = info.fForceExplicitReconstruction;
  52. VkSamplerYcbcrConversion conversion;
  53. GR_VK_CALL(gpu->vkInterface(), CreateSamplerYcbcrConversion(gpu->device(), &ycbcrCreateInfo,
  54. nullptr, &conversion));
  55. if (conversion == VK_NULL_HANDLE) {
  56. return nullptr;
  57. }
  58. return new GrVkSamplerYcbcrConversion(conversion, GenerateKey(info));
  59. #else
  60. return nullptr;
  61. #endif
  62. }
  63. void GrVkSamplerYcbcrConversion::freeGPUData(GrVkGpu* gpu) const {
  64. SkASSERT(fYcbcrConversion);
  65. GR_VK_CALL(gpu->vkInterface(), DestroySamplerYcbcrConversion(gpu->device(), fYcbcrConversion,
  66. nullptr));
  67. }
  68. GrVkSamplerYcbcrConversion::Key GrVkSamplerYcbcrConversion::GenerateKey(
  69. const GrVkYcbcrConversionInfo& ycbcrInfo) {
  70. SkASSERT(static_cast<int>(ycbcrInfo.fYcbcrModel <= 7));
  71. static const int kRangeShift = 3;
  72. SkASSERT(static_cast<int>(ycbcrInfo.fYcbcrRange) <= 1);
  73. static const int kXChromaOffsetShift = kRangeShift + 1;
  74. SkASSERT(static_cast<int>(ycbcrInfo.fXChromaOffset) <= 1);
  75. static const int kYChromaOffsetShift = kXChromaOffsetShift + 1;
  76. SkASSERT(static_cast<int>(ycbcrInfo.fXChromaOffset) <= 1);
  77. static const int kChromaFilterShift = kYChromaOffsetShift + 1;
  78. SkASSERT(static_cast<int>(ycbcrInfo.fChromaFilter) <= 1);
  79. static const int kReconShift = kChromaFilterShift + 1;
  80. SkASSERT(static_cast<int>(ycbcrInfo.fForceExplicitReconstruction) <= 1);
  81. GR_STATIC_ASSERT(kReconShift <= 7);
  82. uint8_t ycbcrKey = static_cast<uint8_t>(ycbcrInfo.fYcbcrModel);
  83. ycbcrKey |= (static_cast<uint8_t>(ycbcrInfo.fYcbcrRange) << kRangeShift);
  84. ycbcrKey |= (static_cast<uint8_t>(ycbcrInfo.fXChromaOffset) << kXChromaOffsetShift);
  85. ycbcrKey |= (static_cast<uint8_t>(ycbcrInfo.fYChromaOffset) << kYChromaOffsetShift);
  86. ycbcrKey |= (static_cast<uint8_t>(ycbcrInfo.fChromaFilter) << kChromaFilterShift);
  87. ycbcrKey |= (static_cast<uint8_t>(ycbcrInfo.fForceExplicitReconstruction) << kReconShift);
  88. return {ycbcrInfo.fExternalFormat, ycbcrKey};
  89. }