1 // Copyright 2019 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef sw_ComputeProgram_hpp 16 #define sw_ComputeProgram_hpp 17 18 #include "SpirvShader.hpp" 19 20 #include "Reactor/Coroutine.hpp" 21 #include "Vulkan/VkDescriptorSet.hpp" 22 #include "Vulkan/VkPipeline.hpp" 23 24 #include <functional> 25 26 namespace vk { 27 class Device; 28 class PipelineLayout; 29 } // namespace vk 30 31 namespace sw { 32 33 using namespace rr; 34 35 class DescriptorSetsLayout; 36 struct Constants; 37 38 // ComputeProgram builds a SPIR-V compute shader. 39 class ComputeProgram : public Coroutine<SpirvEmitter::YieldResult( 40 const vk::Device *device, 41 void *data, 42 int32_t workgroupX, 43 int32_t workgroupY, 44 int32_t workgroupZ, 45 void *workgroupMemory, 46 int32_t firstSubgroup, 47 int32_t subgroupCount)> 48 { 49 public: 50 ComputeProgram(vk::Device *device, std::shared_ptr<SpirvShader> spirvShader, const vk::PipelineLayout *pipelineLayout, const vk::DescriptorSet::Bindings &descriptorSets); 51 52 virtual ~ComputeProgram(); 53 54 // generate builds the shader program. 55 void generate(); 56 57 // run executes the compute shader routine for all workgroups. 58 void run( 59 const vk::DescriptorSet::Array &descriptorSetObjects, 60 const vk::DescriptorSet::Bindings &descriptorSetBindings, 61 const vk::DescriptorSet::DynamicOffsets &descriptorDynamicOffsets, 62 const vk::Pipeline::PushConstantStorage &pushConstants, 63 uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, 64 uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); 65 66 protected: 67 void emit(SpirvRoutine *routine); 68 void setWorkgroupBuiltins(Pointer<Byte> data, SpirvRoutine *routine, Int workgroupID[3]); 69 void setSubgroupBuiltins(Pointer<Byte> data, SpirvRoutine *routine, Int workgroupID[3], SIMD::Int localInvocationIndex, Int subgroupIndex); 70 71 struct Data 72 { 73 vk::DescriptorSet::Bindings descriptorSets; 74 vk::DescriptorSet::DynamicOffsets descriptorDynamicOffsets; 75 uint4 numWorkgroups; // [x, y, z, -] 76 uint4 workgroupSize; // [x, y, z, -] 77 uint32_t invocationsPerSubgroup; // SPIR-V: "SubgroupSize" 78 uint32_t subgroupsPerWorkgroup; // SPIR-V: "NumSubgroups" 79 uint32_t invocationsPerWorkgroup; // Total number of invocations per workgroup. 80 vk::Pipeline::PushConstantStorage pushConstants; 81 }; 82 83 vk::Device *const device; 84 const std::shared_ptr<SpirvShader> shader; 85 const vk::PipelineLayout *const pipelineLayout; // Reference held by vk::Pipeline 86 const vk::DescriptorSet::Bindings &descriptorSets; 87 }; 88 89 } // namespace sw 90 91 #endif // sw_ComputeProgram_hpp 92