diff --git a/src/frag.glsl b/src/frag.glsl index 789085182f4113c781f8e1414b0f2d7ed278dd54..18fc53d5b86900c884ecb60e56fb88e04bc990cf 100644 --- a/src/frag.glsl +++ b/src/frag.glsl @@ -1,6 +1,7 @@ // global fragment shader #version 460 +#extension GL_EXT_mesh_shader:require #include "include.glsl" #ifdef implicit @@ -53,6 +54,10 @@ const uint MAX_STEPS=50; #endif #include "intervals.glsl" +layout(set=0,binding=20)restrict readonly buffer fragmentMasks{ + uint8_t masks[][masklen]; +}fragmentpassmasks; + #ifdef debug vec3 getNormal(vec3 p,float dens){ vec3 n; @@ -95,7 +100,8 @@ vec2 spheretracing(vec3 ori,vec3 dir,out vec3 p){ //Implicit Surface Entrypoint void main(){ - default_mask(); + //default_mask(); + mask = fragmentpassmasks.masks[gl_PrimitiveID]; vec3 raypos=vertexInput.position.xyz; vec3 p; vec3 raydir=normalize(raypos-(inverse(pc.world)*vec4(camera_uniforms.campos,1)).xyz); diff --git a/src/implicit.mesh.glsl b/src/implicit.mesh.glsl index a6badef5b41913d9a22928c3593278079e8656e6..182c116f6f1152a38695d68ce9368508332d270f 100644 --- a/src/implicit.mesh.glsl +++ b/src/implicit.mesh.glsl @@ -14,14 +14,12 @@ layout(location=0)out VertexOutput vec4 position; }vertexOutput[]; +layout(set=0,binding=20)restrict writeonly buffer fragmentMasks{ + uint8_t masks[][masklen]; +}fragmentpassmasks; + void main() -{ - uint iid=gl_LocalInvocationID.x; - - vec4 offset=vec4(0.,0.,gl_GlobalInvocationID.x,0.); - - vec3 signingvec=sign((inverse(pc.world)*vec4(camera_uniforms.campos,1)).xyz); - +{ //clear_stacks(); default_mask(); @@ -53,6 +51,8 @@ void main() uint vindex = gl_LocalInvocationID.x*8; uint pindex = gl_LocalInvocationID.x*6; + int GlobalInvocationIndex = int(gl_GlobalInvocationID.z*gl_NumWorkGroups.x*gl_NumWorkGroups.y+gl_GlobalInvocationID.y*gl_NumWorkGroups.x+gl_GlobalInvocationID.x); + //adjust scale and position for (int i = 0; i<8; i++) { @@ -62,10 +62,13 @@ void main() positions[i].z += (bounds[2]-bounds[5])*0.25 * (floor(gl_LocalInvocationID.x/16.)-1.5+gl_WorkGroupID.z*2.); } + bvec3 signingvec=greaterThan((inverse(pc.world)*vec4(camera_uniforms.campos,1)).xyz,(positions[0].xyz+positions[7].xyz)/2); + float[2] check = scene(vec3[2](vec3(positions[0].xyz),vec3(positions[7].xyz)), true); if ((check[0] < 0) && (check[1] > 0)) { - //mat4 sw=pc.world; + fragmentpassmasks.masks[GlobalInvocationIndex]=mask; + gl_MeshVerticesEXT[vindex+0].gl_Position=mvp*(positions[0]); gl_MeshVerticesEXT[vindex+1].gl_Position=mvp*(positions[1]); gl_MeshVerticesEXT[vindex+2].gl_Position=mvp*(positions[2]); @@ -83,27 +86,34 @@ void main() vertexOutput[vindex+6].position=(positions[6]); vertexOutput[vindex+7].position=(positions[7]); - if(signingvec.x>0){ + if(signingvec.x){ gl_PrimitiveTriangleIndicesEXT[pindex+0]=uvec3(4,5,6)+uvec3(vindex); gl_PrimitiveTriangleIndicesEXT[pindex+1]=uvec3(5,6,7)+uvec3(vindex); }else{ gl_PrimitiveTriangleIndicesEXT[pindex+0]=uvec3(0,1,2)+uvec3(vindex); gl_PrimitiveTriangleIndicesEXT[pindex+1]=uvec3(1,2,3)+uvec3(vindex); } - if(signingvec.y>0){ + if(signingvec.y){ gl_PrimitiveTriangleIndicesEXT[pindex+2]=uvec3(2,3,6)+uvec3(vindex); gl_PrimitiveTriangleIndicesEXT[pindex+3]=uvec3(7,3,6)+uvec3(vindex); }else{ gl_PrimitiveTriangleIndicesEXT[pindex+2]=uvec3(0,1,4)+uvec3(vindex); gl_PrimitiveTriangleIndicesEXT[pindex+3]=uvec3(5,1,4)+uvec3(vindex); } - if(signingvec.z>0){ + if(signingvec.z){ gl_PrimitiveTriangleIndicesEXT[pindex+4]=uvec3(1,3,5)+uvec3(vindex); gl_PrimitiveTriangleIndicesEXT[pindex+5]=uvec3(3,5,7)+uvec3(vindex); }else{ gl_PrimitiveTriangleIndicesEXT[pindex+4]=uvec3(0,2,4)+uvec3(vindex); gl_PrimitiveTriangleIndicesEXT[pindex+5]=uvec3(2,4,6)+uvec3(vindex); } + + gl_MeshPrimitivesEXT[pindex+0].gl_PrimitiveID=GlobalInvocationIndex; + gl_MeshPrimitivesEXT[pindex+1].gl_PrimitiveID=GlobalInvocationIndex; + gl_MeshPrimitivesEXT[pindex+2].gl_PrimitiveID=GlobalInvocationIndex; + gl_MeshPrimitivesEXT[pindex+3].gl_PrimitiveID=GlobalInvocationIndex; + gl_MeshPrimitivesEXT[pindex+4].gl_PrimitiveID=GlobalInvocationIndex; + gl_MeshPrimitivesEXT[pindex+5].gl_PrimitiveID=GlobalInvocationIndex; } else { gl_MeshVerticesEXT[vindex+0].gl_Position=vec4(0,0,0,1); @@ -115,11 +125,18 @@ void main() gl_MeshVerticesEXT[vindex+6].gl_Position=vec4(0,0,0,1); gl_MeshVerticesEXT[vindex+7].gl_Position=vec4(0,0,0,1); - gl_PrimitiveTriangleIndicesEXT[pindex+0]=uvec3(0,0,0); - gl_PrimitiveTriangleIndicesEXT[pindex+1]=uvec3(0,0,0); - gl_PrimitiveTriangleIndicesEXT[pindex+2]=uvec3(0,0,0); - gl_PrimitiveTriangleIndicesEXT[pindex+3]=uvec3(0,0,0); - gl_PrimitiveTriangleIndicesEXT[pindex+4]=uvec3(0,0,0); - gl_PrimitiveTriangleIndicesEXT[pindex+5]=uvec3(0,0,0); + gl_PrimitiveTriangleIndicesEXT[pindex+0]=uvec3(vindex); + gl_PrimitiveTriangleIndicesEXT[pindex+1]=uvec3(vindex); + gl_PrimitiveTriangleIndicesEXT[pindex+2]=uvec3(vindex); + gl_PrimitiveTriangleIndicesEXT[pindex+3]=uvec3(vindex); + gl_PrimitiveTriangleIndicesEXT[pindex+4]=uvec3(vindex); + gl_PrimitiveTriangleIndicesEXT[pindex+5]=uvec3(vindex); + + gl_MeshPrimitivesEXT[pindex+0].gl_PrimitiveID=0; + gl_MeshPrimitivesEXT[pindex+1].gl_PrimitiveID=0; + gl_MeshPrimitivesEXT[pindex+2].gl_PrimitiveID=0; + gl_MeshPrimitivesEXT[pindex+3].gl_PrimitiveID=0; + gl_MeshPrimitivesEXT[pindex+4].gl_PrimitiveID=0; + gl_MeshPrimitivesEXT[pindex+5].gl_PrimitiveID=0; } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index c71dcbadaacb084cc01ac492d08ed653f9a1878b..5218fb5336252a27d0948ef0546089200dc54d24 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ use cgmath::{ use std::io::Cursor; use std::{sync::Arc, time::Instant}; use vulkano::buffer::allocator::{SubbufferAllocator, SubbufferAllocatorCreateInfo}; +use vulkano::buffer::{Buffer, BufferAllocateInfo, Subbuffer}; use vulkano::command_buffer::allocator::StandardCommandBufferAllocator; use vulkano::descriptor_set::allocator::StandardDescriptorSetAllocator; use vulkano::descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet}; @@ -14,7 +15,7 @@ use vulkano::format::Format; use vulkano::half::f16; use vulkano::image::view::ImageViewCreateInfo; use vulkano::image::{AttachmentImage, SampleCount}; -use vulkano::memory::allocator::StandardMemoryAllocator; +use vulkano::memory::allocator::{MemoryAllocatePreference, MemoryUsage, StandardMemoryAllocator}; use vulkano::pipeline::graphics::depth_stencil::DepthStencilState; use vulkano::pipeline::graphics::multisample::MultisampleState; use vulkano::pipeline::graphics::rasterization::CullMode; @@ -100,6 +101,7 @@ fn main() { let device_extensions = DeviceExtensions { khr_swapchain: true, ext_mesh_shader: true, + khr_fragment_shading_rate: true, ..DeviceExtensions::empty() }; @@ -149,10 +151,12 @@ fn main() { mesh_shader: true, task_shader: true, sample_rate_shading: true, - shader_float16: true, + //shader_float16: true, shader_int16: true, shader_int8: true, storage_buffer8_bit_access: true, + geometry_shader: true, + primitive_fragment_shading_rate: true, ..Features::empty() }, ..Default::default() @@ -356,7 +360,7 @@ fn main() { depth_range: 0.0..1.0, }; - let [RES_X, RES_Y] = images[0].dimensions().width_height(); + //let [RES_X, RES_Y] = images[0].dimensions().width_height(); let ([mut mesh_pipeline, mut implicit_pipeline], mut framebuffers) = window_size_dependent_setup( &memory_allocator, @@ -376,8 +380,6 @@ fn main() { let mut recreate_swapchain = false; let mut previous_frame_end = Some(sync::now(device.clone()).boxed()); - let mut render_start = Instant::now(); - let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone()); let uniform_buffer = SubbufferAllocator::new( @@ -446,6 +448,10 @@ fn main() { .lights .push(Light::new([-4., 6., -8.], [8., 4., 1.], 0.05)); + let fragment_masks_buffer = object_size_dependent_setup(&memory_allocator, &gstate); + + let mut render_start = Instant::now(); + event_loop.run(move |event, _, control_flow| { if let Event::WindowEvent { event: we, .. } = &event { if !gui.update(we) { @@ -794,6 +800,7 @@ fn main() { //WriteDescriptorSet::buffer(10, csg_mat4s.clone()), //WriteDescriptorSet::buffer(11, csg_mats.clone()), WriteDescriptorSet::buffer(12, csg_depends.clone()), + WriteDescriptorSet::buffer(20, fragment_masks_buffer.clone()), ], ) .unwrap(); @@ -1028,6 +1035,8 @@ where .build(allocator.device().clone()) .unwrap(); + println!("Recompiling implicit pipeline... (may take up to 10 minutes)"); + let implicit_pipeline = GraphicsPipeline::start() .render_pass(Subpass::from(render_pass.clone(), 0).unwrap()) .vertex_input_state(OVertex::per_vertex()) @@ -1058,5 +1067,25 @@ where .build(allocator.device().clone()) .unwrap(); + println!("Implicit pipeline compiled"); + ([mesh_pipeline, implicit_pipeline], framebuffers) } + +fn object_size_dependent_setup( + allocator: &StandardMemoryAllocator, + state: &GState, +) -> Subbuffer<[[u8; 29]]> { + let fragment_masks_buffer = Buffer::new_slice( + allocator.clone(), + BufferAllocateInfo { + buffer_usage: BufferUsage::STORAGE_BUFFER, + memory_usage: MemoryUsage::GpuOnly, + allocate_preference: MemoryAllocatePreference::AlwaysAllocate, + ..Default::default() + }, + (state.csg.len() * (4 * 4 * 4) * (3 * 3 * 3) * 29) as u64, + ) + .unwrap(); + fragment_masks_buffer +}