gl46: implement DSA version of gl runtime
This commit is contained in:
parent
7b2721aa19
commit
5078015605
|
@ -13,6 +13,7 @@
|
||||||
<sourceFolder url="file://$MODULE_DIR$/librashader-compiler/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/librashader-compiler/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/librashader-common/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/librashader-common/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/librashader-runtime-d3d11/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/librashader-runtime-d3d11/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/librashader-runtime-gl46/src" isTestSource="false" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
|
|
17
Cargo.lock
generated
17
Cargo.lock
generated
|
@ -418,6 +418,7 @@ dependencies = [
|
||||||
"librashader-reflect",
|
"librashader-reflect",
|
||||||
"librashader-runtime-d3d11",
|
"librashader-runtime-d3d11",
|
||||||
"librashader-runtime-gl",
|
"librashader-runtime-gl",
|
||||||
|
"librashader-runtime-gl46",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -496,6 +497,22 @@ dependencies = [
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "librashader-runtime-gl46"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck",
|
||||||
|
"gl",
|
||||||
|
"glfw",
|
||||||
|
"librashader-common",
|
||||||
|
"librashader-preprocess",
|
||||||
|
"librashader-presets",
|
||||||
|
"librashader-reflect",
|
||||||
|
"rustc-hash",
|
||||||
|
"spirv_cross",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
|
|
|
@ -7,4 +7,5 @@ members = [
|
||||||
"librashader-reflect",
|
"librashader-reflect",
|
||||||
"librashader-runtime-d3d11",
|
"librashader-runtime-d3d11",
|
||||||
"librashader-runtime-gl",
|
"librashader-runtime-gl",
|
||||||
|
"librashader-runtime-gl46",
|
||||||
]
|
]
|
11
README.md
11
README.md
|
@ -9,12 +9,13 @@ librashader (*/ˈli:brəʃeɪdɚ/*) is a preprocessor, compiler, and runtime for
|
||||||
Heavily WIP.
|
Heavily WIP.
|
||||||
|
|
||||||
## Supported Render APIs
|
## Supported Render APIs
|
||||||
librashader supports OpenGL 3, Vulkan, DirectX 11, and DirectX 12. Support is WIP for all runtimes except OpenGL 3. Older versions
|
librashader supports OpenGL 3, OpenGL 4.6, Vulkan, DirectX 11, and DirectX 12. Support is WIP for all runtimes except OpenGL 3. Older versions
|
||||||
of DirectX and OpenGL, as well as Metal, are not supported (but pull-requests are welcome).
|
of DirectX and OpenGL, as well as Metal, are not supported (but pull-requests are welcome).
|
||||||
|
|
||||||
| **API** | **Status** | **`librashader` feature** |
|
| **API** | **Status** | **`librashader` feature** |
|
||||||
|-------------|------------|---------------------------|
|
|-------------|------------|---------------------------|
|
||||||
| OpenGL 3.3+ | ✔ | `gl` |
|
| OpenGL 3.3+ | ✔ | `gl` |
|
||||||
|
| OpenGL 4.6 | ✔ | `gl46` |
|
||||||
| Vulkan | 🚧 | `vk` |
|
| Vulkan | 🚧 | `vk` |
|
||||||
| Direct3D11 | 🚧 | `d3d11` |
|
| Direct3D11 | 🚧 | `d3d11` |
|
||||||
| Direct3D12 | 🚧 | `d3d12` |
|
| Direct3D12 | 🚧 | `d3d12` |
|
||||||
|
@ -54,11 +55,17 @@ Please report an issue if you run into a shader that works in RetroArch, but not
|
||||||
* Sampler objects are used rather than `glTexParameter`.
|
* Sampler objects are used rather than `glTexParameter`.
|
||||||
* Sampler inputs and outputs are not renamed. This is useful for debugging shaders in RenderDoc.
|
* Sampler inputs and outputs are not renamed. This is useful for debugging shaders in RenderDoc.
|
||||||
* UBO and Push Constant Buffer sizes are padded to 16-byte boundaries.
|
* UBO and Push Constant Buffer sizes are padded to 16-byte boundaries.
|
||||||
*
|
* OpenGL 4.6+
|
||||||
|
* All caveats from the OpenGL 3.3+ section should be considered.
|
||||||
|
* Should work on OpenGL 4.5 but this is not guaranteed. The OpenGL 4.6 runtime may eventually switch to using `ARB_spirv_extensions` for loading shaders, and this will not be marked as a breaking change.
|
||||||
|
* The OpenGL 4.6 runtime uses Direct State Access to minimize changes to the OpenGL state. For recent GPUs, this may improve performance.
|
||||||
* Direct3D 11
|
* Direct3D 11
|
||||||
* The staging buffer is not kept around when loading static textures (LUTs).
|
* The staging buffer is not kept around when loading static textures (LUTs).
|
||||||
* HDR10 support is not part of the shader runtime and is not supported.
|
* HDR10 support is not part of the shader runtime and is not supported.
|
||||||
|
|
||||||
|
Most, if not all shader presets should work fine on librashader. The runtime specific differences should not affect the output,
|
||||||
|
and are more a heads-up for integrating librashader into your project.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
The core parts of librashader such as the preprocessor, the preset parser,
|
The core parts of librashader such as the preprocessor, the preset parser,
|
||||||
the reflection library, and the runtimes, are all licensed under the Mozilla Public License version 2.0.
|
the reflection library, and the runtimes, are all licensed under the Mozilla Public License version 2.0.
|
||||||
|
|
|
@ -183,6 +183,7 @@ impl FilterPass {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
// can't use framebuffer.clear because it will unbind.
|
||||||
gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE);
|
gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE);
|
||||||
gl::ClearColor(0.0f32, 0.0f32, 0.0f32, 0.0f32);
|
gl::ClearColor(0.0f32, 0.0f32, 0.0f32, 0.0f32);
|
||||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||||
|
|
|
@ -29,7 +29,7 @@ use crate::texture::Texture;
|
||||||
pub struct FilterChain {
|
pub struct FilterChain {
|
||||||
passes: Box<[FilterPass]>,
|
passes: Box<[FilterPass]>,
|
||||||
common: FilterCommon,
|
common: FilterCommon,
|
||||||
filter_vao: GLuint,
|
pub(crate) draw_quad: DrawQuad,
|
||||||
output_framebuffers: Box<[Framebuffer]>,
|
output_framebuffers: Box<[Framebuffer]>,
|
||||||
feedback_framebuffers: Box<[Framebuffer]>,
|
feedback_framebuffers: Box<[Framebuffer]>,
|
||||||
history_framebuffers: VecDeque<Framebuffer>,
|
history_framebuffers: VecDeque<Framebuffer>,
|
||||||
|
@ -43,7 +43,6 @@ pub struct FilterCommon {
|
||||||
pub output_textures: Box<[Texture]>,
|
pub output_textures: Box<[Texture]>,
|
||||||
pub feedback_textures: Box<[Texture]>,
|
pub feedback_textures: Box<[Texture]>,
|
||||||
pub history_textures: Box<[Texture]>,
|
pub history_textures: Box<[Texture]>,
|
||||||
pub(crate) draw_quad: DrawQuad,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FilterMutable {
|
pub struct FilterMutable {
|
||||||
|
@ -177,17 +176,12 @@ impl FilterChain {
|
||||||
// create VBO objects
|
// create VBO objects
|
||||||
let draw_quad = DrawQuad::new();
|
let draw_quad = DrawQuad::new();
|
||||||
|
|
||||||
let mut filter_vao = 0;
|
|
||||||
unsafe {
|
|
||||||
gl::GenVertexArrays(1, &mut filter_vao);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(FilterChain {
|
Ok(FilterChain {
|
||||||
passes: filters,
|
passes: filters,
|
||||||
output_framebuffers: output_framebuffers.into_boxed_slice(),
|
output_framebuffers: output_framebuffers.into_boxed_slice(),
|
||||||
feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
|
feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
|
||||||
history_framebuffers,
|
history_framebuffers,
|
||||||
filter_vao,
|
draw_quad,
|
||||||
common: FilterCommon {
|
common: FilterCommon {
|
||||||
config: FilterMutable {
|
config: FilterMutable {
|
||||||
passes_enabled: preset.shader_count as usize,
|
passes_enabled: preset.shader_count as usize,
|
||||||
|
@ -199,7 +193,6 @@ impl FilterChain {
|
||||||
output_textures: output_textures.into_boxed_slice(),
|
output_textures: output_textures.into_boxed_slice(),
|
||||||
feedback_textures: feedback_textures.into_boxed_slice(),
|
feedback_textures: feedback_textures.into_boxed_slice(),
|
||||||
history_textures,
|
history_textures,
|
||||||
draw_quad,
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -279,6 +272,15 @@ impl FilterChain {
|
||||||
|
|
||||||
fn load_luts(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();
|
||||||
|
let pixel_unpack = unsafe {
|
||||||
|
let mut binding = 0;
|
||||||
|
gl::GetIntegerv(gl::PIXEL_UNPACK_BUFFER_BINDING, &mut binding);
|
||||||
|
binding
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
gl::BindBuffer(gl::PIXEL_UNPACK_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
for (index, texture) in textures.iter().enumerate() {
|
for (index, texture) in textures.iter().enumerate() {
|
||||||
let image = Image::load(&texture.path)?;
|
let image = Image::load(&texture.path)?;
|
||||||
|
@ -290,10 +292,10 @@ impl FilterChain {
|
||||||
|
|
||||||
let mut handle = 0;
|
let mut handle = 0;
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::GenTextures(1, &mut handle);
|
gl::CreateTextures(gl::TEXTURE_2D,1, &mut handle);
|
||||||
gl::BindTexture(gl::TEXTURE_2D, handle);
|
|
||||||
gl::TexStorage2D(
|
gl::TextureStorage2D(
|
||||||
gl::TEXTURE_2D,
|
handle,
|
||||||
levels as GLsizei,
|
levels as GLsizei,
|
||||||
gl::RGBA8,
|
gl::RGBA8,
|
||||||
image.size.width as GLsizei,
|
image.size.width as GLsizei,
|
||||||
|
@ -302,12 +304,10 @@ impl FilterChain {
|
||||||
|
|
||||||
gl::PixelStorei(gl::UNPACK_ROW_LENGTH, 0);
|
gl::PixelStorei(gl::UNPACK_ROW_LENGTH, 0);
|
||||||
gl::PixelStorei(gl::UNPACK_ALIGNMENT, 4);
|
gl::PixelStorei(gl::UNPACK_ALIGNMENT, 4);
|
||||||
gl::BindBuffer(gl::PIXEL_UNPACK_BUFFER, 0);
|
|
||||||
gl::TexSubImage2D(
|
gl::TextureSubImage2D(
|
||||||
gl::TEXTURE_2D,
|
handle,
|
||||||
0,
|
0, 0, 0,
|
||||||
0,
|
|
||||||
0,
|
|
||||||
image.size.width as GLsizei,
|
image.size.width as GLsizei,
|
||||||
image.size.height as GLsizei,
|
image.size.height as GLsizei,
|
||||||
gl::RGBA,
|
gl::RGBA,
|
||||||
|
@ -317,10 +317,8 @@ impl FilterChain {
|
||||||
|
|
||||||
let mipmap = levels > 1;
|
let mipmap = levels > 1;
|
||||||
if mipmap {
|
if mipmap {
|
||||||
gl::GenerateMipmap(gl::TEXTURE_2D);
|
gl::GenerateTextureMipmap(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
gl::BindTexture(gl::TEXTURE_2D, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
luts.insert(
|
luts.insert(
|
||||||
|
@ -338,6 +336,10 @@ impl FilterChain {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
gl::BindBuffer(gl::PIXEL_UNPACK_BUFFER, pixel_unpack as GLuint);
|
||||||
|
};
|
||||||
Ok(luts)
|
Ok(luts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,17 +418,15 @@ impl FilterChain {
|
||||||
let size = ubo.size;
|
let size = ubo.size;
|
||||||
let mut ring: InlineRingBuffer<GLuint, 16> = InlineRingBuffer::new();
|
let mut ring: InlineRingBuffer<GLuint, 16> = InlineRingBuffer::new();
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::GenBuffers(16, ring.items_mut().as_mut_ptr());
|
gl::CreateBuffers(16, ring.items_mut().as_mut_ptr());
|
||||||
for buffer in ring.items() {
|
for buffer in ring.items() {
|
||||||
gl::BindBuffer(gl::UNIFORM_BUFFER, *buffer);
|
gl::NamedBufferData(
|
||||||
gl::BufferData(
|
*buffer,
|
||||||
gl::UNIFORM_BUFFER,
|
|
||||||
size as GLsizeiptr,
|
size as GLsizeiptr,
|
||||||
std::ptr::null(),
|
std::ptr::null(),
|
||||||
gl::STREAM_DRAW,
|
gl::STREAM_DRAW,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
gl::BindBuffer(gl::UNIFORM_BUFFER, 0);
|
|
||||||
}
|
}
|
||||||
Some(ring)
|
Some(ring)
|
||||||
} else {
|
} else {
|
||||||
|
@ -593,11 +593,9 @@ impl FilterChain {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
|
||||||
// do not need to rebind FBO 0 here since first `draw` will
|
// do not need to rebind FBO 0 here since first `draw` will
|
||||||
// bind automatically.
|
// bind automatically.
|
||||||
gl::BindVertexArray(self.filter_vao);
|
self.draw_quad.bind_vao();
|
||||||
}
|
|
||||||
|
|
||||||
let filter = passes[0].config.filter;
|
let filter = passes[0].config.filter;
|
||||||
let wrap_mode = passes[0].config.wrap_mode;
|
let wrap_mode = passes[0].config.wrap_mode;
|
||||||
|
@ -710,10 +708,9 @@ impl FilterChain {
|
||||||
|
|
||||||
self.push_history(input)?;
|
self.push_history(input)?;
|
||||||
|
|
||||||
// pass.draw should return framebuffer bound to 0.
|
// do not need to rebind FBO 0 here since first `draw` will
|
||||||
unsafe {
|
// bind automatically.
|
||||||
gl::BindVertexArray(0);
|
self.draw_quad.unbind_vao();
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,9 +104,7 @@ impl FilterPass {
|
||||||
fn bind_texture(samplers: &SamplerSet, binding: &TextureBinding, texture: &Texture) {
|
fn bind_texture(samplers: &SamplerSet, binding: &TextureBinding, texture: &Texture) {
|
||||||
unsafe {
|
unsafe {
|
||||||
// eprintln!("setting {} to texunit {}", texture.image.handle, binding.binding);
|
// eprintln!("setting {} to texunit {}", texture.image.handle, binding.binding);
|
||||||
gl::ActiveTexture(gl::TEXTURE0 + binding.binding);
|
gl::BindTextureUnit(binding.binding, texture.image.handle);
|
||||||
|
|
||||||
gl::BindTexture(gl::TEXTURE_2D, texture.image.handle);
|
|
||||||
gl::BindSampler(binding.binding,
|
gl::BindSampler(binding.binding,
|
||||||
samplers.get(texture.wrap_mode, texture.filter, texture.mip_filter));
|
samplers.get(texture.wrap_mode, texture.filter, texture.mip_filter));
|
||||||
}
|
}
|
||||||
|
@ -137,7 +135,7 @@ impl FilterPass {
|
||||||
let framebuffer = output.framebuffer;
|
let framebuffer = output.framebuffer;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::BindFramebuffer(gl::FRAMEBUFFER, framebuffer.handle);
|
// gl::BindFramebuffer(gl::FRAMEBUFFER, framebuffer.handle);
|
||||||
gl::UseProgram(self.program);
|
gl::UseProgram(self.program);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,14 +160,12 @@ impl FilterPass {
|
||||||
let buffer = ring.current();
|
let buffer = ring.current();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::BindBuffer(gl::UNIFORM_BUFFER, *buffer);
|
gl::NamedBufferSubData(
|
||||||
gl::BufferSubData(
|
*buffer,
|
||||||
gl::UNIFORM_BUFFER,
|
|
||||||
0,
|
0,
|
||||||
size as GLsizeiptr,
|
size as GLsizeiptr,
|
||||||
self.uniform_buffer.as_ptr().cast(),
|
self.uniform_buffer.as_ptr().cast(),
|
||||||
);
|
);
|
||||||
gl::BindBuffer(gl::UNIFORM_BUFFER, 0);
|
|
||||||
|
|
||||||
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);
|
||||||
|
@ -183,10 +179,9 @@ impl FilterPass {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE);
|
// can use because DSA
|
||||||
gl::ClearColor(0.0f32, 0.0f32, 0.0f32, 0.0f32);
|
framebuffer.clear();
|
||||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
gl::BindFramebuffer(gl::FRAMEBUFFER, framebuffer.handle);
|
||||||
//
|
|
||||||
gl::Viewport(
|
gl::Viewport(
|
||||||
output.x,
|
output.x,
|
||||||
output.y,
|
output.y,
|
||||||
|
@ -204,36 +199,7 @@ impl FilterPass {
|
||||||
gl::Disable(gl::BLEND);
|
gl::Disable(gl::BLEND);
|
||||||
gl::Disable(gl::DEPTH_TEST);
|
gl::Disable(gl::DEPTH_TEST);
|
||||||
|
|
||||||
gl::EnableVertexAttribArray(0);
|
|
||||||
gl::EnableVertexAttribArray(1);
|
|
||||||
|
|
||||||
gl::BindBuffer(gl::ARRAY_BUFFER, parent.draw_quad.vbo);
|
|
||||||
|
|
||||||
// the provided pointers are of OpenGL provenance with respect to the buffer bound to quad_vbo,
|
|
||||||
// and not a known provenance to the Rust abstract machine, therefore we give it invalid pointers.
|
|
||||||
// that are inexpressible in Rust
|
|
||||||
gl::VertexAttribPointer(
|
|
||||||
0,
|
|
||||||
2,
|
|
||||||
gl::FLOAT,
|
|
||||||
gl::FALSE,
|
|
||||||
(4 * std::mem::size_of::<f32>()) as GLsizei,
|
|
||||||
std::ptr::invalid(0),
|
|
||||||
);
|
|
||||||
gl::VertexAttribPointer(
|
|
||||||
1,
|
|
||||||
2,
|
|
||||||
gl::FLOAT,
|
|
||||||
gl::FALSE,
|
|
||||||
(4 * std::mem::size_of::<f32>()) as GLsizei,
|
|
||||||
std::ptr::invalid(2 * std::mem::size_of::<f32>()),
|
|
||||||
);
|
|
||||||
gl::DrawArrays(gl::TRIANGLE_STRIP, 0, 4);
|
gl::DrawArrays(gl::TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
gl::BindBuffer(gl::ARRAY_BUFFER, 0);
|
|
||||||
gl::DisableVertexAttribArray(0);
|
|
||||||
gl::DisableVertexAttribArray(1);
|
|
||||||
|
|
||||||
gl::Disable(gl::FRAMEBUFFER_SRGB);
|
gl::Disable(gl::FRAMEBUFFER_SRGB);
|
||||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,7 @@ impl Framebuffer {
|
||||||
pub fn new(max_levels: u32) -> Framebuffer {
|
pub fn new(max_levels: u32) -> Framebuffer {
|
||||||
let mut framebuffer = 0;
|
let mut framebuffer = 0;
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::GenFramebuffers(1, &mut framebuffer);
|
gl::CreateFramebuffers(1, &mut framebuffer);
|
||||||
gl::BindFramebuffer(gl::FRAMEBUFFER, framebuffer);
|
|
||||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Framebuffer {
|
Framebuffer {
|
||||||
|
@ -139,11 +137,9 @@ impl Framebuffer {
|
||||||
|
|
||||||
pub(crate) fn clear(&self) {
|
pub(crate) fn clear(&self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::BindFramebuffer(gl::FRAMEBUFFER, self.handle);
|
gl::ClearNamedFramebufferfv(self.handle,
|
||||||
gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE);
|
gl::COLOR, 0,
|
||||||
gl::ClearColor(0.0, 0.0, 0.0, 0.0);
|
[0.0f32, 0.0, 0.0, 0.0].as_ptr().cast());
|
||||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
|
||||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,64 +150,15 @@ impl Framebuffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::BindFramebuffer(gl::FRAMEBUFFER, self.handle);
|
// gl::NamedFramebufferDrawBuffer(self.handle, gl::COLOR_ATTACHMENT1);
|
||||||
|
gl::NamedFramebufferReadBuffer(image.handle, gl::COLOR_ATTACHMENT0);
|
||||||
|
gl::NamedFramebufferDrawBuffer(self.handle, gl::COLOR_ATTACHMENT1);
|
||||||
|
|
||||||
gl::FramebufferTexture2D(
|
gl::BlitNamedFramebuffer(image.handle, self.handle,
|
||||||
gl::READ_FRAMEBUFFER,
|
0, 0, image.size.width as GLint, image.size.height as GLint,
|
||||||
gl::COLOR_ATTACHMENT0,
|
0, 0, self.size.width as GLint, self.size.height as GLint,
|
||||||
gl::TEXTURE_2D,
|
gl::COLOR_BUFFER_BIT, gl::NEAREST);
|
||||||
image.handle,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
|
|
||||||
gl::FramebufferTexture2D(
|
|
||||||
gl::DRAW_FRAMEBUFFER,
|
|
||||||
gl::COLOR_ATTACHMENT1,
|
|
||||||
gl::TEXTURE_2D,
|
|
||||||
self.image,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
gl::DrawBuffer(gl::COLOR_ATTACHMENT1);
|
|
||||||
gl::BlitFramebuffer(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
self.size.width as GLint,
|
|
||||||
self.size.height as GLint,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
self.size.width as GLint,
|
|
||||||
self.size.height as GLint,
|
|
||||||
gl::COLOR_BUFFER_BIT,
|
|
||||||
gl::NEAREST,
|
|
||||||
);
|
|
||||||
|
|
||||||
// cleanup after ourselves.
|
|
||||||
gl::FramebufferTexture2D(
|
|
||||||
gl::READ_FRAMEBUFFER,
|
|
||||||
gl::COLOR_ATTACHMENT0,
|
|
||||||
gl::TEXTURE_2D,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
|
|
||||||
gl::FramebufferTexture2D(
|
|
||||||
gl::DRAW_FRAMEBUFFER,
|
|
||||||
gl::COLOR_ATTACHMENT1,
|
|
||||||
gl::TEXTURE_2D,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
|
|
||||||
// set this back to color_attachment 0
|
|
||||||
gl::FramebufferTexture2D(
|
|
||||||
gl::FRAMEBUFFER,
|
|
||||||
gl::COLOR_ATTACHMENT0,
|
|
||||||
gl::TEXTURE_2D,
|
|
||||||
self.image,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
|
|
||||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -225,22 +172,18 @@ impl Framebuffer {
|
||||||
self.size = size;
|
self.size = size;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::BindFramebuffer(gl::FRAMEBUFFER, self.handle);
|
|
||||||
|
|
||||||
// reset the framebuffer image
|
// reset the framebuffer image
|
||||||
if self.image != 0 {
|
if self.image != 0 {
|
||||||
gl::FramebufferTexture2D(
|
gl::NamedFramebufferTexture(
|
||||||
gl::FRAMEBUFFER,
|
self.handle,
|
||||||
gl::COLOR_ATTACHMENT0,
|
gl::COLOR_ATTACHMENT0,
|
||||||
gl::TEXTURE_2D,
|
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
gl::DeleteTextures(1, &self.image);
|
gl::DeleteTextures(1, &self.image);
|
||||||
}
|
}
|
||||||
|
|
||||||
gl::GenTextures(1, &mut self.image);
|
gl::CreateTextures(gl::TEXTURE_2D,1, &mut self.image);
|
||||||
gl::BindTexture(gl::TEXTURE_2D, self.image);
|
|
||||||
|
|
||||||
if size.width == 0 {
|
if size.width == 0 {
|
||||||
size.width = 1;
|
size.width = 1;
|
||||||
|
@ -257,18 +200,17 @@ impl Framebuffer {
|
||||||
self.levels = 1;
|
self.levels = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
gl::TexStorage2D(
|
gl::TextureStorage2D(
|
||||||
gl::TEXTURE_2D,
|
self.image,
|
||||||
self.levels as GLsizei,
|
self.levels as GLsizei,
|
||||||
self.format,
|
self.format,
|
||||||
size.width as GLsizei,
|
size.width as GLsizei,
|
||||||
size.height as GLsizei,
|
size.height as GLsizei,
|
||||||
);
|
);
|
||||||
|
|
||||||
gl::FramebufferTexture2D(
|
gl::NamedFramebufferTexture(
|
||||||
gl::FRAMEBUFFER,
|
self.handle,
|
||||||
gl::COLOR_ATTACHMENT0,
|
gl::COLOR_ATTACHMENT0,
|
||||||
gl::TEXTURE_2D,
|
|
||||||
self.image,
|
self.image,
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
@ -279,16 +221,14 @@ impl Framebuffer {
|
||||||
gl::FRAMEBUFFER_UNSUPPORTED => {
|
gl::FRAMEBUFFER_UNSUPPORTED => {
|
||||||
eprintln!("unsupported fbo");
|
eprintln!("unsupported fbo");
|
||||||
|
|
||||||
gl::FramebufferTexture2D(
|
gl::NamedFramebufferTexture(
|
||||||
gl::FRAMEBUFFER,
|
self.handle,
|
||||||
gl::COLOR_ATTACHMENT0,
|
gl::COLOR_ATTACHMENT0,
|
||||||
gl::TEXTURE_2D,
|
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
gl::DeleteTextures(1, &self.image);
|
gl::DeleteTextures(1, &self.image);
|
||||||
gl::GenTextures(1, &mut self.image);
|
gl::CreateTextures(gl::TEXTURE_2D, 1, &mut self.image);
|
||||||
gl::BindTexture(1, self.image);
|
|
||||||
|
|
||||||
self.levels = util::calc_miplevel(size);
|
self.levels = util::calc_miplevel(size);
|
||||||
if self.levels > self.max_levels {
|
if self.levels > self.max_levels {
|
||||||
|
@ -298,17 +238,16 @@ impl Framebuffer {
|
||||||
self.levels = 1;
|
self.levels = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
gl::TexStorage2D(
|
gl::TextureStorage2D(
|
||||||
gl::TEXTURE_2D,
|
self.image,
|
||||||
self.levels as GLsizei,
|
self.levels as GLsizei,
|
||||||
ShaderFormat::R8G8B8A8Unorm.into(),
|
ShaderFormat::R8G8B8A8Unorm.into(),
|
||||||
size.width as GLsizei,
|
size.width as GLsizei,
|
||||||
size.height as GLsizei,
|
size.height as GLsizei,
|
||||||
);
|
);
|
||||||
gl::FramebufferTexture2D(
|
gl::NamedFramebufferTexture(
|
||||||
gl::FRAMEBUFFER,
|
self.handle,
|
||||||
gl::COLOR_ATTACHMENT0,
|
gl::COLOR_ATTACHMENT0,
|
||||||
gl::TEXTURE_2D,
|
|
||||||
self.image,
|
self.image,
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
@ -318,9 +257,6 @@ impl Framebuffer {
|
||||||
_ => return Err(FilterChainError::FramebufferInit(status))
|
_ => return Err(FilterChainError::FramebufferInit(status))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
|
||||||
gl::BindTexture(gl::TEXTURE_2D, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -12,7 +12,7 @@ use crate::framebuffer::{Framebuffer, GlImage, Viewport};
|
||||||
|
|
||||||
const WIDTH: u32 = 900;
|
const WIDTH: u32 = 900;
|
||||||
const HEIGHT: u32 = 700;
|
const HEIGHT: u32 = 700;
|
||||||
const TITLE: &str = "librashader OpenGL";
|
const TITLE: &str = "librashader OpenGL 4.6";
|
||||||
|
|
||||||
pub fn compile_program(vertex: &str, fragment: &str) -> GLuint {
|
pub fn compile_program(vertex: &str, fragment: &str) -> GLuint {
|
||||||
let vertex_shader = unsafe { gl::CreateShader(gl::VERTEX_SHADER) };
|
let vertex_shader = unsafe { gl::CreateShader(gl::VERTEX_SHADER) };
|
||||||
|
@ -215,7 +215,7 @@ void main()
|
||||||
gl::ObjectLabel(gl::VERTEX_ARRAY, vao, -1, b"triangle_vao\0".as_ptr().cast());
|
gl::ObjectLabel(gl::VERTEX_ARRAY, vao, -1, b"triangle_vao\0".as_ptr().cast());
|
||||||
|
|
||||||
gl::VertexArrayVertexBuffer(vao, 0,
|
gl::VertexArrayVertexBuffer(vao, 0,
|
||||||
vbo, 0, (6 * std::mem::size_of::<f32>()) as GLint
|
vbo, 0, 6 * std::mem::size_of::<f32>() as GLint
|
||||||
);
|
);
|
||||||
|
|
||||||
gl::EnableVertexArrayAttrib(vao, 0); // this is "layout (location = 0)" in vertex shader
|
gl::EnableVertexArrayAttrib(vao, 0); // this is "layout (location = 0)" in vertex shader
|
||||||
|
@ -226,7 +226,7 @@ void main()
|
||||||
|
|
||||||
gl::EnableVertexArrayAttrib(vao, 1);
|
gl::EnableVertexArrayAttrib(vao, 1);
|
||||||
gl::VertexArrayAttribFormat(vao, 1, 3,
|
gl::VertexArrayAttribFormat(vao, 1, 3,
|
||||||
gl::FLOAT, gl::FALSE, (3 * std::mem::size_of::<f32>() as GLuint));
|
gl::FLOAT, gl::FALSE, 3 * std::mem::size_of::<f32>() as GLuint);
|
||||||
|
|
||||||
|
|
||||||
gl::VertexArrayAttribBinding(vao, 0, 0);
|
gl::VertexArrayAttribBinding(vao, 0, 0);
|
||||||
|
@ -461,13 +461,11 @@ void main()
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
// render to fb
|
// render to fb
|
||||||
|
|
||||||
|
gl::ClearNamedFramebufferfv(rendered_framebuffer, gl::COLOR, 0, [0.3f32, 0.4, 0.6, 1.0].as_ptr().cast());
|
||||||
gl::BindFramebuffer(gl::FRAMEBUFFER, rendered_framebuffer);
|
gl::BindFramebuffer(gl::FRAMEBUFFER, rendered_framebuffer);
|
||||||
gl::Viewport(0, 0, vp_width, vp_height);
|
gl::Viewport(0, 0, vp_width, vp_height);
|
||||||
|
|
||||||
// clear color
|
|
||||||
clear_color(Color(0.3, 0.4, 0.6, 1.0));
|
|
||||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
// do the drawing
|
// do the drawing
|
||||||
gl::UseProgram(triangle_program);
|
gl::UseProgram(triangle_program);
|
||||||
// select vertices
|
// select vertices
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use gl::types::{GLsizeiptr, GLuint};
|
use gl::types::{GLint, GLsizei, GLsizeiptr, GLuint};
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
static QUAD_VBO_DATA: &[f32; 16] = &[
|
static QUAD_VBO_DATA: &[f32; 16] = &[
|
||||||
|
@ -9,24 +9,55 @@ static QUAD_VBO_DATA: &[f32; 16] = &[
|
||||||
];
|
];
|
||||||
|
|
||||||
pub struct DrawQuad {
|
pub struct DrawQuad {
|
||||||
pub vbo: GLuint,
|
vbo: GLuint,
|
||||||
|
vao: GLuint,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DrawQuad {
|
impl DrawQuad {
|
||||||
pub fn new() -> DrawQuad {
|
pub fn new() -> DrawQuad {
|
||||||
let mut vbo = 0;
|
let mut vbo = 0;
|
||||||
|
let mut vao = 0;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::GenBuffers(1, &mut vbo);
|
gl::CreateBuffers(1, &mut vbo);
|
||||||
gl::BindBuffer(gl::ARRAY_BUFFER, vbo);
|
gl::NamedBufferData(
|
||||||
gl::BufferData(
|
vbo,
|
||||||
gl::ARRAY_BUFFER,
|
|
||||||
std::mem::size_of_val(QUAD_VBO_DATA) as GLsizeiptr,
|
std::mem::size_of_val(QUAD_VBO_DATA) as GLsizeiptr,
|
||||||
QUAD_VBO_DATA.as_ptr().cast(),
|
QUAD_VBO_DATA.as_ptr().cast(),
|
||||||
gl::STATIC_DRAW,
|
gl::STATIC_DRAW,
|
||||||
);
|
);
|
||||||
gl::BindBuffer(gl::ARRAY_BUFFER, 0);
|
gl::CreateVertexArrays(1, &mut vao);
|
||||||
|
|
||||||
|
gl::EnableVertexArrayAttrib(vao, 0);
|
||||||
|
gl::EnableVertexArrayAttrib(vao, 1);
|
||||||
|
|
||||||
|
gl::VertexArrayVertexBuffer(vao, 0,
|
||||||
|
vbo, 0, 4 * std::mem::size_of::<f32>() as GLint
|
||||||
|
);
|
||||||
|
|
||||||
|
gl::VertexArrayAttribFormat(vao, 0, 2,
|
||||||
|
gl::FLOAT, gl::FALSE, 0);
|
||||||
|
gl::VertexArrayAttribFormat(vao, 1, 2,
|
||||||
|
gl::FLOAT, gl::FALSE,
|
||||||
|
2 * std::mem::size_of::<f32>() as GLuint);
|
||||||
|
|
||||||
|
gl::VertexArrayAttribBinding(vao, 0, 0);
|
||||||
|
gl::VertexArrayAttribBinding(vao, 1, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawQuad { vbo }
|
DrawQuad { vbo, vao }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind_vao(&self) {
|
||||||
|
unsafe {
|
||||||
|
gl::BindVertexArray(self.vao);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unbind_vao(&self) {
|
||||||
|
unsafe {
|
||||||
|
gl::BindVertexArray(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ librashader-preprocess = { path = "../librashader-preprocess" }
|
||||||
librashader-reflect = { path = "../librashader-reflect" }
|
librashader-reflect = { path = "../librashader-reflect" }
|
||||||
librashader-runtime-d3d11 = { path = "../librashader-runtime-d3d11" }
|
librashader-runtime-d3d11 = { path = "../librashader-runtime-d3d11" }
|
||||||
librashader-runtime-gl = { path = "../librashader-runtime-gl" }
|
librashader-runtime-gl = { path = "../librashader-runtime-gl" }
|
||||||
|
librashader-runtime-gl46 = { path = "../librashader-runtime-gl46" }
|
||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
|
@ -27,7 +27,7 @@ pub mod reflect {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod targets {
|
pub mod targets {
|
||||||
/// Shader compiler targets and runtime for OpenGL.
|
/// Shader compiler targets and runtime for OpenGL 3.3+.
|
||||||
pub mod gl {
|
pub mod gl {
|
||||||
/// Shader compiler target for GLSL.
|
/// Shader compiler target for GLSL.
|
||||||
pub use librashader_reflect::back::targets::GLSL;
|
pub use librashader_reflect::back::targets::GLSL;
|
||||||
|
@ -38,6 +38,17 @@ pub mod targets {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Shader compiler targets and runtime for OpenGL 4.6.
|
||||||
|
pub mod gl46 {
|
||||||
|
/// Shader compiler target for GLSL.
|
||||||
|
pub use librashader_reflect::back::targets::GLSL;
|
||||||
|
|
||||||
|
/// Shader runtime for OpenGL.
|
||||||
|
pub mod runtime {
|
||||||
|
pub use librashader_runtime_gl46::*;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Shader compiler targets and runtime for DirectX.
|
/// Shader compiler targets and runtime for DirectX.
|
||||||
pub mod dx {
|
pub mod dx {
|
||||||
/// Shader compiler target for HLSL.
|
/// Shader compiler target for HLSL.
|
||||||
|
|
Loading…
Reference in a new issue