yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
b16eb592c
master
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{ 19for (auto & shaderModule :m_modules ) 20shaderModule = VK_NULL_HANDLE ; 21} 22 23ShaderProgramImpl ::~ShaderProgramImpl () 24{ 25for (auto shaderModule :m_modules ) 26 { 27if (shaderModule != VK_NULL_HANDLE ) 28 { 29m_device -> m_api .vkDestroyShaderModule (m_device -> m_api .m_device ,shaderModule ,nullptr ); 30 } 31 } 32} 33 34void ShaderProgramImpl ::comFree () 35{ 36m_device .breakStrongReference (); 37} 38 39VkPipelineShaderStageCreateInfo ShaderProgramImpl ::compileEntryPoint ( 40const char * entryPointName , 41ISlangBlob * code , 42VkShaderStageFlagBits stage , 43VkShaderModule & outShaderModule ) 44{ 45char const * dataBegin = (char const * )code -> getBufferPointer (); 46char 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 51VkShaderModuleCreateInfo moduleCreateInfo = {VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; 52moduleCreateInfo .pCode = (uint32_t * )code -> getBufferPointer (); 53moduleCreateInfo .codeSize = code -> getBufferSize (); 54 55VkShaderModule module ; 56SLANG_VK_CHECK (m_device -> m_api .vkCreateShaderModule ( 57m_device -> m_device , 58& moduleCreateInfo , 59nullptr , 60& module )); 61outShaderModule = module ; 62 63VkPipelineShaderStageCreateInfo shaderStageCreateInfo = { 64VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO }; 65shaderStageCreateInfo .stage = stage ; 66 67shaderStageCreateInfo .module = module ; 68shaderStageCreateInfo .pName = entryPointName ; 69 70return shaderStageCreateInfo ; 71} 72 73Result ShaderProgramImpl ::createShaderModule ( 74 slang::EntryPointReflection * entryPointInfo , 75List < ComPtr < ISlangBlob >>& kernelCodes ) 76{ 77ComPtr < ISlangBlob > linkedKernel ; 78ComPtr < slang::ISession > slangSession ; 79m_device -> getSlangSession (slangSession .writeRef ()); 80if (kernelCodes .getCount ()== 1 ) 81 { 82linkedKernel = kernelCodes [0 ]; 83 } 84else 85 { 86linkedKernel = m_device -> m_glslang .linkSPIRV (kernelCodes ); 87if (!linkedKernel ) 88 { 89return SLANG_FAIL ; 90 } 91 } 92 93m_codeBlobs .add (linkedKernel ); 94 95VkShaderModule shaderModule ; 96auto realEntryPointName = entryPointInfo -> getNameOverride (); 97const char * spirvBinaryEntryPointName = "main" ; 98m_stageCreateInfos .add (compileEntryPoint ( 99spirvBinaryEntryPointName , 100linkedKernel , 101 (VkShaderStageFlagBits )VulkanUtil ::getShaderStage (entryPointInfo -> getStage ()), 102shaderModule )); 103m_entryPointNames .add (realEntryPointName ); 104m_modules .add (shaderModule ); 105return SLANG_OK ; 106} 107 108}// namespace vk 109}// namespace gfx