xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/CLKernelVk.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2021 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // CLKernelVk.h: Defines the class interface for CLKernelVk, implementing CLKernelImpl.
7 
8 #ifndef LIBANGLE_RENDERER_VULKAN_CLKERNELVK_H_
9 #define LIBANGLE_RENDERER_VULKAN_CLKERNELVK_H_
10 
11 #include "libANGLE/renderer/vulkan/cl_types.h"
12 #include "libANGLE/renderer/vulkan/vk_cache_utils.h"
13 #include "libANGLE/renderer/vulkan/vk_helpers.h"
14 #include "libANGLE/renderer/vulkan/vk_utils.h"
15 
16 #include "libANGLE/renderer/CLKernelImpl.h"
17 #include "vulkan/vulkan_core.h"
18 
19 namespace rx
20 {
21 
22 struct CLKernelArgument
23 {
24     CLKernelImpl::ArgInfo info{};
25     uint32_t type     = 0;
26     uint32_t ordinal  = 0;
27     size_t handleSize = 0;
28     void *handle      = nullptr;
29     bool used         = false;
30 
31     // Shared operand words/regions for "OpExtInst" type spv instructions
32     // (starts from spv word index/offset 7 and onward)
33     // https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpExtInst
34     // https://github.com/google/clspv/blob/main/docs/OpenCLCOnVulkan.md#kernels
35     union
36     {
37         uint32_t op3;
38         uint32_t descriptorSet;
39         uint32_t pushConstOffset;
40         uint32_t workgroupSpecId;
41     };
42     union
43     {
44         uint32_t op4;
45         uint32_t descriptorBinding;
46         uint32_t pushConstantSize;
47         uint32_t workgroupSize;
48     };
49     union
50     {
51         uint32_t op5;
52         uint32_t podStorageBufferOffset;
53         uint32_t podUniformOffset;
54         uint32_t pointerUniformOffset;
55     };
56     union
57     {
58         uint32_t op6;
59         uint32_t podStorageBufferSize;
60         uint32_t podUniformSize;
61         uint32_t pointerUniformSize;
62     };
63 };
64 using CLKernelArguments = std::vector<CLKernelArgument>;
65 using CLKernelArgsMap   = angle::HashMap<std::string, CLKernelArguments>;
66 
67 class CLKernelVk : public CLKernelImpl
68 {
69   public:
70     using Ptr = std::unique_ptr<CLKernelVk>;
71 
72     struct KernelSpecConstant
73     {
74         uint32_t ID;
75         uint32_t data;
76     };
77     // Setting a reasonable initial value
78     // https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_API.html#CL_DEVICE_MAX_PARAMETER_SIZE
79     using KernelSpecConstants = angle::FastVector<KernelSpecConstant, 128>;
80 
81     CLKernelVk(const cl::Kernel &kernel,
82                std::string &name,
83                std::string &attributes,
84                CLKernelArguments &args);
85     ~CLKernelVk() override;
86 
87     angle::Result init();
88 
89     angle::Result setArg(cl_uint argIndex, size_t argSize, const void *argValue) override;
90 
91     angle::Result createInfo(CLKernelImpl::Info *infoOut) const override;
92 
getProgram()93     CLProgramVk *getProgram() { return mProgram; }
getKernelName()94     const std::string &getKernelName() { return mName; }
getArgs()95     const CLKernelArguments &getArgs() { return mArgs; }
initPipelineLayout()96     angle::Result initPipelineLayout()
97     {
98         PipelineLayoutCache *pipelineLayoutCache = mContext->getPipelineLayoutCache();
99         return pipelineLayoutCache->getPipelineLayout(mContext, mPipelineLayoutDesc,
100                                                       mDescriptorSetLayouts, &mPipelineLayout);
101     }
getPipelineLayout()102     const vk::PipelineLayout &getPipelineLayout() const { return *mPipelineLayout; }
getDescriptorSetLayouts()103     vk::DescriptorSetLayoutPointerArray &getDescriptorSetLayouts() { return mDescriptorSetLayouts; }
getFrontendObject()104     cl::Kernel &getFrontendObject() { return const_cast<cl::Kernel &>(mKernel); }
105 
106     angle::Result getOrCreateComputePipeline(vk::PipelineCacheAccess *pipelineCache,
107                                              const cl::NDRange &ndrange,
108                                              const cl::Device &device,
109                                              vk::PipelineHelper **pipelineOut,
110                                              cl::WorkgroupCount *workgroupCountOut);
111 
getDescriptorSetLayoutDesc(DescriptorSetIndex index)112     const vk::DescriptorSetLayoutDesc &getDescriptorSetLayoutDesc(DescriptorSetIndex index) const
113     {
114         return mDescriptorSetLayoutDescs[index];
115     }
getKernelArgDescriptorSetDesc()116     const vk::DescriptorSetLayoutDesc &getKernelArgDescriptorSetDesc() const
117     {
118         return getDescriptorSetLayoutDesc(DescriptorSetIndex::KernelArguments);
119     }
getLiteralSamplerDescriptorSetDesc()120     const vk::DescriptorSetLayoutDesc &getLiteralSamplerDescriptorSetDesc() const
121     {
122         return getDescriptorSetLayoutDesc(DescriptorSetIndex::LiteralSampler);
123     }
getPrintfDescriptorSetDesc()124     const vk::DescriptorSetLayoutDesc &getPrintfDescriptorSetDesc() const
125     {
126         return getDescriptorSetLayoutDesc(DescriptorSetIndex::Printf);
127     }
128 
getPipelineLayoutDesc()129     const vk::PipelineLayoutDesc &getPipelineLayoutDesc() { return mPipelineLayoutDesc; }
130 
getDescriptorSet(DescriptorSetIndex index)131     VkDescriptorSet getDescriptorSet(DescriptorSetIndex index)
132     {
133         return mDescriptorSets[index]->getDescriptorSet();
134     }
135 
getPodArgumentsData()136     std::vector<uint8_t> &getPodArgumentsData() { return mPodArgumentsData; }
137 
138     bool usesPrintf() const;
139 
140     angle::Result allocateDescriptorSet(
141         DescriptorSetIndex index,
142         angle::EnumIterator<DescriptorSetIndex> layoutIndex,
143         vk::OutsideRenderPassCommandBufferHelper *computePassCommands);
144 
145   private:
146     static constexpr std::array<size_t, 3> kEmptyWorkgroupSize = {0, 0, 0};
147 
148     CLProgramVk *mProgram;
149     CLContextVk *mContext;
150     std::string mName;
151     std::string mAttributes;
152     CLKernelArguments mArgs;
153 
154     // Copy of the pod data
155     std::vector<uint8_t> mPodArgumentsData;
156 
157     vk::ShaderProgramHelper mShaderProgramHelper;
158     vk::ComputePipelineCache mComputePipelineCache;
159     KernelSpecConstants mSpecConstants;
160     vk::PipelineLayoutPtr mPipelineLayout;
161     vk::DescriptorSetLayoutPointerArray mDescriptorSetLayouts{};
162 
163     vk::DescriptorSetArray<vk::DescriptorSetPointer> mDescriptorSets;
164 
165     vk::DescriptorSetArray<vk::DescriptorSetLayoutDesc> mDescriptorSetLayoutDescs;
166     vk::PipelineLayoutDesc mPipelineLayoutDesc;
167 };
168 
169 }  // namespace rx
170 
171 #endif  // LIBANGLE_RENDERER_VULKAN_CLKERNELVK_H_
172