gl: clean up uniform binding storage
This commit is contained in:
parent
2c8f2685f2
commit
d49fa5307a
|
@ -51,7 +51,7 @@ where
|
||||||
{
|
{
|
||||||
fn reflect(
|
fn reflect(
|
||||||
&mut self,
|
&mut self,
|
||||||
pass_number: u32,
|
pass_number: usize,
|
||||||
semantics: &ReflectSemantics,
|
semantics: &ReflectSemantics,
|
||||||
) -> Result<ShaderReflection, ShaderReflectError> {
|
) -> Result<ShaderReflection, ShaderReflectError> {
|
||||||
self.backend.reflect(pass_number, semantics)
|
self.backend.reflect(pass_number, semantics)
|
||||||
|
|
|
@ -46,7 +46,7 @@ pub enum ShaderReflectError {
|
||||||
#[error("vertx and fragment shader must have same binding")]
|
#[error("vertx and fragment shader must have same binding")]
|
||||||
MismatchedUniformBuffer { vertex: u32, fragment: u32 },
|
MismatchedUniformBuffer { vertex: u32, fragment: u32 },
|
||||||
#[error("filter chain is non causal")]
|
#[error("filter chain is non causal")]
|
||||||
NonCausalFilterChain { pass: u32, target: u32 },
|
NonCausalFilterChain { pass: usize, target: usize },
|
||||||
#[error("mismatched offset")]
|
#[error("mismatched offset")]
|
||||||
MismatchedOffset {
|
MismatchedOffset {
|
||||||
semantic: String,
|
semantic: String,
|
||||||
|
|
|
@ -284,7 +284,7 @@ where
|
||||||
fn reflect_buffer_range_metas(
|
fn reflect_buffer_range_metas(
|
||||||
ast: &Ast<T>,
|
ast: &Ast<T>,
|
||||||
resource: &Resource,
|
resource: &Resource,
|
||||||
pass_number: u32,
|
pass_number: usize,
|
||||||
semantics: &ReflectSemantics,
|
semantics: &ReflectSemantics,
|
||||||
meta: &mut ReflectMeta,
|
meta: &mut ReflectMeta,
|
||||||
offset_type: impl Fn(usize) -> MemberOffset,
|
offset_type: impl Fn(usize) -> MemberOffset,
|
||||||
|
@ -478,7 +478,7 @@ where
|
||||||
fn reflect_texture_metas(
|
fn reflect_texture_metas(
|
||||||
&self,
|
&self,
|
||||||
texture: TextureData,
|
texture: TextureData,
|
||||||
pass_number: u32,
|
pass_number: usize,
|
||||||
semantics: &ReflectSemantics,
|
semantics: &ReflectSemantics,
|
||||||
meta: &mut ReflectMeta,
|
meta: &mut ReflectMeta,
|
||||||
) -> Result<(), ShaderReflectError> {
|
) -> Result<(), ShaderReflectError> {
|
||||||
|
@ -594,7 +594,7 @@ where
|
||||||
{
|
{
|
||||||
fn reflect(
|
fn reflect(
|
||||||
&mut self,
|
&mut self,
|
||||||
pass_number: u32,
|
pass_number: usize,
|
||||||
semantics: &ReflectSemantics,
|
semantics: &ReflectSemantics,
|
||||||
) -> Result<ShaderReflection, ShaderReflectError> {
|
) -> Result<ShaderReflection, ShaderReflectError> {
|
||||||
let vertex_res = self.vertex.get_shader_resources()?;
|
let vertex_res = self.vertex.get_shader_resources()?;
|
||||||
|
@ -707,19 +707,19 @@ impl CompileShader<GLSL> for CrossReflect<glsl::Target> {
|
||||||
for res in &vertex_resources.stage_inputs {
|
for res in &vertex_resources.stage_inputs {
|
||||||
let location = self.vertex.get_decoration(res.id, Decoration::Location)?;
|
let location = self.vertex.get_decoration(res.id, Decoration::Location)?;
|
||||||
self.vertex
|
self.vertex
|
||||||
.set_name(res.id, &format!("RARCH_ATTRIBUTE_{location}"))?;
|
.set_name(res.id, &format!("LIBRA_ATTRIBUTE_{location}"))?;
|
||||||
self.vertex.unset_decoration(res.id, Decoration::Location)?;
|
self.vertex.unset_decoration(res.id, Decoration::Location)?;
|
||||||
}
|
}
|
||||||
for res in &vertex_resources.stage_outputs {
|
for res in &vertex_resources.stage_outputs {
|
||||||
let location = self.vertex.get_decoration(res.id, Decoration::Location)?;
|
let location = self.vertex.get_decoration(res.id, Decoration::Location)?;
|
||||||
self.vertex
|
self.vertex
|
||||||
.set_name(res.id, &format!("RARCH_VARYING_{location}"))?;
|
.set_name(res.id, &format!("LIBRA_VARYING_{location}"))?;
|
||||||
self.vertex.unset_decoration(res.id, Decoration::Location)?;
|
self.vertex.unset_decoration(res.id, Decoration::Location)?;
|
||||||
}
|
}
|
||||||
for res in &fragment_resources.stage_inputs {
|
for res in &fragment_resources.stage_inputs {
|
||||||
let location = self.fragment.get_decoration(res.id, Decoration::Location)?;
|
let location = self.fragment.get_decoration(res.id, Decoration::Location)?;
|
||||||
self.fragment
|
self.fragment
|
||||||
.set_name(res.id, &format!("RARCH_VARYING_{location}"))?;
|
.set_name(res.id, &format!("LIBRA_VARYING_{location}"))?;
|
||||||
self.fragment
|
self.fragment
|
||||||
.unset_decoration(res.id, Decoration::Location)?;
|
.unset_decoration(res.id, Decoration::Location)?;
|
||||||
}
|
}
|
||||||
|
@ -732,9 +732,9 @@ impl CompileShader<GLSL> for CrossReflect<glsl::Target> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
for res in &vertex_resources.push_constant_buffers {
|
for res in &vertex_resources.push_constant_buffers {
|
||||||
self.vertex.set_name(res.id, "RARCH_PUSH_VERTEX_INSTANCE")?;
|
self.vertex.set_name(res.id, "LIBRA_PUSH_VERTEX_INSTANCE")?;
|
||||||
self.vertex
|
self.vertex
|
||||||
.set_name(res.base_type_id, "RARCH_PUSH_VERTEX")?;
|
.set_name(res.base_type_id, "LIBRA_PUSH_VERTEX")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: options
|
// todo: options
|
||||||
|
@ -751,8 +751,8 @@ impl CompileShader<GLSL> for CrossReflect<glsl::Target> {
|
||||||
// if flatten {
|
// if flatten {
|
||||||
// self.vertex.flatten_buffer_block(res.id)?;
|
// self.vertex.flatten_buffer_block(res.id)?;
|
||||||
// }
|
// }
|
||||||
self.vertex.set_name(res.id, "RARCH_UBO_VERTEX_INSTANCE")?;
|
self.vertex.set_name(res.id, "LIBRA_UBO_VERTEX_INSTANCE")?;
|
||||||
self.vertex.set_name(res.base_type_id, "RARCH_UBO_VERTEX")?;
|
self.vertex.set_name(res.base_type_id, "LIBRA_UBO_VERTEX")?;
|
||||||
self.vertex
|
self.vertex
|
||||||
.unset_decoration(res.id, Decoration::DescriptorSet)?;
|
.unset_decoration(res.id, Decoration::DescriptorSet)?;
|
||||||
self.vertex.unset_decoration(res.id, Decoration::Binding)?;
|
self.vertex.unset_decoration(res.id, Decoration::Binding)?;
|
||||||
|
@ -767,9 +767,9 @@ impl CompileShader<GLSL> for CrossReflect<glsl::Target> {
|
||||||
}
|
}
|
||||||
for res in &fragment_resources.push_constant_buffers {
|
for res in &fragment_resources.push_constant_buffers {
|
||||||
self.fragment
|
self.fragment
|
||||||
.set_name(res.id, "RARCH_PUSH_FRAGMENT_INSTANCE")?;
|
.set_name(res.id, "LIBRA_PUSH_FRAGMENT_INSTANCE")?;
|
||||||
self.fragment
|
self.fragment
|
||||||
.set_name(res.base_type_id, "RARCH_PUSH_FRAGMENT")?;
|
.set_name(res.base_type_id, "LIBRA_PUSH_FRAGMENT")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if fragment_resources.uniform_buffers.len() > 1 {
|
if fragment_resources.uniform_buffers.len() > 1 {
|
||||||
|
@ -785,9 +785,9 @@ impl CompileShader<GLSL> for CrossReflect<glsl::Target> {
|
||||||
// self.fragment.flatten_buffer_block(res.id)?;
|
// self.fragment.flatten_buffer_block(res.id)?;
|
||||||
// }
|
// }
|
||||||
self.fragment
|
self.fragment
|
||||||
.set_name(res.id, "RARCH_UBO_FRAGMENT_INSTANCE")?;
|
.set_name(res.id, "LIBRA_UBO_FRAGMENT_INSTANCE")?;
|
||||||
self.fragment
|
self.fragment
|
||||||
.set_name(res.base_type_id, "RARCH_UBO_FRAGMENT")?;
|
.set_name(res.base_type_id, "LIBRA_UBO_FRAGMENT")?;
|
||||||
self.fragment
|
self.fragment
|
||||||
.unset_decoration(res.id, Decoration::DescriptorSet)?;
|
.unset_decoration(res.id, Decoration::DescriptorSet)?;
|
||||||
self.fragment
|
self.fragment
|
||||||
|
@ -798,7 +798,7 @@ impl CompileShader<GLSL> for CrossReflect<glsl::Target> {
|
||||||
for res in &fragment_resources.sampled_images {
|
for res in &fragment_resources.sampled_images {
|
||||||
let binding = self.fragment.get_decoration(res.id, Decoration::Binding)?;
|
let binding = self.fragment.get_decoration(res.id, Decoration::Binding)?;
|
||||||
self.fragment
|
self.fragment
|
||||||
.set_name(res.id, &format!("RARCH_TEXTURE_{binding}"))?;
|
.set_name(res.id, &format!("LIBRA_TEXTURE_{binding}"))?;
|
||||||
self.fragment
|
self.fragment
|
||||||
.unset_decoration(res.id, Decoration::DescriptorSet)?;
|
.unset_decoration(res.id, Decoration::DescriptorSet)?;
|
||||||
self.fragment
|
self.fragment
|
||||||
|
|
|
@ -13,7 +13,7 @@ pub mod semantics;
|
||||||
pub trait ReflectShader {
|
pub trait ReflectShader {
|
||||||
fn reflect(
|
fn reflect(
|
||||||
&mut self,
|
&mut self,
|
||||||
pass_number: u32,
|
pass_number: usize,
|
||||||
semantics: &ReflectSemantics,
|
semantics: &ReflectSemantics,
|
||||||
) -> Result<ShaderReflection, ShaderReflectError>;
|
) -> Result<ShaderReflection, ShaderReflectError>;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ impl TextureSemanticMap<UniformSemantic> for FxHashMap<String, UniformSemantic>
|
||||||
{
|
{
|
||||||
if semantics.is_array() {
|
if semantics.is_array() {
|
||||||
let index = &name[semantics.size_uniform_name().len()..];
|
let index = &name[semantics.size_uniform_name().len()..];
|
||||||
let Ok(index) = u32::from_str(index) else {
|
let Ok(index) = usize::from_str(index) else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
return Some(SemanticMap {
|
return Some(SemanticMap {
|
||||||
|
@ -101,7 +101,7 @@ impl TextureSemanticMap<UniformSemantic> for FxHashMap<String, SemanticMap<Textu
|
||||||
{
|
{
|
||||||
if semantics.is_array() {
|
if semantics.is_array() {
|
||||||
let index = &name[semantics.texture_name().len()..];
|
let index = &name[semantics.texture_name().len()..];
|
||||||
let Ok(index) = u32::from_str(index) else {return None};
|
let Ok(index) = usize::from_str(index) else {return None};
|
||||||
return Some(SemanticMap {
|
return Some(SemanticMap {
|
||||||
semantics: *semantics,
|
semantics: *semantics,
|
||||||
index,
|
index,
|
||||||
|
|
|
@ -5,6 +5,15 @@ pub const BASE_SEMANTICS_COUNT: usize = 5;
|
||||||
pub const MAX_BINDINGS_COUNT: u32 = 16;
|
pub const MAX_BINDINGS_COUNT: u32 = 16;
|
||||||
pub const MAX_PUSH_BUFFER_SIZE: u32 = 128;
|
pub const MAX_PUSH_BUFFER_SIZE: u32 = 128;
|
||||||
|
|
||||||
|
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Copy, Clone, Hash)]
|
||||||
|
pub enum UniformType {
|
||||||
|
MVP,
|
||||||
|
Size,
|
||||||
|
Unsigned,
|
||||||
|
Signed,
|
||||||
|
Float
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Copy, Clone, Hash)]
|
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Copy, Clone, Hash)]
|
||||||
#[repr(i32)]
|
#[repr(i32)]
|
||||||
pub enum VariableSemantics {
|
pub enum VariableSemantics {
|
||||||
|
@ -29,6 +38,17 @@ impl VariableSemantics {
|
||||||
index: ()
|
index: ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const fn binding_type(&self) -> UniformType {
|
||||||
|
match self {
|
||||||
|
VariableSemantics::MVP => UniformType::MVP,
|
||||||
|
VariableSemantics::Output => UniformType::Size,
|
||||||
|
VariableSemantics::FinalViewport => UniformType::Size,
|
||||||
|
VariableSemantics::FrameCount => UniformType::Unsigned,
|
||||||
|
VariableSemantics::FrameDirection => UniformType::Signed,
|
||||||
|
VariableSemantics::FloatParameter => UniformType::Float
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Copy, Clone, Hash)]
|
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Copy, Clone, Hash)]
|
||||||
|
@ -78,7 +98,7 @@ impl TextureSemantics {
|
||||||
!matches!(self, TextureSemantics::Original | TextureSemantics::Source)
|
!matches!(self, TextureSemantics::Original | TextureSemantics::Source)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn semantics(self, index: u32) -> SemanticMap<TextureSemantics, u32> {
|
pub const fn semantics(self, index: usize) -> SemanticMap<TextureSemantics> {
|
||||||
SemanticMap {
|
SemanticMap {
|
||||||
semantics: self,
|
semantics: self,
|
||||||
index
|
index
|
||||||
|
@ -95,7 +115,7 @@ pub trait ValidateTypeSemantics<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct SemanticMap<T, I=u32> {
|
pub struct SemanticMap<T, I=usize> {
|
||||||
pub semantics: T,
|
pub semantics: T,
|
||||||
pub index: I,
|
pub index: I,
|
||||||
}
|
}
|
||||||
|
@ -160,3 +180,28 @@ pub struct ShaderReflection {
|
||||||
pub push_constant: Option<PushReflection>,
|
pub push_constant: Option<PushReflection>,
|
||||||
pub meta: ReflectMeta,
|
pub meta: ReflectMeta,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait UniformMeta {
|
||||||
|
fn offset(&self) -> MemberOffset;
|
||||||
|
fn id(&self) -> &str;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UniformMeta for VariableMeta {
|
||||||
|
fn offset(&self) -> MemberOffset {
|
||||||
|
self.offset
|
||||||
|
}
|
||||||
|
|
||||||
|
fn id(&self) -> &str {
|
||||||
|
&self.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UniformMeta for TextureSizeMeta {
|
||||||
|
fn offset(&self) -> MemberOffset {
|
||||||
|
self.offset
|
||||||
|
}
|
||||||
|
|
||||||
|
fn id(&self) -> &str {
|
||||||
|
&self.id
|
||||||
|
}
|
||||||
|
}
|
66
librashader-runtime-gl/src/binding.rs
Normal file
66
librashader-runtime-gl/src/binding.rs
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
use std::borrow::Borrow;
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
|
use gl::types::GLint;
|
||||||
|
use librashader_reflect::reflect::semantics::{MemberOffset, SemanticMap, TextureSemantics, VariableSemantics};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum VariableLocation {
|
||||||
|
Ubo(UniformLocation<GLint>),
|
||||||
|
Push(UniformLocation<GLint>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VariableLocation {
|
||||||
|
pub fn location(&self) -> UniformLocation<GLint> {
|
||||||
|
match self {
|
||||||
|
VariableLocation::Ubo(l) | VariableLocation::Push(l) => *l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct UniformLocation<T> {
|
||||||
|
pub vertex: T,
|
||||||
|
pub fragment: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UniformLocation<GLint> {
|
||||||
|
pub fn is_fragment_valid(&self) -> bool {
|
||||||
|
self.fragment >= 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_vertex_valid(&self) -> bool {
|
||||||
|
self.vertex >= 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_valid(&self) -> bool {
|
||||||
|
self.is_fragment_valid() || self.is_vertex_valid()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub enum MemberLocation {
|
||||||
|
Offset(MemberOffset),
|
||||||
|
Uniform(UniformLocation<GLint>)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct TextureUnit<T>(T);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
|
||||||
|
pub enum UniformBinding {
|
||||||
|
Parameter(String),
|
||||||
|
SemanticVariable(VariableSemantics),
|
||||||
|
TextureSize(SemanticMap<TextureSemantics>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<VariableSemantics> for UniformBinding {
|
||||||
|
fn from(value: VariableSemantics) -> Self {
|
||||||
|
UniformBinding::SemanticVariable(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SemanticMap<TextureSemantics>> for UniformBinding {
|
||||||
|
fn from(value: SemanticMap<TextureSemantics>) -> Self {
|
||||||
|
UniformBinding::TextureSize(value)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::borrow::Borrow;
|
||||||
use std::iter::Filter;
|
use std::iter::Filter;
|
||||||
use gl::types::{GLenum, GLint, GLsizei, GLsizeiptr, GLuint};
|
use gl::types::{GLenum, GLint, GLsizei, GLsizeiptr, GLuint};
|
||||||
use librashader_reflect::back::cross::GlslangGlslContext;
|
use librashader_reflect::back::cross::GlslangGlslContext;
|
||||||
|
@ -11,17 +12,18 @@ use librashader_presets::{Scale2D, ScaleType, Scaling, ShaderPassConfig, ShaderP
|
||||||
use librashader_reflect::reflect::semantics::{MemberOffset, SemanticMap, TextureImage, TextureSemantics, VariableMeta, VariableSemantics};
|
use librashader_reflect::reflect::semantics::{MemberOffset, SemanticMap, TextureImage, TextureSemantics, VariableMeta, VariableSemantics};
|
||||||
use crate::{FilterChain, FilterCommon};
|
use crate::{FilterChain, FilterCommon};
|
||||||
use crate::framebuffer::Framebuffer;
|
use crate::framebuffer::Framebuffer;
|
||||||
use crate::util::{Location, VariableLocation, RingBuffer, Size, GlImage, Texture, Viewport};
|
use crate::binding::{UniformBinding, UniformLocation, VariableLocation};
|
||||||
|
use crate::util::{GlImage, RingBuffer, Size, Texture, Viewport};
|
||||||
|
|
||||||
pub struct FilterPass {
|
pub struct FilterPass {
|
||||||
pub reflection: ShaderReflection,
|
pub reflection: ShaderReflection,
|
||||||
pub compiled: ShaderCompilerOutput<String, GlslangGlslContext>,
|
pub compiled: ShaderCompilerOutput<String, GlslangGlslContext>,
|
||||||
pub program: GLuint,
|
pub program: GLuint,
|
||||||
pub ubo_location: Location<GLuint>,
|
pub ubo_location: UniformLocation<GLuint>,
|
||||||
pub ubo_ring: Option<RingBuffer<GLuint, 16>>,
|
pub ubo_ring: Option<RingBuffer<GLuint, 16>>,
|
||||||
pub uniform_buffer: Box<[u8]>,
|
pub uniform_buffer: Box<[u8]>,
|
||||||
pub push_buffer: Box<[u8]>,
|
pub push_buffer: Box<[u8]>,
|
||||||
pub locations: FxHashMap<String, VariableLocation>,
|
pub variable_bindings: FxHashMap<UniformBinding, (VariableLocation, MemberOffset)>,
|
||||||
pub framebuffer: Framebuffer,
|
pub framebuffer: Framebuffer,
|
||||||
pub feedback_framebuffer: Framebuffer,
|
pub feedback_framebuffer: Framebuffer,
|
||||||
pub source: ShaderSource,
|
pub source: ShaderSource,
|
||||||
|
@ -34,7 +36,7 @@ impl FilterPass {
|
||||||
buffer.copy_from_slice(mvp);
|
buffer.copy_from_slice(mvp);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_vec4(location: Location<GLint>, buffer: &mut [u8], size: Size) {
|
fn build_vec4(location: UniformLocation<GLint>, buffer: &mut [u8], size: Size) {
|
||||||
let vec4 = [size.width as f32, size.height as f32, 1.0 / size.width as f32, 1.0/ size.height as f32];
|
let vec4 = [size.width as f32, size.height as f32, 1.0 / size.width as f32, 1.0/ size.height as f32];
|
||||||
if location.fragment >= 0 || location.vertex >= 0 {
|
if location.fragment >= 0 || location.vertex >= 0 {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -52,7 +54,7 @@ impl FilterPass {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn build_uniform<T>(location: Location<GLint>, buffer: &mut [u8], value: T, glfn: unsafe fn(GLint, T) -> ())
|
fn build_uniform<T>(location: UniformLocation<GLint>, buffer: &mut [u8], value: T, glfn: unsafe fn(GLint, T) -> ())
|
||||||
where T: Copy, T: bytemuck::Pod
|
where T: Copy, T: bytemuck::Pod
|
||||||
{
|
{
|
||||||
if location.fragment >= 0 || location.vertex >= 0 {
|
if location.fragment >= 0 || location.vertex >= 0 {
|
||||||
|
@ -70,19 +72,19 @@ impl FilterPass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_uint(location: Location<GLint>, buffer: &mut [u8], value: u32) {
|
fn build_uint(location: UniformLocation<GLint>, buffer: &mut [u8], value: u32) {
|
||||||
Self::build_uniform(location, buffer, value, gl::Uniform1ui)
|
Self::build_uniform(location, buffer, value, gl::Uniform1ui)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_sint(location: Location<GLint>, buffer: &mut [u8], value: i32) {
|
fn build_sint(location: UniformLocation<GLint>, buffer: &mut [u8], value: i32) {
|
||||||
Self::build_uniform(location, buffer, value, gl::Uniform1i)
|
Self::build_uniform(location, buffer, value, gl::Uniform1i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_float(location: Location<GLint>, buffer: &mut [u8], value: f32) {
|
fn build_float(location: UniformLocation<GLint>, buffer: &mut [u8], value: f32) {
|
||||||
Self::build_uniform(location, buffer, value, gl::Uniform1f)
|
Self::build_uniform(location, buffer, value, gl::Uniform1f)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_texture(binding: &TextureImage, texture: &Texture) {
|
fn bind_texture(binding: &TextureImage, texture: &Texture) {
|
||||||
unsafe {
|
unsafe {
|
||||||
// eprintln!("binding {} = texture {}", binding.binding, texture.image.handle);
|
// eprintln!("binding {} = texture {}", binding.binding, texture.image.handle);
|
||||||
gl::ActiveTexture((gl::TEXTURE0 + binding.binding) as GLenum);
|
gl::ActiveTexture((gl::TEXTURE0 + binding.binding) as GLenum);
|
||||||
|
@ -158,7 +160,8 @@ impl FilterPass {
|
||||||
size
|
size
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_commands(&mut self, parent: &FilterCommon, mvp: Option<&[f32]>, frame_count: u32, frame_direction: u32, viewport: &Viewport, original: &Texture, source: &Texture) {
|
// todo: fix rendertargets (i.e. non-final pass is internal, final pass is user provided fbo)
|
||||||
|
pub fn build_commands(&mut self, parent: &FilterCommon, mvp: Option<&[f32]>, frame_count: u32, frame_direction: i32, viewport: &Viewport, original: &Texture, source: &Texture) {
|
||||||
let mut fb_format = ShaderFormat::R8G8B8A8Unorm;
|
let mut fb_format = ShaderFormat::R8G8B8A8Unorm;
|
||||||
if self.config.srgb_framebuffer {
|
if self.config.srgb_framebuffer {
|
||||||
fb_format = ShaderFormat::R8G8B8A8Srgb;
|
fb_format = ShaderFormat::R8G8B8A8Srgb;
|
||||||
|
@ -247,134 +250,148 @@ impl FilterPass {
|
||||||
}
|
}
|
||||||
|
|
||||||
// framecount should be pre-modded
|
// framecount should be pre-modded
|
||||||
fn build_semantics(&mut self, parent: &FilterCommon, mvp: Option<&[f32]>, frame_count: u32, frame_direction: u32, fb_size: Size, viewport: &Viewport, original: &Texture, source: &Texture) {
|
fn build_semantics(&mut self, parent: &FilterCommon, mvp: Option<&[f32]>, frame_count: u32, frame_direction: i32, fb_size: Size, viewport: &Viewport, original: &Texture, source: &Texture) {
|
||||||
|
if let Some((_location, offset)) = self.variable_bindings.get(&VariableSemantics::MVP.into()) {
|
||||||
if let Some(variable) = self.reflection.meta.variable_meta.get(&VariableSemantics::MVP) {
|
let mvp = mvp.unwrap_or(&[
|
||||||
let mvp = mvp.unwrap_or(&[
|
2f32, 0.0, 0.0, 0.0,
|
||||||
2f32, 0.0, 0.0, 0.0,
|
0.0, 2.0, 0.0, 0.0,
|
||||||
0.0, 2.0, 0.0, 0.0,
|
0.0, 0.0, 2.0, 0.0,
|
||||||
0.0, 0.0, 2.0, 0.0,
|
-1.0, -1.0, 0.0, 1.0
|
||||||
-1.0, -1.0, 0.0, 1.0
|
]);
|
||||||
]);
|
let mvp_size = mvp.len() * std::mem::size_of::<f32>();
|
||||||
|
let (buffer, offset) = match offset {
|
||||||
let mvp_size = mvp.len() * std::mem::size_of::<f32>();
|
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset),
|
||||||
let (buffer, offset) = match variable.offset {
|
MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset)
|
||||||
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, offset),
|
};
|
||||||
MemberOffset::PushConstant(offset) => (&mut self.push_buffer, offset)
|
FilterPass::build_mvp(&mut buffer[offset..][..mvp_size], mvp)
|
||||||
};
|
|
||||||
FilterPass::build_mvp(&mut buffer[offset..][..mvp_size], mvp)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(variable) = self.reflection.meta.variable_meta.get(&VariableSemantics::Output) {
|
if let Some((location, offset)) = self.variable_bindings.get(&VariableSemantics::Output.into()) {
|
||||||
let location = self.locations.get(&variable.id).expect("variable did not have location mapped").location();
|
let (buffer, offset) = match offset {
|
||||||
let (buffer, offset) = match variable.offset {
|
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset),
|
||||||
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, offset),
|
MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset)
|
||||||
MemberOffset::PushConstant(offset) => (&mut self.push_buffer, offset)
|
|
||||||
};
|
|
||||||
FilterPass::build_vec4(location, &mut buffer[offset..][..4], fb_size)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(variable) = self.reflection.meta.variable_meta.get(&VariableSemantics::FinalViewport) {
|
|
||||||
// todo: do all variables have location..?
|
|
||||||
let location = self.locations.get(&variable.id).expect("variable did not have location mapped").location();
|
|
||||||
let (buffer, offset) = match variable.offset {
|
|
||||||
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, offset),
|
|
||||||
MemberOffset::PushConstant(offset) => (&mut self.push_buffer, offset)
|
|
||||||
};
|
|
||||||
FilterPass::build_vec4(location, &mut buffer[offset..][..4], viewport.size)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(variable) = self.reflection.meta.variable_meta.get(&VariableSemantics::FrameCount) {
|
|
||||||
// todo: do all variables have location..?
|
|
||||||
let location = self.locations.get(&variable.id).expect("variable did not have location mapped").location();
|
|
||||||
let (buffer, offset) = match variable.offset {
|
|
||||||
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, offset),
|
|
||||||
MemberOffset::PushConstant(offset) => (&mut self.push_buffer, offset)
|
|
||||||
};
|
|
||||||
FilterPass::build_uint(location, &mut buffer[offset..][..4], frame_count)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(variable) = self.reflection.meta.variable_meta.get(&VariableSemantics::FrameDirection) {
|
|
||||||
// todo: do all variables have location..?
|
|
||||||
let location = self.locations.get(&variable.id).expect("variable did not have location mapped").location();
|
|
||||||
let (buffer, offset) = match variable.offset {
|
|
||||||
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, offset),
|
|
||||||
MemberOffset::PushConstant(offset) => (&mut self.push_buffer, offset)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterPass::build_uint(location, &mut buffer[offset..][..4], frame_direction)
|
FilterPass::build_vec4(location.location(), &mut buffer[offset..][..4], fb_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some((location, offset)) = self.variable_bindings.get(&VariableSemantics::FinalViewport.into()) {
|
||||||
|
let (buffer, offset) = match offset {
|
||||||
|
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset),
|
||||||
|
MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset)
|
||||||
|
};
|
||||||
|
FilterPass::build_vec4(location.location(), &mut buffer[offset..][..4], viewport.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some((location, offset)) = self.variable_bindings.get(&VariableSemantics::FrameCount.into()) {
|
||||||
|
let (buffer, offset) = match offset {
|
||||||
|
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset),
|
||||||
|
MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset)
|
||||||
|
};
|
||||||
|
FilterPass::build_uint(location.location(), &mut buffer[offset..][..4], frame_count)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some((location, offset)) = self.variable_bindings.get(&VariableSemantics::FrameDirection.into()) {
|
||||||
|
let (buffer, offset) = match offset {
|
||||||
|
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset),
|
||||||
|
MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset)
|
||||||
|
};
|
||||||
|
FilterPass::build_sint(location.location(), &mut buffer[offset..][..4], frame_direction)
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(binding) = self.reflection.meta.texture_meta.get(&TextureSemantics::Original.semantics(0)) {
|
if let Some(binding) = self.reflection.meta.texture_meta.get(&TextureSemantics::Original.semantics(0)) {
|
||||||
eprintln!("setting original binding to {}", binding.binding);
|
eprintln!("setting original binding to {}", binding.binding);
|
||||||
FilterPass::set_texture(binding, original);
|
FilterPass::bind_texture(binding, original);
|
||||||
}
|
}
|
||||||
if let Some(variable) = self.reflection.meta.texture_size_meta.get(&TextureSemantics::Original.semantics(0)) {
|
|
||||||
let location = self.locations.get(&variable.id).expect("variable did not have location mapped").location();
|
if let Some((location, offset)) = self.variable_bindings.get(&TextureSemantics::Original.semantics(0).into()) {
|
||||||
let (buffer, offset) = match variable.offset {
|
let (buffer, offset) = match offset {
|
||||||
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, offset),
|
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset),
|
||||||
MemberOffset::PushConstant(offset) => (&mut self.push_buffer, offset)
|
MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset)
|
||||||
};
|
};
|
||||||
FilterPass::build_vec4(location, &mut buffer[offset..][..4], original.image.size);
|
FilterPass::build_vec4(location.location(), &mut buffer[offset..][..4], original.image.size);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if let Some(binding) = self.reflection.meta.texture_meta.get(&TextureSemantics::Source.semantics(0)) {
|
if let Some(binding) = self.reflection.meta.texture_meta.get(&TextureSemantics::Source.semantics(0)) {
|
||||||
// eprintln!("setting source binding to {}", binding.binding);
|
// eprintln!("setting source binding to {}", binding.binding);
|
||||||
FilterPass::set_texture(binding, source);
|
FilterPass::bind_texture(binding, source);
|
||||||
}
|
}
|
||||||
if let Some(variable) = self.reflection.meta.texture_size_meta.get(&TextureSemantics::Source.semantics(0)) {
|
if let Some((location, offset)) = self.variable_bindings.get(&TextureSemantics::Source.semantics(0).into()) {
|
||||||
let location = self.locations.get(&variable.id).expect("variable did not have location mapped").location();
|
let (buffer, offset) = match offset {
|
||||||
let (buffer, offset) = match variable.offset {
|
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset),
|
||||||
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, offset),
|
MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset)
|
||||||
MemberOffset::PushConstant(offset) => (&mut self.push_buffer, offset)
|
|
||||||
};
|
};
|
||||||
FilterPass::build_vec4(location, &mut buffer[offset..][..4], source.image.size);
|
FilterPass::build_vec4(location.location(), &mut buffer[offset..][..4], source.image.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// // todo: history
|
||||||
// todo: history
|
//
|
||||||
|
// // if let Some(binding) = self.reflection.meta.texture_meta.get(&TextureSemantics::OriginalHistory.semantics(0)) {
|
||||||
// if let Some(binding) = self.reflection.meta.texture_meta.get(&TextureSemantics::OriginalHistory.semantics(0)) {
|
// // FilterPass::set_texture(binding, original);
|
||||||
// FilterPass::set_texture(binding, original);
|
// // }
|
||||||
// }
|
// // if let Some(variable) = self.reflection.meta.texture_size_meta.get(&TextureSemantics::OriginalHistory.semantics(0)) {
|
||||||
// if let Some(variable) = self.reflection.meta.texture_size_meta.get(&TextureSemantics::OriginalHistory.semantics(0)) {
|
// // let location = self.locations.get(&variable.id).expect("variable did not have location mapped").location();
|
||||||
// let location = self.locations.get(&variable.id).expect("variable did not have location mapped").location();
|
// // let (buffer, offset) = match variable.offset {
|
||||||
// let (buffer, offset) = match variable.offset {
|
// // MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, offset),
|
||||||
// MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, offset),
|
// // MemberOffset::PushConstant(offset) => (&mut self.push_buffer, offset)
|
||||||
// MemberOffset::PushConstant(offset) => (&mut self.push_buffer, offset)
|
// // };
|
||||||
// };
|
// // FilterPass::build_vec4(location, &mut buffer[offset..][..4], original.image.size);
|
||||||
// FilterPass::build_vec4(location, &mut buffer[offset..][..4], original.image.size);
|
// // }
|
||||||
// }
|
//
|
||||||
|
for (id, (location, offset)) in self.variable_bindings.iter()
|
||||||
for variable in self.reflection.meta.parameter_meta.values() {
|
.filter_map(|(binding, value)| match binding {
|
||||||
let location = self.locations.get(&variable.id).expect("variable did not have location mapped").location();
|
UniformBinding::Parameter(id) => {
|
||||||
let (buffer, offset) = match variable.offset {
|
Some((id, value))
|
||||||
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, offset),
|
}
|
||||||
MemberOffset::PushConstant(offset) => (&mut self.push_buffer, offset)
|
_ => None
|
||||||
|
})
|
||||||
|
{
|
||||||
|
let id = id.as_str();
|
||||||
|
let (buffer, offset) = match offset {
|
||||||
|
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset),
|
||||||
|
MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset)
|
||||||
};
|
};
|
||||||
|
|
||||||
// presets override params
|
// presets override params
|
||||||
let default = self.source.parameters.iter().find(|&p| p.id == variable.id)
|
let default = self.source.parameters.iter().find(|&p| p.id == id)
|
||||||
.map(|f| f.initial)
|
.map(|f| f.initial)
|
||||||
.unwrap_or(0f32);
|
.unwrap_or(0f32);
|
||||||
|
|
||||||
let value = parent.preset.parameters.iter().find(|&p| p.name == variable.id)
|
let value = parent.preset.parameters.iter().find(|&p| p.name == id)
|
||||||
.map(|p| p.value)
|
.map(|p| p.value)
|
||||||
.unwrap_or(default);
|
.unwrap_or(default);
|
||||||
|
|
||||||
FilterPass::build_float(location, &mut buffer[offset..][..4], value)
|
FilterPass::build_float(location.location(), &mut buffer[offset..][..4], value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: deal with both lut name and index
|
for (id, (location, offset)) in self.variable_bindings.iter()
|
||||||
// for (index, lut) in parent.luts.values().enumerate() {
|
.filter_map(|(binding, value)| match binding {
|
||||||
// // todo: sort out order
|
UniformBinding::TextureSize(semantics) => {
|
||||||
// if let Some(variable) = self.reflection.meta.texture_size_meta.get(&TextureSemantics::User.semantics(index as u32)) {
|
if semantics.semantics == TextureSemantics::User {
|
||||||
// }
|
Some((semantics, value))
|
||||||
//
|
} else {
|
||||||
// }
|
None
|
||||||
// todo history
|
}
|
||||||
|
}
|
||||||
|
_ => None
|
||||||
|
})
|
||||||
|
{
|
||||||
|
let (buffer, offset) = match offset {
|
||||||
|
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset),
|
||||||
|
MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset)
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(lut) = parent.luts.get(&id.index) {
|
||||||
|
if let Some(binding) = self.reflection.meta.texture_meta.get(&id) {
|
||||||
|
FilterPass::bind_texture(binding, lut);
|
||||||
|
}
|
||||||
|
|
||||||
|
FilterPass::build_vec4(location.location(), &mut buffer[offset..][..4],
|
||||||
|
lut.image.size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// // todo history
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,6 +5,7 @@ mod filter;
|
||||||
mod filter_pass;
|
mod filter_pass;
|
||||||
mod util;
|
mod util;
|
||||||
mod framebuffer;
|
mod framebuffer;
|
||||||
|
mod binding;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
@ -26,9 +27,11 @@ use librashader_reflect::back::targets::{FromCompilation, GLSL};
|
||||||
use librashader_reflect::front::shaderc::GlslangCompilation;
|
use librashader_reflect::front::shaderc::GlslangCompilation;
|
||||||
use librashader_reflect::reflect::cross::CrossReflect;
|
use librashader_reflect::reflect::cross::CrossReflect;
|
||||||
use librashader_reflect::reflect::{ReflectSemantics, ReflectShader, ShaderReflection, UniformSemantic};
|
use librashader_reflect::reflect::{ReflectSemantics, ReflectShader, ShaderReflection, UniformSemantic};
|
||||||
use librashader_reflect::reflect::semantics::{MemberOffset, SemanticMap, TextureSemantics, VariableMeta, VariableSemantics};
|
use librashader_reflect::reflect::semantics::{MemberOffset, SemanticMap, TextureSemantics, UniformMeta, VariableMeta, VariableSemantics};
|
||||||
use librashader_reflect::reflect::{TextureSemanticMap, VariableSemanticMap};
|
use librashader_reflect::reflect::{TextureSemanticMap, VariableSemanticMap};
|
||||||
use util::{Location, VariableLocation, RingBuffer, Size, GlImage, Texture, Viewport};
|
use binding::{UniformLocation, VariableLocation};
|
||||||
|
use util::{GlImage, RingBuffer, Size, Texture, Viewport};
|
||||||
|
use crate::binding::UniformBinding;
|
||||||
|
|
||||||
unsafe fn gl_compile_shader(stage: GLenum, source: &str) -> GLuint {
|
unsafe fn gl_compile_shader(stage: GLenum, source: &str) -> GLuint {
|
||||||
let shader = gl::CreateShader(stage);
|
let shader = gl::CreateShader(stage);
|
||||||
|
@ -63,7 +66,7 @@ impl FilterChain {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let index = config.id as u32;
|
let index = config.id as usize;
|
||||||
|
|
||||||
// PassOutput
|
// PassOutput
|
||||||
texture_semantics.insert(alias.clone(), SemanticMap {
|
texture_semantics.insert(alias.clone(), SemanticMap {
|
||||||
|
@ -86,31 +89,31 @@ impl FilterChain {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reflect_parameter(pipeline: GLuint, meta: &VariableMeta) -> VariableLocation {
|
fn reflect_uniform_location(pipeline: GLuint, meta: &impl UniformMeta) -> VariableLocation {
|
||||||
// todo: support both ubo and pushco
|
// todo: support both ubo and pushco
|
||||||
// todo: fix this.
|
// todo: fix this.
|
||||||
match meta.offset {
|
match meta.offset() {
|
||||||
MemberOffset::Ubo(_) => {
|
MemberOffset::Ubo(_) => {
|
||||||
let vert_name = format!("RARCH_UBO_VERTEX_INSTANCE.{}\0", meta.id);
|
let vert_name = format!("LIBRA_UBO_VERTEX_INSTANCE.{}\0", meta.id());
|
||||||
let frag_name = format!("RARCH_UBO_FRAGMENT_INSTANCE.{}\0", meta.id);
|
let frag_name = format!("LIBRA_UBO_FRAGMENT_INSTANCE.{}\0", meta.id());
|
||||||
unsafe {
|
unsafe {
|
||||||
let vertex = gl::GetUniformLocation(pipeline, vert_name.as_ptr().cast());
|
let vertex = gl::GetUniformLocation(pipeline, vert_name.as_ptr().cast());
|
||||||
let fragment = gl::GetUniformLocation(pipeline, frag_name.as_ptr().cast());
|
let fragment = gl::GetUniformLocation(pipeline, frag_name.as_ptr().cast());
|
||||||
|
|
||||||
VariableLocation::Ubo(Location {
|
VariableLocation::Ubo(UniformLocation {
|
||||||
vertex,
|
vertex,
|
||||||
fragment
|
fragment
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MemberOffset::PushConstant(_) => {
|
MemberOffset::PushConstant(_) => {
|
||||||
let vert_name = format!("RARCH_PUSH_VERTEX_INSTANCE.{}\0", meta.id);
|
let vert_name = format!("LIBRA_PUSH_VERTEX_INSTANCE.{}\0", meta.id());
|
||||||
let frag_name = format!("RARCH_PUSH_FRAGMENT_INSTANCE.{}\0", meta.id);
|
let frag_name = format!("LIBRA_PUSH_FRAGMENT_INSTANCE.{}\0", meta.id());
|
||||||
unsafe {
|
unsafe {
|
||||||
let vertex = gl::GetUniformLocation(pipeline, vert_name.as_ptr().cast());
|
let vertex = gl::GetUniformLocation(pipeline, vert_name.as_ptr().cast());
|
||||||
let fragment = gl::GetUniformLocation(pipeline, frag_name.as_ptr().cast());
|
let fragment = gl::GetUniformLocation(pipeline, frag_name.as_ptr().cast());
|
||||||
|
|
||||||
VariableLocation::Push(Location {
|
VariableLocation::Push(UniformLocation {
|
||||||
vertex,
|
vertex,
|
||||||
fragment
|
fragment
|
||||||
})
|
})
|
||||||
|
@ -133,7 +136,7 @@ pub struct FilterCommon {
|
||||||
original_history: Vec<Framebuffer>,
|
original_history: Vec<Framebuffer>,
|
||||||
history: Vec<Texture>,
|
history: Vec<Texture>,
|
||||||
feedback: Vec<Texture>,
|
feedback: Vec<Texture>,
|
||||||
luts: FxHashMap<String, Texture>,
|
luts: FxHashMap<usize, Texture>,
|
||||||
pub quad_vbo: GLuint,
|
pub quad_vbo: GLuint,
|
||||||
pub input_framebuffer: Framebuffer,
|
pub input_framebuffer: Framebuffer,
|
||||||
}
|
}
|
||||||
|
@ -174,12 +177,12 @@ impl FilterChain {
|
||||||
for (index, texture) in preset.textures.iter().enumerate() {
|
for (index, texture) in preset.textures.iter().enumerate() {
|
||||||
texture_semantics.insert(texture.name.clone(), SemanticMap {
|
texture_semantics.insert(texture.name.clone(), SemanticMap {
|
||||||
semantics: TextureSemantics::User,
|
semantics: TextureSemantics::User,
|
||||||
index: index as u32
|
index
|
||||||
});
|
});
|
||||||
|
|
||||||
uniform_semantics.insert(format!("{}Size", texture.name), UniformSemantic::Texture(SemanticMap {
|
uniform_semantics.insert(format!("{}Size", texture.name), UniformSemantic::Texture(SemanticMap {
|
||||||
semantics: TextureSemantics::User,
|
semantics: TextureSemantics::User,
|
||||||
index: index as u32
|
index
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +197,7 @@ impl FilterChain {
|
||||||
for (index, (config, source, mut reflect)) in passes.into_iter().enumerate() {
|
for (index, (config, source, mut reflect)) in passes.into_iter().enumerate() {
|
||||||
let mut semantics = semantics.clone();
|
let mut semantics = semantics.clone();
|
||||||
|
|
||||||
let reflection = reflect.reflect(index as u32, &semantics)?;
|
let reflection = reflect.reflect(index, &semantics)?;
|
||||||
let glsl = reflect.compile(GlVersion::V4_60)?;
|
let glsl = reflect.compile(GlVersion::V4_60)?;
|
||||||
|
|
||||||
let vertex_resources = glsl.context.compiler.vertex.get_shader_resources()?;
|
let vertex_resources = glsl.context.compiler.vertex.get_shader_resources()?;
|
||||||
|
@ -210,7 +213,7 @@ impl FilterChain {
|
||||||
|
|
||||||
for res in &vertex_resources.stage_inputs {
|
for res in &vertex_resources.stage_inputs {
|
||||||
let loc = glsl.context.compiler.vertex.get_decoration(res.id, Decoration::Location)?;
|
let loc = glsl.context.compiler.vertex.get_decoration(res.id, Decoration::Location)?;
|
||||||
let loc_name = format!("RARCH_ATTRIBUTE_{loc}\0");
|
let loc_name = format!("LIBRA_ATTRIBUTE_{loc}\0");
|
||||||
eprintln!("{loc_name}");
|
eprintln!("{loc_name}");
|
||||||
gl::BindAttribLocation(program, loc, loc_name.as_str().as_ptr().cast())
|
gl::BindAttribLocation(program, loc, loc_name.as_str().as_ptr().cast())
|
||||||
}
|
}
|
||||||
|
@ -225,7 +228,7 @@ impl FilterChain {
|
||||||
}
|
}
|
||||||
|
|
||||||
for binding in &glsl.context.texture_fixups {
|
for binding in &glsl.context.texture_fixups {
|
||||||
let loc_name = format!("RARCH_TEXTURE_{}\0", *binding);
|
let loc_name = format!("LIBRA_TEXTURE_{}\0", *binding);
|
||||||
unsafe {
|
unsafe {
|
||||||
let location = gl::GetUniformLocation(program, loc_name.as_str().as_ptr().cast());
|
let location = gl::GetUniformLocation(program, loc_name.as_str().as_ptr().cast());
|
||||||
if location >= 0 {
|
if location >= 0 {
|
||||||
|
@ -236,9 +239,9 @@ impl FilterChain {
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::UseProgram(0);
|
gl::UseProgram(0);
|
||||||
(program, Location {
|
(program, UniformLocation {
|
||||||
vertex: gl::GetUniformBlockIndex(program, b"RARCH_UBO_VERTEX\0".as_ptr().cast()),
|
vertex: gl::GetUniformBlockIndex(program, b"LIBRA_UBO_VERTEX\0".as_ptr().cast()),
|
||||||
fragment: gl::GetUniformBlockIndex(program, b"RARCH_UBO_FRAGMENT\0".as_ptr().cast()),
|
fragment: gl::GetUniformBlockIndex(program, b"LIBRA_UBO_FRAGMENT\0".as_ptr().cast()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -265,13 +268,21 @@ impl FilterChain {
|
||||||
// todo: reflect indexed parameters
|
// todo: reflect indexed parameters
|
||||||
let mut locations = FxHashMap::default();
|
let mut locations = FxHashMap::default();
|
||||||
for param in reflection.meta.parameter_meta.values() {
|
for param in reflection.meta.parameter_meta.values() {
|
||||||
locations.insert(param.id.clone(), FilterChain::reflect_parameter(program, param));
|
locations.insert(UniformBinding::Parameter(param.id.clone()),
|
||||||
|
(FilterChain::reflect_uniform_location(program, param), param.offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
for param in reflection.meta.variable_meta.values() {
|
for (semantics, param) in &reflection.meta.variable_meta {
|
||||||
locations.insert(param.id.clone(), FilterChain::reflect_parameter(program, param));
|
locations.insert(UniformBinding::SemanticVariable(semantics.clone()),
|
||||||
|
(FilterChain::reflect_uniform_location(program, param), param.offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (semantics, param) in &reflection.meta.texture_size_meta {
|
||||||
|
locations.insert(UniformBinding::TextureSize(semantics.clone()),
|
||||||
|
(FilterChain::reflect_uniform_location(program, param), param.offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// eprintln!("{:#?}", semantics);
|
// eprintln!("{:#?}", semantics);
|
||||||
eprintln!("{:#?}", reflection.meta);
|
eprintln!("{:#?}", reflection.meta);
|
||||||
|
@ -290,7 +301,7 @@ impl FilterChain {
|
||||||
ubo_ring,
|
ubo_ring,
|
||||||
uniform_buffer,
|
uniform_buffer,
|
||||||
push_buffer,
|
push_buffer,
|
||||||
locations,
|
variable_bindings: locations,
|
||||||
source,
|
source,
|
||||||
// no idea if this works.
|
// no idea if this works.
|
||||||
// retroarch checks if feedback frames are used but we'll just init it tbh.
|
// retroarch checks if feedback frames are used but we'll just init it tbh.
|
||||||
|
@ -323,7 +334,7 @@ impl FilterChain {
|
||||||
// load luts
|
// load luts
|
||||||
let mut luts = FxHashMap::default();
|
let mut luts = FxHashMap::default();
|
||||||
|
|
||||||
for texture in &preset.textures {
|
for (index, texture) in preset.textures.iter().enumerate() {
|
||||||
let image = Image::load(&texture.path)?;
|
let image = Image::load(&texture.path)?;
|
||||||
let levels = if texture.mipmap {
|
let levels = if texture.mipmap {
|
||||||
util::calc_miplevel(image.width, image.height)
|
util::calc_miplevel(image.width, image.height)
|
||||||
|
@ -374,7 +385,7 @@ impl FilterChain {
|
||||||
gl::BindTexture(gl::TEXTURE_2D, 0);
|
gl::BindTexture(gl::TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
luts.insert(texture.name.clone(), Texture {
|
luts.insert(index, Texture {
|
||||||
image: GlImage {
|
image: GlImage {
|
||||||
handle,
|
handle,
|
||||||
format: gl::RGBA8,
|
format: gl::RGBA8,
|
||||||
|
|
|
@ -1,26 +1,6 @@
|
||||||
use gl::types::{GLenum, GLint, GLuint};
|
use gl::types::{GLenum, GLint, GLuint};
|
||||||
use librashader::{FilterMode, WrapMode};
|
use librashader::{FilterMode, WrapMode};
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub struct Location<T> {
|
|
||||||
pub vertex: T,
|
|
||||||
pub fragment: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum VariableLocation {
|
|
||||||
Ubo(Location<GLint>),
|
|
||||||
Push(Location<GLint>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl VariableLocation {
|
|
||||||
pub fn location(&self) -> Location<GLint> {
|
|
||||||
match self {
|
|
||||||
VariableLocation::Ubo(l) | VariableLocation::Push(l) => *l
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn calc_miplevel(width: u32, height: u32) -> u32 {
|
pub fn calc_miplevel(width: u32, height: u32) -> u32 {
|
||||||
let mut size = std::cmp::max(width, height);
|
let mut size = std::cmp::max(width, height);
|
||||||
let mut levels = 0;
|
let mut levels = 0;
|
||||||
|
|
Loading…
Reference in a new issue