2023-08-13 03:42:02 +00:00
|
|
|
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
|
|
|
|
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "gpu_device.h"
|
|
|
|
#include "gpu_shader_cache.h"
|
|
|
|
#include "opengl_loader.h"
|
|
|
|
|
|
|
|
class OpenGLDevice;
|
|
|
|
|
|
|
|
class OpenGLShader final : public GPUShader
|
|
|
|
{
|
|
|
|
friend OpenGLDevice;
|
|
|
|
|
|
|
|
public:
|
|
|
|
~OpenGLShader() override;
|
|
|
|
|
2024-05-05 10:21:54 +00:00
|
|
|
void SetDebugName(std::string_view name) override;
|
2023-08-13 03:42:02 +00:00
|
|
|
|
2024-07-22 05:35:28 +00:00
|
|
|
bool Compile(Error* error);
|
2023-08-30 12:20:39 +00:00
|
|
|
|
|
|
|
ALWAYS_INLINE GLuint GetGLId() const { return m_id.value(); }
|
2023-08-13 03:42:02 +00:00
|
|
|
ALWAYS_INLINE const GPUShaderCache::CacheIndexKey& GetKey() const { return m_key; }
|
2024-06-14 04:37:33 +00:00
|
|
|
ALWAYS_INLINE const std::string& GetSource() const { return m_source; }
|
2023-08-13 03:42:02 +00:00
|
|
|
|
|
|
|
private:
|
2023-08-30 12:20:39 +00:00
|
|
|
OpenGLShader(GPUShaderStage stage, const GPUShaderCache::CacheIndexKey& key, std::string source);
|
2023-08-13 03:42:02 +00:00
|
|
|
|
|
|
|
GPUShaderCache::CacheIndexKey m_key;
|
2023-08-30 12:20:39 +00:00
|
|
|
std::string m_source;
|
|
|
|
std::optional<GLuint> m_id;
|
|
|
|
bool m_compile_tried = false;
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
std::string m_debug_name;
|
|
|
|
#endif
|
2023-08-13 03:42:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class OpenGLPipeline final : public GPUPipeline
|
|
|
|
{
|
|
|
|
friend OpenGLDevice;
|
|
|
|
|
|
|
|
public:
|
2023-09-02 12:09:20 +00:00
|
|
|
static constexpr u32 MAX_VERTEX_ATTRIBUTES = 7;
|
2023-08-13 03:42:02 +00:00
|
|
|
|
|
|
|
struct VertexArrayCacheKey
|
|
|
|
{
|
|
|
|
VertexAttribute vertex_attributes[MAX_VERTEX_ATTRIBUTES];
|
|
|
|
u32 vertex_attribute_stride;
|
|
|
|
u32 num_vertex_attributes;
|
|
|
|
|
|
|
|
bool operator==(const VertexArrayCacheKey& rhs) const;
|
|
|
|
bool operator!=(const VertexArrayCacheKey& rhs) const;
|
|
|
|
};
|
|
|
|
struct VertexArrayCacheItem
|
|
|
|
{
|
|
|
|
GLuint vao_id;
|
|
|
|
u32 reference_count;
|
|
|
|
};
|
|
|
|
struct VertexArrayCacheKeyHash
|
|
|
|
{
|
|
|
|
size_t operator()(const VertexArrayCacheKey& k) const;
|
|
|
|
};
|
|
|
|
using VertexArrayCache = std::unordered_map<VertexArrayCacheKey, VertexArrayCacheItem, VertexArrayCacheKeyHash>;
|
|
|
|
|
|
|
|
struct ProgramCacheKey
|
|
|
|
{
|
2023-09-02 12:09:20 +00:00
|
|
|
u64 vs_hash_low, vs_hash_high;
|
|
|
|
u64 gs_hash_low, gs_hash_high;
|
|
|
|
u64 fs_hash_low, fs_hash_high;
|
|
|
|
u32 vs_length;
|
|
|
|
u32 gs_length;
|
|
|
|
u32 fs_length;
|
2023-08-13 03:42:02 +00:00
|
|
|
VertexArrayCacheKey va_key;
|
|
|
|
|
|
|
|
bool operator==(const ProgramCacheKey& rhs) const;
|
|
|
|
bool operator!=(const ProgramCacheKey& rhs) const;
|
|
|
|
};
|
2023-09-02 12:09:20 +00:00
|
|
|
static_assert(sizeof(ProgramCacheKey) == 96); // Has no padding
|
2023-08-13 03:42:02 +00:00
|
|
|
struct ProgramCacheKeyHash
|
|
|
|
{
|
|
|
|
size_t operator()(const ProgramCacheKey& k) const;
|
|
|
|
};
|
|
|
|
struct ProgramCacheItem
|
|
|
|
{
|
|
|
|
GLuint program_id;
|
|
|
|
u32 reference_count;
|
|
|
|
GLenum file_format;
|
|
|
|
u32 file_offset;
|
|
|
|
u32 file_compressed_size;
|
|
|
|
u32 file_uncompressed_size;
|
|
|
|
};
|
|
|
|
using ProgramCache = std::unordered_map<ProgramCacheKey, ProgramCacheItem, ProgramCacheKeyHash>;
|
|
|
|
|
|
|
|
static ProgramCacheKey GetProgramCacheKey(const GraphicsConfig& plconfig);
|
|
|
|
|
|
|
|
~OpenGLPipeline() override;
|
|
|
|
|
|
|
|
ALWAYS_INLINE GLuint GetProgram() const { return m_program; }
|
2023-12-28 08:22:12 +00:00
|
|
|
ALWAYS_INLINE VertexArrayCache::const_iterator GetVAO() const { return m_vao; }
|
2023-08-13 03:42:02 +00:00
|
|
|
ALWAYS_INLINE const RasterizationState& GetRasterizationState() const { return m_rasterization_state; }
|
|
|
|
ALWAYS_INLINE const DepthState& GetDepthState() const { return m_depth_state; }
|
|
|
|
ALWAYS_INLINE const BlendState& GetBlendState() const { return m_blend_state; }
|
|
|
|
ALWAYS_INLINE GLenum GetTopology() const { return m_topology; }
|
|
|
|
|
2024-05-05 10:21:54 +00:00
|
|
|
void SetDebugName(std::string_view name) override;
|
2023-08-13 03:42:02 +00:00
|
|
|
|
|
|
|
private:
|
2023-12-28 08:22:12 +00:00
|
|
|
OpenGLPipeline(const ProgramCacheKey& key, GLuint program, VertexArrayCache::const_iterator vao,
|
|
|
|
const RasterizationState& rs, const DepthState& ds, const BlendState& bs, GLenum topology);
|
2023-08-13 03:42:02 +00:00
|
|
|
|
|
|
|
ProgramCacheKey m_key;
|
2023-12-28 08:22:12 +00:00
|
|
|
VertexArrayCache::const_iterator m_vao;
|
2023-08-13 03:42:02 +00:00
|
|
|
GLuint m_program;
|
|
|
|
BlendState m_blend_state;
|
|
|
|
RasterizationState m_rasterization_state;
|
|
|
|
DepthState m_depth_state;
|
|
|
|
GLenum m_topology;
|
|
|
|
};
|