From f9ffb80b9dd2022a398d39d5fd66befd81f72c9c Mon Sep 17 00:00:00 2001 From: Ulrik Guenther Date: Thu, 18 Apr 2024 21:47:55 +0200 Subject: [PATCH 1/3] VulkanTexture: Fix superfluous logging in copyTo() --- .../kotlin/graphics/scenery/backends/vulkan/VulkanTexture.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/graphics/scenery/backends/vulkan/VulkanTexture.kt b/src/main/kotlin/graphics/scenery/backends/vulkan/VulkanTexture.kt index 4b480f207..b207f9512 100644 --- a/src/main/kotlin/graphics/scenery/backends/vulkan/VulkanTexture.kt +++ b/src/main/kotlin/graphics/scenery/backends/vulkan/VulkanTexture.kt @@ -369,7 +369,7 @@ open class VulkanTexture( tmpBuffer?.let { b -> with(VU.newCommandBuffer(device, commandPools.Transfer, autostart = true)) { - logger.info("${System.nanoTime()}: Copying $width $height $depth") + logger.debug("${System.nanoTime()}: Copying $width $height $depth") transitionLayout(image.image, from = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, to = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, From 770a1d17ab5098589527d8273406892fe0ac0a22 Mon Sep 17 00:00:00 2001 From: Ulrik Guenther Date: Thu, 18 Apr 2024 21:48:18 +0200 Subject: [PATCH 2/3] SystemHelpers: Let dumpToFile() return the file handle used --- src/main/kotlin/graphics/scenery/utils/SystemHelpers.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/graphics/scenery/utils/SystemHelpers.kt b/src/main/kotlin/graphics/scenery/utils/SystemHelpers.kt index 1d67718d5..6f04d9aea 100644 --- a/src/main/kotlin/graphics/scenery/utils/SystemHelpers.kt +++ b/src/main/kotlin/graphics/scenery/utils/SystemHelpers.kt @@ -241,18 +241,21 @@ class SystemHelpers { * * @param[buf] The ByteBuffer to dump. */ - fun dumpToFile(buf: ByteBuffer, filename: String) { + fun dumpToFile(buf: ByteBuffer, filename: String): File? { try { val view = buf.duplicate().order(ByteOrder.LITTLE_ENDIAN) val file = File(filename) val channel = FileOutputStream(file, false).channel channel.write(view) channel.close() + + return file } catch (e: Exception) { logger.error("Unable to dump byte buffer to $filename") e.printStackTrace() } + return null } /** From 1b80c07bfa93f7a3055dff8e071cee1540538c17 Mon Sep 17 00:00:00 2001 From: Ulrik Guenther Date: Thu, 18 Apr 2024 21:49:41 +0200 Subject: [PATCH 3/3] PersistentTextureRequestsExample: Replace semi-deterministic counting issue after renderer shutdown with counting in runAfterRender lambda --- .../PersistentTextureRequestsExample.kt | 47 ++++++++----------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/src/test/kotlin/graphics/scenery/tests/examples/compute/PersistentTextureRequestsExample.kt b/src/test/kotlin/graphics/scenery/tests/examples/compute/PersistentTextureRequestsExample.kt index ae98b44ce..7b4c9a282 100644 --- a/src/test/kotlin/graphics/scenery/tests/examples/compute/PersistentTextureRequestsExample.kt +++ b/src/test/kotlin/graphics/scenery/tests/examples/compute/PersistentTextureRequestsExample.kt @@ -23,6 +23,7 @@ import org.lwjgl.system.MemoryUtil import java.util.concurrent.atomic.AtomicInteger import kotlin.concurrent.thread import kotlin.test.assertEquals +import kotlin.test.assertNotNull /** * Example to show how persistent texture requests - that are served once per frame - may be created @@ -63,13 +64,14 @@ class PersistentTextureRequestsExample : SceneryBase("PersistentTextureRequestsE val volume = Volume.fromRAI(img, UnsignedShortType(), AxisOrder.DEFAULT, "T1 head", hub, VolumeViewerOptions()) volume.transferFunction = TransferFunction.ramp(0.001f, 0.5f, 0.3f) + volume.spatial().scale = Vector3f(20.0f) scene.addChild(volume) - val box = Box(Vector3f(1.0f, 1.0f, 1.0f)) + val box = Box(Vector3f(2.0f)) box.name = "le box du win" box.material { textures["diffuse"] = outputTexture - metallic = 0.0f + metallic = 0.5f roughness = 1.0f } @@ -77,7 +79,7 @@ class PersistentTextureRequestsExample : SceneryBase("PersistentTextureRequestsE val light = PointLight(radius = 15.0f) light.spatial().position = Vector3f(0.0f, 0.0f, 2.0f) - light.intensity = 5.0f + light.intensity = 15.0f light.emissionColor = Vector3f(1.0f, 1.0f, 1.0f) scene.addChild(light) @@ -89,6 +91,14 @@ class PersistentTextureRequestsExample : SceneryBase("PersistentTextureRequestsE scene.addChild(this) } + renderer?.runAfterRendering?.add { + // persistent texture requests run in sync with frame rendering, + // so their count should always be one less than the total number + // of frames rendered (totalFrames is only incremented at the very + // end of the render loop, in submitFrame). + renderer?.let { assertEquals(counter.get().toLong(), it.totalFrames+1) } + } + thread { val opTexture = volumeManager.material().textures["OutputRender"]!! @@ -108,33 +118,16 @@ class PersistentTextureRequestsExample : SceneryBase("PersistentTextureRequestsE //the buffer can now, e.g., be transmitted, as is required for parallel rendering if (buffer != null && prevCounter == 100) { - SystemHelpers.dumpToFile(buffer, "texture-${SystemHelpers.formatDateTime(delimiter = "_")}.raw") - } - } - } + val file = SystemHelpers.dumpToFile(buffer, "texture-${SystemHelpers.formatDateTime(delimiter = "_")}.raw") + assertNotNull(file, "File handle should not be null.") - thread { - while (renderer?.firstImageReady == false) { - Thread.sleep(5) + val sum = file.readBytes().sum() + logger.info("Dumped: $file, ${file.length()} bytes, sum=$sum") + assertEquals(file.length(), 1280*720*4, "File should contain the correct number of bytes for a 1280x720xRGBA image") + assert(sum > 3000000) { "Sum of bytes in file should be non-zero" } + } } - - Thread.sleep(1000) //give some time for the rendering to take place - - renderer?.close() - Thread.sleep(200) //give some time for the renderer to close - - totalFrames = renderer?.totalFrames!! - } - } - - override fun main() { - // add assertions, these only get called when the example is called - // as part of scenery's integration tests - assertions[AssertionCheckPoint.AfterClose]?.add { - - assertEquals ( counter.get().toLong(), totalFrames, "One texture was returned per render frame" ) } - super.main() } /**