summaryrefslogtreecommitdiffstats
path: root/tools/gfx/vulkan/vk-shader-program.cpp
diff options
context:
space:
mode:
authorlucy96chen <47800040+lucy96chen@users.noreply.github.com>2022-05-26 10:54:35 -0700
committerGitHub <noreply@github.com>2022-05-26 10:54:35 -0700
commit43e1b7cdc70b2fcac8a3e8ee72f5bc91726f4ec5 (patch)
tree1e4701b4ab324a199b81e1f6c671f6660f1050c5 /tools/gfx/vulkan/vk-shader-program.cpp
parent5ff4f42c636a67724523e4fe60697cfac64908cd (diff)
Split render-vk.h/.cpp into a set of smaller files (#2244)
* Some preliminary work on splitting render-vk * render-vk split, tests currently crash on null reference * fixed circular include
Diffstat (limited to 'tools/gfx/vulkan/vk-shader-program.cpp')
-rw-r--r--tools/gfx/vulkan/vk-shader-program.cpp91
1 files changed, 91 insertions, 0 deletions
diff --git a/tools/gfx/vulkan/vk-shader-program.cpp b/tools/gfx/vulkan/vk-shader-program.cpp
new file mode 100644
index 000000000..ee307ed04
--- /dev/null
+++ b/tools/gfx/vulkan/vk-shader-program.cpp
@@ -0,0 +1,91 @@
+// vk-shader-program.cpp
+#include "vk-shader-program.h"
+
+#include "vk-device.h"
+#include "vk-util.h"
+
+namespace gfx
+{
+
+using namespace Slang;
+
+namespace vk
+{
+
+ShaderProgramImpl::ShaderProgramImpl(DeviceImpl* device)
+ : m_device(device)
+{
+ for (auto& shaderModule : m_modules)
+ shaderModule = VK_NULL_HANDLE;
+}
+
+ShaderProgramImpl::~ShaderProgramImpl()
+{
+ for (auto shaderModule : m_modules)
+ {
+ if (shaderModule != VK_NULL_HANDLE)
+ {
+ m_device->m_api.vkDestroyShaderModule(m_device->m_api.m_device, shaderModule, nullptr);
+ }
+ }
+}
+
+void ShaderProgramImpl::comFree() { m_device.breakStrongReference(); }
+
+VkPipelineShaderStageCreateInfo ShaderProgramImpl::compileEntryPoint(
+ const char* entryPointName,
+ ISlangBlob* code,
+ VkShaderStageFlagBits stage,
+ VkShaderModule& outShaderModule)
+{
+ char const* dataBegin = (char const*)code->getBufferPointer();
+ char const* dataEnd = (char const*)code->getBufferPointer() + code->getBufferSize();
+
+ // We need to make a copy of the code, since the Slang compiler
+ // will free the memory after a compile request is closed.
+
+ VkShaderModuleCreateInfo moduleCreateInfo = {VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
+ moduleCreateInfo.pCode = (uint32_t*)code->getBufferPointer();
+ moduleCreateInfo.codeSize = code->getBufferSize();
+
+ VkShaderModule module;
+ SLANG_VK_CHECK(m_device->m_api.vkCreateShaderModule(
+ m_device->m_device, &moduleCreateInfo, nullptr, &module));
+ outShaderModule = module;
+
+ VkPipelineShaderStageCreateInfo shaderStageCreateInfo = {
+ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
+ shaderStageCreateInfo.stage = stage;
+
+ shaderStageCreateInfo.module = module;
+ shaderStageCreateInfo.pName = entryPointName;
+
+ return shaderStageCreateInfo;
+}
+
+Result ShaderProgramImpl::createShaderModule(
+ slang::EntryPointReflection* entryPointInfo, ComPtr<ISlangBlob> kernelCode)
+{
+ m_codeBlobs.add(kernelCode);
+ VkShaderModule shaderModule;
+ // HACK: our direct-spirv-emit path generates SPIRV that respects
+ // the original entry point name, while the glslang path always
+ // uses "main" as the name. We should introduce a compiler parameter
+ // to control the entry point naming behavior in SPIRV-direct path
+ // so we can remove the ad-hoc logic here.
+ auto realEntryPointName = entryPointInfo->getNameOverride();
+ const char* spirvBinaryEntryPointName = "main";
+ if (m_device->m_desc.slang.targetFlags & SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY)
+ spirvBinaryEntryPointName = realEntryPointName;
+ m_stageCreateInfos.add(compileEntryPoint(
+ spirvBinaryEntryPointName,
+ kernelCode,
+ (VkShaderStageFlagBits)VulkanUtil::getShaderStage(entryPointInfo->getStage()),
+ shaderModule));
+ m_entryPointNames.add(realEntryPointName);
+ m_modules.add(shaderModule);
+ return SLANG_OK;
+}
+
+} // namespace vk
+} // namespace gfx