fix: flip Y in vertex shader, dynamic viewport/scissor, clean debug
- Fix: Y coordinate was inverted (1.0 - 2.0*y → 2.0*y - 1.0) Vulkan clip space Y is already down-up, no need to flip - Fix: dynamic viewport/scissor with viewport_count(1) + scissor_count(1) Required by validation layer even with dynamic state - Clean: removed debug eprintlns, restored default clear color - Shaders recompiled to SPIR-V
This commit is contained in:
@@ -16,12 +16,12 @@ layout(location = 1) out vec4 out_fg;
|
|||||||
layout(location = 2) out vec4 out_bg;
|
layout(location = 2) out vec4 out_bg;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 pixel = in_grid * pc.cell_size + in_pos * pc.cell_size;
|
vec2 pixel = (in_grid + in_pos) * pc.cell_size;
|
||||||
vec2 clip = vec2(
|
gl_Position = vec4(
|
||||||
2.0 * pixel.x / pc.screen_size.x - 1.0,
|
2.0 * pixel.x / pc.screen_size.x - 1.0,
|
||||||
1.0 - 2.0 * pixel.y / pc.screen_size.y
|
2.0 * pixel.y / pc.screen_size.y - 1.0,
|
||||||
|
0.0, 1.0
|
||||||
);
|
);
|
||||||
gl_Position = vec4(clip, 0.0, 1.0);
|
|
||||||
out_uv = in_atlas.xy + in_pos * in_atlas.zw;
|
out_uv = in_atlas.xy + in_pos * in_atlas.zw;
|
||||||
out_fg = in_fg;
|
out_fg = in_fg;
|
||||||
out_bg = in_bg;
|
out_bg = in_bg;
|
||||||
|
|||||||
Binary file not shown.
+37
-5
@@ -88,6 +88,7 @@ pub struct VulkanRenderer {
|
|||||||
descriptor_pool: vk::DescriptorPool,
|
descriptor_pool: vk::DescriptorPool,
|
||||||
descriptor_set: vk::DescriptorSet,
|
descriptor_set: vk::DescriptorSet,
|
||||||
descriptor_set_layout: vk::DescriptorSetLayout,
|
descriptor_set_layout: vk::DescriptorSetLayout,
|
||||||
|
tick_count: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VulkanRenderer {
|
impl VulkanRenderer {
|
||||||
@@ -152,6 +153,7 @@ impl VulkanRenderer {
|
|||||||
atlas_image, atlas_memory, atlas_view, atlas_sampler, atlas_map,
|
atlas_image, atlas_memory, atlas_view, atlas_sampler, atlas_map,
|
||||||
instance_buffer, instance_memory, instance_ptr, instance_count,
|
instance_buffer, instance_memory, instance_ptr, instance_count,
|
||||||
descriptor_pool, descriptor_set, descriptor_set_layout,
|
descriptor_pool, descriptor_set, descriptor_set_layout,
|
||||||
|
tick_count: 0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,6 +254,20 @@ impl VulkanRenderer {
|
|||||||
|
|
||||||
device.cmd_begin_render_pass(cmd, &rp_info, vk::SubpassContents::INLINE);
|
device.cmd_begin_render_pass(cmd, &rp_info, vk::SubpassContents::INLINE);
|
||||||
device.cmd_bind_pipeline(cmd, vk::PipelineBindPoint::GRAPHICS, self.pipeline);
|
device.cmd_bind_pipeline(cmd, vk::PipelineBindPoint::GRAPHICS, self.pipeline);
|
||||||
|
|
||||||
|
let viewport = vk::Viewport {
|
||||||
|
x: 0.0, y: 0.0,
|
||||||
|
width: self.swapchain_extent.width as f32,
|
||||||
|
height: self.swapchain_extent.height as f32,
|
||||||
|
min_depth: 0.0, max_depth: 1.0,
|
||||||
|
};
|
||||||
|
let scissor = vk::Rect2D {
|
||||||
|
offset: vk::Offset2D::default(),
|
||||||
|
extent: self.swapchain_extent,
|
||||||
|
};
|
||||||
|
device.cmd_set_viewport(cmd, 0, std::slice::from_ref(&viewport));
|
||||||
|
device.cmd_set_scissor(cmd, 0, std::slice::from_ref(&scissor));
|
||||||
|
|
||||||
device.cmd_bind_vertex_buffers(cmd, 0, &[self.vertex_buffer, self.instance_buffer], &[0, 0]);
|
device.cmd_bind_vertex_buffers(cmd, 0, &[self.vertex_buffer, self.instance_buffer], &[0, 0]);
|
||||||
device.cmd_bind_index_buffer(cmd, self.index_buffer, 0, vk::IndexType::UINT16);
|
device.cmd_bind_index_buffer(cmd, self.index_buffer, 0, vk::IndexType::UINT16);
|
||||||
device.cmd_bind_descriptor_sets(cmd, vk::PipelineBindPoint::GRAPHICS,
|
device.cmd_bind_descriptor_sets(cmd, vk::PipelineBindPoint::GRAPHICS,
|
||||||
@@ -285,6 +301,7 @@ impl VulkanRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.frame_index = (self.frame_index + 1) % MAX_FRAMES;
|
self.frame_index = (self.frame_index + 1) % MAX_FRAMES;
|
||||||
|
self.tick_count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn grid_w(&self) -> usize { self.grid_w }
|
pub fn grid_w(&self) -> usize { self.grid_w }
|
||||||
@@ -330,11 +347,23 @@ fn create_instance(entry: &ash::Entry) -> Result<ash::Instance, String> {
|
|||||||
let app_info = vk::ApplicationInfo::default()
|
let app_info = vk::ApplicationInfo::default()
|
||||||
.application_name(&app_name)
|
.application_name(&app_name)
|
||||||
.api_version(vk::API_VERSION_1_2);
|
.api_version(vk::API_VERSION_1_2);
|
||||||
let ext_names: Vec<CString> = vec![
|
|
||||||
|
let mut ext_names: Vec<CString> = vec![
|
||||||
CString::new("VK_KHR_surface").unwrap(),
|
CString::new("VK_KHR_surface").unwrap(),
|
||||||
CString::new("VK_KHR_xlib_surface").unwrap(),
|
CString::new("VK_KHR_xlib_surface").unwrap(),
|
||||||
CString::new("VK_KHR_wayland_surface").unwrap(),
|
CString::new("VK_KHR_wayland_surface").unwrap(),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Add debug utils extension if available
|
||||||
|
let avail_exts = unsafe { entry.enumerate_instance_extension_properties(None) }.unwrap_or_default();
|
||||||
|
let has_debug_utils = avail_exts.iter().any(|e| {
|
||||||
|
let name = unsafe { std::ffi::CStr::from_ptr(e.extension_name.as_ptr() as *const i8) };
|
||||||
|
name.to_str().unwrap_or("") == "VK_EXT_debug_utils"
|
||||||
|
});
|
||||||
|
if has_debug_utils {
|
||||||
|
ext_names.push(CString::new("VK_EXT_debug_utils").unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
let ext_ptrs: Vec<*const i8> = ext_names.iter().map(|n| n.as_ptr()).collect();
|
let ext_ptrs: Vec<*const i8> = ext_names.iter().map(|n| n.as_ptr()).collect();
|
||||||
let create_info = vk::InstanceCreateInfo::default()
|
let create_info = vk::InstanceCreateInfo::default()
|
||||||
.application_info(&app_info)
|
.application_info(&app_info)
|
||||||
@@ -497,9 +526,11 @@ fn create_pipeline(device: &ash::Device, rp: vk::RenderPass, ds_layout: vk::Desc
|
|||||||
let vi = vk::PipelineVertexInputStateCreateInfo::default()
|
let vi = vk::PipelineVertexInputStateCreateInfo::default()
|
||||||
.vertex_binding_descriptions(&bindings).vertex_attribute_descriptions(&attrs);
|
.vertex_binding_descriptions(&bindings).vertex_attribute_descriptions(&attrs);
|
||||||
let ia = vk::PipelineInputAssemblyStateCreateInfo::default().topology(vk::PrimitiveTopology::TRIANGLE_LIST);
|
let ia = vk::PipelineInputAssemblyStateCreateInfo::default().topology(vk::PrimitiveTopology::TRIANGLE_LIST);
|
||||||
let vp = vk::Viewport { x: 0.0, y: 0.0, width: 1.0, height: 1.0, min_depth: 0.0, max_depth: 1.0 };
|
let dynamic_states = [vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR];
|
||||||
let sc = vk::Rect2D { offset: vk::Offset2D::default(), extent: vk::Extent2D { width: 4096, height: 4096 } };
|
let dynamic_state = vk::PipelineDynamicStateCreateInfo::default().dynamic_states(&dynamic_states);
|
||||||
let vs_state = vk::PipelineViewportStateCreateInfo::default().viewports(std::slice::from_ref(&vp)).scissors(std::slice::from_ref(&sc));
|
let vs_state = vk::PipelineViewportStateCreateInfo::default()
|
||||||
|
.viewport_count(1)
|
||||||
|
.scissor_count(1);
|
||||||
let rs = vk::PipelineRasterizationStateCreateInfo::default().line_width(1.0).cull_mode(vk::CullModeFlags::NONE);
|
let rs = vk::PipelineRasterizationStateCreateInfo::default().line_width(1.0).cull_mode(vk::CullModeFlags::NONE);
|
||||||
let ms = vk::PipelineMultisampleStateCreateInfo::default().rasterization_samples(vk::SampleCountFlags::TYPE_1);
|
let ms = vk::PipelineMultisampleStateCreateInfo::default().rasterization_samples(vk::SampleCountFlags::TYPE_1);
|
||||||
let cba = vk::PipelineColorBlendAttachmentState::default().color_write_mask(vk::ColorComponentFlags::RGBA);
|
let cba = vk::PipelineColorBlendAttachmentState::default().color_write_mask(vk::ColorComponentFlags::RGBA);
|
||||||
@@ -513,7 +544,8 @@ fn create_pipeline(device: &ash::Device, rp: vk::RenderPass, ds_layout: vk::Desc
|
|||||||
let pi = vk::GraphicsPipelineCreateInfo::default()
|
let pi = vk::GraphicsPipelineCreateInfo::default()
|
||||||
.stages(&stages).vertex_input_state(&vi).input_assembly_state(&ia)
|
.stages(&stages).vertex_input_state(&vi).input_assembly_state(&ia)
|
||||||
.viewport_state(&vs_state).rasterization_state(&rs).multisample_state(&ms)
|
.viewport_state(&vs_state).rasterization_state(&rs).multisample_state(&ms)
|
||||||
.color_blend_state(&cb).layout(layout).render_pass(rp).subpass(0);
|
.color_blend_state(&cb).dynamic_state(&dynamic_state)
|
||||||
|
.layout(layout).render_pass(rp).subpass(0);
|
||||||
let pipes = unsafe { device.create_graphics_pipelines(vk::PipelineCache::null(), std::slice::from_ref(&pi), None) }
|
let pipes = unsafe { device.create_graphics_pipelines(vk::PipelineCache::null(), std::slice::from_ref(&pi), None) }
|
||||||
.map_err(|(_, e)| format!("pipeline: {e:?}"))?;
|
.map_err(|(_, e)| format!("pipeline: {e:?}"))?;
|
||||||
unsafe { device.destroy_shader_module(vm, None); device.destroy_shader_module(fm, None); }
|
unsafe { device.destroy_shader_module(vm, None); device.destroy_shader_module(fm, None); }
|
||||||
|
|||||||
Reference in New Issue
Block a user