• 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_GL_RUNTIME_SHARED_BUFFER_H_
17 #define TENSORFLOW_LITE_DELEGATES_GPU_GL_RUNTIME_SHARED_BUFFER_H_
18 
19 #include <algorithm>
20 #include <iterator>
21 #include <vector>
22 
23 #include "tensorflow/lite/delegates/gpu/common/status.h"
24 #include "tensorflow/lite/delegates/gpu/common/util.h"
25 #include "tensorflow/lite/delegates/gpu/gl/gl_buffer.h"
26 #include "tensorflow/lite/delegates/gpu/gl/object.h"
27 #include "tensorflow/lite/delegates/gpu/gl/portable_gl31.h"
28 
29 namespace tflite {
30 namespace gpu {
31 namespace gl {
32 
33 // Class accumulates readonly data and creates a single buffer out of it.
34 // User should call Add one or more times and complete shared buffer creation
35 // with CreateSharedBuffer() call.
36 class SharedBufferData {
37  public:
SharedBufferData()38   SharedBufferData() {
39     glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &alignment_);
40   }
41 
42   // @return true if data was added to the shared buffer.
Add(const ObjectData & data,GlBuffer * buffer)43   bool Add(const ObjectData& data, GlBuffer* buffer) {
44     // TODO(akulik): Does it make sense to bundle even big buffers > 1MB?
45 
46     // align buffer's data.
47     shared_data_.resize(AlignByN(shared_data_.size(), alignment_), 0);
48     // Accumulate readonly data in a single shared buffer buffer.
49     *buffer = GlBuffer(GL_SHADER_STORAGE_BUFFER, buffer_id_.id(), data.size(),
50                        shared_data_.size(), /*has_ownership=*/false);
51     std::copy(data.begin(), data.end(), std::back_inserter(shared_data_));
52     return true;
53   }
54 
empty()55   bool empty() const { return shared_data_.empty(); }
56 
57   // Returns a single GlBuffer that owns entire shared data.
CreateSharedGlBuffer(GlBuffer * gl_buffer)58   absl::Status CreateSharedGlBuffer(GlBuffer* gl_buffer) {
59     // Upload data to a buffer
60     gl_buffer_internal::BufferBinder binder(GL_SHADER_STORAGE_BUFFER,
61                                             buffer_id_.id());
62     RETURN_IF_ERROR(TFLITE_GPU_CALL_GL(glBufferData, GL_SHADER_STORAGE_BUFFER,
63                                        shared_data_.size(), shared_data_.data(),
64                                        GL_STATIC_READ));
65     *gl_buffer = GlBuffer(GL_SHADER_STORAGE_BUFFER, buffer_id_.Release(),
66                           shared_data_.size(), 0, /*has_ownership=*/true);
67     return absl::OkStatus();
68   }
69 
70  private:
71   GLint alignment_ = 256;
72   gl_buffer_internal::BufferId buffer_id_;
73   ObjectData shared_data_;
74 };
75 
76 }  // namespace gl
77 }  // namespace gpu
78 }  // namespace tflite
79 
80 #endif  // TENSORFLOW_LITE_DELEGATES_GPU_GL_RUNTIME_SHARED_BUFFER_H_
81