Skip to content

ComputeTarget.kt

src/jvmMain/kotlin/afield/graphics/vulkan/targets/ComputeTarget.kt · 101 lines

package afield.graphics.vulkan.targets

import afield.app.diagnostics.Named
import afield.graphics.vulkan.Renderer
import afield.graphics.vulkan.Target
import afield.graphics.vulkan.device.CommandBuffer
import afield.graphics.render.ComputeModule
import afield.graphics.render.ComputeModulePointer
import afield.graphics.render.RayTracingModule
import afield.graphics.render.RayTracingModulePointer
import afield.graphics.render.pointer
import afield.math.linalg.Rectanglef
import org.lwjgl.system.MemoryStack

A Target that records compute and ray-tracing modules into a frame without drawing to a window.

Modules and plain command-recording functions are added with += on a ComputeTarget and run each frame: compute modules first, then ray-tracing modules, then the other targets.

class ComputeTarget

Records named compute modules, ray-tracing modules and other Targets into the frame's command buffer.

class ComputeTarget(
    /** The renderer this target records into, and the identity each added module's lifecycle claim is filed under. */
    val renderer: Renderer
) : Target {

var modules = mutableMapOf<String, ComputeModulePointer>()

The compute modules dispatched each frame, by name, in insertion order and before rayTracingModules. Add with +=.

var rayTracingModules = mutableMapOf<String, RayTracingModulePointer>()

The ray-tracing modules traced each frame, by name, after every compute module has been recorded.

var others = mutableMapOf<String, Target>()

Targets recorded after this one's own modules, by name. A (name, (CommandBuffer, Int) -> Unit) pair added with += lands here too, wrapped as a target, which is how plain recording code joins the frame.

operator fun plusAssign(m: Pair<String, ComputeModulePointer>)

    @JvmName("plusAssign")
    operator fun plusAssign(m: Pair<String, ComputeModulePointer>) {
        modules.putOwned(m.first, m.second, renderer)
    }

operator fun plusAssign(m: Named<ComputeModulePointer>)

    @JvmName("plusAssign_n")
    operator fun plusAssign(m: Named<ComputeModulePointer>) {
        modules.putOwned(m.name, m.value, renderer)
    }

operator fun plusAssign(m: Pair<String, ComputeModule>)

    @JvmName("plusAssign_module")
    operator fun plusAssign(m: Pair<String, ComputeModule>) {
        modules.putOwned(m.first, m.second.pointer(), renderer)
    }

operator fun plusAssign(m: Pair<String, RayTracingModulePointer>)

    @JvmName("plusAssign_rayTracing")
    operator fun plusAssign(m: Pair<String, RayTracingModulePointer>) {
        rayTracingModules.putOwned(m.first, m.second, renderer)
    }

operator fun plusAssign(m: Pair<String, RayTracingModule>)

    @JvmName("plusAssign_rayTracingModule")
    operator fun plusAssign(m: Pair<String, RayTracingModule>) {
        rayTracingModules.putOwned(m.first, m.second.pointer(), renderer)
    }

operator fun plusAssign(m: Pair<String, Target>)

    @JvmName("plusAssign_target")
    operator fun plusAssign(m: Pair<String, Target>) {
        others.putOwned(m.first, m.second, renderer)
    }

operator fun plusAssign(m: Pair<String, (CommandBuffer, Int) -> Unit>) {

    @JvmName("plusAssign_function")
    operator fun plusAssign(m: Pair<String, (CommandBuffer, Int) -> Unit>) {
        others.putOwned(m.first, object : Target {
            override fun render(command: CommandBuffer, index: Int) {
                m.second.invoke(command, index)
            }
        }, renderer)
    }

override fun render(command: CommandBuffer, index: Int)

    override fun render(command: CommandBuffer, index: Int) {
        MemoryStack.stackPush().use { stack ->

            // this is a difference from rendertarget (which is using a more dynamic thing)

//            val begin = VkCommandBufferBeginInfo.calloc(stack)
//            begin.sType(VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO)
//            vkBeginCommandBuffer(command.vkCommandBuffer, begin)

            modules.forEach {
                it.value.render(command, Rectanglef(0f, 0f, 0f, 0f))
            }

            rayTracingModules.forEach {
                it.value.render(command, Rectanglef(0f, 0f, 0f, 0f))
            }

//            vkEndCommandBuffer(command.vkCommandBuffer)

            others.forEach { it.value.render(command, index) }
        }
    }


}