{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreih33ettudhb4rwidgipnbcz36bx5az37d7fugsgtc6gapruo2f4gm",
"uri": "at://did:plc:dxjzgxe7cvirxkwfjr2tjspt/app.bsky.feed.post/3mmyo4qfezoi2"
},
"path": "/t/jme-vulkan/49551#post_14",
"publishedAt": "2026-05-29T13:32:30.000Z",
"site": "https://hub.jmonkeyengine.org",
"tags": [
"@Override",
"@Deprecated"
],
"textContent": "\n @Override\n @Deprecated\n public void invalidateState() {\n // Used to clear OpenGL's hidden driver state cache. Your DrawCmdBuilder constructs a brand new RendererStateSnapshot for every Draw, making it naturally immune to state residue issues.\n }\n\n @Override\n public void setDepthRange(float start, float end) {\n stateTracker.setDepthRange(start, end);\n }\n\n @Override\n @Deprecated\n public void postFrame() {\n // Previously used to hook glfwSwapBuffers. Now, the presentation logic is perfectly encapsulated by your VulkanFrameDriver.renderOneFrame() (including Semaphore and Fence rotation).\n }\n\n @Override\n public void deleteShader(Shader shader) {\n if (shader == null) {\n return;\n }\n\n // 1. Defensive programming: If the frontend is currently binding this soon-to-be-destroyed Shader, force unbind it\n // to prevent dangling pointers from causing crashes during subsequent DrawCmd construction.\n if (stateTracker.getCurrentShader() == shader) {\n stateTracker.setShader(null);\n }\n\n // 2. Proactively remove the reference to this Shader object from the command builder's frontend cache.\n if (drawCmdBuilder != null) {\n drawCmdBuilder.deleteShader(shader);\n }\n\n // 3. Mark the jME3 NativeObject as collected, safely removing it from the NativeObjectManager's tracking queue.\n shader.resetObject();\n\n // Note:\n // In this Vulkan architecture, the underlying VkShaderModule and VulkanPipeline are completely deduplicated\n // and cached globally in VulkanShaders and VulkanPipelineManager based on the Hash value of the GLSL source code.\n // We do not destroy the underlying Vulkan resources here; instead, we leave it to VulkanRuntime to destroy them uniformly during cleanup.\n // This maximizes reuse and avoids severe frame drops and stuttering caused by \"destroying and recompiling\" at runtime.\n }\n\n @Override\n public void deleteShaderSource(Shader.ShaderSource source) {\n if (source == null) {\n return;\n }\n\n // Simply inform the jME3 engine layer that this object has been released.\n // The Vulkan backend does not individually manage fragmented ShaderSource handles (unlike OpenGL's glCreateShader).\n // We extract and assemble the complete Shader, compile it uniformly into SPIR-V, and cache it via VulkanShaders.\n source.resetObject();\n }\n\n @Override\n public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyDepth) {\n copyFrameBuffer(src, dst, true, copyDepth);\n }\n\n @Override\n public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyColor, boolean copyDepth) {\n if (!copyColor && !copyDepth) {\n return;\n }\n\n // Generate the command and enqueue it, waiting to be executed uniformly outside the RenderPass during the RecordFrame stage.\n com.jme3.renderer.vulkan.cmd.CopyCmd cmd = com.jme3.renderer.vulkan.cmd.CopyCmd.acquire();\n cmd.src = src;\n cmd.dst = dst;\n cmd.copyColor = copyColor;\n cmd.copyDepth = copyDepth;\n drawQueue.enqueueCopy(cmd);\n }\n\n @Override\n @Deprecated\n public void setMainFrameBufferOverride(FrameBuffer fb) {\n }\n\n @Override\n public void readFrameBuffer(FrameBuffer fb, ByteBuffer byteBuf) {\n // If JME3 does not request a specific format, default to returning the standard RGBA8.\n readFrameBufferWithFormat(fb, byteBuf, Image.Format.RGBA8);\n }\n\n @Override\n public void readFrameBufferWithFormat(FrameBuffer fb, ByteBuffer byteBuf, Image.Format format) {\n if (byteBuf == null || format == null) {\n return;\n }\n try {\n runtime.readFrameBuffer(fb, byteBuf, format);\n } catch (Throwable t) {\n LOGGER.log(Level.WARNING, \"Failed to read FrameBuffer pixels\", t);\n }\n }\n\n @Override\n public void deleteFrameBuffer(FrameBuffer fb) {\n if (fb == null) {\n return;\n }\n\n // If the frontend is currently binding this soon-to-be-destroyed FrameBuffer, force unbind it.\n // This prevents dangling pointers from causing crashes due to missing VRAM during subsequent Draw rendering.\n if (stateTracker.getCurrentFb() == fb) {\n stateTracker.setFrameBuffer(null);\n }\n\n try {\n // Delegate to Runtime for the safe destruction of underlying VRAM, preventing Vulkan crashes through a delayed destruction queue mechanism.\n runtime.deleteFrameBuffer(fb);\n } catch (Throwable t) {\n LOGGER.log(Level.WARNING, \"Failed to delete FrameBuffer\", t);\n }\n }\n\n\n\n @Override\n @Deprecated\n public void popDebugGroup() {\n // Vulkan natively supports vkCmdBeginDebugUtilsLabelEXT, but the cost-to-benefit ratio is extremely low. Modern Vulkan development relies heavily on external tools like RenderDoc / Nsight, so engine-layer label tagging can be omitted. Keep empty.\n }\n\n @Override\n @Deprecated\n public void pushDebugGroup(String name) {\n // Vulkan natively supports vkCmdBeginDebugUtilsLabelEXT, but the cost-to-benefit ratio is extremely low. Modern Vulkan development relies heavily on external tools like RenderDoc / Nsight, so engine-layer label tagging can be omitted. Keep empty.\n }\n\n @Override\n @Deprecated\n public void resetGLObjects() {\n // Used to handle OpenGL Context loss. In your Vulkan architecture, device loss recovery is completely triggered by VulkanFrameDriver via Swapchain Recreate, and VMA manages memory uniformly. This kind of global legacy ID reset is unnecessary.\n }\n\n @Override\n public void setDefaultAnisotropicFilter(int level) {\n runtime.setDefaultAnisotropicFilter(level);\n }\n\n @Override\n public int getDefaultAnisotropicFilter() {\n return runtime.getDefaultAnisotropicFilter();\n }\n\n @Override\n public void setAlphaToCoverage(boolean value) {\n stateTracker.setAlphaToCoverage(value);\n }\n\n @Override\n public boolean getAlphaToCoverage() {\n return stateTracker.getAlphaToCoverage();\n }\n\n @Override\n public void setMainFrameBufferSrgb(boolean srgb) {\n runtime.setMainFrameBufferSrgb(srgb);\n }\n\n @Override\n public boolean isMainFrameBufferSrgb() {\n return runtime.isMainFrameBufferSrgb();\n }\n\n @Override\n public void setLinearizeSrgbImages(boolean linearize) {\n runtime.setLinearizeSrgbImages(linearize);\n }\n\n @Override\n public boolean isLinearizeSrgbImages() {\n return runtime.isLinearizeSrgbImages();\n }\n\n @Override\n @Deprecated\n public int[] generateProfilingTasks(int numTasks) {\n // This is the built-in GPU timeline profiler of the JME3 engine. Implementing this in Vulkan requires using VkQueryPool to write Timestamps and handling out-of-order queue synchronization, which has a very low cost-to-benefit ratio. Modern development should directly use external tools like RenderDoc or Nsight. Just keep returning 0 / false / new int[0].\n return new int[0];\n }\n\n @Override\n @Deprecated\n public void startProfiling(int taskId) {\n // This is the built-in GPU timeline profiler of the JME3 engine. Implementing this in Vulkan requires using VkQueryPool to write Timestamps and handling out-of-order queue synchronization, which has a very low cost-to-benefit ratio. Modern development should directly use external tools like RenderDoc or Nsight. Just keep returning 0 / false / new int[0].\n }\n\n @Override\n @Deprecated\n public void stopProfiling() {\n // This is the built-in GPU timeline profiler of the JME3 engine. Implementing this in Vulkan requires using VkQueryPool to write Timestamps and handling out-of-order queue synchronization, which has a very low cost-to-benefit ratio. Modern development should directly use external tools like RenderDoc or Nsight. Just keep returning 0 / false / new int[0].\n }\n\n @Override\n @Deprecated\n public long getProfilingTime(int taskId) {\n // This is the built-in GPU timeline profiler of the JME3 engine. Implementing this in Vulkan requires using VkQueryPool to write Timestamps and handling out-of-order queue synchronization, which has a very low cost-to-benefit ratio. Modern development should directly use external tools like RenderDoc or Nsight. Just keep returning 0 / false / new int[0].\n return 0;\n }\n\n @Override\n @Deprecated\n public boolean isTaskResultAvailable(int taskId) {\n // Built-in GPU time-consuming query. Writing Timestamps via VkQueryPool and synchronizing them in out-of-order queues in Vulkan is highly complex and carries high overhead. This functionality is completely left to external frame capture tools like RenderDoc. Return false, 0, or new int[0].\n return false;\n }\n\n @Override\n public float getMaxLineWidth() {\n // Modern Vulkan recommends always fixing the line width to 1.0f. Line widths greater than 1 require GPU support for the wideLines feature (mostly unsupported on Mac and mobile). Just keep returning 1.0f;\n return 1.0f;\n }\n\n @Override\n @Deprecated\n public void setTextureImage(int unit, TextureImage tex) throws TextureUnitException {\n // Compute Shader image read/write. The current renderer architecture focuses on the Graphics Pipeline and has not yet implemented Compute Shader Image Load/Store functionality. Keep empty.\n }\n\n @Override\n @Deprecated\n public void updateShaderStorageBufferObjectData(com.jme3.shader.bufferobject.BufferObject bo) {\n\n }\n\n @Override\n @Deprecated\n public void updateUniformBufferObjectData(com.jme3.shader.bufferobject.BufferObject bo) {\n // Direct UBO/SSBO binding. In this architecture, UBO data (like WVP, material parameters) is extracted from the Shader and Material by the DrawCmdBuilder and written to dc.uboData, then dynamically written via high-frequency providers. There is no need to bind these objects individually the OpenGL way. Keep empty.\n }\n\n @Override\n @Deprecated\n public void setShaderStorageBufferObject(int bindingPoint, com.jme3.shader.bufferobject.BufferObject bufferObject) {\n // Direct UBO/SSBO binding. In this architecture, UBO data (like WVP, material parameters) is extracted from the Shader and Material by the DrawCmdBuilder and written to dc.uboData, then dynamically written via high-frequency providers. There is no need to bind these objects individually the OpenGL way. Keep empty.\n }\n\n @Override\n @Deprecated\n public void setUniformBufferObject(int bindingPoint, com.jme3.shader.bufferobject.BufferObject bufferObject) {\n // Direct UBO/SSBO binding. In this architecture, UBO data (like WVP, material parameters) is extracted from the Shader and Material by the DrawCmdBuilder and written to dc.uboData, then dynamically written via high-frequency providers. There is no need to bind these objects individually the OpenGL way. Keep empty.\n }\n\n @Override\n @Deprecated\n public void deleteBuffer(BufferObject bo) {\n // In the Vulkan architecture, the data flow of UBOs has been completely refactored. It follows a fully dynamic, data-driven, high-performance path, perfectly bypassing jME3's native BufferObject.\n }\n\n\nAdded the specific implementation of the render method. Some of them have been marked for deletion.",
"title": "jme-Vulkan"
}