• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2019 The TensorFlow 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 
16 #ifndef TENSORFLOW_LITE_DELEGATES_GPU_CL_TEXTURE2D_H_
17 #define TENSORFLOW_LITE_DELEGATES_GPU_CL_TEXTURE2D_H_
18 
19 #include "absl/strings/str_cat.h"
20 #include "absl/types/span.h"
21 #include "tensorflow/lite/delegates/gpu/cl/cl_command_queue.h"
22 #include "tensorflow/lite/delegates/gpu/cl/cl_context.h"
23 #include "tensorflow/lite/delegates/gpu/cl/gpu_object.h"
24 #include "tensorflow/lite/delegates/gpu/cl/opencl_wrapper.h"
25 #include "tensorflow/lite/delegates/gpu/cl/util.h"
26 #include "tensorflow/lite/delegates/gpu/common/data_type.h"
27 #include "tensorflow/lite/delegates/gpu/common/status.h"
28 #include "tensorflow/lite/delegates/gpu/common/task/texture2d_desc.h"
29 
30 namespace tflite {
31 namespace gpu {
32 namespace cl {
33 
34 // Texture2D represent formatted GPU data storage.
35 // Texture2D is moveable but not copyable.
36 class Texture2D : public GPUObject {
37  public:
Texture2D()38   Texture2D() {}  // just for using Texture2D as a class members
39   Texture2D(cl_mem texture, int width, int height, cl_channel_type type);
40 
41   // Move only
42   Texture2D(Texture2D&& texture);
43   Texture2D& operator=(Texture2D&& texture);
44   Texture2D(const Texture2D&) = delete;
45   Texture2D& operator=(const Texture2D&) = delete;
46 
~Texture2D()47   virtual ~Texture2D() { Release(); }
48 
GetMemoryPtr()49   cl_mem GetMemoryPtr() const { return texture_; }
50 
51   // Writes data to a texture. Data should point to a region that
52   // has exact width * height * sizeof(pixel) bytes.
53   template <typename T>
54   absl::Status WriteData(CLCommandQueue* queue, const absl::Span<T> data);
55 
56   // Reads data from Texture2D into CPU memory.
57   template <typename T>
58   absl::Status ReadData(CLCommandQueue* queue, std::vector<T>* result) const;
59 
60   absl::Status GetGPUResources(const GPUObjectDescriptor* obj_ptr,
61                                GPUResourcesWithValue* resources) const override;
62 
63   absl::Status CreateFromTexture2DDescriptor(const Texture2DDescriptor& desc,
64                                              CLContext* context);
65 
66  private:
67   void Release();
68 
69   cl_mem texture_ = nullptr;
70   int width_;
71   int height_;
72   cl_channel_type channel_type_;
73 };
74 
75 using Texture2DPtr = std::shared_ptr<Texture2D>;
76 
77 // Creates new 4-channel 2D texture with f32 elements
78 absl::Status CreateTexture2DRGBA32F(int width, int height, CLContext* context,
79                                     Texture2D* result);
80 
81 // Creates new 4-channel 2D texture with f16 elements
82 absl::Status CreateTexture2DRGBA16F(int width, int height, CLContext* context,
83                                     Texture2D* result);
84 
85 absl::Status CreateTexture2DRGBA(DataType type, int width, int height,
86                                  CLContext* context, Texture2D* result);
87 
88 absl::Status CreateTexture2DRGBA(DataType type, int width, int height,
89                                  void* data, CLContext* context,
90                                  Texture2D* result);
91 
92 template <typename T>
WriteData(CLCommandQueue * queue,const absl::Span<T> data)93 absl::Status Texture2D::WriteData(CLCommandQueue* queue,
94                                   const absl::Span<T> data) {
95   const int element_size = ChannelTypeToSizeInBytes(channel_type_);
96   if (sizeof(T) % element_size != 0) {
97     return absl::InvalidArgumentError(
98         "Template type T has not suitable element type for created texture.");
99   }
100   if (4 * width_ * height_ * element_size != data.size() * sizeof(T)) {
101     return absl::InvalidArgumentError(
102         "absl::Span<T> data size is different from texture allocated size.");
103   }
104 
105   RETURN_IF_ERROR(queue->EnqueueWriteImage(texture_, int3(width_, height_, 1),
106                                            data.data()));
107 
108   return absl::OkStatus();
109 }
110 
111 template <typename T>
ReadData(CLCommandQueue * queue,std::vector<T> * result)112 absl::Status Texture2D::ReadData(CLCommandQueue* queue,
113                                  std::vector<T>* result) const {
114   const int element_size = ChannelTypeToSizeInBytes(channel_type_);
115   if (sizeof(T) != element_size) {
116     return absl::InvalidArgumentError("Pixel format is different.");
117   }
118 
119   const int elements_count = width_ * height_ * 4;
120   result->resize(elements_count);
121 
122   return queue->EnqueueReadImage(texture_, int3(width_, height_, 1),
123                                  result->data());
124 }
125 
126 }  // namespace cl
127 }  // namespace gpu
128 }  // namespace tflite
129 
130 #endif  // TENSORFLOW_LITE_DELEGATES_GPU_CL_TEXTURE2D_H_
131