gl: cleanup and refactor
- allow frame and filterchain init to take optional config object by caller - allow binding MVP as a uniform
This commit is contained in:
parent
964da02c39
commit
9e2c914e57
|
@ -392,7 +392,7 @@ impl FilterChain {
|
||||||
|
|
||||||
let semantics = ReflectSemantics {
|
let semantics = ReflectSemantics {
|
||||||
uniform_semantics,
|
uniform_semantics,
|
||||||
non_uniform_semantics: texture_semantics,
|
texture_semantics: texture_semantics,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((passes, semantics))
|
Ok((passes, semantics))
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
use gl::types::GLint;
|
use gl::types::GLint;
|
||||||
use librashader_reflect::reflect::semantics::{
|
use librashader_reflect::reflect::semantics::{BindingStage, MemberOffset};
|
||||||
MemberOffset, SemanticMap, TextureSemantics, VariableSemantics,
|
|
||||||
};
|
|
||||||
use std::hash::Hash;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum VariableLocation {
|
pub enum VariableLocation {
|
||||||
|
@ -25,24 +22,22 @@ pub struct UniformLocation<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UniformLocation<GLint> {
|
impl UniformLocation<GLint> {
|
||||||
pub fn is_fragment_valid(&self) -> bool {
|
// pub fn is_fragment_valid(&self) -> bool {
|
||||||
self.fragment >= 0
|
// self.fragment >= 0
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
// pub fn is_vertex_valid(&self) -> bool {
|
||||||
|
// self.vertex >= 0
|
||||||
|
// }
|
||||||
|
|
||||||
pub fn is_vertex_valid(&self) -> bool {
|
pub fn is_valid(&self, stage: BindingStage) -> bool {
|
||||||
self.vertex >= 0
|
let mut validity = false;
|
||||||
|
if stage.contains(BindingStage::FRAGMENT) {
|
||||||
|
validity = validity || self.fragment >= 0;
|
||||||
}
|
}
|
||||||
|
if stage.contains(BindingStage::VERTEX) {
|
||||||
pub fn is_valid(&self) -> bool {
|
validity = validity || self.vertex >= 0;
|
||||||
self.is_fragment_valid() || self.is_vertex_valid()
|
}
|
||||||
|
validity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub enum MemberLocation {
|
|
||||||
Offset(MemberOffset),
|
|
||||||
Uniform(UniformLocation<GLint>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub struct TextureUnit<T>(T);
|
|
||||||
|
|
|
@ -4,10 +4,10 @@ use crate::framebuffer::{Framebuffer, GlImage, Viewport};
|
||||||
use crate::quad_render::DrawQuad;
|
use crate::quad_render::DrawQuad;
|
||||||
use crate::render_target::RenderTarget;
|
use crate::render_target::RenderTarget;
|
||||||
use crate::util;
|
use crate::util;
|
||||||
use crate::util::{gl_get_version, InlineRingBuffer};
|
use crate::util::{gl_get_version, gl_u16_to_version, InlineRingBuffer};
|
||||||
use crate::error::{FilterChainError, Result};
|
use crate::error::{FilterChainError, Result};
|
||||||
|
|
||||||
use gl::types::{GLenum, GLint, GLsizei, GLsizeiptr, GLuint};
|
use gl::types::{GLint, GLsizei, GLsizeiptr, GLuint};
|
||||||
use librashader_common::image::Image;
|
use librashader_common::image::Image;
|
||||||
use librashader_common::{FilterMode, Size, WrapMode};
|
use librashader_common::{FilterMode, Size, WrapMode};
|
||||||
use librashader_preprocess::ShaderSource;
|
use librashader_preprocess::ShaderSource;
|
||||||
|
@ -22,6 +22,7 @@ use std::collections::VecDeque;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use librashader_reflect::back::{CompilerBackend, CompileShader, FromCompilation};
|
use librashader_reflect::back::{CompilerBackend, CompileShader, FromCompilation};
|
||||||
use librashader_reflect::front::shaderc::GlslangCompilation;
|
use librashader_reflect::front::shaderc::GlslangCompilation;
|
||||||
|
use crate::options::{FilterChainOptions, FrameOptions};
|
||||||
use crate::samplers::SamplerSet;
|
use crate::samplers::SamplerSet;
|
||||||
use crate::texture::Texture;
|
use crate::texture::Texture;
|
||||||
|
|
||||||
|
@ -133,11 +134,14 @@ type ShaderPassMeta<'a> = (
|
||||||
|
|
||||||
impl FilterChain {
|
impl FilterChain {
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
pub fn load_from_preset(preset: ShaderPreset) -> Result<FilterChain> {
|
pub fn load_from_preset(preset: ShaderPreset, options: Option<&FilterChainOptions>) -> Result<FilterChain> {
|
||||||
let (passes, semantics) = FilterChain::load_preset(&preset)?;
|
let (passes, semantics) = FilterChain::load_preset(&preset)?;
|
||||||
|
|
||||||
|
let version = options.map(|o| gl_u16_to_version(o.gl_version))
|
||||||
|
.unwrap_or_else(|| gl_get_version());
|
||||||
|
|
||||||
// initialize passes
|
// initialize passes
|
||||||
let filters = FilterChain::init_passes(passes, &semantics)?;
|
let filters = FilterChain::init_passes(version, passes, &semantics)?;
|
||||||
|
|
||||||
let default_filter = filters.first().map(|f| f.config.filter).unwrap_or_default();
|
let default_filter = filters.first().map(|f| f.config.filter).unwrap_or_default();
|
||||||
let default_wrap = filters
|
let default_wrap = filters
|
||||||
|
@ -160,7 +164,7 @@ impl FilterChain {
|
||||||
feedback_textures.resize_with(filters.len(), Texture::default);
|
feedback_textures.resize_with(filters.len(), Texture::default);
|
||||||
|
|
||||||
// load luts
|
// load luts
|
||||||
let luts = FilterChain::load_luts(&samplers, &preset.textures)?;
|
let luts = FilterChain::load_luts(&preset.textures)?;
|
||||||
|
|
||||||
let (history_framebuffers, history_textures) =
|
let (history_framebuffers, history_textures) =
|
||||||
FilterChain::init_history(&filters, default_filter, default_wrap);
|
FilterChain::init_history(&filters, default_filter, default_wrap);
|
||||||
|
@ -194,10 +198,10 @@ impl FilterChain {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load the shader preset at the given path into a filter chain.
|
/// Load the shader preset at the given path into a filter chain.
|
||||||
pub fn load_from_path(path: impl AsRef<Path>) -> Result<FilterChain> {
|
pub fn load_from_path(path: impl AsRef<Path>, options: Option<&FilterChainOptions>) -> Result<FilterChain> {
|
||||||
// load passes from preset
|
// load passes from preset
|
||||||
let preset = ShaderPreset::try_parse(path)?;
|
let preset = ShaderPreset::try_parse(path)?;
|
||||||
Self::load_from_preset(preset)
|
Self::load_from_preset(preset, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_preset(
|
fn load_preset(
|
||||||
|
@ -260,13 +264,13 @@ impl FilterChain {
|
||||||
|
|
||||||
let semantics = ReflectSemantics {
|
let semantics = ReflectSemantics {
|
||||||
uniform_semantics,
|
uniform_semantics,
|
||||||
non_uniform_semantics: texture_semantics,
|
texture_semantics,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((passes, semantics))
|
Ok((passes, semantics))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_luts(samplers: &SamplerSet, textures: &[TextureConfig]) -> Result<FxHashMap<usize, Texture>> {
|
fn load_luts(textures: &[TextureConfig]) -> Result<FxHashMap<usize, Texture>> {
|
||||||
let mut luts = FxHashMap::default();
|
let mut luts = FxHashMap::default();
|
||||||
|
|
||||||
for (index, texture) in textures.iter().enumerate() {
|
for (index, texture) in textures.iter().enumerate() {
|
||||||
|
@ -305,10 +309,6 @@ impl FilterChain {
|
||||||
);
|
);
|
||||||
|
|
||||||
let mipmap = levels > 1;
|
let mipmap = levels > 1;
|
||||||
// let linear = texture.filter_mode == FilterMode::Linear;
|
|
||||||
|
|
||||||
// set mipmaps and wrapping
|
|
||||||
|
|
||||||
if mipmap {
|
if mipmap {
|
||||||
gl::GenerateMipmap(gl::TEXTURE_2D);
|
gl::GenerateMipmap(gl::TEXTURE_2D);
|
||||||
}
|
}
|
||||||
|
@ -335,6 +335,7 @@ impl FilterChain {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_passes(
|
fn init_passes(
|
||||||
|
version: GlVersion,
|
||||||
passes: Vec<ShaderPassMeta>,
|
passes: Vec<ShaderPassMeta>,
|
||||||
semantics: &ReflectSemantics,
|
semantics: &ReflectSemantics,
|
||||||
) -> Result<Box<[FilterPass]>> {
|
) -> Result<Box<[FilterPass]>> {
|
||||||
|
@ -343,7 +344,7 @@ impl FilterChain {
|
||||||
// initialize passes
|
// initialize passes
|
||||||
for (index, (config, source, mut reflect)) in passes.into_iter().enumerate() {
|
for (index, (config, source, mut reflect)) in passes.into_iter().enumerate() {
|
||||||
let reflection = reflect.reflect(index, semantics)?;
|
let reflection = reflect.reflect(index, semantics)?;
|
||||||
let glsl = reflect.compile(gl_get_version())?;
|
let glsl = reflect.compile(version)?;
|
||||||
|
|
||||||
let vertex_resources = glsl.context.compiler.vertex.get_shader_resources()?;
|
let vertex_resources = glsl.context.compiler.vertex.get_shader_resources()?;
|
||||||
|
|
||||||
|
@ -444,7 +445,6 @@ impl FilterChain {
|
||||||
]
|
]
|
||||||
.into_boxed_slice();
|
.into_boxed_slice();
|
||||||
|
|
||||||
// todo: reflect indexed parameters
|
|
||||||
let mut uniform_bindings = FxHashMap::default();
|
let mut uniform_bindings = FxHashMap::default();
|
||||||
for param in reflection.meta.parameter_meta.values() {
|
for param in reflection.meta.parameter_meta.values() {
|
||||||
uniform_bindings.insert(
|
uniform_bindings.insert(
|
||||||
|
@ -571,12 +571,14 @@ impl FilterChain {
|
||||||
/// Process a frame with the input image.
|
/// Process a frame with the input image.
|
||||||
///
|
///
|
||||||
/// When this frame returns, GL_FRAMEBUFFER is bound to 0.
|
/// When this frame returns, GL_FRAMEBUFFER is bound to 0.
|
||||||
pub fn frame(&mut self, count: usize, viewport: &Viewport, input: &GlImage, clear: bool) -> Result<()> {
|
pub fn frame(&mut self, count: usize, viewport: &Viewport, input: &GlImage, options: Option<&FrameOptions>) -> Result<()> {
|
||||||
if clear {
|
if let Some(options) = options {
|
||||||
|
if options.clear_history {
|
||||||
for framebuffer in &self.history_framebuffers {
|
for framebuffer in &self.history_framebuffers {
|
||||||
framebuffer.clear()
|
framebuffer.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if self.passes.is_empty() {
|
if self.passes.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use gl::types::{GLenum, GLint, GLsizei, GLsizeiptr, GLuint};
|
use gl::types::{GLint, GLsizei, GLsizeiptr, GLuint};
|
||||||
use librashader_reflect::back::cross::GlslangGlslContext;
|
use librashader_reflect::back::cross::GlslangGlslContext;
|
||||||
use librashader_reflect::back::ShaderCompilerOutput;
|
use librashader_reflect::back::ShaderCompilerOutput;
|
||||||
use librashader_reflect::reflect::ShaderReflection;
|
use librashader_reflect::reflect::ShaderReflection;
|
||||||
|
@ -6,7 +6,7 @@ use librashader_reflect::reflect::ShaderReflection;
|
||||||
use librashader_common::{ShaderFormat, Size};
|
use librashader_common::{ShaderFormat, Size};
|
||||||
use librashader_preprocess::ShaderSource;
|
use librashader_preprocess::ShaderSource;
|
||||||
use librashader_presets::ShaderPassConfig;
|
use librashader_presets::ShaderPassConfig;
|
||||||
use librashader_reflect::reflect::semantics::{MemberOffset, TextureBinding, TextureSemantics, UniformBinding, VariableSemantics};
|
use librashader_reflect::reflect::semantics::{BindingStage, MemberOffset, TextureBinding, TextureSemantics, UniformBinding, VariableSemantics};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use crate::binding::{UniformLocation, VariableLocation};
|
use crate::binding::{UniformLocation, VariableLocation};
|
||||||
|
@ -31,19 +31,30 @@ pub struct FilterPass {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FilterPass {
|
impl FilterPass {
|
||||||
fn build_mvp(buffer: &mut [u8], mvp: &[f32]) {
|
fn build_mat4(location: UniformLocation<GLint>, buffer: &mut [u8], mvp: &[f32; 16]) {
|
||||||
|
if location.is_valid(BindingStage::VERTEX | BindingStage::FRAGMENT) {
|
||||||
|
unsafe {
|
||||||
|
if location.is_valid(BindingStage::VERTEX) {
|
||||||
|
gl::UniformMatrix4fv(location.vertex, 1, gl::FALSE, mvp.as_ptr());
|
||||||
|
}
|
||||||
|
if location.is_valid(BindingStage::FRAGMENT) {
|
||||||
|
gl::UniformMatrix4fv(location.fragment, 1, gl::FALSE, mvp.as_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
let mvp = bytemuck::cast_slice(mvp);
|
let mvp = bytemuck::cast_slice(mvp);
|
||||||
buffer.copy_from_slice(mvp);
|
buffer.copy_from_slice(mvp);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn build_vec4(location: UniformLocation<GLint>, buffer: &mut [u8], size: impl Into<[f32; 4]>) {
|
fn build_vec4(location: UniformLocation<GLint>, buffer: &mut [u8], size: impl Into<[f32; 4]>) {
|
||||||
let vec4 = size.into();
|
let vec4 = size.into();
|
||||||
if location.fragment >= 0 || location.vertex >= 0 {
|
if location.is_valid(BindingStage::VERTEX | BindingStage::FRAGMENT) {
|
||||||
unsafe {
|
unsafe {
|
||||||
if location.vertex >= 0 {
|
if location.is_valid(BindingStage::VERTEX) {
|
||||||
gl::Uniform4fv(location.vertex, 1, vec4.as_ptr());
|
gl::Uniform4fv(location.vertex, 1, vec4.as_ptr());
|
||||||
}
|
}
|
||||||
if location.fragment >= 0 {
|
if location.is_valid(BindingStage::FRAGMENT) {
|
||||||
gl::Uniform4fv(location.fragment, 1, vec4.as_ptr());
|
gl::Uniform4fv(location.fragment, 1, vec4.as_ptr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,12 +74,12 @@ impl FilterPass {
|
||||||
T: Copy,
|
T: Copy,
|
||||||
T: bytemuck::Pod,
|
T: bytemuck::Pod,
|
||||||
{
|
{
|
||||||
if location.fragment >= 0 || location.vertex >= 0 {
|
if location.is_valid(BindingStage::VERTEX | BindingStage::FRAGMENT) {
|
||||||
unsafe {
|
unsafe {
|
||||||
if location.vertex >= 0 {
|
if location.is_valid(BindingStage::VERTEX) {
|
||||||
glfn(location.vertex, value);
|
glfn(location.vertex, value);
|
||||||
}
|
}
|
||||||
if location.fragment >= 0 {
|
if location.is_valid(BindingStage::FRAGMENT) {
|
||||||
glfn(location.fragment, value);
|
glfn(location.fragment, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,7 +174,7 @@ impl FilterPass {
|
||||||
if self.ubo_location.vertex != gl::INVALID_INDEX {
|
if self.ubo_location.vertex != gl::INVALID_INDEX {
|
||||||
gl::BindBufferBase(gl::UNIFORM_BUFFER, self.ubo_location.vertex, *buffer);
|
gl::BindBufferBase(gl::UNIFORM_BUFFER, self.ubo_location.vertex, *buffer);
|
||||||
}
|
}
|
||||||
if self.ubo_location.vertex != gl::INVALID_INDEX {
|
if self.ubo_location.fragment != gl::INVALID_INDEX {
|
||||||
gl::BindBufferBase(gl::UNIFORM_BUFFER, self.ubo_location.fragment, *buffer);
|
gl::BindBufferBase(gl::UNIFORM_BUFFER, self.ubo_location.fragment, *buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,7 +244,7 @@ impl FilterPass {
|
||||||
&mut self,
|
&mut self,
|
||||||
pass_index: usize,
|
pass_index: usize,
|
||||||
parent: &FilterCommon,
|
parent: &FilterCommon,
|
||||||
mvp: &[f32],
|
mvp: &[f32; 16],
|
||||||
frame_count: u32,
|
frame_count: u32,
|
||||||
frame_direction: i32,
|
frame_direction: i32,
|
||||||
fb_size: Size<u32>,
|
fb_size: Size<u32>,
|
||||||
|
@ -242,7 +253,7 @@ impl FilterPass {
|
||||||
source: &Texture,
|
source: &Texture,
|
||||||
) {
|
) {
|
||||||
// Bind MVP
|
// Bind MVP
|
||||||
if let Some((_location, offset)) =
|
if let Some((location, offset)) =
|
||||||
self.uniform_bindings.get(&VariableSemantics::MVP.into())
|
self.uniform_bindings.get(&VariableSemantics::MVP.into())
|
||||||
{
|
{
|
||||||
let mvp_size = mvp.len() * std::mem::size_of::<f32>();
|
let mvp_size = mvp.len() * std::mem::size_of::<f32>();
|
||||||
|
@ -250,7 +261,7 @@ impl FilterPass {
|
||||||
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_mvp(&mut buffer[offset..][..mvp_size], mvp)
|
FilterPass::build_mat4(location.location(), &mut buffer[offset..][..mvp_size], mvp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind OutputSize
|
// bind OutputSize
|
||||||
|
|
|
@ -344,7 +344,7 @@ pub struct Viewport<'a> {
|
||||||
pub x: i32,
|
pub x: i32,
|
||||||
pub y: i32,
|
pub y: i32,
|
||||||
pub output: &'a Framebuffer,
|
pub output: &'a Framebuffer,
|
||||||
pub mvp: Option<&'a [f32]>,
|
pub mvp: Option<&'a [f32; 16]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Copy, Clone)]
|
#[derive(Default, Debug, Copy, Clone)]
|
||||||
|
|
|
@ -517,7 +517,7 @@ void main()
|
||||||
padded_size: Default::default(),
|
padded_size: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
filter.frame(framecount, &viewport, &rendered, false)
|
filter.frame(framecount, &viewport, &rendered, None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -20,6 +20,7 @@ pub use framebuffer::Viewport;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod hello_triangle;
|
mod hello_triangle;
|
||||||
mod texture;
|
mod texture;
|
||||||
|
mod options;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
@ -30,7 +31,7 @@ mod tests {
|
||||||
fn triangle_gl() {
|
fn triangle_gl() {
|
||||||
let (glfw, window, events, shader, vao) = hello_triangle::setup();
|
let (glfw, window, events, shader, vao) = hello_triangle::setup();
|
||||||
let mut filter =
|
let mut filter =
|
||||||
FilterChain::load_from_path("../test/slang-shaders/crt/crt-royale.slangp")
|
FilterChain::load_from_path("../test/slang-shaders/crt/crt-royale.slangp", None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
hello_triangle::do_loop(glfw, window, events, shader, vao, &mut filter);
|
hello_triangle::do_loop(glfw, window, events, shader, vao, &mut filter);
|
||||||
}
|
}
|
||||||
|
|
11
librashader-runtime-gl/src/options.rs
Normal file
11
librashader-runtime-gl/src/options.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct FrameOptions {
|
||||||
|
pub clear_history: bool
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct FilterChainOptions {
|
||||||
|
pub gl_version: u16
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::framebuffer::{Framebuffer, Viewport};
|
use crate::framebuffer::{Framebuffer, Viewport};
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
static DEFAULT_MVP: &[f32] = &[
|
static DEFAULT_MVP: &[f32; 16] = &[
|
||||||
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,
|
||||||
|
@ -10,14 +10,14 @@ static DEFAULT_MVP: &[f32] = &[
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct RenderTarget<'a> {
|
pub struct RenderTarget<'a> {
|
||||||
pub mvp: &'a [f32],
|
pub mvp: &'a [f32; 16],
|
||||||
pub framebuffer: &'a Framebuffer,
|
pub framebuffer: &'a Framebuffer,
|
||||||
pub x: i32,
|
pub x: i32,
|
||||||
pub y: i32
|
pub y: i32
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> RenderTarget<'a> {
|
impl<'a> RenderTarget<'a> {
|
||||||
pub fn new(backbuffer: &'a Framebuffer, mvp: Option<&'a [f32]>, x: i32, y: i32) -> Self {
|
pub fn new(backbuffer: &'a Framebuffer, mvp: Option<&'a [f32; 16]>, x: i32, y: i32) -> Self {
|
||||||
if let Some(mvp) = mvp {
|
if let Some(mvp) = mvp {
|
||||||
RenderTarget {
|
RenderTarget {
|
||||||
framebuffer: backbuffer,
|
framebuffer: backbuffer,
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
use std::iter::Filter;
|
|
||||||
use gl::types::{GLenum, GLint, GLuint};
|
use gl::types::{GLenum, GLint, GLuint};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use librashader_common::{FilterMode, WrapMode};
|
use librashader_common::{FilterMode, WrapMode};
|
||||||
use crate::error::Result;
|
|
||||||
|
|
||||||
pub struct SamplerSet {
|
pub struct SamplerSet {
|
||||||
// todo: may need to deal with differences in mip filter.
|
// todo: may need to deal with differences in mip filter.
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::framebuffer::GlImage;
|
|
||||||
use gl::types::{GLenum, GLuint};
|
use gl::types::{GLenum, GLuint};
|
||||||
use librashader_common::{FilterMode, Size, WrapMode};
|
use librashader_common::Size;
|
||||||
use librashader_reflect::back::cross::GlVersion;
|
use librashader_reflect::back::cross::GlVersion;
|
||||||
|
|
||||||
pub fn calc_miplevel(size: Size<u32>) -> u32 {
|
pub fn calc_miplevel(size: Size<u32>) -> u32 {
|
||||||
|
@ -111,3 +110,20 @@ pub fn gl_get_version() -> GlVersion {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn gl_u16_to_version(version: u16) -> GlVersion {
|
||||||
|
match version {
|
||||||
|
300 => GlVersion::V1_30,
|
||||||
|
310 => GlVersion::V1_40,
|
||||||
|
320 => GlVersion::V1_50,
|
||||||
|
330 => GlVersion::V3_30,
|
||||||
|
400 => GlVersion::V4_00,
|
||||||
|
410 => GlVersion::V4_10,
|
||||||
|
420 => GlVersion::V4_20,
|
||||||
|
430 => GlVersion::V4_30,
|
||||||
|
440 => GlVersion::V4_40,
|
||||||
|
450 => GlVersion::V4_50,
|
||||||
|
460 => GlVersion::V4_60,
|
||||||
|
_ => GlVersion::V1_50
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue