Further OpenGL 3.1 support (#4612)

This commit is contained in:
Zoxc 2023-10-30 16:51:13 +01:00 committed by GitHub
parent ac896cf223
commit 8f6fcb1e6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 90 additions and 22 deletions

View File

@ -611,6 +611,10 @@ impl super::Adapter {
super::PrivateCapabilities::DEBUG_FNS,
supported((3, 2), (4, 3)) && !web_gl,
);
private_caps.set(
super::PrivateCapabilities::INVALIDATE_FRAMEBUFFER,
supported((3, 0), (4, 3)),
);
let max_texture_size = unsafe { gl.get_parameter_i32(glow::MAX_TEXTURE_SIZE) } as u32;
let max_texture_3d_size = unsafe { gl.get_parameter_i32(glow::MAX_3D_TEXTURE_SIZE) } as u32;

View File

@ -474,6 +474,9 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
panic!("Multiple render attachments with external framebuffers are not supported.");
}
// `COLOR_ATTACHMENT0` to `COLOR_ATTACHMENT31` gives 32 possible color attachments.
assert!(desc.color_attachments.len() <= 32);
match desc
.color_attachments
.first()

View File

@ -750,14 +750,60 @@ impl crate::Device<super::Api> for super::Device {
if conv::is_layered_target(target) {
unsafe {
gl.tex_storage_3d(
target,
desc.mip_level_count as i32,
format_desc.internal,
desc.size.width as i32,
desc.size.height as i32,
desc.size.depth_or_array_layers as i32,
)
if self
.shared
.private_caps
.contains(PrivateCapabilities::TEXTURE_STORAGE)
{
gl.tex_storage_3d(
target,
desc.mip_level_count as i32,
format_desc.internal,
desc.size.width as i32,
desc.size.height as i32,
desc.size.depth_or_array_layers as i32,
)
} else if target == glow::TEXTURE_3D {
let mut width = desc.size.width;
let mut height = desc.size.width;
let mut depth = desc.size.depth_or_array_layers;
for i in 0..desc.mip_level_count {
gl.tex_image_3d(
target,
i as i32,
format_desc.internal as i32,
width as i32,
height as i32,
depth as i32,
0,
format_desc.external,
format_desc.data_type,
None,
);
width = max(1, width / 2);
height = max(1, height / 2);
depth = max(1, depth / 2);
}
} else {
let mut width = desc.size.width;
let mut height = desc.size.width;
for i in 0..desc.mip_level_count {
gl.tex_image_3d(
target,
i as i32,
format_desc.internal as i32,
width as i32,
height as i32,
desc.size.depth_or_array_layers as i32,
0,
format_desc.external,
format_desc.data_type,
None,
);
width = max(1, width / 2);
height = max(1, height / 2);
}
}
};
} else if desc.sample_count > 1 {
unsafe {

View File

@ -167,6 +167,8 @@ bitflags::bitflags! {
const TEXTURE_STORAGE = 1 << 12;
/// Supports `push_debug_group`, `pop_debug_group` and `debug_message_insert`.
const DEBUG_FNS = 1 << 13;
/// Supports framebuffer invalidation.
const INVALIDATE_FRAMEBUFFER = 1 << 14;
}
}

View File

@ -969,7 +969,13 @@ impl super::Queue {
unsafe { gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, Some(self.draw_fbo)) };
}
C::InvalidateAttachments(ref list) => {
unsafe { gl.invalidate_framebuffer(glow::DRAW_FRAMEBUFFER, list) };
if self
.shared
.private_caps
.contains(PrivateCapabilities::INVALIDATE_FRAMEBUFFER)
{
unsafe { gl.invalidate_framebuffer(glow::DRAW_FRAMEBUFFER, list) };
}
}
C::SetDrawColorBuffers(count) => {
self.draw_buffer_count = count;
@ -990,16 +996,14 @@ impl super::Queue {
&& is_srgb
{
unsafe { self.perform_shader_clear(gl, draw_buffer, *color) };
} else if draw_buffer < 32 {
// Prefer `clear_color` as `clear_buffer_f32_slice` crashes on Sandy Bridge
} else {
// Prefer `clear` as `clear_buffer` functions have issues on Sandy Bridge
// on Windows.
unsafe {
gl.draw_buffers(&[glow::COLOR_ATTACHMENT0 + draw_buffer]);
gl.clear_color(color[0], color[1], color[2], color[3]);
gl.clear(glow::COLOR_BUFFER_BIT);
}
} else {
unsafe { gl.clear_buffer_f32_slice(glow::COLOR, draw_buffer, color) };
}
}
C::ClearColorU(draw_buffer, ref color) => {
@ -1009,20 +1013,29 @@ impl super::Queue {
unsafe { gl.clear_buffer_i32_slice(glow::COLOR, draw_buffer, color) };
}
C::ClearDepth(depth) => {
unsafe { gl.clear_buffer_f32_slice(glow::DEPTH, 0, &[depth]) };
// Prefer `clear` as `clear_buffer` functions have issues on Sandy Bridge
// on Windows.
unsafe {
gl.clear_depth_f32(depth);
gl.clear(glow::DEPTH_BUFFER_BIT);
}
}
C::ClearStencil(value) => {
unsafe { gl.clear_buffer_i32_slice(glow::STENCIL, 0, &[value as i32]) };
// Prefer `clear` as `clear_buffer` functions have issues on Sandy Bridge
// on Windows.
unsafe {
gl.clear_stencil(value as i32);
gl.clear(glow::STENCIL_BUFFER_BIT);
}
}
C::ClearDepthAndStencil(depth, stencil_value) => {
// Prefer `clear` as `clear_buffer` functions have issues on Sandy Bridge
// on Windows.
unsafe {
gl.clear_buffer_depth_stencil(
glow::DEPTH_STENCIL,
0,
depth,
stencil_value as i32,
)
};
gl.clear_depth_f32(depth);
gl.clear_stencil(stencil_value as i32);
gl.clear(glow::DEPTH_BUFFER_BIT | glow::STENCIL_BUFFER_BIT);
}
}
C::BufferBarrier(raw, usage) => {
let mut flags = 0;