mirror of
https://github.com/libretro/RetroArch
synced 2025-04-18 14:42:30 +00:00
(shader_gl_core.cpp) Simplify
This commit is contained in:
parent
c85bf21fbb
commit
3225876f0b
@ -92,6 +92,8 @@ GLuint gl_core_cross_compile_program(
|
|||||||
GLuint program = 0;
|
GLuint program = 0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
spirv_cross::ShaderResources vertex_resources;
|
||||||
|
spirv_cross::ShaderResources fragment_resources;
|
||||||
spirv_cross::CompilerGLSL vertex_compiler(vertex, vertex_size / 4);
|
spirv_cross::CompilerGLSL vertex_compiler(vertex, vertex_size / 4);
|
||||||
spirv_cross::CompilerGLSL fragment_compiler(fragment, fragment_size / 4);
|
spirv_cross::CompilerGLSL fragment_compiler(fragment, fragment_size / 4);
|
||||||
spirv_cross::CompilerGLSL::Options opts;
|
spirv_cross::CompilerGLSL::Options opts;
|
||||||
@ -105,11 +107,12 @@ GLuint gl_core_cross_compile_program(
|
|||||||
opts.fragment.default_float_precision = spirv_cross::CompilerGLSL::Options::Precision::Highp;
|
opts.fragment.default_float_precision = spirv_cross::CompilerGLSL::Options::Precision::Highp;
|
||||||
opts.fragment.default_int_precision = spirv_cross::CompilerGLSL::Options::Precision::Highp;
|
opts.fragment.default_int_precision = spirv_cross::CompilerGLSL::Options::Precision::Highp;
|
||||||
opts.enable_420pack_extension = false;
|
opts.enable_420pack_extension = false;
|
||||||
|
|
||||||
vertex_compiler.set_common_options(opts);
|
vertex_compiler.set_common_options(opts);
|
||||||
fragment_compiler.set_common_options(opts);
|
fragment_compiler.set_common_options(opts);
|
||||||
|
|
||||||
auto vertex_resources = vertex_compiler.get_shader_resources();
|
vertex_resources = vertex_compiler.get_shader_resources();
|
||||||
auto fragment_resources = fragment_compiler.get_shader_resources();
|
fragment_resources = fragment_compiler.get_shader_resources();
|
||||||
|
|
||||||
for (auto &res : vertex_resources.stage_inputs)
|
for (auto &res : vertex_resources.stage_inputs)
|
||||||
{
|
{
|
||||||
@ -276,7 +279,7 @@ GLuint gl_core_cross_compile_program(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force proper bindings for textures.
|
/* Force proper bindings for textures. */
|
||||||
for (auto &binding : texture_binding_fixups)
|
for (auto &binding : texture_binding_fixups)
|
||||||
{
|
{
|
||||||
GLint location = glGetUniformLocation(program, (string("RARCH_TEXTURE_") + to_string(binding)).c_str());
|
GLint location = glGetUniformLocation(program, (string("RARCH_TEXTURE_") + to_string(binding)).c_str());
|
||||||
@ -320,7 +323,8 @@ static unsigned num_miplevels(unsigned width, unsigned height)
|
|||||||
{
|
{
|
||||||
unsigned size = MAX(width, height);
|
unsigned size = MAX(width, height);
|
||||||
unsigned levels = 0;
|
unsigned levels = 0;
|
||||||
while (size) {
|
while (size)
|
||||||
|
{
|
||||||
levels++;
|
levels++;
|
||||||
size >>= 1;
|
size >>= 1;
|
||||||
}
|
}
|
||||||
@ -372,44 +376,44 @@ static gl_core_filter_chain_address wrap_to_address(gfx_wrap_type type)
|
|||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
default:
|
|
||||||
case RARCH_WRAP_EDGE:
|
|
||||||
return GL_CORE_FILTER_CHAIN_ADDRESS_CLAMP_TO_EDGE;
|
|
||||||
|
|
||||||
case RARCH_WRAP_BORDER:
|
case RARCH_WRAP_BORDER:
|
||||||
return GL_CORE_FILTER_CHAIN_ADDRESS_CLAMP_TO_BORDER;
|
return GL_CORE_FILTER_CHAIN_ADDRESS_CLAMP_TO_BORDER;
|
||||||
|
|
||||||
case RARCH_WRAP_REPEAT:
|
case RARCH_WRAP_REPEAT:
|
||||||
return GL_CORE_FILTER_CHAIN_ADDRESS_REPEAT;
|
return GL_CORE_FILTER_CHAIN_ADDRESS_REPEAT;
|
||||||
|
|
||||||
case RARCH_WRAP_MIRRORED_REPEAT:
|
case RARCH_WRAP_MIRRORED_REPEAT:
|
||||||
return GL_CORE_FILTER_CHAIN_ADDRESS_MIRRORED_REPEAT;
|
return GL_CORE_FILTER_CHAIN_ADDRESS_MIRRORED_REPEAT;
|
||||||
|
case RARCH_WRAP_EDGE:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return GL_CORE_FILTER_CHAIN_ADDRESS_CLAMP_TO_EDGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLenum address_to_gl(gl_core_filter_chain_address type)
|
static GLenum address_to_gl(gl_core_filter_chain_address type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
default:
|
|
||||||
case GL_CORE_FILTER_CHAIN_ADDRESS_CLAMP_TO_EDGE:
|
|
||||||
return GL_CLAMP_TO_EDGE;
|
|
||||||
|
|
||||||
#ifdef HAVE_OPENGLES3
|
#ifdef HAVE_OPENGLES3
|
||||||
case GL_CORE_FILTER_CHAIN_ADDRESS_CLAMP_TO_BORDER:
|
case GL_CORE_FILTER_CHAIN_ADDRESS_CLAMP_TO_BORDER:
|
||||||
//RARCH_WARN("[GLCore]: No CLAMP_TO_BORDER in GLES3. Falling back to edge clamp.\n");
|
#if 0
|
||||||
|
RARCH_WARN("[GLCore]: No CLAMP_TO_BORDER in GLES3. Falling back to edge clamp.\n");
|
||||||
|
#endif
|
||||||
return GL_CLAMP_TO_EDGE;
|
return GL_CLAMP_TO_EDGE;
|
||||||
#else
|
#else
|
||||||
case GL_CORE_FILTER_CHAIN_ADDRESS_CLAMP_TO_BORDER:
|
case GL_CORE_FILTER_CHAIN_ADDRESS_CLAMP_TO_BORDER:
|
||||||
return GL_CLAMP_TO_BORDER;
|
return GL_CLAMP_TO_BORDER;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case GL_CORE_FILTER_CHAIN_ADDRESS_REPEAT:
|
case GL_CORE_FILTER_CHAIN_ADDRESS_REPEAT:
|
||||||
return GL_REPEAT;
|
return GL_REPEAT;
|
||||||
|
|
||||||
case GL_CORE_FILTER_CHAIN_ADDRESS_MIRRORED_REPEAT:
|
case GL_CORE_FILTER_CHAIN_ADDRESS_MIRRORED_REPEAT:
|
||||||
return GL_MIRRORED_REPEAT;
|
return GL_MIRRORED_REPEAT;
|
||||||
|
case GL_CORE_FILTER_CHAIN_ADDRESS_CLAMP_TO_EDGE:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return GL_CLAMP_TO_EDGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLenum convert_filter_to_mag_gl(gl_core_filter_chain_filter filter)
|
static GLenum convert_filter_to_mag_gl(gl_core_filter_chain_filter filter)
|
||||||
@ -418,11 +422,12 @@ static GLenum convert_filter_to_mag_gl(gl_core_filter_chain_filter filter)
|
|||||||
{
|
{
|
||||||
case GL_CORE_FILTER_CHAIN_LINEAR:
|
case GL_CORE_FILTER_CHAIN_LINEAR:
|
||||||
return GL_LINEAR;
|
return GL_LINEAR;
|
||||||
|
|
||||||
default:
|
|
||||||
case GL_CORE_FILTER_CHAIN_NEAREST:
|
case GL_CORE_FILTER_CHAIN_NEAREST:
|
||||||
return GL_NEAREST;
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return GL_NEAREST;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLenum convert_filter_to_min_gl(gl_core_filter_chain_filter filter, gl_core_filter_chain_filter mipfilter)
|
static GLenum convert_filter_to_min_gl(gl_core_filter_chain_filter filter, gl_core_filter_chain_filter mipfilter)
|
||||||
@ -433,7 +438,6 @@ static GLenum convert_filter_to_min_gl(gl_core_filter_chain_filter filter, gl_co
|
|||||||
return GL_LINEAR_MIPMAP_NEAREST;
|
return GL_LINEAR_MIPMAP_NEAREST;
|
||||||
else if (mipfilter == GL_CORE_FILTER_CHAIN_LINEAR)
|
else if (mipfilter == GL_CORE_FILTER_CHAIN_LINEAR)
|
||||||
return GL_NEAREST_MIPMAP_LINEAR;
|
return GL_NEAREST_MIPMAP_LINEAR;
|
||||||
else
|
|
||||||
return GL_NEAREST_MIPMAP_NEAREST;
|
return GL_NEAREST_MIPMAP_NEAREST;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -656,7 +660,7 @@ Framebuffer::Framebuffer(GLenum format_, unsigned max_levels_)
|
|||||||
{
|
{
|
||||||
glGenFramebuffers(1, &framebuffer);
|
glGenFramebuffers(1, &framebuffer);
|
||||||
|
|
||||||
// Need to bind to create.
|
/* Need to bind to create */
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
@ -729,12 +733,14 @@ void Framebuffer::init()
|
|||||||
|
|
||||||
if (fallback)
|
if (fallback)
|
||||||
{
|
{
|
||||||
|
unsigned levels;
|
||||||
|
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
||||||
glDeleteTextures(1, &image);
|
glDeleteTextures(1, &image);
|
||||||
glGenTextures(1, &image);
|
glGenTextures(1, &image);
|
||||||
glBindTexture(GL_TEXTURE_2D, image);
|
glBindTexture(GL_TEXTURE_2D, image);
|
||||||
|
|
||||||
unsigned levels = num_miplevels(size.width, size.height);
|
levels = num_miplevels(size.width, size.height);
|
||||||
if (max_levels < levels)
|
if (max_levels < levels)
|
||||||
levels = max_levels;
|
levels = max_levels;
|
||||||
glTexStorage2D(GL_TEXTURE_2D, levels,
|
glTexStorage2D(GL_TEXTURE_2D, levels,
|
||||||
@ -865,41 +871,38 @@ class UBORing
|
|||||||
public:
|
public:
|
||||||
~UBORing();
|
~UBORing();
|
||||||
void init(size_t size, unsigned count);
|
void init(size_t size, unsigned count);
|
||||||
void update_and_bind(unsigned vertex_binding, unsigned fragment_binding, const void *data, size_t size);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<GLuint> buffers;
|
std::vector<GLuint> buffers;
|
||||||
unsigned buffer_index = 0;
|
unsigned buffer_index = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
void UBORing::init(size_t size, unsigned count)
|
void UBORing::init(size_t size, unsigned count)
|
||||||
{
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
buffers.resize(count);
|
buffers.resize(count);
|
||||||
glGenBuffers(count, buffers.data());
|
glGenBuffers(count, buffers.data());
|
||||||
for (auto &buf : buffers)
|
|
||||||
|
for (i = 0; i < buffers.size(); i++)
|
||||||
{
|
{
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, buf);
|
glBindBuffer(GL_UNIFORM_BUFFER, buffers[i]);
|
||||||
glBufferData(GL_UNIFORM_BUFFER, size, nullptr, GL_STREAM_DRAW);
|
glBufferData(GL_UNIFORM_BUFFER, size, NULL, GL_STREAM_DRAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UBORing::update_and_bind(unsigned vertex_binding, unsigned fragment_binding, const void *data, size_t size)
|
static void ubo_ring_update_and_bind(
|
||||||
|
unsigned vertex_binding,
|
||||||
|
unsigned fragment_binding,
|
||||||
|
const void *data, size_t size, GLuint id)
|
||||||
{
|
{
|
||||||
if (vertex_binding == GL_INVALID_INDEX && fragment_binding == GL_INVALID_INDEX)
|
glBindBuffer(GL_UNIFORM_BUFFER, id);
|
||||||
return;
|
|
||||||
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, buffers[buffer_index]);
|
|
||||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, size, data);
|
glBufferSubData(GL_UNIFORM_BUFFER, 0, size, data);
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
if (vertex_binding != GL_INVALID_INDEX)
|
if (vertex_binding != GL_INVALID_INDEX)
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, vertex_binding, buffers[buffer_index]);
|
glBindBufferBase(GL_UNIFORM_BUFFER, vertex_binding, id);
|
||||||
if (fragment_binding != GL_INVALID_INDEX)
|
if (fragment_binding != GL_INVALID_INDEX)
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, fragment_binding, buffers[buffer_index]);
|
glBindBufferBase(GL_UNIFORM_BUFFER, fragment_binding, id);
|
||||||
|
|
||||||
buffer_index++;
|
|
||||||
if (buffer_index >= buffers.size())
|
|
||||||
buffer_index = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UBORing::~UBORing()
|
UBORing::~UBORing()
|
||||||
@ -1024,7 +1027,8 @@ private:
|
|||||||
|
|
||||||
void set_semantic_texture(slang_texture_semantic semantic,
|
void set_semantic_texture(slang_texture_semantic semantic,
|
||||||
const Texture &texture);
|
const Texture &texture);
|
||||||
void set_semantic_texture_array(slang_texture_semantic semantic, unsigned index,
|
void set_semantic_texture_array(slang_texture_semantic semantic,
|
||||||
|
unsigned index,
|
||||||
const Texture &texture);
|
const Texture &texture);
|
||||||
|
|
||||||
slang_reflection reflection;
|
slang_reflection reflection;
|
||||||
@ -1032,10 +1036,12 @@ private:
|
|||||||
std::vector<uint8_t> uniforms;
|
std::vector<uint8_t> uniforms;
|
||||||
|
|
||||||
void build_semantics(uint8_t *buffer,
|
void build_semantics(uint8_t *buffer,
|
||||||
const float *mvp, const Texture &original, const Texture &source);
|
const float *mvp,
|
||||||
|
const Texture &original, const Texture &source);
|
||||||
void build_semantic_vec4(uint8_t *data, slang_semantic semantic,
|
void build_semantic_vec4(uint8_t *data, slang_semantic semantic,
|
||||||
unsigned width, unsigned height);
|
unsigned width, unsigned height);
|
||||||
void build_semantic_uint(uint8_t *data, slang_semantic semantic, uint32_t value);
|
void build_semantic_uint(uint8_t *data,
|
||||||
|
slang_semantic semantic, uint32_t value);
|
||||||
void build_semantic_parameter(uint8_t *data, unsigned index, float value);
|
void build_semantic_parameter(uint8_t *data, unsigned index, float value);
|
||||||
void build_semantic_texture_vec4(uint8_t *data,
|
void build_semantic_texture_vec4(uint8_t *data,
|
||||||
slang_texture_semantic semantic,
|
slang_texture_semantic semantic,
|
||||||
@ -1046,7 +1052,8 @@ private:
|
|||||||
void build_semantic_texture(uint8_t *buffer,
|
void build_semantic_texture(uint8_t *buffer,
|
||||||
slang_texture_semantic semantic, const Texture &texture);
|
slang_texture_semantic semantic, const Texture &texture);
|
||||||
void build_semantic_texture_array(uint8_t *buffer,
|
void build_semantic_texture_array(uint8_t *buffer,
|
||||||
slang_texture_semantic semantic, unsigned index, const Texture &texture);
|
slang_texture_semantic semantic,
|
||||||
|
unsigned index, const Texture &texture);
|
||||||
|
|
||||||
uint64_t frame_count = 0;
|
uint64_t frame_count = 0;
|
||||||
unsigned frame_count_period = 0;
|
unsigned frame_count_period = 0;
|
||||||
@ -1083,10 +1090,8 @@ bool Pass::build()
|
|||||||
framebuffer_feedback.reset();
|
framebuffer_feedback.reset();
|
||||||
|
|
||||||
if (!final_pass)
|
if (!final_pass)
|
||||||
{
|
|
||||||
framebuffer = unique_ptr<Framebuffer>(
|
framebuffer = unique_ptr<Framebuffer>(
|
||||||
new Framebuffer(pass_info.rt_format, pass_info.max_levels));
|
new Framebuffer(pass_info.rt_format, pass_info.max_levels));
|
||||||
}
|
|
||||||
|
|
||||||
for (auto ¶m : parameters)
|
for (auto ¶m : parameters)
|
||||||
{
|
{
|
||||||
@ -1173,38 +1178,44 @@ void Pass::reflect_parameter(const std::string &name, slang_texture_semantic_met
|
|||||||
|
|
||||||
void Pass::reflect_parameter_array(const std::string &name, std::vector<slang_texture_semantic_meta> &meta)
|
void Pass::reflect_parameter_array(const std::string &name, std::vector<slang_texture_semantic_meta> &meta)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < meta.size(); i++)
|
size_t i;
|
||||||
|
for (i = 0; i < meta.size(); i++)
|
||||||
{
|
{
|
||||||
auto n = name + std::to_string(i);
|
std::string n = name + std::to_string(i);
|
||||||
auto &m = meta[i];
|
slang_texture_semantic_meta *m = (slang_texture_semantic_meta*)&meta[i];
|
||||||
|
|
||||||
if (m.uniform)
|
if (m->uniform)
|
||||||
{
|
{
|
||||||
int vert = glGetUniformLocation(pipeline, (std::string("RARCH_UBO_VERTEX_INSTANCE.") + n).c_str());
|
int vert = glGetUniformLocation(pipeline,
|
||||||
int frag = glGetUniformLocation(pipeline, (std::string("RARCH_UBO_FRAGMENT_INSTANCE.") + n).c_str());
|
(std::string("RARCH_UBO_VERTEX_INSTANCE.") + n).c_str());
|
||||||
|
int frag = glGetUniformLocation(pipeline,
|
||||||
|
(std::string("RARCH_UBO_FRAGMENT_INSTANCE.") + n).c_str());
|
||||||
|
|
||||||
if (vert >= 0)
|
if (vert >= 0)
|
||||||
m.location.ubo_vertex = vert;
|
m->location.ubo_vertex = vert;
|
||||||
if (frag >= 0)
|
if (frag >= 0)
|
||||||
m.location.ubo_fragment = frag;
|
m->location.ubo_fragment = frag;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m.push_constant)
|
if (m->push_constant)
|
||||||
{
|
{
|
||||||
int vert = glGetUniformLocation(pipeline, (std::string("RARCH_PUSH_VERTEX_INSTANCE.") + n).c_str());
|
int vert = glGetUniformLocation(pipeline,
|
||||||
int frag = glGetUniformLocation(pipeline, (std::string("RARCH_PUSH_FRAGMENT_INSTANCE.") + n).c_str());
|
(std::string("RARCH_PUSH_VERTEX_INSTANCE.") + n).c_str());
|
||||||
|
int frag = glGetUniformLocation(pipeline,
|
||||||
|
(std::string("RARCH_PUSH_FRAGMENT_INSTANCE.") + n).c_str());
|
||||||
|
|
||||||
if (vert >= 0)
|
if (vert >= 0)
|
||||||
m.location.push_vertex = vert;
|
m->location.push_vertex = vert;
|
||||||
if (frag >= 0)
|
if (frag >= 0)
|
||||||
m.location.push_fragment = frag;
|
m->location.push_fragment = frag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Pass::init_pipeline()
|
bool Pass::init_pipeline()
|
||||||
{
|
{
|
||||||
pipeline = gl_core_cross_compile_program(vertex_shader.data(), vertex_shader.size() * sizeof(uint32_t),
|
pipeline = gl_core_cross_compile_program(
|
||||||
|
vertex_shader.data(), vertex_shader.size() * sizeof(uint32_t),
|
||||||
fragment_shader.data(), fragment_shader.size() * sizeof(uint32_t),
|
fragment_shader.data(), fragment_shader.size() * sizeof(uint32_t),
|
||||||
&locations, false);
|
&locations, false);
|
||||||
|
|
||||||
@ -1305,78 +1316,78 @@ void Pass::end_frame()
|
|||||||
void Pass::build_semantic_vec4(uint8_t *data, slang_semantic semantic,
|
void Pass::build_semantic_vec4(uint8_t *data, slang_semantic semantic,
|
||||||
unsigned width, unsigned height)
|
unsigned width, unsigned height)
|
||||||
{
|
{
|
||||||
auto &refl = reflection.semantics[semantic];
|
slang_semantic_meta *refl = (slang_semantic_meta*)
|
||||||
|
&reflection.semantics[semantic];
|
||||||
|
|
||||||
if (data && refl.uniform)
|
if (data && refl->uniform)
|
||||||
{
|
{
|
||||||
if (refl.location.ubo_vertex >= 0 || refl.location.ubo_fragment >= 0)
|
if (refl->location.ubo_vertex >= 0 || refl->location.ubo_fragment >= 0)
|
||||||
{
|
{
|
||||||
float v4[4];
|
float v4[4];
|
||||||
build_vec4(v4, width, height);
|
build_vec4(v4, width, height);
|
||||||
if (refl.location.ubo_vertex >= 0)
|
if (refl->location.ubo_vertex >= 0)
|
||||||
glUniform4fv(refl.location.ubo_vertex, 1, v4);
|
glUniform4fv(refl->location.ubo_vertex, 1, v4);
|
||||||
if (refl.location.ubo_fragment >= 0)
|
if (refl->location.ubo_fragment >= 0)
|
||||||
glUniform4fv(refl.location.ubo_fragment, 1, v4);
|
glUniform4fv(refl->location.ubo_fragment, 1, v4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
build_vec4(
|
build_vec4(
|
||||||
reinterpret_cast<float *>(data + refl.ubo_offset),
|
reinterpret_cast<float *>(data + refl->ubo_offset),
|
||||||
width,
|
width,
|
||||||
height);
|
height);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (refl.push_constant)
|
if (refl->push_constant)
|
||||||
{
|
{
|
||||||
if (refl.location.push_vertex >= 0 || refl.location.push_fragment >= 0)
|
if ( refl->location.push_vertex >= 0 ||
|
||||||
|
refl->location.push_fragment >= 0)
|
||||||
{
|
{
|
||||||
float v4[4];
|
float v4[4];
|
||||||
build_vec4(v4, width, height);
|
build_vec4(v4, width, height);
|
||||||
if (refl.location.push_vertex >= 0)
|
if (refl->location.push_vertex >= 0)
|
||||||
glUniform4fv(refl.location.push_vertex, 1, v4);
|
glUniform4fv(refl->location.push_vertex, 1, v4);
|
||||||
if (refl.location.push_fragment >= 0)
|
if (refl->location.push_fragment >= 0)
|
||||||
glUniform4fv(refl.location.push_fragment, 1, v4);
|
glUniform4fv(refl->location.push_fragment, 1, v4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
build_vec4(
|
build_vec4(
|
||||||
reinterpret_cast<float *>(push_constant_buffer.data() + refl.push_constant_offset),
|
reinterpret_cast<float *>
|
||||||
|
(push_constant_buffer.data() + refl->push_constant_offset),
|
||||||
width,
|
width,
|
||||||
height);
|
height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Pass::build_semantic_parameter(uint8_t *data, unsigned index, float value)
|
void Pass::build_semantic_parameter(uint8_t *data, unsigned index, float value)
|
||||||
{
|
{
|
||||||
auto &refl = reflection.semantic_float_parameters[index];
|
slang_semantic_meta *refl = (slang_semantic_meta*)
|
||||||
|
&reflection.semantic_float_parameters[index];
|
||||||
|
|
||||||
/* We will have filtered out stale parameters. */
|
/* We will have filtered out stale parameters. */
|
||||||
if (data && refl.uniform)
|
if (data && refl->uniform)
|
||||||
{
|
{
|
||||||
if (refl.location.ubo_vertex >= 0 || refl.location.ubo_fragment >= 0)
|
if (refl->location.ubo_vertex >= 0 || refl->location.ubo_fragment >= 0)
|
||||||
{
|
{
|
||||||
if (refl.location.ubo_vertex >= 0)
|
if (refl->location.ubo_vertex >= 0)
|
||||||
glUniform1f(refl.location.ubo_vertex, value);
|
glUniform1f(refl->location.ubo_vertex, value);
|
||||||
if (refl.location.ubo_fragment >= 0)
|
if (refl->location.ubo_fragment >= 0)
|
||||||
glUniform1f(refl.location.ubo_fragment, value);
|
glUniform1f(refl->location.ubo_fragment, value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*reinterpret_cast<float *>(data + refl.ubo_offset) = value;
|
*reinterpret_cast<float *>(data + refl->ubo_offset) = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (refl.push_constant)
|
if (refl->push_constant)
|
||||||
{
|
{
|
||||||
if (refl.location.push_vertex >= 0 || refl.location.push_fragment >= 0)
|
if (refl->location.push_vertex >= 0 || refl->location.push_fragment >= 0)
|
||||||
{
|
{
|
||||||
if (refl.location.push_vertex >= 0)
|
if (refl->location.push_vertex >= 0)
|
||||||
glUniform1f(refl.location.push_vertex, value);
|
glUniform1f(refl->location.push_vertex, value);
|
||||||
if (refl.location.push_fragment >= 0)
|
if (refl->location.push_fragment >= 0)
|
||||||
glUniform1f(refl.location.push_fragment, value);
|
glUniform1f(refl->location.push_fragment, value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*reinterpret_cast<float *>(push_constant_buffer.data() + refl.push_constant_offset) = value;
|
*reinterpret_cast<float *>(push_constant_buffer.data() + refl->push_constant_offset) = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1448,13 +1459,11 @@ void Pass::build_semantic_texture_array_vec4(uint8_t *data, slang_texture_semant
|
|||||||
glUniform4fv(refl[index].location.ubo_fragment, 1, v4);
|
glUniform4fv(refl[index].location.ubo_fragment, 1, v4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
build_vec4(
|
build_vec4(
|
||||||
reinterpret_cast<float *>(data + refl[index].ubo_offset),
|
reinterpret_cast<float *>(data + refl[index].ubo_offset),
|
||||||
width,
|
width,
|
||||||
height);
|
height);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (refl[index].push_constant)
|
if (refl[index].push_constant)
|
||||||
{
|
{
|
||||||
@ -1468,14 +1477,12 @@ void Pass::build_semantic_texture_array_vec4(uint8_t *data, slang_texture_semant
|
|||||||
glUniform4fv(refl[index].location.push_fragment, 1, v4);
|
glUniform4fv(refl[index].location.push_fragment, 1, v4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
build_vec4(
|
build_vec4(
|
||||||
reinterpret_cast<float *>(push_constant_buffer.data() + refl[index].push_constant_offset),
|
reinterpret_cast<float *>(push_constant_buffer.data() + refl[index].push_constant_offset),
|
||||||
width,
|
width,
|
||||||
height);
|
height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Pass::build_semantic_texture_vec4(uint8_t *data, slang_texture_semantic semantic,
|
void Pass::build_semantic_texture_vec4(uint8_t *data, slang_texture_semantic semantic,
|
||||||
unsigned width, unsigned height)
|
unsigned width, unsigned height)
|
||||||
@ -1549,87 +1556,85 @@ void Pass::build_semantic_texture_array(uint8_t *buffer,
|
|||||||
void Pass::build_semantics(uint8_t *buffer,
|
void Pass::build_semantics(uint8_t *buffer,
|
||||||
const float *mvp, const Texture &original, const Texture &source)
|
const float *mvp, const Texture &original, const Texture &source)
|
||||||
{
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
/* MVP */
|
/* MVP */
|
||||||
if (buffer && reflection.semantics[SLANG_SEMANTIC_MVP].uniform)
|
if (buffer && reflection.semantics[SLANG_SEMANTIC_MVP].uniform)
|
||||||
{
|
{
|
||||||
size_t offset = reflection.semantics[SLANG_SEMANTIC_MVP].ubo_offset;
|
size_t offset = reflection.semantics[
|
||||||
|
SLANG_SEMANTIC_MVP].ubo_offset;
|
||||||
if (mvp)
|
if (mvp)
|
||||||
memcpy(buffer + offset, mvp, sizeof(float) * 16);
|
memcpy(buffer + offset,
|
||||||
|
mvp, sizeof(float) * 16);
|
||||||
else
|
else
|
||||||
build_default_matrix(reinterpret_cast<float *>(buffer + offset));
|
build_default_matrix(reinterpret_cast<float *>(
|
||||||
|
buffer + offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reflection.semantics[SLANG_SEMANTIC_MVP].push_constant)
|
if (reflection.semantics[SLANG_SEMANTIC_MVP].push_constant)
|
||||||
{
|
{
|
||||||
size_t offset = reflection.semantics[SLANG_SEMANTIC_MVP].push_constant_offset;
|
size_t offset = reflection.semantics[
|
||||||
|
SLANG_SEMANTIC_MVP].push_constant_offset;
|
||||||
|
|
||||||
if (mvp)
|
if (mvp)
|
||||||
memcpy(push_constant_buffer.data() + offset, mvp, sizeof(float) * 16);
|
memcpy(push_constant_buffer.data() + offset,
|
||||||
|
mvp, sizeof(float) * 16);
|
||||||
else
|
else
|
||||||
build_default_matrix(reinterpret_cast<float *>(push_constant_buffer.data() + offset));
|
build_default_matrix(reinterpret_cast<float *>(
|
||||||
|
push_constant_buffer.data() + offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Output information */
|
/* Output information */
|
||||||
build_semantic_vec4(buffer, SLANG_SEMANTIC_OUTPUT,
|
build_semantic_vec4(buffer, SLANG_SEMANTIC_OUTPUT,
|
||||||
current_framebuffer_size.width, current_framebuffer_size.height);
|
current_framebuffer_size.width,
|
||||||
|
current_framebuffer_size.height);
|
||||||
build_semantic_vec4(buffer, SLANG_SEMANTIC_FINAL_VIEWPORT,
|
build_semantic_vec4(buffer, SLANG_SEMANTIC_FINAL_VIEWPORT,
|
||||||
unsigned(current_viewport.width), unsigned(current_viewport.height));
|
unsigned(current_viewport.width),
|
||||||
|
unsigned(current_viewport.height));
|
||||||
|
|
||||||
build_semantic_uint(buffer, SLANG_SEMANTIC_FRAME_COUNT,
|
build_semantic_uint(buffer, SLANG_SEMANTIC_FRAME_COUNT,
|
||||||
frame_count_period ? uint32_t(frame_count % frame_count_period) : uint32_t(frame_count));
|
frame_count_period
|
||||||
|
? uint32_t(frame_count % frame_count_period)
|
||||||
|
: uint32_t(frame_count));
|
||||||
|
|
||||||
/* Standard inputs */
|
/* Standard inputs */
|
||||||
build_semantic_texture(buffer, SLANG_TEXTURE_SEMANTIC_ORIGINAL, original);
|
build_semantic_texture(buffer, SLANG_TEXTURE_SEMANTIC_ORIGINAL, original);
|
||||||
build_semantic_texture(buffer, SLANG_TEXTURE_SEMANTIC_SOURCE, source);
|
build_semantic_texture(buffer, SLANG_TEXTURE_SEMANTIC_SOURCE, source);
|
||||||
|
|
||||||
/* ORIGINAL_HISTORY[0] is an alias of ORIGINAL. */
|
/* ORIGINAL_HISTORY[0] is an alias of ORIGINAL. */
|
||||||
build_semantic_texture_array(buffer, SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY, 0, original);
|
build_semantic_texture_array(buffer,
|
||||||
|
SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY, 0, original);
|
||||||
|
|
||||||
/* Parameters. */
|
/* Parameters. */
|
||||||
for (auto ¶m : filtered_parameters)
|
for (i = 0; i < filtered_parameters.size(); i++)
|
||||||
{
|
build_semantic_parameter(buffer,
|
||||||
float value = common->shader_preset->parameters[param.index].current;
|
filtered_parameters[i].semantic_index,
|
||||||
build_semantic_parameter(buffer, param.semantic_index, value);
|
common->shader_preset->parameters[
|
||||||
}
|
filtered_parameters[i].index].current);
|
||||||
|
|
||||||
/* Previous inputs. */
|
/* Previous inputs. */
|
||||||
unsigned i = 0;
|
for (i = 0; i < common->original_history.size(); i++)
|
||||||
for (auto &texture : common->original_history)
|
|
||||||
{
|
|
||||||
build_semantic_texture_array(buffer,
|
build_semantic_texture_array(buffer,
|
||||||
SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY, i + 1,
|
SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY, i + 1,
|
||||||
texture);
|
common->original_history[i]);
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Previous passes. */
|
/* Previous passes. */
|
||||||
i = 0;
|
for (i = 0; i < common->pass_outputs.size(); i++)
|
||||||
for (auto &texture : common->pass_outputs)
|
|
||||||
{
|
|
||||||
build_semantic_texture_array(buffer,
|
build_semantic_texture_array(buffer,
|
||||||
SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT, i,
|
SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT, i,
|
||||||
texture);
|
common->pass_outputs[i]);
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Feedback FBOs. */
|
/* Feedback FBOs. */
|
||||||
i = 0;
|
for (i = 0; i < common->framebuffer_feedback.size(); i++)
|
||||||
for (auto &texture : common->framebuffer_feedback)
|
|
||||||
{
|
|
||||||
build_semantic_texture_array(buffer,
|
build_semantic_texture_array(buffer,
|
||||||
SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK, i,
|
SLANG_TEXTURE_SEMANTIC_PASS_FEEDBACK, i,
|
||||||
texture);
|
common->framebuffer_feedback[i]);
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* LUTs. */
|
/* LUTs. */
|
||||||
i = 0;
|
for (i = 0; i < common->luts.size(); i++)
|
||||||
for (auto &lut : common->luts)
|
|
||||||
{
|
|
||||||
build_semantic_texture_array(buffer,
|
build_semantic_texture_array(buffer,
|
||||||
SLANG_TEXTURE_SEMANTIC_USER, i,
|
SLANG_TEXTURE_SEMANTIC_USER, i,
|
||||||
lut->get_texture());
|
common->luts[i]->get_texture());
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pass::build_commands(
|
void Pass::build_commands(
|
||||||
@ -1639,16 +1644,15 @@ void Pass::build_commands(
|
|||||||
const float *mvp)
|
const float *mvp)
|
||||||
{
|
{
|
||||||
current_viewport = vp;
|
current_viewport = vp;
|
||||||
auto size = get_output_size(
|
Size2D size = get_output_size(
|
||||||
{ original.texture.width, original.texture.height },
|
{ original.texture.width, original.texture.height },
|
||||||
{ source.texture.width, source.texture.height });
|
{ source.texture.width, source.texture.height });
|
||||||
|
|
||||||
if (framebuffer &&
|
if (framebuffer &&
|
||||||
(size.width != framebuffer->get_size().width ||
|
(size.width != framebuffer->get_size().width ||
|
||||||
size.height != framebuffer->get_size().height))
|
size.height != framebuffer->get_size().height))
|
||||||
{
|
|
||||||
framebuffer->set_size(size);
|
framebuffer->set_size(size);
|
||||||
}
|
|
||||||
current_framebuffer_size = size;
|
current_framebuffer_size = size;
|
||||||
|
|
||||||
glUseProgram(pipeline);
|
glUseProgram(pipeline);
|
||||||
@ -1656,35 +1660,39 @@ void Pass::build_commands(
|
|||||||
build_semantics(uniforms.data(), mvp, original, source);
|
build_semantics(uniforms.data(), mvp, original, source);
|
||||||
|
|
||||||
if (locations.flat_ubo_vertex >= 0)
|
if (locations.flat_ubo_vertex >= 0)
|
||||||
{
|
|
||||||
glUniform4fv(locations.flat_ubo_vertex,
|
glUniform4fv(locations.flat_ubo_vertex,
|
||||||
GLsizei((reflection.ubo_size + 15) / 16),
|
GLsizei((reflection.ubo_size + 15) / 16),
|
||||||
reinterpret_cast<const float *>(uniforms.data()));
|
reinterpret_cast<const float *>(uniforms.data()));
|
||||||
}
|
|
||||||
|
|
||||||
if (locations.flat_ubo_fragment >= 0)
|
if (locations.flat_ubo_fragment >= 0)
|
||||||
{
|
|
||||||
glUniform4fv(locations.flat_ubo_fragment,
|
glUniform4fv(locations.flat_ubo_fragment,
|
||||||
GLsizei((reflection.ubo_size + 15) / 16),
|
GLsizei((reflection.ubo_size + 15) / 16),
|
||||||
reinterpret_cast<const float *>(uniforms.data()));
|
reinterpret_cast<const float *>(uniforms.data()));
|
||||||
}
|
|
||||||
|
|
||||||
if (locations.flat_push_vertex >= 0)
|
if (locations.flat_push_vertex >= 0)
|
||||||
{
|
|
||||||
glUniform4fv(locations.flat_push_vertex,
|
glUniform4fv(locations.flat_push_vertex,
|
||||||
GLsizei((reflection.push_constant_size + 15) / 16),
|
GLsizei((reflection.push_constant_size + 15) / 16),
|
||||||
reinterpret_cast<const float *>(push_constant_buffer.data()));
|
reinterpret_cast<const float *>(push_constant_buffer.data()));
|
||||||
}
|
|
||||||
|
|
||||||
if (locations.flat_push_fragment >= 0)
|
if (locations.flat_push_fragment >= 0)
|
||||||
{
|
|
||||||
glUniform4fv(locations.flat_push_fragment,
|
glUniform4fv(locations.flat_push_fragment,
|
||||||
GLsizei((reflection.push_constant_size + 15) / 16),
|
GLsizei((reflection.push_constant_size + 15) / 16),
|
||||||
reinterpret_cast<const float *>(push_constant_buffer.data()));
|
reinterpret_cast<const float *>(push_constant_buffer.data()));
|
||||||
}
|
|
||||||
|
|
||||||
ubo_ring.update_and_bind(locations.buffer_index_ubo_vertex, locations.buffer_index_ubo_fragment,
|
if (!( locations.buffer_index_ubo_vertex == GL_INVALID_INDEX
|
||||||
uniforms.data(), reflection.ubo_size);
|
&& locations.buffer_index_ubo_fragment == GL_INVALID_INDEX))
|
||||||
|
{
|
||||||
|
ubo_ring_update_and_bind(
|
||||||
|
locations.buffer_index_ubo_vertex,
|
||||||
|
locations.buffer_index_ubo_fragment,
|
||||||
|
uniforms.data(), reflection.ubo_size,
|
||||||
|
ubo_ring.buffers[ubo_ring.buffer_index]
|
||||||
|
);
|
||||||
|
|
||||||
|
ubo_ring.buffer_index++;
|
||||||
|
if (ubo_ring.buffer_index >= ubo_ring.buffers.size())
|
||||||
|
ubo_ring.buffer_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* The final pass is always executed inside
|
/* The final pass is always executed inside
|
||||||
* another render pass since the frontend will
|
* another render pass since the frontend will
|
||||||
@ -1699,14 +1707,10 @@ void Pass::build_commands(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (final_pass)
|
if (final_pass)
|
||||||
{
|
|
||||||
glViewport(current_viewport.x, current_viewport.y,
|
glViewport(current_viewport.x, current_viewport.y,
|
||||||
current_viewport.width, current_viewport.height);
|
current_viewport.width, current_viewport.height);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
glViewport(0, 0, size.width, size.height);
|
glViewport(0, 0, size.width, size.height);
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef HAVE_OPENGLES3
|
#ifndef HAVE_OPENGLES3
|
||||||
if (framebuffer && framebuffer->get_format() == GL_SRGB8_ALPHA8)
|
if (framebuffer && framebuffer->get_format() == GL_SRGB8_ALPHA8)
|
||||||
@ -1723,21 +1727,16 @@ void Pass::build_commands(
|
|||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
if (!final_pass)
|
if (!final_pass)
|
||||||
{
|
|
||||||
if (framebuffer->get_levels() > 1)
|
if (framebuffer->get_levels() > 1)
|
||||||
framebuffer->generate_mips();
|
framebuffer->generate_mips();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gl_core_filter_chain
|
struct gl_core_filter_chain
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
gl_core_filter_chain(unsigned num_passes)
|
gl_core_filter_chain(unsigned num_passes) { set_num_passes(num_passes); }
|
||||||
{
|
|
||||||
set_num_passes(num_passes);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void set_shader_preset(unique_ptr<video_shader> shader)
|
inline void set_shader_preset(unique_ptr<video_shader> shader)
|
||||||
{
|
{
|
||||||
@ -1795,7 +1794,7 @@ void gl_core_filter_chain::clear_history_and_feedback()
|
|||||||
texture->clear();
|
texture->clear();
|
||||||
for (auto &pass : passes)
|
for (auto &pass : passes)
|
||||||
{
|
{
|
||||||
auto *fb = pass->get_feedback_framebuffer();
|
gl_core::Framebuffer *fb = pass->get_feedback_framebuffer();
|
||||||
if (fb)
|
if (fb)
|
||||||
fb->clear();
|
fb->clear();
|
||||||
}
|
}
|
||||||
@ -1803,44 +1802,55 @@ void gl_core_filter_chain::clear_history_and_feedback()
|
|||||||
|
|
||||||
void gl_core_filter_chain::update_history_info()
|
void gl_core_filter_chain::update_history_info()
|
||||||
{
|
{
|
||||||
unsigned i = 0;
|
unsigned i;
|
||||||
for (auto &texture : original_history)
|
for (i = 0; i < original_history.size(); i++)
|
||||||
{
|
{
|
||||||
auto &source = common.original_history[i];
|
gl_core::Texture *source = (gl_core::Texture*)
|
||||||
source.texture.image = texture->get_image();
|
&common.original_history[i];
|
||||||
source.texture.width = texture->get_size().width;
|
|
||||||
source.texture.height = texture->get_size().height;
|
if (!source)
|
||||||
source.filter = passes.front()->get_source_filter();
|
continue;
|
||||||
source.mip_filter = passes.front()->get_mip_filter();
|
|
||||||
source.address = passes.front()->get_address_mode();
|
source->texture.image = original_history[i]->get_image();
|
||||||
i++;
|
source->texture.width = original_history[i]->get_size().width;
|
||||||
|
source->texture.height = original_history[i]->get_size().height;
|
||||||
|
source->filter = passes.front()->get_source_filter();
|
||||||
|
source->mip_filter = passes.front()->get_mip_filter();
|
||||||
|
source->address = passes.front()->get_address_mode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gl_core_filter_chain::update_feedback_info()
|
void gl_core_filter_chain::update_feedback_info()
|
||||||
{
|
{
|
||||||
|
unsigned i;
|
||||||
if (common.framebuffer_feedback.empty())
|
if (common.framebuffer_feedback.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (unsigned i = 0; i < passes.size() - 1; i++)
|
for (i = 0; i < passes.size() - 1; i++)
|
||||||
{
|
{
|
||||||
auto fb = passes[i]->get_feedback_framebuffer();
|
gl_core::Framebuffer *fb = passes[i]->get_feedback_framebuffer();
|
||||||
if (!fb)
|
if (!fb)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto &source = common.framebuffer_feedback[i];
|
gl_core::Texture *source = (gl_core::Texture*)
|
||||||
source.texture.image = fb->get_image();
|
&common.framebuffer_feedback[i];
|
||||||
source.texture.width = fb->get_size().width;
|
|
||||||
source.texture.height = fb->get_size().height;
|
if (!source)
|
||||||
source.filter = passes[i]->get_source_filter();
|
continue;
|
||||||
source.mip_filter = passes[i]->get_mip_filter();
|
|
||||||
source.address = passes[i]->get_address_mode();
|
source->texture.image = fb->get_image();
|
||||||
|
source->texture.width = fb->get_size().width;
|
||||||
|
source->texture.height = fb->get_size().height;
|
||||||
|
source->filter = passes[i]->get_source_filter();
|
||||||
|
source->mip_filter = passes[i]->get_mip_filter();
|
||||||
|
source->address = passes[i]->get_address_mode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gl_core_filter_chain::build_offscreen_passes(const gl_core_viewport &vp)
|
void gl_core_filter_chain::build_offscreen_passes(const gl_core_viewport &vp)
|
||||||
{
|
{
|
||||||
/* First frame, make sure our history and feedback textures are in a clean state. */
|
/* First frame, make sure our history and feedback textures
|
||||||
|
* are in a clean state. */
|
||||||
if (require_clear)
|
if (require_clear)
|
||||||
{
|
{
|
||||||
clear_history_and_feedback();
|
clear_history_and_feedback();
|
||||||
@ -1863,6 +1873,7 @@ void gl_core_filter_chain::build_offscreen_passes(const gl_core_viewport &vp)
|
|||||||
passes[i]->build_commands(original, source, vp, nullptr);
|
passes[i]->build_commands(original, source, vp, nullptr);
|
||||||
|
|
||||||
auto &fb = passes[i]->get_framebuffer();
|
auto &fb = passes[i]->get_framebuffer();
|
||||||
|
|
||||||
source.texture.image = fb.get_image();
|
source.texture.image = fb.get_image();
|
||||||
source.texture.width = fb.get_size().width;
|
source.texture.width = fb.get_size().width;
|
||||||
source.texture.height = fb.get_size().height;
|
source.texture.height = fb.get_size().height;
|
||||||
@ -1883,9 +1894,7 @@ void gl_core_filter_chain::update_history()
|
|||||||
if (input_texture.width != tmp->get_size().width ||
|
if (input_texture.width != tmp->get_size().width ||
|
||||||
input_texture.height != tmp->get_size().height ||
|
input_texture.height != tmp->get_size().height ||
|
||||||
(input_texture.format != 0 && input_texture.format != tmp->get_format()))
|
(input_texture.format != 0 && input_texture.format != tmp->get_format()))
|
||||||
{
|
|
||||||
tmp->set_size({ input_texture.width, input_texture.height }, input_texture.format);
|
tmp->set_size({ input_texture.width, input_texture.height }, input_texture.format);
|
||||||
}
|
|
||||||
|
|
||||||
tmp->copy(common, input_texture.image);
|
tmp->copy(common, input_texture.image);
|
||||||
|
|
||||||
@ -1901,14 +1910,13 @@ void gl_core_filter_chain::end_frame()
|
|||||||
* pass is the last that reads from
|
* pass is the last that reads from
|
||||||
* the history and dispatch the copy earlier. */
|
* the history and dispatch the copy earlier. */
|
||||||
if (!original_history.empty())
|
if (!original_history.empty())
|
||||||
{
|
|
||||||
update_history();
|
update_history();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void gl_core_filter_chain::build_viewport_pass(
|
void gl_core_filter_chain::build_viewport_pass(
|
||||||
const gl_core_viewport &vp, const float *mvp)
|
const gl_core_viewport &vp, const float *mvp)
|
||||||
{
|
{
|
||||||
|
unsigned i;
|
||||||
/* First frame, make sure our history and feedback textures are in a clean state. */
|
/* First frame, make sure our history and feedback textures are in a clean state. */
|
||||||
if (require_clear)
|
if (require_clear)
|
||||||
{
|
{
|
||||||
@ -1947,22 +1955,23 @@ void gl_core_filter_chain::build_viewport_pass(
|
|||||||
passes.back()->build_commands(original, source, vp, mvp);
|
passes.back()->build_commands(original, source, vp, mvp);
|
||||||
|
|
||||||
/* For feedback FBOs, swap current and previous. */
|
/* For feedback FBOs, swap current and previous. */
|
||||||
for (auto &pass : passes)
|
for (i = 0; i < passes.size(); i++)
|
||||||
pass->end_frame();
|
passes[i]->end_frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gl_core_filter_chain::init_history()
|
bool gl_core_filter_chain::init_history()
|
||||||
{
|
{
|
||||||
|
unsigned i;
|
||||||
|
size_t required_images = 0;
|
||||||
|
|
||||||
original_history.clear();
|
original_history.clear();
|
||||||
common.original_history.clear();
|
common.original_history.clear();
|
||||||
|
|
||||||
size_t required_images = 0;
|
for (i = 0; i < passes.size(); i++)
|
||||||
for (auto &pass : passes)
|
|
||||||
{
|
|
||||||
required_images =
|
required_images =
|
||||||
max(required_images,
|
max(required_images,
|
||||||
pass->get_reflection().semantic_textures[SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY].size());
|
passes[i]->get_reflection().semantic_textures[
|
||||||
}
|
SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY].size());
|
||||||
|
|
||||||
if (required_images < 2)
|
if (required_images < 2)
|
||||||
{
|
{
|
||||||
@ -1976,10 +1985,8 @@ bool gl_core_filter_chain::init_history()
|
|||||||
original_history.reserve(required_images);
|
original_history.reserve(required_images);
|
||||||
common.original_history.resize(required_images);
|
common.original_history.resize(required_images);
|
||||||
|
|
||||||
for (unsigned i = 0; i < required_images; i++)
|
for (i = 0; i < required_images; i++)
|
||||||
{
|
|
||||||
original_history.emplace_back(new gl_core::Framebuffer(0, 1));
|
original_history.emplace_back(new gl_core::Framebuffer(0, 1));
|
||||||
}
|
|
||||||
|
|
||||||
RARCH_LOG("[GLCore]: Using history of %u frames.\n", unsigned(required_images));
|
RARCH_LOG("[GLCore]: Using history of %u frames.\n", unsigned(required_images));
|
||||||
|
|
||||||
@ -1993,12 +2000,13 @@ bool gl_core_filter_chain::init_history()
|
|||||||
|
|
||||||
bool gl_core_filter_chain::init_feedback()
|
bool gl_core_filter_chain::init_feedback()
|
||||||
{
|
{
|
||||||
common.framebuffer_feedback.clear();
|
unsigned i;
|
||||||
|
|
||||||
bool use_feedbacks = false;
|
bool use_feedbacks = false;
|
||||||
|
|
||||||
|
common.framebuffer_feedback.clear();
|
||||||
|
|
||||||
/* Final pass cannot have feedback. */
|
/* Final pass cannot have feedback. */
|
||||||
for (unsigned i = 0; i < passes.size() - 1; i++)
|
for (i = 0; i < passes.size() - 1; i++)
|
||||||
{
|
{
|
||||||
bool use_feedback = false;
|
bool use_feedback = false;
|
||||||
for (auto &pass : passes)
|
for (auto &pass : passes)
|
||||||
@ -2085,9 +2093,12 @@ void gl_core_filter_chain::set_pass_info(unsigned pass, const gl_core_filter_cha
|
|||||||
|
|
||||||
void gl_core_filter_chain::set_num_passes(unsigned num_passes)
|
void gl_core_filter_chain::set_num_passes(unsigned num_passes)
|
||||||
{
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
pass_info.resize(num_passes);
|
pass_info.resize(num_passes);
|
||||||
passes.reserve(num_passes);
|
passes.reserve(num_passes);
|
||||||
for (unsigned i = 0; i < num_passes; i++)
|
|
||||||
|
for (i = 0; i < num_passes; i++)
|
||||||
{
|
{
|
||||||
passes.emplace_back(new gl_core::Pass(i + 1 == num_passes));
|
passes.emplace_back(new gl_core::Pass(i + 1 == num_passes));
|
||||||
passes.back()->set_common_resources(&common);
|
passes.back()->set_common_resources(&common);
|
||||||
@ -2107,10 +2118,12 @@ void gl_core_filter_chain::add_parameter(unsigned pass, unsigned index, const st
|
|||||||
|
|
||||||
bool gl_core_filter_chain::init()
|
bool gl_core_filter_chain::init()
|
||||||
{
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
if (!init_alias())
|
if (!init_alias())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (unsigned i = 0; i < passes.size(); i++)
|
for (i = 0; i < passes.size(); i++)
|
||||||
{
|
{
|
||||||
auto &pass = passes[i];
|
auto &pass = passes[i];
|
||||||
RARCH_LOG("[slang]: Building pass #%u (%s)\n", i,
|
RARCH_LOG("[slang]: Building pass #%u (%s)\n", i,
|
||||||
@ -2137,8 +2150,8 @@ void gl_core_filter_chain::set_input_texture(
|
|||||||
{
|
{
|
||||||
input_texture = texture;
|
input_texture = texture;
|
||||||
|
|
||||||
// Need a copy to remove padding.
|
/* Need a copy to remove padding.
|
||||||
// GL HW render interface in libretro is kinda garbage now ...
|
* GL HW render interface in libretro is kinda garbage now ... */
|
||||||
if (input_texture.padded_width != input_texture.width ||
|
if (input_texture.padded_width != input_texture.width ||
|
||||||
input_texture.padded_height != input_texture.height)
|
input_texture.padded_height != input_texture.height)
|
||||||
{
|
{
|
||||||
@ -2148,9 +2161,7 @@ void gl_core_filter_chain::set_input_texture(
|
|||||||
if (input_texture.width != copy_framebuffer->get_size().width ||
|
if (input_texture.width != copy_framebuffer->get_size().width ||
|
||||||
input_texture.height != copy_framebuffer->get_size().height ||
|
input_texture.height != copy_framebuffer->get_size().height ||
|
||||||
(input_texture.format != 0 && input_texture.format != copy_framebuffer->get_format()))
|
(input_texture.format != 0 && input_texture.format != copy_framebuffer->get_format()))
|
||||||
{
|
|
||||||
copy_framebuffer->set_size({ input_texture.width, input_texture.height }, input_texture.format);
|
copy_framebuffer->set_size({ input_texture.width, input_texture.height }, input_texture.format);
|
||||||
}
|
|
||||||
|
|
||||||
copy_framebuffer->copy_partial(common, input_texture.image,
|
copy_framebuffer->copy_partial(common, input_texture.image,
|
||||||
float(input_texture.width) / input_texture.padded_width,
|
float(input_texture.width) / input_texture.padded_width,
|
||||||
@ -2184,6 +2195,7 @@ static unique_ptr<gl_core::StaticTexture> gl_core_filter_chain_load_lut(
|
|||||||
gl_core_filter_chain *chain,
|
gl_core_filter_chain *chain,
|
||||||
const video_shader_lut *shader)
|
const video_shader_lut *shader)
|
||||||
{
|
{
|
||||||
|
GLuint tex = 0;
|
||||||
texture_image image = {};
|
texture_image image = {};
|
||||||
image.supports_rgba = true;
|
image.supports_rgba = true;
|
||||||
|
|
||||||
@ -2191,7 +2203,7 @@ static unique_ptr<gl_core::StaticTexture> gl_core_filter_chain_load_lut(
|
|||||||
return {};
|
return {};
|
||||||
|
|
||||||
unsigned levels = shader->mipmap ? gl_core::num_miplevels(image.width, image.height) : 1;
|
unsigned levels = shader->mipmap ? gl_core::num_miplevels(image.width, image.height) : 1;
|
||||||
GLuint tex = 0;
|
|
||||||
glGenTextures(1, &tex);
|
glGenTextures(1, &tex);
|
||||||
glBindTexture(GL_TEXTURE_2D, tex);
|
glBindTexture(GL_TEXTURE_2D, tex);
|
||||||
glTexStorage2D(GL_TEXTURE_2D, levels,
|
glTexStorage2D(GL_TEXTURE_2D, levels,
|
||||||
@ -2222,7 +2234,8 @@ static bool gl_core_filter_chain_load_luts(
|
|||||||
gl_core_filter_chain *chain,
|
gl_core_filter_chain *chain,
|
||||||
video_shader *shader)
|
video_shader *shader)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < shader->luts; i++)
|
unsigned i;
|
||||||
|
for (i = 0; i < shader->luts; i++)
|
||||||
{
|
{
|
||||||
auto image = gl_core_filter_chain_load_lut(chain, &shader->lut[i]);
|
auto image = gl_core_filter_chain_load_lut(chain, &shader->lut[i]);
|
||||||
if (!image)
|
if (!image)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user