diff options
author | egdaniel <egdaniel@google.com> | 2016-04-01 10:10:45 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-04-01 10:10:45 -0700 |
commit | 8f1dcaa6f3cc098bd5efd2595ca20e0bc1847d10 (patch) | |
tree | 9dea85eef080ce98062f3dc16fc4d11ac06e9f35 /src | |
parent | 549c8991959333e5c0f53faebcbbd5d6bc8f6a56 (diff) |
Update vulkan format features in caps.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1847963003
Review URL: https://codereview.chromium.org/1847963003
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/vk/GrVkCaps.cpp | 163 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCaps.h | 72 | ||||
-rw-r--r-- | src/gpu/vk/GrVkGpu.cpp | 3 | ||||
-rw-r--r-- | src/gpu/vk/GrVkImage.cpp | 4 | ||||
-rw-r--r-- | src/gpu/vk/GrVkSampler.cpp | 5 |
5 files changed, 108 insertions, 139 deletions
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp index 88ff8ee3e0..7a1577e66c 100644 --- a/src/gpu/vk/GrVkCaps.cpp +++ b/src/gpu/vk/GrVkCaps.cpp @@ -57,9 +57,8 @@ void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface* this->initGrCaps(properties, memoryProperties, featureFlags); this->initGLSLCaps(properties, featureFlags); - this->initConfigTexturableTable(vkInterface, physDev); - this->initConfigRenderableTable(vkInterface, physDev); - this->initStencilFormats(vkInterface, physDev); + this->initConfigTable(vkInterface, physDev); + this->initStencilFormat(vkInterface, physDev); if (SkToBool(extensionFlags & kNV_glsl_shader_GrVkExtensionFlag)) { // Currently disabling this feature since it does not play well with validation layers which @@ -162,122 +161,70 @@ void GrVkCaps::initGLSLCaps(const VkPhysicalDeviceProperties& properties, properties.limits.maxDescriptorSetSamplers); } -static void format_supported_for_feature(const GrVkInterface* interface, - VkPhysicalDevice physDev, - VkFormat format, - VkFormatFeatureFlagBits featureBit, - bool* linearSupport, - bool* optimalSupport) { +bool stencil_format_supported(const GrVkInterface* interface, + VkPhysicalDevice physDev, + VkFormat format) { VkFormatProperties props; memset(&props, 0, sizeof(VkFormatProperties)); GR_VK_CALL(interface, GetPhysicalDeviceFormatProperties(physDev, format, &props)); - *linearSupport = SkToBool(props.linearTilingFeatures & featureBit); - *optimalSupport = SkToBool(props.optimalTilingFeatures & featureBit); + return SkToBool(VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT & props.optimalTilingFeatures); } -static void config_supported_for_feature(const GrVkInterface* interface, - VkPhysicalDevice physDev, - GrPixelConfig config, - VkFormatFeatureFlagBits featureBit, - bool* linearSupport, - bool* optimalSupport) { - VkFormat format; - if (!GrPixelConfigToVkFormat(config, &format)) { - *linearSupport = false; - *optimalSupport = false; - return; +void GrVkCaps::initStencilFormat(const GrVkInterface* interface, VkPhysicalDevice physDev) { + // List of legal stencil formats (though perhaps not supported on + // the particular gpu/driver) from most preferred to least. We are guaranteed to have either + // VK_FORMAT_D24_UNORM_S8_UINT or VK_FORMAT_D24_SFLOAT_S8_UINT. VK_FORMAT_D32_SFLOAT_S8_UINT + // can optionally have 24 unused bits at the end so we assume the total bits is 64. + static const StencilFormat + // internal Format stencil bits total bits packed? + gS8 = { VK_FORMAT_S8_UINT, 8, 8, false }, + gD24S8 = { VK_FORMAT_D24_UNORM_S8_UINT, 8, 32, true }, + gD32S8 = { VK_FORMAT_D32_SFLOAT_S8_UINT, 8, 64, true }; + + if (stencil_format_supported(interface, physDev, VK_FORMAT_S8_UINT)) { + fPreferedStencilFormat = gS8; + } else if (stencil_format_supported(interface, physDev, VK_FORMAT_D24_UNORM_S8_UINT)) { + fPreferedStencilFormat = gD24S8; + } else { + SkASSERT(stencil_format_supported(interface, physDev, VK_FORMAT_D32_SFLOAT_S8_UINT)); + fPreferedStencilFormat = gD32S8; } - format_supported_for_feature(interface, physDev, format, featureBit, - linearSupport, optimalSupport); } -// Currently just assumeing if something can be rendered to without MSAA it also works for MSAAA -#define SET_CONFIG_IS_RENDERABLE(config) \ - config_supported_for_feature(interface, \ - physDev, \ - config, \ - VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT, \ - &fConfigLinearRenderSupport[config][kNo_MSAA], \ - &fConfigRenderSupport[config][kNo_MSAA] ); \ - fConfigRenderSupport[config][kYes_MSAA] = fConfigRenderSupport[config][kNo_MSAA]; \ - fConfigLinearRenderSupport[config][kYes_MSAA] = fConfigLinearRenderSupport[config][kNo_MSAA]; - - -void GrVkCaps::initConfigRenderableTable(const GrVkInterface* interface, VkPhysicalDevice physDev) { - enum { - kNo_MSAA = 0, - kYes_MSAA = 1, - }; - - // Base render support - SET_CONFIG_IS_RENDERABLE(kAlpha_8_GrPixelConfig); - SET_CONFIG_IS_RENDERABLE(kRGB_565_GrPixelConfig); - SET_CONFIG_IS_RENDERABLE(kRGBA_4444_GrPixelConfig); - SET_CONFIG_IS_RENDERABLE(kRGBA_8888_GrPixelConfig); - SET_CONFIG_IS_RENDERABLE(kBGRA_8888_GrPixelConfig); - - SET_CONFIG_IS_RENDERABLE(kSRGBA_8888_GrPixelConfig); - - // Float render support - SET_CONFIG_IS_RENDERABLE(kRGBA_float_GrPixelConfig); - SET_CONFIG_IS_RENDERABLE(kRGBA_half_GrPixelConfig); - SET_CONFIG_IS_RENDERABLE(kAlpha_half_GrPixelConfig); +void GrVkCaps::initConfigTable(const GrVkInterface* interface, VkPhysicalDevice physDev) { + for (int i = 0; i < kGrPixelConfigCnt; ++i) { + VkFormat format; + if (GrPixelConfigToVkFormat(static_cast<GrPixelConfig>(i), &format)) { + fConfigTable[i].init(interface, physDev, format); + } + } } -#define SET_CONFIG_IS_TEXTURABLE(config) \ - config_supported_for_feature(interface, \ - physDev, \ - config, \ - VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, \ - &fConfigLinearTextureSupport[config], \ - &fConfigTextureSupport[config]); - -void GrVkCaps::initConfigTexturableTable(const GrVkInterface* interface, VkPhysicalDevice physDev) { - // Base texture support - SET_CONFIG_IS_TEXTURABLE(kAlpha_8_GrPixelConfig); - SET_CONFIG_IS_TEXTURABLE(kRGB_565_GrPixelConfig); - SET_CONFIG_IS_TEXTURABLE(kRGBA_4444_GrPixelConfig); - SET_CONFIG_IS_TEXTURABLE(kRGBA_8888_GrPixelConfig); - SET_CONFIG_IS_TEXTURABLE(kBGRA_8888_GrPixelConfig); - - SET_CONFIG_IS_TEXTURABLE(kIndex_8_GrPixelConfig); - SET_CONFIG_IS_TEXTURABLE(kSRGBA_8888_GrPixelConfig); - - // Compressed texture support - SET_CONFIG_IS_TEXTURABLE(kETC1_GrPixelConfig); - SET_CONFIG_IS_TEXTURABLE(kLATC_GrPixelConfig); - SET_CONFIG_IS_TEXTURABLE(kR11_EAC_GrPixelConfig); - SET_CONFIG_IS_TEXTURABLE(kASTC_12x12_GrPixelConfig); - - // Float texture support - SET_CONFIG_IS_TEXTURABLE(kRGBA_float_GrPixelConfig); - SET_CONFIG_IS_TEXTURABLE(kRGBA_half_GrPixelConfig); - SET_CONFIG_IS_TEXTURABLE(kAlpha_half_GrPixelConfig); -} +void GrVkCaps::ConfigInfo::InitConfigFlags(VkFormatFeatureFlags vkFlags, uint16_t* flags) { + if (SkToBool(VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT & vkFlags) && + SkToBool(VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT & vkFlags)) { + *flags = *flags | kTextureable_Flag; + } -#define SET_CONFIG_CAN_STENCIL(config) \ - bool SK_MACRO_APPEND_LINE(linearSupported); \ - bool SK_MACRO_APPEND_LINE(optimalSupported); \ - format_supported_for_feature(interface, \ - physDev, \ - config.fInternalFormat, \ - VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, \ - &SK_MACRO_APPEND_LINE(linearSupported), \ - &SK_MACRO_APPEND_LINE(optimalSupported)); \ - if (SK_MACRO_APPEND_LINE(linearSupported)) fLinearStencilFormats.push_back(config); \ - if (SK_MACRO_APPEND_LINE(optimalSupported)) fStencilFormats.push_back(config); - -void GrVkCaps::initStencilFormats(const GrVkInterface* interface, VkPhysicalDevice physDev) { - // Build up list of legal stencil formats (though perhaps not supported on - // the particular gpu/driver) from most preferred to least. + if (SkToBool(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT & vkFlags)) { + *flags = *flags | kRenderable_Flag; + } - static const StencilFormat - // internal Format stencil bits total bits packed? - gS8 = { VK_FORMAT_S8_UINT, 8, 8, false }, - gD24S8 = { VK_FORMAT_D24_UNORM_S8_UINT, 8, 32, true }; + if (SkToBool(VK_FORMAT_FEATURE_BLIT_SRC_BIT & vkFlags)) { + *flags = *flags | kBlitSrc_Flag; + } - // I'm simply assuming that these two will be supported since they are used in example code. - // TODO: Actaully figure this out - SET_CONFIG_CAN_STENCIL(gS8); - SET_CONFIG_CAN_STENCIL(gD24S8); + if (SkToBool(VK_FORMAT_FEATURE_BLIT_DST_BIT & vkFlags)) { + *flags = *flags | kBlitDst_Flag; + } +} + +void GrVkCaps::ConfigInfo::init(const GrVkInterface* interface, + VkPhysicalDevice physDev, + VkFormat format) { + VkFormatProperties props; + memset(&props, 0, sizeof(VkFormatProperties)); + GR_VK_CALL(interface, GetPhysicalDeviceFormatProperties(physDev, format, &props)); + InitConfigFlags(props.linearTilingFeatures, &fLinearFlags); + InitConfigFlags(props.optimalTilingFeatures, &fOptimalFlags); } diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h index 5834b151fd..0bd3801cbd 100644 --- a/src/gpu/vk/GrVkCaps.h +++ b/src/gpu/vk/GrVkCaps.h @@ -31,42 +31,48 @@ public: bool isConfigTexturable(GrPixelConfig config) const override { SkASSERT(kGrPixelConfigCnt > config); - return fConfigTextureSupport[config]; + return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fOptimalFlags); } bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const override { SkASSERT(kGrPixelConfigCnt > config); - return fConfigRenderSupport[config][withMSAA]; + return SkToBool(ConfigInfo::kRenderable_Flag & fConfigTable[config].fOptimalFlags); + } + + bool isConfigTexurableLinearly(GrPixelConfig config) const { + SkASSERT(kGrPixelConfigCnt > config); + return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fLinearFlags); } bool isConfigRenderableLinearly(GrPixelConfig config, bool withMSAA) const { SkASSERT(kGrPixelConfigCnt > config); - return fConfigLinearRenderSupport[config][withMSAA]; + return !withMSAA && SkToBool(ConfigInfo::kRenderable_Flag & + fConfigTable[config].fLinearFlags); } - bool isConfigTexurableLinearly(GrPixelConfig config) const { + bool configCanBeDstofBlit(GrPixelConfig config, bool linearTiled) const { SkASSERT(kGrPixelConfigCnt > config); - return fConfigLinearTextureSupport[config]; + const uint16_t& flags = linearTiled ? fConfigTable[config].fLinearFlags : + fConfigTable[config].fOptimalFlags; + return SkToBool(ConfigInfo::kBlitDst_Flag & flags); } - bool canUseGLSLForShaderModule() const { - return fCanUseGLSLForShaderModule; + bool configCanBeSrcofBlit(GrPixelConfig config, bool linearTiled) const { + SkASSERT(kGrPixelConfigCnt > config); + const uint16_t& flags = linearTiled ? fConfigTable[config].fLinearFlags : + fConfigTable[config].fOptimalFlags; + return SkToBool(ConfigInfo::kBlitSrc_Flag & flags); } - /** - * Gets an array of legal stencil formats. These formats are not guaranteed to be supported by - * the driver but are legal VK_TEXTURE_FORMATs. - */ - const SkTArray<StencilFormat, true>& stencilFormats() const { - return fStencilFormats; + bool canUseGLSLForShaderModule() const { + return fCanUseGLSLForShaderModule; } /** - * Gets an array of legal stencil formats. These formats are not guaranteed to be supported by - * the driver but are legal VK_TEXTURE_FORMATs. + * Returns both a supported and most prefered stencil format to use in draws. */ - const SkTArray<StencilFormat, true>& linearStencilFormats() const { - return fLinearStencilFormats; + const StencilFormat& preferedStencilFormat() const { + return fPreferedStencilFormat; } GrGLSLCaps* glslCaps() const { return reinterpret_cast<GrGLSLCaps*>(fShaderCaps.get()); } @@ -79,22 +85,30 @@ private: uint32_t featureFlags); void initGLSLCaps(const VkPhysicalDeviceProperties&, uint32_t featureFlags); void initSampleCount(const VkPhysicalDeviceProperties& properties); - void initConfigRenderableTable(const GrVkInterface* iface, VkPhysicalDevice physDev); - void initConfigTexturableTable(const GrVkInterface* iface, VkPhysicalDevice physDev); - void initStencilFormats(const GrVkInterface* iface, VkPhysicalDevice physDev); - bool fConfigTextureSupport[kGrPixelConfigCnt]; - // For Vulkan we track whether a config is supported linearly (without need for swizzling) - bool fConfigLinearTextureSupport[kGrPixelConfigCnt]; + void initConfigTable(const GrVkInterface*, VkPhysicalDevice); + void initStencilFormat(const GrVkInterface* iface, VkPhysicalDevice physDev); + + struct ConfigInfo { + ConfigInfo() : fOptimalFlags(0), fLinearFlags(0) {} + + void init(const GrVkInterface*, VkPhysicalDevice, VkFormat); + static void InitConfigFlags(VkFormatFeatureFlags, uint16_t* flags); - // The first entry for each config is without msaa and the second is with. - bool fConfigRenderSupport[kGrPixelConfigCnt][2]; - // The first entry for each config is without msaa and the second is with. - bool fConfigLinearRenderSupport[kGrPixelConfigCnt][2]; + enum { + kTextureable_Flag = 0x1, + kRenderable_Flag = 0x2, + kBlitSrc_Flag = 0x4, + kBlitDst_Flag = 0x8, + }; - SkTArray<StencilFormat, true> fLinearStencilFormats; - SkTArray<StencilFormat, true> fStencilFormats; + uint16_t fOptimalFlags; + uint16_t fLinearFlags; + }; + ConfigInfo fConfigTable[kGrPixelConfigCnt]; + + StencilFormat fPreferedStencilFormat; // Tells of if we can pass in straight GLSL string into vkCreateShaderModule bool fCanUseGLSLForShaderModule; diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp index de1e9052fa..55f1eae997 100644 --- a/src/gpu/vk/GrVkGpu.cpp +++ b/src/gpu/vk/GrVkGpu.cpp @@ -650,8 +650,7 @@ GrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRen int samples = rt->numStencilSamples(); - SkASSERT(this->vkCaps().stencilFormats().count()); - const GrVkCaps::StencilFormat& sFmt = this->vkCaps().stencilFormats()[0]; + const GrVkCaps::StencilFormat& sFmt = this->vkCaps().preferedStencilFormat(); GrVkStencilAttachment* stencil(GrVkStencilAttachment::Create(this, GrGpuResource::kCached_LifeCycle, diff --git a/src/gpu/vk/GrVkImage.cpp b/src/gpu/vk/GrVkImage.cpp index f91c6a9ee6..74136308ea 100644 --- a/src/gpu/vk/GrVkImage.cpp +++ b/src/gpu/vk/GrVkImage.cpp @@ -58,6 +58,10 @@ const GrVkImage::Resource* GrVkImage::CreateResource(const GrVkGpu* gpu, if (!GrSampleCountToVkSampleCount(imageDesc.fSamples, &vkSamples)) { return nullptr; } + + SkASSERT(VK_IMAGE_TILING_OPTIMAL == imageDesc.fImageTiling || + VK_SAMPLE_COUNT_1_BIT == vkSamples); + const VkImageCreateInfo imageCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType NULL, // pNext diff --git a/src/gpu/vk/GrVkSampler.cpp b/src/gpu/vk/GrVkSampler.cpp index fb8dacae87..75c2ee80d6 100644 --- a/src/gpu/vk/GrVkSampler.cpp +++ b/src/gpu/vk/GrVkSampler.cpp @@ -52,6 +52,11 @@ GrVkSampler* GrVkSampler::Create(const GrVkGpu* gpu, const GrTextureParams& para createInfo.maxAnisotropy = 1.0f; createInfo.compareEnable = VK_FALSE; createInfo.compareOp = VK_COMPARE_OP_NEVER; + // Vulkan doesn't have a direct mapping of GL's nearest or linear filters for minFilter since + // there is always a mipmapMode. To get the same effect as GL we can set minLod = maxLod = 0.0. + // This works since our min and mag filters are the same (this forces us to use mag on the 0 + // level mip). If the filters weren't the same we could set min = 0 and max = 0.25 to force + // the minFilter on mip level 0. createInfo.minLod = 0.0f; createInfo.maxLod = 0.0f; createInfo.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; |