yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
b152f1bb1
master
1//TEST:EXECUTABLE: 2import gfx; 3import slang; 4 5export __extern_cpp int main() 6{ 7 gfx.DeviceDesc deviceDesc = {}; 8 deviceDesc.deviceType = gfx.DeviceType.CPU; 9 Optional<gfx.IDevice> device; 10 gfx.gfxCreateDevice(&deviceDesc, device); 11 if (device == none) 12 { 13 printf("fail\n"); 14 return -1; 15 } 16 17 gfx.CommandQueueDesc queueDesc = {gfx::QueueType::Graphics}; 18 queueDesc.type = gfx.QueueType.Graphics; 19 Optional<gfx.ICommandQueue> queue; 20 device.value.createCommandQueue(&queueDesc, queue); 21 22 gfx.ShaderProgramDesc2 programDesc = {}; 23 NativeString s = R"( 24 [shader("compute")] 25 [numthreads(4, 1, 1)] 26 void computeMain( 27 uint3 sv_dispatchThreadID: SV_DispatchThreadID, 28 uniform RWStructuredBuffer<float> buffer 29 ) 30 { 31 var input = buffer[sv_dispatchThreadID.x]; 32 buffer[sv_dispatchThreadID.x] = sv_dispatchThreadID.x; 33 })"; 34 programDesc.sourceData = s; 35 programDesc.sourceType = gfx.ShaderModuleSourceType.SlangSource; 36 programDesc.sourceDataSize = s.length; 37 programDesc.entryPointCount = 1; 38 NativeString entryPointName = "computeMain"; 39 programDesc.entryPointNames = &entryPointName; 40 Optional<gfx.IShaderProgram> program; 41 Optional<slang.ISlangBlob> diagBlob; 42 device.value.createProgram2(&programDesc, program, diagBlob); 43 44 Optional<gfx.IPipelineState> pipeline; 45 gfx.ComputePipelineStateDesc pipelineDesc; 46 pipelineDesc.program = NativeRef<gfx.IShaderProgram>(program.value); 47 device.value.createComputePipelineState(&pipelineDesc, pipeline); 48 49 Optional<gfx.ITransientResourceHeap> transientHeap; 50 gfx.TransientResourceHeapDesc transientHeapDesc; 51 transientHeapDesc.constantBufferDescriptorCount = 64; 52 transientHeapDesc.constantBufferSize = 1024; 53 transientHeapDesc.srvDescriptorCount = 1024; 54 transientHeapDesc.uavDescriptorCount = 1024; 55 transientHeapDesc.samplerDescriptorCount = 256; 56 transientHeapDesc.accelerationStructureDescriptorCount = 32; 57 device.value.createTransientResourceHeap(&transientHeapDesc, transientHeap); 58 59 Optional<gfx.IBufferResource> buffer; 60 gfx.BufferResourceDesc bufferDesc = {}; 61 bufferDesc.memoryType = gfx.MemoryType.DeviceLocal; 62 bufferDesc.allowedStates.add(gfx.ResourceState.UnorderedAccess); 63 bufferDesc.defaultState = gfx.ResourceState.UnorderedAccess; 64 bufferDesc.elementSize = 4; 65 bufferDesc.sizeInBytes = 256; 66 bufferDesc.type = gfx.ResourceType.Buffer; 67 device.value.createBufferResource(&bufferDesc, nullptr, buffer); 68 69 Optional<gfx.IResourceView> bufferView; 70 gfx.ResourceViewDesc viewDesc; 71 viewDesc.type = gfx.ResourceViewType.UnorderedAccess; 72 device.value.createBufferView(buffer.value, none, &viewDesc, bufferView); 73 74 Optional<gfx.ICommandBuffer> commandBuffer; 75 transientHeap.value.createCommandBuffer(commandBuffer); 76 Optional<gfx.IComputeCommandEncoder> encoder; 77 commandBuffer.value.encodeComputeCommands(encoder); 78 Optional<gfx.IShaderObject> rootObject; 79 encoder.value.bindPipeline(pipeline.value, rootObject); 80 Optional<gfx.IShaderObject> entryPointObject; 81 rootObject.value.getEntryPoint(0, entryPointObject); 82 gfx.ShaderOffset offset = {}; 83 entryPointObject.value.setResource(&offset, bufferView.value); 84 encoder.value.dispatchCompute(1, 1, 1); 85 encoder.value.endEncoding(); 86 commandBuffer.value.close(); 87 88 NativeRef<gfx.ICommandBuffer> commandBufferRef = NativeRef<gfx.ICommandBuffer>(commandBuffer.value); 89 queue.value.executeCommandBuffers(1, &commandBufferRef, none, 0); 90 queue.value.waitOnHost(); 91 92 Optional<slang.ISlangBlob> blob; 93 device.value.readBufferResource(buffer.value, 0, 16, blob); 94 95 for (int i = 0; i < 4; i++) 96 { 97 float val = ((float *)blob.value.getBufferPointer())[i]; 98 printf("%.1f\n", val); 99 } 100 return 0; 101}