Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "gpu/vulkan/vulkan_shader_module.h" | |
| 6 | |
| 7 #include <memory> | |
| 8 #include <shaderc/shaderc.h> | |
| 9 #include <sstream> | |
| 10 | |
| 11 #include "base/logging.h" | |
| 12 #include "gpu/vulkan/vulkan_device_queue.h" | |
| 13 | |
| 14 class ShaderCCompiler { | |
|
piman
2016/05/16 23:35:31
Move this into an anonymous namespace, to avoid po
David Yen
2016/05/17 18:13:57
Done.
| |
| 15 public: | |
| 16 class CompilationResult { | |
| 17 public: | |
| 18 explicit CompilationResult(shaderc_compilation_result_t compilation_result) | |
| 19 : compilation_result_(compilation_result) {} | |
| 20 | |
| 21 ~CompilationResult() { shaderc_result_release(compilation_result_); } | |
| 22 | |
| 23 bool IsValid() const { | |
| 24 return shaderc_compilation_status_success == | |
| 25 shaderc_result_get_compilation_status(compilation_result_); | |
| 26 } | |
| 27 | |
| 28 std::string GetErrors() const { | |
| 29 return shaderc_result_get_error_message(compilation_result_); | |
| 30 } | |
| 31 | |
| 32 std::string GetResult() const { | |
| 33 return std::string(shaderc_result_get_bytes(compilation_result_), | |
| 34 shaderc_result_get_length(compilation_result_)); | |
| 35 } | |
| 36 | |
| 37 private: | |
| 38 shaderc_compilation_result_t compilation_result_; | |
| 39 }; | |
| 40 | |
| 41 ShaderCCompiler() | |
| 42 : compiler_(shaderc_compiler_initialize()), | |
| 43 compiler_options_(shaderc_compile_options_initialize()) {} | |
| 44 | |
| 45 ~ShaderCCompiler() { shaderc_compiler_release(compiler_); } | |
| 46 | |
| 47 void AddMacroDef(const std::string& name, const std::string& value) { | |
| 48 shaderc_compile_options_add_macro_definition(compiler_options_, | |
| 49 name.c_str(), name.length(), | |
| 50 value.c_str(), value.length()); | |
| 51 } | |
| 52 | |
| 53 std::unique_ptr<ShaderCCompiler::CompilationResult> CompileShaderModule( | |
| 54 gpu::VulkanShaderModule::ShaderType shader_type, | |
| 55 const std::string& name, | |
| 56 const std::string& entry_point, | |
| 57 const std::string& source) { | |
| 58 return std::unique_ptr<ShaderCCompiler::CompilationResult>( | |
|
piman
2016/05/16 23:35:31
nit: you can use base::MakeUnique<CompilationResul
David Yen
2016/05/17 18:13:57
Done.
| |
| 59 new CompilationResult(shaderc_compile_into_spv( | |
| 60 compiler_, source.c_str(), source.length(), | |
| 61 (shader_type == gpu::VulkanShaderModule::ShaderType::VERTEX | |
| 62 ? shaderc_glsl_vertex_shader | |
| 63 : shaderc_glsl_fragment_shader), | |
| 64 name.c_str(), entry_point.c_str(), compiler_options_))); | |
| 65 } | |
| 66 | |
| 67 private: | |
| 68 shaderc_compiler_t compiler_; | |
| 69 shaderc_compile_options_t compiler_options_; | |
| 70 }; | |
| 71 | |
| 72 namespace gpu { | |
| 73 | |
| 74 VulkanShaderModule::VulkanShaderModule(VulkanDeviceQueue* device_queue) | |
| 75 : device_queue_(device_queue) { | |
| 76 DCHECK(device_queue_); | |
| 77 } | |
| 78 | |
| 79 VulkanShaderModule::~VulkanShaderModule() { | |
| 80 DCHECK_EQ(static_cast<VkShaderModule>(VK_NULL_HANDLE), handle_); | |
| 81 } | |
| 82 | |
| 83 bool VulkanShaderModule::InitializeGLSL(ShaderType type, | |
| 84 const std::string& name, | |
| 85 const std::string& entry_point, | |
| 86 const std::string& source) { | |
| 87 ShaderCCompiler shaderc_compiler; | |
| 88 std::unique_ptr<ShaderCCompiler::CompilationResult> compilation_result( | |
| 89 shaderc_compiler.CompileShaderModule(type, name, entry_point, source)); | |
| 90 | |
| 91 if (!compilation_result->IsValid()) { | |
| 92 error_messages_ = compilation_result->GetErrors(); | |
| 93 return false; | |
| 94 } | |
| 95 | |
| 96 return InitializeSPIRV(type, name, entry_point, | |
| 97 compilation_result->GetResult()); | |
| 98 } | |
| 99 | |
| 100 bool VulkanShaderModule::InitializeSPIRV(ShaderType type, | |
| 101 const std::string& name, | |
| 102 const std::string& entry_point, | |
| 103 const std::string& source) { | |
| 104 DCHECK_EQ(static_cast<VkShaderModule>(VK_NULL_HANDLE), handle_); | |
| 105 shader_type_ = type; | |
| 106 name_ = name; | |
| 107 entry_point_ = entry_point; | |
| 108 | |
| 109 std::string aligned_source; | |
| 110 | |
| 111 VkShaderModuleCreateInfo shader_module_create_info = {}; | |
| 112 shader_module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; | |
| 113 const int source_mod = source.length() % 4; | |
| 114 if (source_mod != 0) { | |
| 115 aligned_source = entry_point; | |
|
piman
2016/05/16 23:35:31
Did you mean aligned_source = source?
David Yen
2016/05/17 18:13:57
Oops, done.
| |
| 116 for (int i = 0; i < (4 - source_mod); ++i) { | |
| 117 aligned_source += ' '; | |
| 118 } | |
| 119 shader_module_create_info.pCode = | |
| 120 reinterpret_cast<const uint32_t*>(aligned_source.c_str()); | |
| 121 shader_module_create_info.codeSize = aligned_source.length() / 4; | |
| 122 } else { | |
| 123 shader_module_create_info.pCode = | |
| 124 reinterpret_cast<const uint32_t*>(source.c_str()); | |
| 125 shader_module_create_info.codeSize = source.length() / 4; | |
| 126 } | |
| 127 | |
| 128 VkShaderModule shader_module = VK_NULL_HANDLE; | |
| 129 VkResult result = | |
| 130 vkCreateShaderModule(device_queue_->GetVulkanDevice(), | |
| 131 &shader_module_create_info, nullptr, &shader_module); | |
| 132 if (VK_SUCCESS != result) { | |
| 133 std::stringstream ss; | |
| 134 ss << "vkCreateShaderModule() failed: " << result; | |
| 135 error_messages_ = ss.str(); | |
| 136 DLOG(ERROR) << error_messages_; | |
| 137 return false; | |
| 138 } | |
| 139 | |
| 140 handle_ = shader_module; | |
| 141 return true; | |
| 142 } | |
| 143 | |
| 144 void VulkanShaderModule::Destroy() { | |
| 145 if (handle_ != VK_NULL_HANDLE) { | |
| 146 vkDestroyShaderModule(device_queue_->GetVulkanDevice(), handle_, nullptr); | |
| 147 handle_ = VK_NULL_HANDLE; | |
| 148 } | |
| 149 | |
| 150 shader_type_ = ShaderType::INVALID; | |
| 151 entry_point_.clear(); | |
| 152 error_messages_.clear(); | |
| 153 } | |
| 154 | |
| 155 } // namespace gpu | |
| OLD | NEW |