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_GL_GL_TEXTURE_H_ 17 #define TENSORFLOW_LITE_DELEGATES_GPU_GL_GL_TEXTURE_H_ 18 19 #include "absl/types/span.h" 20 #include "tensorflow/lite/delegates/gpu/common/data_type.h" 21 #include "tensorflow/lite/delegates/gpu/common/status.h" 22 #include "tensorflow/lite/delegates/gpu/common/tensor.h" 23 #include "tensorflow/lite/delegates/gpu/common/types.h" 24 #include "tensorflow/lite/delegates/gpu/gl/gl_call.h" 25 #include "tensorflow/lite/delegates/gpu/gl/portable_gl31.h" 26 27 namespace tflite { 28 namespace gpu { 29 namespace gl { 30 31 // Texture is an RAII wrapper for OpenGL texture object. 32 // See https://www.khronos.org/opengl/wiki/Texture for more information. 33 // 34 // Texture is moveable but not copyable. 35 class GlTexture { 36 public: 37 // Creates invalid texture. GlTexture()38 GlTexture() 39 : GlTexture(GL_INVALID_ENUM, GL_INVALID_INDEX, GL_INVALID_ENUM, 0, 0, 40 false) {} 41 GlTexture(GLenum target,GLuint id,GLenum format,size_t bytes_size,GLint layer,bool owned)42 GlTexture(GLenum target, GLuint id, GLenum format, size_t bytes_size, 43 GLint layer, bool owned) 44 : id_(id), 45 target_(target), 46 format_(format), 47 bytes_size_(bytes_size), 48 layer_(layer), 49 owned_(owned) {} 50 51 // Move-only 52 GlTexture(GlTexture&& texture); 53 GlTexture& operator=(GlTexture&& texture); 54 GlTexture(const GlTexture&) = delete; 55 GlTexture& operator=(const GlTexture&) = delete; 56 57 ~GlTexture(); 58 59 // Binds a texture as an image to the given index. 60 absl::Status BindAsReadonlyImage(uint32_t index) const; 61 62 // Bind texture as an image for write access at given index. 63 absl::Status BindAsWriteonlyImage(uint32_t index) const; 64 65 // Bind texture as an image for read-write access at given index. 66 absl::Status BindAsReadWriteImage(uint32_t index) const; 67 68 // Binds a texture as a sampler to the given index. 69 absl::Status BindAsSampler2D(uint32_t index) const; 70 target()71 GLenum target() const { return target_; } 72 id()73 GLuint id() const { return id_; } 74 format()75 GLenum format() const { return format_; } 76 layer()77 GLint layer() const { return layer_; } 78 is_valid()79 bool is_valid() const { return id_ != GL_INVALID_INDEX; } 80 bytes_size()81 size_t bytes_size() const { return bytes_size_; } 82 83 // @return true if this object actually owns corresponding GL buffer 84 // and manages it's lifetime. has_ownership()85 bool has_ownership() const { return owned_; } 86 87 private: 88 void Invalidate(); 89 90 absl::Status BindImage(uint32_t index, GLenum access) const; 91 92 GLuint id_; 93 GLenum target_; 94 GLenum format_; 95 size_t bytes_size_; 96 GLint layer_; 97 bool owned_; 98 }; 99 100 // Creates new 2D image texture that will be filled with float32 data once which 101 // will be used for reading. 102 // 103 // @param size defines 2D image texture size where each pixel is RGBA. 104 absl::Status CreateReadOnlyImageTexture(const uint2& size, 105 absl::Span<const float> data, 106 GlTexture* gl_texture); 107 108 // Creates new 2D image texture that will be filled with float16 data once which 109 // will be used for reading. 110 // 111 // @param size defines 2D image texture size where each pixel is RGBA. 112 absl::Status CreateReadOnlyImageTextureF16(const uint2& size, 113 absl::Span<const uint16_t> data, 114 GlTexture* gl_texture); 115 116 // Creates new 2D image texture that will be filled with uint8 data once which 117 // will be used for reading. 118 // 119 // @param size defines 2D image texture size where each pixel is RGBA. 120 absl::Status CreateReadOnlyImageTextureU8(const uint2& size, 121 absl::Span<const uint8_t> data, 122 GlTexture* gl_texture); 123 124 // Creates new 3D RGBA image texture that will be filled with float32 data once 125 // which will be used for reading. 126 // 127 // @param size defines 3D image texture size where each pixel is RGBA. 128 absl::Status CreateReadOnlyImageTexture(const uint3& size, 129 absl::Span<const float> data, 130 GlTexture* gl_texture); 131 132 // Creates new 3D RGBA image texture that will be filled with float16 data once 133 // which will be used for reading. 134 // 135 // @param size defines 3D image texture size where each pixel is RGBA. 136 absl::Status CreateReadOnlyImageTextureF16(const uint3& size, 137 absl::Span<const uint16_t> data, 138 GlTexture* gl_texture); 139 140 // Creates new RGBA 2D image texture 141 // 142 // @param size defines 2D image texture size where each pixel is RGBA. 143 absl::Status CreateReadWriteRgbaImageTexture(DataType data_type, 144 const uint2& size, 145 GlTexture* gl_texture); 146 147 // Creates new RGBA 3D image texture 148 // 149 // @param size defines 3D image texture size where each pixel is RGBA. 150 absl::Status CreateReadWriteRgbaImageTexture(DataType data_type, 151 const uint3& size, 152 GlTexture* gl_texture); 153 154 namespace gl_texture_internal { 155 156 // RAII for creating and/or owning texture id. 157 class TextureId { 158 public: TextureId()159 TextureId() : id_(GL_INVALID_INDEX) { 160 TFLITE_GPU_CALL_GL(glGenTextures, 1 /* number of textures*/, &id_) 161 .IgnoreError(); 162 } 163 TextureId(GLuint id)164 explicit TextureId(GLuint id) : id_(id) {} 165 ~TextureId()166 ~TextureId() { 167 if (id_ != GL_INVALID_INDEX) { 168 TFLITE_GPU_CALL_GL(glDeleteTextures, 1, &id_).IgnoreError(); 169 } 170 } 171 id()172 GLuint id() const { return id_; } 173 Release()174 GLuint Release() { 175 GLuint id = GL_INVALID_INDEX; 176 std::swap(id, id_); 177 return id; 178 } 179 180 private: 181 GLuint id_; 182 }; 183 184 // RAII for binding and unbinding a texture. 185 class TextureBinder { 186 public: TextureBinder(GLenum target,GLuint id)187 TextureBinder(GLenum target, GLuint id) : target_(target) { 188 TFLITE_GPU_CALL_GL(glBindTexture, target_, id).IgnoreError(); 189 } 190 ~TextureBinder()191 ~TextureBinder() { 192 TFLITE_GPU_CALL_GL(glBindTexture, target_, 0).IgnoreError(); 193 } 194 195 private: 196 const GLenum target_; 197 }; 198 199 } // namespace gl_texture_internal 200 } // namespace gl 201 } // namespace gpu 202 } // namespace tflite 203 204 #endif // TENSORFLOW_LITE_DELEGATES_GPU_GL_GL_TEXTURE_H_ 205