Mercurial > games > semicongine
changeset 1171:dc6e1660831d compiletime-tests
merge
author | sam <sam@basx.dev> |
---|---|
date | Wed, 26 Jun 2024 17:46:36 +0700 |
parents | 58694b30b9cb (current diff) 2addc5f6804f (diff) |
children | 2e0b527c2753 |
files | semicongine/renderer.nim semicongine/vulkan/renderpass.nim |
diffstat | 7 files changed, 181 insertions(+), 51 deletions(-) [+] |
line wrap: on
line diff
--- a/semicongine/audio.nim Sat Jun 22 08:45:14 2024 +0700 +++ b/semicongine/audio.nim Wed Jun 26 17:46:36 2024 +0700 @@ -16,8 +16,8 @@ export audiotypes -const NBUFFERS = 4 -const BUFFERSAMPLECOUNT = 2048 +const NBUFFERS = 32 +const BUFFERSAMPLECOUNT = 256 type Playback = object @@ -202,6 +202,11 @@ proc updateSoundBuffer(mixer: var Mixer) = let t = getMonoTime() + + let tDebug = getTime() + # echo "" + # echo tDebug + let dt = (t - mixer.lastUpdate).inNanoseconds.float64 / 1_000_000_000'f64 mixer.lastUpdate = t @@ -237,7 +242,9 @@ track.playing.del(id) mixer.buffers[mixer.currentBuffer][i] = mixedSample # send data to sound device + # echo getTime() - tDebug mixer.device.WriteSoundData(mixer.currentBuffer) + # echo getTime() - tDebug mixer.currentBuffer = (mixer.currentBuffer + 1) mod mixer.buffers.len # DSP functions
--- a/semicongine/engine.nim Sat Jun 22 08:45:14 2024 +0700 +++ b/semicongine/engine.nim Wed Jun 26 17:46:36 2024 +0700 @@ -114,6 +114,7 @@ backFaceCulling = true, vSync = false, inFlightFrames = 2, + samples = VK_SAMPLE_COUNT_1_BIT, ) = assert not engine.renderer.isSome @@ -130,6 +131,7 @@ backFaceCulling = backFaceCulling, vSync = vSync, inFlightFrames = inFlightFrames, + samples = samples, )) proc InitRenderer*(engine: var Engine, clearColor = NewVec4f(0, 0, 0, 0), vSync = false) = @@ -195,6 +197,12 @@ func Limits*(engine: Engine): VkPhysicalDeviceLimits = engine.device.physicalDevice.properties.limits +func MaxFramebufferSampleCount*(engine: Engine, maxSamples = VK_SAMPLE_COUNT_8_BIT): VkSampleCountFlagBits = + let available = VkSampleCountFlags( + engine.Limits.framebufferColorSampleCounts.uint32 and engine.Limits.framebufferDepthSampleCounts.uint32 + ).toEnums + return min(max(available), maxSamples) + proc UpdateInputs*(engine: Engine): bool = UpdateInputs(engine.window.PendingEvents())
--- a/semicongine/renderer.nim Sat Jun 22 08:45:14 2024 +0700 +++ b/semicongine/renderer.nim Wed Jun 26 17:46:36 2024 +0700 @@ -62,16 +62,23 @@ backFaceCulling = true, vSync = false, inFlightFrames = 2, + samples = VK_SAMPLE_COUNT_1_BIT, ): Renderer = assert device.vk.Valid result.device = device - result.renderPass = device.CreateRenderPass(shaders, clearColor = clearColor, backFaceCulling = backFaceCulling) + result.renderPass = device.CreateRenderPass( + shaders, + clearColor = clearColor, + backFaceCulling = backFaceCulling, + samples = samples + ) let swapchain = device.CreateSwapchain( result.renderPass.vk, device.physicalDevice.GetSurfaceFormats().FilterSurfaceFormat(), vSync = vSync, inFlightFrames = inFlightFrames, + samples = samples, ) if not swapchain.isSome: raise newException(Exception, "Unable to create swapchain")
--- a/semicongine/vulkan/image.nim Sat Jun 22 08:45:14 2024 +0700 +++ b/semicongine/vulkan/image.nim Wed Jun 26 17:46:36 2024 +0700 @@ -150,8 +150,38 @@ addr region ) +proc CreateImage*(device: Device, width, height, depth: uint32, format: VkFormat, samples: VkSampleCountFlagBits, usage: openArray[VkImageUsageFlagBits]): VulkanImage = + assert device.vk.Valid + assert width > 0 + assert height > 0 + + result.device = device + result.usage = @usage + + + result.width = width + result.height = height + result.depth = depth + result.format = format + + var imageInfo = VkImageCreateInfo( + sType: VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + imageType: VK_IMAGE_TYPE_2D, + extent: VkExtent3D(width: uint32(width), height: uint32(height), depth: 1), + mipLevels: 1, + arrayLayers: 1, + format: result.format, + tiling: VK_IMAGE_TILING_OPTIMAL, + initialLayout: VK_IMAGE_LAYOUT_UNDEFINED, + usage: toBits result.usage, + sharingMode: VK_SHARING_MODE_EXCLUSIVE, + samples: samples, + ) + checkVkResult device.vk.vkCreateImage(addr imageInfo, nil, addr result.vk) + result.allocateMemory(requireMappable = false, preferVRAM = true, preferAutoFlush = false) + # currently only usable for texture access from shader -proc createImage[T](device: Device, queue: Queue, width, height: uint32, depth: PixelDepth, image: Image[T]): VulkanImage = +proc createTextureImage[T](device: Device, queue: Queue, width, height: uint32, depth: PixelDepth, image: Image[T]): VulkanImage = assert device.vk.Valid assert width > 0 assert height > 0 @@ -319,9 +349,9 @@ proc UploadTexture*(device: Device, queue: Queue, texture: Texture): VulkanTexture = assert device.vk.Valid if texture.isGrayscale: - result.image = createImage(device = device, queue = queue, width = texture.grayImage.width, height = texture.grayImage.height, depth = 1, image = texture.grayImage) + result.image = createTextureImage(device = device, queue = queue, width = texture.grayImage.width, height = texture.grayImage.height, depth = 1, image = texture.grayImage) else: - result.image = createImage(device = device, queue = queue, width = texture.colorImage.width, height = texture.colorImage.height, depth = 4, image = texture.colorImage) + result.image = createTextureImage(device = device, queue = queue, width = texture.colorImage.width, height = texture.colorImage.height, depth = 4, image = texture.colorImage) result.imageView = result.image.CreateImageView() result.sampler = result.image.device.CreateSampler(texture.sampler)
--- a/semicongine/vulkan/pipeline.nim Sat Jun 22 08:45:14 2024 +0700 +++ b/semicongine/vulkan/pipeline.nim Wed Jun 26 17:46:36 2024 +0700 @@ -55,7 +55,7 @@ descriptor.imageviews.add emptyTexture.imageView descriptor.samplers.add emptyTexture.sampler -proc CreatePipeline*(device: Device, renderPass: VkRenderPass, shaderConfiguration: ShaderConfiguration, inFlightFrames: int, subpass = 0'u32, backFaceCulling = true): ShaderPipeline = +proc CreatePipeline*(device: Device, renderPass: VkRenderPass, shaderConfiguration: ShaderConfiguration, inFlightFrames: int, subpass = 0'u32, backFaceCulling = true, samples = VK_SAMPLE_COUNT_1_BIT): ShaderPipeline = assert renderPass.Valid assert device.vk.Valid @@ -128,7 +128,7 @@ multisampling = VkPipelineMultisampleStateCreateInfo( sType: VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, sampleShadingEnable: VK_FALSE, - rasterizationSamples: VK_SAMPLE_COUNT_1_BIT, + rasterizationSamples: samples, minSampleShading: 1.0, pSampleMask: nil, alphaToCoverageEnable: VK_FALSE,
--- a/semicongine/vulkan/renderpass.nim Sat Jun 22 08:45:14 2024 +0700 +++ b/semicongine/vulkan/renderpass.nim Wed Jun 26 17:46:36 2024 +0700 @@ -1,72 +1,116 @@ import ../core +import ../material +import ./device +import ./physicaldevice +import ./pipeline +import ./shader import ./framebuffer +type + RenderPass* = object + vk*: VkRenderPass + device*: Device + shaderPipelines*: seq[(MaterialType, ShaderPipeline)] + clearColor*: Vec4f + proc CreateRenderPass*( - device: VkDevice, - format: VkFormat, -): VkRenderPass = + device: Device, + shaders: openArray[(MaterialType, ShaderConfiguration)], + clearColor = Vec4f([0.8'f32, 0.8'f32, 0.8'f32, 1'f32]), + backFaceCulling = true, + inFlightFrames = 2, + samples = VK_SAMPLE_COUNT_1_BIT +): RenderPass = + assert device.vk.Valid - var - attachments = @[VkAttachmentDescription( - format: format, - samples: VK_SAMPLE_COUNT_1_BIT, + # some asserts + for (materialtype, shaderconfig) in shaders: + shaderconfig.AssertCanRender(materialtype) + + var attachments = @[ + VkAttachmentDescription( + format: device.physicalDevice.GetSurfaceFormats().FilterSurfaceFormat().format, + samples: samples, loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR, storeOp: VK_ATTACHMENT_STORE_OP_STORE, stencilLoadOp: VK_ATTACHMENT_LOAD_OP_DONT_CARE, stencilStoreOp: VK_ATTACHMENT_STORE_OP_DONT_CARE, initialLayout: VK_IMAGE_LAYOUT_UNDEFINED, - finalLayout: VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - )] + finalLayout: if samples == VK_SAMPLE_COUNT_1_BIT: VK_IMAGE_LAYOUT_PRESENT_SRC_KHR else: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + ), + ] + + if samples != VK_SAMPLE_COUNT_1_BIT: + attachments.add VkAttachmentDescription( + format: device.physicalDevice.GetSurfaceFormats().FilterSurfaceFormat().format, + samples: VK_SAMPLE_COUNT_1_BIT, + loadOp: VK_ATTACHMENT_LOAD_OP_DONT_CARE, + storeOp: VK_ATTACHMENT_STORE_OP_STORE, + stencilLoadOp: VK_ATTACHMENT_LOAD_OP_DONT_CARE, + stencilStoreOp: VK_ATTACHMENT_STORE_OP_DONT_CARE, + initialLayout: VK_IMAGE_LAYOUT_UNDEFINED, + finalLayout: VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + ) + + var # dependencies seems to be optional, TODO: benchmark difference dependencies = @[VkSubpassDependency( srcSubpass: VK_SUBPASS_EXTERNAL, dstSubpass: 0, - srcStageMask: toBits [VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT], - srcAccessMask: VkAccessFlags(0), - dstStageMask: toBits [VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT], - dstAccessMask: toBits [VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT], + srcStageMask: toBits [VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT], + srcAccessMask: toBits [VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT], + dstStageMask: toBits [VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT], + dstAccessMask: toBits [VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT], )] - outputs = @[ - VkAttachmentReference( - attachment: 0, - layout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - ) - ] + colorAttachment = VkAttachmentReference( + attachment: 0, + layout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + ) + resolveAttachment = VkAttachmentReference( + attachment: 1, + layout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + ) - var subpassesList = [ - VkSubpassDescription( - flags: VkSubpassDescriptionFlags(0), - pipelineBindPoint: VK_PIPELINE_BIND_POINT_GRAPHICS, - inputAttachmentCount: 0, - pInputAttachments: nil, - colorAttachmentCount: uint32(outputs.len), - pColorAttachments: outputs.ToCPointer, - pResolveAttachments: nil, - pDepthStencilAttachment: nil, - preserveAttachmentCount: 0, - pPreserveAttachments: nil, - ) - ] + var subpass = VkSubpassDescription( + flags: VkSubpassDescriptionFlags(0), + pipelineBindPoint: VK_PIPELINE_BIND_POINT_GRAPHICS, + inputAttachmentCount: 0, + pInputAttachments: nil, + colorAttachmentCount: 1, + pColorAttachments: addr(colorAttachment), + pResolveAttachments: if samples == VK_SAMPLE_COUNT_1_BIT: nil else: addr(resolveAttachment), + pDepthStencilAttachment: nil, + preserveAttachmentCount: 0, + pPreserveAttachments: nil, + ) var createInfo = VkRenderPassCreateInfo( sType: VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, attachmentCount: uint32(attachments.len), pAttachments: attachments.ToCPointer, - subpassCount: uint32(subpassesList.len), - pSubpasses: subpassesList.ToCPointer, + subpassCount: 1, + pSubpasses: addr(subpass), dependencyCount: uint32(dependencies.len), pDependencies: dependencies.ToCPointer, ) - checkVkResult device.vkCreateRenderPass(addr(createInfo), nil, addr(result)) + result.device = device + result.clearColor = clearColor + checkVkResult device.vk.vkCreateRenderPass(addr(createInfo), nil, addr(result.vk)) -proc BeginRenderCommands*(commandBuffer: VkCommandBuffer, renderpass: VkRenderPass, framebuffer: Framebuffer, oneTimeSubmit: bool, clearColor: Vec4f) = + for (_, shaderconfig) in shaders: + assert shaderconfig.outputs.len == 1 + for (materialtype, shaderconfig) in shaders: + result.shaderPipelines.add (materialtype, device.CreatePipeline(result.vk, shaderconfig, inFlightFrames, 0, backFaceCulling = backFaceCulling, samples = samples)) + +proc BeginRenderCommands*(commandBuffer: VkCommandBuffer, renderpass: RenderPass, framebuffer: Framebuffer, oneTimeSubmit: bool) = assert commandBuffer.Valid + assert renderpass.vk.Valid assert framebuffer.vk.Valid let w = framebuffer.dimension.x h = framebuffer.dimension.y - var clearColors = [VkClearValue(color: VkClearColorValue(float32: clearColor))] + var clearColors = [VkClearValue(color: VkClearColorValue(float32: renderpass.clearColor))] var beginInfo = VkCommandBufferBeginInfo( sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, @@ -75,7 +119,7 @@ ) renderPassInfo = VkRenderPassBeginInfo( sType: VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - renderPass: renderpass, + renderPass: renderPass.vk, framebuffer: framebuffer.vk, renderArea: VkRect2D( offset: VkOffset2D(x: 0, y: 0), @@ -105,3 +149,12 @@ proc EndRenderCommands*(commandBuffer: VkCommandBuffer) = commandBuffer.vkCmdEndRenderPass() checkVkResult commandBuffer.vkEndCommandBuffer() + + +proc Destroy*(renderPass: var RenderPass) = + assert renderPass.device.vk.Valid + assert renderPass.vk.Valid + renderPass.device.vk.vkDestroyRenderPass(renderPass.vk, nil) + renderPass.vk.Reset + for _, pipeline in renderPass.shaderPipelines.mitems: + pipeline.Destroy()
--- a/semicongine/vulkan/swapchain.nim Sat Jun 22 08:45:14 2024 +0700 +++ b/semicongine/vulkan/swapchain.nim Wed Jun 26 17:46:36 2024 +0700 @@ -17,6 +17,9 @@ nFramebuffers*: uint32 currentInFlight*: int currentFramebufferIndex: uint32 + samples: VkSampleCountFlagBits + colorImage: VulkanImage + colorImageView: ImageView framebufferViews*: seq[ImageView] framebuffers*: seq[Framebuffer] queueFinishedFence*: seq[Fence] @@ -35,9 +38,10 @@ renderPass: VkRenderPass, surfaceFormat: VkSurfaceFormatKHR, inFlightFrames: int, + samples: VkSampleCountFlagBits, desiredFramebufferCount = 3'u32, oldSwapchain = VkSwapchainKHR(0), - vSync = false + vSync = false, ): Option[Swapchain] = assert device.vk.Valid assert device.physicalDevice.vk.Valid @@ -79,9 +83,21 @@ dimension: TVec2[uint32]([capabilities.currentExtent.width, capabilities.currentExtent.height]), inFlightFrames: inFlightFrames, renderPass: renderPass, - vSync: vSync + vSync: vSync, + samples: samples, ) + if samples != VK_SAMPLE_COUNT_1_BIT: + swapchain.colorImage = device.CreateImage( + width = capabilities.currentExtent.width, + height = capabilities.currentExtent.height, + depth = 4, + samples = samples, + format = surfaceFormat.format, + usage = [VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT], + ) + swapchain.colorImageView = swapchain.colorImage.CreateImageView() + if device.vk.vkCreateSwapchainKHR(addr createInfo, nil, addr swapchain.vk) == VK_SUCCESS: checkVkResult device.vk.vkGetSwapchainImagesKHR(swapchain.vk, addr swapchain.nFramebuffers, nil) var framebuffers = newSeq[VkImage](swapchain.nFramebuffers) @@ -89,7 +105,10 @@ for framebuffer in framebuffers: let framebufferView = VulkanImage(vk: framebuffer, format: surfaceFormat.format, device: device).CreateImageView() swapchain.framebufferViews.add framebufferView - swapchain.framebuffers.add device.CreateFramebuffer(renderPass, [framebufferView], swapchain.dimension) + if samples == VK_SAMPLE_COUNT_1_BIT: + swapchain.framebuffers.add device.CreateFramebuffer(renderPass, [framebufferView], swapchain.dimension) + else: + swapchain.framebuffers.add device.CreateFramebuffer(renderPass, [swapchain.colorImageView, framebufferView], swapchain.dimension) for i in 0 ..< swapchain.inFlightFrames: swapchain.queueFinishedFence.add device.CreateFence() swapchain.imageAvailableSemaphore.add device.CreateSemaphore() @@ -97,6 +116,7 @@ debug &"Created swapchain with: {swapchain.nFramebuffers} framebuffers, {inFlightFrames} in-flight frames, {swapchain.dimension.x}x{swapchain.dimension.y}" assert device.FirstPresentationQueue().isSome, "No present queue found" swapchain.presentQueue = device.FirstPresentationQueue().get + result = some(swapchain) else: result = none(Swapchain) @@ -173,6 +193,10 @@ for framebuffer in swapchain.framebuffers.mitems: assert framebuffer.vk.Valid framebuffer.Destroy() + if swapchain.colorImage.vk.Valid: + swapchain.colorImage.Destroy() + if swapchain.colorImageView.vk.Valid: + swapchain.colorImageView.Destroy() for i in 0 ..< swapchain.inFlightFrames: assert swapchain.queueFinishedFence[i].vk.Valid assert swapchain.imageAvailableSemaphore[i].vk.Valid @@ -194,5 +218,6 @@ desiredFramebufferCount = swapchain.nFramebuffers, inFlightFrames = swapchain.inFlightFrames, oldSwapchain = swapchain.vk, - vSync = swapchain.vSync + vSync = swapchain.vSync, + samples = swapchain.samples, )