diff --git a/assets/shaders/convert.comp.spv b/assets/shaders/convert.comp.spv index eef316d..c8447df 100644 Binary files a/assets/shaders/convert.comp.spv and b/assets/shaders/convert.comp.spv differ diff --git a/assets/shaders/oit.frag.spv b/assets/shaders/oit.frag.spv index c0ecd82..4f54526 100644 Binary files a/assets/shaders/oit.frag.spv and b/assets/shaders/oit.frag.spv differ diff --git a/assets/shaders/pbr.frag.spv b/assets/shaders/pbr.frag.spv index 36729ed..e69ab73 100644 Binary files a/assets/shaders/pbr.frag.spv and b/assets/shaders/pbr.frag.spv differ diff --git a/src/gears/game.d b/src/gears/game.d index 12f6c34..aebefec 100644 --- a/src/gears/game.d +++ b/src/gears/game.d @@ -2,6 +2,7 @@ import aliases; import includes; import renderer : Destroy; import renderer; +import vulkan; import util; import alloc; import platform; @@ -24,6 +25,9 @@ struct Game Pipeline ui_pipeline; Pipeline oit_pipeline; + ImageView draw_image, depth_image; + ImageView aux_image; + GlobalUniforms globals; PushConst pc; @@ -31,9 +35,14 @@ struct Game Camera camera; - Model model; -} + Model tree; + Model rock; + Model magic_rock; + Model log; + Model stump; + SLList!(Model) models; +} Game InitGame(PlatformWindow* window) @@ -49,15 +58,25 @@ InitGame(PlatformWindow* window) ambient_color: Vec4(0.7, 0.7, 0.7, 1.0), }, }; + + Extent ext = GetExtent(&g.rd); + + CreateImageView(&g.rd, &g.draw_image, ext.w, ext.h, GetDrawImageFormat(&g.rd), IU.Draw, false); + CreateImageView(&g.rd, &g.depth_image, ext.w, ext.h, FMT.D_SF32, IU.Depth, true); + CreateImageView(&g.rd, &g.aux_image, ext.w, ext.h, FMT.R_U32, IU.Storage); GfxPipelineInfo triangle_info = { vertex_shader: "shaders/triangle.vert.spv", frag_shader: "shaders/triangle.frag.spv", + draw_image: &g.draw_image, + depth_image: &g.depth_image, }; GfxPipelineInfo ui_info = { vertex_shader: "shaders/gui.vert.spv", frag_shader: "shaders/gui.frag.spv", + draw_image: &g.draw_image, + depth_image: &g.depth_image, input_rate: IR.Instance, input_rate_stride: UIVertex.sizeof, vertex_attributes: [ @@ -71,6 +90,8 @@ InitGame(PlatformWindow* window) GfxPipelineInfo pbr_info = { vertex_shader: "shaders/pbr.vert.spv", frag_shader: "shaders/pbr.frag.spv", + draw_image: &g.draw_image, + depth_image: &g.depth_image, input_rate_stride: Vertex.sizeof, vertex_attributes: [ { binding: 0, location: 0, format: FMT.RGBA_F32, offset: 0 }, @@ -84,36 +105,96 @@ InitGame(PlatformWindow* window) GfxPipelineInfo oit_info = { vertex_shader: "shaders/full_screen_triangle.vert.spv", frag_shader: "shaders/oit.frag.spv", + draw_image: &g.draw_image, + depth_image: &g.depth_image, }; CompPipelineInfo gradient_info = { shader: "shaders/gradient.comp.spv", }; - Logf("pbr"); g.pbr_pipeline = BuildGfxPipeline(&g.rd, &pbr_info); - Logf("triangle"); g.triangle_pipeline = BuildGfxPipeline(&g.rd, &triangle_info); - Logf("ui"); g.ui_pipeline = BuildGfxPipeline(&g.rd, &ui_info); - Logf("oit"); g.oit_pipeline = BuildGfxPipeline(&g.rd, &oit_info); g.compute_pipeline = BuildCompPipeline(&g.rd, &gradient_info); PrintShader(&g.rd, &g.pbr_pipeline, VK_SHADER_STAGE_VERTEX_BIT); - g.model = LoadModel(&g.rd, "models/Tree01.m3d"); + g.rock = LoadModel(&g.rd, "models/BigRock01.m3d"); + g.tree = LoadModel(&g.rd, "models/Tree01.m3d"); + g.magic_rock = LoadModel(&g.rd, "models/MagicRock01.m3d"); + g.log = LoadModel(&g.rd, "models/Log01.m3d"); + g.stump = LoadModel(&g.rd, "models/Stump01.m3d"); SetClearColor(&g.rd, Vec4(0.3, 0.5, 0.9, 1.0)); ClearColorEnabled(&g.rd, true); + assert(g.aux_image.view != null); + + UpdateAuxImage(&g.rd, &g.aux_image); + return g; } +void +Copy(Model* dst, Model* src) +{ + dst.vertex_buffer = src.vertex_buffer; + dst.index_buffer = src.index_buffer; + dst.parts = src.parts; + dst.materials = src.materials; + dst.textures = src.textures; +} + void ProcessInputs(Game* g, Camera* cam) { + foreach(i; 0 .. g.window.inputs.count) + { + InputEvent event = g.window.inputs.events[i]; + switch(event.key) + { + case Input.One: + { + Node!(Model)* node = Alloc!(Node!(Model)); + Copy(&node.value, &g.tree); + node.value.pos = cam.pos; + PushFront(&g.models, node, null); + } break; + case Input.Two: + { + Node!(Model)* node = Alloc!(Node!(Model)); + Copy(&node.value, &g.rock); + node.value.pos = cam.pos; + PushFront(&g.models, node, null); + } break; + case Input.Three: + { + Node!(Model)* node = Alloc!(Node!(Model)); + Copy(&node.value, &g.magic_rock); + node.value.pos = cam.pos; + PushFront(&g.models, node, null); + } break; + case Input.Four: + { + Node!(Model)* node = Alloc!(Node!(Model)); + Copy(&node.value, &g.log); + node.value.pos = cam.pos; + PushFront(&g.models, node, null); + } break; + case Input.Five: + { + Node!(Model)* node = Alloc!(Node!(Model)); + Copy(&node.value, &g.stump); + node.value.pos = cam.pos; + PushFront(&g.models, node, null); + } break; + default: break; + } + } + HandleInputs(cam, &g.window.inputs); } @@ -126,6 +207,12 @@ Cycle(Game* g) ProcessInputs(g, &g.camera); + ResizeDrawImageIfNeeded(&g.rd, &g.draw_image); + ResizeDrawImageIfNeeded(&g.rd, &g.depth_image); + ResizeDrawImageIfNeeded(&g.rd, &g.aux_image); + + UpdateAuxImage(&g.rd, &g.aux_image); + //Sort(g, g.camera.pos, &g.model); //Update(g, &g.camera); @@ -134,7 +221,13 @@ Cycle(Game* g) BeginFrame(&g.rd); + PrepAuxImage(&g.rd.vk, &g.aux_image); + Bind(&g.rd, &g.compute_pipeline); + + ClearColor(&g.rd, &g.aux_image, Vec4(0.0)); + + ImageBarrier(&g.rd); Extent ext = GetExtent(&g.rd); f32 aspect = (cast(f32)ext.x) / (cast(f32)ext.y); @@ -146,36 +239,56 @@ Cycle(Game* g) g.globals.res.y = ext.y; SetUniform(&g.rd, &g.globals); - //DrawRect(&g.rd, 150.0, 300.0, 500.0, 700.0, Vec4(0.0, 0.0, 1.0, 1.0)); - - //PrepComputeDrawImage(&g.rd); - - //Dispatch(&g.rd); - - BeginRender(&g.rd); + BeginRendering(&g.rd, &g.draw_image, &g.depth_image); Bind(&g.rd, &g.ui_pipeline); BindUIBuffers(&g.rd); - //DrawUI(&g.rd); - Bind(&g.rd, &g.triangle_pipeline); - //Draw(&g.rd, 3, 1); - Bind(&g.rd, &g.pbr_pipeline); g.pc.model_matrix = Mat4Identity(); - DrawModel(g, &g.model); - FinishFrame(&g.rd); + Node!(Model)* model = g.models.first; + for(;;) + { + if (model == null) + { + break; + } + + DrawModel(g, &model.value); + model = model.next; + } + + /* + ImageBarrier(&g.rd); + + Bind(&g.rd, &g.oit_pipeline); + + Draw(&g.rd, 3, 1); + */ + + FinishRendering(&g.rd); + + //ImageBarrier(&g.rd); + + //BeginRendering(&g.rd, &g.draw_image, &g.depth_image); + + + //FinishRendering(&g.rd); + + Submit(&g.rd, &g.draw_image); } pragma(inline): void DrawModel(Game* g, Model* model) { BindBuffers(&g.rd, &model.index_buffer, &model.vertex_buffer); + g.pc.model_matrix = Mat4Identity(); + Translate(&g.pc.model_matrix, model.pos); foreach(i, part; model.parts) { g.pc.mat_id = part.mat; @@ -192,7 +305,18 @@ Destroy(Game* g) Destroy(&g.rd, &g.triangle_pipeline); Destroy(&g.rd, &g.ui_pipeline); Destroy(&g.rd, &g.compute_pipeline); - Destroy(&g.rd, &g.model); + + Node!(Model)* model = g.models.first; + for(;;) + { + if (model == null) + { + break; + } + + Destroy(&g.rd, &model.value); + model = model.next; + } Destroy(&g.rd); } diff --git a/src/gears/main.d b/src/gears/main.d index 0683ddc..aaa3db9 100644 --- a/src/gears/main.d +++ b/src/gears/main.d @@ -15,6 +15,8 @@ import core.stdc.string : memcpy; // 3. Determine how to better handle inputs // 4. Make assets loaded from the disk in debug mode // 5. Set up multisampling +// 6. Remove renderer.d and just move the interface into vulkan.d +// 7. Remove dynamic rendering void main(string[] argv) { diff --git a/src/gears/renderer.d b/src/gears/renderer.d index aa476e9..6e8ca45 100644 --- a/src/gears/renderer.d +++ b/src/gears/renderer.d @@ -4,7 +4,7 @@ import assets; import util; import alloc; import vulkan; -import vulkan : Destroy, Init, Draw, DrawIndexed, Bind, BindUIBuffers, BeginRender, SetUniform, PrepComputeDrawImage, Dispatch, FinishFrame, BeginFrame, WaitIdle, PushConstants, BindBuffers, SetClearColor, ImageBarrier; +import vulkan : Destroy, Init, Draw, DrawIndexed, Bind, BindUIBuffers, BeginRendering, SetUniform, PrepComputeDrawImage, Dispatch, SubmitAndPresent, BeginFrame, WaitIdle, PushConstants, BindBuffers, SetClearColor, ImageBarrier, CreateImageView, GetDrawImageFormat, FinishRendering, UpdateAuxImage, ClearColor, SubmitAndPresent; import assets; import std.math.traits : isNaN; import util : Logf; @@ -25,6 +25,20 @@ enum InputRate : int alias IR = InputRate; +enum ImageUsage : VkImageUsageFlagBits +{ + None = cast(VkImageUsageFlagBits)0, + Draw = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + Depth = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + Texture = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, + Convert = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, + Storage = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, + Swapchain = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, +} + +alias IU = ImageUsage; + enum Format : VkFormat { UINT = VK_FORMAT_R32_UINT, @@ -37,13 +51,14 @@ enum Format : VkFormat RG_U32 = VK_FORMAT_R32G32_UINT, RGBA_UNORM = VK_FORMAT_R8G8B8A8_UNORM, RGBA_SRGB = VK_FORMAT_R8G8B8A8_SRGB, + D_SF32 = VK_FORMAT_D32_SFLOAT, } alias FMT = Format; -enum BufferType : int +enum BufferType : VkBufferUsageFlagBits { - None = 0, + None = cast(VkBufferUsageFlagBits)0, Vertex = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, Index = VK_BUFFER_USAGE_INDEX_BUFFER_BIT, Uniform = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, @@ -54,6 +69,13 @@ enum BufferType : int alias BT = BufferType; +enum ImageLayout : VkImageLayout +{ + Undefined = VK_IMAGE_LAYOUT_UNDEFINED, + General = VK_IMAGE_LAYOUT_GENERAL, + ColorAttach = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, +} + struct GlobalUniforms { Mat4 view_matrix = Mat4Identity(); @@ -88,35 +110,24 @@ struct Specialization struct GfxPipelineInfo { - string vertex_shader; - string frag_shader; - InputRate input_rate; - u32 input_rate_stride; - Attribute[] vertex_attributes; + string vertex_shader; + string frag_shader; + InputRate input_rate; + u32 input_rate_stride; + Attribute[] vertex_attributes; Specialization vert_spec; Specialization frag_spec; + ImageView* draw_image; + ImageView* depth_image; } struct CompPipelineInfo { - string shader; - Specialization spec; + string shader; + Specialization spec; VkPipelineLayout *layout; } -struct Renderer -{ - Arena arena; - Arena temp_arena; - - Vulkan vk; - PlatformWindow* window; - - UIVertex[] ui_vertex_buf; - u32[] ui_index_buf; - u32 ui_count; -} - struct PushConst { Mat4 model_matrix; @@ -127,6 +138,8 @@ struct Extent { u32 x; u32 y; + alias x w; + alias y h; } struct UIVertex @@ -170,6 +183,54 @@ struct Model u32[] indices; } +struct Image +{ + VkImage image; + VmaAllocation alloc; + Format format; + VkImageLayout layout; + u32 w; + u32 h; + bool depth_image; + ImageUsage usage; +} + +struct BufferView +{ + Buffer base; + VkBufferView view; + + alias base this; +} + +struct ImageView +{ + Image base; + VkImageView view; + + alias base this; +} + +struct Buffer +{ + VkBuffer buffer; + VmaAllocation alloc; + u64 size; +} + +struct Renderer +{ + Arena arena; + Arena temp_arena; + + Vulkan vk; + PlatformWindow* window; + + UIVertex[] ui_vertex_buf; + u32[] ui_index_buf; + u32 ui_count; +} + Renderer InitRenderer(PlatformWindow* window) { @@ -213,12 +274,6 @@ DrawUI(Renderer* rd) DrawIndexed(rd, 6, rd.ui_count, 0); } -pragma(inline): void -FinishFrame(Renderer* rd) -{ - FinishFrame(&rd.vk); -} - pragma(inline): void Dispatch(Renderer* rd) { @@ -238,9 +293,9 @@ SetUniform(Renderer* rd, GlobalUniforms* uniforms) } pragma(inline): void -BeginRender(Renderer* rd) +BeginRendering(Renderer* rd, ImageView* draw_image, ImageView* depth_image) { - BeginRender(&rd.vk); + BeginRendering(&rd.vk, draw_image, depth_image); } pragma(inline): void @@ -645,6 +700,54 @@ ImageBarrier(Renderer* rd) ImageBarrier(&rd.vk); } +void +CreateImageView(Renderer* rd, ImageView* view, u32 w, u32 h, Format format, ImageUsage usage, bool depth_image = false) +{ + CreateImageView(&rd.vk, view, w, h, format, usage, depth_image); +} + +Format +GetDrawImageFormat(Renderer* rd) +{ + return cast(Format)GetDrawImageFormat(&rd.vk); +} + +pragma(inline): void +ResizeDrawImageIfNeeded(Renderer* rd, ImageView* view) +{ + Extent ext = GetExtent(rd); + + if (view.w != ext.w || view.h != ext.h) + { + Destroy(view, rd.vk.device, rd.vk.vma); + CreateImageView(&rd.vk, view, ext.w, ext.h, view.format, view.usage, view.depth_image); + } +} + +void +FinishRendering(Renderer* rd) +{ + FinishRendering(&rd.vk); +} + +void +Submit(Renderer* rd, ImageView* view) +{ + SubmitAndPresent(&rd.vk, view); +} + +void +UpdateAuxImage(Renderer* rd, ImageView* view) +{ + UpdateAuxImage(&rd.vk, view); +} + +void +ClearColor(Renderer* rd, ImageView* view, Vec4 color) +{ + ClearColor(&rd.vk, view, color); +} + void Destroy(Renderer* rd, Model* model) { diff --git a/src/gears/vulkan.d b/src/gears/vulkan.d index be4026b..717d170 100644 --- a/src/gears/vulkan.d +++ b/src/gears/vulkan.d @@ -4,6 +4,7 @@ import aliases; import std.stdio; import std.algorithm.comparison; import core.stdc.string : strcmp, memcpy; +import core.stdc.stdio : Printf = printf; import std.format : sformat; import util; import alloc; @@ -52,6 +53,7 @@ const char*[] VK_BASE_DEVICE_EXTENSIONS = [ cast(char*)VK_KHR_SWAPCHAIN_EXTENSION_NAME, cast(char*)VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, cast(char*)VK_KHR_8BIT_STORAGE_EXTENSION_NAME, + cast(char*)"VK_KHR_dynamic_rendering_local_read", ]; const char*[] VK_AMD_DEVICE_EXTENSIONS = [ @@ -75,15 +77,6 @@ const VkFormat[] VK_IMAGE_FORMATS = [ VK_FORMAT_R8G8B8A8_UNORM, ]; -const VkImageUsageFlags VK_DRAW_IMAGE_USAGE_FLAGS = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | - VK_IMAGE_USAGE_TRANSFER_DST_BIT | - VK_IMAGE_USAGE_STORAGE_BIT | - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - -const VkImageUsageFlags TEXTURE_IMAGE_USAGE = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; -const VkImageUsageFlags CONVERT_IMAGE_USAGE = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; -const VkImageUsageFlags OIT_IMAGE_USAGE = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; - enum StepInitialized : u32 { Renderer = 1, @@ -113,30 +106,6 @@ enum DescType : u32 alias DT = DescType; -struct Image -{ - VkImage image; - VmaAllocation alloc; - VkFormat format; - VkImageLayout layout; -} - -struct BufferView -{ - Buffer base; - VkBufferView view; - - alias base this; -} - -struct ImageView -{ - Image base; - VkImageView view; - - alias base this; -} - struct MappedBuffer(T) { Buffer base; @@ -146,13 +115,6 @@ struct MappedBuffer(T) alias base this; } -struct Buffer -{ - VkBuffer buffer; - VmaAllocation alloc; - u64 size; -} - struct DescBindings { u32[] free; @@ -550,19 +512,19 @@ BeginFrame(Vulkan* vk) } void -BeginRender(Vulkan* vk) +BeginRendering(Vulkan* vk, ImageView* draw_image, ImageView* depth_image) { // TODO: probably get rid of these - Transition(vk.cmds[vk.frame_index], &vk.draw_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - Transition(vk.cmds[vk.frame_index], &vk.depth_image, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL); + Transition(vk.cmds[vk.frame_index], draw_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + Transition(vk.cmds[vk.frame_index], depth_image, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL); VkImage image = CurrentImage(vk); Transition(vk.cmds[vk.frame_index], image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); VkRenderingAttachmentInfo col_attach = { sType: VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - imageView: vk.draw_image.view, - imageLayout: vk.draw_image.layout, + imageView: draw_image.view, + imageLayout: draw_image.layout, loadOp: (vk.enable_clear_color ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD), // CLEAR instead of LOAD if wanting to clear colors, also clearColor value (or whatever) storeOp: VK_ATTACHMENT_STORE_OP_STORE, clearValue: { @@ -572,8 +534,8 @@ BeginRender(Vulkan* vk) VkRenderingAttachmentInfo depth_attach = { sType: VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - imageView: vk.depth_image.view, - imageLayout: vk.depth_image.layout, + imageView: depth_image.view, + imageLayout: depth_image.layout, loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR, storeOp: VK_ATTACHMENT_STORE_OP_STORE, }; @@ -604,6 +566,12 @@ SetClearColor(Vulkan* vk, Vec4 color) vk.clear_color.float32[3] = color.a; } +void +PrepAuxImage(Vulkan* vk, ImageView* view) +{ + Transition(vk.cmds[vk.frame_index], view, VK_IMAGE_LAYOUT_GENERAL); +} + void PrepComputeDrawImage(Vulkan* vk) { @@ -611,21 +579,25 @@ PrepComputeDrawImage(Vulkan* vk) } void -FinishFrame(Vulkan* vk) +FinishRendering(Vulkan* vk) +{ + vkCmdEndRendering(vk.cmds[vk.frame_index]); +} + +void +SubmitAndPresent(Vulkan* vk, ImageView* draw_image) { scope(exit) { vk.last_pipeline[vk.frame_index] = null; vk.frame_index = (vk.frame_index + 1) % FRAME_OVERLAP; } - + VkImage image = CurrentImage(vk); VkSemaphore acquire_sem = vk.acquire_sems[vk.frame_index]; VkSemaphore submit_sem = vk.submit_sems[vk.image_index]; - vkCmdEndRendering(vk.cmds[vk.frame_index]); - - Transition(vk.cmds[vk.frame_index], &vk.draw_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + Transition(vk.cmds[vk.frame_index], draw_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); VkExtent2D extent = { width: vk.swapchain_extent.width, @@ -633,7 +605,7 @@ FinishFrame(Vulkan* vk) }; // TODO: Find out how to copy from same dimension images (pretty sure its not blitting) - Copy(vk.cmds[vk.frame_index], &vk.draw_image.base, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, extent, extent); + Copy(vk.cmds[vk.frame_index], &draw_image.base, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, extent, extent); Transition(vk.cmds[vk.frame_index], image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); @@ -771,7 +743,7 @@ TransferAssets(Vulkan* vk) pragma(inline): void CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, u32 ch, u8[] data) { - CreateImageView(vk, view, w, h, FMT.RGBA_UNORM, TEXTURE_IMAGE_USAGE); + CreateImageView(vk, view, w, h, FMT.RGBA_UNORM, IU.Texture); if (ch == 4) { @@ -784,7 +756,7 @@ CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, u32 ch, u8[] data) assert(Transfer(vk, &buf, data), "CreateImageView failure: Buffer Transfer error"); ImageView conv_view; - CreateImageView(vk, &conv_view, w, h, FMT.RGBA_F32, CONVERT_IMAGE_USAGE); + CreateImageView(vk, &conv_view, w, h, FMT.RGBA_F32, IU.Convert); WriteConvDescriptor(vk, &buf); WriteConvDescriptor(vk, &conv_view); @@ -906,7 +878,7 @@ CreateBufferView(Vulkan* vk, BufferView* view, u64 size, Format format) } pragma(inline): void -CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, Format format = FMT.RGBA_UNORM, VkImageUsageFlags usage) +CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, Format format, ImageUsage usage, bool depth_image = false) { VmaAllocationCreateInfo alloc_info = { usage: VMA_MEMORY_USAGE_GPU_ONLY, @@ -937,9 +909,6 @@ CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, Format format = FMT.R image_info.pQueueFamilyIndices = cast(const u32*)[vk.gfx_index, vk.tfer_index]; } - view.layout = VK_IMAGE_LAYOUT_UNDEFINED; - view.format = VK_FORMAT_R8G8B8A8_SRGB; - VkResult result = vmaCreateImage(vk.vma, &image_info, &alloc_info, &view.image, &view.alloc, null); // TODO: handle errors and realloc assert(VkCheck("CreateImageView failure: vmaCreateImage error", result), "CreateImageView failure"); @@ -950,7 +919,7 @@ CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, Format format = FMT.R viewType: VK_IMAGE_VIEW_TYPE_2D, format: format, subresourceRange: { - aspectMask: VK_IMAGE_ASPECT_COLOR_BIT, + aspectMask: (depth_image ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT), levelCount: 1, layerCount: 1, }, @@ -959,6 +928,13 @@ CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, Format format = FMT.R result = vkCreateImageView(vk.device, &view_info, null, &view.view); // TODO: also handle here assert(VkCheck("CreateImageView failure: vkCreateImageView error", result), "CreateImageView failure"); + + view.layout = VK_IMAGE_LAYOUT_UNDEFINED; + view.format = format; + view.w = w; + view.h = h; + view.depth_image = depth_image; + view.usage = usage; } u32 @@ -1378,7 +1354,7 @@ CreateGraphicsPipeline(Vulkan* vk, GfxPipelineInfo* build_info) VkPipelineDepthStencilStateCreateInfo depth_info = { sType: VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, depthTestEnable: VK_TRUE, - depthWriteEnable: VK_FALSE, + depthWriteEnable: VK_TRUE, depthCompareOp: VK_COMPARE_OP_GREATER_OR_EQUAL, depthBoundsTestEnable: VK_FALSE, stencilTestEnable: VK_FALSE, @@ -1389,8 +1365,8 @@ CreateGraphicsPipeline(Vulkan* vk, GfxPipelineInfo* build_info) VkPipelineRenderingCreateInfo rendering_info = { sType: VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, colorAttachmentCount: 1, - pColorAttachmentFormats: &vk.draw_image.format, - depthAttachmentFormat: vk.depth_image.format, + pColorAttachmentFormats: cast(VkFormat*)&build_info.draw_image.format, + depthAttachmentFormat: build_info.depth_image.format, }; VkPipelineColorBlendAttachmentState blend_state = { @@ -1555,6 +1531,25 @@ CreateComputePipeline(Vulkan* vk, CompPipelineInfo* comp_info) return pipeline; } +void +ClearColor(Vulkan* vk, ImageView* view, Vec4 color) +{ + VkImageSubresourceRange clear_range = { + aspectMask: (view.depth_image ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT), + levelCount: 1, + layerCount: 1, + }; + + vkCmdClearColorImage( + vk.cmds[vk.frame_index], + view.image, + view.layout, + cast(VkClearColorValue*)color.v, + 1, + &clear_range + ); +} + void SetUniform(Vulkan* vk, GlobalUniforms* globals) { @@ -1897,7 +1892,6 @@ InitDescriptors(Vulkan* vk) // Also add samples/supersampling scaling CreateBufferView(vk, &vk.a_buffer_view, (u32.sizeof * 2) * vk.swapchain_extent.width * vk.swapchain_extent.height, FMT.RG_U32); - CreateImageView(vk, &vk.aux_image, vk.swapchain_extent.width, vk.swapchain_extent.height, FMT.R_U32, OIT_IMAGE_USAGE); VkDescriptorBufferInfo a_buffer_info = { buffer: vk.a_buffer_view.buffer, @@ -1937,14 +1931,6 @@ InitDescriptors(Vulkan* vk) pBufferInfo: &a_buffer_info, pTexelBufferView: &vk.a_buffer_view.view, }, - { - sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - dstSet: vk.desc_sets[DT.Shared], - dstBinding: 5, - descriptorCount: 1, - descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - pImageInfo: &aux_info, - }, { sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, dstSet: vk.desc_sets[DT.Shared], @@ -1963,6 +1949,31 @@ InitDescriptors(Vulkan* vk) return success; } + +// TODO: better descriptor updating +void +UpdateAuxImage(Vulkan* vk, ImageView* view) +{ + VkDescriptorImageInfo aux_info = { + sampler: vk.oit_sampler, + imageView: view.view, + imageLayout: VK_IMAGE_LAYOUT_GENERAL, + }; + + assert(view.view != VK_NULL_HANDLE); + + VkWriteDescriptorSet write = { + sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + dstSet: vk.desc_sets[DT.Shared], + dstBinding: 5, + descriptorCount: 1, + descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + pImageInfo: &aux_info, + }; + + vkUpdateDescriptorSets(vk.device, 1, &write, 0, null); +} + void WriteDrawImageDesc(Vulkan* vk) { @@ -2243,7 +2254,7 @@ GetDrawImageFormat(Vulkan* vk) format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, - VK_DRAW_IMAGE_USAGE_FLAGS, + IU.Draw, 0, &props ); @@ -2269,91 +2280,14 @@ CreateDrawImages(Vulkan* vk) bool success = true; - VkFormat draw_format = GetDrawImageFormat(vk); - VkFormat depth_format = VK_FORMAT_D32_SFLOAT; + Format draw_format = cast(Format)GetDrawImageFormat(vk); + Format depth_format = cast(Format)VK_FORMAT_D32_SFLOAT; - VmaAllocationCreateInfo alloc_info = { - usage: VMA_MEMORY_USAGE_GPU_ONLY, - requiredFlags: VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - }; + u32 w = vk.swapchain_extent.width; + u32 h = vk.swapchain_extent.height; - VkImageCreateInfo image_info = { - sType: VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, - imageType: VK_IMAGE_TYPE_2D, - mipLevels: 1, - arrayLayers: 1, - samples: VK_SAMPLE_COUNT_1_BIT, - tiling: VK_IMAGE_TILING_OPTIMAL, - usage: VK_DRAW_IMAGE_USAGE_FLAGS, - extent: vk.swapchain_extent, - format: draw_format, - }; - - VkResult result = vmaCreateImage(vk.vma, &image_info, &alloc_info, &vk.draw_image.image, &vk.draw_image.alloc, null); - success = VkCheck("vmaCreateImage failure", result); - - if (success) - { - VkImageViewCreateInfo view_info = { - sType: VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - image: vk.draw_image.image, - format: draw_format, - viewType: VK_IMAGE_VIEW_TYPE_2D, - subresourceRange: { - aspectMask: VK_IMAGE_ASPECT_COLOR_BIT, - baseMipLevel: 0, - levelCount: 1, - baseArrayLayer: 0, - layerCount: 1, - }, - }; - - result = vkCreateImageView(vk.device, &view_info, null, &vk.draw_image.view); - success = VkCheck("vkCreateImageView failure", result); - } - - if (success) - { - VkImageCreateInfo depth_image_info = { - sType: VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, - imageType: VK_IMAGE_TYPE_2D, - mipLevels: 1, - arrayLayers: 1, - samples: VK_SAMPLE_COUNT_1_BIT, - tiling: VK_IMAGE_TILING_OPTIMAL, - format: depth_format, - usage: VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, - extent: vk.swapchain_extent, - }; - - result = vmaCreateImage(vk.vma, &depth_image_info, &alloc_info, &vk.depth_image.image, &vk.depth_image.alloc, null); - success = VkCheck("vmaCreateImage failure", result); - } - - if (success) - { - VkImageViewCreateInfo depth_view_info = { - sType: VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - image: vk.depth_image.image, - viewType: VK_IMAGE_VIEW_TYPE_2D, - format: depth_format, - subresourceRange: { - aspectMask: VK_IMAGE_ASPECT_DEPTH_BIT, - baseMipLevel: 0, - levelCount: 1, - baseArrayLayer: 0, - layerCount: 1, - }, - }; - - result = vkCreateImageView(vk.device, &depth_view_info, null, &vk.depth_image.view); - success = VkCheck("vmaCreateImageView failure", result); - } - - vk.draw_image.format = draw_format; - vk.draw_image.layout = VK_IMAGE_LAYOUT_UNDEFINED; - vk.depth_image.format = depth_format; - vk.depth_image.layout = VK_IMAGE_LAYOUT_UNDEFINED; + CreateImageView(vk, &vk.draw_image, w, h, draw_format, IU.Draw, false); + CreateImageView(vk, &vk.depth_image, w, h, depth_format, IU.Depth, true); return success; } @@ -2407,7 +2341,7 @@ CreateSwapchain(Vulkan* vk) VkSwapchainCreateInfoKHR info = { sType: VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, imageArrayLayers: 1, - imageUsage: VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + imageUsage: IU.Swapchain, compositeAlpha: VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, clipped: VK_TRUE, imageSharingMode: VK_SHARING_MODE_EXCLUSIVE, diff --git a/src/shaders/convert.comp.glsl b/src/shaders/convert.comp.glsl index d30f114..1d5fe45 100644 --- a/src/shaders/convert.comp.glsl +++ b/src/shaders/convert.comp.glsl @@ -1,7 +1,6 @@ #version 460 #extension GL_EXT_shader_8bit_storage : require -#extension GL_EXT_debug_printf : require layout (constant_id = 0) const int CHANNELS = 3; @@ -35,7 +34,6 @@ void main() uint index = x + y * PC.x; vec4 col = vec4(vec3(uint(src[index]) / 255.0), 1.0); - debugPrintfEXT("col = %v4f", col); imageStore(dst, ivec2(x, y), col); } else if (CHANNELS == 2) @@ -45,7 +43,6 @@ void main() float f = uint(src[index]) / 255.0; float a = uint(src[index+1]) / 255.0; vec4 col = vec4(f, f, f, a); - debugPrintfEXT("col = %v4f", col); imageStore(dst, ivec2(x, y), col); } else if (CHANNELS == 3) @@ -53,7 +50,6 @@ void main() uint index = (x + y * PC.x) * 3; vec4 col = vec4(uint(src[index]) / 255.0, uint(src[index+1]) / 255.0, uint(src[index+2]) / 255.0, 1.0); - debugPrintfEXT("col = %v4f", col); imageStore(dst, ivec2(x, y), col); } } diff --git a/src/shaders/oit.frag.glsl b/src/shaders/oit.frag.glsl index d9b84d5..88a8561 100644 --- a/src/shaders/oit.frag.glsl +++ b/src/shaders/oit.frag.glsl @@ -27,7 +27,7 @@ void BubbleSort(inout uvec2 array[OIT_LAYERS], int n) float UnPreMultSRGBToLinear(float col) { - return col < 0.04045f ? col / 12.92f : pow((col + 0.055f) / 1.055f, 2.4f); + return (col < 0.04045f) ? (col / 12.92f) : pow((col + 0.055f) / 1.055f, 2.4f); } vec4 UnPreMultSRGBToLinear(vec4 col) @@ -47,7 +47,7 @@ void DoBlend(inout vec4 color, vec4 base_color) void DoBlendPacked(inout vec4 color, uint fragment) { vec4 unpacked_color = unpackUnorm4x8(fragment); - unpacked_color = UnPreMultSRGBToLinear(unpacked_color); + //unpacked_color = UnPreMultSRGBToLinear(unpacked_color); unpacked_color.rgb *= unpacked_color.a; DoBlend(color, unpacked_color); } diff --git a/src/shaders/pbr.frag.glsl b/src/shaders/pbr.frag.glsl index e47f671..1b2ba70 100644 --- a/src/shaders/pbr.frag.glsl +++ b/src/shaders/pbr.frag.glsl @@ -50,7 +50,7 @@ void main() vec4 tex_col = texture(sampler2D(Textures[nonuniformEXT(Materials[nonuniformEXT(PC.mat_id)].albedo_texture)], SamplerNearest), FragData.uv); vec4 out_col = CalculateDirectionalLight(col, tex_col, G.light_color, G.light_direction, FragData.normal); - out_col.a = Materials[nonuniformEXT(PC.mat_id)].alpha; + out_col.a = 1.0;// Materials[nonuniformEXT(PC.mat_id)].alpha; if (Materials[nonuniformEXT(PC.mat_id)].alpha_has_texture) { @@ -58,7 +58,11 @@ void main() out_col.a = alpha_col.a; } - vec4 srgb_col = UnPreMultLinearToSRGB(out_col); + FragColor = out_col; + + /* + TODO: set up OIT again + vec4 srgb_col = out_col;// UnPreMultLinearToSRGB(out_col); uvec4 store_value = uvec4(packUnorm4x8(srgb_col), floatBitsToUint(gl_FragCoord.z), store_mask, 0); @@ -73,4 +77,5 @@ void main() { FragColor = vec4(out_col.rgb * out_col.a, out_col.a); // Change to vec4(0.0) to disable tail blending } + */ } diff --git a/src/shaders/structures.layout b/src/shaders/structures.layout index b150455..537d48d 100644 --- a/src/shaders/structures.layout +++ b/src/shaders/structures.layout @@ -2,7 +2,7 @@ // **** STRUCTS MUST BE PACKED IN OPTIMAL PACKING ORDER TO MATCH D STRUCTS **** // **************************************************************************** -#define OIT_LAYERS 64 +#define OIT_LAYERS 8 layout (set = 0, binding = 0) uniform GlobalUniforms { mat4 view_matrix;