mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 13:55:38 +00:00
GL/ShaderCache: Support geometry shaders
This commit is contained in:
parent
a43a0a14cc
commit
b45b70970b
|
@ -81,22 +81,43 @@ void Program::ResetLastProgram()
|
||||||
s_last_program_id = 0;
|
s_last_program_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Program::Compile(const std::string_view vertex_shader, const std::string_view fragment_shader)
|
bool Program::Compile(const std::string_view vertex_shader, const std::string_view geometry_shader,
|
||||||
|
const std::string_view fragment_shader)
|
||||||
{
|
{
|
||||||
GLuint vertex_shader_id = CompileShader(GL_VERTEX_SHADER, vertex_shader);
|
GLuint vertex_shader_id = 0;
|
||||||
if (vertex_shader_id == 0)
|
if (!vertex_shader.empty())
|
||||||
return false;
|
|
||||||
|
|
||||||
GLuint fragment_shader_id = CompileShader(GL_FRAGMENT_SHADER, fragment_shader);
|
|
||||||
if (fragment_shader_id == 0)
|
|
||||||
{
|
{
|
||||||
glDeleteShader(vertex_shader_id);
|
vertex_shader_id = CompileShader(GL_VERTEX_SHADER, vertex_shader);
|
||||||
return false;
|
if (vertex_shader_id == 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint geometry_shader_id = 0;
|
||||||
|
if (!geometry_shader.empty())
|
||||||
|
{
|
||||||
|
geometry_shader_id = CompileShader(GL_GEOMETRY_SHADER, geometry_shader);
|
||||||
|
if (geometry_shader_id == 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint fragment_shader_id = 0;
|
||||||
|
if (!fragment_shader.empty())
|
||||||
|
{
|
||||||
|
fragment_shader_id = CompileShader(GL_FRAGMENT_SHADER, fragment_shader);
|
||||||
|
if (fragment_shader_id == 0)
|
||||||
|
{
|
||||||
|
glDeleteShader(vertex_shader_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_program_id = glCreateProgram();
|
m_program_id = glCreateProgram();
|
||||||
glAttachShader(m_program_id, vertex_shader_id);
|
if (vertex_shader_id != 0)
|
||||||
glAttachShader(m_program_id, fragment_shader_id);
|
glAttachShader(m_program_id, vertex_shader_id);
|
||||||
|
if (geometry_shader_id != 0)
|
||||||
|
glAttachShader(m_program_id, geometry_shader_id);
|
||||||
|
if (fragment_shader_id != 0)
|
||||||
|
glAttachShader(m_program_id, fragment_shader_id);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,8 @@ public:
|
||||||
bool IsVaild() const { return m_program_id != 0; }
|
bool IsVaild() const { return m_program_id != 0; }
|
||||||
bool IsBound() const { return s_last_program_id == m_program_id; }
|
bool IsBound() const { return s_last_program_id == m_program_id; }
|
||||||
|
|
||||||
bool Compile(const std::string_view vertex_shader, const std::string_view fragment_shader);
|
bool Compile(const std::string_view vertex_shader, const std::string_view geometry_shader,
|
||||||
|
const std::string_view fragment_shader);
|
||||||
|
|
||||||
bool CreateFromBinary(const void* data, u32 data_length, u32 data_format);
|
bool CreateFromBinary(const void* data, u32 data_length, u32 data_format);
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,9 @@ struct CacheIndexEntry
|
||||||
u64 vertex_source_hash_low;
|
u64 vertex_source_hash_low;
|
||||||
u64 vertex_source_hash_high;
|
u64 vertex_source_hash_high;
|
||||||
u32 vertex_source_length;
|
u32 vertex_source_length;
|
||||||
|
u64 geometry_source_hash_low;
|
||||||
|
u64 geometry_source_hash_high;
|
||||||
|
u32 geometry_source_length;
|
||||||
u64 fragment_source_hash_low;
|
u64 fragment_source_hash_low;
|
||||||
u64 fragment_source_hash_high;
|
u64 fragment_source_hash_high;
|
||||||
u32 fragment_source_length;
|
u32 fragment_source_length;
|
||||||
|
@ -33,7 +36,9 @@ bool ShaderCache::CacheIndexKey::operator==(const CacheIndexKey& key) const
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
vertex_source_hash_low == key.vertex_source_hash_low && vertex_source_hash_high == key.vertex_source_hash_high &&
|
vertex_source_hash_low == key.vertex_source_hash_low && vertex_source_hash_high == key.vertex_source_hash_high &&
|
||||||
vertex_source_length == key.vertex_source_length && fragment_source_hash_low == key.fragment_source_hash_low &&
|
vertex_source_length == key.vertex_source_length && geometry_source_hash_low == key.geometry_source_hash_low &&
|
||||||
|
geometry_source_hash_high == key.geometry_source_hash_high &&
|
||||||
|
geometry_source_length == key.geometry_source_length && fragment_source_hash_low == key.fragment_source_hash_low &&
|
||||||
fragment_source_hash_high == key.fragment_source_hash_high && fragment_source_length == key.fragment_source_length);
|
fragment_source_hash_high == key.fragment_source_hash_high && fragment_source_length == key.fragment_source_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +46,9 @@ bool ShaderCache::CacheIndexKey::operator!=(const CacheIndexKey& key) const
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
vertex_source_hash_low != key.vertex_source_hash_low || vertex_source_hash_high != key.vertex_source_hash_high ||
|
vertex_source_hash_low != key.vertex_source_hash_low || vertex_source_hash_high != key.vertex_source_hash_high ||
|
||||||
vertex_source_length != key.vertex_source_length || fragment_source_hash_low != key.fragment_source_hash_low ||
|
vertex_source_length != key.vertex_source_length || geometry_source_hash_low != key.geometry_source_hash_low ||
|
||||||
|
geometry_source_hash_high != key.geometry_source_hash_high ||
|
||||||
|
geometry_source_length != key.geometry_source_length || fragment_source_hash_low != key.fragment_source_hash_low ||
|
||||||
fragment_source_hash_high != key.fragment_source_hash_high || fragment_source_length != key.fragment_source_length);
|
fragment_source_hash_high != key.fragment_source_hash_high || fragment_source_length != key.fragment_source_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,9 +167,10 @@ bool ShaderCache::ReadExisting(const std::string& index_filename, const std::str
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CacheIndexKey key{entry.vertex_source_hash_low, entry.vertex_source_hash_high,
|
const CacheIndexKey key{
|
||||||
entry.vertex_source_length, entry.fragment_source_hash_low,
|
entry.vertex_source_hash_low, entry.vertex_source_hash_high, entry.vertex_source_length,
|
||||||
entry.fragment_source_hash_high, entry.fragment_source_length};
|
entry.geometry_source_hash_low, entry.geometry_source_hash_high, entry.geometry_source_length,
|
||||||
|
entry.fragment_source_hash_low, entry.fragment_source_hash_high, entry.fragment_source_length};
|
||||||
const CacheIndexData data{entry.file_offset, entry.blob_size, entry.blob_format};
|
const CacheIndexData data{entry.file_offset, entry.blob_size, entry.blob_format};
|
||||||
m_index.emplace(key, data);
|
m_index.emplace(key, data);
|
||||||
}
|
}
|
||||||
|
@ -191,6 +199,7 @@ bool ShaderCache::Recreate()
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderCache::CacheIndexKey ShaderCache::GetCacheKey(const std::string_view& vertex_shader,
|
ShaderCache::CacheIndexKey ShaderCache::GetCacheKey(const std::string_view& vertex_shader,
|
||||||
|
const std::string_view& geometry_shader,
|
||||||
const std::string_view& fragment_shader)
|
const std::string_view& fragment_shader)
|
||||||
{
|
{
|
||||||
union ShaderHash
|
union ShaderHash
|
||||||
|
@ -203,18 +212,33 @@ ShaderCache::CacheIndexKey ShaderCache::GetCacheKey(const std::string_view& vert
|
||||||
u8 bytes[16];
|
u8 bytes[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
ShaderHash vertex_hash;
|
ShaderHash vertex_hash = {};
|
||||||
ShaderHash fragment_hash;
|
ShaderHash geometry_hash = {};
|
||||||
|
ShaderHash fragment_hash = {};
|
||||||
|
|
||||||
MD5Digest digest;
|
MD5Digest digest;
|
||||||
digest.Update(vertex_shader.data(), static_cast<u32>(vertex_shader.length()));
|
if (!vertex_shader.empty())
|
||||||
digest.Final(vertex_hash.bytes);
|
{
|
||||||
|
digest.Update(vertex_shader.data(), static_cast<u32>(vertex_shader.length()));
|
||||||
|
digest.Final(vertex_hash.bytes);
|
||||||
|
}
|
||||||
|
|
||||||
digest.Reset();
|
if (!geometry_shader.empty())
|
||||||
digest.Update(fragment_shader.data(), static_cast<u32>(fragment_shader.length()));
|
{
|
||||||
digest.Final(fragment_hash.bytes);
|
digest.Reset();
|
||||||
|
digest.Update(geometry_shader.data(), static_cast<u32>(geometry_shader.length()));
|
||||||
|
digest.Final(geometry_hash.bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fragment_shader.empty())
|
||||||
|
{
|
||||||
|
digest.Reset();
|
||||||
|
digest.Update(fragment_shader.data(), static_cast<u32>(fragment_shader.length()));
|
||||||
|
digest.Final(fragment_hash.bytes);
|
||||||
|
}
|
||||||
|
|
||||||
return CacheIndexKey{vertex_hash.low, vertex_hash.high, static_cast<u32>(vertex_shader.length()),
|
return CacheIndexKey{vertex_hash.low, vertex_hash.high, static_cast<u32>(vertex_shader.length()),
|
||||||
|
geometry_hash.low, geometry_hash.high, static_cast<u32>(geometry_shader.length()),
|
||||||
fragment_hash.low, fragment_hash.high, static_cast<u32>(fragment_shader.length())};
|
fragment_hash.low, fragment_hash.high, static_cast<u32>(fragment_shader.length())};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,15 +253,16 @@ std::string ShaderCache::GetBlobFileName() const
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Program> ShaderCache::GetProgram(const std::string_view vertex_shader,
|
std::optional<Program> ShaderCache::GetProgram(const std::string_view vertex_shader,
|
||||||
|
const std::string_view geometry_shader,
|
||||||
const std::string_view fragment_shader, const PreLinkCallback& callback)
|
const std::string_view fragment_shader, const PreLinkCallback& callback)
|
||||||
{
|
{
|
||||||
if (!m_program_binary_supported)
|
if (!m_program_binary_supported)
|
||||||
return CompileProgram(vertex_shader, fragment_shader, callback, false);
|
return CompileProgram(vertex_shader, geometry_shader, fragment_shader, callback, false);
|
||||||
|
|
||||||
const auto key = GetCacheKey(vertex_shader, fragment_shader);
|
const auto key = GetCacheKey(vertex_shader, geometry_shader, fragment_shader);
|
||||||
auto iter = m_index.find(key);
|
auto iter = m_index.find(key);
|
||||||
if (iter == m_index.end())
|
if (iter == m_index.end())
|
||||||
return CompileAndAddProgram(key, vertex_shader, fragment_shader, callback);
|
return CompileAndAddProgram(key, vertex_shader, geometry_shader, fragment_shader, callback);
|
||||||
|
|
||||||
std::vector<u8> data(iter->second.blob_size);
|
std::vector<u8> data(iter->second.blob_size);
|
||||||
if (std::fseek(m_blob_file, iter->second.file_offset, SEEK_SET) != 0 ||
|
if (std::fseek(m_blob_file, iter->second.file_offset, SEEK_SET) != 0 ||
|
||||||
|
@ -254,17 +279,18 @@ std::optional<Program> ShaderCache::GetProgram(const std::string_view vertex_sha
|
||||||
Log_WarningPrintf(
|
Log_WarningPrintf(
|
||||||
"Failed to create program from binary, this may be due to a driver or GPU Change. Recreating cache.");
|
"Failed to create program from binary, this may be due to a driver or GPU Change. Recreating cache.");
|
||||||
if (!Recreate())
|
if (!Recreate())
|
||||||
return CompileProgram(vertex_shader, fragment_shader, callback, false);
|
return CompileProgram(vertex_shader, geometry_shader, fragment_shader, callback, false);
|
||||||
else
|
else
|
||||||
return CompileAndAddProgram(key, vertex_shader, fragment_shader, callback);
|
return CompileAndAddProgram(key, vertex_shader, geometry_shader, fragment_shader, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Program> ShaderCache::CompileProgram(const std::string_view& vertex_shader,
|
std::optional<Program> ShaderCache::CompileProgram(const std::string_view& vertex_shader,
|
||||||
|
const std::string_view& geometry_shader,
|
||||||
const std::string_view& fragment_shader,
|
const std::string_view& fragment_shader,
|
||||||
const PreLinkCallback& callback, bool set_retrievable)
|
const PreLinkCallback& callback, bool set_retrievable)
|
||||||
{
|
{
|
||||||
Program prog;
|
Program prog;
|
||||||
if (!prog.Compile(vertex_shader, fragment_shader))
|
if (!prog.Compile(vertex_shader, geometry_shader, fragment_shader))
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|
||||||
if (callback)
|
if (callback)
|
||||||
|
@ -281,10 +307,11 @@ std::optional<Program> ShaderCache::CompileProgram(const std::string_view& verte
|
||||||
|
|
||||||
std::optional<Program> ShaderCache::CompileAndAddProgram(const CacheIndexKey& key,
|
std::optional<Program> ShaderCache::CompileAndAddProgram(const CacheIndexKey& key,
|
||||||
const std::string_view& vertex_shader,
|
const std::string_view& vertex_shader,
|
||||||
|
const std::string_view& geometry_shader,
|
||||||
const std::string_view& fragment_shader,
|
const std::string_view& fragment_shader,
|
||||||
const PreLinkCallback& callback)
|
const PreLinkCallback& callback)
|
||||||
{
|
{
|
||||||
std::optional<Program> prog = CompileProgram(vertex_shader, fragment_shader, callback, true);
|
std::optional<Program> prog = CompileProgram(vertex_shader, geometry_shader, fragment_shader, callback, true);
|
||||||
if (!prog)
|
if (!prog)
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|
||||||
|
@ -305,6 +332,9 @@ std::optional<Program> ShaderCache::CompileAndAddProgram(const CacheIndexKey& ke
|
||||||
entry.vertex_source_hash_low = key.vertex_source_hash_low;
|
entry.vertex_source_hash_low = key.vertex_source_hash_low;
|
||||||
entry.vertex_source_hash_high = key.vertex_source_hash_high;
|
entry.vertex_source_hash_high = key.vertex_source_hash_high;
|
||||||
entry.vertex_source_length = key.vertex_source_length;
|
entry.vertex_source_length = key.vertex_source_length;
|
||||||
|
entry.geometry_source_hash_low = key.geometry_source_hash_low;
|
||||||
|
entry.geometry_source_hash_high = key.geometry_source_hash_high;
|
||||||
|
entry.geometry_source_length = key.geometry_source_length;
|
||||||
entry.fragment_source_hash_low = key.fragment_source_hash_low;
|
entry.fragment_source_hash_low = key.fragment_source_hash_low;
|
||||||
entry.fragment_source_hash_high = key.fragment_source_hash_high;
|
entry.fragment_source_hash_high = key.fragment_source_hash_high;
|
||||||
entry.fragment_source_length = key.fragment_source_length;
|
entry.fragment_source_length = key.fragment_source_length;
|
||||||
|
|
|
@ -22,17 +22,20 @@ public:
|
||||||
|
|
||||||
void Open(bool is_gles, std::string_view base_path);
|
void Open(bool is_gles, std::string_view base_path);
|
||||||
|
|
||||||
std::optional<Program> GetProgram(const std::string_view vertex_shader, const std::string_view fragment_shader,
|
std::optional<Program> GetProgram(const std::string_view vertex_shader, const std::string_view geometry_shader,
|
||||||
const PreLinkCallback& callback = {});
|
const std::string_view fragment_shader, const PreLinkCallback& callback = {});
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr u32 FILE_VERSION = 1;
|
static constexpr u32 FILE_VERSION = 2;
|
||||||
|
|
||||||
struct CacheIndexKey
|
struct CacheIndexKey
|
||||||
{
|
{
|
||||||
u64 vertex_source_hash_low;
|
u64 vertex_source_hash_low;
|
||||||
u64 vertex_source_hash_high;
|
u64 vertex_source_hash_high;
|
||||||
u32 vertex_source_length;
|
u32 vertex_source_length;
|
||||||
|
u64 geometry_source_hash_low;
|
||||||
|
u64 geometry_source_hash_high;
|
||||||
|
u32 geometry_source_length;
|
||||||
u64 fragment_source_hash_low;
|
u64 fragment_source_hash_low;
|
||||||
u64 fragment_source_hash_high;
|
u64 fragment_source_hash_high;
|
||||||
u32 fragment_source_length;
|
u32 fragment_source_length;
|
||||||
|
@ -47,6 +50,7 @@ private:
|
||||||
{
|
{
|
||||||
std::size_t h = 0;
|
std::size_t h = 0;
|
||||||
hash_combine(h, e.vertex_source_hash_low, e.vertex_source_hash_high, e.vertex_source_length,
|
hash_combine(h, e.vertex_source_hash_low, e.vertex_source_hash_high, e.vertex_source_length,
|
||||||
|
e.geometry_source_hash_low, e.geometry_source_hash_high, e.geometry_source_length,
|
||||||
e.fragment_source_hash_low, e.fragment_source_hash_high, e.fragment_source_length);
|
e.fragment_source_hash_low, e.fragment_source_hash_high, e.fragment_source_length);
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
@ -61,7 +65,8 @@ private:
|
||||||
|
|
||||||
using CacheIndex = std::unordered_map<CacheIndexKey, CacheIndexData, CacheIndexEntryHasher>;
|
using CacheIndex = std::unordered_map<CacheIndexKey, CacheIndexData, CacheIndexEntryHasher>;
|
||||||
|
|
||||||
static CacheIndexKey GetCacheKey(const std::string_view& vertex_shader, const std::string_view& fragment_shader);
|
static CacheIndexKey GetCacheKey(const std::string_view& vertex_shader, const std::string_view& geometry_shader,
|
||||||
|
const std::string_view& fragment_shader);
|
||||||
|
|
||||||
std::string GetIndexFileName() const;
|
std::string GetIndexFileName() const;
|
||||||
std::string GetBlobFileName() const;
|
std::string GetBlobFileName() const;
|
||||||
|
@ -71,9 +76,11 @@ private:
|
||||||
void Close();
|
void Close();
|
||||||
bool Recreate();
|
bool Recreate();
|
||||||
|
|
||||||
std::optional<Program> CompileProgram(const std::string_view& vertex_shader, const std::string_view& fragment_shader,
|
std::optional<Program> CompileProgram(const std::string_view& vertex_shader, const std::string_view& geometry_shader,
|
||||||
const PreLinkCallback& callback, bool set_retrievable);
|
const std::string_view& fragment_shader, const PreLinkCallback& callback,
|
||||||
|
bool set_retrievable);
|
||||||
std::optional<Program> CompileAndAddProgram(const CacheIndexKey& key, const std::string_view& vertex_shader,
|
std::optional<Program> CompileAndAddProgram(const CacheIndexKey& key, const std::string_view& vertex_shader,
|
||||||
|
const std::string_view& geometry_shader,
|
||||||
const std::string_view& fragment_shader, const PreLinkCallback& callback);
|
const std::string_view& fragment_shader, const PreLinkCallback& callback);
|
||||||
|
|
||||||
std::string m_base_path;
|
std::string m_base_path;
|
||||||
|
|
|
@ -311,7 +311,7 @@ bool GPU_HW_OpenGL::CompilePrograms()
|
||||||
static_cast<BatchRenderMode>(render_mode), static_cast<TextureMode>(texture_mode),
|
static_cast<BatchRenderMode>(render_mode), static_cast<TextureMode>(texture_mode),
|
||||||
ConvertToBoolUnchecked(dithering), ConvertToBoolUnchecked(interlacing));
|
ConvertToBoolUnchecked(dithering), ConvertToBoolUnchecked(interlacing));
|
||||||
|
|
||||||
std::optional<GL::Program> prog = m_shader_cache.GetProgram(vs, fs, [this, textured](GL::Program& prog) {
|
std::optional<GL::Program> prog = m_shader_cache.GetProgram(vs, {}, fs, [this, textured](GL::Program& prog) {
|
||||||
prog.BindAttribute(0, "a_pos");
|
prog.BindAttribute(0, "a_pos");
|
||||||
prog.BindAttribute(1, "a_col0");
|
prog.BindAttribute(1, "a_col0");
|
||||||
if (textured)
|
if (textured)
|
||||||
|
@ -347,7 +347,7 @@ bool GPU_HW_OpenGL::CompilePrograms()
|
||||||
const std::string fs = shadergen.GenerateDisplayFragmentShader(ConvertToBoolUnchecked(depth_24bit),
|
const std::string fs = shadergen.GenerateDisplayFragmentShader(ConvertToBoolUnchecked(depth_24bit),
|
||||||
ConvertToBoolUnchecked(interlaced));
|
ConvertToBoolUnchecked(interlaced));
|
||||||
|
|
||||||
std::optional<GL::Program> prog = m_shader_cache.GetProgram(vs, fs, [this](GL::Program& prog) {
|
std::optional<GL::Program> prog = m_shader_cache.GetProgram(vs, {}, fs, [this](GL::Program& prog) {
|
||||||
if (!m_is_gles)
|
if (!m_is_gles)
|
||||||
{
|
{
|
||||||
if (m_supports_dual_source_blend)
|
if (m_supports_dual_source_blend)
|
||||||
|
@ -373,7 +373,7 @@ bool GPU_HW_OpenGL::CompilePrograms()
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<GL::Program> prog =
|
std::optional<GL::Program> prog =
|
||||||
m_shader_cache.GetProgram(shadergen.GenerateScreenQuadVertexShader(),
|
m_shader_cache.GetProgram(shadergen.GenerateScreenQuadVertexShader(), {},
|
||||||
shadergen.GenerateInterlacedFillFragmentShader(), [this](GL::Program& prog) {
|
shadergen.GenerateInterlacedFillFragmentShader(), [this](GL::Program& prog) {
|
||||||
if (!m_is_gles)
|
if (!m_is_gles)
|
||||||
prog.BindFragData(0, "o_col0");
|
prog.BindFragData(0, "o_col0");
|
||||||
|
@ -385,7 +385,7 @@ bool GPU_HW_OpenGL::CompilePrograms()
|
||||||
prog->Bind();
|
prog->Bind();
|
||||||
m_vram_interlaced_fill_program = std::move(*prog);
|
m_vram_interlaced_fill_program = std::move(*prog);
|
||||||
|
|
||||||
prog = m_shader_cache.GetProgram(shadergen.GenerateScreenQuadVertexShader(),
|
prog = m_shader_cache.GetProgram(shadergen.GenerateScreenQuadVertexShader(), {},
|
||||||
shadergen.GenerateVRAMReadFragmentShader(), [this](GL::Program& prog) {
|
shadergen.GenerateVRAMReadFragmentShader(), [this](GL::Program& prog) {
|
||||||
if (!m_is_gles)
|
if (!m_is_gles)
|
||||||
prog.BindFragData(0, "o_col0");
|
prog.BindFragData(0, "o_col0");
|
||||||
|
@ -400,7 +400,7 @@ bool GPU_HW_OpenGL::CompilePrograms()
|
||||||
|
|
||||||
if (m_supports_texture_buffer)
|
if (m_supports_texture_buffer)
|
||||||
{
|
{
|
||||||
prog = m_shader_cache.GetProgram(shadergen.GenerateScreenQuadVertexShader(),
|
prog = m_shader_cache.GetProgram(shadergen.GenerateScreenQuadVertexShader(), {},
|
||||||
shadergen.GenerateVRAMWriteFragmentShader(), [this](GL::Program& prog) {
|
shadergen.GenerateVRAMWriteFragmentShader(), [this](GL::Program& prog) {
|
||||||
if (!m_is_gles)
|
if (!m_is_gles)
|
||||||
prog.BindFragData(0, "o_col0");
|
prog.BindFragData(0, "o_col0");
|
||||||
|
|
|
@ -419,7 +419,7 @@ void main()
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
if (!m_display_program.Compile(GetGLSLVersionHeader() + fullscreen_quad_vertex_shader,
|
if (!m_display_program.Compile(GetGLSLVersionHeader() + fullscreen_quad_vertex_shader, {},
|
||||||
GetGLSLVersionHeader() + display_fragment_shader))
|
GetGLSLVersionHeader() + display_fragment_shader))
|
||||||
{
|
{
|
||||||
Log_ErrorPrintf("Failed to compile display shaders");
|
Log_ErrorPrintf("Failed to compile display shaders");
|
||||||
|
|
|
@ -332,7 +332,7 @@ void main()
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
if (!m_display_program.Compile(GetGLSLVersionHeader() + fullscreen_quad_vertex_shader,
|
if (!m_display_program.Compile(GetGLSLVersionHeader() + fullscreen_quad_vertex_shader, {},
|
||||||
GetGLSLVersionHeader() + display_fragment_shader))
|
GetGLSLVersionHeader() + display_fragment_shader))
|
||||||
{
|
{
|
||||||
Log_ErrorPrintf("Failed to compile display shaders");
|
Log_ErrorPrintf("Failed to compile display shaders");
|
||||||
|
|
Loading…
Reference in a new issue