• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/CLMemory.h"
17 #include "libANGLE/renderer/CLKernelImpl.h"
18 #include "vulkan/vulkan_core.h"
19 
20 namespace rx
21 {
22 
23 struct CLKernelArgument
24 {
25     CLKernelImpl::ArgInfo info{};
26     uint32_t type     = 0;
27     uint32_t ordinal  = 0;
28     size_t handleSize = 0;
29     void *handle      = nullptr;
30     bool used         = false;
31 
32     // Shared operand words/regions for "OpExtInst" type spv instructions
33     // (starts from spv word index/offset 7 and onward)
34     // https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpExtInst
35     // https://github.com/google/clspv/blob/main/docs/OpenCLCOnVulkan.md#kernels
36     union
37     {
38         uint32_t op3;
39         uint32_t descriptorSet;
40         uint32_t pushConstOffset;
41         uint32_t workgroupSpecId;
42     };
43     union
44     {
45         uint32_t op4;
46         uint32_t descriptorBinding;
47         uint32_t pushConstantSize;
48         uint32_t workgroupSize;
49     };
50     union
51     {
52         uint32_t op5;
53         uint32_t podStorageBufferOffset;
54         uint32_t podUniformOffset;
55         uint32_t pointerUniformOffset;
56     };
57     union
58     {
59         uint32_t op6;
60         uint32_t podStorageBufferSize;
61         uint32_t podUniformSize;
62         uint32_t pointerUniformSize;
63     };
64 };
65 using CLKernelArguments = std::vector<CLKernelArgument>;
66 using CLKernelArgsMap   = angle::HashMap<std::string, CLKernelArguments>;
67 
68 class CLKernelVk : public CLKernelImpl
69 {
70   public:
71     using Ptr = std::unique_ptr<CLKernelVk>;
72 
73     struct KernelSpecConstant
74     {
75         uint32_t ID;
76         uint32_t data;
77     };
78     // Setting a reasonable initial value
79     // https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_API.html#CL_DEVICE_MAX_PARAMETER_SIZE
80     using KernelSpecConstants = angle::FastVector<KernelSpecConstant, 128>;
81 
82     CLKernelVk(const cl::Kernel &kernel,
83                std::string &name,
84                std::string &attributes,
85                CLKernelArguments &args);
86     ~CLKernelVk() override;
87 
88     angle::Result init();
89 
90     angle::Result setArg(cl_uint argIndex, size_t argSize, const void *argValue) override;
91 
92     angle::Result createInfo(CLKernelImpl::Info *infoOut) const override;
93 
94     angle::Result initPipelineLayout();
95 
getProgram()96     CLProgramVk *getProgram() { return mProgram; }
getKernelName()97     const std::string &getKernelName() { return mName; }
getArgs()98     const CLKernelArguments &getArgs() { return mArgs; }
getPipelineLayout()99     const vk::PipelineLayout &getPipelineLayout() const { return *mPipelineLayout; }
getDescriptorSetLayouts()100     vk::DescriptorSetLayoutPointerArray &getDescriptorSetLayouts() { return mDescriptorSetLayouts; }
getFrontendObject()101     cl::Kernel &getFrontendObject() { return const_cast<cl::Kernel &>(mKernel); }
102 
103     angle::Result getOrCreateComputePipeline(vk::PipelineCacheAccess *pipelineCache,
104                                              const cl::NDRange &ndrange,
105                                              const cl::Device &device,
106                                              vk::PipelineHelper **pipelineOut);
107 
getDescriptorSetLayoutDesc(DescriptorSetIndex index)108     const vk::DescriptorSetLayoutDesc &getDescriptorSetLayoutDesc(DescriptorSetIndex index) const
109     {
110         return mDescriptorSetLayoutDescs[index];
111     }
getKernelArgDescriptorSetDesc()112     const vk::DescriptorSetLayoutDesc &getKernelArgDescriptorSetDesc() const
113     {
114         return getDescriptorSetLayoutDesc(DescriptorSetIndex::KernelArguments);
115     }
getLiteralSamplerDescriptorSetDesc()116     const vk::DescriptorSetLayoutDesc &getLiteralSamplerDescriptorSetDesc() const
117     {
118         return getDescriptorSetLayoutDesc(DescriptorSetIndex::LiteralSampler);
119     }
getPrintfDescriptorSetDesc()120     const vk::DescriptorSetLayoutDesc &getPrintfDescriptorSetDesc() const
121     {
122         return getDescriptorSetLayoutDesc(DescriptorSetIndex::Printf);
123     }
124 
getPipelineLayoutDesc()125     const vk::PipelineLayoutDesc &getPipelineLayoutDesc() { return mPipelineLayoutDesc; }
126 
getDescriptorSet(DescriptorSetIndex index)127     VkDescriptorSet getDescriptorSet(DescriptorSetIndex index)
128     {
129         return mDescriptorSets[index]->getDescriptorSet();
130     }
131 
getPodArgumentPushConstantsData()132     std::vector<uint8_t> &getPodArgumentPushConstantsData() { return mPodArgumentPushConstants; }
133 
getPodBuffer()134     cl::MemoryPtr getPodBuffer() { return mPodBuffer; }
135 
136     bool usesPrintf() const;
137 
138     angle::Result allocateDescriptorSet(
139         DescriptorSetIndex index,
140         angle::EnumIterator<DescriptorSetIndex> layoutIndex,
141         vk::OutsideRenderPassCommandBufferHelper *computePassCommands);
142 
143   private:
144     // Initialize the descriptor pools for this kernel resources
145     angle::Result initializeDescriptorPools();
146 
147     CLProgramVk *mProgram;
148     CLContextVk *mContext;
149     std::string mName;
150     std::string mAttributes;
151     CLKernelArguments mArgs;
152 
153     std::vector<uint8_t> mPodArgumentPushConstants;
154     cl::MemoryPtr mPodBuffer;
155 
156     vk::ShaderProgramHelper mShaderProgramHelper;
157     ComputePipelineCache mComputePipelineCache;
158     KernelSpecConstants mSpecConstants;
159 
160     // Pipeline and DescriptorSetLayout Shared pointers
161     vk::PipelineLayoutPtr mPipelineLayout;
162     vk::DescriptorSetLayoutPointerArray mDescriptorSetLayouts{};
163 
164     // DescriptorSet and DescriptorPool shared pointers for this kernel resources
165     vk::DescriptorSetArray<vk::DescriptorSetPointer> mDescriptorSets;
166     vk::DescriptorSetArray<vk::DynamicDescriptorPoolPointer> mDynamicDescriptorPools;
167 
168     vk::DescriptorSetArray<vk::DescriptorSetLayoutDesc> mDescriptorSetLayoutDescs;
169     vk::PipelineLayoutDesc mPipelineLayoutDesc;
170 };
171 
172 }  // namespace rx
173 
174 #endif  // LIBANGLE_RENDERER_VULKAN_CLKERNELVK_H_
175