blob: 9abf14d8d9a8e725b06b0f6b7fa4f213920b5950 [file] [log] [blame]
/*
* 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 GrVkTypes_DEFINED
#define GrVkTypes_DEFINED
#include "include/core/SkTypes.h"
#include "include/gpu/vk/GrVkVulkan.h"
#ifndef VK_VERSION_1_1
#error Skia requires the use of Vulkan 1.1 headers
#endif
#include <functional>
#include "include/gpu/GrTypes.h"
typedef intptr_t GrVkBackendMemory;
/**
* Types for interacting with Vulkan resources created externally to Skia. GrBackendObjects for
* Vulkan textures are really const GrVkImageInfo*
*/
struct GrVkAlloc {
GrVkAlloc()
: fMemory(VK_NULL_HANDLE)
, fOffset(0)
, fSize(0)
, fFlags(0)
, fBackendMemory(0)
, fUsesSystemHeap(false) {}
GrVkAlloc(VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, uint32_t flags)
: fMemory(memory)
, fOffset(offset)
, fSize(size)
, fFlags(flags)
, fBackendMemory(0)
, fUsesSystemHeap(false) {}
VkDeviceMemory fMemory; // can be VK_NULL_HANDLE iff is an RT and is borrowed
VkDeviceSize fOffset;
VkDeviceSize fSize; // this can be indeterminate iff Tex uses borrow semantics
uint32_t fFlags;
GrVkBackendMemory fBackendMemory; // handle to memory allocated via GrVkMemoryAllocator.
enum Flag {
kNoncoherent_Flag = 0x1, // memory must be flushed to device after mapping
kMappable_Flag = 0x2, // memory is able to be mapped.
};
bool operator==(const GrVkAlloc& that) const {
return fMemory == that.fMemory && fOffset == that.fOffset && fSize == that.fSize &&
fFlags == that.fFlags && fUsesSystemHeap == that.fUsesSystemHeap;
}
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()
: fFormat(VK_FORMAT_UNDEFINED)
, fExternalFormat(0)
, 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) {}
GrVkYcbcrConversionInfo(VkFormat format,
int64_t externalFormat,
VkSamplerYcbcrModelConversion ycbcrModel,
VkSamplerYcbcrRange ycbcrRange,
VkChromaLocation xChromaOffset,
VkChromaLocation yChromaOffset,
VkFilter chromaFilter,
VkBool32 forceExplicitReconstruction,
VkFormatFeatureFlags formatFeatures)
: fFormat(format)
, fExternalFormat(externalFormat)
, fYcbcrModel(ycbcrModel)
, fYcbcrRange(ycbcrRange)
, fXChromaOffset(xChromaOffset)
, fYChromaOffset(yChromaOffset)
, fChromaFilter(chromaFilter)
, fForceExplicitReconstruction(forceExplicitReconstruction)
, fFormatFeatures(formatFeatures) {
SkASSERT(fYcbcrModel != VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY);
// Either format or externalFormat must be specified.
SkASSERT((fFormat != VK_FORMAT_UNDEFINED) ^ (externalFormat != 0));
}
GrVkYcbcrConversionInfo(VkSamplerYcbcrModelConversion ycbcrModel,
VkSamplerYcbcrRange ycbcrRange,
VkChromaLocation xChromaOffset,
VkChromaLocation yChromaOffset,
VkFilter chromaFilter,
VkBool32 forceExplicitReconstruction,
uint64_t externalFormat,
VkFormatFeatureFlags externalFormatFeatures)
: GrVkYcbcrConversionInfo(VK_FORMAT_UNDEFINED, externalFormat, ycbcrModel, ycbcrRange,
xChromaOffset, yChromaOffset, chromaFilter,
forceExplicitReconstruction, externalFormatFeatures) {}
bool operator==(const GrVkYcbcrConversionInfo& that) const {
// Invalid objects are not required to have all other fields initialized or matching.
if (!this->isValid() && !that.isValid()) {
return true;
}
return this->fFormat == that.fFormat &&
this->fExternalFormat == that.fExternalFormat &&
this->fYcbcrModel == that.fYcbcrModel &&
this->fYcbcrRange == that.fYcbcrRange &&
this->fXChromaOffset == that.fXChromaOffset &&
this->fYChromaOffset == that.fYChromaOffset &&
this->fChromaFilter == that.fChromaFilter &&
this->fForceExplicitReconstruction == that.fForceExplicitReconstruction;
}
bool operator!=(const GrVkYcbcrConversionInfo& that) const { return !(*this == that); }
bool isValid() const { return fYcbcrModel != VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY; }
// Format of the source image. Must be set to VK_FORMAT_UNDEFINED for external images or
// a valid image format otherwise.
VkFormat fFormat;
// The external format. Must be non-zero for external images, zero otherwise.
// Should be compatible to be used in a VkExternalFormatANDROID struct.
uint64_t fExternalFormat;
VkSamplerYcbcrModelConversion fYcbcrModel;
VkSamplerYcbcrRange fYcbcrRange;
VkChromaLocation fXChromaOffset;
VkChromaLocation fYChromaOffset;
VkFilter fChromaFilter;
VkBool32 fForceExplicitReconstruction;
// For external images format features here should be those returned by a call to
// vkAndroidHardwareBufferFormatPropertiesANDROID
VkFormatFeatureFlags fFormatFeatures;
};
struct GrVkImageInfo {
VkImage fImage;
GrVkAlloc fAlloc;
VkImageTiling fImageTiling;
VkImageLayout fImageLayout;
VkFormat fFormat;
uint32_t fLevelCount;
uint32_t fCurrentQueueFamily;
GrProtected fProtected;
GrVkYcbcrConversionInfo fYcbcrConversionInfo;
GrVkImageInfo()
: fImage(VK_NULL_HANDLE)
, fAlloc()
, fImageTiling(VK_IMAGE_TILING_OPTIMAL)
, fImageLayout(VK_IMAGE_LAYOUT_UNDEFINED)
, fFormat(VK_FORMAT_UNDEFINED)
, fLevelCount(0)
, fCurrentQueueFamily(VK_QUEUE_FAMILY_IGNORED)
, fProtected(GrProtected::kNo)
, fYcbcrConversionInfo() {}
GrVkImageInfo(VkImage image,
GrVkAlloc alloc,
VkImageTiling imageTiling,
VkImageLayout layout,
VkFormat format,
uint32_t levelCount,
uint32_t currentQueueFamily = VK_QUEUE_FAMILY_IGNORED,
GrProtected isProtected = GrProtected::kNo,
GrVkYcbcrConversionInfo ycbcrConversionInfo = GrVkYcbcrConversionInfo())
: fImage(image)
, fAlloc(alloc)
, fImageTiling(imageTiling)
, fImageLayout(layout)
, fFormat(format)
, fLevelCount(levelCount)
, fCurrentQueueFamily(currentQueueFamily)
, fProtected(isProtected)
, fYcbcrConversionInfo(ycbcrConversionInfo) {}
GrVkImageInfo(const GrVkImageInfo& info, VkImageLayout layout)
: fImage(info.fImage)
, fAlloc(info.fAlloc)
, fImageTiling(info.fImageTiling)
, fImageLayout(layout)
, fFormat(info.fFormat)
, fLevelCount(info.fLevelCount)
, fCurrentQueueFamily(info.fCurrentQueueFamily)
, fProtected(info.fProtected)
, fYcbcrConversionInfo(info.fYcbcrConversionInfo) {}
// 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
// to our internal GrVkImageInfo by calling getTextureHandle on a GrVkTexture.
void updateImageLayout(VkImageLayout layout) { fImageLayout = layout; }
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 && fProtected == that.fProtected &&
fYcbcrConversionInfo == that.fYcbcrConversionInfo;
}
};
using GrVkGetProc = std::function<PFN_vkVoidFunction(
const char*, // function name
VkInstance, // instance or VK_NULL_HANDLE
VkDevice // device or VK_NULL_HANDLE
)>;
/**
* This object is wrapped in a GrBackendDrawableInfo and passed in as an argument to
* drawBackendGpu() calls on an SkDrawable. The drawable will use this info to inject direct
* Vulkan calls into our stream of GPU draws.
*
* The SkDrawable is given a secondary VkCommandBuffer in which to record draws. The GPU backend
* will then execute that command buffer within a render pass it is using for its own draws. The
* drawable is also given the attachment of the color index, a compatible VkRenderPass, and the
* VkFormat of the color attachment so that it can make VkPipeline objects for the draws. The
* SkDrawable must not alter the state of the VkRenderpass or sub pass.
*
* Additionally, the SkDrawable may fill in the passed in fDrawBounds with the bounds of the draws
* that it submits to the command buffer. This will be used by the GPU backend for setting the
* bounds in vkCmdBeginRenderPass. If fDrawBounds is not updated, we will assume that the entire
* attachment may have been written to.
*
* The SkDrawable is always allowed to create its own command buffers and submit them to the queue
* to render offscreen textures which will be sampled in draws added to the passed in
* VkCommandBuffer. If this is done the SkDrawable is in charge of adding the required memory
* barriers to the queue for the sampled images since the Skia backend will not do this.
*
* The VkImage is informational only and should not be used or modified in any ways.
*/
struct GrVkDrawableInfo {
VkCommandBuffer fSecondaryCommandBuffer;
uint32_t fColorAttachmentIndex;
VkRenderPass fCompatibleRenderPass;
VkFormat fFormat;
VkRect2D* fDrawBounds;
VkImage fImage;
};
#endif