Skip to content

Commit

Permalink
Vulkan screen copy pass
Browse files Browse the repository at this point in the history
  • Loading branch information
fabmax committed Jan 29, 2025
1 parent 19ba81b commit 9aa1bc7
Show file tree
Hide file tree
Showing 32 changed files with 454 additions and 169 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ class OpticalDepthLutPass :
var densityFalloff by lutShader::densityFalloff

init {
clearColor = null
drawNode.apply {
addMesh(Attribute.POSITIONS, Attribute.TEXTURE_COORDS) {
generateFullscreenQuad()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ open class DepthMapPass(

override fun release() {
super.release()
shadowPipelines.values.filterNotNull().distinct().forEach { it.release() }
shadowPipelines.values
.filterNotNull()
.distinct()
.filter { !it.isReleased }
.forEach { it.release() }
}

protected data class DepthShaderKey(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ class DrawPipeline(
pipelineHash = pipelineHashBuilder.build()
}

override fun toString(): String {
return "DrawPipeline:\"$name\""
}

fun update(cmd: DrawCommand) {
onUpdate.update()
for (i in onUpdate.indices) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ class FrameCopy(

override fun release() {
super.release()
gpuFrameCopy?.release()
colorCopy.forEach { it.release() }
depthCopy?.release()
gpuFrameCopy?.release()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,8 @@ class BindGroupDataVk(
val compare = if (isDepthTex) samplerSettings.compareOp.vk else VK_COMPARE_OP_ALWAYS

val sampler = backend.device.createSampler {
magFilter(samplerSettings.magFilter.vk)
minFilter(samplerSettings.minFilter.vk)
magFilter(if (isUnfilterable) VK_FILTER_NEAREST else samplerSettings.magFilter.vk)
minFilter(if (isUnfilterable) VK_FILTER_NEAREST else samplerSettings.minFilter.vk)
addressModeU(samplerSettings.addressModeU.vk)
addressModeV(samplerSettings.addressModeV.vk)
addressModeW(samplerSettings.addressModeW.vk)
Expand All @@ -319,7 +319,7 @@ class BindGroupDataVk(
image = image.vkImage,
viewType = viewType,
format = image.format,
aspectMask = if (isDepthTex || isUnfilterable) VK_IMAGE_ASPECT_DEPTH_BIT else VK_IMAGE_ASPECT_COLOR_BIT,
aspectMask = image.imageInfo.aspectMask,
levelCount = if (samplerSettings.numMipLevels > 0) samplerSettings.numMipLevels else image.mipLevels,
layerCount = image.arrayLayers,
baseMipLevel = samplerSettings.baseMipLevel,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,21 @@ class GrowingBufferVk(
var buffer: BufferVk = makeBuffer(bufferInfo)

fun writeData(data: Float32Buffer, commandBuffer: VkCommandBuffer) {
if (data.limit == 0) return

val bufSize = data.limit * 4L
checkSize(bufSize)

backend.memManager.stagingBuffer(bufSize) { stagingBuf ->
data.useRaw { stagingBuf.mapped!!.asFloatBuffer().put(it) }
buffer.copyFrom(stagingBuf, commandBuffer)
}
}

fun writeData(data: Int32Buffer, commandBuffer: VkCommandBuffer) {
if (data.limit == 0) return

val bufSize = data.limit * 4L
checkSize(bufSize)

backend.memManager.stagingBuffer(bufSize) { stagingBuf ->
data.useRaw { stagingBuf.mapped!!.asIntBuffer().put(it) }
buffer.copyFrom(stagingBuf, commandBuffer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class CommandPool(val backendVk: RenderBackendVk, val queue: VkQueue) : BaseRele
commandBufferCount(numBuffers)
}
val handles = mallocPointer(numBuffers)
checkVk(vkAllocateCommandBuffers(device.vkDevice, allocateInfo, handles)) { "Failed creating command buffers" }
vkCheck(vkAllocateCommandBuffers(device.vkDevice, allocateInfo, handles)) { "Failed creating command buffers" }
return buildList {
for (i in 0 until numBuffers) {
add(VkCommandBuffer(handles[i], device.vkDevice))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ internal inline fun Device.allocateDescriptorSets(stack: MemoryStack? = null, bl
memStack(stack) {
val allocInfo = callocVkDescriptorSetAllocateInfo(block)
val handles = mallocLong(allocInfo.descriptorSetCount())
checkVk(vkAllocateDescriptorSets(vkDevice, allocInfo, handles)) { "Failed allocating descriptor sets: $it" }
vkCheck(vkAllocateDescriptorSets(vkDevice, allocInfo, handles)) { "Failed allocating descriptor sets: $it" }
return buildList { repeat(allocInfo.descriptorSetCount()) { add(VkDescriptorSet(handles[it])) } }
}
}
Expand All @@ -115,7 +115,7 @@ internal inline fun Device.createCommandPool(stack: MemoryStack? = null, block:
memStack(stack) {
val createInfo = callocVkCommandPoolCreateInfo(block)
val handle = mallocLong(1)
checkVk(vkCreateCommandPool(vkDevice, createInfo, null, handle)) { "Failed creating command pool: $it" }
vkCheck(vkCreateCommandPool(vkDevice, createInfo, null, handle)) { "Failed creating command pool: $it" }
return VkCommandPool(handle[0])
}
}
Expand All @@ -127,7 +127,7 @@ internal fun Device.createComputePipeline(stack: MemoryStack? = null, block: VkC
this[0].block()
}
val handle = mallocLong(1)
checkVk(vkCreateComputePipelines(vkDevice, VK_NULL_HANDLE, createInfo, null, handle)) { "Failed creating compute pipeline: $it" }
vkCheck(vkCreateComputePipelines(vkDevice, VK_NULL_HANDLE, createInfo, null, handle)) { "Failed creating compute pipeline: $it" }
return VkComputePipeline(handle[0])
}
}
Expand All @@ -137,7 +137,7 @@ internal inline fun Device.createDescriptorPool(stack: MemoryStack? = null, bloc
memStack(stack) {
val createInfo = callocVkDescriptorPoolCreateInfo(block)
val handle = mallocLong(1)
checkVk(vkCreateDescriptorPool(vkDevice, createInfo, null, handle)) { "Failed creating descriptor pool: $it" }
vkCheck(vkCreateDescriptorPool(vkDevice, createInfo, null, handle)) { "Failed creating descriptor pool: $it" }
return VkDescriptorPool(handle[0])
}
}
Expand All @@ -147,7 +147,7 @@ internal inline fun Device.createDescriptorSetLayout(stack: MemoryStack? = null,
memStack(stack) {
val createInfo = callocVkDescriptorSetLayoutCreateInfo(block)
val handle = mallocLong(1)
checkVk(vkCreateDescriptorSetLayout(vkDevice, createInfo, null, handle)) { "Failed creating descriptor set layout: $it" }
vkCheck(vkCreateDescriptorSetLayout(vkDevice, createInfo, null, handle)) { "Failed creating descriptor set layout: $it" }
return VkDescriptorSetLayout(handle[0])
}
}
Expand All @@ -157,7 +157,7 @@ internal inline fun Device.createFramebuffer(stack: MemoryStack? = null, block:
memStack(stack) {
val createInfo = callocVkFramebufferCreateInfo(block)
val handle = mallocLong(1)
checkVk(vkCreateFramebuffer(vkDevice, createInfo, null, handle)) { "Failed creating framebuffer: $it" }
vkCheck(vkCreateFramebuffer(vkDevice, createInfo, null, handle)) { "Failed creating framebuffer: $it" }
return VkFramebuffer(handle[0])
}
}
Expand All @@ -167,7 +167,7 @@ internal inline fun Device.createFence(stack: MemoryStack? = null, block: VkFenc
memStack(stack) {
val createInfo = callocVkFenceCreateInfo(block)
val handle = mallocLong(1)
checkVk(vkCreateFence(vkDevice, createInfo, null, handle)) { "Failed creating fence: $it" }
vkCheck(vkCreateFence(vkDevice, createInfo, null, handle)) { "Failed creating fence: $it" }
return VkFence(handle[0])
}
}
Expand All @@ -179,7 +179,7 @@ internal fun Device.createGraphicsPipeline(stack: MemoryStack? = null, block: Vk
this[0].block()
}
val handle = mallocLong(1)
checkVk(vkCreateGraphicsPipelines(vkDevice, VK_NULL_HANDLE, createInfo, null, handle)) { "Failed creating graphics pipeline: $it" }
vkCheck(vkCreateGraphicsPipelines(vkDevice, VK_NULL_HANDLE, createInfo, null, handle)) { "Failed creating graphics pipeline: $it" }
return VkGraphicsPipeline(handle[0])
}
}
Expand Down Expand Up @@ -214,7 +214,7 @@ internal inline fun Device.createImageView(stack: MemoryStack? = null, block: Vk
memStack(stack) {
val createInfo = callocVkImageViewCreateInfo(block)
val handle = mallocLong(1)
checkVk(vkCreateImageView(vkDevice, createInfo, null, handle)) { "Failed creating image view: $it" }
vkCheck(vkCreateImageView(vkDevice, createInfo, null, handle)) { "Failed creating image view: $it" }
return VkImageView(handle[0])
}
}
Expand All @@ -224,7 +224,7 @@ internal fun Device.createPipelineLayout(stack: MemoryStack? = null, block: VkPi
memStack(stack) {
val createInfo = callocVkPipelineLayoutCreateInfo(block)
val handle = mallocLong(1)
checkVk(vkCreatePipelineLayout(vkDevice, createInfo, null, handle)) { "Failed creating pipeline layout: $it" }
vkCheck(vkCreatePipelineLayout(vkDevice, createInfo, null, handle)) { "Failed creating pipeline layout: $it" }
return VkPipelineLayout(handle[0])
}
}
Expand All @@ -234,7 +234,7 @@ internal fun Device.createQueryPool(stack: MemoryStack? = null, block: VkQueryPo
memStack(stack) {
val createInfo = callocVkQueryPoolCreateInfo(block)
val handle = mallocLong(1)
checkVk(vkCreateQueryPool(vkDevice, createInfo, null, handle)) { "Failed creating query pool: $it" }
vkCheck(vkCreateQueryPool(vkDevice, createInfo, null, handle)) { "Failed creating query pool: $it" }
return VkQueryPool(handle[0])
}
}
Expand All @@ -244,7 +244,7 @@ internal fun Device.createRenderPass(stack: MemoryStack? = null, block: VkRender
memStack(stack) {
val createInfo = callocVkRenderPassCreateInfo(block)
val handle = mallocLong(1)
checkVk(vkCreateRenderPass(vkDevice, createInfo, null, handle)) { "Failed creating render pass: $it" }
vkCheck(vkCreateRenderPass(vkDevice, createInfo, null, handle)) { "Failed creating render pass: $it" }
return VkRenderPass(handle[0])
}
}
Expand All @@ -254,7 +254,7 @@ internal fun Device.createSampler(stack: MemoryStack? = null, block: VkSamplerCr
memStack(stack) {
val createInfo = callocVkSamplerCreateInfo(block)
val handle = mallocLong(1)
checkVk(vkCreateSampler(vkDevice, createInfo, null, handle)) { "Failed creating sampler: $it" }
vkCheck(vkCreateSampler(vkDevice, createInfo, null, handle)) { "Failed creating sampler: $it" }
return VkSampler(handle[0])
}
}
Expand All @@ -264,7 +264,7 @@ internal fun Device.createSemaphore(stack: MemoryStack? = null): VkSemaphore {
memStack(stack) {
val createInfo = callocVkSemaphoreCreateInfo { }
val handle = mallocLong(1)
checkVk(vkCreateSemaphore(vkDevice, createInfo, null, handle)) { "Failed creating semaphore: $it" }
vkCheck(vkCreateSemaphore(vkDevice, createInfo, null, handle)) { "Failed creating semaphore: $it" }
return VkSemaphore(handle[0])
}
}
Expand All @@ -274,7 +274,7 @@ internal fun Device.createShaderModule(stack: MemoryStack? = null, block: VkShad
memStack(stack) {
val createInfo = callocVkShaderModuleCreateInfo(block)
val handle = mallocLong(1)
checkVk(vkCreateShaderModule(vkDevice, createInfo, null, handle)) { "Failed creating shader module: $it" }
vkCheck(vkCreateShaderModule(vkDevice, createInfo, null, handle)) { "Failed creating shader module: $it" }
return VkShaderModule(handle[0])
}
}
Expand All @@ -284,7 +284,7 @@ internal fun Device.createSwapchain(stack: MemoryStack? = null, block: VkSwapcha
memStack(stack) {
val createInfo = callocVkSwapchainCreateInfoKHR(block)
val handle = mallocLong(1)
checkVk(vkCreateSwapchainKHR(vkDevice, createInfo, null, handle)) { "Failed creating swapchain: $it" }
vkCheck(vkCreateSwapchainKHR(vkDevice, createInfo, null, handle)) { "Failed creating swapchain: $it" }
return VkSwapchain(handle[0])
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ class DrawPipelineVk(
}

private fun bindVertexBuffers(cmd: DrawCommand, passEncoderState: PassEncoderState): Boolean {
if (cmd.mesh.geometry.vertexAttributes.isEmpty()) return true

val gpuGeom = cmd.mesh.geometry.gpuGeometry as GeometryVk? ?: return false
val gpuInsts = cmd.instances?.gpuInstances as InstancesVk?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class GlfwVkWindow(val backend: RenderBackendVk, ctx: Lwjgl3Context) : GlfwWindo
init {
memStack {
val lp = mallocLong(1)
checkVk(GLFWVulkan.glfwCreateWindowSurface(backend.instance.vkInstance, windowPtr, null, lp))
vkCheck(GLFWVulkan.glfwCreateWindowSurface(backend.instance.vkInstance, windowPtr, null, lp))
surfaceHandle = lp[0]
}
releaseWith(backend.instance)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ class ImageVk(
}
}

override fun toString(): String {
return "ImageVK:\"${imageInfo.label}\""
}

fun copyFromBuffer(
buffer: VkBuffer,
commandBuffer: VkCommandBuffer,
Expand All @@ -58,7 +62,7 @@ class ImageVk(
bufferOffset(0)
bufferRowLength(0)
bufferImageHeight(0)
imageSubresource().set(VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, arrayLayers)
imageSubresource().set(imageInfo.aspectMask, 0, 0, arrayLayers)
imageOffset().set(0, 0, 0)
imageExtent().set(width, height, depth)
}
Expand All @@ -79,7 +83,7 @@ class ImageVk(
bufferOffset(0)
bufferRowLength(0)
bufferImageHeight(0)
imageSubresource().set(VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, arrayLayers)
imageSubresource().set(imageInfo.aspectMask, 0, 0, arrayLayers)
imageOffset().set(0, 0, 0)
imageExtent().set(width, height, depth)
}
Expand All @@ -100,9 +104,9 @@ class ImageVk(
val region = callocVkImageCopyN(1) { }
for (level in 0 until src.mipLevels) {
region[0].apply {
srcSubresource().set(VK_IMAGE_ASPECT_COLOR_BIT, level, 0, arrayLayers)
srcSubresource().set(src.imageInfo.aspectMask, level, 0, arrayLayers)
srcOffset().set(0, 0, 0)
dstSubresource().set(VK_IMAGE_ASPECT_COLOR_BIT, level, 0, arrayLayers)
dstSubresource().set(imageInfo.aspectMask, level, 0, arrayLayers)
dstOffset().set(0, 0, 0)
extent().set(
(width shr level).coerceAtLeast(1),
Expand All @@ -123,13 +127,6 @@ class ImageVk(

memStack(stack) {
val oldLayout = layout
val hasStencilComponent = format == VK_FORMAT_D32_SFLOAT_S8_UINT || format == VK_FORMAT_D24_UNORM_S8_UINT
val aspectMask = when (newLayout) {
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL if (hasStencilComponent) -> VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL -> VK_IMAGE_ASPECT_DEPTH_BIT
else -> VK_IMAGE_ASPECT_COLOR_BIT
}

val barrier = callocVkImageMemoryBarrierN(1) {
oldLayout(oldLayout)
newLayout(newLayout)
Expand All @@ -138,7 +135,7 @@ class ImageVk(
srcAccessMask(srcAccessMaskForLayout(oldLayout))
dstAccessMask(dstAccessMaskForLayout(newLayout))
image(vkImage.handle)
subresourceRange().set(aspectMask, 0, mipLevels, 0, arrayLayers)
subresourceRange().set(imageInfo.aspectMask, 0, mipLevels, 0, arrayLayers)
}

val srcStage = srcStageForLayout(oldLayout)
Expand Down Expand Up @@ -179,7 +176,7 @@ class ImageVk(
srcAccessMask(srcAccessMaskForLayout(VK_IMAGE_LAYOUT_UNDEFINED))
dstAccessMask(dstAccessMaskForLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL))
subresourceRange {
it.aspectMask(VK_IMAGE_ASPECT_COLOR_BIT)
it.aspectMask(imageInfo.aspectMask)
it.baseArrayLayer(0)
it.layerCount(arrayLayers)
it.baseMipLevel(1)
Expand Down Expand Up @@ -215,15 +212,15 @@ class ImageVk(
srcOffsets(0).set(0, 0, 0)
srcOffsets(1).set(mipWidth, mipHeight, 1)
srcSubresource {
it.aspectMask(VK_IMAGE_ASPECT_COLOR_BIT)
it.aspectMask(imageInfo.aspectMask)
it.mipLevel(i - 1)
it.baseArrayLayer(0)
it.layerCount(arrayLayers)
}
dstOffsets(0).set(0, 0, 0)
dstOffsets(1).set((mipWidth shr 1).coerceAtLeast(1), (mipHeight shr 1).coerceAtLeast(1), 1)
dstSubresource {
it.aspectMask(VK_IMAGE_ASPECT_COLOR_BIT)
it.aspectMask(imageInfo.aspectMask)
it.mipLevel(i)
it.baseArrayLayer(0)
it.layerCount(arrayLayers)
Expand Down Expand Up @@ -259,13 +256,13 @@ class ImageVk(
}

companion object {
fun imageView2d(device: Device, image: ImageVk, aspectMask: Int): VkImageView {
fun imageView2d(device: Device, image: ImageVk): VkImageView {
require(image.depth == 1)
return device.createImageView(
image = image.vkImage,
viewType = VK_IMAGE_VIEW_TYPE_2D,
format = image.format,
aspectMask = aspectMask,
aspectMask = image.imageInfo.aspectMask,
levelCount = image.mipLevels,
layerCount = 1
)
Expand All @@ -275,6 +272,7 @@ class ImageVk(
VK_IMAGE_LAYOUT_UNDEFINED -> 0
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL -> VK_ACCESS_TRANSFER_WRITE_BIT
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL -> VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL -> VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL -> VK_ACCESS_TRANSFER_READ_BIT
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL -> VK_ACCESS_SHADER_READ_BIT
else -> error("Layout not supported / implemented: $layout")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class Instance(val backend: RenderBackendVk, appName: String) : BaseReleasable()

if (dbgMessengerInfo != null) {
val lp = mallocLong(1)
checkVk(EXTDebugUtils.vkCreateDebugUtilsMessengerEXT(vkInstance, dbgMessengerInfo, null, lp))
vkCheck(EXTDebugUtils.vkCreateDebugUtilsMessengerEXT(vkInstance, dbgMessengerInfo, null, lp))
debugMessenger = lp.get()
}
}
Expand Down
Loading

0 comments on commit 9aa1bc7

Please sign in to comment.