yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1#include "vk-pipeline-dump-layer.h" 2 3#include "core/slang-basic.h" 4#include "core/slang-stream.h" 5namespace gfx 6{ 7using namespace Slang ; 8 9struct PipelineDumpContext 10{ 11Dictionary < VkPipelineLayout ,Index > pipelineLayouts ; 12Dictionary < VkShaderModule ,Index > shaderModules ; 13Dictionary < VkDescriptorSetLayout ,Index > descriptorSets ; 14Dictionary < VkPipeline ,Index > computePipelines ; 15 16List < uint8_t > serializedBytes ; 17 18VulkanApi api ; 19 20template < typename T > 21void writeRaw (T v ) 22 { 23auto startIndex = serializedBytes .getCount (); 24serializedBytes .growToCount (startIndex + sizeof (T )); 25memcpy (serializedBytes .getBuffer ()+ startIndex ,& v ,sizeof (T )); 26 } 27 28template < typename T > 29void writeArray (uint32_t elementCount ,const T * data ) 30 { 31writeRaw (elementCount ); 32 33auto startIndex = serializedBytes .getCount (); 34serializedBytes .growToCount (startIndex + sizeof (T )* elementCount ); 35memcpy (serializedBytes .getBuffer ()+ startIndex ,data ,sizeof (T )* elementCount ); 36 } 37 38void writeStr (const char * str ) 39 { 40auto len = (uint32_t )strlen (str )+ 1 ; 41writeRaw (len ); 42 43auto startIndex = serializedBytes .getCount (); 44serializedBytes .growToCount (startIndex + len ); 45memcpy (serializedBytes .getBuffer ()+ startIndex ,str ,len - 1 ); 46serializedBytes [startIndex + len - 1 ]= 0 ; 47 } 48 49void writePipelineLayout (VkPipelineLayout layout ,const VkPipelineLayoutCreateInfo * createInfo ) 50 { 51auto startIndex = serializedBytes .getCount (); 52writeRaw (createInfo -> sType ); 53writeRaw (createInfo -> flags ); 54writeRaw (createInfo -> setLayoutCount ); 55for (uint32_t i = 0 ;i < createInfo -> setLayoutCount ;i ++ ) 56writeRaw (descriptorSets .getValue (createInfo -> pSetLayouts [i ])); 57writeArray (createInfo -> pushConstantRangeCount ,createInfo -> pPushConstantRanges ); 58pipelineLayouts [layout ]= startIndex ; 59 } 60 61void writeShaderModule (VkShaderModule module ,const VkShaderModuleCreateInfo * createInfo ) 62 { 63auto startIndex = serializedBytes .getCount (); 64writeRaw (createInfo -> sType ); 65writeRaw (createInfo -> flags ); 66writeArray ((uint32_t )(createInfo -> codeSize /sizeof (uint32_t )),createInfo -> pCode ); 67shaderModules [module ]= startIndex ; 68 } 69 70void writeDescriptorSetLayout ( 71VkDescriptorSetLayout layout , 72const VkDescriptorSetLayoutCreateInfo * createInfo ) 73 { 74auto startIndex = serializedBytes .getCount (); 75writeRaw (createInfo -> sType ); 76writeRaw (createInfo -> flags ); 77writeArray (createInfo -> bindingCount ,createInfo -> pBindings ); 78descriptorSets [layout ]= startIndex ; 79 } 80 81void writePipeline (VkPipeline pipeline ,const VkComputePipelineCreateInfo * createInfo ) 82 { 83auto startIndex = serializedBytes .getCount (); 84writeRaw (createInfo -> sType ); 85writeRaw (createInfo -> flags ); 86writeRaw (createInfo -> stage .sType ); 87writeRaw (createInfo -> stage .flags ); 88writeRaw (createInfo -> stage .stage ); 89writeRaw (shaderModules .getValue (createInfo -> stage .module )); 90writeStr (createInfo -> stage .pName ); 91writeRaw (pipelineLayouts .getValue (createInfo -> layout )); 92computePipelines [pipeline ]= startIndex ; 93 } 94 95void writeToFile (UnownedStringSlice path ) 96 { 97RefPtr < FileStream > fs = new FileStream (); 98fs -> init (path ,FileMode ::Create ); 99uint32_t pipelineCount = (uint32_t )computePipelines .getCount (); 100fs -> write (& pipelineCount ,sizeof (uint32_t )); 101for (auto & pair :computePipelines ) 102 { 103fs -> write (KeyValueDetail ::getValue (& pair ),sizeof (Index )); 104 } 105Index blobSize = serializedBytes .getCount (); 106fs -> write (& blobSize ,sizeof (blobSize )); 107fs -> write (serializedBytes .getBuffer (),serializedBytes .getCount ()); 108fs -> close (); 109 } 110}; 111 112PipelineDumpContext dumpContext ; 113 114VkResult SLANG_MCALL createPipelineLayout ( 115VkDevice device , 116const VkPipelineLayoutCreateInfo * createInfo , 117const VkAllocationCallbacks * callbacks , 118VkPipelineLayout * outLayout ) 119{ 120auto result = dumpContext .api .vkCreatePipelineLayout (device ,createInfo ,callbacks ,outLayout ); 121dumpContext .writePipelineLayout (* outLayout ,createInfo ); 122return result ; 123} 124 125VkResult SLANG_MCALL createComputePipelines ( 126VkDevice device , 127VkPipelineCache cache , 128uint32_t createInfoCount , 129const VkComputePipelineCreateInfo * createInfos , 130const VkAllocationCallbacks * callbacks , 131VkPipeline * outPipelines ) 132{ 133auto result = dumpContext .api .vkCreateComputePipelines ( 134device , 135cache , 136createInfoCount , 137createInfos , 138callbacks , 139outPipelines ); 140for (uint32_t i = 0 ;i < createInfoCount ;i ++ ) 141dumpContext .writePipeline (outPipelines [i ],createInfos + i ); 142return result ; 143} 144 145VkResult SLANG_MCALL createShaderModule ( 146VkDevice device , 147const VkShaderModuleCreateInfo * createInfo , 148const VkAllocationCallbacks * callbacks , 149VkShaderModule * outShaderModule ) 150{ 151auto result = 152dumpContext .api .vkCreateShaderModule (device ,createInfo ,callbacks ,outShaderModule ); 153dumpContext .writeShaderModule (* outShaderModule ,createInfo ); 154return result ; 155} 156 157VkResult SLANG_MCALL createDescriptorSetLayout ( 158VkDevice device , 159const VkDescriptorSetLayoutCreateInfo * createInfo , 160const VkAllocationCallbacks * callbacks , 161VkDescriptorSetLayout * outDescSetLayout ) 162{ 163auto result = dumpContext .api 164 .vkCreateDescriptorSetLayout (device ,createInfo ,callbacks ,outDescSetLayout ); 165dumpContext .writeDescriptorSetLayout (* outDescSetLayout ,createInfo ); 166return result ; 167} 168 169void installPipelineDumpLayer (VulkanApi & api ) 170{ 171dumpContext .api = api ; 172api .vkCreatePipelineLayout = createPipelineLayout ; 173api .vkCreateComputePipelines = createComputePipelines ; 174api .vkCreateShaderModule = createShaderModule ; 175api .vkCreateDescriptorSetLayout = createDescriptorSetLayout ; 176} 177 178void writePipelineDump (UnownedStringSlice path ) 179{ 180dumpContext .writeToFile (path ); 181} 182}// namespace gfx