From 07636e0582adcfc2a4795069fd0f0ba8aab017d6 Mon Sep 17 00:00:00 2001 From: ygdrasil-io Date: Sun, 3 Mar 2024 14:27:00 +0100 Subject: [PATCH] Implement createShaderModule and createPipelineLayout functions in wgpu The functions createShaderModule and createPipelineLayout were added to classes Device.jvm and Device.js, allowing for the creation of shader modules and pipeline layouts. A simple triangle scene was initialized to demonstrate these new functionalities. Corresponding changes were made in the ShaderModule files across the main and JVM platforms. --- .../SimpleTriangleScene.kt | 35 +++++++++++++++++++ .../kotlin/io.ygdrasil.wgpu/Device.kt | 2 ++ .../kotlin/io.ygdrasil.wgpu/ShaderModule.kt | 17 +++++++++ .../jsMain/kotlin/io.ygdrasil.wgpu/Device.kt | 17 +++++++-- .../io.ygdrasil.wgpu/ShaderModule.js.kt | 25 +++++++++++++ .../kotlin/io.ygdrasil.wgpu/Device.jvm.kt | 7 ++++ .../io.ygdrasil.wgpu/ShaderModule.jvm.kt | 28 +++++++++++++++ .../internal/jvm/Structures.kt | 2 +- 8 files changed, 129 insertions(+), 4 deletions(-) create mode 100644 bindings/wgpu/examples/src/commonMain/kotlin/io.ygdrasil.wgpu.examples/SimpleTriangleScene.kt create mode 100644 bindings/wgpu/wgpu4k/src/commonMain/kotlin/io.ygdrasil.wgpu/ShaderModule.kt create mode 100644 bindings/wgpu/wgpu4k/src/jsMain/kotlin/io.ygdrasil.wgpu/ShaderModule.js.kt create mode 100644 bindings/wgpu/wgpu4k/src/jvmMain/kotlin/io.ygdrasil.wgpu/ShaderModule.jvm.kt diff --git a/bindings/wgpu/examples/src/commonMain/kotlin/io.ygdrasil.wgpu.examples/SimpleTriangleScene.kt b/bindings/wgpu/examples/src/commonMain/kotlin/io.ygdrasil.wgpu.examples/SimpleTriangleScene.kt new file mode 100644 index 00000000..c6111349 --- /dev/null +++ b/bindings/wgpu/examples/src/commonMain/kotlin/io.ygdrasil.wgpu.examples/SimpleTriangleScene.kt @@ -0,0 +1,35 @@ +package io.ygdrasil.wgpu.examples + +import io.ygdrasil.wgpu.ShaderModuleDescriptor + +class SimpleTriangleScene : Application.Scene() { + override fun Application.initialiaze() { + val shaderModule = device.createShaderModule( + ShaderModuleDescriptor( + code = shader + ) + ) + + val pipeline = device.createPipelineLayout() + + TODO("Not yet implemented") + } + + override fun Application.render() { + TODO("Not yet implemented") + } +} + +private val shader = """ + @vertex + fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4 { + let x = f32(i32(in_vertex_index) - 1); + let y = f32(i32(in_vertex_index & 1u) * 2 - 1); + return vec4(x, y, 0.0, 1.0); + } + + @fragment + fn fs_main() -> @location(0) vec4 { + return vec4(1.0, 0.0, 0.0, 1.0); + } +""".trimIndent() \ No newline at end of file diff --git a/bindings/wgpu/wgpu4k/src/commonMain/kotlin/io.ygdrasil.wgpu/Device.kt b/bindings/wgpu/wgpu4k/src/commonMain/kotlin/io.ygdrasil.wgpu/Device.kt index b67ec505..ed02ac60 100644 --- a/bindings/wgpu/wgpu4k/src/commonMain/kotlin/io.ygdrasil.wgpu/Device.kt +++ b/bindings/wgpu/wgpu4k/src/commonMain/kotlin/io.ygdrasil.wgpu/Device.kt @@ -4,6 +4,8 @@ package io.ygdrasil.wgpu expect class Device: AutoCloseable { fun createCommandEncoder(descriptor: CommandEncoderDescriptor? = null): CommandEncoder + fun createShaderModule(descriptor: ShaderModuleDescriptor) + fun createPipelineLayout(): Any } diff --git a/bindings/wgpu/wgpu4k/src/commonMain/kotlin/io.ygdrasil.wgpu/ShaderModule.kt b/bindings/wgpu/wgpu4k/src/commonMain/kotlin/io.ygdrasil.wgpu/ShaderModule.kt new file mode 100644 index 00000000..ce109d78 --- /dev/null +++ b/bindings/wgpu/wgpu4k/src/commonMain/kotlin/io.ygdrasil.wgpu/ShaderModule.kt @@ -0,0 +1,17 @@ +package io.ygdrasil.wgpu + +expect class ShaderModule { +} + +data class ShaderModuleDescriptor( + var code: String, + var label: String? = null, + var sourceMap: Any? = null, + var compilationHints: Array? = null +) { + data class CompilationHint( + var entryPoint: String, + // TODO + //var layout: dynamic /* GPUPipelineLayout? | "auto" */ + ) +} \ No newline at end of file diff --git a/bindings/wgpu/wgpu4k/src/jsMain/kotlin/io.ygdrasil.wgpu/Device.kt b/bindings/wgpu/wgpu4k/src/jsMain/kotlin/io.ygdrasil.wgpu/Device.kt index d66a8427..1b562271 100644 --- a/bindings/wgpu/wgpu4k/src/jsMain/kotlin/io.ygdrasil.wgpu/Device.kt +++ b/bindings/wgpu/wgpu4k/src/jsMain/kotlin/io.ygdrasil.wgpu/Device.kt @@ -9,9 +9,6 @@ actual class Device(val handler: GPUDevice): AutoCloseable { val queue: Queue by lazy { Queue(handler.queue) } - override fun close() { - // Nothing on JS - } actual fun createCommandEncoder(descriptor: CommandEncoderDescriptor?): CommandEncoder { return CommandEncoder( @@ -22,6 +19,20 @@ actual class Device(val handler: GPUDevice): AutoCloseable { ) } + + actual fun createShaderModule(descriptor: ShaderModuleDescriptor): ShaderModule { + return ShaderModule(handler.createShaderModule(descriptor.convert())) + } + + actual fun createPipelineLayout(): Any { + handler.createPipelineLayout( + + ) + } + + override fun close() { + // Nothing on JS + } } private fun CommandEncoderDescriptor.convert(): GPUCommandEncoderDescriptor = object : GPUCommandEncoderDescriptor { diff --git a/bindings/wgpu/wgpu4k/src/jsMain/kotlin/io.ygdrasil.wgpu/ShaderModule.js.kt b/bindings/wgpu/wgpu4k/src/jsMain/kotlin/io.ygdrasil.wgpu/ShaderModule.js.kt new file mode 100644 index 00000000..96008786 --- /dev/null +++ b/bindings/wgpu/wgpu4k/src/jsMain/kotlin/io.ygdrasil.wgpu/ShaderModule.js.kt @@ -0,0 +1,25 @@ +package io.ygdrasil.wgpu + +import io.ygdrasil.wgpu.internal.js.GPUShaderModule +import io.ygdrasil.wgpu.internal.js.GPUShaderModuleCompilationHint +import io.ygdrasil.wgpu.internal.js.GPUShaderModuleDescriptor + +actual class ShaderModule(internal val handler: GPUShaderModule) { +} + +fun ShaderModuleDescriptor.convert(): GPUShaderModuleDescriptor = object : GPUShaderModuleDescriptor { + override var code: String = this@convert.code + override var sourceMap: Any? = this@convert.sourceMap ?: undefined + override var compilationHints: Array? = this@convert + .compilationHints + ?.map { it.convert() } + ?.toTypedArray() + ?: undefined + override var label: String? = this@convert.label ?: undefined + +} + +private fun ShaderModuleDescriptor.CompilationHint.convert() = object : GPUShaderModuleCompilationHint { + override var entryPoint: String = this@convert.entryPoint + override var layout: dynamic = TODO("no yet implemented")//this@convert.layout ?: undefined +} diff --git a/bindings/wgpu/wgpu4k/src/jvmMain/kotlin/io.ygdrasil.wgpu/Device.jvm.kt b/bindings/wgpu/wgpu4k/src/jvmMain/kotlin/io.ygdrasil.wgpu/Device.jvm.kt index a6ec6f2e..e15b9c05 100644 --- a/bindings/wgpu/wgpu4k/src/jvmMain/kotlin/io.ygdrasil.wgpu/Device.jvm.kt +++ b/bindings/wgpu/wgpu4k/src/jvmMain/kotlin/io.ygdrasil.wgpu/Device.jvm.kt @@ -13,6 +13,13 @@ actual class Device(internal val handler: WGPUDeviceImpl) : AutoCloseable { ) } + actual fun createShaderModule(descriptor: ShaderModuleDescriptor): ShaderModule { + return ShaderModule( + wgpuDeviceCreateShaderModule(handler, descriptor.convert()) + ) + } + + override fun close() { wgpuDeviceRelease(handler) } diff --git a/bindings/wgpu/wgpu4k/src/jvmMain/kotlin/io.ygdrasil.wgpu/ShaderModule.jvm.kt b/bindings/wgpu/wgpu4k/src/jvmMain/kotlin/io.ygdrasil.wgpu/ShaderModule.jvm.kt new file mode 100644 index 00000000..89dbb2d0 --- /dev/null +++ b/bindings/wgpu/wgpu4k/src/jvmMain/kotlin/io.ygdrasil.wgpu/ShaderModule.jvm.kt @@ -0,0 +1,28 @@ +package io.ygdrasil.wgpu + +import com.sun.jna.NativeLong +import io.ygdrasil.wgpu.internal.jvm.* + +actual class ShaderModule(internal val handler: WGPUShaderModule?) : AutoCloseable { + override fun close() { + wgpuShaderModuleRelease(handler) + } +} + + +internal fun ShaderModuleDescriptor.convert(): WGPUShaderModuleDescriptor = WGPUShaderModuleDescriptor().also { + it.label = label + it.nextInChain = WGPUShaderModuleWGSLDescriptor.ByReference().also { + it.code = code + it.chain.apply { + sType = WGPUSType.WGPUSType_ShaderModuleWGSLDescriptor.value + } + } + it.hintCount = NativeLong(compilationHints.size) + it.hints = compilationHints.map { it.convert() } + +} + +private fun ShaderModuleDescriptor.CompilationHint.convert() = WGPUShaderModuleCompilationHint.ByReference().also { + TODO("no yet implemented") +} diff --git a/bindings/wgpu/wgpu4k/src/jvmMain/kotlin/io.ygdrasil.wgpu/internal/jvm/Structures.kt b/bindings/wgpu/wgpu4k/src/jvmMain/kotlin/io.ygdrasil.wgpu/internal/jvm/Structures.kt index 6d1af90f..2866f3f3 100644 --- a/bindings/wgpu/wgpu4k/src/jvmMain/kotlin/io.ygdrasil.wgpu/internal/jvm/Structures.kt +++ b/bindings/wgpu/wgpu4k/src/jvmMain/kotlin/io.ygdrasil.wgpu/internal/jvm/Structures.kt @@ -3021,7 +3021,7 @@ public open class WGPUShaderModuleDescriptor : Structure { * Declared([a8(next):[*:b1]i4(sType)x4](WGPUChainedStruct)))* */ @JvmField - public var nextInChain: Pointer? = null + public var nextInChain: WGPUShaderModuleWGSLDescriptor.ByReference? = null /** * mapped from (Char(layout = b1))*