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 // cl_types.h: Defines common types for the OpenCL support in ANGLE. 7 8 #ifndef LIBANGLE_CLTYPES_H_ 9 #define LIBANGLE_CLTYPES_H_ 10 11 #if defined(ANGLE_ENABLE_CL) 12 # include "libANGLE/CLBitField.h" 13 # include "libANGLE/CLRefPointer.h" 14 # include "libANGLE/Debug.h" 15 # include "libANGLE/angletypes.h" 16 17 # include "common/PackedCLEnums_autogen.h" 18 # include "common/angleutils.h" 19 20 // Include frequently used standard headers 21 # include <algorithm> 22 # include <array> 23 # include <functional> 24 # include <list> 25 # include <memory> 26 # include <string> 27 # include <utility> 28 # include <vector> 29 30 namespace cl 31 { 32 33 class Buffer; 34 class CommandQueue; 35 class Context; 36 class Device; 37 class Event; 38 class Image; 39 class Kernel; 40 class Memory; 41 class Object; 42 class Platform; 43 class Program; 44 class Sampler; 45 46 using BufferPtr = RefPointer<Buffer>; 47 using CommandQueuePtr = RefPointer<CommandQueue>; 48 using ContextPtr = RefPointer<Context>; 49 using DevicePtr = RefPointer<Device>; 50 using EventPtr = RefPointer<Event>; 51 using KernelPtr = RefPointer<Kernel>; 52 using MemoryPtr = RefPointer<Memory>; 53 using PlatformPtr = RefPointer<Platform>; 54 using ProgramPtr = RefPointer<Program>; 55 using SamplerPtr = RefPointer<Sampler>; 56 57 using BufferPtrs = std::vector<BufferPtr>; 58 using DevicePtrs = std::vector<DevicePtr>; 59 using EventPtrs = std::vector<EventPtr>; 60 using KernelPtrs = std::vector<KernelPtr>; 61 using MemoryPtrs = std::vector<MemoryPtr>; 62 using PlatformPtrs = std::vector<PlatformPtr>; 63 using ProgramPtrs = std::vector<ProgramPtr>; 64 65 using WorkgroupSize = std::array<size_t, 3>; 66 using GlobalWorkOffset = std::array<size_t, 3>; 67 using GlobalWorkSize = std::array<size_t, 3>; 68 using WorkgroupCount = std::array<uint32_t, 3>; 69 70 template <typename T> 71 using EventStatusMap = std::array<T, 3>; 72 73 using Extents = angle::Extents<size_t>; 74 using Offset = angle::Offset<size_t>; 75 constexpr Offset kOffsetZero(0, 0, 0); 76 77 struct KernelArg 78 { 79 bool isSet; 80 cl_uint index; 81 size_t size; 82 const void *valuePtr; 83 }; 84 85 struct BufferBox 86 { 87 BufferBox(const Offset &offset, 88 const Extents &size, 89 const size_t row_pitch, 90 const size_t slice_pitch, 91 const size_t element_size = 1) mOriginBufferBox92 : mOrigin(offset), 93 mSize(size), 94 mRowPitch(row_pitch == 0 ? element_size * size.width : row_pitch), 95 mSlicePitch(slice_pitch == 0 ? mRowPitch * size.height : slice_pitch), 96 mElementSize(element_size) 97 {} validBufferBox98 bool valid() const 99 { 100 return mSize.width != 0 && mSize.height != 0 && mSize.depth != 0 && 101 mRowPitch >= mSize.width * mElementSize && mSlicePitch >= mRowPitch * mSize.height && 102 mElementSize > 0; 103 } 104 bool operator==(const BufferBox &other) const 105 { 106 return (mOrigin == other.mOrigin && mSize == other.mSize && mRowPitch == other.mRowPitch && 107 mSlicePitch == other.mSlicePitch && mElementSize == other.mElementSize); 108 } 109 bool operator!=(const BufferBox &other) const { return !(*this == other); } 110 getRowOffsetBufferBox111 size_t getRowOffset(size_t slice, size_t row) const 112 { 113 return ((mRowPitch * (mOrigin.y + row)) + (mOrigin.x * mElementSize)) + // row offset 114 (mSlicePitch * (mOrigin.z + slice)); // slice offset 115 } 116 getRowPitchBufferBox117 size_t getRowPitch() { return mRowPitch; } getSlicePitchBufferBox118 size_t getSlicePitch() { return mSlicePitch; } 119 Offset mOrigin; 120 Extents mSize; 121 size_t mRowPitch; 122 size_t mSlicePitch; 123 size_t mElementSize; 124 }; 125 126 struct BufferRect 127 { 128 BufferRect(const Offset &offset, 129 const Extents &size, 130 const size_t row_pitch, 131 const size_t slice_pitch, 132 const size_t element_size = 1) mOriginBufferRect133 : mOrigin(offset), 134 mSize(size), 135 mRowPitch(row_pitch), 136 mSlicePitch(slice_pitch), 137 mElementSize(element_size) 138 {} validBufferRect139 bool valid() const 140 { 141 return mSize.width != 0 && mSize.height != 0 && mSize.depth != 0 && 142 mRowPitch >= mSize.width * mElementSize && mSlicePitch >= mRowPitch * mSize.height && 143 mElementSize > 0; 144 } 145 bool operator==(const BufferRect &other) const 146 { 147 return (mOrigin == other.mOrigin && mSize == other.mSize && mRowPitch == other.mRowPitch && 148 mSlicePitch == other.mSlicePitch && mElementSize == other.mElementSize); 149 } 150 bool operator!=(const BufferRect &other) const { return !(*this == other); } 151 getRowOffsetBufferRect152 size_t getRowOffset(size_t slice, size_t row) const 153 { 154 return ((mRowPitch * (mOrigin.y + row)) + (mOrigin.x * mElementSize)) + // row offset 155 (mSlicePitch * (mOrigin.z + slice)); // slice offset 156 } 157 158 Offset mOrigin; 159 Extents mSize; 160 size_t mRowPitch; 161 size_t mSlicePitch; 162 size_t mElementSize; 163 }; 164 165 struct ImageDescriptor 166 { 167 MemObjectType type; 168 size_t width; 169 size_t height; 170 size_t depth; 171 size_t arraySize; 172 size_t rowPitch; 173 size_t slicePitch; 174 cl_uint numMipLevels; 175 cl_uint numSamples; 176 ImageDescriptorImageDescriptor177 ImageDescriptor(MemObjectType type_, 178 size_t width_, 179 size_t height_, 180 size_t depth_, 181 size_t arraySize_, 182 size_t rowPitch_, 183 size_t slicePitch_, 184 cl_uint numMipLevels_, 185 cl_uint numSamples_) 186 : type(type_), 187 width(width_), 188 height(height_), 189 depth(depth_), 190 arraySize(arraySize_), 191 rowPitch(rowPitch_), 192 slicePitch(slicePitch_), 193 numMipLevels(numMipLevels_), 194 numSamples(numSamples_) 195 { 196 if (type == MemObjectType::Image1D || type == MemObjectType::Image1D_Array || 197 type == MemObjectType::Image1D_Buffer) 198 { 199 height = 1; 200 } 201 if (type == MemObjectType::Image2D) 202 { 203 depth = 1; 204 } 205 if (!(type == MemObjectType::Image1D_Array || type == MemObjectType::Image2D_Array)) 206 { 207 arraySize = 1; 208 } 209 } 210 }; 211 212 struct MemOffsets 213 { 214 size_t x, y, z; 215 }; 216 constexpr MemOffsets kMemOffsetsZero{0, 0, 0}; 217 218 struct Coordinate 219 { 220 size_t x, y, z; 221 }; 222 constexpr Coordinate kCoordinateZero{0, 0, 0}; 223 224 struct NDRange 225 { NDRangeNDRange226 NDRange(cl_uint workDimensionsIn, 227 const size_t *globalWorkOffsetIn, 228 const size_t *globalWorkSizeIn, 229 const size_t *localWorkSizeIn) 230 : workDimensions(workDimensionsIn), 231 globalWorkOffset({0, 0, 0}), 232 globalWorkSize({1, 1, 1}), 233 localWorkSize({1, 1, 1}), 234 nullLocalWorkSize(localWorkSizeIn == nullptr) 235 { 236 for (cl_uint dim = 0; dim < workDimensionsIn; dim++) 237 { 238 if (globalWorkOffsetIn != nullptr) 239 { 240 globalWorkOffset[dim] = globalWorkOffsetIn[dim]; 241 } 242 if (globalWorkSizeIn != nullptr) 243 { 244 globalWorkSize[dim] = globalWorkSizeIn[dim]; 245 } 246 if (localWorkSizeIn != nullptr) 247 { 248 localWorkSize[dim] = localWorkSizeIn[dim]; 249 } 250 } 251 } 252 253 cl_uint workDimensions; 254 GlobalWorkOffset globalWorkOffset; 255 GlobalWorkSize globalWorkSize; 256 WorkgroupSize localWorkSize; 257 bool nullLocalWorkSize{false}; 258 }; 259 260 } // namespace cl 261 262 #endif // ANGLE_ENABLE_CL 263 264 #endif // LIBANGLE_CLTYPES_H_ 265