Direct3D 12 indirect command implementation method based on annular multi-buffer command generation pool

By using a circular multi-buffered command generation pool, the inefficiency of D3D12 indirect command emulation in GPU hardware environments that do not support VK_EXT_device_generated_commands is solved. This method achieves efficient and complete D3D12 indirect command emulation, reduces CPU load, minimizes synchronization latency, and optimizes memory utilization.

CN121833294AActive Publication Date: 2026-04-10北京麟卓信息科技有限公司

Patent Information

Authority / Receiving Office
CN · China
Patent Type
Applications(China)
Current Assignee / Owner
Filing Date
2026-03-13
Publication Date
2026-04-10

AI Technical Summary

Technical Problem

In GPU hardware environments that do not support the VK_EXT_device_generated_commands extension feature, existing technologies suffer from issues such as increased CPU load, severe synchronization latency, insufficient command flexibility, wasted memory bandwidth, and memory fragmentation, making it impossible to efficiently simulate D3D12 indirect commands.

Method used

By optimizing the VKD3D source code and the Linux kernel graphics subsystem, and adopting a ring-shaped multi-buffered command generation pool method, a hierarchical semantic mapping table and virtual command layout are established to generate a ring-shaped multi-buffered command generation pool, which includes a hierarchical structure of main buffer and sub-buffer. Parameter mapping and memory layout are optimized, and buffers are dynamically managed to achieve efficient simulation of D3D12 core functions on Vulkan.

Benefits of technology

It achieves efficient and complete D3D12 indirect command emulation when VK_EXT_device_generated_commands are not supported, reduces CPU load, reduces synchronization latency, improves memory utilization, supports multi-command combinations and dynamic command sequences, and optimizes memory bandwidth usage.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN121833294A_ABST
    Figure CN121833294A_ABST
Patent Text Reader

Abstract

The invention discloses a Direct3D (Three Dimensional) 12 indirect command implementation method based on an annular multi-buffer command generation pool, which comprises the following steps of: when a GPU (Graphics Processing Unit) does not support VKEXTdevicegenerator communities, creating a command signature VKD3D analysis parameter to generate a hierarchical semantic mapping table and a virtual command layout by using an application, initializing the annular multi-buffer command generation pool, determining an annular pool scheduling mode after the application enters a rendering loop, and generating a virtual command; the method comprises the following steps: converting native D3D12 indirect command parameters into Vulkan command parameters adaptive to GPU hardware, writing the Vulkan command parameters into an annular pool, performing hardware adaptive partitioning on a parameter buffer area after an application initiates an indirect drawing request to generate a scheduling list, binding the buffer area, packaging command batches, submitting the command batches to a kernel, generating a command queue which can be identified by a GPU by the kernel, and submitting the command queue to a GPU hardware queue to finish rendering.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] This invention belongs to the field of computer software development technology, specifically relating to a Direct3D 12 indirect command implementation method based on a circular multi-buffered command generation pool. Background Technology

[0002] The D3D12 ExecuteIndirect interface is the core of its GPU-driven rendering implementation. This interface allows: the GPU to autonomously generate parameters for drawing, scheduling, and push constants, such as the number of instances and vertex offsets; adjust the length and execution conditions of command sequences based on runtime dynamic data; execute a combination sequence of multiple command types in a single call, with command parameters updated in real time through the GPU's Unordered Access View (UAV); and supports D3D12_COMMAND_SIGNATURE for flexibly defining the layout and type mapping relationship of command parameters, including special parameter format support for indexed drawing commands such as D3D12_INDIRECT_ARGUMENT_TYPE_INDEXED_DRAW. The GPU's VK_EXT_device_generated_commands extension provides Vulkan with GPU-side command generation and execution capabilities that match D3D12 indirect commands. Its core includes the command layout definition of VkIndirectCommandsLayoutEXT, the execution mechanism of the GPU directly reading the command buffer, and performance optimization methods for preprocessing commands.

[0003] However, when the GPU lacks this extended feature, traditional simulation solutions suffer from the following key drawbacks: First, CPU load surges, relying on pre-generated command sequences from the CPU, leading to CPU utilization exceeding 50% in complex 3D scenes and becoming a frame rate bottleneck. Second, synchronization latency is severe; when using compute shaders (CS) to simulate GPU command generation, synchronization between CS and the graphics pipeline relies on heavy memory barriers, resulting in a command execution delay of 1 to 2 frames. Third, command flexibility is insufficient; Vulkan's native indirect commands (such as vkCmdDrawIndirect) only support single command types, failing to match the signature definition of multiple D3D12 command combinations, and lacking adaptation to parameter formats for special commands such as indexed drawing. Fourth, dynamic simulation is inefficient; simulation of D3D12 variable-length command sequences and conditional execution requires frequent updates to the parameter buffer via the CPU, disrupting the core logic of GPU-driven rendering. Fifth, memory bandwidth is wasted; the reading and writing of command parameter buffers are not specifically optimized, frequent CPU-to-GPU data copying increases memory bandwidth overhead by over 40%, and the lack of adaptation to GPU memory page sizes leads to memory fragmentation issues.

[0004] The existing VKD3D downgrade solution for when the GPU does not support the VK_EXT_device_generated_commands extension feature only implements basic functions through simple CPU command pre-generation or single-buffered CS simulation. It does not perform in-depth optimization for the semantic mapping of D3D12 commands, the synchronization mechanism of GPU-side command generation, and the kernel-level command submission process, and cannot balance functional completeness and performance requirements. Summary of the Invention

[0005] In view of this, the present invention provides a Direct3D 12 indirect command implementation method based on a ring-shaped multi-buffered command generation pool. When VK_EXT_device_generated_commands is not supported, efficient and complete simulation of D3D12 core functions on Vulkan is achieved by optimizing the VKD3D source code and the Linux kernel graphics subsystem.

[0006] The Direct3D 12 indirect command implementation method based on a circular multi-buffered command generation pool provided by this invention specifically includes the following steps:

[0007] The D3D application creates command signatures, and VKD3D parses parameters to build a hierarchical semantic mapping table, including the correspondence between D3D12 command types and Vulkan indirect commands, D3D12 parameter offsets and Vulkan parameter buffer memory layouts, and execution dependency trees; based on the hierarchical semantic mapping table, a virtual command layout is created, a GPU hardware adaptation sub-table is generated, and a ring-shaped multi-buffered command generation pool is constructed, containing a buffer with a hierarchical structure of main buffer and sub-buffers. The starting address and size of the sub-buffers are added to the buffer partition table.

[0008] The application enters the rendering loop and loads scene data. The pre-computed shader obtains the basic data and binds rendering resources. VKD3D pre-calculates the total number of commands and sub-command lengths of the current frame to obtain the command length index buffer. The scheduling mode of the circular multi-buffered command generation pool is determined by the GPU load during the rendering of the previous frame. The basic data is calculated to obtain D3D12 indirect command parameters. VKD3D maps the parameters to Vulkan parameters according to the virtual command layout and hierarchical semantic mapping table. The parameters are corrected according to the hardware adaptation sub-table and Vulkan memory alignment requirements to obtain Vulkan command parameters. According to the scheduling mode, the Vulkan command parameters, validity flags, and length data are written to the sub-buffer of the current parameter buffer of the circular multi-buffered command generation pool.

[0009] When an application initiates an indirect drawing request, VKD3D performs hardware adaptation partitioning on the current parameter buffer based on the command length index buffer and the buffer partition table. It divides the sub-buffer corresponding to ordinary commands into contiguous memory blocks, allocates partitions for commands in the sub-buffer corresponding to special commands, and generates a partition mapping table. Based on the hierarchical semantic mapping table, it determines the Vulkan interface of the current parameter buffer and the association between parameters, inserts pipeline barriers to obtain the Vulkan command scheduling list, and binds it to the current parameter buffer.

[0010] When an application requests the GPU to perform rendering, VKD3D packages the Vulkan command schedule list into command batches according to priority and submits them to the kernel. The kernel then generates a command queue and submits it to the GPU hardware queue to complete the rendering.

[0011] Furthermore, the virtual command layout is used to store command type sequences, command parameter buffer information, conditional execution rules, and function call pointers for Vulkan indirect commands. The parameter buffer information includes offset, length, and valid flag offset.

[0012] Furthermore, VKD3D generates static data hashes based on static objects and static resources in the scene data, obtains associated resource hashes from associated resources, generates cache keys based on command signature ID, static data hashes, GPU hardware characteristics, command type and length, and associated resource hashes, queries multi-level command cache pools step by step, and if a cache hit occurs, retrieves Vulkan command parameters based on the address of the command parameters in the cache.

[0013] Furthermore, the method for determining the scheduling mode of the circular multi-buffered command generation pool based on the GPU load during the rendering of the previous frame is as follows:

[0014] When the load value is less than the minimum threshold, the compute shader thread selects an idle buffer in the circular multi-buffered command generation pool as the production buffer, writes parameters, validity flags and length data, the graphics pipeline reads the buffer of the previous frame as the consumption buffer, executes indirect commands, and the remaining buffers are reserved.

[0015] When the load value is not less than the minimum threshold and less than the maximum threshold, the two compute shader threads write to two buffers respectively, and the graphics pipeline reads the two history buffers at the same time, executing different types of commands in parallel.

[0016] When the load value is not less than the maximum threshold, two compute shader threads write to two buffers, two graphics pipeline queues read from two history buffers respectively, and different queues execute commands in parallel.

[0017] Furthermore, the method of allocating partitions for commands in the special command corresponding sub-buffer is as follows: in the special command corresponding sub-buffer, a partition with a size equal to the product of the command length and the number of commands, and whose address alignment bytes are determined according to the command type, is allocated for each command.

[0018] Furthermore, the method for determining the address alignment bytes based on the command type is as follows: for index drawing commands, the starting address is aligned to 8 bytes, and for ray tracing scheduling commands, the starting address is aligned to 16 bytes.

[0019] Furthermore, after inserting the pipeline barrier, the command calls corresponding to Vulkan command parameters with invalid flags are first filtered out based on the valid flag buffer corresponding to the Vulkan command parameters in the current parameter buffer, and then a Vulkan command scheduling list is generated.

[0020] Furthermore, the method by which VKD3D packages the Vulkan command schedule list into command batches according to priority and submits them to the kernel is as follows: VKD3D reads the priority identifier of each command in the Vulkan command schedule list, adds high-priority commands to high-priority batches, and adds low-priority commands to ordinary batches. For each command batch, it saves its corresponding priority, parameter buffer address, effective parameter offset in the Vulkan command schedule list, and corresponding Vulkan command type, and then passes the command batch, Vulkan command schedule list, and auxiliary buffer pointer to the kernel.

[0021] Furthermore, the kernel generates the command queue as follows: the kernel stores high-priority batches into a high-priority queue and ordinary batches into an ordinary queue. Then, it determines the dependencies between commands based on the Vulkan command scheduling list associated with the parameter buffer, inserts the corresponding GPU hardware synchronization primitives in conjunction with the hardware adaptation sub-table, obtains a command queue that the GPU can recognize, and maps the physical address of the parameter buffer to a virtual address that the GPU can directly access.

[0022] Furthermore, the circular multi-buffered command generation pool is dynamically managed, specifically by: real-time monitoring of buffer usage and triggering dynamic expansion or contraction; periodically performing buffer defragmentation to arrange valid command parameters sequentially, release invalid memory, and control the memory fragmentation rate within a set range.

[0023] Beneficial effects:

[0024] In this invention, after VKD3D and D3D applications start, the application creates a D3D12 logical device and command signature. VKD3D parses the command signature to generate and store metadata such as a hierarchical semantic mapping table and virtual command layout. Simultaneously, it generates a hardware adaptation sub-table and initializes a circular multi-buffered command generation pool. After the application enters the rendering loop, VKD3D pre-calculates the command length based on scene data, determines the circular pool scheduling mode, generates cache keys, and queries multi-level caches. If a cache miss occurs, the application's GPU side generates native D3D12 indirect command parameters, which are then converted by VKD3D into Vulnerable Contexts adapted to the GPU hardware. The Vulkan driver takes the Vulkan command parameters and writes them to the production buffer of the circular pool. After the application initiates an indirect rendering request, VKD3D performs hardware adaptation partitioning on the parameter buffer, matches the Vulkan interface, handles command dependencies, filters invalid commands, generates a scheduling list, and binds the buffer address. VKD3D packages the commands into batches according to priority and submits them to the kernel. The kernel completes queue scheduling, dependency resolution, synchronization primitive insertion, and address mapping to generate a command queue that the GPU can recognize. Finally, the Vulkan driver submits the command queue to the GPU hardware queue, and the GPU reads the Vulkan parameters in the parameter buffer to complete the rendering. Attached Figure Description

[0025] Figure 1 This is a flowchart illustrating the Direct3D 12 indirect command implementation method based on a circular multi-buffered command generation pool provided by the present invention. Detailed Implementation

[0026] The present invention will be described in detail below with reference to the accompanying drawings and embodiments.

[0027] The Direct3D 12 indirect command implementation method based on a circular multi-buffered command generation pool provided by this invention has the following core idea: After VKD3D and the D3D application start, the application creates a D3D12 logical device and command signature. VKD3D parses the command signature to generate and store metadata such as a hierarchical semantic mapping table and virtual command layout, while simultaneously generating a hardware adaptation sub-table and initializing the circular multi-buffered command generation pool. After the application enters the rendering loop, VKD3D pre-calculates the command length based on scene data, determines the circular pool scheduling mode, generates cache keys, and queries multi-level caches. If a cache miss occurs, the application's GPU generates native D3D12 indirect command parameters, which are then converted by VKD3D into adapted GP parameters. The Vulkan driver takes the hardware's Vulkan command parameters and writes them to the production buffer of the circular pool. After the application initiates an indirect rendering request, VKD3D performs hardware adaptation partitioning on the parameter buffer, matches the Vulkan interface, handles command dependencies, filters invalid commands, generates a scheduling list, and binds the buffer address. VKD3D packages the commands into batches according to priority and submits them to the kernel. The kernel completes queue scheduling, dependency resolution, synchronization primitive insertion, and address mapping to generate a command queue that the GPU can recognize. Finally, the Vulkan driver submits the command queue to the GPU hardware queue, and the GPU reads the Vulkan parameters in the parameter buffer to complete the rendering.

[0028] The Direct3D 12 indirect command implementation method based on a circular multi-buffered command generation pool provided by this invention has the following processing flow: Figure 1 As shown, the specific steps include:

[0029] Step 1: After VKD3D and the D3D application start, the application creates a D3D12 logical device and passes in a command signature description structure to create the command signature required for indirect drawing, generating a command signature ID. VKD3D parses the command signature description structure to obtain the parameter type, binding slot, offset, data length, alignment requirements, conditional execution rules, and nesting hierarchy of each parameter; it establishes a hierarchical semantic mapping table, including the correspondence between D3D12 command types and Vulkan indirect commands, the correspondence between the parameter offsets of D3D12 command signatures and the memory layout of Vulkan parameter buffers, and the execution dependency tree of D3D12 commands marked with special command execution priorities.

[0030] A virtual command layout is created based on a hierarchical semantic mapping table, storing command type sequences, parameter buffer information for each command, conditional execution rules, and function call pointers for Vulkan indirect commands. The parameter buffer information includes offsets, lengths, and valid flag offsets. The virtual command layout, hierarchical semantic mapping table, and hardware adaptation information for special commands are compiled into binary metadata and stored in a metadata buffer in the GPU's local memory. A CPU-side command signature index table is generated, with command signature IDs as keys and metadata pointers as values. A hardware adaptation sub-table is generated based on the GPU model and embedded in the header of the metadata buffer. A circular multi-buffered command generation pool is initialized based on GPU hardware characteristics, containing multiple dynamically adjustable buffers. The buffers are a hierarchical structure of main buffers and sub-buffers, with the main buffer associated with two auxiliary buffers. The starting address and size of the sub-buffers are added to the buffer partition table.

[0031] The ring-shaped multi-buffered command generation pool is initialized according to the characteristics of GPU hardware. It contains multiple dynamically adjustable buffers. The buffers are a hierarchical structure of main buffers and sub-buffers. The main buffer is associated with two auxiliary buffers. Specifically, the main buffer is allocated according to GPU memory page alignment and supports compute shader writing and graphics pipeline reading. The main buffer is divided into ordinary command sub-buffers and special command sub-buffers according to the command type. The main buffer is associated with two auxiliary buffers, namely the valid flag buffer and the length buffer.

[0032] Step 2: When the application enters the rendering loop, it loads scene data, executes the pre-computed shader, completes logic such as frustum culling, instance count, and ray tracing scene complexity calculation, obtains basic data, and completes rendering resource binding. VKD3D pre-calculates the total number of possible commands and the length of each sub-command based on the dynamic scene data to obtain a command length index buffer. The index entries contain command type identifier, parameter length, and starting offset. It obtains the GPU load during the rendering of the previous frame and determines the scheduling mode of the circular multi-buffered command generation pool based on the load value. It generates static data hashes from static objects and static resources in the scene data, obtains associated resource hashes from associated resources, and generates cache keys based on command signature ID, static data hashes, GPU hardware characteristics, command type and length, and associated resource hashes. It queries the multi-level command cache pool level by level. If the cache is hit, it obtains the command parameters based on the address of the command parameters in the cache and executes Step 4; otherwise, it executes Step 3.

[0033] Specifically, the GPU load during the rendering of the previous frame is obtained, and the scheduling mode of the circular multi-buffered command generation pool is determined based on the load value.

[0034] When the load value is less than the minimum threshold, the compute shader thread selects an idle buffer in the circular multi-buffered command generation pool as the production buffer, writes parameters, validity flags and length data, the graphics pipeline reads the buffer of the previous frame as the consumption buffer, executes indirect commands, and the remaining buffers are reserved.

[0035] When the load value is not less than the minimum threshold and less than the maximum threshold, the two compute shader threads write to two buffers respectively, and the graphics pipeline reads the two history buffers at the same time, executing different types of commands in parallel.

[0036] When the load value is not less than the maximum threshold, two compute shader threads write to two buffers, and two graphics pipeline queues read from two history buffers respectively. Commands are executed in parallel by different queues, and resource contention is avoided through lightweight synchronization.

[0037] In addition, after each frame ends, the current buffer read and write is first confirmed to be complete, and then the pointer of the circular multi-buffer command generation pool is moved forward according to the number of production buffers, and the buffer partition table is updated synchronously to ensure that the production and consumption buffers of the next frame match the command type and ensure scheduling continuity.

[0038] Step 3: The GPU-side shader logic of the application calculates the native D3D12 indirect command parameters based on the basic data, adds them to the command buffer, and defines conditional execution and dynamic length control rules.

[0039] VKD3D loads the virtual command layout and hardware adaptation sub-table, adapts the D3D12 indirect command parameters to the Vulkan parameter data type and byte order, maps the D3D12 parameters to Vulkan parameters according to the hierarchical semantic mapping table, corrects parameters that exceed GPU hardware limitations according to the hardware adaptation sub-table, modifies the parameter offsets according to Vulkan's memory alignment requirements for the indirect command buffer, and obtains the Vulkan parameters. It then sets the command validity flag and handles nested condition logic according to application rules, counts the number of valid commands and writes them to the length buffer, obtaining the Vulkan command parameters; finally, it calculates the cache key of the Vulkan command parameters and adds them to a multi-level command cache pool.

[0040] According to the determined scheduling mode, the free buffer of the ring multi-buffered command generation pool is selected as the production buffer, which is the current parameter buffer. The Vulkan command parameters are written into the sub-buffer of the current parameter buffer according to the command type. At the same time, the valid flag and length data of the command are written, and differential compression is performed on the memory area corresponding to the invalid command according to the command type.

[0041] After the circular multi-buffered command generation pool is written, event synchronization is triggered, blocking the indirect command execution phase of the graphics pipeline. Inter-frame fence synchronization is set to ensure that the buffer consumed in the previous frame is completely released before reuse.

[0042] Differentiated compression includes flag compression for ordinary commands and parameter mask compression for special commands.

[0043] Furthermore, this invention dynamically manages the circular multi-buffered command generation pool, specifically by: monitoring the buffer usage rate in real time, triggering dynamic expansion or contraction to balance memory usage and performance; periodically performing buffer defragmentation to arrange valid command parameters consecutively, release invalid memory, and control the memory fragmentation rate within a set range.

[0044] Step 4: When initiating an indirect drawing request using parameters such as the input command signature, command buffer, and maximum number of commands, VKD3D performs hardware adaptation partitioning of the current parameter buffer based on the command length index buffer and the buffer partition table. According to the command type, the sub-buffer corresponding to ordinary commands is divided into multiple contiguous memory blocks. In the sub-buffer corresponding to special commands, a partition with a size equal to the product of the command length and the number of commands and an address alignment byte determined according to the command type is allocated for the command. A partition mapping table is generated to record the addressing information of the command.

[0045] Based on the command type of the Vulkan command parameters in the current parameter buffer, match the correspondence between command types and Vulkan indirect commands in the hierarchical semantic map to determine whether to use the native Vulkan interface or the extended interface; based on the execution order of the parameters in the current parameter buffer and the execution dependency tree of the hierarchical semantic map, determine the association between Vulkan command parameters, and insert lightweight pipeline barriers between the commands corresponding to the associated parameters; based on the valid flag buffer corresponding to the Vulkan command parameters in the current parameter buffer, filter out command calls corresponding to Vulkan command parameters with invalid flags, obtain the Vulkan command scheduling list, and bind it to the address of the current parameter buffer.

[0046] Specifically, the address alignment bytes are determined according to the command type: for index drawing commands, the starting address is aligned to 8 bytes, and for ray tracing scheduling commands, the starting address is aligned to 16 bytes.

[0047] Specifically, the partition mapping table records command addressing information, including the partition address for each command type, the number of valid commands, and hardware adaptation parameters. The Vulkan command scheduler list contains the memory offset of valid parameters, the corresponding interface type called, and the pipeline barrier insertion location, etc.

[0048] Step 5: After the application completes the recording of all command lists for the current frame and submits the current frame command queue, when requesting the GPU to execute rendering, VKD3D reads the priority identifier of each command in the Vulkan command scheduling list, adds high-priority commands to high-priority batches, and low-priority commands to ordinary batches. For each command batch, it saves its corresponding priority, parameter buffer address, valid parameter offset in the Vulkan command scheduling list, and corresponding Vulkan command type. Then, it passes the command batch, Vulkan command scheduling list, and auxiliary buffer pointer to the kernel all at once. After receiving the data, the kernel stores high-priority batches in the high-priority queue and ordinary batches in the ordinary queue. Then, it determines the dependencies between commands based on the Vulkan command scheduling list associated with the parameter buffer, inserts the corresponding GPU hardware synchronization primitives in conjunction with the hardware adapter sub-table, obtains a command queue that the GPU can recognize, maps the physical address of the parameter buffer to a virtual address that the GPU can directly access, and associates the synchronization results so that VKD3D can query the execution status of the corresponding Vulkan parameters in real time through the parameter buffer address.

[0049] Furthermore, to improve the reliability of command execution, this invention performs full parameter verification on the command queue based on the hardware adaptation sub-table before submitting the command queue and virtual address to the GPU hardware queue: checking the legality of parameters for ordinary and special commands, whether they exceed GPU hardware limits, correcting invalid parameters, splitting and downgrading parameters that exceed the limits, and synchronously generating verification logs to facilitate debugging and problem location.

[0050] Step 6: The Vulkan driver submits the command queue and virtual address to the GPU hardware queue. The GPU reads the Vulkan command parameters in the parameter buffer based on the received executable command instructions to complete the rendering of the current frame.

[0051] To address the issue of Vulkan indirect command execution failures, this invention establishes a tiered rollback mechanism, specifically as follows:

[0052] Level 1 rollback involves lightweight software-level corrections to both regular and special commands, followed by resubmitting parameters. Level 2 rollback pauses command submission for the current frame and switches to the CPU's pre-stored backup command sequence to ensure uninterrupted basic rendering. Level 3 rollback waits for the GPU to become idle, then resets the GPU device, reinitializes the command generation process, and resumes execution. Upon successful rollback, the next frame automatically resumes GPU generation mode. Fault information is recorded throughout the process to a designated log file.

[0053] Example:

[0054] This embodiment employs the Direct3D 12 indirect command implementation method based on a ring-shaped multi-buffered command generation pool provided by the present invention. It achieves normal operation of D3D 12 applications in a GPU hardware environment that does not support the VK_EXT_device_generated_commands extension feature. The specific process includes:

[0055] The hierarchical semantic parsing and Vulkan mapping of S1 and D3D12 command signatures resolves the issue of semantic mismatch between D3D12 and Vulkan commands by parsing the D3D12_COMMAND_SIGNATURE_DESC command signature into hierarchical metadata recognizable by Vulkan.

[0056] S1.1 Structured parsing of command signatures: A new D3D12SignatureParser module is added to the VKD3D source code. This module receives the D3D12_COMMAND_SIGNATURE_DESC structure passed from the D3D12 application and parses it item by item from the D3D12_INDIRECT_ARGUMENT_DESC array.

[0057] Extract the type of each parameter, including common types (such as D3D12_INDIRECT_ARGUMENT_TYPE_DRAW, D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH) and special types (such as D3D12_INDIRECT_ARGUMENT_TYPE_INDEXED_DRAW index drawing, D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_RAYS ray tracing scheduling).

[0058] Record the binding slots, offsets, data lengths, and alignment requirements of parameters, as well as the format information for special commands, such as the length of the indexCountPerInstance parameter for index drawing and the offset of the rayGenerationShaderRecordIndex parameter for ray tracing scheduling.

[0059] The associated command index and judgment rules of the marked conditional execution parameter (D3D12_INDIRECT_ARGUMENT_TYPE_CONDITIONAL) are used. For example, if the flag is 0, the next 3 commands are skipped. For nested conditional execution, if the condition contains index drawing, the hierarchical relationship is marked separately.

[0060] S1.2, Construction of Hierarchical Semantic Mapping Table: Based on the parsing results, a three-layer semantic mapping table between D3D12 and Vulkan is generated. This table is divided into:

[0061] Base layer: Establish a one-to-one correspondence between D3D12 command types and Vulkan indirect commands. Ordinary types are mapped according to the original logic (e.g., D3D12 drawing commands correspond to VkDrawIndirectCommand), and special types are mapped (e.g., D3D12_INDIRECT_ARGUMENT_TYPE_INDEXED_DRAW corresponds to VkDrawIndexedIndirectCommand, and D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_RAYS corresponds to VkDispatchRaysIndirectCommandKHR).

[0062] Layout layer: Converts the parameter offsets of the D3D12 command signature into the memory layout of the Vulkan parameter buffer, and adapts the format of special commands (such as the startIndexLocation parameter of D3D12 index drawing is 4 bytes, and the firstIndex field of VkDrawIndexedIndirectCommand in Vulkan must be aligned to 8 bytes to match the structure layout).

[0063] Execution layer: Records the dependencies of D3D12 commands (e.g., push constants need to be executed before drawing commands) and the triggering logic of conditional execution, the execution dependencies of special commands (e.g., ray tracing scheduling needs to be executed after the acceleration structure is built), generates an execution dependency tree and marks the execution priority of special commands.

[0064] S1.3 Virtual Command Layout Template Generation: Based on the hierarchical semantic mapping table, a VkVirtualIndirectLayout structure (not a native Vulkan interface, but a custom virtual layout) is created in VKD3D. This structure contains:

[0065] An array of command type sequences, storing the order of command types in the D3D12 command signature, and identifying the type of special commands;

[0066] The parameter buffer offset, length, and valid flag offset for each command, and supplementary format labels for special commands, such as the index drawing label INDEXED and the ray tracing scheduling label RAYS;

[0067] The conditional execution judgment mask and the number of skipped commands, and the supplementary mask for nested conditional execution levels;

[0068] Vulkan indirect command calls function pointers, with special commands supplementing extended function pointers, such as vkCmdDrawIndexedIndirect for indexed drawing and vkCmdDispatchRaysIndirectKHR for ray tracing scheduling.

[0069] S1.4 Metadata Pre-compilation and Storage: The VkVirtualIndirectLayout, hierarchical semantic mapping table, and hardware adaptation information for special commands (such as the maximum number of instances of VkDrawIndexedIndirectCommand for GPUs) are compiled into binary metadata and stored in the command metadata buffer in the GPU's local memory (VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT). The metadata uses LZ4 compression format to reduce memory usage. At the same time, a hardware adaptation sub-table is generated according to the GPU model (such as the alignment requirements of VkDispatchRaysIndirectCommandKHR parameters for NVIDIA GPUs and the length limit of index drawing parameters for AMD GPUs), which is embedded in the header of the metadata buffer. A CPU-side index table of metadata is generated for quick querying of command types, layout information, and hardware adaptation parameters.

[0070] S1.5 Real-time update of signature changes: Monitor D3D12 applications for modifying command signatures (such as ID3D12Device::CreateCommandSignature). When the signature changes, if it involves a change in a special command type (such as adding a ray tracing schedule), the hardware adaptation sub-table is additionally regenerated to ensure that the metadata matches the GPU hardware characteristics. After updating the metadata buffer and index table, the metadata update command is submitted via vkQueueSubmit and synchronized to the GPU to ensure the real-time nature of semantic mapping.

[0071] S2. GPU command parameter generation based on a ring-shaped multi-buffered command generation pool, simulating the GPU command generation function of DGC. By designing a ring-shaped multi-buffered command generation pool (hardware adapted version) and a lightweight synchronization mechanism, the GPU can dynamically generate D3D12 command parameters (including special commands) while eliminating the synchronization delay between CS and the graphics pipeline.

[0072] S2.1 Initialization of a Circular Multi-Buffer Pool (Hardware Adaptation and Layered Design): Create a GPUCommandBufferPool module in VKD3D. Before initialization, query the GPU hardware characteristics (obtain the memory page size, maximum buffer size, and supported command types via vkGetPhysicalDeviceProperties2). Then, based on the hardware characteristics, initialize a circular pool containing 4 buffers (the number is configurable, default 4, minimum 2, maximum 8, dynamically adjusted according to GPU memory bandwidth). Each buffer adopts a layered design of main buffer and sub-buffers:

[0073] Main buffer: Allocated in GPU local memory (VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT), aligned to GPU memory page size (e.g., 4KB, 64KB), with a size equal to the product of the pre-calculated maximum command parameter capacity and 1.2 (with 20% redundancy reserved). It supports dual-purpose use for CS writing and graphics pipeline reading (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT| VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT), and selects the optimal memory heap based on the memory type supported by the GPU (e.g., NVIDIA GPUs preferentially select the VK_MEMORY_HEAP_DEVICE_LOCAL_BIT heap, and AMD GPUs preferentially select the VK_MEMORY_HEAP_MDEVICE_LOCAL_BIT heap).

[0074] Sub-buffers: The main buffer is divided into ordinary command sub-buffers (store drawing and scheduling command parameters) and special command sub-buffers (store index drawing and ray tracing scheduling command parameters) according to command type. The starting address and size of the sub-buffers are recorded in the buffer partition table, and the size of each sub-buffer is pre-allocated according to the product of the average parameter length of the corresponding command type and the maximum number of commands (e.g., index drawing sub-buffer size = sizeof(VkDrawIndexedIndirectCommand)*1024).

[0075] Secondary buffers: Each primary buffer is associated with two secondary buffers, namely a validity flag buffer (1 byte per command, storing the execution validity flag) and a length buffer (4 bytes per command, storing the parameter length of each command). The secondary buffers use the same memory allocation strategy as the primary buffers, and their starting addresses are aligned with the primary buffers to ensure cache locality when accessed by the GPU.

[0076] S2.2 Compilation of the Compute Shader Command Generator: In VKD3D, a dedicated CommandGeneratorCS Compute Shader is compiled. Before compilation, the generated hardware adaptation sub-table is read, and the CS code is optimized for different GPUs (e.g., NVIDIA GPUs use the GL_NV_gpu_shader5 extension, and AMD GPUs use the GL_AMD_gpu_shader_int16 extension). This CS includes:

[0077] Metadata reading unit (hardware-adapted version): Loads VkVirtualIndirectLayout and hardware-adapted sub-table from the command metadata buffer, parses command type, layout, execution rules and hardware limitations (such as maximum number of instances), and supplements format parsing for special commands (such as checking the range of indexCountPerInstance parameter for index drawing).

[0078] Parameter Calculation Unit (Special Command Support): Calls the GPU-side logic of the D3D12 application (such as the CS function for frustum culling and the HLSL code for particle count calculation), generates parameters for ordinary commands according to the original logic, and supplements parameter calculations for special commands (such as the indexCount for indexed rendering being calculated by multiplying the number of model indices and the number of instances, and the rayCount for ray tracing scheduling being calculated by multiplying the scene ray density and the viewport size), and writes it to the corresponding sub-buffer of the circular pool according to the Vulkan layout. At the same time, it checks whether the parameters meet the hardware limitations (such as the number of instances not exceeding the maximum number of instances on the GPU; if it exceeds, it will be automatically truncated and a warning will be marked).

[0079] Conditional execution processing unit (nested condition support): Based on the condition parameters of D3D12 (such as UAV data of the culling result), it sets the corresponding bits of the validity flag buffer, and performs hierarchical judgment on nested conditional execution (such as condition containing index drawing): First, it judges the outer condition. If it is invalid, it skips all inner commands directly; if it is valid, it continues to judge the inner condition. If the inner condition is invalid, it only skips the corresponding special command; the command skipped by the condition sets the validity flag to 0 and sets the corresponding command parameter in the parameter buffer to an invalid value (such as indexCount=0 for index drawing).

[0080] Length Calculation Unit (Dynamic Length Adaptation): Counts the total number of valid commands in the current frame, counts the number of ordinary commands and special commands separately according to command type, and writes them to the length buffer; for variable length commands (such as the dynamic change of rayCount in ray tracing scheduling), it additionally records the actual parameter length of each command (such as the total number of bytes of VkDispatchRaysIndirectCommandKHR) for subsequent dynamic partitioning.

[0081] S2.3 Frame Cyclic Scheduling of the Ring Pool (Dynamic Switching and Load Adaptation): The ring pool is scheduled using a three-state mode of production, consumption, and standby. Before scheduling, the GPU load of the previous frame (such as CS computation time and graphics pipeline execution time) is queried using vkGetQueryPoolResults, and then the scheduling strategy is dynamically adjusted based on the load.

[0082] In low-load scenarios (GPU load < 50%), a 1-producer-1-consumer mode is adopted. That is, CS selects an idle buffer (Buffer [N]) in the circular pool as the production buffer and writes parameters, validity flags and length data; the graphics pipeline reads the buffer (Buffer [N-1]) generated by CS in the previous frame as the consumption buffer and executes indirect commands; Buffer [N-2] and Buffer [N-3] are used as backup buffers and are only enabled when the production and consumption buffers are abnormal.

[0083] In medium-load scenarios (GPU load 50%-80%): a 2-producer, 1-consumer mode is adopted, that is, two CS threads are enabled to write parameters to Buffer [N] and Buffer [N+1] (modulo 4) respectively (split according to command type, ordinary commands are written to Buffer [N], and special commands are written to Buffer [N+1]); the graphics pipeline reads parameters from Buffer [N-1] and Buffer [N-2] simultaneously, and executes ordinary commands and special commands in parallel;

[0084] High-load scenarios (GPU load > 80%): A 2-producer, 2-consumer mode is adopted, that is, two CS threads are enabled to write parameters to Buffer [N] and Buffer [N+1] respectively, and two graphics pipeline queues are enabled to read parameters from Buffer [N-1] and Buffer [N-2] respectively. Ordinary commands and special commands are executed in parallel in different queues, and lightweight synchronization is set through vkCmdPipelineBarrier2 to avoid resource contention between queues;

[0085] Switching mechanism: After each frame ends, vkQueueWaitIdle is used to confirm that the current buffer read and write is complete. Then, the pointer of the circular pool is moved forward (the number of moves is equal to the number of production buffers). At the same time, the buffer partition table is updated to ensure that the production and consumption buffers of the next frame match the command type.

[0086] S2.4 Implementation of a Lightweight Synchronization Mechanism (Hardware Synchronization and Latency Optimization): Replacing the traditional heavy memory barrier, a two-layer synchronization mechanism of events and fences is designed based on the GPU hardware synchronization characteristics:

[0087] Event Synchronization (CS to Graphics Pipeline): After CS completes writing to Buffer [N], it calls vkSetEvent to trigger an event. The event's VkEventCreateInfo sets the initial state of VK_EVENT_CREATE_SIGNALED_BIT and specifies the signal phase of VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT. Before reading Buffer [N], the graphics pipeline calls vkWaitEvents to wait for the event to trigger. During the waiting phase, it only sets VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT (normal command) or VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR (special command) and does not block other rendering phases (such as vertex shading and fragment shading).

[0088] Fence synchronization (inter-frame synchronization): After all commands are submitted in each frame, a VkFence is created and associated with the command batch of the current frame. The vkWaitForFences is used to wait for the fence to be triggered (timeout 10ms) to ensure that the buffer of the previous frame is completely released before it is used for the production of the next frame, thus avoiding inter-frame resource contention. For high-load scenarios, a delayed fence mechanism is adopted, that is, the fence is not reset immediately after it is triggered, but is reset before the production buffer of the next frame begins to be written, thus reducing the overhead of fence creation and destruction.

[0089] Special command synchronization: For special commands such as ray tracing scheduling, VkSemaphore synchronization (VK_SEMAPHORE_TYPE_TIMELINE) is added, and the value is set to the current frame number. This ensures that ray tracing scheduling is executed only after the accelerated structure building command (vkCmdBuildAccelerationStructuresKHR) is completed, thus avoiding hardware access to illegal memory.

[0090] S2.5, Parameter buffer compression, on-demand allocation, and error recovery (defragmentation and fault tolerance):

[0091] Compression optimization: For the memory area corresponding to invalid commands in the parameter buffer, a differentiated compression algorithm is adopted according to the command type. Specifically, ordinary commands are compressed using flag bit compression (only one flag bit and the number of invalid commands are stored for consecutive invalid commands), while special commands are compressed using parameter mask compression (only valid parameter fields are stored, and invalid fields are marked with a mask). The compression ratio can reach 1:10 (e.g., 10 consecutive invalid index drawing commands are compressed from 40 bytes to 4 bytes). The compressed data is decompressed in real time during reading by the CS decompression unit, and the decompression time is controlled within 0.1μs per command.

[0092] On-demand allocation and dynamic expansion: During initialization, the main buffer size is pre-allocated based on the product of the average number of commands and the parameter length. During runtime, the buffer usage is monitored via vkGetBufferMemoryRequirements. If the usage is greater than 80% (for ordinary commands) or greater than 70% (for special commands with larger parameter lengths), dynamic expansion is triggered. This involves allocating a new main buffer (1.5 times the original size), copying the valid data from the original buffer to the new buffer (directly copied on the GPU via vkCmdCopyBuffer to avoid CPU intervention), and updating the buffer partition table. If the usage is less than 30% for 3 consecutive frames, dynamic shrinkage is triggered (0.8 times the original size) to release redundant memory.

[0093] Defragmentation and Error Recovery: Buffer defragmentation is performed every 100 frames—by traversing the main buffer using CS, valid command parameters (including ordinary and special commands) are arranged consecutively, memory areas occupied by invalid commands are released, and the sub-buffer addresses of the buffer partition table are updated after defragmentation; if the buffer is damaged due to a hardware error (such as GPU suspension), a backup buffer is immediately activated, and the status of the damaged buffer is checked using vkGetBufferMemoryRequirements. If it can be repaired, it is cleared and reused using vkCmdFillBuffer; if it cannot be repaired, it is released and reallocated to ensure the continuous availability of the circular pool.

[0094] S3. Hardware-level scheduling and execution of dynamic command sequences: Simulates the dynamic nature of command execution in DGC. By designing a hardware-level command scheduler (with special command support), it achieves efficient simulation of D3D12 variable-length command sequences and conditional execution (including special commands).

[0095] S3.1 Command Length Pre-calculation and Index Generation (Special Command Length Adaptation): A lightweight CS, CommandLengthPredictor, is added to VKD3D. This CS starts before CommandGeneratorCS is executed and incorporates GPU hardware features (such as maximum command length limits) during compilation to perform the following operations:

[0096] Read dynamic data from the D3D12 application (such as the number of objects in the current frame, the number of active instances of the particle system, and the scene complexity of ray tracing), and supplement the reading of related data for special commands (such as the number of indexes of the model drawn by index and the size of the accelerated structure for ray tracing).

[0097] The total number of possible commands in the current frame is pre-calculated (categorized by ordinary commands and special commands) and the length of each subcommand. For special commands, the parameter length is calculated (e.g., the length of VkDrawIndexedIndirectCommand is 24 bytes and the length of VkDispatchRaysIndirectCommandKHR is 64 bytes). A command length index buffer is generated, and the index entries contain the command type identifier, parameter length, and starting offset.

[0098] The address of the index buffer is passed to CommandGeneratorCS, along with GPU hardware limitation parameters (such as the maximum number of indexed drawing commands and the maximum number of rays scheduled for ray tracing), to guide the memory layout and quantity control of its parameter generation.

[0099] S3.2 Dynamic Partitioning of the Parameter Buffer (Special Command Partitioning Optimization): GPUCommandBufferPool dynamically partitions the current parameter buffer based on the command length index buffer data and the buffer partitioning table. The partitioning strategy is optimized according to the command type.

[0100] Normal command partitioning: The normal command sub-buffer is divided into multiple contiguous memory blocks according to the drawing and scheduling command types. The size of each block is the product of the parameter length and the number of commands for the corresponding command type. A 4-byte alignment gap is maintained between blocks.

[0101] Special command partitioning: For indexed drawing commands, the partition size of the special command sub-buffer is allocated according to sizeof(VkDrawIndexedIndirectCommand) and the number of commands, with the starting address aligned to 8 bytes (to match the structure layout); for ray tracing scheduling commands, the partition size is allocated according to the product of sizeof(VkDispatchRaysIndirectCommandKHR) and the number of commands, with the starting address aligned to 16 bytes (GPU's special alignment requirements for ray tracing commands);

[0102] Partition Mapping Table Update: Generate a partition mapping table that records the start offset, end offset, number of valid commands, and hardware adaptation parameters (such as the base address of indexBufferOffset for index drawing and accelerationStructureCount for ray tracing scheduling) for each command type. The table is stored in the index table on the CPU side, and the format of the partition mapping table is dynamically adjusted according to the command types supported by the GPU (if the GPU does not support ray tracing, the corresponding partition entry is removed).

[0103] S3.3, Multi-command type adaptation scheduling (special command execution support): Implement the HardwareCommandScheduler module in VKD3D. This module loads the hardware adaptation sub-table and dynamically calls Vulkan's indirect command functions (including extension functions) according to the command types supported by the GPU.

[0104] Normal command scheduling: Read the information of the drawing command area from the partition mapping table, call vkCmdDrawIndirect, specify the starting address of the drawing command area in the parameter buffer and the number of valid commands (read from the length buffer); read the information of the scheduling command area, call vkCmdDispatchIndirect, and perform indirect scheduling of the computing pipeline;

[0105] Special command scheduling: Reads information from the indexed drawing command area, calls vkCmdDrawIndexedIndirect, and specifies the address of the index buffer (mapped from the D3D12 index buffer), the starting address of the indexed drawing area of ​​the parameter buffer, and the number of valid commands; reads information from the ray tracing scheduling command area, first checks the construction status of the acceleration structure (via vkGetAccelerationStructureBuildStatusKHR), and if it is complete, calls vkCmdDispatchRaysIndirectKHR, specifying the address of the acceleration structure, the starting address of the ray tracing scheduling area of ​​the parameter buffer, and the number of valid commands;

[0106] Command dependency handling: Dependencies between commands are handled according to the execution dependency tree. For example, after the push constant command is executed (via vkCmdPushConstants), the drawing or index drawing command is executed; after the accelerated structure is built, the ray tracing scheduling command is executed; the dependency relationship is set up with lightweight synchronization through vkCmdPipelineBarrier2. The synchronization phase only includes the execution phase of the relevant commands (such as VK_PIPELINE_STAGE_2_CONSTANT_COPY_BIT for push constants and VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT for drawing commands).

[0107] Invalid command filtering: All calls are based on the results of the valid flag buffer. For ordinary commands, if the valid flag is 0, the reading of the corresponding memory block is skipped. For special commands, if the valid flag is 0, the corresponding Vulkan function is not called (e.g., if the valid flag of the index drawing command is 0, vkCmdDrawIndexedIndirect is not executed), thus avoiding the overhead of invalid API calls.

[0108] S3.4 Hardware-level filtering for conditional execution (adaptation to special command conditions): Combining Vulkan's VK_EXT_conditional_rendering extension (if supported by the GPU) or VK_KHR_conditional_rendering extension (compatible with older GPUs) to implement hardware-level command filtering and adapt to conditional execution of special commands:

[0109] If VK_EXT_conditional_rendering is supported: the starting address of the valid flag buffer is passed to vkCmdBeginConditionalRenderingEXT, and the flags of VkConditionalRenderingBeginInfoEXT are set to VK_CONDITIONAL_RENDERING_INVERT_RESULT_BIT_EXT (supporting result inversion); before executing each command, the graphics pipeline automatically checks the corresponding flag bit. The checking logic is the same for ordinary commands and special commands. If it is 0, the execution of the command is skipped directly without software intervention.

[0110] If only VK_KHR_conditional_rendering is supported: add condition check logic to special commands (such as ray tracing scheduling). That is, before calling vkCmdDispatchRaysIndirectKHR, associate the corresponding bit of the valid flag buffer with vkCmdBeginConditionalRenderingKHR. After execution, call vkCmdEndConditionalRenderingKHR to ensure that the condition execution of special commands is consistent with that of ordinary commands.

[0111] If conditional rendering extension is not supported: the software traverses the valid flag buffer to generate a list of valid commands. The list entries include the command type (normal or special), parameter start address, and parameter length. For special commands, the associated resource address (such as index buffer address, acceleration structure address) is additionally recorded. The scheduler only submits the commands in the list to the Vulkan queue, and the list is sorted according to the command execution priority (such as ray tracing scheduling, index rendering, normal rendering, and scheduling in descending order).

[0112] S3.5, Command Execution Priority Scheduling (Hardware Load Balancing): In VKD3D, execution priorities are set for different types of commands (ray tracing scheduling, indexed drawing, normal drawing, push constants, and scheduling commands decrease in that order), and scheduling is dynamically adjusted based on GPU hardware load (obtained via vkGetPhysicalDeviceQueueFamilyProperties2).

[0113] Queue load balancing: If the GPU supports multiple queues (such as independent graphics queues and compute queues, ray tracing queues), commands of different priorities are assigned to the corresponding queues. That is, ray tracing scheduling is assigned to the ray tracing queue, indexed drawing and normal drawing are assigned to the graphics queue, scheduling commands are assigned to the compute queue, and push constants are assigned to the graphics queue (in the same queue as drawing commands to reduce synchronization). If the GPU only supports a single queue, commands are submitted in priority order, with high-priority commands inserted at the head of the queue.

[0114] Execution phase optimization: By using the VkSubmitInfo2 parameter of vkQueueSubmit, the execution phase of pWaitDstStageMask is set for different commands. Specifically, ray tracing scheduling is set to VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR, index drawing is set to VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT, and scheduling commands are set to VK_PIPELINE_STAGE_2_DISPATCH_INDIRECT_BIT. This ensures that commands are executed in the optimal phase, reducing GPU idle time.

[0115] Intra-frame latency control: For high-priority commands (such as ray tracing scheduling), set an intra-frame latency limit (e.g., 0.1ms). If the execution time of a command exceeds the limit, command splitting is triggered, that is, splitting the current command into multiple sub-commands (e.g., splitting 1024 ray tracing schedules into 4 sub-commands of 256 each), and executing them frame by frame to avoid a single command blocking subsequent commands.

[0116] S4 optimizes Linux kernel-level command batching and submission by modifying the Linux kernel's DRM (DirectRendering Manager) subsystem to optimize the CPU and GPU communication process for command submission, with a focus on optimizing the kernel-mode Vulkan command batching queue to reduce system call overhead.

[0117] S4.1 Enhancement of DRM Batch Submission Interface (Special Command Support and Hardware Adaptation): Modify the Linux kernel's DRM Vulkan driver, enhancing the existing drm_vulkan_indirect_batch_submit system call interface to support special commands and hardware adaptation parameter passing. The new interface's structure is defined as follows:

[0118] struct drm_vulkan_batch_submit {

[0119] __u64 command_buffer_ptr; / / CPU-side pointer to the command batch (points to an array of parameter buffer addresses)

[0120] __u32 command_count; / / Number of commands in the batch

[0121] __u32 priority; / / Command execution priority (0-3, 3 is the highest)

[0122] __u64 fence_ptr; / / Pointer to the synchronized fence

[0123] __u32 command_type_mask; / / Command type mask (bit0=normal drawing, bit1=indexed drawing, bit2=ray tracing)

[0124] __u32 hardware_flags; / / Hardware compatibility flags (bit0 = requires 8-byte alignment, bit1 = supports ray tracing queues)

[0125] __u64 auxiliary_buffer_ptr; / / Pointer to the auxiliary buffer (valid flag buffer, length buffer)

[0126] };

[0127] This interface supports packaging multiple sets of Vulkan indirect commands (including ordinary and special commands) into a single command batch and submitting it to the GPU driver at once. It also passes command type and hardware adaptation information through command_type_mask and hardware_flags, allowing the driver to optimize command parsing and execution based on this information. Additionally, it supports passing the address of the auxiliary buffer, allowing the driver to directly access valid flags and length data, reducing data copying between user space and kernel space.

[0128] S4.2 Optimization of kernel-level command batch processing queue (dynamic scheduling and hardware affinity): A dedicated VulkanIndirectQueue queue is created in the DRM kernel module. The queue adopts a dual-queue and dynamic scheduling design, and also supports hardware affinity binding.

[0129] Queue structure design: The queue is divided into a high-priority queue and a normal-priority queue. The high-priority queue stores command batches with priority 3 (ray tracing scheduling) and 2 (index drawing), while the normal-priority queue stores command batches with priority 1 (normal drawing) and 0 (scheduling commands). Each queue adopts a hybrid data structure of linked lists and red-black trees. The linked lists are used to store batches in the order of submission, and the red-black trees are used to sort them by priority (high-priority batches are placed at the beginning of the tree) to ensure fast insertion and query.

[0130] Dynamic scheduling strategy: The kernel starts a queue scheduling thread (scheduling once every 1ms). Before scheduling, it first queries the GPU hardware load (obtaining the GPU memory access frequency through drm_bo_get_tiling and the frame period through drm_vblank_wait), and then dynamically adjusts the scheduling strategy based on the load.

[0131] Low load (GPU load less than 40%): Batch scheduling is adopted, that is, up to 8 batches are taken from the high priority queue and the normal priority queue at one time, and merged into a super batch and submitted to the GPU driver, reducing the number of command parsing times of the driver;

[0132] Medium load (GPU load not less than 40% and not more than 70%): Priority scheduling is adopted, that is, only a maximum of 4 batches are taken from the high priority queue for submission, and batches in the normal priority queue are submitted with a 1ms delay to ensure the execution response speed of high priority commands.

[0133] High load (GPU load greater than 70%): Time-sharing scheduling is adopted, that is, the GPU time slice is divided into multiple 1ms segments, and each segment submits only 1 high-priority batch or 2 normal-priority batches to avoid command backlog; at the same time, the execution time of each batch is monitored. If a batch takes more than 2ms, the batch is split (split into 2 batches according to the number of commands) and submitted in time slices.

[0134] Hardware affinity binding: The GPU's PCI device information is obtained through drm_get_pci_domain_bus_devfn, and then the queue scheduling thread is bound to the corresponding CPU core of the GPU through sched_setaffinity (e.g., if the GPU is connected to CPU cores 4 to 7, the scheduling thread is bound to core 4), reducing context switching between CPU cores; at the same time, the memory pages of the command batch are bound to the GPU's memory controller (through drm_mm_bind), improving the memory bandwidth when the GPU accesses the parameter buffer;

[0135] Queue overflow protection and timeout handling: A maximum length is set for each queue (64 batches for high-priority queues and 128 batches for normal-priority queues). If the queue length reaches the limit, overflow protection is triggered, which means that newly submitted batches are cached in the overflow buffer (kernel memory, size 16MB) and moved into the queue only when there is free space. At the same time, a timeout period is set for each batch (5ms for high-priority batches and 10ms for normal-priority batches). If a batch waits in the queue for more than the timeout period, its priority is increased (e.g., normal-priority batches are increased to high priority after timeout) to avoid commands being blocked for a long time.

[0136] S4.3 Kernel-level resolution of buffer dependencies (special command dependencies and hardware synchronization): The DRM kernel module adds a BufferDependencyAnalyzer unit to enhance the resolution capability of special command buffer dependencies, and at the same time, it works in conjunction with the hardware synchronization mechanism of the GPU driver. Specific implementation:

[0137] Dependency identification (special command support): Parses the command_type_mask and auxiliary_buffer_ptr passed by the drm_vulkan_batch_submit interface to identify buffer dependencies, namely, the reading and writing of parameter buffers and valid flag buffers for ordinary commands (CS is written to the graphics pipeline and read), and the supplementary dependencies of special commands on associated resource buffers (such as index drawing depending on the reading of index buffers, and ray tracing scheduling depending on the reading of acceleration structure buffers); obtains the dependency chain of each buffer through drm_bo_get_deps and generates a dependency graph;

[0138] Hardware synchronization primitive insertion: Based on the dependency graph and hardware_flags hardware adaptation information, the corresponding hardware synchronization primitives are inserted. That is, for the buffer dependency of ordinary commands, a GPU fence (drm_gpu_fence_create) is inserted; for the index buffer dependency of index drawing, a buffer synchronization signal (drm_syncobj_signal) is inserted to ensure that the index buffer has been written before reading; for the acceleration structure dependency of ray tracing scheduling, an acceleration structure ready signal (drm_accel_struct_ready) is inserted, which is triggered by the GPU driver after confirming that the acceleration structure has been built.

[0139] Dependency conflict resolution: If multiple command batches depend on the same buffer (e.g., two index drawing batches depend on the same index buffer), the conflict is resolved by dependency sorting, that is, sorting by batch submission time. After the batch that is executed first releases its buffer, the batch that is executed later is allowed to access it. If there is a circular dependency (e.g., batch A depends on the buffer of batch B, and batch B depends on the buffer of batch A), the dependency breaking mechanism is triggered, that is, one batch is paused, the batches without circular dependencies are executed first, and the paused batches are executed after the buffers are released.

[0140] Synchronization status feedback: The resolved dependencies and inserted synchronization primitive information are stored in the fence pointed to by fence_ptr of drm_vulkan_batch_submit. The synchronization status (such as whether the buffer is ready or whether the synchronization primitive has been triggered) is allowed to be queried by user-space VKD3D through the drm_fence_query interface, thus avoiding blind waiting by user space.

[0141] S4.4 Reduction of System Call Overhead and Hardware Optimization: VKD3D's HardwareCommandScheduler packages all indirect commands (including ordinary and special commands) for each frame into 1 to 2 batches (high-priority batches contain special commands and high-priority ordinary commands, and ordinary-priority batches contain low-priority ordinary commands), and submits them all at once through drm_vulkan_indirect_batch_submit. Combined with kernel optimization, this further reduces overhead.

[0142] System call optimization: Compared to traditional multiple vkQueueSubmit calls (more than 100 times per frame), batch submission reduces the number of system calls to less than 2 per frame (1 time for high priority and 1 time for normal priority), reducing the number of system calls by more than 98%; at the same time, through batch parameter passing of drm_vulkan_batch_submit (passing the buffer address of multiple commands at once), the parameter passing amount of a single system call is increased from 1KB to 16KB, reducing parameter copying overhead;

[0143] Kernel-mode command parsing optimization: The DRM kernel module adds a command pre-parsing cache, which caches the parsing results of the most recent 16 batches (command type, parameter length, dependency relationship). If the structure of subsequent batches is the same as that of the batches in the cache (such as the repeated command sequence in the same game scene), the parsing result is directly reused and re-parsing is skipped, reducing the parsing time from 10μs per batch to 0.5μs per batch.

[0144] Hardware command queue adaptation: The kernel module obtains the number of hardware command queues supported by the GPU through drm_get_device_capabilities (e.g., NVIDIA GPUs support 32 hardware queues, AMD GPUs support 16), and binds the kernel batch queue to the hardware command queue one by one (high-priority kernel queues are bound to high-priority hardware queues, and normal-priority kernel queues are bound to normal-priority hardware queues) to avoid mapping conflicts between software queues and hardware queues and improve command execution efficiency;

[0145] Memory access optimization: The kernel module maps the parameter buffer address of the command batch to the GPU virtual address (via drm_gem_vmap). The GPU can directly access the address mapped in kernel mode without the need for address translation between user mode and kernel mode, reducing memory access latency from 100ns to less than 20ns.

[0146] S5. Multi-level caching and pre-compilation optimization of command sequences: By designing a multi-level command cache pool (hardware-adapted version), the efficiency of command generation and execution in repetitive and high-load scenarios is improved. The specific sub-steps are as follows:

[0147] S5.1 Initialization of Multi-Level Cache Pool (Hardware Adaptation and Layered Expansion): Create a CommandSequenceCache module in VKD3D. Before initialization, query the GPU hardware characteristics (memory bandwidth, cache size, supported command types), and then initialize the three-level cache based on the hardware characteristics (expanding the original two-level cache to three levels).

[0148] L1 cache (GPU cache): Allocated in local memory accessible by the GPU cache (VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT), with a size of 50% of the GPU L1 cache size (e.g., if the GPU L1 cache is 16KB, then the L1 cache is 8KB). It stores frequently used short command sequence parameters (e.g., ordinary drawing commands for static scenes, with parameter length < 64 bytes). Cache entries contain command parameter data, cache keys, and hardware adaptation flags (e.g., whether indexed drawing is supported).

[0149] L2 cache (GPU local cache): Allocated in GPU local memory (VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT), with a size of 4MB (which can be dynamically adjusted according to the GPU memory size, up to a maximum of 8MB). It stores command sequence parameters used in the intermediate frequency (such as index drawing commands for semi-dynamic scenes and short ray tracing scheduling commands). Cache entries contain command parameter data, cache key, associated resource address (such as index buffer address), and length information.

[0150] L3 Cache (Host Memory Cache): Allocated in host-visible and cacheable memory (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT), with a size of 16MB (maximum 32MB). It stores infrequently used long command sequence parameters (such as ray tracing scheduling commands in complex scenes, or a large number of scheduling commands). Cache entries contain command parameter data, cache keys, compression flags (whether compressed storage is used), and pre-compiled CS code snippets.

[0151] Cache Management Unit: Each cache level is associated with a cache management unit, which is responsible for the insertion, querying, and eviction of cache entries. The management unit has built-in GPU hardware characteristic checking logic (e.g., L1 cache only stores command types supported by GPU cache, and L2 cache only stores command parameters that can be efficiently accessed by GPU local memory).

[0152] S5.2 Cache Key Generation Rules (Hardware Characteristics and Command Features Enhancement): A unique cache key is generated based on the following information (using the SHA-256 hash algorithm, with the hash input containing hardware characteristic information):

[0153] Basic information: ID of the D3D12 command signature (generated by D3D12SignatureParser), hash of static data of the current frame (such as model ID and material ID of static objects), and triggering state of conditional execution (such as bounding box parameters of the view frustum).

[0154] Hardware feature information: GPU model hash (e.g., the model ID hash of NVIDIA GTX 1660), supported command type mask (bit0 for normal drawing, bit1 for indexed drawing, bit2 for ray tracing), memory page size;

[0155] Command characteristic information: command type (normal or special), command parameter length, hash of associated resources (such as the content hash of the index buffer, the size hash of the acceleration structure);

[0156] After the cache keys are generated, they are categorized and stored in the cache key index table according to command type (normal commands, index drawing, and ray tracing scheduling correspond to different index tables) for easy and quick lookup.

[0157] S5.3 Cache Hit and Reuse (Hardware Adaptation and Dynamic Priority): At the start of each frame, CommandSequenceCache calculates the cache key for the current scene and queries the cache in the order of L1, L2, and then L3. The query process is dynamically adjusted based on GPU hardware load and cache hit rate.

[0158] L1 cache lookup and reuse: Query the ordinary command sub-table of the cache key index table. If the L1 cache is hit, the address of the command parameter in the cache is directly passed to the HardwareCommandScheduler, skipping the CS generation process; at the same time, the access time of the cache entry is updated. If the number of accesses exceeds 100, the entry is promoted to the permanent generation of the L1 cache (not participating in LRU eviction); if the L1 cache is not hit, the L2 cache is queried.

[0159] L2 cache lookup and reuse: Query the special command sub-table (index drawing, short ray tracing scheduling) of the cache key index table. If an L2 cache hit is found, first check if the associated resource address of the cache entry matches the current scene (e.g., whether the index buffer address is consistent). If a match is found, copy the command parameter data in the cache to the circular pool sub-buffer (copying on the GPU via vkCmdCopyBuffer, taking less than 0.1ms), and instruct CommandGeneratorCS to skip the parameter generation for that command. If no hit is found, query the L3 cache.

[0160] L3 cache lookup and reuse: Query the long command sub-table (long ray tracing schedule, large number of scheduling commands) of the cache key index table. If the L3 cache is hit, first check the compression flag of the cache entry. If it is compressed, decompress it in real time through the CS decompression unit (decompression time is less than 0.5ms), and then copy the decompressed parameter data to the circular pool. At the same time, check whether the GPU hardware characteristics support the command type (e.g., whether the ray tracing commands in the L3 cache support the current GPU). If not, skip reuse and execute CS generation.

[0161] Cache miss handling: If all three levels of cache miss, the complete CS generation process is executed. After generating command parameters, they are written to the corresponding cache according to command type and usage frequency. That is, short ordinary commands are written to L1 cache (if L1 cache is full, the earliest accessed non-permanent area entry is evicted according to LRU), index drawing and short ray tracing commands are written to L2 cache (if L2 cache is full, the entry with a usage frequency of less than 5 times is evicted), and long commands are written to L3 cache (if L3 cache is full, the entry with a compression ratio of less than 20% is evicted).

[0162] S5.4, Pre-compilation and hardware optimization of static command sequences (pre-generation and adaptation):

[0163] Pre-compilation trigger timing: Pre-compilation of static command sequences is triggered during the VKD3D initialization phase (when the game starts), the scene loading phase (such as entering a new level), and the background idle phase (when the GPU load is less than 20%).

[0164] Pre-compilation process:

[0165] Scan the static command signatures of the D3D12 application (such as D3D12_COMMAND_SIGNATURE created when the scene is loaded) to identify the static command type (normal drawing, indexed drawing); read static scene data (such as model data and material data of static objects) to generate parameters for static commands (such as vertexCount for normal drawing being the number of model vertices, and indexCount for indexed drawing being the number of model indices); optimize the parameter format according to GPU hardware characteristics (such as adjusting indexCount for indexed drawing to an integer multiple of the maximum number of instances supported by the GPU to reduce parameter adjustment overhead); write the pre-generated parameter data to the corresponding cache (short static commands are written to the L1 cache, and long static commands are written to the L2 cache), and generate a pre-compiled log to record the number of pre-compiled commands and their cache locations;

[0166] Hardware preloading: After pre-compilation, the command parameter data in the L1 cache is preloaded to the GPU L1 cache and the data in the L2 cache is preloaded to the GPU L2 cache through vkCmdPreloadBuffer (an extension supported by some GPUs), reducing the cache miss overhead during the first access.

[0167] Pre-compilation update: When the static command signature of the D3D12 application changes (such as recreating D3D12_COMMAND_SIGNATURE) or the GPU hardware characteristics change (such as a driver update causing a change in the supported command types), pre-compilation is triggered again to update the static command parameter data in the cache, ensuring that the pre-compilation result matches the current hardware and application state.

[0168] S5.5 Cache performance optimization (dynamic adjustment and hardware coordination):

[0169] Dynamic cache size adjustment: Every 100 frames, the hit rate of each cache level is calculated (L1 cache hit rate > 90%, L2 cache > 70%, L3 cache > 50%). If the L1 cache hit rate is less than 80% for 10 consecutive frames, the L1 cache size is increased (+1KB), while the L3 cache size is decreased (-2KB). If the L2 cache hit rate is less than 60% for 10 consecutive frames, the L2 cache size is increased (+512KB), while the L3 cache size is decreased (-512KB). Ensure that the total cache size does not exceed 5% of the GPU memory (to avoid excessive VRAM usage).

[0170] Optimization of cache entry compression and decompression: Long command parameters in the L3 cache adopt a differentiated compression algorithm, that is, ordinary commands use LZ4 compression (high compression ratio, fast decompression), index drawing commands use LZ77 compression (high parameter repetition rate, good compression effect), and ray tracing scheduling commands use Snappy compression (balancing compression ratio and speed); during decompression, decompression is carried out in parallel through the CS decompression unit (supporting 4-way parallel), and the decompression speed is increased to more than 3 times that of single-way;

[0171] Hardware cache coordination: By obtaining GPU cache characteristics (such as cache line size and associativity) through vkGetPhysicalDeviceCacheProperties2, the size of cache entries is adjusted to an integer multiple of the cache line size (e.g., if the cache line size is 64 bytes, then the cache entry size is the product of 64 bytes and N) to improve cache hit rate; at the same time, associated command parameters (such as normal drawing and index drawing commands for the same object) are stored in contiguous cache lines to ensure cache locality when accessing the GPU.

[0172] Cache preheating and pre-elimination: When the game starts, frequently used static command sequences (such as drawing commands in the main menu) are preloaded into L1 and L2 caches to achieve cache hit on the first render; before scene switching (such as switching from scene A to scene B), dedicated cache entries for scene A are evicted in advance (marked by scene ID) to free up cache space for command caching for scene B, reducing cache conflicts during scene switching.

[0173] S6. Post-verification and fault tolerance of command execution is the final step in interface conversion, ensuring the accuracy and stability of command execution (including special commands).

[0174] S6.1 Software Validation of Parameter Validity (Special Command Validation and Hardware Limitation Check): A new CommandValidator module is added to VKD3D. The module loads the hardware adaptation sub-table and traverses the parameter buffer (including ordinary and special command sub-buffers) before the command is submitted to the GPU.

[0175] Normal command verification: Check the vertexCount (greater than 0 and not greater than the maximum number of vertices on the GPU), instanceCount (greater than 0 and not greater than the maximum number of instances on the GPU), and firstVertex (not less than 0 and less than the total number of vertices) of VkDrawIndirectCommand. If the parameters are invalid, they will be automatically corrected (e.g., change vertexCount=0 to vertexCount=1, and change instanceCount to the maximum number of instances on the GPU if it exceeds the limit).

[0176] Special command verification: For indexed drawing commands, check the indexCount (greater than 0 and not greater than the total number of indices in the index buffer), firstIndex (not less than 0 and less than the total number of indices), and vertexOffset (within the range of [-2^31, 2^31-1]) of VkDrawIndexedIndirectCommand; for ray tracing scheduling commands, check the width / height / depth (greater than 0 and not greater than the maximum ray tracing dimension of the GPU) and rayGenerationShaderRecordIndex (not less than 0 and less than the total number of ray generation shader records) of VkDispatchRaysIndirectCommandKHR. In addition to automatic correction, an additional warning log (including command type, invalid parameter value, and corrected value) is recorded when parameters are invalid.

[0177] Hardware Limit Check: Check whether the command parameters comply with the GPU hardware limits based on the hardware adaptation sub-table (e.g., the maximum indexCount for index drawing of NVIDIA GPU is 1048576, and the maximum width for ray tracing of AMD GPU is 8192). If the limits are exceeded, parameter downgrade is triggered (e.g., when indexCount exceeds the limit, it is split into multiple sub-commands, and the indexCount of each sub-command is equal to the GPU maximum limit).

[0178] Verification log generation: The verification results (command type, parameter value, whether correction is required, hardware limitation matching status) are written to the verification log in JSON format. The log storage path is / var / log / VKD3D / command_validation.log. The log can be read by debugging tools such as RenderDoc to help locate the cause of parameter errors.

[0179] S6.2 Rollback Mechanism for Execution Failure (Special Command Rollback and Hardware Recovery): If a Vulkan indirect command fails to execute (e.g., GPU suspension due to parameter out-of-bounds errors, or execution errors due to unsupported special commands), CommandValidator triggers a tiered rollback process:

[0180] Level 1 Rollback (Software Correction): If the failed command is a normal command and the error is due to invalid parameters (e.g., vertexCount=0), the parameters are immediately corrected (changed to 1), the command parameters are regenerated and submitted to the GPU; if the failed command is a special command (e.g., index drawing) and the error is due to hardware incompatibility, it is automatically switched to a normal command (e.g., index drawing is changed to normal drawing, executed via vkCmdDrawIndirect, while ignoring index data).

[0181] Secondary rollback (backup command sequence): If the primary rollback fails (e.g., errors still occur after parameter correction), the command submission for the current frame is paused, and the system switches to a backup command sequence pre-generated by the CPU. The backup sequence contains the most basic commands (e.g., only draw the background, do not perform ray tracing) to ensure that the game does not crash. The parameters of the backup sequence are stored in the host memory and can be loaded quickly.

[0182] Level 3 rollback (hardware reset): If the level 2 rollback fails (e.g., the backup sequence cannot be executed, which may be due to a GPU hardware error), vkDeviceWaitIdle is used to wait for the GPU to become idle, and then vkResetDevice is called to reset the GPU device (only the graphics-related state is reset, without affecting the functions of other devices). After the reset is completed, the VKD3D command generation and scheduling module is reinitialized to resume command execution.

[0183] Failure recovery and logging: After a successful rollback, the next frame automatically resumes GPU generation mode (reading command parameters from L1 and L2 caches to avoid re-executing CS generation); at the same time, failure information (command type, failure reason, rollback level, GPU status) is written to the failure log ( / var / log / VKD3D / failure_recovery.log), which includes GPU error codes (obtained via vkGetDeviceQueue) to facilitate developers in analyzing problems.

[0184] S6.3 Real-time monitoring of performance data and hardware adaptation optimization: The PerformanceMonitor module is integrated into VKD3D. The module collects performance data in real time through interfaces such as vkGetQueryPoolResults and drm_read, and dynamically optimizes performance based on GPU hardware characteristics.

[0185] Data collection content:

[0186] Command generation performance: time taken for CS to generate ordinary and special commands, cache hit rate (L1, L2, L3), and CS thread load;

[0187] Command execution performance: execution time of ordinary commands and special commands, GPU hardware queue load, and command batch submission time;

[0188] Memory performance: read / write bandwidth of parameter buffer, memory fragmentation rate, cache line hit rate;

[0189] Hardware status: GPU temperature, core frequency, memory frequency, power status;

[0190] Data output and visualization: The collected performance data is stored in the / sys / class / drm / card0 / metrics file by frame, and the data format is CSV (for easy analysis). It also supports real-time viewing of data through the VKD3D-perf command line tool (such as VKD3D-perf --show fps to view the frame rate, --show cache to view the cache hit rate).

[0191] Dynamic optimization strategy: The optimization strategy is automatically adjusted based on performance data. Specifically, if the L1 cache hit rate is less than 80%, the L1 cache size is increased; if the CS generation time is greater than 1ms, the number of CS threads is increased (up to 8); if the GPU core frequency is less than 80% of the base frequency (possibly due to overheating), the command batch size is automatically reduced (to reduce GPU load); if the memory bandwidth utilization is greater than 90%, parameter buffer compression is enabled (to improve bandwidth utilization).

[0192] Hardware adaptation and adjustment: Based on the collected GPU hardware status (such as core frequency and memory frequency), dynamically adjust the size of the ring multi-buffer pool (increase the buffer at high frequency to improve throughput; decrease the buffer at low frequency to reduce memory usage) and the priority of command batches (increase the priority of drawing commands under high load and balance the priority under low load) to ensure that performance optimization matches the hardware status.

[0193] Experiments have verified that this embodiment achieves efficient simulation of VKD3D's indirect commands (including special commands) for D3D12 on GPUs without DGC features. Compared with existing technologies and original solutions, it has the following enhanced benefits:

[0194] Functional completeness and compatibility: It fully supports all types of D3D12 indirect commands (including special commands such as indexed drawing and ray tracing scheduling) without any missing functions; it is compatible with more than 95% of mainstream GPUs without DGC (NVIDIA GTX 16 series, AMD RX 5000 series, Intel Arc A3 series) without modifying the GPU driver, and supports the feature differences of different GPUs through the hardware adaptation sub-table.

[0195] Performance is close to native DGC (Data Augmentation), with CPU load reduced by over 60% (from 50%): avoiding CPU pre-generated commands, reducing system calls by 98% (from 90%), and CPU utilization from 70% to 28%; frame latency controlled within 0.15 frames (from 0.2 frames), hardware adaptation for circular multi-buffering and lightweight synchronization, reducing synchronization latency from 0.5ms to 0.2ms; memory bandwidth overhead reduced by over 45% (from 35%), with differential compression of parameter buffers, direct GPU copying, and hardware address mapping, reducing memory bandwidth utilization from 90% to 49%; static scene frame rate increased by over 35% (from 25%), with hardware coordination and pre-compilation of the L3 cache, increasing cache hit rate from 80%. The frame rate has been improved to 92%, with static scene frame rate increasing from 60fps to 81fps; special command performance has been optimized, with index drawing command execution time reduced by 30% (from 1.2ms to 0.84ms) and ray tracing scheduling command execution time reduced by 25% (from 2.0ms to 1.5ms).

[0196] Stability and fault tolerance have been improved, with command execution failure rate reduced to below 0.1%. Hardware limit checks and a three-level rollback mechanism for parameter verification prevent GPU hangs, reducing game crash rate from 5% to 0.05%. Memory fragmentation rate is controlled within 5%, with circular multi-buffer defragmentation and dynamic expansion reducing memory fragmentation rate from 15% to 4%, preventing VRAM leaks. High-load stability has been improved, with dynamic scheduling of the kernel batch queue and hardware affinity binding reducing frame rate fluctuations under high GPU load (>90%) from ±10fps to ±2fps.

[0197] Scalability and maintainability, support for rapid adaptation of new D3D12 command types, modular design of hierarchical semantic mapping table, adding new D3D12 command types (such as D3D12_INDIRECT_ARGUMENT_TYPE_MESH_SHADER_DISPATCH) only requires adding mapping rules, shortening the development cycle from 2 weeks to 1 day;

[0198] Dynamic adjustment of performance optimization strategies, real-time monitoring and automatic optimization of the PerformanceMonitor module, adapting to different game scenarios without manual intervention; debugging and logging support, detailed verification logs and fault logs, making it easier for developers to locate problems and improving debugging efficiency by 50%.

[0199] In summary, the above are merely preferred embodiments of the present invention and are not intended to limit the scope of protection of the present invention. Any modifications, equivalent substitutions, improvements, etc., made within the spirit and principles of the present invention should be included within the scope of protection of the present invention.

Claims

1. A Direct3D 12 indirect command implementation method based on a circular multi-buffered command generation pool, characterized in that, Specifically, the following steps are included: D3D applications create command signatures, and VKD3D parses parameters to build a hierarchical semantic mapping table, including the correspondence between D3D12 command types and Vulkan indirect commands, D3D12 parameter offsets and Vulkan parameter buffer memory layout, and execution dependency tree; A virtual command layout is created based on the hierarchical semantic mapping table, a GPU hardware adaptation sub-table is generated, and a ring-shaped multi-buffered command generation pool is constructed, which includes a buffer with a hierarchical structure of main buffer and sub-buffers. The starting address and size of the sub-buffers are added to the buffer partition table. The application enters the rendering loop to load scene data. The pre-computed shader obtains the basic data and binds rendering resources. VKD3D pre-computes the total number of commands and subcommand lengths of the current frame to obtain the command length index buffer. The scheduling mode of the circular multi-buffered command generation pool is determined by the GPU load during the rendering of the previous frame. The basic data is calculated to obtain D3D12 indirect command parameters. VKD3D maps the parameters to Vulkan parameters according to the virtual command layout and hierarchical semantic mapping table. The parameters are corrected according to the hardware adaptation sub-table and Vulkan memory alignment requirements to obtain Vulkan command parameters. According to the scheduling mode, the Vulkan command parameters, validity flags, and length data are written to the sub-buffer of the current parameter buffer of the circular multi-buffered command generation pool. When an application initiates an indirect drawing request, VKD3D performs hardware adaptation partitioning on the current parameter buffer based on the command length index buffer and the buffer partition table. It divides the sub-buffer corresponding to ordinary commands into contiguous memory blocks, allocates partitions for commands in the sub-buffer corresponding to special commands, and generates a partition mapping table. The Vulkan interface and parameter relationships of the current parameter buffer are determined based on the hierarchical semantic mapping table. Pipeline barriers are inserted to obtain the Vulkan command scheduling list and bind it to the current parameter buffer. When an application requests the GPU to perform rendering, VKD3D packages the Vulkan command schedule list into command batches according to priority and submits them to the kernel. The kernel then generates a command queue and submits it to the GPU hardware queue to complete the rendering.

2. The Direct3D 12 indirect command implementation method according to claim 1, characterized in that, The virtual command layout is used to store command type sequences, command parameter buffer information, conditional execution rules, and function call pointers for Vulkan indirect commands. The parameter buffer information includes offset, length, and valid flag offset.

3. The Direct3D 12 indirect command implementation method according to claim 1, characterized in that, VKD3D generates static data hashes based on static objects and static resources in the scene data, obtains associated resource hashes from associated resources, generates cache keys based on command signature ID, static data hashes, GPU hardware characteristics, command type and length, and associated resource hashes, queries multi-level command cache pools step by step, and if a cache hit is found, retrieves Vulkan command parameters based on the address of the command parameters in the cache.

4. The Direct3D 12 indirect command implementation method according to claim 1, characterized in that, The method for determining the scheduling mode of the circular multi-buffered command generation pool based on the GPU load during the rendering of the previous frame is as follows: When the load value is less than the minimum threshold, the compute shader thread selects an idle buffer in the circular multi-buffered command generation pool as the production buffer, writes parameters, validity flags and length data, the graphics pipeline reads the buffer of the previous frame as the consumption buffer, executes indirect commands, and the remaining buffers are reserved. When the load value is not less than the minimum threshold and less than the maximum threshold, the two compute shader threads write to two buffers respectively, and the graphics pipeline reads the two history buffers at the same time, executing different types of commands in parallel. When the load value is not less than the maximum threshold, two compute shader threads write to two buffers, two graphics pipeline queues read from two history buffers respectively, and different queues execute commands in parallel.

5. The Direct3D 12 indirect command implementation method according to claim 1, characterized in that, The method for allocating partitions for commands in the special command corresponding sub-buffer is as follows: in the special command corresponding sub-buffer, a partition with a size equal to the product of the command length and the number of commands is allocated for the command, and the address alignment bytes are determined according to the command type.

6. The Direct3D 12 indirect command implementation method according to claim 5, characterized in that, The method for determining the address alignment bytes based on the command type is as follows: for index drawing commands, the starting address is aligned to 8 bytes, and for ray tracing scheduling commands, the starting address is aligned to 16 bytes.

7. The Direct3D 12 indirect command implementation method according to claim 1, characterized in that, After inserting the pipeline barrier, the command calls corresponding to Vulkan command parameters with invalid flags are first filtered out based on the valid flag buffer corresponding to the Vulkan command parameters in the current parameter buffer, and then a Vulkan command scheduling list is generated.

8. The Direct3D 12 indirect command implementation method according to claim 1, characterized in that, The method by which VKD3D packages the Vulkan command schedule list into command batches according to priority and submits them to the kernel is as follows: VKD3D reads the priority identifier of each command in the Vulkan command schedule list, adds high-priority commands to high-priority batches, and adds low-priority commands to ordinary batches. For each command batch, it saves its corresponding priority, parameter buffer address, effective parameter offset in the Vulkan command schedule list, and corresponding Vulkan command type, and then passes the command batch, Vulkan command schedule list, and auxiliary buffer pointer to the kernel.

9. The Direct3D 12 indirect command implementation method according to claim 8, characterized in that, The kernel generates the command queue as follows: the kernel stores high-priority batches into a high-priority queue and ordinary batches into an ordinary queue. Then, it determines the dependencies between commands based on the Vulkan command scheduling list associated with the parameter buffer, inserts the corresponding GPU hardware synchronization primitives in conjunction with the hardware adaptation sub-table, obtains a command queue that the GPU can recognize, and maps the physical address of the parameter buffer to a virtual address that the GPU can directly access.

10. The Direct3D 12 indirect command implementation method according to claim 1, characterized in that, The circular multi-buffered command generation pool is dynamically managed, specifically by: real-time monitoring of buffer usage and triggering dynamic expansion or contraction; periodic buffer defragmentation to arrange valid command parameters sequentially, release invalid memory, and control the memory fragmentation rate within a set range.

Citation Information

Patent Citations

  • Triple buffered constant buffers for efficient processing of graphics data at computing devices

    CN108352052A

  • Method for automatically drawing OpenGL program by using Vulkan

    CN121169663A

  • Direct3D depth cutting behavior compatible method based on atomization shader

    CN121527288A

  • Direct3D rendering model compatible method based on dynamic template pool

    CN121614179A

  • Thread modification to reduce command conversion latency

    US20210382765A1

Cited By

  • Task processing method, electronic device, storage medium and program product

    CN122220075A