opengl_pipeline.h (3541B)
1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR PolyForm-Strict-1.0.0) 3 4 #pragma once 5 6 #include "gpu_device.h" 7 #include "gpu_shader_cache.h" 8 #include "opengl_loader.h" 9 10 class OpenGLDevice; 11 12 class OpenGLShader final : public GPUShader 13 { 14 friend OpenGLDevice; 15 16 public: 17 ~OpenGLShader() override; 18 19 void SetDebugName(std::string_view name) override; 20 21 bool Compile(Error* error); 22 23 ALWAYS_INLINE GLuint GetGLId() const { return m_id.value(); } 24 ALWAYS_INLINE const GPUShaderCache::CacheIndexKey& GetKey() const { return m_key; } 25 ALWAYS_INLINE const std::string& GetSource() const { return m_source; } 26 27 private: 28 OpenGLShader(GPUShaderStage stage, const GPUShaderCache::CacheIndexKey& key, std::string source); 29 30 GPUShaderCache::CacheIndexKey m_key; 31 std::string m_source; 32 std::optional<GLuint> m_id; 33 bool m_compile_tried = false; 34 35 #ifdef _DEBUG 36 std::string m_debug_name; 37 #endif 38 }; 39 40 class OpenGLPipeline final : public GPUPipeline 41 { 42 friend OpenGLDevice; 43 44 public: 45 static constexpr u32 MAX_VERTEX_ATTRIBUTES = 7; 46 47 struct VertexArrayCacheKey 48 { 49 VertexAttribute vertex_attributes[MAX_VERTEX_ATTRIBUTES]; 50 u32 vertex_attribute_stride; 51 u32 num_vertex_attributes; 52 53 bool operator==(const VertexArrayCacheKey& rhs) const; 54 bool operator!=(const VertexArrayCacheKey& rhs) const; 55 }; 56 struct VertexArrayCacheItem 57 { 58 GLuint vao_id; 59 u32 reference_count; 60 }; 61 struct VertexArrayCacheKeyHash 62 { 63 size_t operator()(const VertexArrayCacheKey& k) const; 64 }; 65 using VertexArrayCache = std::unordered_map<VertexArrayCacheKey, VertexArrayCacheItem, VertexArrayCacheKeyHash>; 66 67 struct ProgramCacheKey 68 { 69 u64 vs_hash_low, vs_hash_high; 70 u64 gs_hash_low, gs_hash_high; 71 u64 fs_hash_low, fs_hash_high; 72 u32 vs_length; 73 u32 gs_length; 74 u32 fs_length; 75 VertexArrayCacheKey va_key; 76 77 bool operator==(const ProgramCacheKey& rhs) const; 78 bool operator!=(const ProgramCacheKey& rhs) const; 79 }; 80 static_assert(sizeof(ProgramCacheKey) == 96); // Has no padding 81 struct ProgramCacheKeyHash 82 { 83 size_t operator()(const ProgramCacheKey& k) const; 84 }; 85 struct ProgramCacheItem 86 { 87 GLuint program_id; 88 u32 reference_count; 89 GLenum file_format; 90 u32 file_offset; 91 u32 file_compressed_size; 92 u32 file_uncompressed_size; 93 }; 94 using ProgramCache = std::unordered_map<ProgramCacheKey, ProgramCacheItem, ProgramCacheKeyHash>; 95 96 static ProgramCacheKey GetProgramCacheKey(const GraphicsConfig& plconfig); 97 98 ~OpenGLPipeline() override; 99 100 ALWAYS_INLINE GLuint GetProgram() const { return m_program; } 101 ALWAYS_INLINE VertexArrayCache::const_iterator GetVAO() const { return m_vao; } 102 ALWAYS_INLINE const RasterizationState& GetRasterizationState() const { return m_rasterization_state; } 103 ALWAYS_INLINE const DepthState& GetDepthState() const { return m_depth_state; } 104 ALWAYS_INLINE const BlendState& GetBlendState() const { return m_blend_state; } 105 ALWAYS_INLINE GLenum GetTopology() const { return m_topology; } 106 107 void SetDebugName(std::string_view name) override; 108 109 private: 110 OpenGLPipeline(const ProgramCacheKey& key, GLuint program, VertexArrayCache::const_iterator vao, 111 const RasterizationState& rs, const DepthState& ds, const BlendState& bs, GLenum topology); 112 113 ProgramCacheKey m_key; 114 VertexArrayCache::const_iterator m_vao; 115 GLuint m_program; 116 BlendState m_blend_state; 117 RasterizationState m_rasterization_state; 118 DepthState m_depth_state; 119 GLenum m_topology; 120 };