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 "Device/Context.hpp"
22#include "Vulkan/VkDescriptorSet.hpp"
23
24#include <functional>
25
26namespace vk
27{
28 class PipelineLayout;
29} // namespace vk
30
31namespace sw
32{
33
34 using namespace rr;
35
36 class DescriptorSetsLayout;
37 struct Constants;
38
39 // ComputeProgram builds a SPIR-V compute shader.
40 class ComputeProgram : public Coroutine<SpirvShader::YieldResult(
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(SpirvShader const *spirvShader, vk::PipelineLayout const *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 vk::DescriptorSet::Bindings const &descriptorSetBindings,
60 vk::DescriptorSet::DynamicOffsets const &descriptorDynamicOffsets,
61 PushConstantStorage const &pushConstants,
62 uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ,
63 uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
64
65 protected:
66 void emit(SpirvRoutine* routine);
67 void setWorkgroupBuiltins(Pointer<Byte> data, SpirvRoutine* routine, Int workgroupID[3]);
68 void setSubgroupBuiltins(Pointer<Byte> data, SpirvRoutine* routine, Int workgroupID[3], SIMD::Int localInvocationIndex, Int subgroupIndex);
69
70 struct Data
71 {
72 vk::DescriptorSet::Bindings descriptorSets;
73 vk::DescriptorSet::DynamicOffsets descriptorDynamicOffsets;
74 uint4 numWorkgroups; // [x, y, z, 0]
75 uint4 workgroupSize; // [x, y, z, 0]
76 uint32_t invocationsPerSubgroup; // SPIR-V: "SubgroupSize"
77 uint32_t subgroupsPerWorkgroup; // SPIR-V: "NumSubgroups"
78 uint32_t invocationsPerWorkgroup; // Total number of invocations per workgroup.
79 PushConstantStorage pushConstants;
80 const Constants *constants;
81 };
82
83 SpirvShader const * const shader;
84 vk::PipelineLayout const * const pipelineLayout;
85 const vk::DescriptorSet::Bindings &descriptorSets;
86 };
87
88} // namespace sw
89
90#endif // sw_ComputeProgram_hpp
91