yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1// vk-shader-table.cpp 2#include "vk-shader-table.h" 3 4#include "vk-device.h" 5#include "vk-helper-functions.h" 6#include "vk-transient-heap.h" 7 8namespace gfx 9{ 10 11using namespace Slang ; 12 13namespace vk 14{ 15 16RefPtr < BufferResource > ShaderTableImpl ::createDeviceBuffer ( 17PipelineStateBase * pipeline , 18TransientResourceHeapBase * transientHeap , 19IResourceCommandEncoder * encoder ) 20{ 21auto vkApi = m_device -> m_api ; 22auto rtProps = vkApi .m_rtProperties ; 23uint32_t handleSize = rtProps .shaderGroupHandleSize ; 24m_raygenTableSize = m_rayGenShaderCount * rtProps .shaderGroupBaseAlignment ; 25m_missTableSize = (uint32_t )VulkanUtil ::calcAligned ( 26m_missShaderCount * handleSize , 27rtProps .shaderGroupBaseAlignment ); 28m_hitTableSize = (uint32_t )VulkanUtil ::calcAligned ( 29m_hitGroupCount * handleSize , 30rtProps .shaderGroupBaseAlignment ); 31m_callableTableSize = (uint32_t )VulkanUtil ::calcAligned ( 32m_callableShaderCount * handleSize , 33rtProps .shaderGroupBaseAlignment ); 34uint32_t tableSize = m_raygenTableSize + m_missTableSize + m_hitTableSize + m_callableTableSize ; 35 36auto pipelineImpl = static_cast < RayTracingPipelineStateImpl *> (pipeline ); 37ComPtr < IBufferResource > bufferResource ; 38IBufferResource ::Desc bufferDesc = {}; 39bufferDesc .memoryType = MemoryType ::DeviceLocal ; 40bufferDesc .defaultState = ResourceState ::General ; 41bufferDesc .allowedStates = 42ResourceStateSet (ResourceState ::General ,ResourceState ::CopyDestination ); 43bufferDesc .type = IResource ::Type ::Buffer ; 44bufferDesc .sizeInBytes = tableSize ; 45static_cast < vk::DeviceImpl *> (m_device )-> createBufferResourceImpl ( 46bufferDesc , 47VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR , 48nullptr , 49bufferResource .writeRef ()); 50 51TransientResourceHeapImpl * transientHeapImpl = 52static_cast < TransientResourceHeapImpl *> (transientHeap ); 53 54IBufferResource * stagingBuffer = nullptr ; 55Offset stagingBufferOffset = 0 ; 56transientHeapImpl 57-> allocateStagingBuffer (tableSize ,stagingBuffer ,stagingBufferOffset ,MemoryType ::Upload ); 58 59assert (stagingBuffer ); 60void * stagingPtr = nullptr ; 61stagingBuffer -> map (nullptr ,& stagingPtr ); 62 63List < uint8_t > handles ; 64auto handleCount = pipelineImpl -> shaderGroupCount ; 65auto totalHandleSize = handleSize * handleCount ; 66handles .setCount (totalHandleSize ); 67auto result = vkApi .vkGetRayTracingShaderGroupHandlesKHR ( 68m_device -> m_device , 69pipelineImpl -> m_pipeline , 700 , 71 (uint32_t )handleCount , 72totalHandleSize , 73handles .getBuffer ()); 74 75uint8_t * stagingBufferPtr = (uint8_t * )stagingPtr + stagingBufferOffset ; 76auto subTablePtr = stagingBufferPtr ; 77Int shaderTableEntryCounter = 0 ; 78 79// Each loop calculates the copy source and destination locations by fetching the name 80// of the shader group from the list of shader group names and getting its corresponding 81// index in the buffer of handles. 82for (uint32_t i = 0 ;i < m_rayGenShaderCount ;i ++ ) 83 { 84auto dstHandlePtr = subTablePtr + i * rtProps .shaderGroupBaseAlignment ; 85auto shaderGroupName = m_shaderGroupNames [shaderTableEntryCounter ++ ]; 86auto shaderGroupIndexPtr = 87pipelineImpl -> shaderGroupNameToIndex .tryGetValue (shaderGroupName ); 88if (!shaderGroupIndexPtr ) 89continue ; 90 91auto shaderGroupIndex = * shaderGroupIndexPtr ; 92auto srcHandlePtr = handles .getBuffer ()+ shaderGroupIndex * handleSize ; 93memcpy (dstHandlePtr ,srcHandlePtr ,handleSize ); 94memset (dstHandlePtr + handleSize ,0 ,rtProps .shaderGroupBaseAlignment - handleSize ); 95 } 96subTablePtr += m_raygenTableSize ; 97 98for (uint32_t i = 0 ;i < m_missShaderCount ;i ++ ) 99 { 100auto dstHandlePtr = subTablePtr + i * handleSize ; 101auto shaderGroupName = m_shaderGroupNames [shaderTableEntryCounter ++ ]; 102auto shaderGroupIndexPtr = 103pipelineImpl -> shaderGroupNameToIndex .tryGetValue (shaderGroupName ); 104if (!shaderGroupIndexPtr ) 105continue ; 106 107auto shaderGroupIndex = * shaderGroupIndexPtr ; 108auto srcHandlePtr = handles .getBuffer ()+ shaderGroupIndex * handleSize ; 109memcpy (dstHandlePtr ,srcHandlePtr ,handleSize ); 110 } 111subTablePtr += m_missTableSize ; 112 113for (uint32_t i = 0 ;i < m_hitGroupCount ;i ++ ) 114 { 115auto dstHandlePtr = subTablePtr + i * handleSize ; 116auto shaderGroupName = m_shaderGroupNames [shaderTableEntryCounter ++ ]; 117auto shaderGroupIndexPtr = 118pipelineImpl -> shaderGroupNameToIndex .tryGetValue (shaderGroupName ); 119if (!shaderGroupIndexPtr ) 120continue ; 121 122auto shaderGroupIndex = * shaderGroupIndexPtr ; 123auto srcHandlePtr = handles .getBuffer ()+ shaderGroupIndex * handleSize ; 124memcpy (dstHandlePtr ,srcHandlePtr ,handleSize ); 125 } 126subTablePtr += m_hitTableSize ; 127 128for (uint32_t i = 0 ;i < m_callableShaderCount ;i ++ ) 129 { 130auto dstHandlePtr = subTablePtr + i * handleSize ; 131auto shaderGroupName = m_shaderGroupNames [shaderTableEntryCounter ++ ]; 132auto shaderGroupIndexPtr = 133pipelineImpl -> shaderGroupNameToIndex .tryGetValue (shaderGroupName ); 134if (!shaderGroupIndexPtr ) 135continue ; 136 137auto shaderGroupIndex = * shaderGroupIndexPtr ; 138auto srcHandlePtr = handles .getBuffer ()+ shaderGroupIndex * handleSize ; 139memcpy (dstHandlePtr ,srcHandlePtr ,handleSize ); 140 } 141subTablePtr += m_callableTableSize ; 142 143stagingBuffer -> unmap (nullptr ); 144encoder -> copyBuffer (bufferResource ,0 ,stagingBuffer ,stagingBufferOffset ,tableSize ); 145encoder -> bufferBarrier ( 1461 , 147bufferResource .readRef (), 148 gfx::ResourceState ::CopyDestination , 149 gfx::ResourceState ::ShaderResource ); 150RefPtr < BufferResource > resultPtr = static_cast < BufferResource *> (bufferResource .get ()); 151return _Move (resultPtr ); 152} 153 154}// namespace vk 155}// namespace gfx