diff options
author | egdaniel <egdaniel@google.com> | 2016-03-28 12:14:42 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-03-28 12:14:43 -0700 |
commit | c5ec1408298510410270ea67e895570ccfa76e54 (patch) | |
tree | c2fdfa5510db5978547929b493845cdd11bc0aa6 | |
parent | 2be7e01382ee9c036de9c09585677dfd25d70253 (diff) |
Use NV glsl shader compiler for Vulkan
The nvidia direct glsl shader compiler seems to perform much better than using
shaderc to compile to spir-v first.
This change also includes a change to prefer host cached memory for buffers.
Having cached buffers signifcantly improves performance whenever we need to do
buffer reads and writes.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1835813003
Review URL: https://codereview.chromium.org/1835813003
-rw-r--r-- | src/gpu/vk/GrVkBuffer.cpp | 15 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCaps.cpp | 18 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCaps.h | 11 | ||||
-rw-r--r-- | src/gpu/vk/GrVkGpu.cpp | 2 | ||||
-rw-r--r-- | src/gpu/vk/GrVkPipelineStateBuilder.cpp | 61 |
5 files changed, 69 insertions, 38 deletions
diff --git a/src/gpu/vk/GrVkBuffer.cpp b/src/gpu/vk/GrVkBuffer.cpp index 0718fa5e92..24a593a9a7 100644 --- a/src/gpu/vk/GrVkBuffer.cpp +++ b/src/gpu/vk/GrVkBuffer.cpp @@ -57,14 +57,23 @@ const GrVkBuffer::Resource* GrVkBuffer::Create(const GrVkGpu* gpu, const Desc& d } VkMemoryPropertyFlags requiredMemProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | - VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | + VK_MEMORY_PROPERTY_HOST_CACHED_BIT; if (!GrVkMemory::AllocAndBindBufferMemory(gpu, buffer, requiredMemProps, &alloc)) { - VK_CALL(gpu, DestroyBuffer(gpu->device(), buffer, nullptr)); - return nullptr; + // Try again without requiring host cached memory + requiredMemProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + if (!GrVkMemory::AllocAndBindBufferMemory(gpu, + buffer, + requiredMemProps, + &alloc)) { + VK_CALL(gpu, DestroyBuffer(gpu->device(), buffer, nullptr)); + return nullptr; + } } const GrVkBuffer::Resource* resource = new GrVkBuffer::Resource(buffer, alloc); diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp index 6d1d844525..41bf1ad9e4 100644 --- a/src/gpu/vk/GrVkCaps.cpp +++ b/src/gpu/vk/GrVkCaps.cpp @@ -13,7 +13,10 @@ #include "vk/GrVkBackendContext.h" GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface, - VkPhysicalDevice physDev, uint32_t featureFlags) : INHERITED(contextOptions) { + VkPhysicalDevice physDev, uint32_t featureFlags, uint32_t extensionFlags) + : INHERITED(contextOptions) { + fCanUseGLSLForShaderModule = false; + /************************************************************************** * GrDrawTargetCaps fields **************************************************************************/ @@ -40,11 +43,11 @@ GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* fShaderCaps.reset(new GrGLSLCaps(contextOptions)); - this->init(contextOptions, vkInterface, physDev, featureFlags); + this->init(contextOptions, vkInterface, physDev, featureFlags, extensionFlags); } void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface, - VkPhysicalDevice physDev, uint32_t featureFlags) { + VkPhysicalDevice physDev, uint32_t featureFlags, uint32_t extensionFlags) { VkPhysicalDeviceProperties properties; GR_VK_CALL(vkInterface, GetPhysicalDeviceProperties(physDev, &properties)); @@ -58,12 +61,13 @@ void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface* this->initConfigRenderableTable(vkInterface, physDev); this->initStencilFormats(vkInterface, physDev); - + if (SkToBool(extensionFlags & kNV_glsl_shader_GrVkExtensionFlag)) { + fCanUseGLSLForShaderModule = true; + } this->applyOptionsOverrides(contextOptions); - // need to friend GrVkCaps in GrGLSLCaps.h - // GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get()); - // glslCaps->applyOptionsOverrides(contextOptions); + GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get()); + glslCaps->applyOptionsOverrides(contextOptions); } int get_max_sample_count(VkSampleCountFlags flags) { diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h index a2c9f1f35d..2137251d29 100644 --- a/src/gpu/vk/GrVkCaps.h +++ b/src/gpu/vk/GrVkCaps.h @@ -27,7 +27,7 @@ public: * be called to fill out the caps. */ GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface, - VkPhysicalDevice device, uint32_t featureFlags); + VkPhysicalDevice device, uint32_t featureFlags, uint32_t extensionFlags); bool isConfigTexturable(GrPixelConfig config) const override { SkASSERT(kGrPixelConfigCnt > config); @@ -49,6 +49,10 @@ public: return fConfigLinearTextureSupport[config]; } + 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. @@ -69,7 +73,7 @@ public: private: void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface, - VkPhysicalDevice device, uint32_t featureFlags); + VkPhysicalDevice device, uint32_t featureFlags, uint32_t extensionFlags); void initGrCaps(const VkPhysicalDeviceProperties&, const VkPhysicalDeviceMemoryProperties&, uint32_t featureFlags); @@ -92,6 +96,9 @@ private: SkTArray<StencilFormat, true> fLinearStencilFormats; SkTArray<StencilFormat, true> fStencilFormats; + // Tells of if we can pass in straight GLSL string into vkCreateShaderModule + bool fCanUseGLSLForShaderModule; + typedef GrCaps INHERITED; }; diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp index c4c32d12ff..e0aa2d2987 100644 --- a/src/gpu/vk/GrVkGpu.cpp +++ b/src/gpu/vk/GrVkGpu.cpp @@ -111,7 +111,7 @@ GrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options, fCompiler = shaderc_compiler_initialize(); fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendCtx->fPhysicalDevice, - backendCtx->fFeatures)); + backendCtx->fFeatures, backendCtx->fExtensions)); fCaps.reset(SkRef(fVkCaps.get())); VK_CALL(GetPhysicalDeviceMemoryProperties(backendCtx->fPhysicalDevice, &fPhysDevMemProps)); diff --git a/src/gpu/vk/GrVkPipelineStateBuilder.cpp b/src/gpu/vk/GrVkPipelineStateBuilder.cpp index 3b077f0125..f4bb566de1 100644 --- a/src/gpu/vk/GrVkPipelineStateBuilder.cpp +++ b/src/gpu/vk/GrVkPipelineStateBuilder.cpp @@ -89,41 +89,52 @@ bool GrVkPipelineStateBuilder::CreateVkShaderModule(const GrVkGpu* gpu, } } - shaderc_compiler_t compiler = gpu->shadercCompiler(); - - shaderc_compile_options_t options = shaderc_compile_options_initialize(); - shaderc_compile_options_set_forced_version_profile(options, 140, shaderc_profile_none); - - shaderc_shader_kind shadercStage = vk_shader_stage_to_shaderc_kind(stage); - shaderc_compilation_result_t result = shaderc_compile_into_spv(compiler, - shaderString.c_str(), - strlen(shaderString.c_str()), - shadercStage, - "shader", - "main", - options); - shaderc_compile_options_release(options); -#ifdef SK_DEBUG - if (shaderc_result_get_num_errors(result)) { - SkDebugf("%s\n", shaderString.c_str()); - SkDebugf("%s\n", shaderc_result_get_error_message(result)); - return false; - } -#endif - VkShaderModuleCreateInfo moduleCreateInfo; memset(&moduleCreateInfo, 0, sizeof(VkShaderModuleCreateInfo)); moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; moduleCreateInfo.pNext = nullptr; moduleCreateInfo.flags = 0; - moduleCreateInfo.codeSize = shaderc_result_get_length(result); - moduleCreateInfo.pCode = (const uint32_t*)shaderc_result_get_bytes(result); + + shaderc_compilation_result_t result; + + if (gpu->vkCaps().canUseGLSLForShaderModule()) { + moduleCreateInfo.codeSize = strlen(shaderString.c_str()); + moduleCreateInfo.pCode = (const uint32_t*)shaderString.c_str(); + } else { + + shaderc_compiler_t compiler = gpu->shadercCompiler(); + + shaderc_compile_options_t options = shaderc_compile_options_initialize(); + shaderc_compile_options_set_forced_version_profile(options, 140, shaderc_profile_none); + + shaderc_shader_kind shadercStage = vk_shader_stage_to_shaderc_kind(stage); + result = shaderc_compile_into_spv(compiler, + shaderString.c_str(), + strlen(shaderString.c_str()), + shadercStage, + "shader", + "main", + options); + shaderc_compile_options_release(options); +#ifdef SK_DEBUG + if (shaderc_result_get_num_errors(result)) { + SkDebugf("%s\n", shaderString.c_str()); + SkDebugf("%s\n", shaderc_result_get_error_message(result)); + return false; + } +#endif + + moduleCreateInfo.codeSize = shaderc_result_get_length(result); + moduleCreateInfo.pCode = (const uint32_t*)shaderc_result_get_bytes(result); + } VkResult err = GR_VK_CALL(gpu->vkInterface(), CreateShaderModule(gpu->device(), &moduleCreateInfo, nullptr, shaderModule)); - shaderc_result_release(result); + if (!gpu->vkCaps().canUseGLSLForShaderModule()) { + shaderc_result_release(result); + } if (err) { return false; } |