83 lines
3.0 KiB
Kotlin
83 lines
3.0 KiB
Kotlin
import org.openrndr.application
|
|
import org.openrndr.draw.*
|
|
import org.openrndr.math.Vector2
|
|
import org.openrndr.math.Vector3
|
|
|
|
/**
|
|
* A program identical to compute01.kt, except that the order of variables
|
|
* `age` and `pos` have been swapped, resulting in a less ideal memory layout.
|
|
* In this case the SSBO requires 192 bytes instead of 112, and padding is
|
|
* inserted after the variables `time`, `age` and `pos`.
|
|
*
|
|
* Output: byteBuffer -> text
|
|
*/
|
|
|
|
fun main() = application {
|
|
program {
|
|
// Define SSBO format
|
|
val fmt = shaderStorageFormat {
|
|
primitive("time", BufferPrimitiveType.FLOAT32)
|
|
primitive("vertex", BufferPrimitiveType.VECTOR2_FLOAT32, 3)
|
|
struct("Particle", "particles", 5) {
|
|
primitive("age", BufferPrimitiveType.FLOAT32)
|
|
primitive("pos", BufferPrimitiveType.VECTOR3_FLOAT32)
|
|
}
|
|
}
|
|
println("Study the padding in the format:\n$fmt\n")
|
|
|
|
// Create SSBO
|
|
val ssbo = shaderStorageBuffer(fmt)
|
|
|
|
// Populate SSBO
|
|
ssbo.put {
|
|
write(3.0.toFloat()) // time
|
|
repeat(3) {
|
|
write(Vector2(1.1, 1.2)) // vertex
|
|
}
|
|
repeat(5) {
|
|
write(1.0.toFloat()) // age
|
|
write(Vector3(2.1, 2.2, 2.3))// pos
|
|
}
|
|
}
|
|
|
|
// Create Compute Shader
|
|
val cs = computeStyle {
|
|
computeTransform = """
|
|
b_myData.time = 3.3;
|
|
b_myData.vertex[0] = vec2(7.01);
|
|
b_myData.vertex[1] = vec2(7.02);
|
|
b_myData.vertex[2] = vec2(7.03);
|
|
b_myData.particles[0].pos = vec3(112.0);
|
|
b_myData.particles[0].age = 111.0;
|
|
""".trimIndent()
|
|
}
|
|
cs.buffer("myData", ssbo)
|
|
|
|
// Download SSBO data to CPU
|
|
val byteBufferBeforeExecute = ssbo.createByteBuffer()
|
|
byteBufferBeforeExecute.rewind()
|
|
ssbo.read(byteBufferBeforeExecute)
|
|
|
|
// Execute compute shader
|
|
cs.execute(1, 1, 1)
|
|
|
|
// Download SSBO data to CPU
|
|
val byteBufferAfterExecute = ssbo.createByteBuffer()
|
|
byteBufferAfterExecute.rewind()
|
|
ssbo.read(byteBufferAfterExecute)
|
|
|
|
// Debugging
|
|
|
|
// Notice the (maybe unexpected) 0.0 padding values printed on the console.
|
|
// Depending on the variable size in bytes, padding may be added by the system
|
|
// to align them in memory. This will depend on the sizes of the involved variables,
|
|
// and their order. For instance, a vec3 and a float do not require padding, but
|
|
// a float followed by a vec3 pads the float with 3 values, and the vec3 with one.
|
|
// Run compute02.kt and study the output to observe a more inefficient layout.
|
|
byteBufferBeforeExecute.rewind()
|
|
byteBufferAfterExecute.rewind()
|
|
repeat(ssbo.format.size / 4) {
|
|
println("$it: ${byteBufferBeforeExecute.float} -> ${byteBufferAfterExecute.float}")
|
|
}
|
|
}
|
|
} |