From 9534da89a226433278c3e8984df46633ff3c9aec Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Thu, 27 Feb 2025 16:41:18 +0100 Subject: [PATCH] vulkan: store tex vertices in buffer --- src/gfx_apis/vulkan/renderer.rs | 98 ++++++++++++++------- src/gfx_apis/vulkan/shaders.rs | 20 ++++- src/gfx_apis/vulkan/shaders/tex.common.glsl | 16 +++- src/gfx_apis/vulkan/shaders/tex.vert | 13 +-- 4 files changed, 100 insertions(+), 47 deletions(-) diff --git a/src/gfx_apis/vulkan/renderer.rs b/src/gfx_apis/vulkan/renderer.rs index 5637527e..4fda1a63 100644 --- a/src/gfx_apis/vulkan/renderer.rs +++ b/src/gfx_apis/vulkan/renderer.rs @@ -22,8 +22,9 @@ use { semaphore::VulkanSemaphore, shaders::{ FILL_FRAG, FILL_VERT, FillPushConstants, LEGACY_FILL_FRAG, LEGACY_FILL_VERT, - LEGACY_TEX_FRAG, LEGACY_TEX_VERT, LegacyFillPushConstants, OUT_FRAG, OUT_VERT, - OutPushConstants, TEX_FRAG, TEX_VERT, TexPushConstants, VulkanShader, + LEGACY_TEX_FRAG, LEGACY_TEX_VERT, LegacyFillPushConstants, LegacyTexPushConstants, + OUT_FRAG, OUT_VERT, OutPushConstants, TEX_FRAG, TEX_VERT, TexPushConstants, + TexVertex, VulkanShader, }, transfer_functions::{TF_LINEAR, TF_SRGB}, }, @@ -183,6 +184,8 @@ struct VulkanTexOp { alpha: f32, source_type: TexSourceType, copy_type: TexCopyType, + range_address: DeviceAddress, + instances: u32, } struct VulkanFillOp { @@ -376,18 +379,23 @@ impl VulkanRenderer { let fill_opaque = create_fill_pipeline(false)?; let fill_alpha = create_fill_pipeline(true)?; let create_tex_pipeline = |src_has_alpha, has_alpha_mult| { - self.device - .create_pipeline::(PipelineCreateInfo { - format, - vert: self.tex_vert_shader.clone(), - frag: self.tex_frag_shader.clone(), - blend: src_has_alpha || has_alpha_mult, - src_has_alpha, - has_alpha_mult, - eotf, - oetf, - frag_descriptor_set_layout: Some(self.tex_descriptor_set_layout.clone()), - }) + let push_size = if self.device.descriptor_buffer.is_some() { + size_of::() + } else { + size_of::() + }; + let info = PipelineCreateInfo { + format, + vert: self.tex_vert_shader.clone(), + frag: self.tex_frag_shader.clone(), + blend: src_has_alpha || has_alpha_mult, + src_has_alpha, + has_alpha_mult, + eotf, + oetf, + frag_descriptor_set_layout: Some(self.tex_descriptor_set_layout.clone()), + }; + self.device.create_pipeline2(info, push_size) }; let tex_opaque = create_tex_pipeline(false, false)?; let tex_alpha = create_tex_pipeline(true, false)?; @@ -527,8 +535,16 @@ impl VulkanRenderer { } mops.push(VulkanOp::Fill(f)); } - VulkanOp::Tex(_) => { - mops.push(op); + VulkanOp::Tex(mut c) => { + c.range_address = memory.data_buffer.len() as DeviceAddress; + c.instances = c.range.len() as u32; + for &[pos, tex_pos] in &memory.tex_targets[c.range.clone()] { + let vertex = TexVertex { pos, tex_pos }; + memory + .data_buffer + .extend_from_slice(uapi::as_bytes(&vertex)); + } + mops.push(VulkanOp::Tex(c)); } } } @@ -630,6 +646,8 @@ impl VulkanRenderer { alpha: ct.alpha.unwrap_or_default(), source_type, copy_type, + range_address: 0, + instances: 0, })); } } @@ -669,7 +687,9 @@ impl VulkanRenderer { VulkanOp::Fill(f) => { f.range_address += buffer.buffer.address; } - VulkanOp::Tex(_) => {} + VulkanOp::Tex(c) => { + c.range_address += buffer.buffer.address; + } } } } @@ -988,6 +1008,10 @@ impl VulkanRenderer { .image_view(tex.texture_view) .image_layout(ImageLayout::SHADER_READ_ONLY_OPTIMAL); if let Some(db) = &self.device.descriptor_buffer { + let push = TexPushConstants { + vertices: c.range_address, + alpha: c.alpha, + }; unsafe { db.cmd_set_descriptor_buffer_offsets( buf, @@ -997,6 +1021,14 @@ impl VulkanRenderer { &[0], &[tex.descriptor_buffer_offset.get()], ); + dev.cmd_push_constants( + buf, + pipeline.pipeline_layout, + ShaderStageFlags::VERTEX | ShaderStageFlags::FRAGMENT, + 0, + uapi::as_bytes(&push), + ); + dev.cmd_draw(buf, 4, c.instances, 0, 0); } } else { let write_descriptor_set = WriteDescriptorSet::default() @@ -1011,22 +1043,22 @@ impl VulkanRenderer { slice::from_ref(&write_descriptor_set), ); } - } - for &[pos, tex_pos] in &memory.tex_targets[c.range.clone()] { - let push = TexPushConstants { - pos, - tex_pos, - alpha: c.alpha, - }; - unsafe { - dev.cmd_push_constants( - buf, - pipeline.pipeline_layout, - ShaderStageFlags::VERTEX | ShaderStageFlags::FRAGMENT, - 0, - uapi::as_bytes(&push), - ); - dev.cmd_draw(buf, 4, 1, 0, 0); + for &[pos, tex_pos] in &memory.tex_targets[c.range.clone()] { + let push = LegacyTexPushConstants { + pos, + tex_pos, + alpha: c.alpha, + }; + unsafe { + dev.cmd_push_constants( + buf, + pipeline.pipeline_layout, + ShaderStageFlags::VERTEX | ShaderStageFlags::FRAGMENT, + 0, + uapi::as_bytes(&push), + ); + dev.cmd_draw(buf, 4, 1, 0, 0); + } } } } diff --git a/src/gfx_apis/vulkan/shaders.rs b/src/gfx_apis/vulkan/shaders.rs index 4c77a00a..5fa21821 100644 --- a/src/gfx_apis/vulkan/shaders.rs +++ b/src/gfx_apis/vulkan/shaders.rs @@ -43,15 +43,33 @@ pub struct LegacyFillPushConstants { unsafe impl Packed for LegacyFillPushConstants {} +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct TexVertex { + pub pos: [[f32; 2]; 4], + pub tex_pos: [[f32; 2]; 4], +} + +unsafe impl Packed for TexVertex {} + #[derive(Copy, Clone, Debug)] #[repr(C)] pub struct TexPushConstants { + pub vertices: DeviceAddress, + pub alpha: f32, +} + +unsafe impl Packed for TexPushConstants {} + +#[derive(Copy, Clone, Debug)] +#[repr(C)] +pub struct LegacyTexPushConstants { pub pos: [[f32; 2]; 4], pub tex_pos: [[f32; 2]; 4], pub alpha: f32, } -unsafe impl Packed for TexPushConstants {} +unsafe impl Packed for LegacyTexPushConstants {} #[derive(Copy, Clone, Debug)] #[repr(C)] diff --git a/src/gfx_apis/vulkan/shaders/tex.common.glsl b/src/gfx_apis/vulkan/shaders/tex.common.glsl index 61f3ef3c..9f501e27 100644 --- a/src/gfx_apis/vulkan/shaders/tex.common.glsl +++ b/src/gfx_apis/vulkan/shaders/tex.common.glsl @@ -1,5 +1,15 @@ +#extension GL_EXT_buffer_reference : require + +struct Vertex { + vec2 pos[4]; + vec2 tex_pos[4]; +}; + +layout(buffer_reference, buffer_reference_align = 8, std430) buffer Vertices { + Vertex vertices[]; +}; + layout(push_constant, std430) uniform Data { - layout(offset = 0) vec2 pos[4]; - layout(offset = 32) vec2 tex_pos[4]; - layout(offset = 64) float mul; + Vertices vertices; + float mul; } data; diff --git a/src/gfx_apis/vulkan/shaders/tex.vert b/src/gfx_apis/vulkan/shaders/tex.vert index 7390b4a4..f4f3e13c 100644 --- a/src/gfx_apis/vulkan/shaders/tex.vert +++ b/src/gfx_apis/vulkan/shaders/tex.vert @@ -1,18 +1,11 @@ #version 450 -//#extension GL_EXT_debug_printf : enable #include "tex.common.glsl" layout(location = 0) out vec2 tex_pos; void main() { - vec2 pos; - switch (gl_VertexIndex) { - case 0: pos = data.pos[0]; tex_pos = data.tex_pos[0]; break; - case 1: pos = data.pos[1]; tex_pos = data.tex_pos[1]; break; - case 2: pos = data.pos[2]; tex_pos = data.tex_pos[2]; break; - case 3: pos = data.pos[3]; tex_pos = data.tex_pos[3]; break; - } - gl_Position = vec4(pos, 0.0, 1.0); -// debugPrintfEXT("gl_Position = %v4f, tex_pos = %v2f", gl_Position, tex_pos); + Vertex vertex = data.vertices.vertices[gl_InstanceIndex]; + gl_Position = vec4(vertex.pos[gl_VertexIndex], 0.0, 1.0); + tex_pos = vertex.tex_pos[gl_VertexIndex]; }