A Direct3D Depth Clipping Behavior Compatibility Method Based on Atomized Shaders
By constructing a scene combination metadata table and an atomic component library for multi-dimensional depth processing scenarios, and adaptively selecting the depth transformation method, the compatibility issue of Direct3D on the Vulkan platform where the GPU does not support the VK_EXT_depth_clip_enable extension is resolved, achieving efficient and accurate depth clipping behavior compatibility.
Patent Information
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- Filing Date
- 2026-01-15
- Publication Date
- 2026-04-03
AI Technical Summary
When the GPU does not support the VK_EXT_depth_clip_enable extension, existing technical solutions suffer from performance degradation in depth clipping, reduced frame rate, visual artifacts, and compatibility issues, making it impossible to effectively achieve seamless compatibility of Direct3D applications on the Vulkan platform.
By establishing a scene combination metadata table for multi-dimensional depth processing scenarios, constructing a shader template library of atomic components and component variants, adaptively selecting depth transformation methods, generating Vulkan depth transformation parameters, and mapping them to hardware-independent DRM depth control parameters, the final result of depth rendering conforming to the native logic of Direct3D is generated.
It enables efficient compatibility of Direct3D applications on GPUs that do not support VK_EXT_depth_clip_enable, reduces shader compilation time and CPU-to-GPU state synchronization latency, improves rendering performance and accuracy, and solves the visual artifact problem.
Smart Images

Figure CN121527288B_ABST
Abstract
Description
Technical Field
[0001] The present invention belongs to the technical field of computer software development, and particularly relates to a method for compatible Direct3D depth clipping behavior based on atomized shaders. Background Art
[0002] Depth Clipping in Direct3D (D3D), which is the core part of frustum clipping in the rendering pipeline, occurs after the output of vertex shaders and geometry shaders and before rasterization. It is automatically executed by hardware or drivers. Its core is to determine whether a primitive exceeds the near or far clipping plane of the frustum based on the depth value of the vertex, and then decide whether to cull or clip the primitive. The shader indirectly determines the result of depth clipping by outputting the depth-related coordinates of the vertex.
[0003] As an open-source translation compatibility layer from D3D to Vulkan, the core workflow of DXVK is to convert API calls, rendering state configurations, and HLSL shader codes of D3D applications into corresponding API instructions, pipeline states, and SPIR-V shader codes of Vulkan, so as to achieve seamless operation of Windows D3D applications on Linux systems. There are irreconcilable native differences in the core mechanisms of depth processing between D3D and Vulkan, which is the fundamental reason for DXVK's strong dependence on the VK_EXT_depth_clip_enable extension.
[0004] In terms of depth processing logic, the core behaviors of D3D versions 9 to 11 are defined as the default forced enablement of depth clamping and the independent switch control of frustum clipping. Specifically, regardless of whether it is explicitly configured in a D3D application, the fragment depth value will be automatically restricted by the hardware within the depth range corresponding to the [near, far] plane to avoid rendering anomalies caused by out-of-range depth values. At the same time, D3D provides the D3DRS_CLIPPING rendering state switch, allowing the application to dynamically enable or disable the frustum clipping function. When enabled, vertices outside the [near, far] frustum will be culled and clipped, and when disabled, these vertices will still be rendered, but only the depth value will be clamped to the valid range. In addition, D3D uses a normalized device coordinate (NDC) depth space in the range of [-1, 1], and supports various depth buffer modes such as forward and reverse (far < near). Some D3D9 applications also support directly setting the depth range through D3DRS_ZNEAR or D3DRS_ZFAR, further increasing the state diversity.
[0005] Vulkan's native design is completely different. It does not support default enabling of depth clamping; it requires specific extensions or manual configuration. The view frustum clipping function cannot be independently switched on or off; the clipping logic must be implemented manually in the vertex shader by calculating the `gl_ClipDistance` array, and the clipping state is forcibly bound to the depth clamping state. The NDC depth space range is [0,1], which is fundamentally different from the depth range of D3D. The core value of the `VK_EXT_depth_clip_enable` extension lies in providing hardware-level support for independent control of depth clamping and clipping in Vulkan, enabling DXVK to directly simulate D3D's depth behavior through Vulkan API calls without complex software adaptation.
[0006] However, existing solutions suffer from several fatal flaws when the GPU does not support the VK_EXT_depth_clip_enable extension: First, injecting depth clamping code globally into the fragment shader to implement the clamping function increases shader compilation time by 3 to 5 times and reduces fragment processing performance by 20% to 40%. Second, dynamically switching between rendering or shader variants to control the clipping switch causes high-frequency CPU-to-GPU state synchronization latency, with frame rates dropping to over 50% in scenarios with frequent clipping state switching. Third, the depth range conversion uses a simple linear mapping, resulting in severe accuracy loss and frequent visual artifacts in large depth range (far or near not less than 1000). Fourth, the lack of adaptability to complex scenarios such as custom depth shaders, D3D9 software vertex processing, multiple viewports or cameras, and depth state conflicts leads to compatibility issues such as rendering misalignment and object disappearance in many D3D applications. These problems severely limit the usability of DXVK on older GPUs or hardware without this extension support. Summary of the Invention
[0007] In view of this, the present invention provides a Direct3D depth clipping behavior compatibility method based on atomic shaders, which enables D3D applications to run compatibly on operating system platforms that support Vulkan, even when the GPU does not support the VK_EXT_depth_clip_enable extension.
[0008] This invention provides a Direct3D depth clipping behavior compatibility method based on atomic shaders, which specifically includes the following steps:
[0009] Multi-dimensional deep processing of scenes forms scene combinations, which consist of scene combination identifiers and combination metadata forming a metadata table. The combination metadata includes the values of each dimension, transformation strategies, and shader component combinations. During the DXVK compilation stage, a mapping is established between each scene combination and atomic components and component variants. The component variants are sequentially concatenated to obtain intermediate bytecode, and parameter placeholders and shader logic interfaces are added to form shader templates. The mapping relationship from scene combination identifiers to template identifiers is recorded as the first mapping. The DXVK executable file is compiled and embedded in the compiled metadata table.
[0010] When DXVK starts, it loads the shader template, obtains the D3D application depth processing API call parameters, classifies the parameters and assigns priorities, analyzes the parameters to obtain scene combination identifiers, and forms an atomic parameter set consisting of parameters, scene combination identifiers, priority masks, version numbers and check codes. If the same scene combination identifier exists in the metadata table, the corresponding combination metadata is obtained; otherwise, the combination metadata of the scene combination identifier with the smallest difference is obtained, and the metadata table is updated.
[0011] For the acquired combined metadata, Vulkan depth values are calculated based on the depth range type. The D3D depth comparison function is converted into a Vulkan depth comparison operation, forming Vulkan depth transformation parameters. The Vulkan depth transformation parameters are mapped to DRM depth control parameters. The DRM subsystem packages the DRM depth control parameters, viewport parameters, depth buffer parameters, and pipeline state parameters into a batch synchronization package, and then converts them into hardware instructions adapted to the GPU. DXVK loads the shader template as the target shader based on the first mapping, binds the Vulkan depth transformation parameters to obtain the Vulkan shader module, generates a Vulkan command stream with embedded hardware instructions, and submits it to the GPU to complete the rendering of the D3D application.
[0012] Furthermore, the calculation of the Vulkan depth value based on the depth range type specifically involves: using a linear transformation to calculate the Vulkan depth value when the depth range type is a normal range; using a logarithmic transformation to calculate the Vulkan depth value when the depth range is a large range; and using a two-stage transformation consisting of linear and logarithmic transformations to calculate the Vulkan depth value when the depth range is an extremely large range.
[0013] Furthermore, the depth buffer width is obtained. If it is a 16-bit depth buffer, the precision compensation factor is calculated, and the product of the Vulkan depth value and the precision compensation factor is used as the new Vulkan depth value. Otherwise, the Vulkan depth value remains unchanged.
[0014] Furthermore, the formula for the linear transformation is: vulkan_z = d3d_z * conv_a + conv_b, where vulkan_z is the Vulkan depth value, d3d_z is the D3D depth value, and conv_a and conv_b are transformation coefficients;
[0015] The formula for the logarithmic transformation is: vulkan_z = log (d3d_z * conv_a + 1.0) * (conv_b / log ((d3d_far - d3d_near) * conv_a + 1.0)), where vulkan_z is the Vulkan depth value, d3d_z is the D3D depth value, d3d_far is the depth value of the far clipping plane of the D3D frustum, and d3d_near is the depth value of the near clipping plane of the D3D frustum.
[0016] Furthermore, the Vulkan depth comparison operation is flipped when the depth range type is reverse depth.
[0017] Furthermore, the Vulkan depth conversion parameters consist of conversion coefficients, clamping thresholds, depth range type, precision compensation factor, and Vulkan depth comparison operation.
[0018] Further, the clamping threshold is calculated using the following formulas: vulkan_near_clamp = (d3d_near + 1.0f) * conv_a, vulkan_far_clamp = (d3d_far + 1.0f) * conv_a, where vulkan_near_clamp is the clamping threshold of the near clipping plane of the frustum, vulkan_far_clamp is the clamping threshold of the far clipping plane of the frustum, d3d_far is the depth value of the far clipping plane of the D3D frustum, d3d_near is the depth value of the near clipping plane of the D3D frustum, and conv_a is the conversion coefficient.
[0019] Furthermore, the method for generating and submitting the Vulkan command stream containing embedded hardware instructions to the GPU for rendering is as follows: DXVK concatenates the Vulkan shader module with the existing coordinate transformation, lighting calculation, texture sampling, and color blending logic to obtain a Vulkan shader module including a vertex shader module and a fragment shader module; then, the Vulkan shader module is bound to the Vulkan pipeline to generate a Vulkan command stream for opening the rendering channel, primitive drawing, and closing the rendering channel; the hardware instructions generated by the DRM subsystem are embedded into the Vulkan command stream; and the Vulkan command stream is submitted to the GPU; the GPU executes the shader logic according to the pipeline order, and the atomic components complete the depth processing according to the bound Vulkan depth transformation parameters to obtain a depth rendering result that conforms to the native logic of D3D.
[0020] Furthermore, the multi-dimensional depth processing scenario includes D3D version, depth range type, near-plane characteristics, clipping state, depth buffer bit width, vertex processing mode, and the dimension of the custom depth marker.
[0021] Furthermore, the atomized components include a vertex clipping component, a depth transformation component, a depth clamping component, a reverse depth adaptation component, a custom depth compatibility component, a near-plane precision compensation component, and a vertex processing mode adaptation component; the component variants are adapted versions of the atomized components for specific scenario combinations. Beneficial effects
[0022] This invention establishes a scene composition metadata table containing multi-dimensional depth processing scenes during the DXVK compilation stage, constructs a shader template library containing atomic components and variants, and embeds the pre-compiled scene composition metadata table to generate the DXVK executable file. After DXVK starts, it loads relevant data, intercepts depth processing API calls from D3D applications, extracts parameters to generate an atomic parameter set containing basic parameters, scene composition identifiers, etc., quantifies and determines the atomic parameter set to obtain a scene index, and obtains recommended strategies and shader component combinations by matching or adding scene composition metadata in the scene composition metadata table based on the scene index. It adaptively selects the transformation method based on the scene metadata to calculate the Vulkan depth value, adapts the depth buffer bit width and depth comparison operation to generate Vulkan depth transformation parameters. DXVK maps these parameters to hardware-independent DRM depth control parameters and passes them to the kernel. The DRM subsystem packages the parameters and converts them into GPU-adapted hardware instructions. DXVK loads the corresponding shader template, binds the parameters, splices the original logic to generate a Vulkan shader module, binds the pipeline, generates a Vulkan command stream containing hardware instructions, submits it to the GPU, and finally executes it to obtain a depth rendering result that conforms to the native logic of D3D. Attached Figure Description
[0023] Figure 1 This is a flowchart illustrating a Direct3D depth clipping behavior compatible method based on atomic shaders provided by the present invention. Detailed Implementation
[0024] The present invention will be described in detail below with reference to the accompanying drawings and embodiments.
[0025] This invention provides a Direct3D depth clipping behavior compatibility method based on atomic shaders. The core idea is as follows: During the DXVK compilation phase, a scene composition metadata table containing multi-dimensional depth processing scenes is established; a shader template library containing atomic components and variants is constructed; and a pre-compiled scene composition metadata table is embedded to generate a DXVK executable file. After DXVK starts, relevant data is loaded, depth processing API calls from D3D applications are intercepted, parameters are extracted to generate an atomic parameter set containing basic parameters, scene composition identifiers, etc.; the atomic parameter set is quantized to obtain a scene index; and scene composition elements are matched or added to the scene composition metadata table based on the scene index. The data acquisition recommendation strategy is combined with shader components; the transformation method is adaptively selected based on scene metadata to calculate the Vulkan depth value, and the depth buffer bit width and depth comparison operation are adapted to generate Vulkan depth transformation parameters; DXVK maps this parameter to hardware-independent DRM depth control parameters and passes them to the kernel; the DRM subsystem packages the parameters and converts them into GPU-adapted hardware instructions; DXVK loads the corresponding shader template and binds the parameters, splices the original logic to generate Vulkan shader modules, and after binding the pipeline, generates a Vulkan command stream containing hardware instructions and submits it to the GPU; finally, the GPU executes it to obtain a depth rendering result that conforms to the native logic of D3D.
[0026] This invention provides a Direct3D depth clipping behavior compatible method based on atomic shaders, the process of which is as follows: Figure 1 As shown, the specific steps include:
[0027] Step 1: Create a depth processing scene with multiple dimensions, including D3D version, depth range type, near plane characteristics, clipping state, depth buffer bit width, vertex processing mode, and custom depth markers. Various scene combinations are formed by different values of different depth processing scenes. Assign a unique scene combination identifier to each scene combination. Create a scene combination metadata table to store the values of each dimension of depth processing scenes in the scene combination, recommended conversion strategies, and recommended shader component combinations. Precompile the scene combination metadata table into a binary metadata table.
[0028] During the DXVK compilation phase of the translation layer, atomic components are constructed, and multiple component variants are provided for each atomic component. A mapping relationship between each scene composition and the atomic components and component variants is established. The compiler concatenates the component variants in this mapping relationship according to the execution order of the vertex shader and fragment shader processing flow to obtain intermediate bytecode. Parameter placeholders are inserted into it, and the original DXVK shader logic interface is added. This intermediate bytecode is used as a shader template, and a unique template identifier is generated for each shader template. The mapping relationship between the scene composition identifier and the template identifier is established and recorded as the first mapping, forming the shader template library. The compilation is completed to generate the DXVK executable file, and the binary metadata table is embedded in it.
[0029] In the multi-dimensional depth processing scenario, the D3D version values include D3D9, D3D10, and D3D11; the depth range type values include normal range, large depth range, ultra-large depth range, reverse depth, and extreme scene, determined by the ratio of the depth value of the near clipping plane of the view frustum to the depth value of the far clipping plane of the view frustum; the near plane property values include normal near plane, extremely near plane, and zero near plane, determined by the depth value of the near clipping plane of the view frustum; the clipping state values include clipping enabled and clipping disabled, determined by the clipping enabled flag; the depth buffer property values include 16-bit forward, 24-bit forward, 32-bit forward, and reverse depth, determined by the depth buffer bit width and the reverse depth mode flag; the vertex processing mode values include hardware vertex processing and software vertex processing, determined by the vertex processing mode flag; and the custom depth flag values include non-custom depth and custom depth, determined by the shader analysis results.
[0030] The rule for generating the scene combination identifier is as follows: A fixed number of bits are allocated to each dimension of the depth processing scene. A shift operation is used to move the values of each dimension's depth processing scene to its designated bit position, thus obtaining the unique identifier for that scene combination. The total number of scene combinations is the Cartesian product of the number of values for each dimension's depth processing scene.
[0031] Based on depth processing capabilities, atomic components are categorized into vertex clipping components, depth transformation components, depth clamping components, reverse depth adaptation components, custom depth-compatible components, near-plane precision compensation components, and vertex processing mode adaptation components. Standardized input / output interfaces are defined for each atomic component to ensure flexible integration between components. Component variants correspond to specific scenarios and are adapted versions of atomic components for specific scenario combinations.
[0032] The vertex clipping component implements the conditional branching logic for view frustum clipping. Inputs include a clipping enable flag, D3D near or far planes, and vertex coordinates. Output is an array of clipping distances. Variants include a basic clipping variant and a software vertex processing clipping variant. The depth conversion component implements the D3D to Vulkan depth value conversion. Inputs include the D3D depth value, conversion coefficients, precision compensation factor, and conversion strategy. Output is a Vulkan depth value. Variants include linear conversion variants, logarithmic conversion variants, two-stage conversion variants, and inverse depth conversion variants. The depth clamping component implements the depth value clamping logic. Inputs include the converted depth value, clamping threshold, and hardware saturation write support flag. Output is the clamped depth value. Variants include soft clamping variants and hardware saturation variants. The inverse depth adaptation component... The matching component is used to adapt the depth comparison logic for reverse depth scenes. The input is the clamped depth value and the depth comparison operation, and the output is the adapted depth value and the adapted comparison operation. The custom depth compatibility component is used to adapt to custom depth shaders. The input is a custom depth marker, the converted depth value, and the custom depth value. The output is the final depth value. Variants include the skip built-in logic variant and the hybrid variant. The near-plane precision compensation component is used to optimize the depth precision for very near-plane scenes. The input is the converted depth value and the zero near-plane marker. The output is the compensated depth value. The vertex processing mode adaptation component is used to adapt to hardware and software vertex processing modes. The input is the software vertex processing marker and the clipping distance array. The output is the adapted clipping distance array. Variants include hardware processing variants and software processing variants.
[0033] Furthermore, the template identifier also includes the template version number.
[0034] Step 2: When DXVK starts, it loads the binary metadata table and shader template library into memory, designates the D3D application as the target application, intercepts API calls related to depth processing in the target application and designates them as the first API call, obtains the parameters passed by the first API call, and classifies the parameters into parameter types such as clipping control, depth range, depth buffer attribute, depth writing and testing, and vertex processing mode according to their functions, and assigns priorities to the parameter types; using the parameters as basic parameters, it performs feature recognition on the basic parameters to obtain their corresponding scene combination identifiers, and the atomic parameter set of the target application is composed of the basic parameters, scene combination identifiers, priority masks, version numbers, and check codes.
[0035] The version number is used to identify the update and iteration status of the atomic parameter set, and its initial value can be set to 0. The checksum is a unique value generated by concatenating the binary data of the basic parameters, scene marker, priority mask, and version number in a fixed order using a standard CRC-32 or CRC-64 hash algorithm and then hashing it.
[0036] For example, the priority of the clipping control parameters is set to 3, the priority of the depth range parameters is set to 2, the priority of the depth buffer attribute parameters is set to 4, the priority of the depth write and test parameters is set to 1, and the priority of the vertex processing mode parameters is set to 5.
[0037] Furthermore, this invention performs conflict detection on depth processing-related parameters. When the same type of parameter is modified multiple times within the same frame, it is determined that a parameter conflict has occurred. At this time, according to the priority of the parameter type, the parameter with higher priority overrides the parameter with lower priority, and a conflict log is recorded, including the conflict parameter type, conflict parameter value, and resolution result, which facilitates subsequent debugging and compatibility optimization.
[0038] Step 3: For the obtained atomic parameter set, quantize and determine the original values of each dimension of the deep processing scene according to the established multi-dimensional deep processing scene, and then obtain the corresponding scene index through shift operation; if there is a scene combination identifier in the scene combination metadata table that is the same as the scene index, then obtain the recommended transformation strategy and shader component combination in the corresponding scene combination metadata; otherwise, obtain the recommended transformation strategy and shader component combination in the scene combination metadata corresponding to the scene combination identifier with the smallest difference from the scene index, and at the same time, add scene combination metadata in the scene combination metadata table as the scene combination identifier, including the original values of each dimension, the recommended transformation strategy and shader component combination.
[0039] Step 4: For the acquired scene combination metadata, when its depth range type is a normal range, a linear transformation is used to calculate the Vulkan depth value; when it is a large depth range, a logarithmic transformation is used to calculate the Vulkan depth value; when it is an extremely large depth range, a two-segment transformation consisting of linear and logarithmic transformations is used to calculate the Vulkan depth value; obtain the depth buffer bit width; if it is a 16-bit depth buffer, calculate the precision compensation factor, and use the product of the Vulkan depth value and the precision compensation factor as the new Vulkan depth value; otherwise, keep the Vulkan depth value unchanged; convert the D3D depth comparison function into the corresponding Vulkan depth comparison operation, and invert the Vulkan depth comparison operation when the depth range type is reverse depth;
[0040] The Vulkan depth conversion parameters of the target application consist of conversion coefficients, clamping thresholds, depth range types, precision compensation factors, and Vulkan depth comparison operations. A three-level mapping relationship is established between the atomic parameter set, scene combination metadata, and Vulkan depth conversion parameters to form the mapping relationship of the target application, which is denoted as the second mapping.
[0041] The formula for linear transformation is: vulkan_z = d3d_z * conv_a + conv_b, where vulkan_z is the Vulkan depth value, d3d_z is the D3D depth value, and conv_a and conv_b are transformation coefficients, which are generally set to 0.5.
[0042] The formula for logarithmic transformation is: vulkan_z = log (d3d_z * conv_a + 1.0) * (conv_b / log((d3d_far - d3d_near) * conv_a + 1.0)), where d3d_far is the depth value of the far clipping plane of the D3D view frustum, and d3d_near is the depth value of the near clipping plane of the D3D view frustum.
[0043] The clamping threshold is calculated using the following formulas: vulkan_near_clamp = (d3d_near + 1.0f) * conv_a, vulkan_far_clamp = (d3d_far + 1.0f) * conv_a, where vulkan_near_clamp is the clamping threshold at the near clipping plane of the frustum, and vulkan_far_clamp is the clamping threshold at the far clipping plane of the frustum.
[0044] In addition, parameters need to be adjusted for abnormal scenarios, including: setting vulkan_near_clamp to 0 for zero near-plane scenarios to avoid precision loss due to excessively small clamping thresholds; setting conv_a to -0.5 for inverse depth scenarios to ensure monotonicity of depth values; and pre-calculating the base parameter log_base required for logarithmic transformation (2.0 + (d3d_far / d3d_near) / 10000.0) for large depth range scenarios to prepare for subsequent logarithmic transformation.
[0045] Furthermore, for scenes with extremely large depth ranges, a two-stage conversion formula is adopted: when d3d_z is not greater than 0, a linear conversion is used, and when d3d_z is greater than 0, a logarithmic conversion is used to balance the accuracy of the near plane and the far plane.
[0046] Furthermore, for near-plane scenes, near-plane precision compensation is enabled by setting conv_a to 0.6 and conv_b to 0.4 to expand the distribution range of near-plane depth values.
[0047] Step 5: Based on the second mapping of the target application, DXVK maps the Vulkan depth transformation parameters to kernel-supported, hardware-independent DRM depth control parameters, and then copies the DRM depth control parameters to the kernel-mode buffer.
[0048] The DRM subsystem reads DRM depth control parameters from the kernel-mode buffer, packages the DRM depth control parameters, viewport parameters, depth buffer parameters, and pipeline state parameters into a batch synchronization package, and then converts the hardware-independent parameters in the batch synchronization package into hardware instructions adapted to the current GPU based on the GPU architecture information, and passes the hardware instructions to the user-mode DXVK.
[0049] DXVK obtains the corresponding template identifier based on the scene combination metadata and first mapping of the target application, loads the shader template as the target shader, binds the Vulkan depth transformation parameters to the target shader, and splices together the original coordinate transformation, lighting calculation, texture sampling and color blending logic of DXVK to obtain the Vulkan shader module, which includes the vertex shader module and the fragment shader module.
[0050] DXVK binds the Vulkan shader module to the Vulkan pipeline, generates a Vulkan command stream that opens the rendering pass, draws primitives, and closes the rendering pass, embeds the hardware instructions generated by the DRM subsystem into the Vulkan command stream, and submits the Vulkan command stream to the GPU.
[0051] The GPU executes the shader logic in pipeline order, and the atomic components complete the depth processing according to the bound Vulkan depth transformation parameters to obtain a depth rendering result that conforms to the native logic of D3D.
[0052] To reduce CPU command submission overhead, this invention optimizes the Vulkan command flow by merging adjacent commands of the same type, removing redundant depth state setting commands, and using indirect drawing commands to execute drawing operations where the number of Vulkan depth conversion parameter changes per second exceeds a threshold.
[0053] To further reduce the system overhead of binding Vulkan depth transformation parameters to the target shader, for scene-combined metadata where the number of Vulkan depth transformation parameter changes per second does not exceed a threshold, the binding is achieved by binding the Vulkan depth transformation parameters to a unified buffer object; for scene-combined metadata where the number of Vulkan depth transformation parameter changes per second exceeds a threshold, a dedicated high-speed memory area is used to bind the Vulkan depth transformation parameters to the target shader.
[0054] The data structure of the batch synchronization packet is as follows: packet header (length, type, checksum), GPU architecture marker, DRM depth control parameters, viewport parameters, depth buffer parameters, pipeline status parameters, and tail checksum.
[0055] Furthermore, the DRM subsystem converts the hardware-independent parameters in the batch synchronization package into hardware-dependent instructions for the current GPU based on the GPU architecture information. Specifically, if the GPU supports hardware clamping, the clamping threshold is written to the GPU depth clamping register; if the GPU supports hardware pruning switch, the pruning control class cash flag is mapped to the GPU pruning enable register value; if the GPU does not support the above two hardware features, the parameters are converted into a combination of Vulkan standard instructions that the GPU can recognize through the software emulation instruction generator.
[0056] Furthermore, to address the accuracy loss issue during depth range conversion, this invention achieves real-time monitoring and calibration of depth accuracy, specifically including:
[0057] After each rendering frame, DXVK copies the pixel block data from the depth buffer to a CPU-accessible buffer, converts the depth data to floating-point format, and calculates the effective bit width, variance, and dispersion of the depth values. If any of the following conditions are met: effective bit width is less than a threshold, variance is less than a threshold, or dispersion is greater than a threshold, it is considered an accuracy anomaly. For cases where the effective bit width is less than the threshold, the conversion coefficients are adjusted to expand the distribution range of depth values within the Vulkan range. For cases where the variance is less than the threshold, a more complex conversion method is switched and the conversion coefficients are recalculated. For cases where the dispersion is greater than the threshold, depth offset is enabled to avoid depth value overlap. Example
[0058] This embodiment takes the Linux system as an example and adopts a Direct3D depth clipping behavior compatibility method based on atomic shaders provided by this invention. It solves the DXVK depth behavior compatibility problem when the GPU lacks the VK_EXT_depth_clip_enable extension. The specific process includes:
[0059] S1, Atomized Capture and Conflict Resolution of D3D Depth-Related States. From the API calls of the D3D application, all state parameters affecting depth processing behavior are extracted completely and accurately, and state conflicts caused by multiple API calls are resolved, providing a unified data source for subsequent transformations. This is achieved through extensions to DXVK modules, including:
[0060] S1.1, Full interception and classification of deep-related API calls.
[0061] In the DXVK D3D device interface implementation, all API calls related to depth processing are intercepted. Taking D3D9 as an example, the relevant calls include:
[0062] IDirect3DDevice9::SetRenderState(D3DRS_CLIPPING / D3DRS_ZWRITEENABLE / D3DRS_ZNEAR / D3DRS_ZFAR), IDirect3DDevice9::Set Transform(D3DTS_PROJECTION), IDirect3DDevice9::CreateDepthStencilSurface, IDirect3DDevice9::SetDepthStencilSurface.
[0063] The intercepted parameters are divided into five categories, each assigned a unique atomic identifier and priority:
[0064] Clipping control class (identifier CLIP_STATE_ID, priority 3): Clipping enable and disable flags;
[0065] Depth Range Class (identified by DEPTH_RANGE_ID, priority 2): near and far plane values, including D3DRS_ZNEAR / D3DRS_ZFAR direct configuration values;
[0066] Deep buffer attribute class (identifier DEPTH_BUFFER_ID, priority 4): deep buffer format, forward and reverse modes, bit width, saturation write support flag;
[0067] Depth write and test class (identified by DEPTH_TEST_ID, priority 1): depth write switch, depth comparison function;
[0068] Vertex processing mode class (identifier VERTEX_PROCESS_ID, priority 5): hardware vertex processing and software vertex processing flags.
[0069] S1.2 Accurate extraction and priority merging of multi-source state parameters.
[0070] S1.2.1 Depth Range Parameter Extraction:
[0071] Prioritize extracting explicit configuration values for D3DRS_ZNEAR / D3DRS_ZFAR (D3D9) or viewport TopLeftZ / BottomRightZ (D3D11);
[0072] Handling the extreme scenario of near=0: Automatically set near=1e-6f (to avoid division overflow) and mark is_near_zero = TRUE;
[0073] Clipping state extraction: D3D9 is extracted from the D3DRS_CLIPPING parameter, and D3D11 is extracted from the combination of D3D11_DEPTH_STENCIL_DESC::DepthEnable and D3D11_RASTERIZER_DESC::ScissorEnable, and uniformly converted into the d3d_clip_enabled boolean flag;
[0074] Depth buffer attribute extraction: Extract the format and bit width from the depth buffer creation and binding API, determine whether it is a reverse depth by the relationship between the near and far projection matrices (is_rev_depth = (d3d_far < d3d_near)), and query the GPU feature table to obtain the saturate write support for this format (supports_saturate_write).
[0075] S1.3, Deep State Conflict Detection and Resolution.
[0076] Conflict detection rules: When multiple API calls modify the same type of state within the same frame, such as first setting D3DRS_ZNEAR=0.1 via SetRenderState and then passing a projection matrix with near=0.5 via SetTransform, it is determined to be a state conflict;
[0077] Conflict resolution strategy: Based on defined priorities, higher priority states override lower priority states. For example, if the priority of depth range class 2 is higher than the priority of projection matrix resolution, the explicitly configured ZNEAR overrides the matrix resolution value.
[0078] Conflict logging: Logs are recorded for all conflict scenarios, including conflict state type, conflict parameter value, and resolution result, which facilitates debugging and compatibility optimization.
[0079] S1.4 Construction and version management of atomic parameter sets.
[0080] All parameters after parsing, merging, and conflict resolution are encapsulated into a D3DDepthStateAtom structure, with fields including: basic parameters (d3d_clip_enabled, d3d_near, d3d_far, etc.), scene markers (is_near_zero, is_rev_depth, etc.), parameter priority mask, conflict resolution marker, parameter version number (state_version, an auto-incrementing sequence), and parameter checksum (param_crc, calculated from all fields).
[0081] In DXVK, a D3DDepthStateCache cache pool is created, which adopts a two-level structure of frame-level cache and global cache: the frame-level cache stores the D3DDepthStateAtom of the current frame, and the global cache stores the most recent 32 historical states. An LRU replacement strategy is adopted, and the state is quickly determined to be duplicated by param_crc.
[0082] The refined dimensional breakdown of S2 and D3D depth processing scenes, based on the D3DDepthStateAtom parameter set, clarifies the specific type of the current depth processing scene for the target application, providing a precise basis for shader template matching and transformation strategy selection. The specific implementation added to the DXVK module is as follows:
[0083] S2.1 Definition and Quantitative Judgment of Scene Decomposition Dimensions
[0084] Six core decomposition dimensions are defined, each with clearly defined quantitative judgment criteria to ensure unambiguous scenario classification:
[0085] Dimension 1: D3D version (d3d_version), values: D3D9 (D3D_SDK_VERSION < 32), D3D10 (32≤ D3D_SDK_VERSION < 43), D3D11 (D3D_SDK_VERSION ≥ 43), determined by the D3D application SDK version number obtained during DXVK initialization;
[0086] Dimension 2: Depth range type (depth_range_type), values: normal range (d3d_far / d3d_near < 1000), large depth range (1000 ≤ d3d_far / d3d_near < 10000), super large depth range (d3d_far / d3d_near ≥ 10000), reverse depth (d3d_far < d3d_near), determined by the ratio and magnitude relationship between d3d_near and d3d_far;
[0087] Dimension 3: Near plane characteristics (near_plane_type), values: regular near plane (d3d_near ≥ 1e-3f), extremely near plane (1e-6f ≤ d3d_near < 1e-3f), zero near plane (d3d_near = 1e-6f, after conversion from the original near=0), determination criterion: the numerical range of d3d_near;
[0088] Dimension 4: Clipping State (clip_state), values: clipping enabled (d3d_clip_enabled = TRUE), clipping disabled (d3d_clip_enabled = FALSE), determined by the d3d_clip_enabled flag in D3DDepthStateAtom;
[0089] Dimension 5: Depth buffer characteristics (depth_buffer_type), values: 16-bit positive (depth_bits=16 and is_rev_depth=FALSE), 24-bit positive (depth_bits=24 and is_rev_depth=FALSE), 32-bit positive (depth_bits=32 and is_rev_depth=FALSE), reverse depth (is_rev_depth=TRUE, compatible with all bit widths), determined by: depth buffer bit width and is_rev_depth flag;
[0090] Dimension 6: Vertex processing mode (vertex_process_mode), values: hardware vertex processing (VERTEX_PROCESS_HW), software vertex processing (VERTEX_PROCESS_SW), determined by the vertex_process_mode flag in D3DDepthStateAtom;
[0091] Dimension 7: Custom depth flag (custom_depth_flag), values: non-custom depth (no_custom_depth) and custom depth (has_custom_depth), determination basis: subsequent shader analysis results (field reserved in advance, to be completed in subsequent steps).
[0092] S2.2 Scene Combination Rules and Unique Index Generation.
[0093] Scene combination rules: The values of the 7 dimensions are combined by Cartesian product to form a total of 3 (D3D version) × 4 (depth range type) × 3 (near plane characteristics) × 2 (clipping state) × 4 (depth buffer characteristics) × 2 (vertex processing mode) × 2 (custom depth marker) = 3 × 4 × 3 × 2 × 4 × 2 × 2 = 1152 unique scene combinations.
[0094] Unique index generation: A unique SceneIndex (16-bit unsigned integer) is assigned to each scene combination. The generation rules are as follows:
[0095] SceneIndex = (d3d_version << 13) | (depth_range_type << 11) | (near_plane_type << 9) | (clip_state << 8) | (depth_buffer_type << 6) | (vertex_process_mode << 5) | (custom_depth_flag << 4)
[0096] Each dimension occupies a fixed number of bits to ensure that the index and the scene combination correspond one-to-one without conflict.
[0097] Scene combination metadata storage: Create a SceneMetadata structure to store the dimension values, recommendation transformation strategies, and recommendation shader component combinations for each SceneIndex. Pre-compile it into a binary metadata table, embed it into the DXVK executable file, and load it into memory at startup.
[0098] S2.3 Scene Dynamic Matching and Caching: For the D3DDepthStateAtom of the current frame, match the values of the seven dimensions one by one according to the above judgment criteria to generate SceneIndex; if SceneIndex already exists in the SceneMetadata table, directly obtain the corresponding scene metadata; if it does not exist, such as in an extreme custom scene, trigger the default scene fallback, match the closest scene metadata, and mark is_fallback_scene = TRUE; add a SceneIndex cache field in D3DDepthStateCache, bind it to D3DDepthStateAtom for storage, and avoid repeatedly calculating SceneIndex for the same state.
[0099] S3. Adaptive calculation and standardization of depth conversion parameters: Based on D3DDepthStateAtom and scene metadata, core parameters such as depth conversion coefficients and clamping thresholds required by Vulkan are calculated. At the same time, the conversion strategy is adaptively adjusted according to the scene type to ensure the accuracy and compatibility of depth range conversion.
[0100] S3.1 Selection of scene adaptive transformation strategy and parameter optimization.
[0101] Matching transformation strategies based on scene metadata:
[0102] For standard ranges and standard near-plane scenes, a basic linear transformation formula is used to balance efficiency and accuracy;
[0103] For scenes with a large depth range, a logarithmic transformation formula is used to optimize accuracy: vulkan_z = log (d3d_z * conv_a + 1.0f) * (conv_b / log ((d3d_far - d3d_near) * conv_a + 1.0f)), which uses a logarithmic function to make the depth values uniformly distributed within the Vulkan range [0, 1].
[0104] For scenes with extremely large depth ranges, a two-stage transformation formula is used: linear transformation is used when d3d_z ≤ 0, and logarithmic transformation is used when d3d_z > 0;
[0105] For near-plane scenes, enable near-plane precision compensation, adjust conv_a = 0.6f and conv_b = 0.4f to expand the distribution range of near-plane depth values.
[0106] Depth buffer bit width adaptation: 16-bit depth buffer, the precision compensation factor precision_compensate = 1.0f / (pow (2, 16) - 1.0f) is calculated, and the converted depth value is multiplied by this factor; 24-bit and 32-bit depth buffers, precision_compensate = 1.0f, maintain the original conversion precision.
[0107] Depth comparison function adaptation: Based on the D3D depth comparison function, such as D3DCMP_LESSEQUAL, it is converted into the corresponding Vulkan comparison operation, such as VK_COMPARE_OP_LESS_OR_EQUAL. In reverse depth scenes, the comparison operation is automatically flipped, such as LESS becoming GREATER.
[0108] S3.2 Standardized encapsulation and verification of conversion parameters.
[0109] The parameters such as basic conversion coefficients, clamping threshold, scene type label, precision compensation factor, and depth comparison operation are encapsulated into a VulkanDepthConvParams structure. The fields include: conv_a, conv_b, vulkan_near_clamp, vulkan_far_clamp, precision_compensate, depth_compare_op, conversion_strategy, and param_crc. Among them, conversion_strategy is a conversion strategy enumeration, and param_crc is associated with the param_crc of D3DDepthStateAtom.
[0110] Parameter validation involves calculating the param_crc of VulkanDepthConvParams and performing an XOR operation with the param_crc of D3DDepthStateAtom to ensure the consistency of the parameters with the original state.
[0111] The established three-level mapping table is stored in the DXVK global state manager. When D3DDepthStateAtom changes (i.e., state_version increments), the recalculation and verification of VulkanDepthConvParams are triggered.
[0112] S4, the construction, version management and pre-compilation of the atomic shader template library, to solve the problems of low efficiency and poor compatibility of dynamic shader injection in the existing technology, reduce runtime overhead through pre-compilation, and at the same time ensure that the template covers all 1152 scene combinations.
[0113] S4.1 Atomic component splitting and interface definition of shader templates.
[0114] Based on deep processing capabilities, it is divided into 7 independent atomic components. Each component defines a standardized input / output interface with SPIR-V semantics, ensuring that the components can be flexibly combined.
[0115] VertexClipComponent: Its function is to implement the conditional branch logic of view frustum clipping. The input interface includes the clipping enable flag bool clip_enabled, the rD3D near and far plane float d3d_near and float d3d_fa, and the vertex coordinate vec4 gl_Position. The output interface is the clipping distance array float gl_ClipDistance [2]. Variants include the basic clipping variant for regular scenes and the software vertex processing clipping variant.
[0116] The DepthConvComponent is used to convert depth values from D3D to Vulkan. Its input interfaces include the D3D depth value (float d3d_z), conversion coefficients (float conv_a and float conv_b), precision compensation factor (float precision_compensate), and conversion strategy (enum conversion_strategy). The output interface is the Vulkan depth value (float vulkan_z). Variants include linear conversion variants, logarithmic conversion variants, two-segment conversion variants, and inverse depth conversion variants.
[0117] The DepthClampComponent implements the depth value clamping logic. Its input interfaces include float vulkan_z, clamping thresholds float near_clamp and float far_clamp, and hardware saturation write support flag bool supports_saturate_write. Its output interface is the clamped depth value float clamped_z. Variants include a soft clamping variant (OpClamp instruction) and a hardware saturation variant (which utilizes the depth buffer saturation feature to skip the soft clamping).
[0118] The RevDepthAdaptComponent is used to adapt the depth comparison logic for reverse depth scenarios. Its input interfaces include the clamped depth value (float clamped_z) and the depth comparison operation (VkCompareOpdepth_compare_op). Its output interfaces include the adapted depth value (float adapted_z) and the adapted comparison operation (VkCompareOp adapted_compare_op). It has no variations, is a single logic, and is compatible with all reverse depth scenarios.
[0119] CustomDepthCompatComponent: This component adapts to custom depth shaders. Its input interfaces include a custom depth flag (bool is_custom_depth), a converted depth value (float vulkan_z), and a custom depth value (float custom_z). Its output interface is the final depth value (float final_z). Variants include a variant that skips built-in logic (using only custom depth) and a hybrid variant (custom depth + clamping).
[0120] NearPlaneCompensateComponent: Its function is to optimize the depth accuracy of near-plane scenes. The input interface includes the converted depth value float vulkan_z and the zero near-plane marker bool is_near_zero. The output interface is the compensated depth value float compensated_z. It has no variations and is a single logic.
[0121] VertexProcessAdaptComponent: The function is to adapt hardware and software vertex processing modes. The input interface includes the software vertex processing flag bool is_software_vertex and the clipping distance array float gl_ClipDistance [2]. The output interface is the adapted clipping distance array float gl_ClipDistance [2]. Variants include hardware processing variant (preserving clipping distance) and software processing variant (forcibly setting the clipping distance to a positive value and skipping GPU clipping).
[0122] S4.2 Component variant selection and scene template splicing: Based on SceneMetadata, define the mapping rules for components and variants for each SceneIndex.
[0123] For example, SceneIndex=D3D9 + large depth range + regular near plane + clipping enabled + 24-bit positive depth + hardware vertex processing + non-custom depth, the mapping rule is: VertexClipComponent (basic clipping variant) + DepthConvComponent (logarithmic transformation variant) + DepthClampComponent (soft clamp variant) + near plane precision compensation component (enabled) + other components (default variant).
[0124] The template splicing process is as follows: read the mapping rules of the components and variants corresponding to SceneIndex, and splice the SPIR-V code fragments of each component according to the fixed order of the vertex shader process and the fragment shader process. The fixed order of the vertex shader process is vertex clipping, depth transformation, near plane compensation, and finally vertex processing mode adaptation. The fixed order of the fragment shader process is depth clamping, reverse depth adaptation, and finally custom depth compatibility.
[0125] Insert standardized parameter placeholders: The placeholders correspond one-to-one with the fields of the VulkanDepthConvParams structure, in the format {PARAM_NAME}, such as {CONV_A}, to supplement the original DXVK shader logic interfaces, such as coordinate transformation and texture sampling interfaces, to ensure that the template is compatible with the existing DXVK pipeline.
[0126] S4.3 Template Version Management and Compatibility Adaptation:
[0127] Template version number definition: TemplateVersion = (MajorVersion << 16) | (MinorVersion << 8) | PatchVersion, where: MajorVersion is the major version number, which increments when the component structure changes; MinorVersion is the minor version number, which increments when a component variant is added; PatchVersion is the patch version number, which increments when a bug is fixed.
[0128] Version compatibility mechanism: The minimum supported Vulkan version (MinVulkanVersion) and the list of supported GPU architectures (SupportedGPUArch) are stored in the template metadata. When DXVK starts, it detects the GPU characteristics and automatically selects a compatible template version.
[0129] Template conflict resolution: If multiple compatible versions exist for the same SceneIndex, the highest version is selected first; if the highest version is incompatible with the current GPU, it is automatically downgraded to the second highest version.
[0130] S4.4 Template pre-compilation and multi-level caching optimization.
[0131] Pre-compilation process: During the DXVK compilation stage, the mapping rules of all 1152 scene components and variants are read, the glslangValidator compiler is called, and the code of each component variant is compiled in the concatenation order to generate SPIR-V bytecode. The SPIR-V bytecode is optimized by removing redundant instructions, merging duplicate branches, compressing debugging information, and optimizing register allocation, which reduces the bytecode size by 25%-30%. A TemplateID (SceneIndex |(TemplateVersion << 16)) is generated for each template to ensure the uniqueness of the template.
[0132] The design incorporates a three-level cache: L1 cache, a DXVK process memory cache that stores the 16 sets of templates currently used by the application, using array storage with an access latency of ≤10ns; L2 cache, a DXVK local file cache that stores all pre-compiled templates named by TemplateID, using LZ4 compression to reduce disk usage; and L3 cache, a system-level shared cache that is shared by multiple DXVK processes to reduce redundant compilation and disk I / O.
[0133] Cache verification mechanism: Each cache file stores verification information such as TemplateID, param_crc, and GPUArch. Verification is performed during loading to ensure that the template matches the current scene and GPU characteristics.
[0134] S5 extends the Linux kernel-mode hardware-independent depth control abstraction channel by modifying the Linux kernel DRM subsystem to build a dedicated depth control channel between user-mode DXVK and kernel-mode GPU hardware abstraction. This enables efficient transfer of depth parameters, batch synchronization, and hardware-independent adaptation, avoiding the problem of frequent state switching in existing technologies.
[0135] S5.1 Define a hardware-independent depth control data structure.
[0136] In the Linux kernel's DRM-related header files, a new hardware-independent `struct drm_depth_control_params` structure has been added to ensure compatibility with parameter passing requirements across all GPU architectures.
[0137] struct drm_depth_control_params {
[0138] uint32_t template_id; / / Shader template ID (from step 4)
[0139] uint16_t scene_index; / / Scene index (from step 2)
[0140] bool d3d_clip_enabled; / / D3D clipping enabled flag
[0141] float conv_a; / / Depth conversion factor a
[0142] float conv_b; / / Depth conversion factor b
[0143] float vulkan_near_clamp; / / Vulkan near clipping threshold
[0144] float vulkan_far_clamp; / / Vulkan far clipping threshold
[0145] float precision_compensate; / / Precision compensation factor
[0146] bool is_rev_depth; / / Reverse depth marker
[0147] bool is_custom_depth; / / Custom depth marker
[0148] bool is_software_vertex; / / Software vertex processing flag
[0149] bool supports_saturate_write; / / Hardware saturate write support flag
[0150] VkCompareOp depth_compare_op; / / Depth comparison operation
[0151] enum conversion_strategy conv_strategy; / / Conversion strategy
[0152] uint32_t param_crc; / / Parameter checksum (consistent with the DXVK side)
[0153] uint64_t state_timestamp; / / State timestamp (used for synchronization)
[0154] uint32_t template_version; / / Template version number (for compatibility)
[0155] };
[0156] A new `struct drm_depth_state_cache` structure has been added for storing kernel-mode depth state cache and hardware adaptation information.
[0157] struct drm_depth_state_cache {
[0158] struct drm_depth_control_params cache_entries
[32] ; / / Caches 32 sets of parameters (supports multiple viewports)
[0159] uint8_t lru_counter
[32] ; / / LRU counter
[0160] uint16_t current_index; / / Current active parameter index
[0161] uint64_t last_sync_timestamp; / / Last synchronization timestamp
[0162] struct drm_gpu_arch_info gpu_arch; / / GPU architecture information (AMD / Intel / NVIDIA)
[0163] bool support_hw_clamp; / / GPU hardware clamping support flag
[0164] bool support_hw_clip_toggle; / / GPU hardware clipping switch support flag
[0165] };
[0166] The struct drm_gpu_arch_info stores information such as GPU architecture, supported Vulkan versions, and depth-related hardware features, which are obtained by the kernel through the DRM subsystem during initialization.
[0167] S5.2 System Call Interface Extension and Parameter Validation: Two new system calls are added to the Linux kernel for parameter interaction between DXVK and kernel mode, supporting hardware-independent parameter passing.
[0168] `sys_drm_depth_control_set` is used by DXVK to pass depth control parameters to the kernel. Its function prototype is `long sys_drm_depth_control_set (const struct drm_depth_control_params __user*params)`. The function implementation process is as follows: User-space parameter copy: The user-space parameters passed by DXVK are copied to the kernel-space buffer; Hardware compatibility check: Based on `drm_gpu_arch_info`, the `template_version` and `conv_strategy` parameters are checked for compatibility with the current GPU; Parameter validity check: `param_crc` is checked (the kernel recalculates and compares it with the input value), and the parameter value range (e.g., `conv_a` is within [-1.0f, 1.0f]); Cache update: The `scene_index` and `param_crc` are used to determine if the parameter is already in the cache. If it exists, `lru_counter` is updated; otherwise, the cache entry is replaced according to the LRU policy.
[0169] `sys_drm_depth_control_get` is used by DXVK to query the current depth status in kernel space. Its function prototype is `long sys_drm_depth_control_get (struct drm_depth_control_params __user *params, uint32_t query_type)`. The implementation process includes: supporting two query types: `QUERY_CURRENT` (querying currently active parameters) and `QUERY_CACHE` (querying all parameters in the cache); copying parameters from the kernel cache to user space, including hardware adaptation flags related to `gpu_arch` (such as `support_hw_clamp`); and system call registration: assigning unique system call numbers (e.g., 380, 381) to two system calls, registering them in `syscall_table`, and adding declarations in `unistd.h` to ensure DXVK can access them through the standard system call interface.
[0170] S5.3 Hardware-independent deep state batch synchronization mechanism. In the DRM subsystem, the atomic state commit logic is extended to add a hardware-independent deep state batch synchronization function.
[0171] Batch synchronization package construction involves packaging depth control parameters, viewport parameters, depth buffer parameters, and pipeline state parameters into a hardware-independent batch synchronization package. The format is defined as: [Package header (length, type, checksum) + GPU architecture marker + depth control parameters + viewport parameters + depth buffer parameters + pipeline state parameters + tail checksum]. Hardware adaptation conversion: The kernel, based on `drm_gpu_arch_info`, converts the hardware-independent parameters in the batch synchronization package into hardware-dependent instructions for the current GPU. If the GPU supports hardware clamping (`support_hw_clamp = TRUE`), then `vulkan_near_clamp` / `vulkan_far_clamp` are directly written to the GPU depth clamping register. If the GPU supports hardware clipping (`support_hw_clip_toggle = ...`), then ... If TRUE is selected, d3d_clip_enabled will be mapped to the GPU clipping enable register value. If the GPU does not support the above hardware features, the parameters will be converted into a combination of standard Vulkan instructions that the GPU can recognize, such as vkCmdSetViewport, vkCmdSetDepthBias, vkCmdSetLogicOp, etc., through a software emulation instruction generator.
[0172] Optimize high-frequency switching: For scenes that switch more than 30 times per second, the kernel automatically enables a parameter merging strategy. For example, it merges 2 to 4 frequently switched parameter sets into a composite parameter set and dynamically selects the corresponding shader logic and hardware instructions through scene_index to reduce the number of synchronizations.
[0173] S5.4, a hardware-independent implementation of a soft-simulation instruction generator.
[0174] Implement hardware-independent soft simulation instruction generation logic, supporting all GPU architectures. Depth clamping soft simulation generates the `vkCmdSetDepthBoundsTestEnable` instruction, setting `vulkan_near_clamp` / `vulkan_far_clamp` as the depth boundary, achieving soft clamping through depth boundary testing. Clipping switch soft simulation generates vertex shader auxiliary instructions, implementing clipping switching through dynamic assignment of the `gl_ClipDistance` array; when enabled, it calculates the clipping distance, and when disabled, it forces the clipping distance to a positive value. Reverse depth soft simulation generates the `vkCmdSetDepthCompareOp` instruction, dynamically toggling depth comparison operations such as `VK_COMPARE_OP_LESS` and `VK_COMPARE_OP_GREATER`. Soft simulation instruction optimization merges the generated soft simulation instructions with other GPU instructions from the application, removing redundant instructions to ensure minimal performance loss during soft simulation.
[0175] S6, User-space-kernel-space parameter bidirectional synchronization and verification, is used to ensure that VulkanDepthConvParams on the DXVK side is completely consistent with drm_depth_control_params in the kernel space, avoiding problems caused by transmission errors, data tampering or hardware incompatibility during parameter synchronization.
[0176] S6.1 Parameter Synchronization Initiation and Transmission: After generating VulkanDepthConvParams, the DXVK side queries the corresponding TemplateID based on SceneIndex, constructs a drm_depth_control_params structure, and maps the fields one-to-one with VulkanDepthConvParams; it calls the sys_drm_depth_control_set system call to pass drm_depth_control_params to the kernel, and simultaneously passes GPUArch information, which is queried by VulkanvkGetPhysicalDeviceProperties when DXVK starts; transmission timeout handling: a 10ms timeout is set. If the system call times out and does not return, it automatically retryes 3 times. If it still fails, the fallback strategy is triggered, and the default scene parameters are used.
[0177] S6.2 Kernel-mode parameter verification and hardware adaptation feedback: After receiving parameters, the kernel performs parameter validity verification and hardware compatibility verification. If the verification passes, the kernel updates the cache and returns 0 to indicate success. At the same time, the returned data carries hardware adaptation flags such as support_hw_clamp / support_hw_clip_toggle. If the verification fails, such as due to parameter incompatibility or CRC mismatch, the kernel returns error codes such as -EINVAL or -ENOTSUPP, and carries the reason for the failure in the returned data.
[0178] S6.3 DXVK Side Parameter Verification and Adaptation Adjustment. DXVK receives the kernel's return result. If the return is successful, it calls sys_drm_depth_control_get to query the current parameters in the kernel cache; it calculates the queried parameters and their local drm_depth_control_params' param_crc. If they match, synchronization is successful; if they do not match, forced synchronization is triggered, parameters are retransmitted and verified; if the return fails, the parameters are adjusted according to the error code. In case of hardware incompatibility errors, the conversion_strategy is automatically switched to software simulation priority, the template version number is reduced, the parameters are reconstructed and synchronized, and in case of CRC mismatch errors, the local parameter param_crc is recalculated and synchronized again. The synchronization result is cached, and the successfully synchronized drm_depth_control_params are bound and stored with VulkanDepthConvParams to avoid duplicate synchronization of the same parameter.
[0179] Dynamic adaptation and command generation of the S7 and DXVK side depth processing pipelines are achieved, completing shader template matching, parameter binding, and Vulkan command stream generation, ultimately realizing Vulkan simulation of D3D depth behavior.
[0180] S7.1 Fast matching and loading of shader templates: DXVK calculates the TemplateID based on SceneIndex and the TemplateVersion returned by the kernel; it loads templates according to the three-level cache order, prioritizing loading from the L1 cache, and if a template is not found, loading it from the L2 cache, decompressing it, and storing it in the L1 cache; finally, loading it from the L3 cache, copying it to the local L2 cache, and then storing it in the L1 cache; template loading verification: after loading, the TemplateID and param_crc are verified to ensure that the template matches the current parameters; if they do not match, the template is reloaded.
[0181] S7.2 Dynamic Binding and Optimization of Template Parameters. Binding method selection: For low-frequency parameter change scenarios with ≤10 changes per second, use a unified buffer object (UBO) for binding. Create a DXVK_DEPTH_UBO with a size of sizeof(VulkanDepthConvParams), update the VulkanDepthConvParams parameters to the UBO, and bind it to the pipeline via vkCmdBindDescriptorSets. For high-frequency parameter change scenarios with >10 changes per second, use push constant binding. Store core parameters including conv_a, conv_b, near_clamp, far_clamp, and clip_enabled in the push constant (push constant capacity ≤128 bytes) to reduce UBO update overhead. Parameter update optimization: Only update the UBO or push constant when the parameter param_crc changes, avoiding invalid updates.
[0182] S7.3 Integration of shader templates with the existing DXVK pipeline.
[0183] Vertex shader integration involves combining the loaded vertex shader template with DXVK's existing vertex transformation logic, including coordinate transformation, texture coordinate generation, and lighting calculation, through a standardized interface; atomic components are called in the order of vertex clipping component, depth transformation component, near-plane precision compensation component, and vertex processing mode adaptation component.
[0184] Fragment shader integration involves combining the loaded fragment shader template with existing fragment processing logic in DXVK, including texture sampling, lighting calculation, and color blending, through a standardized interface; atomic components are called in the order of depth clamping component, reverse depth adaptation component, and then custom depth-compatible component.
[0185] S7.4, Generation and Optimization of Vulkan Command Streams.
[0186] Command stream generation: The DXVK module adds depth control command generation logic, binds depth-related shader modules, descriptor sets, and pipeline states, and embeds hardware-related instructions from the kernel batch synchronization package, such as viewport settings, depth buffer binding, and depth comparison operation settings, to generate core rendering commands such as vkCmdBeginRenderPass, vkCmdDraw, and vkCmdEndRenderPass.
[0187] Command flow optimization merges adjacent similar commands, such as consecutive viewport setting commands, removes redundant depth state setting commands, such as repeated settings when parameters have not changed, and uses vkCmdDrawIndexedIndirect for high-frequency drawing commands, such as batch drawing of particle systems, to reduce CPU command submission overhead.
[0188] S8, Real-time Depth Accuracy Monitoring and Calibration, is used to solve the accuracy loss problem in depth range conversion. By monitoring the depth buffer data in real time, it dynamically adjusts the conversion parameters and strategies to ensure that the depth accuracy meets the rendering requirements.
[0189] S8.1 Depth Accuracy Monitoring Data Acquisition. A new depth accuracy monitoring logic has been added to the DXVK module. After each rendering frame, the 16×16 pixel block data from the depth buffer is copied to the CPU-accessible staging buffer via vkCmdCopyImage. The copied depth data is parsed and converted to floating-point format. The effective bit width of the depth value is calculated by counting the number of significant digits in the binary representation of the depth value. Variance is used to determine the uniformity of the depth value distribution, and dispersion is used to determine whether z-fighting exists. The monitoring frequency is controlled: monitoring is performed every 10 frames in normal scenes and every 2 frames in scenes with large depth ranges / very close to a plane, to avoid excessive resource consumption by the monitoring logic.
[0190] S8.2, Accuracy Anomaly Judgment and Calibration Strategy. Anomaly judgment thresholds include: effective bit width < 16 bits, variance < 1e-6 indicating overly concentrated distribution, and dispersion > 0.01 indicating significant z-fighting. Meeting any one of these conditions constitutes an accuracy anomaly. The dynamic calibration strategy adjusts the coefficients of conv_a and conv_b if the effective bit width is insufficient, expanding the distribution range of depth values within the Vulkan [0, 1] range, such as conv_a = 0.6f and conv_b = 0.4f. If the variance is too small, a more complex transformation strategy, such as linear to logarithmic conversion, is used, and conv_a and conv_b are recalculated. If the dispersion is too large, depth offset vkCmdSetDepthBias is enabled, setting depthBiasConstantFactor = 1e-5f and depthBiasSlopeFactor = 1e-5f to avoid depth value overlap.
[0191] The calibration parameters are updated, and the calibrated parameters are updated to VulkanDepthConvParams and resynchronized to the kernel, triggering the shader parameter binding update.
[0192] S8.3, Calibration Effect Verification and Rollback: After calibration, monitor for 3 consecutive frames. If the accuracy indicators return to normal (i.e., the effective bit width is ≥16 bits, the variance is ≥1e-6, and the dispersion is ≤0.01), the calibration parameters are retained. If the accuracy does not improve or deteriorates after calibration, the parameters before calibration are automatically rolled back, and a calibration failure log is recorded for subsequent optimization.
[0193] S9 offers comprehensive compatibility adaptation for complex scenarios, providing targeted adaptation solutions for complex scenarios such as custom depth shaders, software vertex processing, multiple viewports and cameras, and depth state conflicts, ensuring comprehensive compatibility coverage.
[0194] S9.1 Custom depth shader adaptation and shader recognition: Add HLSL shader syntax analysis logic to the DXVK module to detect whether it contains SV_Depth semantics D3D11 or manually modify the D3 and D9 code of gl_Position.z, and mark is_custom_depth = TRUE.
[0195] The adaptation strategy involves selecting a template that matches the corresponding variant of the custom depth-compatible component, skipping the built-in depth conversion and clamping logic. Kernel synchronization involves passing the `is_custom_depth = TRUE` flag, causing the kernel to switch the depth clamping logic to a saturation mode during the depth buffer write phase, utilizing the hardware saturation characteristics of the GPU depth buffer to achieve clamping. Conflict handling involves adding lightweight clamping logic in the fragment shader if the custom depth value exceeds the [near, far] range, applying only to custom depth scenes to avoid rendering anomalies.
[0196] S9.2 and D3D9 software vertex processing scene adaptation. The adaptation logic is as follows: CPU-side preprocessing: In the DXVK module, CPU-side vertex clipping and depth transformation logic is added. Based on the d3d_clip_enabled flag, the software-processed vertices are clipped to frustum, and the Vulkan depth value is calculated and clamped using the transformation formula. GPU-side adaptation: By synchronizing the is_software_vertex = TRUE flag in the kernel, the kernel disables the GPU-side clipping and depth transformation logic to avoid CPU and GPU processing conflicts. Vertex data transmission: The CPU-processed vertex data is updated to the GPU vertex buffer through vkCmdUpdateBuffer to reduce the GPU computational pressure.
[0197] S9.3, Multi-viewport and Multi-camera Scene Adaptation. Multi-viewport parameter aggregation: A new multi-viewport depth parameter aggregation logic has been added to the DXVK module. The D3DDepthStateAtom parameters of multiple viewports are aggregated into a D3DMultiViewportDepthState structure. Parameters for each viewport are distinguished by index. The VulkanDepthConvParams parameters for each viewport are calculated and packaged into an array. Batch synchronization: The sys_drm_depth_control_set system call is used to batch pass multi-viewport depth parameters to the kernel. The kernel adapts the parameters to the Vulkan multi-viewport extension (VK_EXT_multiview), assigning independent depth control parameters to each viewport. Camera switching optimization: When a D3D application switches cameras (modifies the projection matrix), DXVK only updates the VulkanDepthConvParams parameters for the corresponding camera. The kernel uses a "partial update" mechanism to only synchronize the changed parameters, keeping the depth state of other viewports unchanged.
[0198] S9.4, Deep State Conflicts and Extreme Scenario Adaptation.
[0199] Depth state conflict adaptation: When a D3D application frequently switches depth states within the same frame (> 50 times per second), DXVK automatically enables the state merging strategy, merging all switched states into a composite state, and dynamically selecting the corresponding shader logic through SceneIndex to reduce state switching overhead.
[0200] For extreme scenario adaptation, in scenarios with near=0 and far=inf, vulkan_near_clamp = 0.0f and vulkan_far_clamp = 1.0f are adjusted, and a logarithmic transformation strategy is adopted to avoid depth value overflow. For 16-bit depth buffer and large depth range scenarios, double-precision depth simulation is enabled, and the depth offset is dynamically adjusted through vkCmdSetDepthBias to improve depth discrimination. For non-standard depth logic in older D3D9 games, targeted depth processing code is injected through the DXVK shader patching mechanism to ensure compatibility with non-standard behavior.
[0201] S10, Vulkan command stream commit feedback and retries, is used to ensure the reliability of Vulkan command stream commits, handle abnormal situations such as commit failure and timeout, and avoid rendering interruptions caused by command stream commit problems.
[0202] Command stream submission and status query: DXVK submits Vulkan command streams via vkQueueSubmit, and records the submission timestamp and command stream ID; after submission, it queries the command stream execution status via vkGetFenceStatus, and sets a 50ms timeout.
[0203] Error handling and retries: If a submission times out, the submission will be automatically retried twice. If it still times out, the simplified command stream mode will be switched to, which removes unnecessary optimization commands while retaining the core rendering logic, and then the submission will be resubmitted. If the submission fails, it will be handled according to the failure reason code, such as VK_ERROR_DEVICE_LOST or VK_ERROR_OUT_OF_DATE_KHR. If it is VK_ERROR_DEVICE_LOST, the Vulkan device and depth state will be reinitialized, parameters will be resynchronized, and the submission will be resubmitted. If it is VK_ERROR_OUT_OF_DATE_KHR, the render target and depth buffer will be recreated, the render target bindings in the command stream will be updated, and the submission will be resubmitted.
[0204] Failure logs record detailed information for all failed submissions, including command flow ID, reason for failure, number of retries, and processing result, facilitating debugging and optimization.
[0205] This invention solves the compatibility problem of DXVK depth behavior when the VK_EXT_depth_clip_enable extension is not available. The experimental results are as follows:
[0206] Performance is effectively improved. The pre-compiled shader template library avoids the overhead of runtime shader injection and recompilation (shader compilation time is reduced by more than 90%). The kernel-mode batch synchronization mechanism reduces the latency of CPU to GPU state switching. According to actual tests, in the general D3D application scenario, the rendering frame rate is improved by 35%-55% compared with the existing shader injection solution. In the high-frequency clipping state switching scenario, the frame rate can be improved by more than 60%. In the deep range scenario, the frame rate loss is controlled within 10%.
[0207] With optimized depth accuracy, through scene adaptive transformation strategy and real-time accuracy monitoring and calibration mechanism, the effective bit width of depth value is maintained above 18 bits, and the occurrence rate of z-fighting is reduced by more than 95%. Even in extreme scenes such as large depth range (far / near=10000) and extremely near plane (near=1e-6f), clear depth hierarchy can still be maintained, and the depth rendering effect is consistent with the native D3D environment.
[0208] With comprehensive compatibility coverage, including shader templates for 1152 scene combinations, custom depth shader adaptation, software vertex processing adaptation, multi-viewport and multi-camera adaptation, and extreme scene adaptation mechanisms, it ensures that more than 98% of D3D 9-11 applications can run normally, including older D3D9 games, complex D3D11 rendering engine applications, and applications with custom depth logic.
[0209] With strong hardware adaptability, the kernel-mode hardware-independent design and software emulation instruction generator ensure that the solution is compatible with all GPUs supporting Vulkan 1.0 and above, including older integrated graphics cards such as Intel HD Graphics 4000 and low-end discrete graphics cards such as NVIDIA GeForce GT 630, which do not support the VK_EXT_depth_clip_enable extension. It is also compatible with the features of different GPU architectures of AMD, Intel and NVIDIA.
[0210] With excellent reliability and maintainability, the bidirectional parameter verification, command stream submission feedback and retry mechanism improve the running stability of DXVK by 80% and reduce crashes caused by parameter synchronization errors and command stream submission failures. The atomic component design, standardized parameter interface and modular step division make the solution easy to adapt to future new D3D versions such as D3D12 backward compatible scenarios or deep processing scenarios. Subsequent maintenance only requires expanding atomic components or scene combination rules, without reconstructing the overall architecture.
[0211] 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 depth clipping behavior compatible method based on atomized shaders, characterized in that, Specifically, the following steps are included: Multi-dimensional deep processing of scenes forms scene combinations, which consist of scene combination identifiers and combination metadata forming a metadata table. The combination metadata includes the values of each dimension, transformation strategies, and shader component combinations. During the DXVK compilation stage, a mapping is established between each scene combination and atomic components and component variants. The component variants are sequentially concatenated to obtain intermediate bytecode, and parameter placeholders and shader logic interfaces are added to form shader templates. The mapping relationship from scene combination identifiers to template identifiers is recorded as the first mapping. The DXVK executable file is compiled and embedded in the compiled metadata table. When DXVK starts, it loads the shader template, obtains the D3D application depth processing API call parameters, classifies the parameters and assigns priorities, analyzes the parameters to obtain scene combination identifiers, and forms an atomic parameter set consisting of parameters, scene combination identifiers, priority masks, version numbers and check codes. If the same scene combination identifier exists in the metadata table, the corresponding combination metadata is obtained; otherwise, the combination metadata of the scene combination identifier with the smallest difference is obtained, and the metadata table is updated. For the acquired combined metadata, Vulkan depth values are calculated based on the depth range type. The D3D depth comparison function is converted into a Vulkan depth comparison operation to form Vulkan depth transformation parameters. The Vulkan depth transformation parameters are mapped to DRM depth control parameters. The DRM subsystem packages the DRM depth control parameters, viewport parameters, depth buffer parameters, and pipeline state parameters into a batch synchronization package, and then converts them into hardware instructions adapted to the GPU. DXVK loads the shader template as the target shader based on the first mapping, binds the Vulkan depth transformation parameters to obtain the Vulkan shader module, generates a Vulkan command stream with embedded hardware instructions, and submits it to the GPU to complete the rendering of the D3D application. The method for generating and submitting the Vulkan command stream containing embedded hardware instructions to the GPU for rendering is as follows: DXVK concatenates the Vulkan shader module with the existing coordinate transformation, lighting calculation, texture sampling, and color blending logic to obtain a Vulkan shader module including a vertex shader module and a fragment shader module; then, the Vulkan shader module is bound to the Vulkan pipeline to generate a Vulkan command stream that enables rendering passes, primitive drawing, and ends rendering passes. The hardware instructions generated by the DRM subsystem are embedded into the Vulkan command stream, and the Vulkan command stream is submitted to the GPU; the GPU executes the shader logic according to the pipeline order, and the atomic components complete the depth processing according to the bound Vulkan depth transformation parameters to obtain a depth rendering result that conforms to the native logic of D3D.
2. The Direct3D depth clipping behavior compatible method according to claim 1, characterized in that, The calculation of Vulkan depth value based on depth range type is specifically as follows: when the depth range type is a normal range, a linear transformation is used to calculate the Vulkan depth value; when it is a large depth range, a logarithmic transformation is used to calculate the Vulkan depth value; and when it is an extremely large depth range, a two-stage transformation consisting of linear and logarithmic transformations is used to calculate the Vulkan depth value.
3. The Direct3D depth clipping behavior compatible method according to claim 2, characterized in that, Get the depth buffer width. If it is a 16-bit depth buffer, calculate the precision compensation factor and use the product of the Vulkan depth value and the precision compensation factor as the new Vulkan depth value. Otherwise, keep the Vulkan depth value unchanged.
4. The Direct3D depth clipping behavior compatible method according to claim 2, characterized in that, The formula for the linear transformation is: vulkan_z = d3d_z * conv_a + conv_b, where vulkan_z is the Vulkan depth value, d3d_z is the D3D depth value, and conv_a and conv_b are transformation coefficients; The formula for the logarithmic transformation is: vulkan_z = log (d3d_z * conv_a + 1.0) * (conv_b / log((d3d_far - d3d_near) * conv_a + 1.0)), where vulkan_z is the Vulkan depth value, d3d_z is the D3D depth value, d3d_far is the depth value of the far clipping plane of the D3D frustum, and d3d_near is the depth value of the near clipping plane of the D3D frustum.
5. The Direct3D depth clipping behavior compatible method according to claim 1, characterized in that, The Vulkan depth comparison operation is flipped when the depth range type is reversed depth.
6. The Direct3D depth clipping behavior compatible method according to claim 1, characterized in that, The Vulkan depth conversion parameters consist of conversion coefficients, clamping threshold, depth range type, accuracy compensation factor, and Vulkan depth comparison operation.
7. The Direct3D depth clipping behavior compatible method according to claim 6, characterized in that, The clamping threshold is calculated using the following formulas: vulkan_near_clamp = (d3d_near + 1.0f) * conv_a, vulkan_far_clamp = (d3d_far + 1.0f) * conv_a, where vulkan_near_clamp is the clamping threshold of the near clipping plane of the frustum, vulkan_far_clamp is the clamping threshold of the far clipping plane of the frustum, d3d_far is the depth value of the far clipping plane of the D3D frustum, d3d_near is the depth value of the near clipping plane of the D3D frustum, and conv_a is the conversion coefficient.
8. The Direct3D depth clipping behavior compatible method according to claim 1, characterized in that, The multi-dimensional depth processing scenario includes D3D version, depth range type, near-plane characteristics, clipping state, depth buffer bit width, vertex processing mode, and dimensions of custom depth markers.
9. The Direct3D depth clipping behavior compatible method according to claim 1, characterized in that, The atomized components include a vertex clipping component, a depth transformation component, a depth clamping component, a reverse depth adaptation component, a custom depth compatibility component, a near-plane precision compensation component, and a vertex processing mode adaptation component; component variants are adapted versions of the atomized components for specific scenario combinations.
Citation Information
Patent Citations
Method for converting Vulkan ray tracing pipeline into calculation pipeline
CN116596738A
Modular volume rendering using visual programming
US20080136817A1