• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
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 GLES_DEVICE_GLES_H
17 #define GLES_DEVICE_GLES_H
18 
19 #include <cstddef>
20 #include <cstdint>
21 #include <mutex>
22 
23 #include <base/containers/string_view.h>
24 #include <base/containers/unique_ptr.h>
25 #include <base/containers/vector.h>
26 #include <base/math/vector.h>
27 #include <base/namespace.h>
28 #include <render/device/pipeline_state_desc.h>
29 #include <render/gles/intf_device_gles.h>
30 #include <render/namespace.h>
31 #include <render/resource_handle.h>
32 
33 #include "device/device.h"
34 #include "gles/swapchain_gles.h"
35 
36 #if RENDER_HAS_GLES_BACKEND
37 #include "egl_state.h"
38 #endif
39 #if RENDER_HAS_GL_BACKEND
40 #include "wgl_state.h"
41 #endif
42 
43 RENDER_BEGIN_NAMESPACE()
44 class ComputePipelineStateObject;
45 class GpuBuffer;
46 class GpuComputeProgram;
47 class GpuImage;
48 class GpuResourceManager;
49 class GpuSemaphore;
50 class GpuSampler;
51 class GpuShaderProgram;
52 class GraphicsPipelineStateObject;
53 class LowLevelDeviceGLES;
54 class NodeContextDescriptorSetManager;
55 class NodeContextPoolManager;
56 class RenderBackend;
57 class RenderFrameSync;
58 class PlatformGpuMemoryAllocator;
59 class ShaderManager;
60 class Swapchain;
61 class SwapchainGLES;
62 
63 struct BackendSpecificImageDesc;
64 struct GpuAccelerationStructureDesc;
65 struct GpuBufferDesc;
66 struct GpuComputeProgramCreateData;
67 struct GpuImageDesc;
68 struct GpuImagePlatformData;
69 struct GpuSamplerDesc;
70 struct GpuShaderProgramCreateData;
71 struct SwapchainCreateInfo;
72 struct PipelineLayout;
73 
74 class DeviceGLES final : public Device {
75 public:
76     // NOTE: normalized flag
77     struct ImageFormat {
78         BASE_NS::Format coreFormat;
79         uint32_t format;
80         uint32_t internalFormat;
81         uint32_t dataType;
82         uint32_t bytesperpixel;
83         struct {
84             bool compressed;
85             uint8_t blockW;
86             uint8_t blockH;
87             uint32_t bytesperblock;
88         } compression;
89         BASE_NS::Math::UVec4 swizzle;
90     };
91 
92     explicit DeviceGLES(RenderContext& renderContext);
93     ~DeviceGLES() override;
94 
95     // From IDevice
96     DeviceBackendType GetBackendType() const override;
97     const DevicePlatformData& GetPlatformData() const override;
98     AsBuildSizes GetAccelerationStructureBuildSizes(const AsBuildGeometryInfo& geometry,
99         BASE_NS::array_view<const AsGeometryTrianglesInfo> triangles,
100         BASE_NS::array_view<const AsGeometryAabbsInfo> aabbs,
101         BASE_NS::array_view<const AsGeometryInstancesInfo> instances) const override;
102     FormatProperties GetFormatProperties(BASE_NS::Format format) const override;
103     ILowLevelDevice& GetLowLevelDevice() const override;
104     // NOTE: can be called from API
105     void WaitForIdle() override;
106 
107     PlatformGpuMemoryAllocator* GetPlatformGpuMemoryAllocator() override;
108 
109     // (re-)create swapchain
110     BASE_NS::unique_ptr<Swapchain> CreateDeviceSwapchain(const SwapchainCreateInfo& swapchainCreateInfo) override;
111     void DestroyDeviceSwapchain() override;
112 
113     bool IsActive() const;
114     void Activate() override;
115     void Deactivate() override;
116 
117     bool AllowThreadedProcessing() const override;
118 
119     GpuQueue GetValidGpuQueue(const GpuQueue& gpuQueue) const override;
120     uint32_t GetGpuQueueCount() const override;
121 
122     void InitializePipelineCache(BASE_NS::array_view<const uint8_t> initialData) override;
123     BASE_NS::vector<uint8_t> GetPipelineCache() const override;
124 
125     BASE_NS::unique_ptr<GpuBuffer> CreateGpuBuffer(const GpuBufferDesc& desc) override;
126     BASE_NS::unique_ptr<GpuBuffer> CreateGpuBuffer(const GpuAccelerationStructureDesc& desc) override;
127     BASE_NS::unique_ptr<GpuBuffer> CreateGpuBuffer(const BackendSpecificBufferDesc& desc) override;
128 
129     // Create gpu image resources
130     BASE_NS::unique_ptr<GpuImage> CreateGpuImage(const GpuImageDesc& desc) override;
131     BASE_NS::unique_ptr<GpuImage> CreateGpuImageView(
132         const GpuImageDesc& desc, const GpuImagePlatformData& platformData) override;
133     BASE_NS::unique_ptr<GpuImage> CreateGpuImageView(
134         const GpuImageDesc& desc, const BackendSpecificImageDesc& platformData) override;
135     BASE_NS::vector<BASE_NS::unique_ptr<GpuImage>> CreateGpuImageViews(const Swapchain& platformSwapchain) override;
136 
137     BASE_NS::unique_ptr<GpuSampler> CreateGpuSampler(const GpuSamplerDesc& desc) override;
138 
139     BASE_NS::unique_ptr<RenderFrameSync> CreateRenderFrameSync() override;
140 
141     BASE_NS::unique_ptr<RenderBackend> CreateRenderBackend(
142         GpuResourceManager& gpuResourceMgr, CORE_NS::ITaskQueue* queue) override;
143 
144     BASE_NS::unique_ptr<ShaderModule> CreateShaderModule(const ShaderModuleCreateInfo& data) override;
145     BASE_NS::unique_ptr<ShaderModule> CreateComputeShaderModule(const ShaderModuleCreateInfo& data) override;
146     BASE_NS::unique_ptr<GpuShaderProgram> CreateGpuShaderProgram(const GpuShaderProgramCreateData& data) override;
147     BASE_NS::unique_ptr<GpuComputeProgram> CreateGpuComputeProgram(const GpuComputeProgramCreateData& data) override;
148 
149     BASE_NS::unique_ptr<NodeContextDescriptorSetManager> CreateNodeContextDescriptorSetManager() override;
150     BASE_NS::unique_ptr<NodeContextPoolManager> CreateNodeContextPoolManager(
151         class GpuResourceManager& gpuResourceMgr, const GpuQueue& gpuQueue) override;
152 
153     BASE_NS::unique_ptr<GraphicsPipelineStateObject> CreateGraphicsPipelineStateObject(
154         const GpuShaderProgram& gpuProgram, const GraphicsState& graphicsState, const PipelineLayout& pipelineLayout,
155         const VertexInputDeclarationView& vertexInputDeclaration,
156         const ShaderSpecializationConstantDataView& specializationConstants,
157         BASE_NS::array_view<const DynamicStateEnum> dynamicStates, const RenderPassDesc& renderPassDesc,
158         const BASE_NS::array_view<const RenderPassSubpassDesc>& renderPassSubpassDescs, uint32_t subpassIndex,
159         const LowLevelRenderPassData* renderPassData, const LowLevelPipelineLayoutData* pipelineLayoutData) override;
160 
161     BASE_NS::unique_ptr<ComputePipelineStateObject> CreateComputePipelineStateObject(
162         const GpuComputeProgram& gpuProgram, const PipelineLayout& pipelineLayout,
163         const ShaderSpecializationConstantDataView& specializationConstants,
164         const LowLevelPipelineLayoutData* pipelineLayoutData) override;
165 
166     BASE_NS::unique_ptr<GpuSemaphore> CreateGpuSemaphore() override;
167     BASE_NS::unique_ptr<GpuSemaphore> CreateGpuSemaphoreView(uint64_t handle) override;
168 
169     void SetBackendConfig(const BackendConfig& config) override;
170 
171     // Internal apis, only usable by other parts of GLES backend.
172     bool HasExtension(BASE_NS::string_view extension) const;
173     void Activate(RenderHandle swapchain);
174 #if RENDER_HAS_GL_BACKEND
175     const WGLHelpers::WGLState& GetEglState();
176 #endif
177 #if RENDER_HAS_GLES_BACKEND
178     const EGLHelpers::EGLState& GetEglState();
179     bool IsDepthResolveSupported() const;
180 #endif
181 
182     uint32_t CacheProgram(
183         BASE_NS::string_view vertSource, BASE_NS::string_view fragSource, BASE_NS::string_view compSource);
184     void ReleaseProgram(uint32_t program);
185 
186     void UseProgram(uint32_t program);
187     void BindBuffer(uint32_t target, uint32_t buffer);
188     void BindBufferRange(uint32_t target, uint32_t binding, uint32_t buffer, uint64_t offset, uint64_t size);
189     void BindSampler(uint32_t textureUnit, uint32_t sampler);
190     void BindTexture(uint32_t textureUnit, uint32_t target, uint32_t texture); // target = GL_TEXTURE_2D et al.
191     void BindImageTexture(uint32_t unit, uint32_t texture, uint32_t level, bool layered, uint32_t layer,
192         uint32_t access, uint32_t format);
193     void BindFrameBuffer(uint32_t fbo);
194     void BindReadFrameBuffer(uint32_t fbo);
195     void BindWriteFrameBuffer(uint32_t fbo);
196     void BindVertexArray(uint32_t vao);
197 
198     void BindVertexBuffer(uint32_t slot, uint32_t buffer, intptr_t offset, intptr_t stride);
199     void VertexBindingDivisor(uint32_t slot, uint32_t divisor);
200     void BindElementBuffer(uint32_t buffer);
201 
202     uint32_t BoundReadFrameBuffer() const;
203     uint32_t BoundWriteFrameBuffer() const;
204 
205     uint32_t BoundProgram() const;
206     uint32_t BoundBuffer(uint32_t target) const;
207     uint32_t BoundBuffer(uint32_t target, uint32_t binding) const;
208     uint32_t BoundSampler(uint32_t textureUnit) const;
209     uint32_t BoundTexture(uint32_t textureUnit, uint32_t target) const;
210     uint32_t BoundVertexArray() const;
211 
212     // Creation functions for objects.
213     uint32_t CreateVertexArray();
214     // Deletion functions for objects.
215     void DeleteTexture(uint32_t texture);
216     void DeleteBuffer(uint32_t buffer);
217     void DeleteSampler(uint32_t sampler);
218     void DeleteVertexArray(uint32_t vao);
219     void DeleteFrameBuffer(uint32_t fbo);
220 
221     void SetActiveTextureUnit(uint32_t textureUnit); // hide this.
222     // swizzles for textures
223     void TexSwizzle(uint32_t image, uint32_t target, const BASE_NS::Math::UVec4& swizzle);
224     // texture upload / storage
225     void TexStorage2D(
226         uint32_t image, uint32_t target, uint32_t levels, uint32_t internalformat, const BASE_NS::Math::UVec2& extent);
227     void TexStorage3D(
228         uint32_t image, uint32_t target, uint32_t levels, uint32_t internalformat, const BASE_NS::Math::UVec3& extent);
229     void TexStorage2DMultisample(uint32_t image, uint32_t target, uint32_t samples, uint32_t internalformat,
230         const BASE_NS::Math::UVec2& extent, bool fixedsamplelocations);
231     void TexStorage3DMultisample(uint32_t image, uint32_t target, uint32_t samples, uint32_t internalformat,
232         const BASE_NS::Math::UVec3& extent, bool fixedsamplelocations);
233     void TexSubImage2D(uint32_t image, uint32_t target, uint32_t level, const BASE_NS::Math::UVec2& offset,
234         const BASE_NS::Math::UVec2& extent, uint32_t format, uint32_t type, const void* pixels);
235     void TexSubImage3D(uint32_t image, uint32_t target, uint32_t level, const BASE_NS::Math::UVec3& offset,
236         const BASE_NS::Math::UVec3& extent, uint32_t format, uint32_t type, const void* pixels);
237     void CompressedTexSubImage2D(uint32_t image, uint32_t target, uint32_t level, const BASE_NS::Math::UVec2& offset,
238         const BASE_NS::Math::UVec2& extent, uint32_t format, uint32_t imageSize, const void* data);
239     void CompressedTexSubImage3D(uint32_t image, uint32_t target, uint32_t level, const BASE_NS::Math::UVec3& offset,
240         const BASE_NS::Math::UVec3& extent, uint32_t format, uint32_t imageSize, const void* data);
241 
242     const ImageFormat& GetGlImageFormat(BASE_NS::Format format) const;
243 
244     void SwapBuffers(const SwapchainGLES&);
245 
246 private:
247     enum BufferBindId : uint32_t {
248         UNIFORM_BUFFER_BIND = 0,
249         SHADER_STORAGE_BUFFER_BIND,
250 #ifdef HANDLE_UNSUPPORTED_ENUMS
251         ATOMIC_COUNTER_BUFFER_BIND,
252         TRANSFORM_FEEDBACK_BUFFER_BIND,
253 #endif
254         MAX_BUFFER_BIND_ID
255     };
256 
257     enum BufferTargetId : uint32_t {
258         PIXEL_UNPACK_BUFFER = 0,
259         PIXEL_PACK_BUFFER,
260         COPY_READ_BUFFER,
261         COPY_WRITE_BUFFER,
262         UNIFORM_BUFFER,
263         SHADER_STORAGE_BUFFER,
264         DISPATCH_INDIRECT_BUFFER,
265         DRAW_INDIRECT_BUFFER,
266 #ifdef HANDLE_UNSUPPORTED_ENUMS
267         ATOMIC_COUNTER_BUFFER,
268         QUERY_BUFFER,
269         TRANSFORM_FEEDBACK_BUFFER,
270         ARRAY_BUFFER,
271         ELEMENT_ARRAY_BUFFER, // stored in VAO state...
272         TEXTURE_BUFFER,
273 #endif
274         MAX_BUFFER_TARGET_ID
275     };
276 
277     enum TextureTargetId : uint32_t {
278         TEXTURE_2D = 0,
279         TEXTURE_CUBE_MAP = 1,
280 #if RENDER_HAS_GLES_BACKEND
281         TEXTURE_EXTERNAL_OES = 2,
282 #endif
283         TEXTURE_2D_MULTISAMPLE = 3,
284         TEXTURE_2D_ARRAY = 4,
285         TEXTURE_2D_MULTISAMPLE_ARRAY = 5,
286         TEXTURE_3D = 6,
287         MAX_TEXTURE_TARGET_ID
288     };
289 
290     static constexpr uint32_t READ_ONLY { 0x88B8 }; /* GL_READ_ONLY */
291     static constexpr uint32_t R32UI { 0x8236 };     /* GL_R32UI */
292     static constexpr uint32_t MAX_TEXTURE_UNITS { 16 };
293     static constexpr uint32_t MAX_SAMPLERS { 16 };
294     static constexpr uint32_t MAX_BOUND_IMAGE { 16 };
295     static constexpr uint32_t MAX_BINDING_VALUE { 16 };
296 
297     // Cleanup cache state when deleting objects.
298     void UnBindTexture(uint32_t texture);
299     void UnBindBuffer(uint32_t buffer);
300     void UnBindBufferFromVertexArray(uint32_t buffer);
301     void UnBindSampler(uint32_t sampler);
302     void UnBindVertexArray(uint32_t vao);
303     void UnBindFrameBuffer(uint32_t fbo);
304 
305     BASE_NS::vector<BASE_NS::string_view> extensions_;
306     BASE_NS::vector<ImageFormat> supportedFormats_;
307     bool supportsBinaryShaders_ { false };
308     bool supportsBinaryPrograms_ { false };
309 
310     enum { VERTEX_CACHE = 0, FRAGMENT_CACHE = 1, COMPUTE_CACHE = 2, MAX_CACHES };
311     struct ShaderCache {
312         size_t hit { 0 };
313         size_t miss { 0 };
314         struct Entry {
315             uint32_t shader { 0 };
316             uint64_t hash { 0 }; // hash of generated GLSL
317             uint32_t refCount { 0 };
318         };
319         BASE_NS::vector<Entry> cache;
320     };
321     ShaderCache shaders_[MAX_CACHES];
322 
323     const ShaderCache::Entry& CacheShader(int type, BASE_NS::string_view source);
324     void ReleaseShader(uint32_t type, uint32_t shader);
325 
326     struct ProgramCache {
327         uint32_t program { 0 };
328         uint32_t vertShader { 0 };
329         uint32_t fragShader { 0 };
330         uint32_t compShader { 0 };
331         uint64_t hashVert { 0 };
332         uint64_t hashFrag { 0 };
333         uint64_t hashComp { 0 };
334         uint32_t refCount { 0 };
335     };
336     BASE_NS::vector<ProgramCache> programs_;
337     size_t pCacheHit_ { 0 };
338     size_t pCacheMiss_ { 0 };
339 
340 #if RENDER_HAS_GL_BACKEND
341 #if _WIN32
342     const DeviceBackendType backendType_ = DeviceBackendType::OPENGL;
343     WGLHelpers::WGLState eglState_;
344 #else
345 #error RENDER_NS::DeviceBackendType::OPENGL not implemented for this platform yet.
346 #endif
347 #endif
348 #if RENDER_HAS_GLES_BACKEND
349     const DeviceBackendType backendType_ = DeviceBackendType::OPENGLES;
350     EGLHelpers::EGLState eglState_;
351     BackendConfigGLES backendConfig_ { {}, false };
352 #endif
353     mutable std::recursive_mutex activeMutex_;
354     static thread_local bool isActiveInThread_;
355     uint32_t isActive_ { 0 };
356     bool isRenderbackendRunning_ { false };
357     BASE_NS::unique_ptr<LowLevelDeviceGLES> lowLevelDevice_;
358     // GL State cache..
359     // cache.
360     uint32_t activeTextureUnit_ = { 0 };
361     uint32_t boundSampler_[MAX_SAMPLERS] = { 0 };
362 
363     struct {
364         bool bound { false };
365         uint32_t texture { 0 };
366         uint32_t level { 0 };
367         bool layered { false };
368         uint32_t layer { 0 };
369         uint32_t access { READ_ONLY };
370         uint32_t format { R32UI };
371     } boundImage_[MAX_BOUND_IMAGE] = { {} };
372 
373     uint32_t boundTexture_[MAX_TEXTURE_UNITS][MAX_TEXTURE_TARGET_ID] = { { 0 } }; // [textureunit][target type]
374 
375     struct BufferCache {
376         bool cached { false };
377         uint32_t buffer { 0 };
378         uint64_t offset { 0 };
379         uint64_t size { 0 };
380     };
381     // Cache for GL_ATOMIC_COUNTER_BUFFER, GL_TRANSFORM_FEEDBACK_BUFFER, GL_UNIFORM_BUFFER, or GL_SHADER_STORAGE_BUFFER
382     // bindings.
383     BufferCache boundBuffers_[MAX_BUFFER_BIND_ID][MAX_BINDING_VALUE] = { {} };
384 
385     // bufferBound_ caches GL_PIXEL_UNPACK_BUFFER / GL_COPY_READ_BUFFER / GL_COPY_WRITE_BUFFER (and other generic
386     // bindings)
387     struct {
388         bool bound { false };
389         uint32_t buffer { 0 };
390     } bufferBound_[MAX_BUFFER_TARGET_ID];
391     uint32_t boundReadFbo_ { 0 };
392     uint32_t boundWriteFbo_ { 0 };
393     uint32_t boundVao_ { 0 };
394     uint32_t boundProgram_ { 0 };
395     struct VAOState {
396         uint32_t vao { 0 }; // GL name for object.
397         struct {
398             bool bound { false };
399             uint32_t buffer { 0 };
400         } elementBuffer;
401         struct {
402             bool bound { false };
403             uint32_t buffer { 0 };
404             intptr_t offset { 0 };
405             intptr_t stride { 0 };
406             uint32_t divisor { 0 };
407         } vertexBufferBinds[PipelineStateConstants::MAX_VERTEX_BUFFER_COUNT];
408     };
409     BASE_NS::vector<VAOState> vaoStates_;
410     size_t vaoStatesInUse_ = 0;
411 
412     // glid -> internal id
413     static BufferBindId IndexedTargetToTargetId(uint32_t target);
414     static uint32_t TargetToBinding(uint32_t target);
415     static BufferTargetId GenericTargetToTargetId(uint32_t target);
416     static TextureTargetId TextureTargetToTargetId(uint32_t target);
417 
418     // internal id -> glid
419     static uint32_t GenericTargetIdToTarget(BufferTargetId target);
420     static uint32_t IndexedTargetIdToTarget(BufferBindId target);
421     static uint32_t TextureTargetIdToTarget(TextureTargetId target);
422 };
423 
424 // Wrapper for low level device access
425 class LowLevelDeviceGLES final : public ILowLevelDeviceGLES {
426 public:
427     explicit LowLevelDeviceGLES(DeviceGLES& deviceGLES);
428     ~LowLevelDeviceGLES() override = default;
429 
430     DeviceBackendType GetBackendType() const override;
431 
432 #if RENDER_HAS_EXPERIMENTAL
433     void Activate() override;
434     void Deactivate() override;
435     void SwapBuffers() override;
436 #endif
437 
438 private:
439     DeviceGLES& deviceGLES_;
440     GpuResourceManager& gpuResourceMgr_;
441 };
442 
443 #if (RENDER_HAS_GL_BACKEND)
444 BASE_NS::unique_ptr<Device> CreateDeviceGL(RenderContext& renderContext);
445 #endif
446 #if (RENDER_HAS_GLES_BACKEND)
447 BASE_NS::unique_ptr<Device> CreateDeviceGLES(RenderContext& renderContext);
448 #endif
449 RENDER_END_NAMESPACE()
450 
451 #endif // GLES_DEVICE_GLES_H
452