yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Lujin WangChange SLANG_OVERRIDE_xxx_PATH and fix header file path (#7207)b16eb592c

master
2.9 KiB109 linesraw
1// vk-shader-program.cpp
2#include "vk-shader-program.h"
3
4#include "spirv-tools/include/spirv-tools/linker.hpp"
5#include "vk-device.h"
6#include "vk-util.h"
7
8namespace gfx
9{
10
11using namespace Slang;
12
13namespace vk
14{
15
16ShaderProgramImpl::ShaderProgramImpl(DeviceImpl* device)
17    : m_device(device)
18{
19    for (auto& shaderModule : m_modules)
20        shaderModule = VK_NULL_HANDLE;
21}
22
23ShaderProgramImpl::~ShaderProgramImpl()
24{
25    for (auto shaderModule : m_modules)
26    {
27        if (shaderModule != VK_NULL_HANDLE)
28        {
29            m_device->m_api.vkDestroyShaderModule(m_device->m_api.m_device, shaderModule, nullptr);
30        }
31    }
32}
33
34void ShaderProgramImpl::comFree()
35{
36    m_device.breakStrongReference();
37}
38
39VkPipelineShaderStageCreateInfo ShaderProgramImpl::compileEntryPoint(
40    const char* entryPointName,
41    ISlangBlob* code,
42    VkShaderStageFlagBits stage,
43    VkShaderModule& outShaderModule)
44{
45    char const* dataBegin = (char const*)code->getBufferPointer();
46    char const* dataEnd = (char const*)code->getBufferPointer() + code->getBufferSize();
47
48    // We need to make a copy of the code, since the Slang compiler
49    // will free the memory after a compile request is closed.
50
51    VkShaderModuleCreateInfo moduleCreateInfo = {VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
52    moduleCreateInfo.pCode = (uint32_t*)code->getBufferPointer();
53    moduleCreateInfo.codeSize = code->getBufferSize();
54
55    VkShaderModule module;
56    SLANG_VK_CHECK(m_device->m_api.vkCreateShaderModule(
57        m_device->m_device,
58        &moduleCreateInfo,
59        nullptr,
60        &module));
61    outShaderModule = module;
62
63    VkPipelineShaderStageCreateInfo shaderStageCreateInfo = {
64        VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
65    shaderStageCreateInfo.stage = stage;
66
67    shaderStageCreateInfo.module = module;
68    shaderStageCreateInfo.pName = entryPointName;
69
70    return shaderStageCreateInfo;
71}
72
73Result ShaderProgramImpl::createShaderModule(
74    slang::EntryPointReflection* entryPointInfo,
75    List<ComPtr<ISlangBlob>>& kernelCodes)
76{
77    ComPtr<ISlangBlob> linkedKernel;
78    ComPtr<slang::ISession> slangSession;
79    m_device->getSlangSession(slangSession.writeRef());
80    if (kernelCodes.getCount() == 1)
81    {
82        linkedKernel = kernelCodes[0];
83    }
84    else
85    {
86        linkedKernel = m_device->m_glslang.linkSPIRV(kernelCodes);
87        if (!linkedKernel)
88        {
89            return SLANG_FAIL;
90        }
91    }
92
93    m_codeBlobs.add(linkedKernel);
94
95    VkShaderModule shaderModule;
96    auto realEntryPointName = entryPointInfo->getNameOverride();
97    const char* spirvBinaryEntryPointName = "main";
98    m_stageCreateInfos.add(compileEntryPoint(
99        spirvBinaryEntryPointName,
100        linkedKernel,
101        (VkShaderStageFlagBits)VulkanUtil::getShaderStage(entryPointInfo->getStage()),
102        shaderModule));
103    m_entryPointNames.add(realEntryPointName);
104    m_modules.add(shaderModule);
105    return SLANG_OK;
106}
107
108} // namespace vk
109} // namespace gfx