aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar egdaniel <egdaniel@google.com>2016-03-28 12:14:42 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-03-28 12:14:43 -0700
commitc5ec1408298510410270ea67e895570ccfa76e54 (patch)
treec2fdfa5510db5978547929b493845cdd11bc0aa6
parent2be7e01382ee9c036de9c09585677dfd25d70253 (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.cpp15
-rw-r--r--src/gpu/vk/GrVkCaps.cpp18
-rw-r--r--src/gpu/vk/GrVkCaps.h11
-rw-r--r--src/gpu/vk/GrVkGpu.cpp2
-rw-r--r--src/gpu/vk/GrVkPipelineStateBuilder.cpp61
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;
}