Add MaxAPIVersion to GrVkBackendContext.

This moves us to the correct way of handling the correct version of
Vulkan that the client wants us to use.

Bug: skia:
Change-Id: I6c7962b5d2d48ae142c6a701c30f5af3801ac99b
Reviewed-on: https://skia-review.googlesource.com/c/187382
Reviewed-by: Sergey Ulanov <sergeyu@chromium.org>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Greg Daniel 2019-01-28 13:15:05 -05:00 committed by Skia Commit-Bot
parent 9850fd23a0
commit 41f0e28fd5
6 changed files with 61 additions and 23 deletions

View File

@ -49,7 +49,10 @@ struct SK_API GrVkBackendContext {
VkQueue fQueue;
uint32_t fGraphicsQueueIndex;
uint32_t fMinAPIVersion; // Deprecated. Set fInstanceVersion instead.
uint32_t fInstanceVersion = 0;
uint32_t fInstanceVersion = 0; // Deprecated. Set fMaxApiVersion instead.
// The max api version set here should match the value set in VkApplicationInfo::apiVersion when
// then VkInstance was created.
uint32_t fMaxAPIVersion = 0;
uint32_t fExtensions = 0; // Deprecated. Use fVkExtensions instead.
const GrVkExtensions* fVkExtensions = nullptr;
uint32_t fFeatures; // Deprecated. Use either fDeviceFeatures[2] instead.

View File

@ -18,7 +18,8 @@
GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
VkPhysicalDevice physDev, const VkPhysicalDeviceFeatures2& features,
uint32_t instanceVersion, const GrVkExtensions& extensions)
uint32_t instanceVersion, uint32_t physicalDeviceVersion,
const GrVkExtensions& extensions)
: INHERITED(contextOptions) {
/**************************************************************************
@ -48,7 +49,7 @@ GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface*
fShaderCaps.reset(new GrShaderCaps(contextOptions));
this->init(contextOptions, vkInterface, physDev, features, extensions);
this->init(contextOptions, vkInterface, physDev, features, physicalDeviceVersion, extensions);
}
bool GrVkCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
@ -230,7 +231,7 @@ template<typename T> T* get_extension_feature_struct(const VkPhysicalDeviceFeatu
void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
VkPhysicalDevice physDev, const VkPhysicalDeviceFeatures2& features,
const GrVkExtensions& extensions) {
uint32_t physicalDeviceVersion, const GrVkExtensions& extensions) {
VkPhysicalDeviceProperties properties;
GR_VK_CALL(vkInterface, GetPhysicalDeviceProperties(physDev, &properties));
@ -238,7 +239,7 @@ void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface*
VkPhysicalDeviceMemoryProperties memoryProperties;
GR_VK_CALL(vkInterface, GetPhysicalDeviceMemoryProperties(physDev, &memoryProperties));
uint32_t physicalDeviceVersion = properties.apiVersion;
SkASSERT(physicalDeviceVersion <= properties.apiVersion);
if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
extensions.hasExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 1)) {

View File

@ -29,7 +29,8 @@ public:
*/
GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
VkPhysicalDevice device, const VkPhysicalDeviceFeatures2& features,
uint32_t instanceVersion, const GrVkExtensions& extensions);
uint32_t instanceVersion, uint32_t physicalDeviceVersion,
const GrVkExtensions& extensions);
bool isConfigTexturable(GrPixelConfig config) const override {
return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fOptimalFlags);
@ -165,7 +166,8 @@ private:
};
void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
VkPhysicalDevice device, const VkPhysicalDeviceFeatures2&, const GrVkExtensions&);
VkPhysicalDevice device, const VkPhysicalDeviceFeatures2&,
uint32_t physicalDeviceVersion, const GrVkExtensions&);
void initGrCaps(const GrVkInterface* vkInterface,
VkPhysicalDevice physDev,
const VkPhysicalDeviceProperties&,

View File

@ -68,6 +68,21 @@ sk_sp<GrGpu> GrVkGpu::Make(const GrVkBackendContext& backendContext,
return nullptr;
}
PFN_vkEnumerateInstanceVersion localEnumerateInstanceVersion =
reinterpret_cast<PFN_vkEnumerateInstanceVersion>(
backendContext.fGetProc("vkEnumerateInstanceVersion",
VK_NULL_HANDLE, VK_NULL_HANDLE));
uint32_t instanceVersion = 0;
if (!localEnumerateInstanceVersion) {
instanceVersion = VK_MAKE_VERSION(1, 0, 0);
} else {
VkResult err = localEnumerateInstanceVersion(&instanceVersion);
if (err) {
SkDebugf("Failed to enumerate instance version. Err: %d\n", err);
return nullptr;
}
}
PFN_vkGetPhysicalDeviceProperties localGetPhysicalDeviceProperties =
reinterpret_cast<PFN_vkGetPhysicalDeviceProperties>(
backendContext.fGetProc("vkGetPhysicalDeviceProperties",
@ -81,17 +96,22 @@ sk_sp<GrGpu> GrVkGpu::Make(const GrVkBackendContext& backendContext,
localGetPhysicalDeviceProperties(backendContext.fPhysicalDevice, &physDeviceProperties);
uint32_t physDevVersion = physDeviceProperties.apiVersion;
uint32_t apiVersion = backendContext.fMaxAPIVersion ? backendContext.fMaxAPIVersion
: instanceVersion;
instanceVersion = SkTMin(instanceVersion, apiVersion);
physDevVersion = SkTMin(physDevVersion, apiVersion);
sk_sp<const GrVkInterface> interface;
if (backendContext.fVkExtensions) {
interface.reset(new GrVkInterface(backendContext.fGetProc,
backendContext.fInstance,
backendContext.fDevice,
backendContext.fInstanceVersion,
instanceVersion,
physDevVersion,
backendContext.fVkExtensions));
if (!interface->validate(backendContext.fInstanceVersion, physDevVersion,
backendContext.fVkExtensions)) {
if (!interface->validate(instanceVersion, physDevVersion, backendContext.fVkExtensions)) {
return nullptr;
}
} else {
@ -101,21 +121,23 @@ sk_sp<GrGpu> GrVkGpu::Make(const GrVkBackendContext& backendContext,
interface.reset(new GrVkInterface(backendContext.fGetProc,
backendContext.fInstance,
backendContext.fDevice,
backendContext.fInstanceVersion,
instanceVersion,
physDevVersion,
&extensions));
if (!interface->validate(backendContext.fInstanceVersion, physDevVersion, &extensions)) {
if (!interface->validate(instanceVersion, physDevVersion, &extensions)) {
return nullptr;
}
}
return sk_sp<GrGpu>(new GrVkGpu(context, options, backendContext, interface));
return sk_sp<GrGpu>(new GrVkGpu(context, options, backendContext, interface, instanceVersion,
physDevVersion));
}
////////////////////////////////////////////////////////////////////////////////
GrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options,
const GrVkBackendContext& backendContext, sk_sp<const GrVkInterface> interface)
const GrVkBackendContext& backendContext, sk_sp<const GrVkInterface> interface,
uint32_t instanceVersion, uint32_t physicalDeviceVersion)
: INHERITED(context)
, fInterface(std::move(interface))
, fMemoryAllocator(backendContext.fMemoryAllocator)
@ -136,19 +158,18 @@ GrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options,
fCompiler = new SkSL::Compiler();
uint32_t instanceVersion = backendContext.fInstanceVersion ? backendContext.fInstanceVersion
: backendContext.fMinAPIVersion;
if (backendContext.fDeviceFeatures2) {
fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendContext.fPhysicalDevice,
*backendContext.fDeviceFeatures2, instanceVersion,
physicalDeviceVersion,
*backendContext.fVkExtensions));
} else if (backendContext.fDeviceFeatures) {
VkPhysicalDeviceFeatures2 features2;
features2.pNext = nullptr;
features2.features = *backendContext.fDeviceFeatures;
fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendContext.fPhysicalDevice,
features2, instanceVersion, *backendContext.fVkExtensions));
features2, instanceVersion, physicalDeviceVersion,
*backendContext.fVkExtensions));
} else {
VkPhysicalDeviceFeatures2 features;
memset(&features, 0, sizeof(VkPhysicalDeviceFeatures2));
@ -163,7 +184,8 @@ GrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options,
features.features.sampleRateShading = true;
}
fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendContext.fPhysicalDevice,
features, instanceVersion, GrVkExtensions()));
features, instanceVersion, physicalDeviceVersion,
GrVkExtensions()));
}
fCaps.reset(SkRef(fVkCaps.get()));

View File

@ -175,7 +175,7 @@ public:
private:
GrVkGpu(GrContext*, const GrContextOptions&, const GrVkBackendContext&,
sk_sp<const GrVkInterface>);
sk_sp<const GrVkInterface>, uint32_t instanceVersion, uint32_t physicalDeviceVersion);
void onResetContext(uint32_t resetBits) override {}

View File

@ -397,6 +397,16 @@ bool CreateVkBackendContext(GrVkGetProc getProc,
}
}
SkASSERT(instanceVersion >= VK_MAKE_VERSION(1, 0, 0));
uint32_t apiVersion = VK_MAKE_VERSION(1, 0, 0);
if (instanceVersion >= VK_MAKE_VERSION(1, 1, 0)) {
// If the instance version is 1.0 we must have the apiVersion also be 1.0. However, if the
// instance version is 1.1 or higher, we can set the apiVersion to be whatever the highest
// api we may use in skia (technically it can be arbitrary). So for now we set it to 1.1
// since that is the highest vulkan version.
apiVersion = VK_MAKE_VERSION(1, 1, 0);
}
instanceVersion = SkTMin(instanceVersion, apiVersion);
VkPhysicalDevice physDev;
VkDevice device;
@ -409,7 +419,7 @@ bool CreateVkBackendContext(GrVkGetProc getProc,
0, // applicationVersion
"vktest", // pEngineName
0, // engineVerison
instanceVersion, // apiVersion
apiVersion, // apiVersion
};
SkTArray<VkLayerProperties> instanceLayers;
@ -512,7 +522,7 @@ bool CreateVkBackendContext(GrVkGetProc getProc,
VkPhysicalDeviceProperties physDeviceProperties;
grVkGetPhysicalDeviceProperties(physDev, &physDeviceProperties);
int physDeviceVersion = physDeviceProperties.apiVersion;
int physDeviceVersion = SkTMin(physDeviceProperties.apiVersion, apiVersion);
// query to get the initial queue props size
uint32_t queueCount;
@ -666,7 +676,7 @@ bool CreateVkBackendContext(GrVkGetProc getProc,
ctx->fDevice = device;
ctx->fQueue = queue;
ctx->fGraphicsQueueIndex = graphicsQueueIndex;
ctx->fInstanceVersion = instanceVersion;
ctx->fMaxAPIVersion = apiVersion;
ctx->fVkExtensions = extensions;
ctx->fDeviceFeatures2 = features;
ctx->fGetProc = getProc;