Revert "Add support for Ycbcr Conversion Samplers in vulkan."
This reverts commit 6cd74900da
.
Reason for revert: breaking win vulkan bots
Original change's description:
> Add support for Ycbcr Conversion Samplers in vulkan.
>
> The only thing missing from this CL is that we need to bake the
> ycbcr conversion samplers into the VkPipeline when we create it. As that
> is a larger change, that will be broken up into a few follow on CLs.
>
> Currently this only supports ycbcr conversion samplers when used with
> external textures.
>
> Bug: skia:
> Change-Id: I23e95b19469093072589ebbbfb7926ab79dcdea9
> Reviewed-on: https://skia-review.googlesource.com/c/164602
> Reviewed-by: Brian Salomon <bsalomon@google.com>
> Reviewed-by: Jim Van Verth <jvanverth@google.com>
> Commit-Queue: Greg Daniel <egdaniel@google.com>
TBR=egdaniel@google.com,jvanverth@google.com,bsalomon@google.com
Change-Id: Ib56905821cbfd40cf30ec89269b551ce01605a1a
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:
Reviewed-on: https://skia-review.googlesource.com/c/173982
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
This commit is contained in:
parent
6cd74900da
commit
f4bf973592
@ -635,8 +635,6 @@ skia_vk_sources = [
|
||||
"$_src/gpu/vk/GrVkResourceProvider.h",
|
||||
"$_src/gpu/vk/GrVkSampler.cpp",
|
||||
"$_src/gpu/vk/GrVkSampler.h",
|
||||
"$_src/gpu/vk/GrVkSamplerYcbcrConversion.cpp",
|
||||
"$_src/gpu/vk/GrVkSamplerYcbcrConversion.h",
|
||||
"$_src/gpu/vk/GrVkSemaphore.cpp",
|
||||
"$_src/gpu/vk/GrVkSemaphore.h",
|
||||
"$_src/gpu/vk/GrVkStencilAttachment.cpp",
|
||||
|
@ -48,14 +48,9 @@ public:
|
||||
}
|
||||
|
||||
static GrBackendFormat MakeVk(VkFormat format) {
|
||||
return GrBackendFormat(format, GrVkYcbcrConversionInfo());
|
||||
return GrBackendFormat(format);
|
||||
}
|
||||
|
||||
// This is used for external textures and the VkFormat is assumed to be VK_FORMAT_UNDEFINED.
|
||||
// This call is only supported on Android since the GrVkYcbcrConvesionInfo contains an android
|
||||
// external format.
|
||||
static GrBackendFormat MakeVk(const GrVkYcbcrConversionInfo& ycbcrInfo);
|
||||
|
||||
#ifdef SK_METAL
|
||||
static GrBackendFormat MakeMtl(GrMTLPixelFormat format) {
|
||||
return GrBackendFormat(format);
|
||||
@ -78,8 +73,6 @@ public:
|
||||
// it returns nullptr
|
||||
const VkFormat* getVkFormat() const;
|
||||
|
||||
const GrVkYcbcrConversionInfo* getVkYcbcrConversionInfo() const;
|
||||
|
||||
#ifdef SK_METAL
|
||||
// If the backend API is Metal, this returns a pointer to a GrMTLPixelFormat. Otherwise
|
||||
// it returns nullptr
|
||||
@ -99,7 +92,7 @@ public:
|
||||
private:
|
||||
GrBackendFormat(GrGLenum format, GrGLenum target);
|
||||
|
||||
GrBackendFormat(const VkFormat vkFormat, const GrVkYcbcrConversionInfo&);
|
||||
GrBackendFormat(const VkFormat vkFormat);
|
||||
|
||||
#ifdef SK_METAL
|
||||
GrBackendFormat(const GrMTLPixelFormat mtlFormat);
|
||||
@ -112,10 +105,7 @@ private:
|
||||
|
||||
union {
|
||||
GrGLenum fGLFormat; // the sized, internal format of the GL resource
|
||||
struct {
|
||||
VkFormat fFormat;
|
||||
GrVkYcbcrConversionInfo fYcbcrConversionInfo;
|
||||
} fVk;
|
||||
VkFormat fVkFormat;
|
||||
#ifdef SK_METAL
|
||||
GrMTLPixelFormat fMtlFormat;
|
||||
#endif
|
||||
|
@ -64,73 +64,14 @@ private:
|
||||
friend class GrVkHeap; // For access to usesSystemHeap
|
||||
bool fUsesSystemHeap;
|
||||
};
|
||||
|
||||
// This struct is used to pass in the necessary information to create a VkSamplerYcbcrConversion
|
||||
// object for an VkExternalFormatANDROID.
|
||||
struct GrVkYcbcrConversionInfo {
|
||||
GrVkYcbcrConversionInfo()
|
||||
: fYcbcrModel(VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY)
|
||||
, fYcbcrRange(VK_SAMPLER_YCBCR_RANGE_ITU_FULL)
|
||||
, fXChromaOffset(VK_CHROMA_LOCATION_COSITED_EVEN)
|
||||
, fYChromaOffset(VK_CHROMA_LOCATION_COSITED_EVEN)
|
||||
, fChromaFilter(VK_FILTER_NEAREST)
|
||||
, fForceExplicitReconstruction(false)
|
||||
, fExternalFormat(0)
|
||||
, fExternalFormatFeatures(0) {}
|
||||
|
||||
GrVkYcbcrConversionInfo(VkSamplerYcbcrModelConversion ycbcrModel,
|
||||
VkSamplerYcbcrRange ycbcrRange,
|
||||
VkChromaLocation xChromaOffset,
|
||||
VkChromaLocation yChromaOffset,
|
||||
VkFilter chromaFilter,
|
||||
VkBool32 forceExplicitReconstruction,
|
||||
uint64_t externalFormat,
|
||||
VkFormatFeatureFlags externalFormatFeatures)
|
||||
: fYcbcrModel(ycbcrModel)
|
||||
, fYcbcrRange(ycbcrRange)
|
||||
, fXChromaOffset(xChromaOffset)
|
||||
, fYChromaOffset(yChromaOffset)
|
||||
, fChromaFilter(chromaFilter)
|
||||
, fForceExplicitReconstruction(forceExplicitReconstruction)
|
||||
, fExternalFormat(externalFormat)
|
||||
, fExternalFormatFeatures(externalFormatFeatures) {}
|
||||
|
||||
bool operator==(const GrVkYcbcrConversionInfo& that) const {
|
||||
return this->fYcbcrModel == that.fYcbcrModel &&
|
||||
this->fYcbcrRange == that.fYcbcrRange &&
|
||||
this->fXChromaOffset == that.fXChromaOffset &&
|
||||
this->fYChromaOffset == that.fYChromaOffset &&
|
||||
this->fChromaFilter == that.fChromaFilter &&
|
||||
this->fForceExplicitReconstruction == that.fForceExplicitReconstruction &&
|
||||
this->fExternalFormat == that.fExternalFormat;
|
||||
// We don't check fExternalFormatFeatures here since all matching external formats must have
|
||||
// the same format features at least in terms of how they effect ycbcr sampler conversion.
|
||||
}
|
||||
|
||||
bool isValid() const { return fExternalFormat != 0; }
|
||||
|
||||
VkSamplerYcbcrModelConversion fYcbcrModel;
|
||||
VkSamplerYcbcrRange fYcbcrRange;
|
||||
VkChromaLocation fXChromaOffset;
|
||||
VkChromaLocation fYChromaOffset;
|
||||
VkFilter fChromaFilter;
|
||||
VkBool32 fForceExplicitReconstruction;
|
||||
// The external format should be compatible to be used in a VkExternalFormatANDROID struct
|
||||
uint64_t fExternalFormat;
|
||||
// The format features here should be those returned by a call to
|
||||
// vkAndroidHardwareBufferFormatPropertiesANDROID
|
||||
VkFormatFeatureFlags fExternalFormatFeatures;
|
||||
};
|
||||
|
||||
struct GrVkImageInfo {
|
||||
VkImage fImage;
|
||||
GrVkAlloc fAlloc;
|
||||
VkImageTiling fImageTiling;
|
||||
VkImageLayout fImageLayout;
|
||||
VkFormat fFormat;
|
||||
uint32_t fLevelCount;
|
||||
uint32_t fCurrentQueueFamily;
|
||||
GrVkYcbcrConversionInfo fYcbcrConversionInfo;
|
||||
VkImage fImage;
|
||||
GrVkAlloc fAlloc;
|
||||
VkImageTiling fImageTiling;
|
||||
VkImageLayout fImageLayout;
|
||||
VkFormat fFormat;
|
||||
uint32_t fLevelCount;
|
||||
uint32_t fCurrentQueueFamily;
|
||||
|
||||
GrVkImageInfo()
|
||||
: fImage(VK_NULL_HANDLE)
|
||||
@ -139,21 +80,18 @@ struct GrVkImageInfo {
|
||||
, fImageLayout(VK_IMAGE_LAYOUT_UNDEFINED)
|
||||
, fFormat(VK_FORMAT_UNDEFINED)
|
||||
, fLevelCount(0)
|
||||
, fCurrentQueueFamily(VK_QUEUE_FAMILY_IGNORED)
|
||||
, fYcbcrConversionInfo() {}
|
||||
, fCurrentQueueFamily(VK_QUEUE_FAMILY_IGNORED) {}
|
||||
|
||||
GrVkImageInfo(VkImage image, GrVkAlloc alloc, VkImageTiling imageTiling, VkImageLayout layout,
|
||||
VkFormat format, uint32_t levelCount,
|
||||
uint32_t currentQueueFamily = VK_QUEUE_FAMILY_IGNORED,
|
||||
GrVkYcbcrConversionInfo ycbcrConversionInfo = GrVkYcbcrConversionInfo())
|
||||
uint32_t currentQueueFamily = VK_QUEUE_FAMILY_IGNORED)
|
||||
: fImage(image)
|
||||
, fAlloc(alloc)
|
||||
, fImageTiling(imageTiling)
|
||||
, fImageLayout(layout)
|
||||
, fFormat(format)
|
||||
, fLevelCount(levelCount)
|
||||
, fCurrentQueueFamily(currentQueueFamily)
|
||||
, fYcbcrConversionInfo(ycbcrConversionInfo) {}
|
||||
, fCurrentQueueFamily(currentQueueFamily) {}
|
||||
|
||||
GrVkImageInfo(const GrVkImageInfo& info, VkImageLayout layout)
|
||||
: fImage(info.fImage)
|
||||
@ -162,8 +100,7 @@ struct GrVkImageInfo {
|
||||
, fImageLayout(layout)
|
||||
, fFormat(info.fFormat)
|
||||
, fLevelCount(info.fLevelCount)
|
||||
, fCurrentQueueFamily(info.fCurrentQueueFamily)
|
||||
, fYcbcrConversionInfo(info.fYcbcrConversionInfo) {}
|
||||
, fCurrentQueueFamily(info.fCurrentQueueFamily) {}
|
||||
|
||||
// This gives a way for a client to update the layout of the Image if they change the layout
|
||||
// while we're still holding onto the wrapped texture. They will first need to get a handle
|
||||
@ -173,9 +110,7 @@ struct GrVkImageInfo {
|
||||
bool operator==(const GrVkImageInfo& that) const {
|
||||
return fImage == that.fImage && fAlloc == that.fAlloc &&
|
||||
fImageTiling == that.fImageTiling && fImageLayout == that.fImageLayout &&
|
||||
fFormat == that.fFormat && fLevelCount == that.fLevelCount &&
|
||||
fCurrentQueueFamily == that.fCurrentQueueFamily &&
|
||||
fYcbcrConversionInfo == that.fYcbcrConversionInfo;
|
||||
fFormat == that.fFormat && fLevelCount == that.fLevelCount;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -63,36 +63,20 @@ const GrGLenum* GrBackendFormat::getGLTarget() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrBackendFormat GrBackendFormat::MakeVk(const GrVkYcbcrConversionInfo& ycbcrInfo) {
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
return GrBackendFormat(VK_FORMAT_UNDEFINED, ycbcrInfo);
|
||||
#else
|
||||
return GrBackendFormat();
|
||||
#endif
|
||||
}
|
||||
|
||||
GrBackendFormat::GrBackendFormat(VkFormat vkFormat, const GrVkYcbcrConversionInfo& ycbcrInfo)
|
||||
GrBackendFormat::GrBackendFormat(VkFormat vkFormat)
|
||||
: fBackend(GrBackendApi::kVulkan)
|
||||
#ifdef SK_VULKAN
|
||||
, fValid(true)
|
||||
#else
|
||||
, fValid(false)
|
||||
#endif
|
||||
, fVkFormat(vkFormat)
|
||||
, fTextureType(GrTextureType::k2D) {
|
||||
fVk.fFormat = vkFormat;
|
||||
fVk.fYcbcrConversionInfo = ycbcrInfo;
|
||||
}
|
||||
|
||||
const VkFormat* GrBackendFormat::getVkFormat() const {
|
||||
if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
|
||||
return &fVk.fFormat;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const GrVkYcbcrConversionInfo* GrBackendFormat::getVkYcbcrConversionInfo() const {
|
||||
if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
|
||||
return &fVk.fYcbcrConversionInfo;
|
||||
return &fVkFormat;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -194,27 +194,6 @@ bool GrVkCaps::canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* s
|
||||
srcConfig, SkToBool(src->asTextureProxy()));
|
||||
}
|
||||
|
||||
template<typename T> T* get_extension_feature_struct(const VkPhysicalDeviceFeatures2& features,
|
||||
VkStructureType type) {
|
||||
// All Vulkan structs that could be part of the features chain will start with the
|
||||
// structure type followed by the pNext pointer. We cast to the CommonVulkanHeader
|
||||
// so we can get access to the pNext for the next struct.
|
||||
struct CommonVulkanHeader {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
};
|
||||
|
||||
void* pNext = features.pNext;
|
||||
while (pNext) {
|
||||
CommonVulkanHeader* header = static_cast<CommonVulkanHeader*>(pNext);
|
||||
if (header->sType == type) {
|
||||
return static_cast<T*>(pNext);
|
||||
}
|
||||
pNext = header->pNext;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
|
||||
VkPhysicalDevice physDev, const VkPhysicalDeviceFeatures2& features,
|
||||
const GrVkExtensions& extensions) {
|
||||
@ -284,24 +263,6 @@ void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface*
|
||||
}
|
||||
#endif
|
||||
|
||||
auto ycbcrFeatures =
|
||||
get_extension_feature_struct<VkPhysicalDeviceSamplerYcbcrConversionFeatures>(
|
||||
features,
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES);
|
||||
if (ycbcrFeatures && ycbcrFeatures->samplerYcbcrConversion &&
|
||||
fSupportsAndroidHWBExternalMemory &&
|
||||
(physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
|
||||
(extensions.hasExtension(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, 1) &&
|
||||
this->supportsMaintenance1() &&
|
||||
this->supportsBindMemory2() &&
|
||||
this->supportsMemoryRequirements2() &&
|
||||
this->supportsPhysicalDeviceProperties2()))) {
|
||||
fSupportsYcbcrConversion = true;
|
||||
}
|
||||
// We always push back the default GrVkYcbcrConversionInfo so that the case of no conversion
|
||||
// will return a key of 0.
|
||||
fYcbcrInfos.push_back(GrVkYcbcrConversionInfo());
|
||||
|
||||
this->initGrCaps(vkInterface, physDev, properties, memoryProperties, features, extensions);
|
||||
this->initShaderCaps(properties, features);
|
||||
|
||||
@ -415,6 +376,27 @@ int get_max_sample_count(VkSampleCountFlags flags) {
|
||||
return 64;
|
||||
}
|
||||
|
||||
template<typename T> T* get_extension_feature_struct(const VkPhysicalDeviceFeatures2& features,
|
||||
VkStructureType type) {
|
||||
// All Vulkan structs that could be part of the features chain will start with the
|
||||
// structure type followed by the pNext pointer. We cast to the CommonVulkanHeader
|
||||
// so we can get access to the pNext for the next struct.
|
||||
struct CommonVulkanHeader {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
};
|
||||
|
||||
void* pNext = features.pNext;
|
||||
while (pNext) {
|
||||
CommonVulkanHeader* header = static_cast<CommonVulkanHeader*>(pNext);
|
||||
if (header->sType == type) {
|
||||
return static_cast<T*>(pNext);
|
||||
}
|
||||
pNext = header->pNext;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void GrVkCaps::initGrCaps(const GrVkInterface* vkInterface,
|
||||
VkPhysicalDevice physDev,
|
||||
const VkPhysicalDeviceProperties& properties,
|
||||
@ -846,10 +828,6 @@ GrBackendFormat GrVkCaps::onCreateFormatFromBackendTexture(
|
||||
const GrBackendTexture& backendTex) const {
|
||||
GrVkImageInfo vkInfo;
|
||||
SkAssertResult(backendTex.getVkImageInfo(&vkInfo));
|
||||
if (vkInfo.fYcbcrConversionInfo.isValid()) {
|
||||
SkASSERT(vkInfo.fFormat == VK_FORMAT_UNDEFINED);
|
||||
return GrBackendFormat::MakeVk(vkInfo.fYcbcrConversionInfo);
|
||||
}
|
||||
return GrBackendFormat::MakeVk(vkInfo.fFormat);
|
||||
}
|
||||
|
||||
|
@ -130,9 +130,6 @@ public:
|
||||
// Returns true if the device supports importing Android hardware buffers into Vulkan memory.
|
||||
bool supportsAndroidHWBExternalMemory() const { return fSupportsAndroidHWBExternalMemory; }
|
||||
|
||||
// Returns true if it supports ycbcr conversion for samplers
|
||||
bool supportsYcbcrConversion() const { return fSupportsYcbcrConversion; }
|
||||
|
||||
/**
|
||||
* Helpers used by canCopySurface. In all cases if the SampleCnt parameter is zero that means
|
||||
* the surface is not a render target, otherwise it is the number of samples in the render
|
||||
@ -197,8 +194,6 @@ private:
|
||||
void initConfigTable(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&);
|
||||
void initStencilFormat(const GrVkInterface* iface, VkPhysicalDevice physDev);
|
||||
|
||||
uint8_t getYcbcrKeyFromYcbcrInfo(const GrVkYcbcrConversionInfo& info);
|
||||
|
||||
void applyDriverCorrectnessWorkarounds(const VkPhysicalDeviceProperties&);
|
||||
|
||||
struct ConfigInfo {
|
||||
@ -226,8 +221,6 @@ private:
|
||||
|
||||
StencilFormat fPreferredStencilFormat;
|
||||
|
||||
SkSTArray<1, GrVkYcbcrConversionInfo> fYcbcrInfos;
|
||||
|
||||
bool fMustDoCopiesFromOrigin = false;
|
||||
bool fMustSubmitCommandsBeforeCopyOp = false;
|
||||
bool fMustSleepOnTearDown = false;
|
||||
@ -245,8 +238,6 @@ private:
|
||||
bool fSupportsExternalMemory = false;
|
||||
bool fSupportsAndroidHWBExternalMemory = false;
|
||||
|
||||
bool fSupportsYcbcrConversion = false;
|
||||
|
||||
typedef GrCaps INHERITED;
|
||||
};
|
||||
|
||||
|
@ -261,8 +261,7 @@ bool GrVkCopyManager::copySurfaceAsDraw(GrVkGpu* gpu,
|
||||
|
||||
GrSamplerState samplerState = GrSamplerState::ClampNearest();
|
||||
|
||||
GrVkSampler* sampler = resourceProv.findOrCreateCompatibleSampler(
|
||||
samplerState, GrVkYcbcrConversionInfo());
|
||||
GrVkSampler* sampler = resourceProv.findOrCreateCompatibleSampler(samplerState);
|
||||
|
||||
VkDescriptorImageInfo imageInfo;
|
||||
memset(&imageInfo, 0, sizeof(VkDescriptorImageInfo));
|
||||
|
@ -870,17 +870,15 @@ bool GrVkGpu::updateBuffer(GrVkBuffer* buffer, const void* src,
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool check_image_info(const GrVkCaps& caps,
|
||||
const GrVkImageInfo& info,
|
||||
GrPixelConfig config) {
|
||||
if (VK_NULL_HANDLE == info.fImage || VK_NULL_HANDLE == info.fAlloc.fMemory) {
|
||||
static bool check_backend_texture(const GrBackendTexture& backendTex,
|
||||
GrPixelConfig config) {
|
||||
GrVkImageInfo info;
|
||||
if (!backendTex.getVkImageInfo(&info)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (info.fYcbcrConversionInfo.isValid()) {
|
||||
if (!caps.supportsYcbcrConversion() || info.fFormat != VK_NULL_HANDLE) {
|
||||
return false;
|
||||
}
|
||||
if (VK_NULL_HANDLE == info.fImage || VK_NULL_HANDLE == info.fAlloc.fMemory) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SkASSERT(GrVkFormatPixelConfigPairIsValid(info.fFormat, config));
|
||||
@ -889,12 +887,7 @@ static bool check_image_info(const GrVkCaps& caps,
|
||||
|
||||
sk_sp<GrTexture> GrVkGpu::onWrapBackendTexture(const GrBackendTexture& backendTex,
|
||||
GrWrapOwnership ownership, bool purgeImmediately) {
|
||||
GrVkImageInfo imageInfo;
|
||||
if (!backendTex.getVkImageInfo(&imageInfo)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!check_image_info(this->vkCaps(), imageInfo, backendTex.config())) {
|
||||
if (!check_backend_texture(backendTex, backendTex.config())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -905,6 +898,10 @@ sk_sp<GrTexture> GrVkGpu::onWrapBackendTexture(const GrBackendTexture& backendTe
|
||||
surfDesc.fConfig = backendTex.config();
|
||||
surfDesc.fSampleCnt = 1;
|
||||
|
||||
GrVkImageInfo imageInfo;
|
||||
if (!backendTex.getVkImageInfo(&imageInfo)) {
|
||||
return nullptr;
|
||||
}
|
||||
sk_sp<GrVkImageLayout> layout = backendTex.getGrVkImageLayout();
|
||||
SkASSERT(layout);
|
||||
return GrVkTexture::MakeWrappedTexture(this, surfDesc, ownership, purgeImmediately,
|
||||
@ -914,12 +911,7 @@ sk_sp<GrTexture> GrVkGpu::onWrapBackendTexture(const GrBackendTexture& backendTe
|
||||
sk_sp<GrTexture> GrVkGpu::onWrapRenderableBackendTexture(const GrBackendTexture& backendTex,
|
||||
int sampleCnt,
|
||||
GrWrapOwnership ownership) {
|
||||
GrVkImageInfo imageInfo;
|
||||
if (!backendTex.getVkImageInfo(&imageInfo)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!check_image_info(this->vkCaps(), imageInfo, backendTex.config())) {
|
||||
if (!check_backend_texture(backendTex, backendTex.config())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -930,6 +922,10 @@ sk_sp<GrTexture> GrVkGpu::onWrapRenderableBackendTexture(const GrBackendTexture&
|
||||
surfDesc.fConfig = backendTex.config();
|
||||
surfDesc.fSampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, backendTex.config());
|
||||
|
||||
GrVkImageInfo imageInfo;
|
||||
if (!backendTex.getVkImageInfo(&imageInfo)) {
|
||||
return nullptr;
|
||||
}
|
||||
sk_sp<GrVkImageLayout> layout = backendTex.getGrVkImageLayout();
|
||||
SkASSERT(layout);
|
||||
|
||||
|
@ -48,7 +48,6 @@ public:
|
||||
return GrBackendFormat::MakeVk(this->imageFormat());
|
||||
}
|
||||
uint32_t mipLevels() const { return fInfo.fLevelCount; }
|
||||
GrVkYcbcrConversionInfo ycbcrConversionInfo() const { return fInfo.fYcbcrConversionInfo; }
|
||||
const Resource* resource() const { return fResource; }
|
||||
bool isLinearTiled() const {
|
||||
return SkToBool(VK_IMAGE_TILING_LINEAR == fInfo.fImageTiling);
|
||||
|
@ -7,37 +7,16 @@
|
||||
|
||||
#include "GrVkImageView.h"
|
||||
#include "GrVkGpu.h"
|
||||
#include "GrVkSamplerYcbcrConversion.h"
|
||||
#include "GrVkUtil.h"
|
||||
|
||||
const GrVkImageView* GrVkImageView::Create(GrVkGpu* gpu, VkImage image, VkFormat format,
|
||||
Type viewType, uint32_t miplevels,
|
||||
const GrVkYcbcrConversionInfo& ycbcrInfo) {
|
||||
|
||||
void* pNext = nullptr;
|
||||
VkSamplerYcbcrConversionInfo conversionInfo;
|
||||
GrVkSamplerYcbcrConversion* ycbcrConversion = nullptr;
|
||||
|
||||
if (ycbcrInfo.isValid()) {
|
||||
SkASSERT(gpu->vkCaps().supportsYcbcrConversion() && format == VK_FORMAT_UNDEFINED);
|
||||
|
||||
ycbcrConversion =
|
||||
gpu->resourceProvider().findOrCreateCompatibleSamplerYcbcrConversion(ycbcrInfo);
|
||||
if (!ycbcrConversion) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
conversionInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO;
|
||||
conversionInfo.pNext = nullptr;
|
||||
conversionInfo.conversion = ycbcrConversion->ycbcrConversion();
|
||||
pNext = &conversionInfo;
|
||||
}
|
||||
|
||||
const GrVkImageView* GrVkImageView::Create(const GrVkGpu* gpu, VkImage image, VkFormat format,
|
||||
Type viewType, uint32_t miplevels) {
|
||||
VkImageView imageView;
|
||||
|
||||
// Create the VkImageView
|
||||
VkImageViewCreateInfo viewInfo = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // sType
|
||||
pNext, // pNext
|
||||
NULL, // pNext
|
||||
0, // flags
|
||||
image, // image
|
||||
VK_IMAGE_VIEW_TYPE_2D, // viewType
|
||||
@ -58,20 +37,9 @@ const GrVkImageView* GrVkImageView::Create(GrVkGpu* gpu, VkImage image, VkFormat
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new GrVkImageView(imageView, ycbcrConversion);
|
||||
return new GrVkImageView(imageView);
|
||||
}
|
||||
|
||||
void GrVkImageView::freeGPUData(const GrVkGpu* gpu) const {
|
||||
GR_VK_CALL(gpu->vkInterface(), DestroyImageView(gpu->device(), fImageView, nullptr));
|
||||
|
||||
if (fYcbcrConversion) {
|
||||
fYcbcrConversion->unref(gpu);
|
||||
}
|
||||
}
|
||||
|
||||
void GrVkImageView::abandonGPUData() const {
|
||||
if (fYcbcrConversion) {
|
||||
fYcbcrConversion->unrefAndAbandon();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,9 +13,6 @@
|
||||
#include "GrTypes.h"
|
||||
#include "GrVkResource.h"
|
||||
|
||||
class GrVkSamplerYcbcrConversion;
|
||||
struct GrVkYcbcrConversionInfo;
|
||||
|
||||
class GrVkImageView : public GrVkResource {
|
||||
public:
|
||||
enum Type {
|
||||
@ -23,9 +20,8 @@ public:
|
||||
kStencil_Type
|
||||
};
|
||||
|
||||
static const GrVkImageView* Create(GrVkGpu* gpu, VkImage image, VkFormat format,
|
||||
Type viewType, uint32_t miplevels,
|
||||
const GrVkYcbcrConversionInfo& ycbcrInfo);
|
||||
static const GrVkImageView* Create(const GrVkGpu* gpu, VkImage image, VkFormat format,
|
||||
Type viewType, uint32_t miplevels);
|
||||
|
||||
VkImageView imageView() const { return fImageView; }
|
||||
|
||||
@ -36,17 +32,14 @@ public:
|
||||
#endif
|
||||
|
||||
private:
|
||||
GrVkImageView(VkImageView imageView, GrVkSamplerYcbcrConversion* ycbcrConversion)
|
||||
: INHERITED(), fImageView(imageView), fYcbcrConversion(ycbcrConversion) {}
|
||||
GrVkImageView(VkImageView imageView) : INHERITED(), fImageView(imageView) {}
|
||||
|
||||
GrVkImageView(const GrVkImageView&);
|
||||
GrVkImageView& operator=(const GrVkImageView&);
|
||||
|
||||
void freeGPUData(const GrVkGpu* gpu) const override;
|
||||
void abandonGPUData() const override;
|
||||
|
||||
VkImageView fImageView;
|
||||
GrVkSamplerYcbcrConversion* fYcbcrConversion;
|
||||
|
||||
typedef GrVkResource INHERITED;
|
||||
};
|
||||
|
@ -243,8 +243,7 @@ void GrVkPipelineState::setAndBindTextures(GrVkGpu* gpu,
|
||||
GrVkTexture* texture = samplerBindings[i].fTexture;
|
||||
|
||||
const GrVkImageView* textureView = texture->textureView();
|
||||
GrVkSampler* sampler = gpu->resourceProvider().findOrCreateCompatibleSampler(
|
||||
state, texture->ycbcrConversionInfo());
|
||||
GrVkSampler* sampler = gpu->resourceProvider().findOrCreateCompatibleSampler(state);
|
||||
|
||||
VkDescriptorImageInfo imageInfo;
|
||||
memset(&imageInfo, 0, sizeof(VkDescriptorImageInfo));
|
||||
|
@ -148,8 +148,7 @@ GrVkRenderTarget::MakeWrappedRenderTarget(GrVkGpu* gpu,
|
||||
|
||||
// Create Resolve attachment view
|
||||
resolveAttachmentView = GrVkImageView::Create(gpu, info.fImage, pixelFormat,
|
||||
GrVkImageView::kColor_Type, 1,
|
||||
GrVkYcbcrConversionInfo());
|
||||
GrVkImageView::kColor_Type, 1);
|
||||
if (!resolveAttachmentView) {
|
||||
GrVkImage::DestroyImageInfo(gpu, &msInfo);
|
||||
return nullptr;
|
||||
@ -162,8 +161,7 @@ GrVkRenderTarget::MakeWrappedRenderTarget(GrVkGpu* gpu,
|
||||
|
||||
// Get color attachment view
|
||||
const GrVkImageView* colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat,
|
||||
GrVkImageView::kColor_Type, 1,
|
||||
GrVkYcbcrConversionInfo());
|
||||
GrVkImageView::kColor_Type, 1);
|
||||
if (!colorAttachmentView) {
|
||||
if (desc.fSampleCnt > 1) {
|
||||
resolveAttachmentView->unref(gpu);
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "GrVkGpu.h"
|
||||
#include "GrVkPipeline.h"
|
||||
#include "GrVkRenderTarget.h"
|
||||
#include "GrVkSampler.h"
|
||||
#include "GrVkUniformBuffer.h"
|
||||
#include "GrVkUtil.h"
|
||||
|
||||
@ -165,14 +166,10 @@ GrVkDescriptorPool* GrVkResourceProvider::findOrCreateCompatibleDescriptorPool(
|
||||
return new GrVkDescriptorPool(fGpu, type, count);
|
||||
}
|
||||
|
||||
GrVkSampler* GrVkResourceProvider::findOrCreateCompatibleSampler(
|
||||
const GrSamplerState& params, const GrVkYcbcrConversionInfo& ycbcrInfo) {
|
||||
GrVkSampler* sampler = fSamplers.find(GrVkSampler::GenerateKey(params, ycbcrInfo));
|
||||
GrVkSampler* GrVkResourceProvider::findOrCreateCompatibleSampler(const GrSamplerState& params) {
|
||||
GrVkSampler* sampler = fSamplers.find(GrVkSampler::GenerateKey(params));
|
||||
if (!sampler) {
|
||||
sampler = GrVkSampler::Create(fGpu, params, ycbcrInfo);
|
||||
if (!sampler) {
|
||||
return nullptr;
|
||||
}
|
||||
sampler = GrVkSampler::Create(fGpu, params);
|
||||
fSamplers.add(sampler);
|
||||
}
|
||||
SkASSERT(sampler);
|
||||
@ -180,22 +177,6 @@ GrVkSampler* GrVkResourceProvider::findOrCreateCompatibleSampler(
|
||||
return sampler;
|
||||
}
|
||||
|
||||
GrVkSamplerYcbcrConversion* GrVkResourceProvider::findOrCreateCompatibleSamplerYcbcrConversion(
|
||||
const GrVkYcbcrConversionInfo& ycbcrInfo) {
|
||||
GrVkSamplerYcbcrConversion* ycbcrConversion =
|
||||
fYcbcrConversions.find(GrVkSamplerYcbcrConversion::GenerateKey(ycbcrInfo));
|
||||
if (!ycbcrConversion) {
|
||||
ycbcrConversion = GrVkSamplerYcbcrConversion::Create(fGpu, ycbcrInfo);
|
||||
if (!ycbcrConversion) {
|
||||
return nullptr;
|
||||
}
|
||||
fYcbcrConversions.add(ycbcrConversion);
|
||||
}
|
||||
SkASSERT(ycbcrConversion);
|
||||
ycbcrConversion->ref();
|
||||
return ycbcrConversion;
|
||||
}
|
||||
|
||||
GrVkPipelineState* GrVkResourceProvider::findOrCreateCompatiblePipelineState(
|
||||
const GrPipeline& pipeline, const GrPrimitiveProcessor& proc, GrPrimitiveType primitiveType,
|
||||
VkRenderPass compatibleRenderPass) {
|
||||
@ -368,7 +349,7 @@ void GrVkResourceProvider::destroyResources(bool deviceLost) {
|
||||
fRenderPassArray.reset();
|
||||
|
||||
// Iterate through all store GrVkSamplers and unref them before resetting the hash.
|
||||
SkTDynamicHash<GrVkSampler, GrVkSampler::Key>::Iter iter(&fSamplers);
|
||||
SkTDynamicHash<GrVkSampler, uint8_t>::Iter iter(&fSamplers);
|
||||
for (; !iter.done(); ++iter) {
|
||||
(*iter).unref(fGpu);
|
||||
}
|
||||
@ -427,7 +408,7 @@ void GrVkResourceProvider::abandonResources() {
|
||||
fRenderPassArray.reset();
|
||||
|
||||
// Iterate through all store GrVkSamplers and unrefAndAbandon them before resetting the hash.
|
||||
SkTDynamicHash<GrVkSampler, GrVkSampler::Key>::Iter iter(&fSamplers);
|
||||
SkTDynamicHash<GrVkSampler, uint8_t>::Iter iter(&fSamplers);
|
||||
for (; !iter.done(); ++iter) {
|
||||
(*iter).unrefAndAbandon();
|
||||
}
|
||||
|
@ -16,8 +16,6 @@
|
||||
#include "GrVkPipelineStateBuilder.h"
|
||||
#include "GrVkRenderPass.h"
|
||||
#include "GrVkResource.h"
|
||||
#include "GrVkSampler.h"
|
||||
#include "GrVkSamplerYcbcrConversion.h"
|
||||
#include "GrVkUtil.h"
|
||||
#include "SkLRUCache.h"
|
||||
#include "SkTArray.h"
|
||||
@ -33,6 +31,7 @@ class GrVkPipeline;
|
||||
class GrVkPipelineState;
|
||||
class GrVkPrimaryCommandBuffer;
|
||||
class GrVkRenderTarget;
|
||||
class GrVkSampler;
|
||||
class GrVkSecondaryCommandBuffer;
|
||||
class GrVkUniformHandler;
|
||||
|
||||
@ -98,15 +97,9 @@ public:
|
||||
// of our cache of GrVkDescriptorPools.
|
||||
GrVkDescriptorPool* findOrCreateCompatibleDescriptorPool(VkDescriptorType type, uint32_t count);
|
||||
|
||||
// Finds or creates a compatible GrVkSampler based on the GrSamplerState and
|
||||
// GrVkYcbcrConversionInfo. The refcount is incremented and a pointer returned.
|
||||
GrVkSampler* findOrCreateCompatibleSampler(const GrSamplerState&,
|
||||
const GrVkYcbcrConversionInfo& ycbcrInfo);
|
||||
|
||||
// Finds or creates a compatible GrVkSamplerYcbcrConversion based on the GrSamplerState and
|
||||
// GrVkYcbcrConversionInfo. The refcount is incremented and a pointer returned.
|
||||
GrVkSamplerYcbcrConversion* findOrCreateCompatibleSamplerYcbcrConversion(
|
||||
const GrVkYcbcrConversionInfo& ycbcrInfo);
|
||||
// Finds or creates a compatible GrVkSampler based on the GrSamplerState.
|
||||
// The refcount is incremented and a pointer returned.
|
||||
GrVkSampler* findOrCreateCompatibleSampler(const GrSamplerState&);
|
||||
|
||||
GrVkPipelineState* findOrCreateCompatiblePipelineState(const GrPipeline&,
|
||||
const GrPrimitiveProcessor&,
|
||||
@ -259,10 +252,7 @@ private:
|
||||
|
||||
// Stores GrVkSampler objects that we've already created so we can reuse them across multiple
|
||||
// GrVkPipelineStates
|
||||
SkTDynamicHash<GrVkSampler, GrVkSampler::Key> fSamplers;
|
||||
|
||||
// Stores GrVkSamplerYcbcrConversion objects that we've already created so we can reuse them.
|
||||
SkTDynamicHash<GrVkSamplerYcbcrConversion, GrVkSamplerYcbcrConversion::Key> fYcbcrConversions;
|
||||
SkTDynamicHash<GrVkSampler, uint8_t> fSamplers;
|
||||
|
||||
// Cache of GrVkPipelineStates
|
||||
PipelineStateCache* fPipelineStateCache;
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include "GrVkSampler.h"
|
||||
|
||||
#include "GrVkGpu.h"
|
||||
#include "GrVkSamplerYcbcrConversion.h"
|
||||
|
||||
static inline VkSamplerAddressMode wrap_mode_to_vk_sampler_address(
|
||||
GrSamplerState::WrapMode wrapMode) {
|
||||
@ -24,8 +23,7 @@ static inline VkSamplerAddressMode wrap_mode_to_vk_sampler_address(
|
||||
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
}
|
||||
|
||||
GrVkSampler* GrVkSampler::Create(GrVkGpu* gpu, const GrSamplerState& samplerState,
|
||||
const GrVkYcbcrConversionInfo& ycbcrInfo) {
|
||||
GrVkSampler* GrVkSampler::Create(const GrVkGpu* gpu, const GrSamplerState& samplerState) {
|
||||
static VkFilter vkMinFilterModes[] = {
|
||||
VK_FILTER_NEAREST,
|
||||
VK_FILTER_LINEAR,
|
||||
@ -40,7 +38,7 @@ GrVkSampler* GrVkSampler::Create(GrVkGpu* gpu, const GrSamplerState& samplerStat
|
||||
VkSamplerCreateInfo createInfo;
|
||||
memset(&createInfo, 0, sizeof(VkSamplerCreateInfo));
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
createInfo.pNext = nullptr;
|
||||
createInfo.pNext = 0;
|
||||
createInfo.flags = 0;
|
||||
createInfo.magFilter = vkMagFilterModes[static_cast<int>(samplerState.filter())];
|
||||
createInfo.minFilter = vkMinFilterModes[static_cast<int>(samplerState.filter())];
|
||||
@ -64,80 +62,32 @@ GrVkSampler* GrVkSampler::Create(GrVkGpu* gpu, const GrSamplerState& samplerStat
|
||||
createInfo.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
|
||||
createInfo.unnormalizedCoordinates = VK_FALSE;
|
||||
|
||||
VkSamplerYcbcrConversionInfo conversionInfo;
|
||||
GrVkSamplerYcbcrConversion* ycbcrConversion = nullptr;
|
||||
if (ycbcrInfo.isValid()) {
|
||||
SkASSERT(gpu->vkCaps().supportsYcbcrConversion());
|
||||
|
||||
ycbcrConversion =
|
||||
gpu->resourceProvider().findOrCreateCompatibleSamplerYcbcrConversion(ycbcrInfo);
|
||||
if (!ycbcrConversion) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
conversionInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO;
|
||||
conversionInfo.pNext = nullptr;
|
||||
conversionInfo.conversion = ycbcrConversion->ycbcrConversion();
|
||||
|
||||
createInfo.pNext = &conversionInfo;
|
||||
|
||||
const VkFormatFeatureFlags& flags = ycbcrInfo.fExternalFormatFeatures;
|
||||
|
||||
if (!SkToBool(flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT)) {
|
||||
createInfo.magFilter = VK_FILTER_NEAREST;
|
||||
createInfo.minFilter = VK_FILTER_NEAREST;
|
||||
} else if (
|
||||
!(flags &
|
||||
VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT)) {
|
||||
createInfo.magFilter = ycbcrInfo.fChromaFilter;
|
||||
createInfo.minFilter = ycbcrInfo.fChromaFilter;
|
||||
}
|
||||
|
||||
// Required values when using ycbcr conversion
|
||||
createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
createInfo.anisotropyEnable = VK_FALSE;
|
||||
createInfo.unnormalizedCoordinates = VK_FALSE;
|
||||
}
|
||||
|
||||
VkSampler sampler;
|
||||
GR_VK_CALL_ERRCHECK(gpu->vkInterface(), CreateSampler(gpu->device(),
|
||||
&createInfo,
|
||||
nullptr,
|
||||
&sampler));
|
||||
|
||||
return new GrVkSampler(sampler, ycbcrConversion, GenerateKey(samplerState, ycbcrInfo));
|
||||
return new GrVkSampler(sampler, GenerateKey(samplerState));
|
||||
}
|
||||
|
||||
void GrVkSampler::freeGPUData(const GrVkGpu* gpu) const {
|
||||
SkASSERT(fSampler);
|
||||
GR_VK_CALL(gpu->vkInterface(), DestroySampler(gpu->device(), fSampler, nullptr));
|
||||
if (fYcbcrConversion) {
|
||||
fYcbcrConversion->unref(gpu);
|
||||
}
|
||||
}
|
||||
|
||||
void GrVkSampler::abandonGPUData() const {
|
||||
if (fYcbcrConversion) {
|
||||
fYcbcrConversion->unrefAndAbandon();
|
||||
}
|
||||
}
|
||||
|
||||
GrVkSampler::Key GrVkSampler::GenerateKey(const GrSamplerState& samplerState,
|
||||
const GrVkYcbcrConversionInfo& ycbcrInfo) {
|
||||
uint8_t GrVkSampler::GenerateKey(const GrSamplerState& samplerState) {
|
||||
const int kTileModeXShift = 2;
|
||||
const int kTileModeYShift = 4;
|
||||
|
||||
SkASSERT(static_cast<int>(samplerState.filter()) <= 3);
|
||||
uint8_t samplerKey = static_cast<uint16_t>(samplerState.filter());
|
||||
uint8_t key = static_cast<uint8_t>(samplerState.filter());
|
||||
|
||||
SkASSERT(static_cast<int>(samplerState.wrapModeX()) <= 3);
|
||||
samplerKey |= (static_cast<uint8_t>(samplerState.wrapModeX()) << kTileModeXShift);
|
||||
key |= (static_cast<uint8_t>(samplerState.wrapModeX()) << kTileModeXShift);
|
||||
|
||||
SkASSERT(static_cast<int>(samplerState.wrapModeY()) <= 3);
|
||||
samplerKey |= (static_cast<uint8_t>(samplerState.wrapModeY()) << kTileModeYShift);
|
||||
key |= (static_cast<uint8_t>(samplerState.wrapModeY()) << kTileModeYShift);
|
||||
|
||||
return {samplerKey, GrVkSamplerYcbcrConversion::GenerateKey(ycbcrInfo)};
|
||||
return key;
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrVkSampler_DEFINED
|
||||
#define GrVkSampler_DEFINED
|
||||
@ -11,43 +11,22 @@
|
||||
#include "GrVkVulkan.h"
|
||||
|
||||
#include "GrVkResource.h"
|
||||
#include "GrVkSamplerYcbcrConversion.h"
|
||||
#include "SkOpts.h"
|
||||
#include "vk/GrVkTypes.h"
|
||||
|
||||
class GrSamplerState;
|
||||
class GrVkGpu;
|
||||
|
||||
|
||||
class GrVkSampler : public GrVkResource {
|
||||
public:
|
||||
static GrVkSampler* Create(GrVkGpu* gpu, const GrSamplerState&, const GrVkYcbcrConversionInfo&);
|
||||
static GrVkSampler* Create(const GrVkGpu* gpu, const GrSamplerState&);
|
||||
|
||||
VkSampler sampler() const { return fSampler; }
|
||||
|
||||
struct Key {
|
||||
Key(uint16_t samplerKey, const GrVkSamplerYcbcrConversion::Key& ycbcrKey) {
|
||||
// We must memset here since the GrVkSamplerYcbcrConversion has a 64 bit value which may
|
||||
// force alignment padding to occur in the middle of the Key struct.
|
||||
memset(this, 0, sizeof(Key));
|
||||
fSamplerKey = samplerKey;
|
||||
fYcbcrKey = ycbcrKey;
|
||||
}
|
||||
uint16_t fSamplerKey;
|
||||
GrVkSamplerYcbcrConversion::Key fYcbcrKey;
|
||||
|
||||
bool operator==(const Key& that) const {
|
||||
return this->fSamplerKey == that.fSamplerKey &&
|
||||
this->fYcbcrKey == that.fYcbcrKey;
|
||||
}
|
||||
};
|
||||
|
||||
// Helpers for hashing GrVkSampler
|
||||
static Key GenerateKey(const GrSamplerState&, const GrVkYcbcrConversionInfo&);
|
||||
static uint8_t GenerateKey(const GrSamplerState&);
|
||||
|
||||
static const Key& GetKey(const GrVkSampler& sampler) { return sampler.fKey; }
|
||||
static uint32_t Hash(const Key& key) {
|
||||
return SkOpts::hash(reinterpret_cast<const uint32_t*>(&key), sizeof(Key));
|
||||
}
|
||||
static const uint8_t& GetKey(const GrVkSampler& sampler) { return sampler.fKey; }
|
||||
static uint32_t Hash(const uint16_t& key) { return key; }
|
||||
|
||||
#ifdef SK_TRACE_VK_RESOURCES
|
||||
void dumpInfo() const override {
|
||||
@ -56,15 +35,12 @@ public:
|
||||
#endif
|
||||
|
||||
private:
|
||||
GrVkSampler(VkSampler sampler, GrVkSamplerYcbcrConversion* ycbcrConversion, Key key)
|
||||
: INHERITED(), fSampler(sampler), fYcbcrConversion(ycbcrConversion), fKey(key) {}
|
||||
GrVkSampler(VkSampler sampler, uint16_t key) : INHERITED(), fSampler(sampler), fKey(key) {}
|
||||
|
||||
void freeGPUData(const GrVkGpu* gpu) const override;
|
||||
void abandonGPUData() const override;
|
||||
|
||||
VkSampler fSampler;
|
||||
GrVkSamplerYcbcrConversion* fYcbcrConversion;
|
||||
Key fKey;
|
||||
VkSampler fSampler;
|
||||
uint8_t fKey;
|
||||
|
||||
typedef GrVkResource INHERITED;
|
||||
};
|
||||
|
@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "GrVkSamplerYcbcrConversion.h"
|
||||
|
||||
#include "GrVkGpu.h"
|
||||
|
||||
GrVkSamplerYcbcrConversion* GrVkSamplerYcbcrConversion::Create(
|
||||
const GrVkGpu* gpu, const GrVkYcbcrConversionInfo& info) {
|
||||
if (!gpu->vkCaps().supportsYcbcrConversion()) {
|
||||
return nullptr;
|
||||
}
|
||||
// We only support creating ycbcr conversion for external formats;
|
||||
SkASSERT(info.fExternalFormat);
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
const VkFormatFeatureFlags& featureFlags = info.fExternalFormatFeatures;
|
||||
if (info.fXChromaOffset == VK_CHROMA_LOCATION_MIDPOINT ||
|
||||
info.fYChromaOffset == VK_CHROMA_LOCATION_MIDPOINT) {
|
||||
SkASSERT(featureFlags & VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT);
|
||||
}
|
||||
if (info.fXChromaOffset == VK_CHROMA_LOCATION_COSITED_EVEN ||
|
||||
info.fYChromaOffset == VK_CHROMA_LOCATION_COSITED_EVEN) {
|
||||
SkASSERT(featureFlags & VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT);
|
||||
}
|
||||
if (info.fChromaFilter == VK_FILTER_LINEAR) {
|
||||
SkASSERT(featureFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT);
|
||||
}
|
||||
if (info.fForceExplicitReconstruction) {
|
||||
SkASSERT(featureFlags &
|
||||
VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
VkExternalFormatANDROID externalFormat;
|
||||
externalFormat.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID;
|
||||
externalFormat.pNext = nullptr;
|
||||
externalFormat.externalFormat = info.fExternalFormat;
|
||||
|
||||
VkSamplerYcbcrConversionCreateInfo ycbcrCreateInfo;
|
||||
memset(&ycbcrCreateInfo, 0, sizeof(VkSamplerYcbcrConversionCreateInfo));
|
||||
ycbcrCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO;
|
||||
ycbcrCreateInfo.pNext = &externalFormat;
|
||||
ycbcrCreateInfo.format = VK_FORMAT_UNDEFINED;
|
||||
ycbcrCreateInfo.ycbcrModel = info.fYcbcrModel;
|
||||
ycbcrCreateInfo.ycbcrRange = info.fYcbcrRange;
|
||||
// Componets is ignored for external format conversions;
|
||||
// ycbcrCreateInfo.components = {0, 0, 0, 0};
|
||||
ycbcrCreateInfo.xChromaOffset = info.fXChromaOffset;
|
||||
ycbcrCreateInfo.yChromaOffset = info.fYChromaOffset;
|
||||
ycbcrCreateInfo.chromaFilter = info.fChromaFilter;
|
||||
ycbcrCreateInfo.forceExplicitReconstruction = info.fForceExplicitReconstruction;
|
||||
|
||||
VkSamplerYcbcrConversion conversion;
|
||||
GR_VK_CALL(gpu->vkInterface(), CreateSamplerYcbcrConversion(gpu->device(), &ycbcrCreateInfo,
|
||||
nullptr, &conversion));
|
||||
if (conversion == VK_NULL_HANDLE) {
|
||||
return nullptr;
|
||||
}
|
||||
return new GrVkSamplerYcbcrConversion(conversion, GenerateKey(info));
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void GrVkSamplerYcbcrConversion::freeGPUData(const GrVkGpu* gpu) const {
|
||||
SkASSERT(fYcbcrConversion);
|
||||
GR_VK_CALL(gpu->vkInterface(), DestroySamplerYcbcrConversion(gpu->device(), fYcbcrConversion,
|
||||
nullptr));
|
||||
}
|
||||
|
||||
GrVkSamplerYcbcrConversion::Key GrVkSamplerYcbcrConversion::GenerateKey(
|
||||
const GrVkYcbcrConversionInfo& ycbcrInfo) {
|
||||
SkASSERT(static_cast<int>(ycbcrInfo.fYcbcrModel <= 7));
|
||||
static const int kRangeShift = 3;
|
||||
SkASSERT(static_cast<int>(ycbcrInfo.fYcbcrRange) <= 1);
|
||||
static const int kXChromaOffsetShift = kRangeShift + 1;
|
||||
SkASSERT(static_cast<int>(ycbcrInfo.fXChromaOffset) <= 1);
|
||||
static const int kYChromaOffsetShift = kXChromaOffsetShift + 1;
|
||||
SkASSERT(static_cast<int>(ycbcrInfo.fXChromaOffset) <= 1);
|
||||
static const int kChromaFilterShift = kYChromaOffsetShift + 1;
|
||||
SkASSERT(static_cast<int>(ycbcrInfo.fChromaFilter) <= 1);
|
||||
static const int kReconShift = kChromaFilterShift + 1;
|
||||
SkASSERT(static_cast<int>(ycbcrInfo.fForceExplicitReconstruction) <= 1);
|
||||
GR_STATIC_ASSERT(kReconShift <= 7);
|
||||
|
||||
uint8_t ycbcrKey = static_cast<uint8_t>(ycbcrInfo.fYcbcrModel);
|
||||
ycbcrKey |= (static_cast<uint8_t>(ycbcrInfo.fYcbcrRange) << kRangeShift);
|
||||
ycbcrKey |= (static_cast<uint8_t>(ycbcrInfo.fXChromaOffset) << kXChromaOffsetShift);
|
||||
ycbcrKey |= (static_cast<uint8_t>(ycbcrInfo.fYChromaOffset) << kYChromaOffsetShift);
|
||||
ycbcrKey |= (static_cast<uint8_t>(ycbcrInfo.fChromaFilter) << kChromaFilterShift);
|
||||
ycbcrKey |= (static_cast<uint8_t>(ycbcrInfo.fForceExplicitReconstruction) << kReconShift);
|
||||
|
||||
return {ycbcrInfo.fExternalFormat, ycbcrKey};
|
||||
}
|
||||
|
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrVkSamplerYcbcrConverison_DEFINED
|
||||
#define GrVkSamplerYcbcrConverison_DEFINED
|
||||
|
||||
#include "GrVkVulkan.h"
|
||||
|
||||
#include "GrVkResource.h"
|
||||
|
||||
#include "SkOpts.h"
|
||||
#include "vk/GrVkTypes.h"
|
||||
|
||||
class GrVkGpu;
|
||||
|
||||
class GrVkSamplerYcbcrConversion : public GrVkResource {
|
||||
public:
|
||||
static GrVkSamplerYcbcrConversion* Create(const GrVkGpu* gpu, const GrVkYcbcrConversionInfo&);
|
||||
|
||||
VkSamplerYcbcrConversion ycbcrConversion() const { return fYcbcrConversion; }
|
||||
|
||||
struct Key {
|
||||
Key() : fExternalFormat(0), fConversionKey(0) {}
|
||||
Key(uint64_t externalFormat, uint8_t conversionKey)
|
||||
: fExternalFormat(externalFormat), fConversionKey(conversionKey) {}
|
||||
|
||||
uint64_t fExternalFormat;
|
||||
uint8_t fConversionKey;
|
||||
|
||||
bool operator==(const Key& that) const {
|
||||
return this->fExternalFormat == that.fExternalFormat &&
|
||||
this->fConversionKey == that.fConversionKey;
|
||||
}
|
||||
};
|
||||
|
||||
// Helpers for hashing GrVkSamplerYcbcrConversion
|
||||
static Key GenerateKey(const GrVkYcbcrConversionInfo& ycbcrInfo);
|
||||
|
||||
static const Key& GetKey(const GrVkSamplerYcbcrConversion& ycbcrConversion) {
|
||||
return ycbcrConversion.fKey;
|
||||
}
|
||||
static uint32_t Hash(const Key& key) {
|
||||
return SkOpts::hash(reinterpret_cast<const uint32_t*>(&key), sizeof(Key));
|
||||
}
|
||||
|
||||
#ifdef SK_TRACE_VK_RESOURCES
|
||||
void dumpInfo() const override {
|
||||
SkDebugf("GrVkSamplerYcbcrConversion: %d (%d refs)\n", fYcbcrConversion, this->getRefCnt());
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
GrVkSamplerYcbcrConversion(VkSamplerYcbcrConversion ycbcrConversion, Key key)
|
||||
: INHERITED()
|
||||
, fYcbcrConversion(ycbcrConversion)
|
||||
, fKey(key) {}
|
||||
|
||||
void freeGPUData(const GrVkGpu* gpu) const override;
|
||||
|
||||
VkSamplerYcbcrConversion fYcbcrConversion;
|
||||
Key fKey;
|
||||
|
||||
typedef GrVkResource INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -51,8 +51,7 @@ GrVkStencilAttachment* GrVkStencilAttachment::Create(GrVkGpu* gpu,
|
||||
|
||||
const GrVkImageView* imageView = GrVkImageView::Create(gpu, info.fImage,
|
||||
format.fInternalFormat,
|
||||
GrVkImageView::kStencil_Type, 1,
|
||||
GrVkYcbcrConversionInfo());
|
||||
GrVkImageView::kStencil_Type, 1);
|
||||
if (!imageView) {
|
||||
GrVkImage::DestroyImageInfo(gpu, &info);
|
||||
return nullptr;
|
||||
|
@ -76,9 +76,9 @@ sk_sp<GrVkTexture> GrVkTexture::MakeNewTexture(GrVkGpu* gpu, SkBudgeted budgeted
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const GrVkImageView* imageView = GrVkImageView::Create(
|
||||
gpu, info.fImage, info.fFormat, GrVkImageView::kColor_Type, info.fLevelCount,
|
||||
info.fYcbcrConversionInfo);
|
||||
const GrVkImageView* imageView = GrVkImageView::Create(gpu, info.fImage, info.fFormat,
|
||||
GrVkImageView::kColor_Type,
|
||||
info.fLevelCount);
|
||||
if (!imageView) {
|
||||
GrVkImage::DestroyImageInfo(gpu, &info);
|
||||
return nullptr;
|
||||
@ -98,9 +98,9 @@ sk_sp<GrVkTexture> GrVkTexture::MakeWrappedTexture(GrVkGpu* gpu,
|
||||
// Wrapped textures require both image and allocation (because they can be mapped)
|
||||
SkASSERT(VK_NULL_HANDLE != info.fImage && VK_NULL_HANDLE != info.fAlloc.fMemory);
|
||||
|
||||
const GrVkImageView* imageView = GrVkImageView::Create(
|
||||
gpu, info.fImage, info.fFormat, GrVkImageView::kColor_Type, info.fLevelCount,
|
||||
info.fYcbcrConversionInfo);
|
||||
const GrVkImageView* imageView = GrVkImageView::Create(gpu, info.fImage, info.fFormat,
|
||||
GrVkImageView::kColor_Type,
|
||||
info.fLevelCount);
|
||||
if (!imageView) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -100,9 +100,9 @@ sk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::Make(GrVkGpu* gpu,
|
||||
bool isWrapped) {
|
||||
VkImage image = info.fImage;
|
||||
// Create the texture ImageView
|
||||
const GrVkImageView* imageView = GrVkImageView::Create(
|
||||
gpu, image, info.fFormat, GrVkImageView::kColor_Type, info.fLevelCount,
|
||||
info.fYcbcrConversionInfo);
|
||||
const GrVkImageView* imageView = GrVkImageView::Create(gpu, image, info.fFormat,
|
||||
GrVkImageView::kColor_Type,
|
||||
info.fLevelCount);
|
||||
if (!imageView) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -141,7 +141,7 @@ sk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::Make(GrVkGpu* gpu,
|
||||
// Create resolve attachment view.
|
||||
resolveAttachmentView = GrVkImageView::Create(gpu, image, pixelFormat,
|
||||
GrVkImageView::kColor_Type,
|
||||
info.fLevelCount, GrVkYcbcrConversionInfo());
|
||||
info.fLevelCount);
|
||||
if (!resolveAttachmentView) {
|
||||
GrVkImage::DestroyImageInfo(gpu, &msInfo);
|
||||
imageView->unref(gpu);
|
||||
@ -154,8 +154,7 @@ sk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::Make(GrVkGpu* gpu,
|
||||
}
|
||||
|
||||
const GrVkImageView* colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat,
|
||||
GrVkImageView::kColor_Type, 1,
|
||||
GrVkYcbcrConversionInfo());
|
||||
GrVkImageView::kColor_Type, 1);
|
||||
if (!colorAttachmentView) {
|
||||
if (desc.fSampleCnt > 1) {
|
||||
resolveAttachmentView->unref(gpu);
|
||||
@ -252,8 +251,7 @@ bool GrVkTextureRenderTarget::updateForMipmap(GrVkGpu* gpu, const GrVkImageInfo&
|
||||
newInfo.fImage,
|
||||
pixelFormat,
|
||||
GrVkImageView::kColor_Type,
|
||||
newInfo.fLevelCount,
|
||||
GrVkYcbcrConversionInfo());
|
||||
newInfo.fLevelCount);
|
||||
if (!resolveAttachmentView) {
|
||||
return false;
|
||||
}
|
||||
@ -264,8 +262,7 @@ bool GrVkTextureRenderTarget::updateForMipmap(GrVkGpu* gpu, const GrVkImageInfo&
|
||||
newInfo.fImage,
|
||||
pixelFormat,
|
||||
GrVkImageView::kColor_Type,
|
||||
1,
|
||||
GrVkYcbcrConversionInfo());
|
||||
1);
|
||||
if (!colorAttachmentView) {
|
||||
return false;
|
||||
}
|
||||
|
@ -75,7 +75,6 @@ bool GrPixelConfigToVkFormat(GrPixelConfig config, VkFormat* format) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
bool GrVkFormatPixelConfigPairIsValid(VkFormat format, GrPixelConfig config) {
|
||||
switch (format) {
|
||||
case VK_FORMAT_R8G8B8A8_UNORM:
|
||||
@ -114,7 +113,6 @@ bool GrVkFormatPixelConfigPairIsValid(VkFormat format, GrPixelConfig config) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool GrVkFormatIsSupported(VkFormat format) {
|
||||
switch (format) {
|
||||
|
@ -36,12 +36,10 @@ bool GrPixelConfigToVkFormat(GrPixelConfig config, VkFormat* format);
|
||||
|
||||
bool GrVkFormatIsSupported(VkFormat);
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
/**
|
||||
* Returns true if the passed in VkFormat and GrPixelConfig are compatible with each other.
|
||||
*/
|
||||
bool GrVkFormatPixelConfigPairIsValid(VkFormat, GrPixelConfig);
|
||||
#endif
|
||||
|
||||
bool GrSampleCountToVkSampleCount(uint32_t samples, VkSampleCountFlagBits* vkSamples);
|
||||
|
||||
|
@ -352,17 +352,6 @@ static void setup_extension_features(GrVkGetProc getProc, VkInstance inst, VkPhy
|
||||
tailPNext = &blend->pNext;
|
||||
}
|
||||
|
||||
VkPhysicalDeviceSamplerYcbcrConversionFeatures* ycbcrFeature = nullptr;
|
||||
if (physDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
|
||||
extensions->hasExtension(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, 1)) {
|
||||
ycbcrFeature = (VkPhysicalDeviceSamplerYcbcrConversionFeatures*) sk_malloc_throw(
|
||||
sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeatures));
|
||||
ycbcrFeature->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
|
||||
ycbcrFeature->pNext = nullptr;
|
||||
*tailPNext = ycbcrFeature;
|
||||
tailPNext = &ycbcrFeature->pNext;
|
||||
}
|
||||
|
||||
if (physDeviceVersion >= VK_MAKE_VERSION(1, 1, 0)) {
|
||||
ACQUIRE_VK_PROC_LOCAL(GetPhysicalDeviceFeatures2, inst, VK_NULL_HANDLE);
|
||||
grVkGetPhysicalDeviceFeatures2(physDev, features);
|
||||
|
Loading…
Reference in New Issue
Block a user