MetalCompute 1.0
An API to make GPU compute calls easier
Loading...
Searching...
No Matches
MTLComputeTexture.hpp
Go to the documentation of this file.
1#include <iostream>
2#include <vector>
4
5#pragma once
6
7namespace MTLCompute {
8
9 template<typename T>
10 class Texture {
11 private:
12 MTL::Device *gpu;
13 MTL::Texture *texture;
14 MTL::TextureDescriptor *descriptor;
15 int width = -1;
16 int height = -1;
17 bool freed = false;
18
25 void swap(Texture &tex) noexcept {
26 using std::swap;
27 swap(this->gpu, tex.gpu);
28 swap(this->texture, tex.texture);
29 swap(this->width, tex.width);
30 swap(this->height, tex.height);
31 swap(this->freed, tex.freed);
32 }
33
42 std::vector<T> flatten(std::vector<std::vector<T>> &v) const {
43 std::vector<T> result;
44 for (auto &inner : v) {
45 result.insert(result.end(), inner.begin(), inner.end());
46 }
47 return result;
48 }
49
60 std::vector<std::vector<T>> unflatten(std::vector<T> &v, int width, int height) const {
61 std::vector<std::vector<T>> result(height, std::vector<T>(width));
62 for (int i = 0; i < height; i++) {
63 for (int j = 0; j < width; j++) {
64 result[i][j] = v[i*width + j];
65 }
66 }
67 return result;
68 }
69
70 public:
71
83 Texture(MTL::Device *gpu, int width, int height, TextureType tt) {
84 this->gpu = gpu;
86 throw std::invalid_argument("Texture size too large, max size is 16384");
87 }
88 this->width = width;
89 this->height = height;
90 this->descriptor = MTL::TextureDescriptor::alloc()->init();
91 this->descriptor->setTextureType(MTL::TextureType2D);
92 this->descriptor->setPixelFormat(static_cast<MTL::PixelFormat>(tt));
93 if (sizeof(T) != TextureTypeSizes[tt]) {
94 std::cout << sizeof(T) << " " << TextureTypeSizes[tt] << std::endl;
95 throw std::invalid_argument("Texture type does not match template type");
96 }
97 this->descriptor->setWidth(width);
98 this->descriptor->setHeight(height);
99 this->texture = this->gpu->newTexture(this->descriptor);
100 }
101
112 Texture(MTL::Device *gpu, int width, int height) {
113 this->gpu = gpu;
115 throw std::invalid_argument("Texture size too large, max size is 16384");
116 }
117 this->width = width;
118 this->height = height;
119 this->descriptor = MTL::TextureDescriptor::alloc()->init();
120 this->descriptor->setTextureType(MTL::TextureType2D);
121 if (typeid(uint8_t) == typeid(T)) {
122 this->descriptor->setPixelFormat(MTL::PixelFormatR8Uint);
123 } else if (typeid(uint16_t) == typeid(T)) {
124 this->descriptor->setPixelFormat(MTL::PixelFormatR16Uint);
125 } else if (typeid(uint32_t) == typeid(T)) {
126 this->descriptor->setPixelFormat(MTL::PixelFormatR32Uint);
127 } else if (typeid(float) == typeid(T)) {
128 this->descriptor->setPixelFormat(MTL::PixelFormatR32Float);
129 } else if (typeid(int8_t) == typeid(T)) {
130 this->descriptor->setPixelFormat(MTL::PixelFormatR8Sint);
131 } else if (typeid(int16_t) == typeid(T)) {
132 this->descriptor->setPixelFormat(MTL::PixelFormatR16Sint);
133 } else if (typeid(int32_t) == typeid(T)) {
134 this->descriptor->setPixelFormat(MTL::PixelFormatR32Sint);
135 } else if (typeid(float) == typeid(T)) {
136 this->descriptor->setPixelFormat(MTL::PixelFormatR32Float);
137 } else {
138 throw std::invalid_argument("Texture type not supported");
139 }
140 this->descriptor->setWidth(width);
141 this->descriptor->setHeight(height);
142 this->texture = this->gpu->newTexture(this->descriptor);
143 }
144
145
154 Texture(const Texture &other) {
155 this->gpu = other.gpu;
156 this->texture = other.texture;
157 this->width = other.width;
158 this->height = other.height;
159 this->descriptor = other.descriptor;
160 }
161
162
170 this->gpu = nullptr;
171 this->descriptor = nullptr;
172 this->texture = nullptr;
173 this->width = -1;
174 this->height = -1;
175 }
176
185 if (!this->freed) {
186 this->texture->autorelease();
187 this->descriptor->autorelease();
188 this->freed = true;
189 }
190 }
191
198 void operator=(std::vector<std::vector<T>> data) {
199 if (this->freed) {
200 throw std::runtime_error("Texture already freed");
201 }
202 if (data.size() != this->height || data[0].size() != this->width) {
203 throw std::invalid_argument("Data size does not match texture size");
204 }
205 if (data.size() > MAX_TEXTURE_SIZE || data[0].size() > MAX_TEXTURE_SIZE) {
206 throw std::invalid_argument("Data size too large, max size is 16384");
207 }
208 std::vector<T> flat = flatten(data);
209 this->texture->replaceRegion(MTL::Region::Make2D(0, 0, this->width, this->height), 0, flat.data(), this->width*sizeof(T));
210 }
211
218 Texture & operator=(const Texture &other) {
219
220 Texture temp(other);
221 swap(temp);
222
223 return *this;
224 }
225
234 std::vector<T> operator[](size_t index) const {
235 if (this->freed) {
236 throw std::runtime_error("Texture already freed");
237 }
238 if (index >= (long)this->width*(long)this->height) {
239 throw std::out_of_range("Index out of bounds");
240 }
241 std::vector<T> flat((long)this->width*(long)this->height);
242 this->texture->getBytes(flat.data(), this->width*sizeof(T), MTL::Region::Make2D(0, 0, this->width, this->height), 0);
243 return unflatten(flat, this->width, this->height)[index];
244 }
245
252 std::vector<std::vector<T>> getData() {
253 if (this->freed) {
254 throw std::runtime_error("Buffer already freed");
255 }
256 if (this->width == -1 || this->height == -1) {
257 throw std::runtime_error("Buffer not initialized");
258 }
259 std::vector<T> flat((long)this->width*(long)this->height);
260 this->texture->getBytes(flat.data(), this->width*sizeof(T), MTL::Region::Make2D(0, 0, this->width, this->height), 0);
261 return unflatten(flat, this->width, this->height);
262 }
263
270 MTL::Texture *getTexture() {
271 return this->texture;
272 }
273
280 MTL::Device *getGPU() {
281 return this->gpu;
282 }
283
290 bool getFreed() {
291 return this->freed;
292 }
293
300 MTL::TextureDescriptor *getDescriptor() {
301 return this->descriptor;
302 }
303
310 int getWidth() {
311 return this->width;
312 }
313
320 int getHeight() {
321 return this->height;
322 }
323 };
324
325}
Definition MTLComputeTexture.hpp:10
bool getFreed()
Get whether the texture has been freed.
Definition MTLComputeTexture.hpp:290
std::vector< std::vector< T > > unflatten(std::vector< T > &v, int width, int height) const
Unflatten a 1D vector into a 2D vector.
Definition MTLComputeTexture.hpp:60
std::vector< T > flatten(std::vector< std::vector< T > > &v) const
Flatten a 2D vector into a 1D vector.
Definition MTLComputeTexture.hpp:42
int height
The width and height of the texture.
Definition MTLComputeTexture.hpp:16
Texture & operator=(const Texture &other)
Overload the = operator to set texture contents from another texture.
Definition MTLComputeTexture.hpp:218
MTL::Device * getGPU()
Get the GPU device.
Definition MTLComputeTexture.hpp:280
MTL::Texture * getTexture()
Get the MTL::Texture object.
Definition MTLComputeTexture.hpp:270
int getWidth()
Get the width of the texture.
Definition MTLComputeTexture.hpp:310
MTL::TextureDescriptor * getDescriptor()
Get the texture descriptor.
Definition MTLComputeTexture.hpp:300
Texture()
Default constructor for the Texture class.
Definition MTLComputeTexture.hpp:169
void operator=(std::vector< std::vector< T > > data)
Overload the = operator to set texture contents from a vector.
Definition MTLComputeTexture.hpp:198
int width
The width and height of the texture.
Definition MTLComputeTexture.hpp:15
Texture(MTL::Device *gpu, int width, int height)
Constructor for the Texture class.
Definition MTLComputeTexture.hpp:112
std::vector< T > operator[](size_t index) const
Overload the [] operator to get a row from the texture.
Definition MTLComputeTexture.hpp:234
MTL::Device * gpu
The Metal device object.
Definition MTLComputeTexture.hpp:12
void swap(Texture &tex) noexcept
Swap the contents of two Textures.
Definition MTLComputeTexture.hpp:25
std::vector< std::vector< T > > getData()
Get the data from the texture as a vector.
Definition MTLComputeTexture.hpp:252
bool freed
Whether the texture has been freed.
Definition MTLComputeTexture.hpp:17
Texture(MTL::Device *gpu, int width, int height, TextureType tt)
Constructor for the Texture class.
Definition MTLComputeTexture.hpp:83
~Texture()
Destructor for the Texture class.
Definition MTLComputeTexture.hpp:184
Texture(const Texture &other)
Copy constructor for the Texture class.
Definition MTLComputeTexture.hpp:154
int getHeight()
Get the height of the texture.
Definition MTLComputeTexture.hpp:320
MTL::Texture * texture
The Metal texture object.
Definition MTLComputeTexture.hpp:13
MTL::TextureDescriptor * descriptor
The Metal texture descriptor object.
Definition MTLComputeTexture.hpp:14
Definition MTLComputeBuffer.hpp:7
constexpr long MAX_TEXTURE_SIZE
Definition MTLComputeGlobals.hpp:13
std::map< TextureType, size_t > TextureTypeSizes
Definition MTLComputeGlobals.hpp:34
TextureType
Definition MTLComputeGlobals.hpp:22