Merge branch 'master' into filter-uuid

This commit is contained in:
meladath 2023-09-01 15:14:36 +01:00 committed by GitHub
commit 8e117058f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
461 changed files with 40061 additions and 54469 deletions

View File

@ -7,14 +7,9 @@ assignees: ''
---
Please describe your issue as accurately as possible. If you run into a problem with a binary release, make sure to test with latest `master` as well.
Please describe your issue as accurately as possible.
**Important:** When reporting an issue with a specific game or application, such as crashes or rendering issues, please include log files and, if possible, a D3D11/D3D9 Apitrace (see https://github.com/apitrace/apitrace) so that the issue can be reproduced.
In order to create a trace for **D3D11/D3D10**: Run `wine apitrace.exe trace -a dxgi YOURGAME.exe`.
In order to create a trace for **D3D9**: Follow https://github.com/doitsujin/dxvk/wiki/Making-a-Trace.
Preferably record the trace on Windows, or wined3d if possible.
**Reports with no log files will be ignored.**
If you use Windows, please check the following page: https://github.com/doitsujin/dxvk/wiki/Windows
### Software information
Name of the game, settings used etc.
@ -28,7 +23,9 @@ Name of the game, settings used etc.
### Apitrace file(s)
- Put a link here
For instructions on how to use apitrace, see: https://github.com/doitsujin/dxvk/wiki/Using-Apitrace
### Log files
- d3d9.log:
- d3d11.log:
- dxgi.log:
Please attach Proton or Wine logs as a text file:
- When using Proton, set the Steam launch options for your game to `PROTON_LOG=1 %command%` and attach the corresponding `steam-xxxxx.log` file in your home directory.
- When using regular Wine, use `wine game.exe > game.log 2>&1` and attach the resulting `game.log` file.

View File

@ -3,23 +3,23 @@ name: Artifacts (Package)
on: [push, pull_request, workflow_dispatch]
jobs:
build-artifacts:
artifacts-mingw-w64:
runs-on: ubuntu-20.04
steps:
- name: Checkout code
id: checkout-code
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
submodules: recursive
fetch-depth: 0
- name: Setup problem matcher
uses: Joshua-Ashton/gcc-problem-matcher@v1
uses: Joshua-Ashton/gcc-problem-matcher@v2
- name: Build release
id: build-release
uses: Joshua-Ashton/arch-mingw-github-action@v7
uses: Joshua-Ashton/arch-mingw-github-action@v8
with:
command: |
export VERSION_NAME="${GITHUB_REF##*/}-${GITHUB_SHA##*/}"
@ -28,8 +28,39 @@ jobs:
- name: Upload artifacts
id: upload-artifacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: dxvk-${{ env.VERSION_NAME }}
path: build/dxvk-${{ env.VERSION_NAME }}
if-no-files-found: error
artifacts-steamrt-sniper:
runs-on: ubuntu-20.04
container: registry.gitlab.steamos.cloud/steamrt/sniper/sdk:beta
steps:
- name: Checkout code
id: checkout-code
uses: actions/checkout@v3
with:
submodules: recursive
fetch-depth: 0
- name: Setup problem matcher
uses: Joshua-Ashton/gcc-problem-matcher@v2
- name: Build release
id: build-release
shell: bash
run: |
export VERSION_NAME="${GITHUB_REF##*/}-${GITHUB_SHA##*/}"
./package-native.sh ${VERSION_NAME} build --no-package
echo "VERSION_NAME=${VERSION_NAME}" >> $GITHUB_ENV
- name: Upload artifacts
id: upload-artifacts
uses: actions/upload-artifact@v3
with:
name: dxvk-${{ env.VERSION_NAME }}
path: build/dxvk-native-${{ env.VERSION_NAME }}
if-no-files-found: error

View File

@ -9,16 +9,15 @@ jobs:
steps:
- name: Checkout code
id: checkout-code
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
submodules: recursive
- name: Setup glslangValidator
shell: pwsh
run: |
choco install vulkan-sdk -y
Write-Output "$([System.Environment]::GetEnvironmentVariable('VULKAN_SDK', 'Machine'))\Bin" `
| Out-File -FilePath "${Env:GITHUB_PATH}" -Append
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HansKristian-Work/vkd3d-proton-ci/main/glslangValidator.exe" -OutFile "glslangValidator.exe"
Write-Output "$pwd" | Out-File -FilePath "${Env:GITHUB_PATH}" -Append
- name: Setup Meson
shell: pwsh

13
.gitmodules vendored Normal file
View File

@ -0,0 +1,13 @@
[submodule "include/native/directx"]
path = include/native/directx
url = https://github.com/Joshua-Ashton/mingw-directx-headers
[submodule "include/vulkan"]
path = include/vulkan
url = https://github.com/KhronosGroup/Vulkan-Headers
[submodule "include/spirv"]
path = include/spirv
url = https://github.com/KhronosGroup/SPIRV-Headers.git
[submodule "subprojects/libdisplay-info"]
path = subprojects/libdisplay-info
url = https://gitlab.freedesktop.org/JoshuaAshton/libdisplay-info.git
branch = windows

View File

@ -1,5 +1,5 @@
Copyright (c) 2017-2021 Philip Rebohle
Copyright (c) 2019-2021 Joshua Ashton
Copyright (c) 2017 Philip Rebohle
Copyright (c) 2019 Joshua Ashton
zlib/libpng license

View File

@ -9,34 +9,45 @@ The most recent development builds can be found [here](https://github.com/doitsu
Release builds can be found [here](https://github.com/doitsujin/dxvk/releases).
## How to use
In order to install a DXVK package obtained from the [release](https://github.com/doitsujin/dxvk/releases) page into a given wine prefix, run the following commands from within the DXVK directory:
In order to install a DXVK package obtained from the [release](https://github.com/doitsujin/dxvk/releases) page into a given wine prefix, copy or symlink the DLLs into the following directories as follows, then open `winecfg` and manually add DLL overrides for `d3d11`, `d3d10core`, `dxgi`, and `d3d9`.
In a default Wine prefix that would be as follows:
```
export WINEPREFIX=/path/to/.wine-prefix
./setup_dxvk.sh install
export WINEPREFIX=/path/to/wineprefix
cp x64/*.dll $WINEPREFIX/drive_c/windows/system32
cp x32/*.dll $WINEPREFIX/drive_c/windows/syswow64
winecfg
```
This will **copy** the DLLs into the `system32` and `syswow64` directories of your wine prefix and set up the required DLL overrides. Pure 32-bit prefixes are also supported.
The setup script optionally takes the following arguments:
- `--symlink`: Create symbolic links to the DLL files instead of copying them. This is especially useful for development.
- `--with-d3d10`: Install the `d3d10{_1}.dll` helper libraries.
- `--without-dxgi`: Do not install DXVK's DXGI implementation and use the one provided by wine instead.
Verify that your application uses DXVK instead of wined3d by checking for the presence of the log file `d3d9.log` or `d3d11.log` in the application's directory, or by enabling the HUD (see notes below).
In order to remove DXVK from a prefix, run the following command:
For a pure 32-bit Wine prefix (non default) the 32-bit DLLs instead go to the `system32` directory:
```
export WINEPREFIX=/path/to/.wine-prefix
./setup_dxvk.sh uninstall
export WINEPREFIX=/path/to/wineprefix
cp x32/*.dll $WINEPREFIX/drive_c/windows/system32
winecfg
```
Verify that your application uses DXVK instead of wined3d by enabling the HUD (see notes below).
In order to remove DXVK from a prefix, remove the DLLs and DLL overrides, and run `wineboot -u` to restore the original DLL files.
Tools such as Steam Play, Lutris, Bottles, Heroic Launcher, etc will automatically handle setup of dxvk on their own when enabled.
### Notes on Vulkan drivers
Before reporting an issue, please check the [Wiki](https://github.com/doitsujin/dxvk/wiki/Driver-support) page on the current driver status and make sure you run a recent enough driver version for your hardware.
## Build instructions
In order to pull in all submodules that are needed for building, clone the repository using the following command:
```
git clone --recursive https://github.com/doitsujin/dxvk.git
```
### Requirements:
- [wine 3.10](https://www.winehq.org/) or newer
- [Meson](https://mesonbuild.com/) build system (at least version 0.46)
- [Mingw-w64](https://www.mingw-w64.org) compiler and headers (at least version 8.0)
- [wine 7.1](https://www.winehq.org/) or newer
- [Meson](https://mesonbuild.com/) build system (at least version 0.49)
- [Mingw-w64](https://www.mingw-w64.org) compiler and headers (at least version 10.0)
- [glslang](https://github.com/KhronosGroup/glslang) compiler
### Building DLLs
@ -60,19 +71,21 @@ ninja install
```
# 64-bit build. For 32-bit builds, replace
# build-win64.txt with build-win32.txt
meson --cross-file build-win64.txt --buildtype release --prefix /your/dxvk/directory build.w64
meson setup --cross-file build-win64.txt --buildtype release --prefix /your/dxvk/directory build.w64
cd build.w64
ninja install
```
The D3D9, D3D10, D3D11 and DXGI DLLs will be located in `/your/dxvk/directory/bin`. Setup has to be done manually in this case.
### Notes on Vulkan drivers
Before reporting an issue, please check the [Wiki](https://github.com/doitsujin/dxvk/wiki/Driver-support) page on the current driver status and make sure you run a recent enough driver version for your hardware.
### Online multi-player games
Manipulation of Direct3D libraries in multi-player games may be considered cheating and can get your account **banned**. This may also apply to single-player games with an embedded or dedicated multiplayer portion. **Use at your own risk.**
### Logs
When used with Wine, DXVK will print log messages to `stderr`. Additionally, standalone log files can optionally be generated by setting the `DXVK_LOG_PATH` variable, where log files in the given directory will be called `app_d3d11.log`, `app_dxgi.log` etc., where `app` is the name of the game executable.
On Windows, log files will be created in the game's working directory by default, which is usually next to the game executable.
### HUD
The `DXVK_HUD` environment variable controls a HUD which can display the framerate and some stat counters. It accepts a comma-separated list of the following options:
- `devinfo`: Displays the name of the GPU and the driver version.
@ -81,6 +94,7 @@ The `DXVK_HUD` environment variable controls a HUD which can display the framera
- `submissions`: Shows the number of command buffers submitted per frame.
- `drawcalls`: Shows the number of draw calls and render passes per frame.
- `pipelines`: Shows the total number of graphics and compute pipelines.
- `descriptors`: Shows the number of descriptor pools and descriptor sets.
- `memory`: Shows the amount of device memory allocated and used.
- `gpuload`: Shows estimated GPU load. May be inaccurate.
- `version`: Shows DXVK version.
@ -89,6 +103,7 @@ The `DXVK_HUD` environment variable controls a HUD which can display the framera
- `compiler`: Shows shader compiler activity
- `samplers`: Shows the current number of sampler pairs used *[D3D9 Only]*
- `scale=x`: Scales the HUD by a factor of `x` (e.g. `1.5`)
- `opacity=y`: Adjusts the HUD opacity by a factor of `y` (e.g. `0.5`, `1.0` being fully opaque).
Additionally, `DXVK_HUD=1` has the same effect as `DXVK_HUD=devinfo,fps`, and `DXVK_HUD=full` enables all available HUD elements.
@ -101,20 +116,34 @@ Some applications do not provide a method to select a different GPU. In that cas
**Note:** If the device filter is configured incorrectly, it may filter out all devices and applications will be unable to create a D3D device.
### Graphics Pipeline Library
On drivers which support `VK_EXT_graphics_pipeline_library` Vulkan shaders will be compiled at the time the game loads its D3D shaders, rather than at draw time. This reduces or eliminates shader compile stutter in many games when compared to the previous system.
In games that load their shaders during loading screens or in the menu, this can lead to prolonged periods of very high CPU utilization, especially on weaker CPUs. For affected games it is recommended to wait for shader compilation to finish before starting the game to avoid stutter and low performance. Shader compiler activity can be monitored with `DXVK_HUD=compiler`.
This feature largely replaces the state cache.
**Note:** Games which only load their D3D shaders at draw time (e.g. most Unreal Engine games) will still exhibit some stutter, although it should still be less severe than without this feature.
### State cache
DXVK caches pipeline state by default, so that shaders can be recompiled ahead of time on subsequent runs of an application, even if the driver's own shader cache got invalidated in the meantime. This cache is enabled by default, and generally reduces stuttering.
The following environment variables can be used to control the cache:
- `DXVK_STATE_CACHE=0` Disables the state cache.
- `DXVK_STATE_CACHE`: Controls the state cache. The following values are supported:
- `disable`: Disables the cache entirely.
- `reset`: Clears the cache file.
- `DXVK_STATE_CACHE_PATH=/some/directory` Specifies a directory where to put the cache files. Defaults to the current working directory of the application.
This feature is mostly only relevant on systems without support for `VK_EXT_graphics_pipeline_library`
### Debugging
The following environment variables can be used for **debugging** purposes.
- `VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation` Enables Vulkan debug layers. Highly recommended for troubleshooting rendering issues and driver crashes. Requires the Vulkan SDK to be installed on the host system.
- `DXVK_LOG_LEVEL=none|error|warn|info|debug` Controls message logging.
- `DXVK_LOG_PATH=/some/directory` Changes path where log files are stored. Set to `none` to disable log file creation entirely, without disabling logging.
- `DXVK_DEBUG=markers|validation` Enables use of the `VK_EXT_debug_utils` extension for translating performance event markers, or to enable Vulkan validation, respecticely.
- `DXVK_CONFIG_FILE=/xxx/dxvk.conf` Sets path to the configuration file.
- `DXVK_PERF_EVENTS=1` Enables use of the VK_EXT_debug_utils extension for translating performance event markers.
- `DXVK_CONFIG="dxgi.hideAmdGpu = True; dxgi.syncInterval = 0"` Can be used to set config variables through the environment instead of a configuration file using the same syntax. `;` is used as a seperator.
## Troubleshooting
DXVK requires threading support from your mingw-w64 build environment. If you

View File

@ -1 +1 @@
1.10.1
2.2

415
VP_DXVK_requirements.json Normal file
View File

@ -0,0 +1,415 @@
{
"$schema": "https://schema.khronos.org/vulkan/profiles-0.8.1-224.json#",
"capabilities": {
"vulkan10requirements": {
"features": {
"VkPhysicalDeviceFeatures": {
"robustBufferAccess": true
}
}
},
"vulkan11requirements": {
"features": {
"VkPhysicalDeviceVulkan11Features": {
"multiview": true
}
},
"properties": {
"VkPhysicalDeviceVulkan11Properties": {
"maxMultiviewViewCount": 6,
"maxMultiviewInstanceIndex": 134217727
}
}
},
"vulkan12requirements": {
"features": {
"VkPhysicalDeviceVulkan12Features": {
"uniformBufferStandardLayout": true,
"subgroupBroadcastDynamicId": true,
"imagelessFramebuffer": true,
"separateDepthStencilLayouts": true,
"hostQueryReset": true,
"timelineSemaphore": true,
"shaderSubgroupExtendedTypes": true
}
},
"properties": {
"VkPhysicalDeviceVulkan12Properties": {
"maxTimelineSemaphoreValueDifference": 2147483647
}
}
},
"vulkan13requirements": {
"features": {
"VkPhysicalDeviceVulkan12Features": {
"vulkanMemoryModel": true,
"vulkanMemoryModelDeviceScope": true,
"bufferDeviceAddress": true
},
"VkPhysicalDeviceVulkan13Features": {
"robustImageAccess": true,
"shaderTerminateInvocation": true,
"shaderZeroInitializeWorkgroupMemory": true,
"synchronization2": true,
"shaderIntegerDotProduct": true,
"maintenance4": true,
"pipelineCreationCacheControl": true,
"subgroupSizeControl": true,
"computeFullSubgroups": true,
"shaderDemoteToHelperInvocation": true,
"inlineUniformBlock": true,
"dynamicRendering": true
}
},
"properties": {
"VkPhysicalDeviceVulkan13Properties": {
"maxBufferSize": 1073741824,
"maxInlineUniformBlockSize": 256,
"maxPerStageDescriptorInlineUniformBlocks": 4,
"maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks": 4,
"maxDescriptorSetInlineUniformBlocks": 4,
"maxDescriptorSetUpdateAfterBindInlineUniformBlocks": 4,
"maxInlineUniformTotalSize": 4
}
}
},
"d3d9_baseline": {
"extensions": {
"VK_EXT_robustness2": 1
},
"features": {
"VkPhysicalDeviceFeatures": {
"geometryShader": true,
"imageCubeArray": true,
"depthClamp": true,
"depthBiasClamp": true,
"fillModeNonSolid": true,
"sampleRateShading": true,
"shaderClipDistance": true,
"shaderCullDistance": true,
"textureCompressionBC": true,
"occlusionQueryPrecise": true,
"independentBlend": true,
"fullDrawIndexUint32": true,
"shaderImageGatherExtended": true
},
"VkPhysicalDeviceVulkan12Features": {
"samplerMirrorClampToEdge": true
},
"VkPhysicalDeviceRobustness2FeaturesEXT": {
"nullDescriptor": true,
"robustBufferAccess2": true
}
}
},
"d3d9_optional": {
"extensions": {
"VK_EXT_memory_priority": 1,
"VK_EXT_vertex_attribute_divisor": 1,
"VK_EXT_depth_clip_enable": 1,
"VK_EXT_custom_border_color": 1,
"VK_EXT_attachment_feedback_loop_layout": 1,
"VK_EXT_non_seamless_cube_map": 1
},
"features": {
"VkPhysicalDeviceFeatures": {
"depthBounds": true,
"vertexPipelineStoresAndAtomics": true,
"pipelineStatisticsQuery": true,
"samplerAnisotropy": true
},
"VkPhysicalDeviceMemoryPriorityFeaturesEXT": {
"memoryPriority": true
},
"VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT": {
"vertexAttributeInstanceRateDivisor": true,
"vertexAttributeInstanceRateZeroDivisor": true
},
"VkPhysicalDeviceDepthClipEnableFeaturesEXT": {
"depthClipEnable": true
},
"VkPhysicalDeviceCustomBorderColorFeaturesEXT": {
"customBorderColors": true,
"customBorderColorWithoutFormat": true
},
"VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT": {
"attachmentFeedbackLoopLayout": true
},
"VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT": {
"nonSeamlessCubeMap": true
}
}
},
"d3d11_baseline": {
"extensions": {
"VK_EXT_robustness2": 1,
"VK_EXT_transform_feedback": 1
},
"features": {
"VkPhysicalDeviceFeatures": {
"depthBiasClamp": true,
"depthClamp": true,
"dualSrcBlend": true,
"fillModeNonSolid": true,
"fullDrawIndexUint32": true,
"geometryShader": true,
"imageCubeArray": true,
"independentBlend": true,
"multiViewport": true,
"occlusionQueryPrecise": true,
"sampleRateShading": true,
"shaderClipDistance": true,
"shaderCullDistance": true,
"shaderImageGatherExtended": true,
"textureCompressionBC": true
},
"VkPhysicalDeviceVulkan11Features": {
"shaderDrawParameters": true
},
"VkPhysicalDeviceVulkan12Features": {
"samplerMirrorClampToEdge": true
},
"VkPhysicalDeviceRobustness2FeaturesEXT": {
"nullDescriptor": true,
"robustBufferAccess2": true
},
"VkPhysicalDeviceTransformFeedbackFeaturesEXT": {
"transformFeedback": true,
"geometryStreams": true
}
}
},
"d3d11_baseline_optional":{
"extensions": {
"VK_EXT_memory_priority": 1,
"VK_EXT_vertex_attribute_divisor": 1,
"VK_EXT_custom_border_color": 1,
"VK_EXT_depth_clip_enable": 1,
"VK_EXT_swapchain_colorspace": 1,
"VK_EXT_hdr_metadata": 1
},
"features": {
"VkPhysicalDeviceFeatures": {
"depthBounds": true,
"pipelineStatisticsQuery": true,
"logicOp": true,
"samplerAnisotropy": true
},
"VkPhysicalDeviceMemoryPriorityFeaturesEXT": {
"memoryPriority": true
},
"VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT": {
"vertexAttributeInstanceRateDivisor": true,
"vertexAttributeInstanceRateZeroDivisor": true
},
"VkPhysicalDeviceCustomBorderColorFeaturesEXT": {
"customBorderColors": true,
"customBorderColorWithoutFormat": true
},
"VkPhysicalDeviceDepthClipEnableFeaturesEXT": {
"depthClipEnable": true
}
}
},
"d3d11_level11_0": {
"features": {
"VkPhysicalDeviceFeatures": {
"drawIndirectFirstInstance": true,
"fragmentStoresAndAtomics": true,
"multiDrawIndirect": true,
"tessellationShader": true
}
}
},
"d3d11_level11_0_optional": {
"features": {
"VkPhysicalDeviceFeatures": {
"shaderFloat64": true,
"shaderInt64": true
}
}
},
"d3d11_level11_1": {
"features": {
"VkPhysicalDeviceFeatures": {
"logicOp": true,
"vertexPipelineStoresAndAtomics": true
}
}
},
"d3d11_level12_0": {
"features": {
"VkPhysicalDeviceFeatures": {
"shaderResourceResidency": true,
"shaderResourceMinLod": true,
"sparseBinding": true,
"sparseResidencyBuffer": true,
"sparseResidencyAliased": true,
"sparseResidencyImage2D": true
},
"VkPhysicalDeviceVulkan12Features": {
"samplerFilterMinmax": true
}
},
"properties": {
"VkPhysicalDeviceProperties": {
"sparseProperties": {
"residencyStandard2DBlockShape": true,
"residencyAlignedMipSize": false,
"residencyNonResidentStrict": true
}
}
}
}
},
"profiles": {
"VP_DXVK_d3d9_baseline": {
"version": 1,
"api-version": "1.3.204",
"label": "DXVK D3D9 Baseline profile",
"description": "DXVK for D3D9 minimum requirements",
"capabilities": [
"vulkan10requirements",
"vulkan11requirements",
"vulkan12requirements",
"vulkan13requirements",
"d3d9_baseline"
]
},
"VP_DXVK_d3d9_optimal": {
"version": 1,
"api-version": "1.3.224",
"label": "DXVK D3D9 Optimal profile",
"description": "DXVK for D3D9 including optional capabilities",
"capabilities": [
"vulkan10requirements",
"vulkan11requirements",
"vulkan12requirements",
"vulkan13requirements",
"d3d9_baseline",
"d3d9_optional"
]
},
"VP_DXVK_d3d10_level_10_1_baseline": {
"version": 1,
"api-version": "1.3.204",
"label": "DXVK D3D10 Level 10.1 Baseline profile",
"description": "DXVK for D3D10 Feature Level 10.1 minimum requirements",
"capabilities": [
"vulkan10requirements",
"vulkan11requirements",
"vulkan12requirements",
"vulkan13requirements",
"d3d11_baseline"
]
},
"VP_DXVK_d3d11_level_11_0_baseline": {
"version": 1,
"api-version": "1.3.204",
"label": "DXVK D3D11 Level 11.0 Baseline profile",
"description": "DXVK for D3D11 Feature Level 11.0 minimum requirements",
"capabilities": [
"vulkan10requirements",
"vulkan11requirements",
"vulkan12requirements",
"vulkan13requirements",
"d3d11_baseline",
"d3d11_level11_0"
]
},
"VP_DXVK_d3d11_level_11_1_baseline": {
"version": 1,
"api-version": "1.3.204",
"label": "DXVK D3D11 Level 11.1 Baseline profile",
"description": "DXVK for D3D11 Feature Level 11.1 minimum requirements",
"capabilities": [
"vulkan10requirements",
"vulkan11requirements",
"vulkan12requirements",
"vulkan13requirements",
"d3d11_baseline",
"d3d11_level11_0",
"d3d11_level11_1"
]
},
"VP_DXVK_d3d11_level_11_1_optimal": {
"version": 1,
"api-version": "1.3.204",
"label": "DXVK D3D11 Level 11.1 Optimal profile",
"description": "DXVK for D3D11 Feature Level 11.1 including optional capabilities",
"capabilities": [
"vulkan10requirements",
"vulkan11requirements",
"vulkan12requirements",
"vulkan13requirements",
"d3d11_baseline",
"d3d11_baseline_optional",
"d3d11_level11_0",
"d3d11_level11_0_optional",
"d3d11_level11_1"
]
},
"VP_DXVK_d3d11_level_12_0_optimal": {
"version": 1,
"api-version": "1.3.204",
"label": "DXVK D3D11 Level 12.0 Optimal profile",
"description": "DXVK for D3D11 Feature Level 12.0 including optional capabilities",
"capabilities": [
"vulkan10requirements",
"vulkan11requirements",
"vulkan12requirements",
"vulkan13requirements",
"d3d11_baseline",
"d3d11_baseline_optional",
"d3d11_level11_0",
"d3d11_level11_0_optional",
"d3d11_level11_1",
"d3d11_level12_0"
]
}
},
"contributors": {
"Philip Rebohle": {
"company": "Valve"
},
"Joshua Ashton": {
"company": "Valve"
},
"Pierre-Loup A. Griffais": {
"company": "Valve"
},
"Georg Lehmann": {
"company": "DXVK"
},
"Christophe Riccio": {
"company": "LunarG"
}
},
"history": [
{
"revision": 4,
"date": "2022-12-18",
"author": "Joshua Ashton",
"comment": "Add VK_EXT_swapchain_colorspace and VK_EXT_hdr_metadata to d3d11_baseline_optional"
},
{
"revision": 3,
"date": "2022-10-13",
"author": "Christophe Riccio",
"comment": "Factorize history and contributors sections using schema 0.8.1"
},
{
"revision": 2,
"date": "2022-08-30",
"author": "Philip Rebohle",
"comment": "Add VP_DXVK_d3d11_level_12_0_optimal profile"
},
{
"revision": 1,
"date": "2022-08-22",
"author": "Christophe Riccio",
"comment": "Initial revision"
}
]
}

240
dxvk.conf
View File

@ -1,3 +1,15 @@
# Expose the HDR10 ColorSpace (DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020)
# to the application by default.
# This shows to the game that the global Windows 'HDR Mode' is enabled.
# Many (broken) games will need this to be set to consider exposing HDR output
# as determine it based on the DXGIOutput's current ColorSpace instead of
# using CheckColorSpaceSupport.
# This defaults to the value of the DXVK_HDR environment variable.
#
# Supported values: True, False
# dxgi.enableHDR = True
# Create the VkSurface on the first call to IDXGISwapChain::Present,
# rather than when creating the swap chain. Some games that start
# rendering with a different graphics API may require this option,
@ -19,9 +31,10 @@
# d3d9.maxFrameLatency = 0
# Enables a frame rate limiter, unless the game is already
# limited to the same refresh rate by vertical synchronization.
#
# Enables frame rate limiter. The main purpose of this is to work around
# bugs in games that have physics or other simulation tied to their frame
# rate, but do not provide their own limiter.
#
# Supported values : Any non-negative integer
# dxgi.maxFrameRate = 0
@ -48,14 +61,31 @@
# d3d9.customDeviceDesc = ""
# Report Nvidia GPUs as AMD GPUs by default. This is enabled by default
# to work around issues with NVAPI, but may cause issues in some games.
# Report Nvidia GPUs as AMD GPUs. Unless NVAPI support is explicitly
# enabled through proton, this is done by default in order to work
# around crashes or low performance with Nvidia-speciic code paths
# in games, especially Unreal Engine.
#
# Supported values: True, False
# Supported values: Auto, True, False
# dxgi.nvapiHack = True
# dxgi.hideNvidiaGpu = Auto
# Report AMD GPUs as Nvidia GPUs. This is only done for games that are
# known to have issues with AMDAGS or other AMD-specific code paths.
#
# Supported values: Auto, True, False
# dxgi.hideAmdGpu = Auto
# Report Intel GPUs as AMD GPUs. This is only done for games that are
# known to have issues with Intel-specific libraries such as XESS.
#
# Supported values: Auto, True, False
# dxgi.hideIntelGpu = Auto
# Override maximum amount of device memory and shared system memory
# reported to the application. This may fix texture streaming issues
@ -109,17 +139,7 @@
#
# Supported values: Auto, True, False
# dxgi.tearFree = Auto
# d3d9.tearFree = Auto
# Performs range check on dynamically indexed constant buffers in shaders.
# This may be needed to work around a certain type of game bug, but may
# also introduce incorrect behaviour.
#
# Supported values: True, False
# d3d11.constantBufferRangeCheck = False
# dxvk.tearFree = Auto
# Assume single-use mode for command lists created on deferred contexts.
@ -135,9 +155,9 @@
# with. Setting this to a higher value may allow some applications to run
# that would otherwise fail to create a D3D11 device.
#
# Supported values: 9_1, 9_2, 9_3, 10_0, 10_1, 11_0, 11_1
# Supported values: 9_1, 9_2, 9_3, 10_0, 10_1, 11_0, 11_1, 12_0, 12_1
# d3d11.maxFeatureLevel = 11_1
# d3d11.maxFeatureLevel = 12_1
# Overrides the maximum allowed tessellation factor. This can be used to
@ -178,6 +198,26 @@
# d3d9.samplerAnisotropy = -1
# Changes the mipmap LOD bias for all samplers. The given number will be
# added to the LOD bias provided by the application, rather than replacing
# it entirely. Positive values will reduce texture detail, while negative
# values may increase sharpness at the cost of shimmer.
#
# Supported values: Any number between -2.0 and 1.0
# d3d11.samplerLodBias = 0.0
# d3d9.samplerLodBias = 0.0
# Clamps any negative LOD bias to 0. Applies after samplerLodBias has been
# applied. May help with games that use a high negative LOD bias by default.
#
# Supported values: True, False
# d3d11.clampNegativeLodBias = False
# d3d9.clampNegativeLodBias = False
# Declares vertex positions as invariant in order to solve
# potential Z-fighting issues at a small performance cost.
#
@ -187,6 +227,16 @@
# d3d9.invariantPosition = True
# Forces per-sample rate shading when MSAA is enabled, rather than per-pixel
# shading. May improve visual clarity at a significant performance cost, but
# may also introduce visual issues in some games.
#
# Supported values: True, False
# d3d11.forceSampleRateShading = False
# d3d9.forceSampleRateShading = False
# Forces the sample count of all textures to 1, and performs
# the needed fixups in resolve operations and shaders.
#
@ -234,10 +284,22 @@
# d3d11.cachedDynamicResources = ""
# Force-enables the D3D11 context lock via the ID3D10Multithread
# interface. This may be useful to debug race conditions.
#
# Supported values: True, False
# d3d11.enableContextLock = False
# Sets number of pipeline compiler threads.
#
# If the graphics pipeline library feature is enabled, the given
# number of threads will be used for shader compilation. Some of
# these threads will be reserved for high-priority work.
#
# Supported values:
# - 0 to automatically determine the number of threads to use
# - 0 to use all available CPU cores
# - any positive number to enforce the thread count
# dxvk.numCompilerThreads = 0
@ -258,18 +320,43 @@
# dxvk.useRawSsbo = Auto
# Controls Nvidia HVV behaviour.
# Changes memory chunk size.
#
# Disables the host-visible, device-local heap on Nvidia drivers. This
# is used to avoid NVIDIA driver bug 3114283 on affected drivers, as
# well as in specific games on newer drivers.being enabled on all
# affected drivers.
# Can be used to override the maximum memory chunk size.
#
# Supported values:
# - Auto: Don't change the default
# - True, False: Always enable / disable
# - 0 to use the defaults
# - any positive integer to limit the chunk size, in MiB
# dxvk.shrinkNvidiaHvvHeap = Auto
# dxvk.maxChunkSize = 0
# Controls graphics pipeline library behaviour
#
# Can be used to change VK_EXT_graphics_pipeline_library usage for
# debugging purpose. Doing so will likely result in increased stutter
# or degraded performance.
#
# Supported values:
# - Auto: Enable if supported, and compile optimized pipelines in the background
# - True: Enable if supported, but do not compile optimized pipelines
# - False: Always disable the feature
# dxvk.enableGraphicsPipelineLibrary = Auto
# Controls pipeline lifetime tracking
#
# If enabled, pipeline libraries will be freed aggressively in order
# save memory and address space. Has no effect if graphics pipeline
# libraries are not supported or disabled.
#
# Supported values:
# - Auto: Enable tracking for 32-bit applications only
# - True: Always enable tracking
# - False: Always disable tracking
# dxvk.trackPipelineLifetime = Auto
# Sets enabled HUD elements
@ -294,17 +381,6 @@
# d3d9.shaderModel = 3
# Evict Managed on Unlock
#
# Decides whether we should evict managed resources from
# system memory when they are unlocked entirely.
#
# Supported values:
# - True, False: Always enable / disable
# d3d9.evictManagedOnUnlock = False
# DPI Awareness
#
# Decides whether we should call SetProcessDPIAware on device
@ -405,16 +481,6 @@
# d3d9.longMad = False
# Alpha Test Wiggle Room
#
# Workaround for games using alpha test == 1.0, etc due to wonky interpolation or
# misc. imprecision on some vendors
#
# Supported values:
# - True/False
# d3d9.alphaTestWiggleRoom = False
# Device Local Constant Buffers
#
# Enables using device local, host accessible memory for constant buffers in D3D9.
@ -426,15 +492,6 @@
# d3d9.deviceLocalConstantBuffers = False
# No Explicit Front Buffer
#
# Disables the front buffer
#
# Supported values:
# - True/False
# d3d9.noExplicitFrontBuffer = False
# Support DF formats
#
# Support the vendor extension DF floating point depth formats
@ -444,10 +501,19 @@
# d3d9.supportDFFormats = True
# Use D32f for D24
#
# Useful for reproducing AMD issues on other hw.
#
# Supported values:
# - True/False
# d3d9.useD32forD24 = False
# Support X4R4G4B4
#
# Support the X4R4G4B4 format.
# The Sims 2 is a horrible game made by complete morons.
# The Sims 2 is a very broken game.
#
# Supported values:
# - True/False
@ -466,7 +532,7 @@
# Disable A8 as a Render Target
#
# Disable support for A8 format render targets
# Once again, The Sims 2 is a horrible game made by complete morons.
# Once again, The Sims 2 is a very broken game.
#
# Supported values:
# - True/False
@ -506,26 +572,6 @@
# d3d9.forceAspectRatio = ""
# Allow Do Not Wait
#
# Allow the do not wait lock flag to be used
# Useful if some apps use this incorrectly.
#
# Supported values:
# - True/False
# d3d9.allowDoNotWait = True
# Allow Discard
#
# Allow the discard lock flag to be used
# Useful if some apps use this incorrectly.
#
# Supported values:
# - True/False
# d3d9.allowDiscard = True
# Enumerate by Displays
#
# Whether we should enumerate D3D9 adapters by display (windows behaviour)
@ -537,23 +583,43 @@
# d3d9.enumerateByDisplays = True
# APITrace Mode
# Cached Dynamic Buffers
#
# Makes all host visible buffers cached and coherent
# Improves performance when apitracing, but also can impact
# some dumb games.
# Allocates dynamic resources in D3DPOOL_DEFAULT in
# cached system memory rather than uncached memory or host-visible
# VRAM, in order to allow fast readback from the CPU. This is only
# useful for buggy applications, and may reduce GPU-bound performance.
#
# Supported values:
# - True/False
# d3d9.apitraceMode = False
# d3d9.cachedDynamicBuffers = False
# Seamless Cubes
#
# Don't use non seamless cube maps even if they are supported.
# Non seamless cubes are correct d3d9 behavior, but can produce worse looking edges.
#
# Supported values:
# - True/False
# d3d9.seamlessCubes = False
# Debug Utils
#
# Enables debug utils as this is off by default, this enables user annotations like BeginEvent()/EndEvent().
# Alternatively could be enabled with DXVK_PERF_EVENTS=1 environment variable.
# Alternatively could be enabled with DXVK_DEBUG=markers environment variable.
#
# Supported values:
# - True/False
# dxvk.enableDebugUtils = False
# Memory limit for locked D3D9 textures
#
# How much virtual memory will be used for textures (in MB).
# 0 to disable the limit.
# THIS DOES NOT IMPACT ACTUAL MEMORY CONSUMPTION OR TEXTURE QUALITY.
# DO NOT CHANGE THIS UNLESS YOU HAVE A VERY GOOD REASON.
# d3d9.textureMemory = 100

@ -0,0 +1 @@
Subproject commit 9df86f2341616ef1888ae59919feaa6d4fad693d

View File

@ -0,0 +1,3 @@
#pragma once
// Don't care.

View File

@ -0,0 +1,3 @@
#pragma once
// Don't care.

View File

@ -0,0 +1,3 @@
#pragma once
// Don't care.

View File

@ -0,0 +1,3 @@
#pragma once
// Don't care.

View File

@ -0,0 +1,8 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the mingw-w64 runtime package.
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
#if !(defined(lint) || defined(RC_INVOKED))
#pragma pack(pop)
#endif

View File

@ -0,0 +1,8 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the mingw-w64 runtime package.
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
#if !(defined(lint) || defined(RC_INVOKED))
#pragma pack(push,4)
#endif

View File

@ -0,0 +1,3 @@
#pragma once
// Don't care.

View File

@ -0,0 +1,3 @@
#pragma once
// Don't care.

View File

@ -0,0 +1,52 @@
#pragma once
#include "windows_base.h"
typedef interface IUnknown IUnknown;
DEFINE_GUID(IID_IUnknown, 0x00000000,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46)
#ifdef __cplusplus
struct IUnknown {
public:
virtual HRESULT QueryInterface(REFIID riid, void** ppvObject) = 0;
template<class Q>
HRESULT STDMETHODCALLTYPE QueryInterface(Q **pp) {
return QueryInterface(__uuidof(Q), (void **)pp);
}
virtual ULONG AddRef() = 0;
virtual ULONG Release() = 0;
};
#else
typedef struct IUnknownVtbl
{
BEGIN_INTERFACE
HRESULT (STDMETHODCALLTYPE *QueryInterface)(
IUnknown *This,
REFIID riid,
void **ppvObject
);
ULONG (STDMETHODCALLTYPE *AddRef)(IUnknown *This);
ULONG (STDMETHODCALLTYPE *Release)(IUnknown *This);
END_INTERFACE
} IUnknownVtbl;
interface IUnknown
{
CONST_VTBL struct IUnknownVtbl *lpVtbl;
};
#define IUnknown_AddRef(This) ((This)->lpVtbl->AddRef(This))
#define IUnknown_Release(This) ((This)->lpVtbl->Release(This))
#endif // __cplusplus
DECLARE_UUIDOF_HELPER(IUnknown, 0x00000000,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46)
#define IID_PPV_ARGS(ppType) __uuidof(decltype(**(ppType))), [](auto** pp) { (void)static_cast<IUnknown*>(*pp); return reinterpret_cast<void**>(pp); }(ppType)

View File

@ -0,0 +1,4 @@
#pragma once
#include "windows_base.h"
#include "unknwn.h"

View File

@ -0,0 +1,386 @@
#pragma once
#ifdef __cplusplus
#include <cstdint>
#include <cstring>
#else
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#endif // __cplusplus
// GCC complains about the COM interfaces
// not having virtual destructors
// and class conversion for C...DESC helper types
#if defined(__GNUC__) && defined(__cplusplus)
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#pragma GCC diagnostic ignored "-Wclass-conversion"
#endif // __GNUC__ && __cplusplus
typedef int32_t INT;
typedef uint32_t UINT;
typedef int32_t LONG;
typedef uint32_t ULONG;
typedef int32_t *LPLONG;
typedef int32_t HRESULT;
typedef wchar_t WCHAR;
typedef WCHAR *NWPSTR, *LPWSTR, *PWSTR;
typedef unsigned char UCHAR, *PUCHAR;
typedef char CHAR;
typedef const CHAR *LPCSTR, *PCSTR;
typedef INT BOOL;
typedef BOOL WINBOOL;
typedef uint16_t UINT16;
typedef uint32_t UINT32;
typedef uint64_t UINT64;
typedef void VOID;
typedef void* PVOID;
typedef void* LPVOID;
typedef const void* LPCVOID;
typedef size_t SIZE_T;
typedef int8_t INT8;
typedef uint8_t UINT8;
typedef uint8_t BYTE;
typedef int16_t SHORT;
typedef uint16_t USHORT;
typedef int64_t LONGLONG;
typedef uint64_t ULONGLONG;
typedef intptr_t LONG_PTR;
typedef float FLOAT;
#ifndef GUID_DEFINED
#define GUID_DEFINED
typedef struct GUID {
uint32_t Data1;
uint16_t Data2;
uint16_t Data3;
uint8_t Data4[8];
} GUID;
#endif // GUID_DEFINED
typedef GUID UUID;
typedef GUID IID;
#ifdef __cplusplus
#define REFIID const IID&
#define REFGUID const GUID&
#define REFCLSID const GUID&
#else
#define REFIID const IID*
#define REFGUID const GUID*
#define REFCLSID const GUID* const
#endif // __cplusplus
#ifdef __cplusplus
template <typename T>
constexpr GUID __uuidof_helper();
#define __uuidof(T) __uuidof_helper<T>()
#define __uuidof_var(T) __uuidof_helper<decltype(T)>()
inline bool operator==(const GUID& a, const GUID& b) { return std::memcmp(&a, &b, sizeof(GUID)) == 0; }
inline bool operator!=(const GUID& a, const GUID& b) { return std::memcmp(&a, &b, sizeof(GUID)) != 0; }
#endif // __cplusplus
typedef uint32_t DWORD;
typedef uint16_t WORD;
typedef DWORD *LPDWORD;
typedef void* HANDLE;
typedef HANDLE HMONITOR;
typedef HANDLE HDC;
typedef HANDLE HMODULE;
typedef HANDLE HINSTANCE;
typedef HANDLE HWND;
typedef HANDLE HKEY;
typedef HANDLE *LPHANDLE;
typedef DWORD COLORREF;
#if INTPTR_MAX == INT64_MAX
typedef int64_t INT_PTR;
typedef uint64_t UINT_PTR;
#else
typedef int32_t INT_PTR;
typedef uint32_t UINT_PTR;
#endif
typedef INT_PTR* PINT_PTR;
typedef UINT_PTR* PUINT_PTR;
#ifdef STRICT
#define DECLARE_HANDLE(a) typedef struct a##__ { int unused; } *a
#else /*STRICT*/
#define DECLARE_HANDLE(a) typedef HANDLE a
#endif /*STRICT*/
typedef char* LPSTR;
typedef wchar_t* LPWSTR;
typedef const char* LPCSTR;
typedef const wchar_t* LPCWSTR;
typedef struct LUID {
DWORD LowPart;
LONG HighPart;
} LUID;
typedef struct POINT {
LONG x;
LONG y;
} POINT;
typedef POINT* LPPOINT;
typedef struct RECT {
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT,*PRECT,*NPRECT,*LPRECT;
typedef struct SIZE {
LONG cx;
LONG cy;
} SIZE,*PSIZE,*LPSIZE;
typedef union {
struct {
DWORD LowPart;
LONG HighPart;
};
struct {
DWORD LowPart;
LONG HighPart;
} u;
LONGLONG QuadPart;
} LARGE_INTEGER;
typedef struct MEMORYSTATUS {
DWORD dwLength;
SIZE_T dwTotalPhys;
} MEMORYSTATUS;
typedef struct SECURITY_ATTRIBUTES {
DWORD nLength;
void* lpSecurityDescriptor;
BOOL bInheritHandle;
} SECURITY_ATTRIBUTES;
typedef struct PALETTEENTRY {
BYTE peRed;
BYTE peGreen;
BYTE peBlue;
BYTE peFlags;
} PALETTEENTRY, *PPALETTEENTRY, *LPPALETTEENTRY;
typedef struct RGNDATAHEADER {
DWORD dwSize;
DWORD iType;
DWORD nCount;
DWORD nRgnSize;
RECT rcBound;
} RGNDATAHEADER;
typedef struct RGNDATA {
RGNDATAHEADER rdh;
char Buffer[1];
} RGNDATA,*PRGNDATA,*NPRGNDATA,*LPRGNDATA;
// Ignore these.
#define STDMETHODCALLTYPE
#define __stdcall
#define CONST const
#define CONST_VTBL const
#define TRUE 1
#define FALSE 0
#define WAIT_TIMEOUT 0x00000102
#define WAIT_FAILED 0xffffffff
#define WAIT_OBJECT_0 0
#define WAIT_ABANDONED 0x00000080
#define interface struct
#define MIDL_INTERFACE(x) struct
#ifdef __cplusplus
#define DEFINE_GUID(iid, a, b, c, d, e, f, g, h, i, j, k) \
constexpr GUID iid = {a,b,c,{d,e,f,g,h,i,j,k}};
#define DECLARE_UUIDOF_HELPER(type, a, b, c, d, e, f, g, h, i, j, k) \
extern "C++" { template <> constexpr GUID __uuidof_helper<type>() { return GUID{a,b,c,{d,e,f,g,h,i,j,k}}; } } \
extern "C++" { template <> constexpr GUID __uuidof_helper<type*>() { return __uuidof_helper<type>(); } } \
extern "C++" { template <> constexpr GUID __uuidof_helper<const type*>() { return __uuidof_helper<type>(); } } \
extern "C++" { template <> constexpr GUID __uuidof_helper<type&>() { return __uuidof_helper<type>(); } } \
extern "C++" { template <> constexpr GUID __uuidof_helper<const type&>() { return __uuidof_helper<type>(); } }
#else
#define DEFINE_GUID(iid, a, b, c, d, e, f, g, h, i, j, k) \
static const GUID iid = {a,b,c,{d,e,f,g,h,i,j,k}};
#define DECLARE_UUIDOF_HELPER(type, a, b, c, d, e, f, g, h, i, j, k)
#endif // __cplusplus
#define __CRT_UUID_DECL(type, a, b, c, d, e, f, g, h, i, j, k) DECLARE_UUIDOF_HELPER(type, a, b, c, d, e, f, g, h, i, j, k)
#define S_OK 0
#define S_FALSE 1
#define E_INVALIDARG ((HRESULT)0x80070057)
#define E_FAIL ((HRESULT)0x80004005)
#define E_NOINTERFACE ((HRESULT)0x80004002)
#define E_NOTIMPL ((HRESULT)0x80004001)
#define E_OUTOFMEMORY ((HRESULT)0x8007000E)
#define E_POINTER ((HRESULT)0x80004003)
#define DXGI_STATUS_OCCLUDED ((HRESULT)0x087a0001)
#define DXGI_STATUS_CLIPPED ((HRESULT)0x087a0002)
#define DXGI_STATUS_NO_REDIRECTION ((HRESULT)0x087a0004)
#define DXGI_STATUS_NO_DESKTOP_ACCESS ((HRESULT)0x087a0005)
#define DXGI_STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE ((HRESULT)0x087a0006)
#define DXGI_STATUS_MODE_CHANGED ((HRESULT)0x087a0007)
#define DXGI_STATUS_MODE_CHANGE_IN_PROGRESS ((HRESULT)0x087a0008)
#define DXGI_STATUS_UNOCCLUDED ((HRESULT)0x087a0009)
#define DXGI_STATUS_DDA_WAS_STILL_DRAWING ((HRESULT)0x087a000a)
#define DXGI_STATUS_PRESENT_REQUIRED ((HRESULT)0x087a002f)
#define DXGI_ERROR_INVALID_CALL ((HRESULT)0x887A0001)
#define DXGI_ERROR_NOT_FOUND ((HRESULT)0x887A0002)
#define DXGI_ERROR_MORE_DATA ((HRESULT)0x887A0003)
#define DXGI_ERROR_UNSUPPORTED ((HRESULT)0x887A0004)
#define DXGI_ERROR_DEVICE_REMOVED ((HRESULT)0x887A0005)
#define DXGI_ERROR_DEVICE_HUNG ((HRESULT)0x887A0006)
#define DXGI_ERROR_DEVICE_RESET ((HRESULT)0x887A0007)
#define DXGI_ERROR_WAS_STILL_DRAWING ((HRESULT)0x887A000A)
#define DXGI_ERROR_FRAME_STATISTICS_DISJOINT ((HRESULT)0x887A000B)
#define DXGI_ERROR_GRAPHICS_VIDPN_SOURCE_IN_USE ((HRESULT)0x887A000C)
#define DXGI_ERROR_DRIVER_INTERNAL_ERROR ((HRESULT)0x887A0020)
#define DXGI_ERROR_NONEXCLUSIVE ((HRESULT)0x887A0021)
#define DXGI_ERROR_NOT_CURRENTLY_AVAILABLE ((HRESULT)0x887A0022)
#define DXGI_ERROR_REMOTE_CLIENT_DISCONNECTED ((HRESULT)0x887A0023)
#define DXGI_ERROR_REMOTE_OUTOFMEMORY ((HRESULT)0x887A0024)
#define DXGI_ERROR_ACCESS_LOST ((HRESULT)0x887A0026)
#define DXGI_ERROR_WAIT_TIMEOUT ((HRESULT)0x887A0027)
#define DXGI_ERROR_SESSION_DISCONNECTED ((HRESULT)0x887A0028)
#define DXGI_ERROR_RESTRICT_TO_OUTPUT_STALE ((HRESULT)0x887A0029)
#define DXGI_ERROR_CANNOT_PROTECT_CONTENT ((HRESULT)0x887A002A)
#define DXGI_ERROR_ACCESS_DENIED ((HRESULT)0x887A002B)
#define DXGI_ERROR_NAME_ALREADY_EXISTS ((HRESULT)0x887A002C)
#define DXGI_ERROR_SDK_COMPONENT_MISSING ((HRESULT)0x887A002D)
#define WINAPI
#define WINUSERAPI
#define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
#define MAKE_HRESULT(sev,fac,code) \
((HRESULT) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) )
#ifdef __cplusplus
#define STDMETHOD(name) virtual HRESULT name
#define STDMETHOD_(type, name) virtual type name
#else
#define STDMETHOD(name) HRESULT (STDMETHODCALLTYPE *name)
#define STDMETHOD_(type, name) type (STDMETHODCALLTYPE *name)
#endif // __cplusplus
#define THIS_
#define THIS
#define __C89_NAMELESSSTRUCTNAME
#define __C89_NAMELESSUNIONNAME
#define __C89_NAMELESSUNIONNAME1
#define __C89_NAMELESSUNIONNAME2
#define __C89_NAMELESSUNIONNAME3
#define __C89_NAMELESSUNIONNAME4
#define __C89_NAMELESSUNIONNAME5
#define __C89_NAMELESSUNIONNAME6
#define __C89_NAMELESSUNIONNAME7
#define __C89_NAMELESSUNIONNAME8
#define __C89_NAMELESS
#define DUMMYUNIONNAME
#define DUMMYSTRUCTNAME
#define DUMMYUNIONNAME1
#define DUMMYUNIONNAME2
#define DUMMYUNIONNAME3
#define DUMMYUNIONNAME4
#define DUMMYUNIONNAME5
#define DUMMYUNIONNAME6
#define DUMMYUNIONNAME7
#define DUMMYUNIONNAME8
#define DUMMYUNIONNAME9
#ifdef __cplusplus
#define DECLARE_INTERFACE(x) struct x
#define DECLARE_INTERFACE_(x, y) struct x : public y
#else
#define DECLARE_INTERFACE(x) \
typedef interface x { \
const struct x##Vtbl *lpVtbl; \
} x; \
typedef const struct x##Vtbl x##Vtbl; \
const struct x##Vtbl
#define DECLARE_INTERFACE_(x, y) DECLARE_INTERFACE(x)
#endif // __cplusplus
#define BEGIN_INTERFACE
#define END_INTERFACE
#ifdef __cplusplus
#define PURE = 0
#else
#define PURE
#endif // __cplusplus
#define DECLSPEC_SELECTANY
#define __MSABI_LONG(x) x
#define ENUM_CURRENT_SETTINGS ((DWORD)-1)
#define ENUM_REGISTRY_SETTINGS ((DWORD)-2)
#define INVALID_HANDLE_VALUE ((HANDLE)-1)
#define DUPLICATE_CLOSE_SOURCE ((DWORD)0x1)
#define DUPLICATE_SAME_ACCESS ((DWORD)0x2)
#define FAILED(hr) ((HRESULT)(hr) < 0)
#define SUCCEEDED(hr) ((HRESULT)(hr) >= 0)
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
#define ZeroMemory RtlZeroMemory
#ifndef DEFINE_ENUM_FLAG_OPERATORS
#ifdef __cplusplus
# define DEFINE_ENUM_FLAG_OPERATORS(type) \
extern "C++" \
{ \
inline type operator &(type x, type y) { return (type)((int)x & (int)y); } \
inline type operator &=(type &x, type y) { return (type &)((int &)x &= (int)y); } \
inline type operator ~(type x) { return (type)~(int)x; } \
inline type operator |(type x, type y) { return (type)((int)x | (int)y); } \
inline type operator |=(type &x, type y) { return (type &)((int &)x |= (int)y); } \
inline type operator ^(type x, type y) { return (type)((int)x ^ (int)y); } \
inline type operator ^=(type &x, type y) { return (type &)((int &)x ^= (int)y); } \
}
#else
# define DEFINE_ENUM_FLAG_OPERATORS(type)
#endif
#endif /* DEFINE_ENUM_FLAG_OPERATORS */

View File

@ -0,0 +1,25 @@
#include <windows.h>
#include <GLFW/glfw3.h>
namespace dxvk::wsi {
inline GLFWwindow* fromHwnd(HWND hWindow) {
return reinterpret_cast<GLFWwindow*>(hWindow);
}
inline HWND toHwnd(GLFWwindow* pWindow) {
return reinterpret_cast<HWND>(pWindow);
}
// Offset so null HMONITORs go to -1
inline int32_t fromHmonitor(HMONITOR hMonitor) {
return static_cast<int32_t>(reinterpret_cast<intptr_t>(hMonitor)) - 1;
}
// Offset so -1 display id goes to 0 == NULL
inline HMONITOR toHmonitor(int32_t displayId) {
return reinterpret_cast<HMONITOR>(static_cast<intptr_t>(displayId + 1));
}
}

View File

@ -0,0 +1,25 @@
#include <windows.h>
#include <SDL2/SDL.h>
namespace dxvk::wsi {
inline SDL_Window* fromHwnd(HWND hWindow) {
return reinterpret_cast<SDL_Window*>(hWindow);
}
inline HWND toHwnd(SDL_Window* pWindow) {
return reinterpret_cast<HWND>(pWindow);
}
// Offset so null HMONITORs go to -1
inline int32_t fromHmonitor(HMONITOR hMonitor) {
return static_cast<int32_t>(reinterpret_cast<intptr_t>(hMonitor)) - 1;
}
// Offset so -1 display id goes to 0 == NULL
inline HMONITOR toHmonitor(int32_t displayId) {
return reinterpret_cast<HMONITOR>(static_cast<intptr_t>(displayId + 1));
}
}

View File

@ -0,0 +1,11 @@
#pragma once
#ifdef DXVK_WSI_WIN32
#error You shouldnt be using this code path.
#elif DXVK_WSI_SDL2
#include "wsi/native_sdl2.h"
#elif DXVK_WSI_GLFW
#include "wsi/native_glfw.h"
#else
#error Unknown wsi!
#endif

1
include/spirv Submodule

@ -0,0 +1 @@
Subproject commit 0bcc624926a25a2a273d07877fd25a6ff5ba1cfb

View File

@ -1,131 +0,0 @@
/*
** Copyright (c) 2014-2016 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and/or associated documentation files (the "Materials"),
** to deal in the Materials without restriction, including without limitation
** the rights to use, copy, modify, merge, publish, distribute, sublicense,
** and/or sell copies of the Materials, and to permit persons to whom the
** Materials are furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in
** all copies or substantial portions of the Materials.
**
** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
** IN THE MATERIALS.
*/
#ifndef GLSLstd450_H
#define GLSLstd450_H
static const int GLSLstd450Version = 100;
static const int GLSLstd450Revision = 3;
enum GLSLstd450 {
GLSLstd450Bad = 0, // Don't use
GLSLstd450Round = 1,
GLSLstd450RoundEven = 2,
GLSLstd450Trunc = 3,
GLSLstd450FAbs = 4,
GLSLstd450SAbs = 5,
GLSLstd450FSign = 6,
GLSLstd450SSign = 7,
GLSLstd450Floor = 8,
GLSLstd450Ceil = 9,
GLSLstd450Fract = 10,
GLSLstd450Radians = 11,
GLSLstd450Degrees = 12,
GLSLstd450Sin = 13,
GLSLstd450Cos = 14,
GLSLstd450Tan = 15,
GLSLstd450Asin = 16,
GLSLstd450Acos = 17,
GLSLstd450Atan = 18,
GLSLstd450Sinh = 19,
GLSLstd450Cosh = 20,
GLSLstd450Tanh = 21,
GLSLstd450Asinh = 22,
GLSLstd450Acosh = 23,
GLSLstd450Atanh = 24,
GLSLstd450Atan2 = 25,
GLSLstd450Pow = 26,
GLSLstd450Exp = 27,
GLSLstd450Log = 28,
GLSLstd450Exp2 = 29,
GLSLstd450Log2 = 30,
GLSLstd450Sqrt = 31,
GLSLstd450InverseSqrt = 32,
GLSLstd450Determinant = 33,
GLSLstd450MatrixInverse = 34,
GLSLstd450Modf = 35, // second operand needs an OpVariable to write to
GLSLstd450ModfStruct = 36, // no OpVariable operand
GLSLstd450FMin = 37,
GLSLstd450UMin = 38,
GLSLstd450SMin = 39,
GLSLstd450FMax = 40,
GLSLstd450UMax = 41,
GLSLstd450SMax = 42,
GLSLstd450FClamp = 43,
GLSLstd450UClamp = 44,
GLSLstd450SClamp = 45,
GLSLstd450FMix = 46,
GLSLstd450IMix = 47, // Reserved
GLSLstd450Step = 48,
GLSLstd450SmoothStep = 49,
GLSLstd450Fma = 50,
GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to
GLSLstd450FrexpStruct = 52, // no OpVariable operand
GLSLstd450Ldexp = 53,
GLSLstd450PackSnorm4x8 = 54,
GLSLstd450PackUnorm4x8 = 55,
GLSLstd450PackSnorm2x16 = 56,
GLSLstd450PackUnorm2x16 = 57,
GLSLstd450PackHalf2x16 = 58,
GLSLstd450PackDouble2x32 = 59,
GLSLstd450UnpackSnorm2x16 = 60,
GLSLstd450UnpackUnorm2x16 = 61,
GLSLstd450UnpackHalf2x16 = 62,
GLSLstd450UnpackSnorm4x8 = 63,
GLSLstd450UnpackUnorm4x8 = 64,
GLSLstd450UnpackDouble2x32 = 65,
GLSLstd450Length = 66,
GLSLstd450Distance = 67,
GLSLstd450Cross = 68,
GLSLstd450Normalize = 69,
GLSLstd450FaceForward = 70,
GLSLstd450Reflect = 71,
GLSLstd450Refract = 72,
GLSLstd450FindILsb = 73,
GLSLstd450FindSMsb = 74,
GLSLstd450FindUMsb = 75,
GLSLstd450InterpolateAtCentroid = 76,
GLSLstd450InterpolateAtSample = 77,
GLSLstd450InterpolateAtOffset = 78,
GLSLstd450NMin = 79,
GLSLstd450NMax = 80,
GLSLstd450NClamp = 81,
GLSLstd450Count
};
#endif // #ifndef GLSLstd450_H

View File

@ -1,135 +0,0 @@
/*
** Copyright (c) 2014-2016 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and/or associated documentation files (the "Materials"),
** to deal in the Materials without restriction, including without limitation
** the rights to use, copy, modify, merge, publish, distribute, sublicense,
** and/or sell copies of the Materials, and to permit persons to whom the
** Materials are furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in
** all copies or substantial portions of the Materials.
**
** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
** IN THE MATERIALS.
*/
#ifndef GLSLstd450_HPP
#define GLSLstd450_HPP
namespace spv {
static const int GLSLstd450Version = 100;
static const int GLSLstd450Revision = 3;
enum GLSLstd450 {
GLSLstd450Bad = 0, // Don't use
GLSLstd450Round = 1,
GLSLstd450RoundEven = 2,
GLSLstd450Trunc = 3,
GLSLstd450FAbs = 4,
GLSLstd450SAbs = 5,
GLSLstd450FSign = 6,
GLSLstd450SSign = 7,
GLSLstd450Floor = 8,
GLSLstd450Ceil = 9,
GLSLstd450Fract = 10,
GLSLstd450Radians = 11,
GLSLstd450Degrees = 12,
GLSLstd450Sin = 13,
GLSLstd450Cos = 14,
GLSLstd450Tan = 15,
GLSLstd450Asin = 16,
GLSLstd450Acos = 17,
GLSLstd450Atan = 18,
GLSLstd450Sinh = 19,
GLSLstd450Cosh = 20,
GLSLstd450Tanh = 21,
GLSLstd450Asinh = 22,
GLSLstd450Acosh = 23,
GLSLstd450Atanh = 24,
GLSLstd450Atan2 = 25,
GLSLstd450Pow = 26,
GLSLstd450Exp = 27,
GLSLstd450Log = 28,
GLSLstd450Exp2 = 29,
GLSLstd450Log2 = 30,
GLSLstd450Sqrt = 31,
GLSLstd450InverseSqrt = 32,
GLSLstd450Determinant = 33,
GLSLstd450MatrixInverse = 34,
GLSLstd450Modf = 35, // second operand needs an OpVariable to write to
GLSLstd450ModfStruct = 36, // no OpVariable operand
GLSLstd450FMin = 37,
GLSLstd450UMin = 38,
GLSLstd450SMin = 39,
GLSLstd450FMax = 40,
GLSLstd450UMax = 41,
GLSLstd450SMax = 42,
GLSLstd450FClamp = 43,
GLSLstd450UClamp = 44,
GLSLstd450SClamp = 45,
GLSLstd450FMix = 46,
GLSLstd450IMix = 47, // Reserved
GLSLstd450Step = 48,
GLSLstd450SmoothStep = 49,
GLSLstd450Fma = 50,
GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to
GLSLstd450FrexpStruct = 52, // no OpVariable operand
GLSLstd450Ldexp = 53,
GLSLstd450PackSnorm4x8 = 54,
GLSLstd450PackUnorm4x8 = 55,
GLSLstd450PackSnorm2x16 = 56,
GLSLstd450PackUnorm2x16 = 57,
GLSLstd450PackHalf2x16 = 58,
GLSLstd450PackDouble2x32 = 59,
GLSLstd450UnpackSnorm2x16 = 60,
GLSLstd450UnpackUnorm2x16 = 61,
GLSLstd450UnpackHalf2x16 = 62,
GLSLstd450UnpackSnorm4x8 = 63,
GLSLstd450UnpackUnorm4x8 = 64,
GLSLstd450UnpackDouble2x32 = 65,
GLSLstd450Length = 66,
GLSLstd450Distance = 67,
GLSLstd450Cross = 68,
GLSLstd450Normalize = 69,
GLSLstd450FaceForward = 70,
GLSLstd450Reflect = 71,
GLSLstd450Refract = 72,
GLSLstd450FindILsb = 73,
GLSLstd450FindSMsb = 74,
GLSLstd450FindUMsb = 75,
GLSLstd450InterpolateAtCentroid = 76,
GLSLstd450InterpolateAtSample = 77,
GLSLstd450InterpolateAtOffset = 78,
GLSLstd450NMin = 79,
GLSLstd450NMax = 80,
GLSLstd450NClamp = 81,
GLSLstd450Count
};
}
#endif // #ifndef GLSLstd450_HPP

File diff suppressed because it is too large Load Diff

1
include/vulkan Submodule

@ -0,0 +1 @@
Subproject commit 85c2334e92e215cce34e8e0ed8b2dce4700f4a50

View File

@ -1,84 +0,0 @@
//
// File: vk_platform.h
//
/*
** Copyright 2014-2021 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
#ifndef VK_PLATFORM_H_
#define VK_PLATFORM_H_
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
/*
***************************************************************************************************
* Platform-specific directives and type declarations
***************************************************************************************************
*/
/* Platform-specific calling convention macros.
*
* Platforms should define these so that Vulkan clients call Vulkan commands
* with the same calling conventions that the Vulkan implementation expects.
*
* VKAPI_ATTR - Placed before the return type in function declarations.
* Useful for C++11 and GCC/Clang-style function attribute syntax.
* VKAPI_CALL - Placed after the return type in function declarations.
* Useful for MSVC-style calling convention syntax.
* VKAPI_PTR - Placed between the '(' and '*' in function pointer types.
*
* Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void);
* Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void);
*/
#if defined(_WIN32)
// On Windows, Vulkan commands use the stdcall convention
#define VKAPI_ATTR
#define VKAPI_CALL __stdcall
#define VKAPI_PTR VKAPI_CALL
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
#error "Vulkan isn't supported for the 'armeabi' NDK ABI"
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
// On Android 32-bit ARM targets, Vulkan functions use the "hardfloat"
// calling convention, i.e. float parameters are passed in registers. This
// is true even if the rest of the application passes floats on the stack,
// as it does by default when compiling for the armeabi-v7a NDK ABI.
#define VKAPI_ATTR __attribute__((pcs("aapcs-vfp")))
#define VKAPI_CALL
#define VKAPI_PTR VKAPI_ATTR
#else
// On other platforms, use the default calling convention
#define VKAPI_ATTR
#define VKAPI_CALL
#define VKAPI_PTR
#endif
#if !defined(VK_NO_STDDEF_H)
#include <stddef.h>
#endif // !defined(VK_NO_STDDEF_H)
#if !defined(VK_NO_STDINT_H)
#if defined(_MSC_VER) && (_MSC_VER < 1600)
typedef signed __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef signed __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
#endif // !defined(VK_NO_STDINT_H)
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif

View File

@ -1,92 +0,0 @@
#ifndef VULKAN_H_
#define VULKAN_H_ 1
/*
** Copyright 2015-2021 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
#include "vk_platform.h"
#include "vulkan_core.h"
#ifdef VK_USE_PLATFORM_ANDROID_KHR
#include "vulkan_android.h"
#endif
#ifdef VK_USE_PLATFORM_FUCHSIA
#include <zircon/types.h>
#include "vulkan_fuchsia.h"
#endif
#ifdef VK_USE_PLATFORM_IOS_MVK
#include "vulkan_ios.h"
#endif
#ifdef VK_USE_PLATFORM_MACOS_MVK
#include "vulkan_macos.h"
#endif
#ifdef VK_USE_PLATFORM_METAL_EXT
#include "vulkan_metal.h"
#endif
#ifdef VK_USE_PLATFORM_VI_NN
#include "vulkan_vi.h"
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
#include <wayland-client.h>
#include "vulkan_wayland.h"
#endif
#ifdef VK_USE_PLATFORM_WIN32_KHR
#include <windows.h>
#include "vulkan_win32.h"
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
#include <xcb/xcb.h>
#include "vulkan_xcb.h"
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR
#include <X11/Xlib.h>
#include "vulkan_xlib.h"
#endif
#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
#include <directfb.h>
#include "vulkan_directfb.h"
#endif
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#include "vulkan_xlib_xrandr.h"
#endif
#ifdef VK_USE_PLATFORM_GGP
#include <ggp_c/vulkan_types.h>
#include "vulkan_ggp.h"
#endif
#ifdef VK_USE_PLATFORM_SCREEN_QNX
#include <screen/screen.h>
#include "vulkan_screen.h"
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
#include "vulkan_beta.h"
#endif
#endif // VULKAN_H_

File diff suppressed because it is too large Load Diff

View File

@ -1,315 +0,0 @@
#ifndef VULKAN_WIN32_H_
#define VULKAN_WIN32_H_ 1
/*
** Copyright 2015-2021 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#ifdef __cplusplus
extern "C" {
#endif
#define VK_KHR_win32_surface 1
#define VK_KHR_WIN32_SURFACE_SPEC_VERSION 6
#define VK_KHR_WIN32_SURFACE_EXTENSION_NAME "VK_KHR_win32_surface"
typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
typedef struct VkWin32SurfaceCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkWin32SurfaceCreateFlagsKHR flags;
HINSTANCE hinstance;
HWND hwnd;
} VkWin32SurfaceCreateInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkCreateWin32SurfaceKHR)(VkInstance instance, const VkWin32SurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(
VkInstance instance,
const VkWin32SurfaceCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR(
VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex);
#endif
#define VK_KHR_external_memory_win32 1
#define VK_KHR_EXTERNAL_MEMORY_WIN32_SPEC_VERSION 1
#define VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME "VK_KHR_external_memory_win32"
typedef struct VkImportMemoryWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
VkExternalMemoryHandleTypeFlagBits handleType;
HANDLE handle;
LPCWSTR name;
} VkImportMemoryWin32HandleInfoKHR;
typedef struct VkExportMemoryWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
const SECURITY_ATTRIBUTES* pAttributes;
DWORD dwAccess;
LPCWSTR name;
} VkExportMemoryWin32HandleInfoKHR;
typedef struct VkMemoryWin32HandlePropertiesKHR {
VkStructureType sType;
void* pNext;
uint32_t memoryTypeBits;
} VkMemoryWin32HandlePropertiesKHR;
typedef struct VkMemoryGetWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
VkDeviceMemory memory;
VkExternalMemoryHandleTypeFlagBits handleType;
} VkMemoryGetWin32HandleInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleKHR)(VkDevice device, const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle);
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandlePropertiesKHR)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE handle, VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleKHR(
VkDevice device,
const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo,
HANDLE* pHandle);
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandlePropertiesKHR(
VkDevice device,
VkExternalMemoryHandleTypeFlagBits handleType,
HANDLE handle,
VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties);
#endif
#define VK_KHR_win32_keyed_mutex 1
#define VK_KHR_WIN32_KEYED_MUTEX_SPEC_VERSION 1
#define VK_KHR_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_KHR_win32_keyed_mutex"
typedef struct VkWin32KeyedMutexAcquireReleaseInfoKHR {
VkStructureType sType;
const void* pNext;
uint32_t acquireCount;
const VkDeviceMemory* pAcquireSyncs;
const uint64_t* pAcquireKeys;
const uint32_t* pAcquireTimeouts;
uint32_t releaseCount;
const VkDeviceMemory* pReleaseSyncs;
const uint64_t* pReleaseKeys;
} VkWin32KeyedMutexAcquireReleaseInfoKHR;
#define VK_KHR_external_semaphore_win32 1
#define VK_KHR_EXTERNAL_SEMAPHORE_WIN32_SPEC_VERSION 1
#define VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME "VK_KHR_external_semaphore_win32"
typedef struct VkImportSemaphoreWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
VkSemaphore semaphore;
VkSemaphoreImportFlags flags;
VkExternalSemaphoreHandleTypeFlagBits handleType;
HANDLE handle;
LPCWSTR name;
} VkImportSemaphoreWin32HandleInfoKHR;
typedef struct VkExportSemaphoreWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
const SECURITY_ATTRIBUTES* pAttributes;
DWORD dwAccess;
LPCWSTR name;
} VkExportSemaphoreWin32HandleInfoKHR;
typedef struct VkD3D12FenceSubmitInfoKHR {
VkStructureType sType;
const void* pNext;
uint32_t waitSemaphoreValuesCount;
const uint64_t* pWaitSemaphoreValues;
uint32_t signalSemaphoreValuesCount;
const uint64_t* pSignalSemaphoreValues;
} VkD3D12FenceSubmitInfoKHR;
typedef struct VkSemaphoreGetWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
VkSemaphore semaphore;
VkExternalSemaphoreHandleTypeFlagBits handleType;
} VkSemaphoreGetWin32HandleInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreWin32HandleKHR)(VkDevice device, const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo);
typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreWin32HandleKHR)(VkDevice device, const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreWin32HandleKHR(
VkDevice device,
const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo);
VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreWin32HandleKHR(
VkDevice device,
const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo,
HANDLE* pHandle);
#endif
#define VK_KHR_external_fence_win32 1
#define VK_KHR_EXTERNAL_FENCE_WIN32_SPEC_VERSION 1
#define VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME "VK_KHR_external_fence_win32"
typedef struct VkImportFenceWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
VkFence fence;
VkFenceImportFlags flags;
VkExternalFenceHandleTypeFlagBits handleType;
HANDLE handle;
LPCWSTR name;
} VkImportFenceWin32HandleInfoKHR;
typedef struct VkExportFenceWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
const SECURITY_ATTRIBUTES* pAttributes;
DWORD dwAccess;
LPCWSTR name;
} VkExportFenceWin32HandleInfoKHR;
typedef struct VkFenceGetWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
VkFence fence;
VkExternalFenceHandleTypeFlagBits handleType;
} VkFenceGetWin32HandleInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkImportFenceWin32HandleKHR)(VkDevice device, const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo);
typedef VkResult (VKAPI_PTR *PFN_vkGetFenceWin32HandleKHR)(VkDevice device, const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkImportFenceWin32HandleKHR(
VkDevice device,
const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo);
VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceWin32HandleKHR(
VkDevice device,
const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo,
HANDLE* pHandle);
#endif
#define VK_NV_external_memory_win32 1
#define VK_NV_EXTERNAL_MEMORY_WIN32_SPEC_VERSION 1
#define VK_NV_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME "VK_NV_external_memory_win32"
typedef struct VkImportMemoryWin32HandleInfoNV {
VkStructureType sType;
const void* pNext;
VkExternalMemoryHandleTypeFlagsNV handleType;
HANDLE handle;
} VkImportMemoryWin32HandleInfoNV;
typedef struct VkExportMemoryWin32HandleInfoNV {
VkStructureType sType;
const void* pNext;
const SECURITY_ATTRIBUTES* pAttributes;
DWORD dwAccess;
} VkExportMemoryWin32HandleInfoNV;
typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleNV)(VkDevice device, VkDeviceMemory memory, VkExternalMemoryHandleTypeFlagsNV handleType, HANDLE* pHandle);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleNV(
VkDevice device,
VkDeviceMemory memory,
VkExternalMemoryHandleTypeFlagsNV handleType,
HANDLE* pHandle);
#endif
#define VK_NV_win32_keyed_mutex 1
#define VK_NV_WIN32_KEYED_MUTEX_SPEC_VERSION 2
#define VK_NV_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_NV_win32_keyed_mutex"
typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV {
VkStructureType sType;
const void* pNext;
uint32_t acquireCount;
const VkDeviceMemory* pAcquireSyncs;
const uint64_t* pAcquireKeys;
const uint32_t* pAcquireTimeoutMilliseconds;
uint32_t releaseCount;
const VkDeviceMemory* pReleaseSyncs;
const uint64_t* pReleaseKeys;
} VkWin32KeyedMutexAcquireReleaseInfoNV;
#define VK_EXT_full_screen_exclusive 1
#define VK_EXT_FULL_SCREEN_EXCLUSIVE_SPEC_VERSION 4
#define VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME "VK_EXT_full_screen_exclusive"
typedef enum VkFullScreenExclusiveEXT {
VK_FULL_SCREEN_EXCLUSIVE_DEFAULT_EXT = 0,
VK_FULL_SCREEN_EXCLUSIVE_ALLOWED_EXT = 1,
VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT = 2,
VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT = 3,
VK_FULL_SCREEN_EXCLUSIVE_MAX_ENUM_EXT = 0x7FFFFFFF
} VkFullScreenExclusiveEXT;
typedef struct VkSurfaceFullScreenExclusiveInfoEXT {
VkStructureType sType;
void* pNext;
VkFullScreenExclusiveEXT fullScreenExclusive;
} VkSurfaceFullScreenExclusiveInfoEXT;
typedef struct VkSurfaceCapabilitiesFullScreenExclusiveEXT {
VkStructureType sType;
void* pNext;
VkBool32 fullScreenExclusiveSupported;
} VkSurfaceCapabilitiesFullScreenExclusiveEXT;
typedef struct VkSurfaceFullScreenExclusiveWin32InfoEXT {
VkStructureType sType;
const void* pNext;
HMONITOR hmonitor;
} VkSurfaceFullScreenExclusiveWin32InfoEXT;
typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes);
typedef VkResult (VKAPI_PTR *PFN_vkAcquireFullScreenExclusiveModeEXT)(VkDevice device, VkSwapchainKHR swapchain);
typedef VkResult (VKAPI_PTR *PFN_vkReleaseFullScreenExclusiveModeEXT)(VkDevice device, VkSwapchainKHR swapchain);
typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupSurfacePresentModes2EXT)(VkDevice device, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkDeviceGroupPresentModeFlagsKHR* pModes);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModes2EXT(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
uint32_t* pPresentModeCount,
VkPresentModeKHR* pPresentModes);
VKAPI_ATTR VkResult VKAPI_CALL vkAcquireFullScreenExclusiveModeEXT(
VkDevice device,
VkSwapchainKHR swapchain);
VKAPI_ATTR VkResult VKAPI_CALL vkReleaseFullScreenExclusiveModeEXT(
VkDevice device,
VkSwapchainKHR swapchain);
VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModes2EXT(
VkDevice device,
const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
VkDeviceGroupPresentModeFlagsKHR* pModes);
#endif
#ifdef __cplusplus
}
#endif
#endif

Binary file not shown.

View File

@ -1,17 +0,0 @@
; File generated automatically from d3dcompiler_43.spec; do not edit!
LIBRARY d3dcompiler_43.dll
EXPORTS
D3DAssemble @1
D3DCompile @3
D3DCreateBlob @5
D3DDisassemble @8
D3DGetBlobPart @9
D3DGetDebugInfo @10
D3DGetInputAndOutputSignatureBlob @11
D3DGetInputSignatureBlob @12
D3DGetOutputSignatureBlob @13
D3DPreprocess @14
D3DReflect @15
D3DStripShader @17

Binary file not shown.

Binary file not shown.

View File

@ -1,17 +0,0 @@
; File generated automatically from d3dcompiler_43.spec; do not edit!
LIBRARY d3dcompiler_43.dll
EXPORTS
D3DAssemble@32 @1
D3DCompile@44 @3
D3DCreateBlob@8 @5
D3DDisassemble@20 @8
D3DGetBlobPart@20 @9
D3DGetDebugInfo@12 @10
D3DGetInputAndOutputSignatureBlob@12 @11
D3DGetInputSignatureBlob@12 @12
D3DGetOutputSignatureBlob@12 @13
D3DPreprocess@28 @14
D3DReflect@16 @15
D3DStripShader@16 @17

Binary file not shown.

View File

@ -1,40 +1,31 @@
project('dxvk', ['c', 'cpp'], version : 'v1.10.1', meson_version : '>= 0.49', default_options : [ 'cpp_std=c++17' ])
project('dxvk', ['c', 'cpp'], version : 'v2.2', meson_version : '>= 0.49', default_options : [ 'cpp_std=c++17', 'warning_level=2' ])
cpu_family = target_machine.cpu_family()
platform = target_machine.system()
cpp = meson.get_compiler('cpp')
cc = meson.get_compiler('c')
dxvk_is_msvc = cpp.get_id() == 'msvc'
compiler_args = [
'-DNOMINMAX',
'-D_WIN32_WINNT=0xa00',
'-msse',
'-msse2',
'-msse3',
'-mfpmath=sse',
'-Wimplicit-fallthrough',
# gcc
'-Wno-missing-field-initializers',
'-Wno-unused-parameter',
'-Wno-cast-function-type', # Needed for GetProcAddress.
# clang
'-Wno-unused-private-field',
'-Wno-microsoft-exception-spec',
'-Wno-extern-c-compat',
'-Wno-unused-const-variable',
'-Wno-missing-braces',
]
link_args = [
'-static',
'-static-libgcc',
'-static-libstdc++',
# We need to set the section alignment for debug symbols to
# work properly as well as avoiding a memcpy from the Wine loader.
'-Wl,--file-alignment=4096',
]
# Wine's built-in back traces only work with dwarf2 symbols
if get_option('debug') and target_machine.system() == 'windows'
compiler_args += [
'-gstrict-dwarf',
'-gdwarf-2',
]
endif
link_args = []
if get_option('build_id')
link_args += [
@ -42,71 +33,129 @@ if get_option('build_id')
]
endif
if cpu_family == 'x86'
dxvk_include_dirs = [
'./include',
'./include/vulkan/include',
'./include/spirv/include'
]
proj_displayinfo = subproject('libdisplay-info')
dep_displayinfo = proj_displayinfo.get_variable('di_dep')
if platform == 'windows'
compiler_args += [
'-DNOMINMAX',
'-D_WIN32_WINNT=0xa00',
]
link_args += [
'-Wl,--enable-stdcall-fixup',
'-Wl,--add-stdcall-alias',
'-static',
'-static-libgcc',
'-static-libstdc++',
# We need to set the section alignment for debug symbols to
# work properly as well as avoiding a memcpy from the Wine loader.
'-Wl,--file-alignment=4096',
]
# Wine's built-in back traces only work with dwarf4 symbols
if get_option('debug')
compiler_args += [
'-gdwarf-4',
]
endif
# Enable stdcall fixup on 32-bit
if cpu_family == 'x86'
link_args += [
'-Wl,--enable-stdcall-fixup',
'-Wl,--kill-at',
]
endif
lib_d3d9 = cpp.find_library('d3d9')
lib_d3d11 = cpp.find_library('d3d11')
lib_dxgi = cpp.find_library('dxgi')
if dxvk_is_msvc
lib_d3dcompiler_47 = cpp.find_library('d3dcompiler')
else
lib_d3dcompiler_47 = cpp.find_library('d3dcompiler_47')
endif
if dxvk_is_msvc
res_ext = '.res'
wrc = find_program('rc')
wrc_generator = generator(wrc,
output : [ '@BASENAME@' + res_ext ],
arguments : [ '/fo', '@OUTPUT@', '@INPUT@' ],
)
else
res_ext = '.o'
wrc = find_program('windres')
wrc_generator = generator(wrc,
output : [ '@BASENAME@' + res_ext ],
arguments : [ '-i', '@INPUT@', '-o', '@OUTPUT@' ],
)
endif
dxvk_wsi = 'win32'
dxvk_name_prefix = ''
compiler_args += ['-DDXVK_WSI_WIN32']
else
wrc = find_program('touch')
wrc_generator = generator(wrc, output : [ '@BASENAME@_ignored.h' ], arguments : [ '@OUTPUT@' ] )
dxvk_include_dirs += [
'./include/native',
'./include/native/windows',
'./include/native/directx'
]
dxvk_wsi = get_option('dxvk_native_wsi')
if dxvk_wsi == 'sdl2'
lib_sdl2 = cpp.find_library('SDL2')
compiler_args += ['-DDXVK_WSI_SDL2']
elif dxvk_wsi == 'glfw'
lib_glfw = cpp.find_library('glfw')
compiler_args += ['-DDXVK_WSI_GLFW']
endif
dxvk_name_prefix = 'libdxvk_'
link_args += [
'-static-libgcc',
'-static-libstdc++',
]
endif
dxvk_include_path = include_directories(dxvk_include_dirs)
add_project_arguments(cpp.get_supported_arguments(compiler_args), language: 'cpp')
add_project_arguments(cc.get_supported_arguments(compiler_args), language: 'c')
add_project_link_arguments(cpp.get_supported_link_arguments(link_args), language: 'cpp')
add_project_link_arguments(cc.get_supported_link_arguments(link_args), language: 'c')
dxvk_include_path = include_directories('./include')
if (cpu_family == 'x86_64')
dxvk_library_path = meson.source_root() + '/lib'
else
dxvk_library_path = meson.source_root() + '/lib32'
endif
dxvk_extradep = [ ]
lib_vulkan = cpp.find_library('vulkan-1', dirs : dxvk_library_path)
lib_d3d9 = cpp.find_library('d3d9')
lib_d3d11 = cpp.find_library('d3d11')
lib_dxgi = cpp.find_library('dxgi')
lib_d3dcompiler_43 = cpp.find_library('d3dcompiler_43', dirs : dxvk_library_path)
if dxvk_is_msvc
lib_d3dcompiler_47 = cpp.find_library('d3dcompiler')
else
lib_d3dcompiler_47 = cpp.find_library('d3dcompiler_47')
endif
exe_ext = ''
dll_ext = ''
def_spec_ext = '.def'
glsl_compiler = find_program('glslangValidator')
glsl_args = [ '-V', '--vn', '@BASENAME@', '@INPUT@', '-o', '@OUTPUT@' ]
if run_command(glsl_compiler, [ '--quiet', '--version' ], check : false).returncode() == 0
glsl_args += [ '--quiet' ]
endif
glsl_generator = generator(glsl_compiler,
glsl_compiler = find_program('glslang', 'glslangValidator')
glsl_args = [
'--quiet',
'--target-env', 'vulkan1.2',
'--vn', '@BASENAME@',
'--depfile', '@DEPFILE@',
'@INPUT@',
'-o', '@OUTPUT@',
]
glsl_generator = generator(
glsl_compiler,
output : [ '@BASENAME@.h' ],
depfile : '@BASENAME@.h.d',
arguments : glsl_args,
)
if dxvk_is_msvc
res_ext = '.res'
wrc = find_program('rc')
wrc_generator = generator(wrc,
output : [ '@BASENAME@' + res_ext ],
arguments : [ '/fo', '@OUTPUT@', '@INPUT@' ],
)
else
res_ext = '.o'
wrc = find_program('windres')
wrc_generator = generator(wrc,
output : [ '@BASENAME@' + res_ext ],
arguments : [ '-i', '@INPUT@', '-o', '@OUTPUT@' ],
)
endif
dxvk_version = vcs_tag(
command: ['git', 'describe', '--dirty=+'],
input: 'version.h.in',
@ -114,9 +163,3 @@ dxvk_version = vcs_tag(
)
subdir('src')
enable_tests = get_option('enable_tests')
if enable_tests
subdir('tests')
endif

View File

@ -1,6 +1,7 @@
option('enable_tests', type : 'boolean', value : false)
option('enable_dxgi', type : 'boolean', value : true, description: 'Build DXGI')
option('enable_d3d9', type : 'boolean', value : true, description: 'Build D3D9')
option('enable_d3d10', type : 'boolean', value : true, description: 'Build D3D10')
option('enable_d3d11', type : 'boolean', value : true, description: 'Build D3D11')
option('build_id', type : 'boolean', value : false)
option('dxvk_native_wsi', type : 'string', value : 'sdl2', description: 'WSI system to use if building natively.')

88
package-native.sh Executable file
View File

@ -0,0 +1,88 @@
#!/usr/bin/env bash
set -e
shopt -s extglob
if [ -z "$1" ] || [ -z "$2" ]; then
echo "Usage: $0 version destdir [--no-package] [--dev-build]"
exit 1
fi
DXVK_VERSION="$1"
DXVK_SRC_DIR=$(readlink -f "$0")
DXVK_SRC_DIR=$(dirname "$DXVK_SRC_DIR")
DXVK_BUILD_DIR=$(realpath "$2")"/dxvk-native-$DXVK_VERSION"
DXVK_ARCHIVE_PATH=$(realpath "$2")"/dxvk-native-$DXVK_VERSION.tar.gz"
if [ -e "$DXVK_BUILD_DIR" ]; then
echo "Build directory $DXVK_BUILD_DIR already exists"
exit 1
fi
shift 2
opt_nopackage=0
opt_devbuild=0
opt_buildid=false
CC=${CC:="gcc"}
CXX=${CXX:="g++"}
while [ $# -gt 0 ]; do
case "$1" in
"--no-package")
opt_nopackage=1
;;
"--dev-build")
opt_nopackage=1
opt_devbuild=1
;;
"--build-id")
opt_buildid=true
;;
*)
echo "Unrecognized option: $1" >&2
exit 1
esac
shift
done
function build_arch {
cd "$DXVK_SRC_DIR"
opt_strip=
if [ $opt_devbuild -eq 0 ]; then
opt_strip=--strip
fi
CC="$CC -m$1" CXX="$CXX -m$1" meson setup \
--buildtype "release" \
--prefix "$DXVK_BUILD_DIR/usr" \
$opt_strip \
--bindir "$2" \
--libdir "$2" \
-Dbuild_id=$opt_buildid \
"$DXVK_BUILD_DIR/build.$1"
cd "$DXVK_BUILD_DIR/build.$1"
ninja install
if [ $opt_devbuild -eq 0 ]; then
rm -r "$DXVK_BUILD_DIR/build.$1"
fi
}
function package {
cd "$DXVK_BUILD_DIR"
tar -czf "$DXVK_ARCHIVE_PATH" "usr"
cd ".."
rm -R "dxvk-native-$DXVK_VERSION"
}
build_arch 64 lib
build_arch 32 lib32
if [ $opt_nopackage -eq 0 ]; then
package
fi

View File

@ -10,7 +10,8 @@ if [ -z "$1" ] || [ -z "$2" ]; then
fi
DXVK_VERSION="$1"
DXVK_SRC_DIR=`dirname $(readlink -f $0)`
DXVK_SRC_DIR=$(readlink -f "$0")
DXVK_SRC_DIR=$(dirname "$DXVK_SRC_DIR")
DXVK_BUILD_DIR=$(realpath "$2")"/dxvk-$DXVK_VERSION"
DXVK_ARCHIVE_PATH=$(realpath "$2")"/dxvk-$DXVK_VERSION.tar.gz"
@ -57,14 +58,13 @@ function build_arch {
opt_strip=--strip
fi
meson --cross-file "$DXVK_SRC_DIR/$crossfile$1.txt" \
--buildtype "release" \
--prefix "$DXVK_BUILD_DIR" \
$opt_strip \
--bindir "x$1" \
--libdir "x$1" \
-Denable_tests=false \
-Dbuild_id=$opt_buildid \
meson setup --cross-file "$DXVK_SRC_DIR/$crossfile$1.txt" \
--buildtype "release" \
--prefix "$DXVK_BUILD_DIR" \
$opt_strip \
--bindir "x$1" \
--libdir "x$1" \
-Dbuild_id=$opt_buildid \
"$DXVK_BUILD_DIR/build.$1"
cd "$DXVK_BUILD_DIR/build.$1"
@ -77,11 +77,6 @@ function build_arch {
fi
}
function build_script {
cp "$DXVK_SRC_DIR/setup_dxvk.sh" "$DXVK_BUILD_DIR/setup_dxvk.sh"
chmod +x "$DXVK_BUILD_DIR/setup_dxvk.sh"
}
function package {
cd "$DXVK_BUILD_DIR/.."
tar -czf "$DXVK_ARCHIVE_PATH" "dxvk-$DXVK_VERSION"
@ -90,7 +85,6 @@ function package {
build_arch 64
build_arch 32
build_script
if [ $opt_nopackage -eq 0 ]; then
package

View File

@ -1,216 +0,0 @@
#!/usr/bin/env bash
# default directories
dxvk_lib32=${dxvk_lib32:-"x32"}
dxvk_lib64=${dxvk_lib64:-"x64"}
# figure out where we are
basedir=$(dirname "$(readlink -f $0)")
# figure out which action to perform
action="$1"
case "$action" in
install)
;;
uninstall)
;;
*)
echo "Unrecognized action: $action"
echo "Usage: $0 [install|uninstall] [--without-dxgi] [--with-d3d10] [--symlink]"
exit 1
esac
# process arguments
shift
with_dxgi=true
with_d3d10=false
file_cmd="cp -v"
while (($# > 0)); do
case "$1" in
"--without-dxgi")
with_dxgi=false
;;
"--with-d3d10")
with_d3d10=true
;;
"--symlink")
file_cmd="ln -s -v"
;;
esac
shift
done
# check wine prefix before invoking wine, so that we
# don't accidentally create one if the user screws up
if [ -n "$WINEPREFIX" ] && ! [ -f "$WINEPREFIX/system.reg" ]; then
echo "$WINEPREFIX:"' Not a valid wine prefix.' >&2
exit 1
fi
# find wine executable
export WINEDEBUG=-all
# disable mscoree and mshtml to avoid downloading
# wine gecko and mono
export WINEDLLOVERRIDES="mscoree,mshtml="
wine="wine"
wine64="wine64"
wineboot="wineboot"
# $PATH is the way for user to control where wine is located (including custom Wine versions).
# Pure 64-bit Wine (non Wow64) requries skipping 32-bit steps.
# In such case, wine64 and winebooot will be present, but wine binary will be missing,
# however it can be present in other PATHs, so it shouldn't be used, to avoid versions mixing.
wine_path=$(dirname "$(which $wineboot)")
wow64=true
if ! [ -f "$wine_path/$wine" ]; then
wine=$wine64
wow64=false
fi
# resolve 32-bit and 64-bit system32 path
winever=$($wine --version | grep wine)
if [ -z "$winever" ]; then
echo "$wine:"' Not a wine executable. Check your $wine.' >&2
exit 1
fi
# ensure wine placeholder dlls are recreated
# if they are missing
$wineboot -u
win64_sys_path=$($wine64 winepath -u 'C:\windows\system32' 2> /dev/null)
win64_sys_path="${win64_sys_path/$'\r'/}"
if $wow64; then
win32_sys_path=$($wine winepath -u 'C:\windows\system32' 2> /dev/null)
win32_sys_path="${win32_sys_path/$'\r'/}"
fi
if [ -z "$win32_sys_path" ] && [ -z "$win64_sys_path" ]; then
echo 'Failed to resolve C:\windows\system32.' >&2
exit 1
fi
# create native dll override
overrideDll() {
$wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v $1 /d native /f >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo -e "Failed to add override for $1"
exit 1
fi
}
# remove dll override
restoreDll() {
$wine reg delete 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v $1 /f > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Failed to remove override for $1"
fi
}
# copy or link dxvk dll, back up original file
installFile() {
dstfile="${1}/${3}.dll"
srcfile="${basedir}/${2}/${3}.dll"
if [ -f "${srcfile}.so" ]; then
srcfile="${srcfile}.so"
fi
if ! [ -f "${srcfile}" ]; then
echo "${srcfile}: File not found. Skipping." >&2
return 1
fi
if [ -n "$1" ]; then
if [ -f "${dstfile}" ] || [ -h "${dstfile}" ]; then
if ! [ -f "${dstfile}.old" ]; then
mv -v "${dstfile}" "${dstfile}.old"
else
rm -v "${dstfile}"
fi
$file_cmd "${srcfile}" "${dstfile}"
else
echo "${dstfile}: File not found in wine prefix" >&2
return 1
fi
fi
return 0
}
# remove dxvk dll, restore original file
uninstallFile() {
dstfile="${1}/${3}.dll"
srcfile="${basedir}/${2}/${3}.dll"
if [ -f "${srcfile}.so" ]; then
srcfile="${srcfile}.so"
fi
if ! [ -f "${srcfile}" ]; then
echo "${srcfile}: File not found. Skipping." >&2
return 1
fi
if ! [ -f "${dstfile}" ] && ! [ -h "${dstfile}" ]; then
echo "${dstfile}: File not found. Skipping." >&2
return 1
fi
if [ -f "${dstfile}.old" ]; then
rm -v "${dstfile}"
mv -v "${dstfile}.old" "${dstfile}"
return 0
else
return 1
fi
}
install() {
installFile "$win64_sys_path" "$dxvk_lib64" "$1"
inst64_ret="$?"
inst32_ret=-1
if $wow64; then
installFile "$win32_sys_path" "$dxvk_lib32" "$1"
inst32_ret="$?"
fi
if (( ($inst32_ret == 0) || ($inst64_ret == 0) )); then
overrideDll "$1"
fi
}
uninstall() {
uninstallFile "$win64_sys_path" "$dxvk_lib64" "$1"
uninst64_ret="$?"
uninst32_ret=-1
if $wow64; then
uninstallFile "$win32_sys_path" "$dxvk_lib32" "$1"
uninst32_ret="$?"
fi
if (( ($uninst32_ret == 0) || ($uninst64_ret == 0) )); then
restoreDll "$1"
fi
}
# skip dxgi during install if not explicitly
# enabled, but always try to uninstall it
if $with_dxgi || [ "$action" == "uninstall" ]; then
$action dxgi
fi
$action d3d9
if $with_d3d10 || [ "$action" == "uninstall" ]; then
$action d3d10
$action d3d10_1
fi
$action d3d10core
$action d3d11

View File

@ -1,29 +0,0 @@
LIBRARY D3D10.DLL
EXPORTS
D3D10CreateDevice
D3D10CreateDeviceAndSwapChain
D3D10GetVertexShaderProfile
D3D10GetGeometryShaderProfile
D3D10GetPixelShaderProfile
D3D10CreateBlob
D3D10GetInputSignatureBlob
D3D10GetOutputSignatureBlob
D3D10ReflectShader
D3D10CompileShader
D3D10CreateEffectFromMemory
D3D10CreateEffectPoolFromMemory
D3D10CompileEffectFromMemory
D3D10DisassembleEffect
D3D10DisassembleShader
D3D10PreprocessShader
D3D10CreateStateBlock
D3D10StateBlockMaskDifference
D3D10StateBlockMaskDisableAll
D3D10StateBlockMaskDisableCapture
D3D10StateBlockMaskEnableAll
D3D10StateBlockMaskEnableCapture
D3D10StateBlockMaskGetSetting
D3D10StateBlockMaskIntersect
D3D10StateBlockMaskUnion
D3D10GetVersion
D3D10RegisterLayers

View File

@ -1,29 +0,0 @@
LIBRARY D3D10_1.DLL
EXPORTS
D3D10CreateDevice1
D3D10CreateDeviceAndSwapChain1
D3D10GetVertexShaderProfile
D3D10GetGeometryShaderProfile
D3D10GetPixelShaderProfile
D3D10CreateBlob
D3D10GetInputSignatureBlob
D3D10GetOutputSignatureBlob
D3D10ReflectShader
D3D10CompileShader
D3D10CreateEffectFromMemory
D3D10CreateEffectPoolFromMemory
D3D10CompileEffectFromMemory
D3D10DisassembleEffect
D3D10DisassembleShader
D3D10PreprocessShader
D3D10CreateStateBlock
D3D10StateBlockMaskDifference
D3D10StateBlockMaskDisableAll
D3D10StateBlockMaskDisableCapture
D3D10StateBlockMaskEnableAll
D3D10StateBlockMaskEnableCapture
D3D10StateBlockMaskGetSetting
D3D10StateBlockMaskIntersect
D3D10StateBlockMaskUnion
D3D10GetVersion
D3D10RegisterLayers

View File

@ -9,10 +9,14 @@ extern "C" {
HRESULT __stdcall D3D11CoreCreateDevice(
IDXGIFactory* pFactory,
IDXGIAdapter* pAdapter,
D3D_DRIVER_TYPE DriverType,
HMODULE Software,
UINT Flags,
const D3D_FEATURE_LEVEL* pFeatureLevels,
UINT FeatureLevels,
ID3D11Device** ppDevice);
UINT SDKVersion,
ID3D11Device** ppDevice,
D3D_FEATURE_LEVEL* pFeatureLevel);
DLLEXPORT HRESULT __stdcall D3D10CoreCreateDevice(
@ -31,8 +35,8 @@ extern "C" {
if (FAILED(hr))
return hr;
hr = D3D11CoreCreateDevice(pFactory, pAdapter,
Flags, &FeatureLevel, 1, &d3d11Device);
hr = D3D11CoreCreateDevice(pFactory, pAdapter, D3D_DRIVER_TYPE_UNKNOWN,
nullptr, Flags, &FeatureLevel, 1, D3D11_SDK_VERSION, &d3d11Device, nullptr);
if (FAILED(hr))
return hr;

View File

@ -1,9 +0,0 @@
#pragma once
#include "d3d10_include.h"
#ifdef _MSC_VER
struct __declspec(uuid("0803425a-57f5-4dd6-9465-a87570834a08")) ID3D10StateBlock;
#else
__CRT_UUID_DECL(ID3D10StateBlock, 0x0803425a,0x57f5,0x4dd6,0x94,0x65,0xa8,0x75,0x70,0x83,0x4a,0x08);
#endif

View File

@ -1,335 +0,0 @@
#include <d3dcompiler.h>
#include "d3d10_include.h"
#include "d3d10_reflection.h"
#include "../dxgi/dxgi_adapter.h"
namespace dxvk {
Logger Logger::s_instance("d3d10.log");
}
extern "C" {
using namespace dxvk;
HRESULT __stdcall D3D10CoreCreateDevice(
IDXGIFactory* pFactory,
IDXGIAdapter* pAdapter,
UINT Flags,
D3D_FEATURE_LEVEL FeatureLevel,
ID3D10Device** ppDevice);
static HRESULT D3D10InternalCreateDeviceAndSwapChain(
IDXGIAdapter* pAdapter,
D3D10_DRIVER_TYPE DriverType,
HMODULE Software,
UINT Flags,
D3D10_FEATURE_LEVEL1 HardwareLevel,
UINT SDKVersion,
DXGI_SWAP_CHAIN_DESC* pSwapChainDesc,
IDXGISwapChain** ppSwapChain,
REFIID deviceIID,
void** ppDevice) {
InitReturnPtr(ppDevice);
InitReturnPtr(ppSwapChain);
if (ppSwapChain && !pSwapChainDesc)
return E_INVALIDARG;
HRESULT hr;
// Get DXGI factory and adapter. This is mostly
// copied from the equivalent D3D11 functions.
Com<IDXGIFactory> dxgiFactory = nullptr;
Com<IDXGIAdapter> dxgiAdapter = pAdapter;
Com<ID3D10Device> device = nullptr;
if (!pAdapter) {
if (DriverType != D3D10_DRIVER_TYPE_HARDWARE)
Logger::warn("D3D10CreateDevice: Unsupported driver type");
hr = CreateDXGIFactory(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&dxgiFactory));
if (FAILED(hr)) {
Logger::err("D3D10CreateDevice: Failed to create a DXGI factory");
return hr;
}
hr = dxgiFactory->EnumAdapters(0, &dxgiAdapter);
if (FAILED(hr)) {
Logger::err("D3D10CreateDevice: No default adapter available");
return hr;
}
} else {
if (FAILED(dxgiAdapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&dxgiFactory)))) {
Logger::err("D3D10CreateDevice: Failed to query DXGI factory from DXGI adapter");
return E_INVALIDARG;
}
if (DriverType != D3D10_DRIVER_TYPE_HARDWARE || Software)
return E_INVALIDARG;
}
hr = D3D10CoreCreateDevice(
dxgiFactory.ptr(), dxgiAdapter.ptr(),
Flags, D3D_FEATURE_LEVEL(HardwareLevel),
&device);
if (FAILED(hr))
return hr;
if (ppSwapChain) {
DXGI_SWAP_CHAIN_DESC desc = *pSwapChainDesc;
hr = dxgiFactory->CreateSwapChain(device.ptr(), &desc, ppSwapChain);
if (FAILED(hr)) {
Logger::err("D3D10CreateDevice: Failed to create swap chain");
return hr;
}
}
if (ppDevice) {
// Just assume that this succeeds
device->QueryInterface(deviceIID, ppDevice);
}
if (!ppDevice && !ppSwapChain)
return S_FALSE;
return S_OK;
}
DLLEXPORT HRESULT __stdcall D3D10CreateDevice(
IDXGIAdapter* pAdapter,
D3D10_DRIVER_TYPE DriverType,
HMODULE Software,
UINT Flags,
UINT SDKVersion,
ID3D10Device** ppDevice) {
return D3D10InternalCreateDeviceAndSwapChain(
pAdapter, DriverType, Software, Flags,
D3D10_FEATURE_LEVEL_10_0, SDKVersion,
nullptr, nullptr,
__uuidof(ID3D10Device),
reinterpret_cast<void**>(ppDevice));
}
DLLEXPORT HRESULT __stdcall D3D10CreateDevice1(
IDXGIAdapter* pAdapter,
D3D10_DRIVER_TYPE DriverType,
HMODULE Software,
UINT Flags,
D3D10_FEATURE_LEVEL1 HardwareLevel,
UINT SDKVersion,
ID3D10Device1** ppDevice) {
return D3D10InternalCreateDeviceAndSwapChain(
pAdapter, DriverType, Software, Flags,
HardwareLevel, SDKVersion,
nullptr, nullptr,
__uuidof(ID3D10Device1),
reinterpret_cast<void**>(ppDevice));
}
DLLEXPORT HRESULT __stdcall D3D10CreateDeviceAndSwapChain(
IDXGIAdapter* pAdapter,
D3D10_DRIVER_TYPE DriverType,
HMODULE Software,
UINT Flags,
UINT SDKVersion,
DXGI_SWAP_CHAIN_DESC* pSwapChainDesc,
IDXGISwapChain** ppSwapChain,
ID3D10Device** ppDevice) {
return D3D10InternalCreateDeviceAndSwapChain(
pAdapter, DriverType, Software, Flags,
D3D10_FEATURE_LEVEL_10_0, SDKVersion,
pSwapChainDesc, ppSwapChain,
__uuidof(ID3D10Device),
reinterpret_cast<void**>(ppDevice));
}
DLLEXPORT HRESULT __stdcall D3D10CreateDeviceAndSwapChain1(
IDXGIAdapter* pAdapter,
D3D10_DRIVER_TYPE DriverType,
HMODULE Software,
UINT Flags,
D3D10_FEATURE_LEVEL1 HardwareLevel,
UINT SDKVersion,
DXGI_SWAP_CHAIN_DESC* pSwapChainDesc,
IDXGISwapChain** ppSwapChain,
ID3D10Device1** ppDevice) {
return D3D10InternalCreateDeviceAndSwapChain(
pAdapter, DriverType, Software, Flags,
HardwareLevel, SDKVersion,
pSwapChainDesc, ppSwapChain,
__uuidof(ID3D10Device1),
reinterpret_cast<void**>(ppDevice));
}
const char* STDMETHODCALLTYPE D3D10GetVertexShaderProfile (ID3D10Device*) { return "vs_4_1"; }
const char* STDMETHODCALLTYPE D3D10GetGeometryShaderProfile (ID3D10Device*) { return "gs_4_1"; }
const char* STDMETHODCALLTYPE D3D10GetPixelShaderProfile (ID3D10Device*) { return "ps_4_1"; }
HRESULT STDMETHODCALLTYPE D3D10CreateBlob(SIZE_T size, LPD3D10BLOB* ppBuffer) {
return D3DCreateBlob(size, ppBuffer);
}
HRESULT STDMETHODCALLTYPE D3D10GetInputSignatureBlob(
const void* pShaderBytecode,
SIZE_T BytecodeLength,
ID3D10Blob** ppSignatureBlob) {
return D3DGetInputSignatureBlob(
pShaderBytecode,
BytecodeLength,
ppSignatureBlob);
}
HRESULT STDMETHODCALLTYPE D3D10GetOutputSignatureBlob(
const void* pShaderBytecode,
SIZE_T BytecodeLength,
ID3D10Blob** ppSignatureBlob) {
return D3DGetOutputSignatureBlob(
pShaderBytecode,
BytecodeLength,
ppSignatureBlob);
}
HRESULT STDMETHODCALLTYPE D3D10ReflectShader(
const void* pShaderBytecode,
SIZE_T BytecodeLength,
ID3D10ShaderReflection** ppReflector) {
static const GUID IID_ID3D11ShaderReflection =
{0x0a233719,0x3960,0x4578,{0x9d,0x7c,0x20,0x3b,0x8b,0x1d,0x9c,0xc1}};
InitReturnPtr(ppReflector);
Com<ID3D11ShaderReflection> d3d11Reflector = nullptr;
HRESULT hr = D3DReflect(pShaderBytecode,
BytecodeLength, IID_ID3D11ShaderReflection,
reinterpret_cast<void**>(&d3d11Reflector));
if (FAILED(hr)) {
Logger::err("D3D10ReflectShader: Failed to create ID3D11ShaderReflection");
return hr;
}
*ppReflector = ref(new D3D10ShaderReflection(d3d11Reflector.ptr()));
return S_OK;
}
HRESULT STDMETHODCALLTYPE D3D10CompileShader(
LPCSTR pSrcData,
SIZE_T SrcDataSize,
LPCSTR pFileName,
const D3D10_SHADER_MACRO* pDefines,
LPD3D10INCLUDE pInclude,
LPCSTR pFunctionName,
LPCSTR pProfile,
UINT Flags,
ID3D10Blob** ppShader,
ID3D10Blob** ppErrorMsgs) {
return D3DCompile(pSrcData, SrcDataSize, pFileName,
pDefines, pInclude, pFunctionName, pProfile, Flags,
0, ppShader, ppErrorMsgs);
}
HRESULT STDMETHODCALLTYPE D3D10CreateEffectFromMemory(
void* pData,
SIZE_T DataSize,
UINT EffectFlags,
ID3D10Device* pDevice,
ID3D10EffectPool* pEffectPool,
ID3D10Effect** ppEffect) {
Logger::warn("D3D10CreateEffectFromMemory: Not implemented");
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE D3D10CreateEffectPoolFromMemory(
void* pData,
SIZE_T DataSize,
UINT EffectFlags,
ID3D10Device* pDevice,
ID3D10EffectPool** ppEffectPool) {
Logger::warn("D3D10CreateEffectPoolFromMemory: Not implemented");
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE D3D10CompileEffectFromMemory(
void* pData,
SIZE_T DataLength,
LPCSTR pSrcFileName,
const D3D10_SHADER_MACRO* pDefines,
ID3D10Include* pInclude,
UINT ShaderFlags,
UINT EffectFlags,
ID3D10Blob** ppCompiledEffect,
ID3D10Blob** ppErrors) {
Logger::warn("D3D10CompileEffectFromMemory: Not implemented");
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE D3D10DisassembleEffect(
ID3D10Effect* pEffect,
BOOL EnableColorCode,
ID3D10Blob** ppDisassembly) {
Logger::warn("D3D10DisassembleEffect: Not implemented");
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE D3D10DisassembleShader(
const void* pShader,
SIZE_T BytecodeLength,
BOOL EnableColorCode,
LPCSTR pComments,
ID3D10Blob** ppDisassembly) {
return D3DDisassemble(
pShader, BytecodeLength,
0, pComments, ppDisassembly);
}
HRESULT STDMETHODCALLTYPE D3D10PreprocessShader(
LPCSTR pSrcData,
SIZE_T SrcDataSize,
LPCSTR pFileName,
const D3D10_SHADER_MACRO* pDefines,
LPD3D10INCLUDE pInclude,
ID3D10Blob** ppShaderText,
ID3D10Blob** ppErrorMsgs) {
return D3DPreprocess(
pSrcData, SrcDataSize,
pFileName, pDefines,
pInclude,
ppShaderText,
ppErrorMsgs);
}
UINT64 STDMETHODCALLTYPE D3D10GetVersion() {
return 0xa000100041770ull;
}
HRESULT STDMETHODCALLTYPE D3D10RegisterLayers() {
return E_NOTIMPL;
}
}

View File

@ -6,9 +6,12 @@ namespace dxvk {
D3D10Multithread::D3D10Multithread(
IUnknown* pParent,
BOOL Protected)
BOOL Protected,
BOOL Force)
: m_parent (pParent),
m_protected (Protected) {
m_protected (Protected || Force),
m_enabled (Protected),
m_forced (Force) {
}
@ -49,12 +52,18 @@ namespace dxvk {
BOOL STDMETHODCALLTYPE D3D10Multithread::SetMultithreadProtected(
BOOL bMTProtect) {
return std::exchange(m_protected, bMTProtect);
BOOL result = m_enabled;
m_enabled = bMTProtect;
if (!m_forced)
m_protected = m_enabled;
return result;
}
BOOL STDMETHODCALLTYPE D3D10Multithread::GetMultithreadProtected() {
return m_protected;
return m_enabled;
}
}

View File

@ -64,7 +64,8 @@ namespace dxvk {
D3D10Multithread(
IUnknown* pParent,
BOOL Protected);
BOOL Protected,
BOOL Force);
~D3D10Multithread();
@ -95,6 +96,8 @@ namespace dxvk {
IUnknown* m_parent;
BOOL m_protected;
BOOL m_enabled;
BOOL m_forced;
sync::RecursiveSpinlock m_mutex;

View File

@ -6,7 +6,6 @@ namespace dxvk {
class D3D10Device;
class D3D11Device;
class D3D11DeviceContext;
class D3D11Query;
class D3D10Query : public ID3D10Predicate {

View File

@ -1,326 +0,0 @@
#include "d3d10_reflection.h"
namespace dxvk {
D3D10ShaderReflectionType::D3D10ShaderReflectionType(
ID3D11ShaderReflectionType* d3d11)
: m_d3d11(d3d11) {
}
D3D10ShaderReflectionType::~D3D10ShaderReflectionType() {
}
HRESULT STDMETHODCALLTYPE D3D10ShaderReflectionType::GetDesc(
D3D10_SHADER_TYPE_DESC* pDesc) {
D3D11_SHADER_TYPE_DESC d3d11Desc;
HRESULT hr = m_d3d11->GetDesc(&d3d11Desc);
if (FAILED(hr))
return hr;
pDesc->Class = D3D10_SHADER_VARIABLE_CLASS(d3d11Desc.Class);
pDesc->Type = D3D10_SHADER_VARIABLE_TYPE (d3d11Desc.Type);
pDesc->Rows = d3d11Desc.Rows;
pDesc->Columns = d3d11Desc.Columns;
pDesc->Elements = d3d11Desc.Elements;
pDesc->Members = d3d11Desc.Members;
pDesc->Offset = d3d11Desc.Offset;
return S_OK;
}
ID3D10ShaderReflectionType* STDMETHODCALLTYPE D3D10ShaderReflectionType::GetMemberTypeByIndex(
UINT Index) {
return FindMemberType(m_d3d11->GetMemberTypeByIndex(Index));
}
ID3D10ShaderReflectionType* STDMETHODCALLTYPE D3D10ShaderReflectionType::GetMemberTypeByName(
const char* Name) {
return FindMemberType(m_d3d11->GetMemberTypeByName(Name));
}
const char* STDMETHODCALLTYPE D3D10ShaderReflectionType::GetMemberTypeName(
UINT Index) {
return m_d3d11->GetMemberTypeName(Index);
}
ID3D10ShaderReflectionType* D3D10ShaderReflectionType::FindMemberType(
ID3D11ShaderReflectionType* pMemberType) {
if (!pMemberType)
return nullptr;
auto entry = m_members.find(pMemberType);
if (entry == m_members.end()) {
entry = m_members.insert({ pMemberType,
std::make_unique<D3D10ShaderReflectionType>(pMemberType) }).first;
}
return entry->second.get();
}
D3D10ShaderReflectionVariable::D3D10ShaderReflectionVariable(ID3D11ShaderReflectionVariable* d3d11)
: m_d3d11(d3d11), m_type(m_d3d11->GetType()) {
}
D3D10ShaderReflectionVariable::~D3D10ShaderReflectionVariable() {
}
HRESULT STDMETHODCALLTYPE D3D10ShaderReflectionVariable::GetDesc(
D3D10_SHADER_VARIABLE_DESC* pDesc) {
D3D11_SHADER_VARIABLE_DESC d3d11Desc;
HRESULT hr = m_d3d11->GetDesc(&d3d11Desc);
if (FAILED(hr))
return hr;
pDesc->Name = d3d11Desc.Name;
pDesc->StartOffset = d3d11Desc.StartOffset;
pDesc->Size = d3d11Desc.Size;
pDesc->uFlags = d3d11Desc.uFlags;
pDesc->DefaultValue = d3d11Desc.DefaultValue;
return S_OK;
}
ID3D10ShaderReflectionType* STDMETHODCALLTYPE D3D10ShaderReflectionVariable::GetType() {
return &m_type;
}
D3D10ShaderReflectionConstantBuffer::D3D10ShaderReflectionConstantBuffer(
ID3D11ShaderReflectionConstantBuffer* d3d11)
: m_d3d11(d3d11) {
}
D3D10ShaderReflectionConstantBuffer::~D3D10ShaderReflectionConstantBuffer() {
}
HRESULT STDMETHODCALLTYPE D3D10ShaderReflectionConstantBuffer::GetDesc(
D3D10_SHADER_BUFFER_DESC* pDesc) {
D3D11_SHADER_BUFFER_DESC d3d11Desc;
HRESULT hr = m_d3d11->GetDesc(&d3d11Desc);
if (FAILED(hr))
return hr;
pDesc->Name = d3d11Desc.Name;
pDesc->Type = D3D10_CBUFFER_TYPE(d3d11Desc.Type);
pDesc->Variables = d3d11Desc.Variables;
pDesc->Size = d3d11Desc.Size;
pDesc->uFlags = d3d11Desc.uFlags;
return S_OK;
}
ID3D10ShaderReflectionVariable* STDMETHODCALLTYPE D3D10ShaderReflectionConstantBuffer::GetVariableByIndex(
UINT Index) {
return FindVariable(m_d3d11->GetVariableByIndex(Index));
}
ID3D10ShaderReflectionVariable* STDMETHODCALLTYPE D3D10ShaderReflectionConstantBuffer::GetVariableByName(
LPCSTR Name) {
return FindVariable(m_d3d11->GetVariableByName(Name));
}
ID3D10ShaderReflectionVariable* D3D10ShaderReflectionConstantBuffer::FindVariable(
ID3D11ShaderReflectionVariable* pVariable) {
if (!pVariable)
return nullptr;
auto entry = m_variables.find(pVariable);
if (entry == m_variables.end()) {
entry = m_variables.emplace(
std::piecewise_construct,
std::forward_as_tuple(pVariable),
std::forward_as_tuple(pVariable)).first;
}
return &entry->second;
}
D3D10ShaderReflection::D3D10ShaderReflection(ID3D11ShaderReflection* d3d11)
: m_d3d11(d3d11) {
}
D3D10ShaderReflection::~D3D10ShaderReflection() {
}
HRESULT STDMETHODCALLTYPE D3D10ShaderReflection::QueryInterface(
REFIID riid,
void** ppvObject) {
if (ppvObject == nullptr)
return E_POINTER;
static const GUID IID_ID3D10ShaderReflection
= {0xd40e20b6,0xf8f7,0x42ad,{0xab,0x20,0x4b,0xaf,0x8f,0x15,0xdf,0xaa}};
if (riid == __uuidof(IUnknown)
|| riid == IID_ID3D10ShaderReflection) {
*ppvObject = ref(this);
return S_OK;
}
return E_NOINTERFACE;
}
HRESULT STDMETHODCALLTYPE D3D10ShaderReflection::GetDesc(
D3D10_SHADER_DESC* pDesc) {
D3D11_SHADER_DESC d3d11Desc;
HRESULT hr = m_d3d11->GetDesc(&d3d11Desc);
if (FAILED(hr))
return hr;
pDesc->Version = d3d11Desc.Version;
pDesc->Creator = d3d11Desc.Creator;
pDesc->Flags = d3d11Desc.Flags;
pDesc->ConstantBuffers = d3d11Desc.ConstantBuffers;
pDesc->BoundResources = d3d11Desc.BoundResources;
pDesc->InputParameters = d3d11Desc.InputParameters;
pDesc->OutputParameters = d3d11Desc.OutputParameters;
pDesc->InstructionCount = d3d11Desc.InstructionCount;
pDesc->TempRegisterCount = d3d11Desc.TempRegisterCount;
pDesc->TempArrayCount = d3d11Desc.TempArrayCount;
pDesc->DefCount = d3d11Desc.DefCount;
pDesc->DclCount = d3d11Desc.DclCount;
pDesc->TextureNormalInstructions = d3d11Desc.TextureNormalInstructions;
pDesc->TextureLoadInstructions = d3d11Desc.TextureLoadInstructions;
pDesc->TextureCompInstructions = d3d11Desc.TextureCompInstructions;
pDesc->TextureBiasInstructions = d3d11Desc.TextureBiasInstructions;
pDesc->TextureGradientInstructions = d3d11Desc.TextureGradientInstructions;
pDesc->FloatInstructionCount = d3d11Desc.FloatInstructionCount;
pDesc->IntInstructionCount = d3d11Desc.IntInstructionCount;
pDesc->UintInstructionCount = d3d11Desc.UintInstructionCount;
pDesc->StaticFlowControlCount = d3d11Desc.StaticFlowControlCount;
pDesc->DynamicFlowControlCount = d3d11Desc.DynamicFlowControlCount;
pDesc->MacroInstructionCount = d3d11Desc.MacroInstructionCount;
pDesc->ArrayInstructionCount = d3d11Desc.ArrayInstructionCount;
pDesc->CutInstructionCount = d3d11Desc.CutInstructionCount;
pDesc->EmitInstructionCount = d3d11Desc.EmitInstructionCount;
pDesc->GSOutputTopology = D3D10_PRIMITIVE_TOPOLOGY(d3d11Desc.GSOutputTopology);
pDesc->GSMaxOutputVertexCount = d3d11Desc.GSMaxOutputVertexCount;
return S_OK;
}
ID3D10ShaderReflectionConstantBuffer* STDMETHODCALLTYPE
D3D10ShaderReflection::GetConstantBufferByIndex(
UINT Index) {
return FindConstantBuffer(m_d3d11->GetConstantBufferByIndex(Index));
}
ID3D10ShaderReflectionConstantBuffer* STDMETHODCALLTYPE
D3D10ShaderReflection::GetConstantBufferByName(
LPCSTR Name) {
return FindConstantBuffer(m_d3d11->GetConstantBufferByName(Name));
}
HRESULT STDMETHODCALLTYPE D3D10ShaderReflection::GetInputParameterDesc(
UINT ParameterIndex,
D3D10_SIGNATURE_PARAMETER_DESC* pDesc) {
D3D11_SIGNATURE_PARAMETER_DESC d3d11Desc;
HRESULT hr = m_d3d11->GetInputParameterDesc(ParameterIndex, &d3d11Desc);
if (FAILED(hr))
return hr;
ConvertSignatureParameterDesc(&d3d11Desc, pDesc);
return S_OK;
}
HRESULT STDMETHODCALLTYPE D3D10ShaderReflection::GetOutputParameterDesc(
UINT ParameterIndex,
D3D10_SIGNATURE_PARAMETER_DESC* pDesc) {
D3D11_SIGNATURE_PARAMETER_DESC d3d11Desc;
HRESULT hr = m_d3d11->GetOutputParameterDesc(ParameterIndex, &d3d11Desc);
if (FAILED(hr))
return hr;
ConvertSignatureParameterDesc(&d3d11Desc, pDesc);
return S_OK;
}
HRESULT STDMETHODCALLTYPE D3D10ShaderReflection::GetResourceBindingDesc(
UINT ResourceIndex,
D3D10_SHADER_INPUT_BIND_DESC* pDesc) {
D3D11_SHADER_INPUT_BIND_DESC d3d11Desc;
HRESULT hr = m_d3d11->GetResourceBindingDesc(
ResourceIndex, &d3d11Desc);
if (FAILED(hr))
return hr;
pDesc->Name = d3d11Desc.Name;
pDesc->Type = D3D10_SHADER_INPUT_TYPE(d3d11Desc.Type);
pDesc->BindPoint = d3d11Desc.BindPoint;
pDesc->BindCount = d3d11Desc.BindCount;
pDesc->uFlags = d3d11Desc.uFlags;
pDesc->ReturnType = D3D10_RESOURCE_RETURN_TYPE(d3d11Desc.ReturnType);
pDesc->Dimension = D3D10_SRV_DIMENSION (d3d11Desc.Dimension);
pDesc->NumSamples = d3d11Desc.NumSamples;
return S_OK;
}
ID3D10ShaderReflectionConstantBuffer* D3D10ShaderReflection::FindConstantBuffer(
ID3D11ShaderReflectionConstantBuffer* pConstantBuffer) {
if (!pConstantBuffer)
return nullptr;
auto entry = m_constantBuffers.find(pConstantBuffer);
if (entry == m_constantBuffers.end()) {
entry = m_constantBuffers.emplace(
std::piecewise_construct,
std::forward_as_tuple(pConstantBuffer),
std::forward_as_tuple(pConstantBuffer)).first;
}
return &entry->second;
}
void D3D10ShaderReflection::ConvertSignatureParameterDesc(
const D3D11_SIGNATURE_PARAMETER_DESC* pSrcDesc,
D3D10_SIGNATURE_PARAMETER_DESC* pDstDesc) {
pDstDesc->SemanticName = pSrcDesc->SemanticName;
pDstDesc->SemanticIndex = pSrcDesc->SemanticIndex;
pDstDesc->Register = pSrcDesc->Register;
pDstDesc->SystemValueType = D3D10_NAME(pSrcDesc->SystemValueType);
pDstDesc->ComponentType = D3D10_REGISTER_COMPONENT_TYPE(pSrcDesc->ComponentType);
pDstDesc->Mask = pSrcDesc->Mask;
pDstDesc->ReadWriteMask = pSrcDesc->ReadWriteMask;
}
}

View File

@ -1,163 +0,0 @@
#pragma once
#include <unordered_map>
#include <vector>
#include "d3d10_include.h"
#include <d3d10shader.h>
#include <d3d11shader.h>
namespace dxvk {
class D3D10ShaderReflectionType : public ID3D10ShaderReflectionType {
public:
D3D10ShaderReflectionType(
ID3D11ShaderReflectionType* d3d11);
~D3D10ShaderReflectionType();
HRESULT STDMETHODCALLTYPE GetDesc(
D3D10_SHADER_TYPE_DESC* pDesc);
ID3D10ShaderReflectionType* STDMETHODCALLTYPE GetMemberTypeByIndex(
UINT Index);
ID3D10ShaderReflectionType* STDMETHODCALLTYPE GetMemberTypeByName(
const char* Name);
const char* STDMETHODCALLTYPE GetMemberTypeName(
UINT Index);
ID3D11ShaderReflectionType* GetD3D11Iface() {
return m_d3d11;
}
private:
ID3D11ShaderReflectionType* m_d3d11;
std::unordered_map<
ID3D11ShaderReflectionType*,
std::unique_ptr<D3D10ShaderReflectionType>> m_members;
ID3D10ShaderReflectionType* FindMemberType(
ID3D11ShaderReflectionType* pMemberType);
};
class D3D10ShaderReflectionVariable : public ID3D10ShaderReflectionVariable {
public:
D3D10ShaderReflectionVariable(
ID3D11ShaderReflectionVariable* d3d11);
~D3D10ShaderReflectionVariable();
HRESULT STDMETHODCALLTYPE GetDesc(
D3D10_SHADER_VARIABLE_DESC* pDesc);
ID3D10ShaderReflectionType* STDMETHODCALLTYPE GetType();
ID3D11ShaderReflectionVariable* STDMETHODCALLTYPE GetD3D11Iface() {
return m_d3d11;
}
private:
ID3D11ShaderReflectionVariable* m_d3d11;
D3D10ShaderReflectionType m_type;
};
class D3D10ShaderReflectionConstantBuffer : public ID3D10ShaderReflectionConstantBuffer {
public:
D3D10ShaderReflectionConstantBuffer(
ID3D11ShaderReflectionConstantBuffer* d3d11);
~D3D10ShaderReflectionConstantBuffer();
HRESULT STDMETHODCALLTYPE GetDesc(
D3D10_SHADER_BUFFER_DESC* pDesc);
ID3D10ShaderReflectionVariable* STDMETHODCALLTYPE GetVariableByIndex(
UINT Index);
ID3D10ShaderReflectionVariable* STDMETHODCALLTYPE GetVariableByName(
LPCSTR Name);
ID3D11ShaderReflectionConstantBuffer* STDMETHODCALLTYPE GetD3D11Iface() {
return m_d3d11;
}
private:
ID3D11ShaderReflectionConstantBuffer* m_d3d11;
std::unordered_map<
ID3D11ShaderReflectionVariable*,
D3D10ShaderReflectionVariable> m_variables;
ID3D10ShaderReflectionVariable* FindVariable(
ID3D11ShaderReflectionVariable* pVariable);
};
class D3D10ShaderReflection : public ComObject<ID3D10ShaderReflection> {
public:
D3D10ShaderReflection(ID3D11ShaderReflection* d3d11);
~D3D10ShaderReflection();
HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid,
void** ppvObject);
HRESULT STDMETHODCALLTYPE GetDesc(
D3D10_SHADER_DESC* pDesc);
ID3D10ShaderReflectionConstantBuffer* STDMETHODCALLTYPE GetConstantBufferByIndex(
UINT Index);
ID3D10ShaderReflectionConstantBuffer* STDMETHODCALLTYPE GetConstantBufferByName(
LPCSTR Name);
HRESULT STDMETHODCALLTYPE GetInputParameterDesc(
UINT ParameterIndex,
D3D10_SIGNATURE_PARAMETER_DESC* pDesc);
HRESULT STDMETHODCALLTYPE GetOutputParameterDesc(
UINT ParameterIndex,
D3D10_SIGNATURE_PARAMETER_DESC* pDesc);
HRESULT STDMETHODCALLTYPE GetResourceBindingDesc(
UINT ResourceIndex,
D3D10_SHADER_INPUT_BIND_DESC* pDesc);
private:
Com<ID3D11ShaderReflection> m_d3d11;
std::unordered_map<
ID3D11ShaderReflectionConstantBuffer*,
D3D10ShaderReflectionConstantBuffer> m_constantBuffers;
ID3D10ShaderReflectionConstantBuffer* FindConstantBuffer(
ID3D11ShaderReflectionConstantBuffer* pConstantBuffer);
void ConvertSignatureParameterDesc(
const D3D11_SIGNATURE_PARAMETER_DESC* pSrcDesc,
D3D10_SIGNATURE_PARAMETER_DESC* pDstDesc);
};
}

View File

@ -1,432 +0,0 @@
#include "d3d10_state_block.h"
#define MAKE_STATE_TYPE(field, count) { offsetof(D3D10_STATE_BLOCK_MASK, field), count }
namespace dxvk {
static const std::array<std::pair<size_t, size_t>, 24> g_stateTypes = {{
MAKE_STATE_TYPE(SOBuffers, 1),
MAKE_STATE_TYPE(OMRenderTargets, 1),
MAKE_STATE_TYPE(OMDepthStencilState, 1),
MAKE_STATE_TYPE(OMBlendState, 1),
MAKE_STATE_TYPE(VS, 1),
MAKE_STATE_TYPE(VSSamplers, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT),
MAKE_STATE_TYPE(VSShaderResources, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT),
MAKE_STATE_TYPE(VSConstantBuffers, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT),
MAKE_STATE_TYPE(GS, 1),
MAKE_STATE_TYPE(GSSamplers, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT),
MAKE_STATE_TYPE(GSShaderResources, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT),
MAKE_STATE_TYPE(GSConstantBuffers, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT),
MAKE_STATE_TYPE(PS, 1),
MAKE_STATE_TYPE(PSSamplers, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT),
MAKE_STATE_TYPE(PSShaderResources, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT),
MAKE_STATE_TYPE(PSConstantBuffers, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT),
MAKE_STATE_TYPE(IAVertexBuffers, D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT),
MAKE_STATE_TYPE(IAIndexBuffer, 1),
MAKE_STATE_TYPE(IAInputLayout, 1),
MAKE_STATE_TYPE(IAPrimitiveTopology, 1),
MAKE_STATE_TYPE(RSViewports, 1),
MAKE_STATE_TYPE(RSScissorRects, 1),
MAKE_STATE_TYPE(RSRasterizerState, 1),
MAKE_STATE_TYPE(Predication, 1),
}};
D3D10StateBlock::D3D10StateBlock(
ID3D10Device* pDevice,
const D3D10_STATE_BLOCK_MASK* pMask)
: m_device(pDevice), m_mask(*pMask) {
}
D3D10StateBlock::~D3D10StateBlock() {
}
HRESULT STDMETHODCALLTYPE D3D10StateBlock::QueryInterface(
REFIID riid,
void** ppvObject) {
if (ppvObject == nullptr)
return E_POINTER;
*ppvObject = nullptr;
if (riid == __uuidof(IUnknown)
|| riid == __uuidof(ID3D10StateBlock)) {
*ppvObject = ref(this);
return S_OK;
}
Logger::warn("D3D10StateBlock::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
return E_NOINTERFACE;
}
HRESULT STDMETHODCALLTYPE D3D10StateBlock::Capture() {
m_state = D3D10_STATE_BLOCK_STATE();
if (TestBit(&m_mask.VS, 0)) m_device->VSGetShader(&m_state.vs);
if (TestBit(&m_mask.GS, 0)) m_device->GSGetShader(&m_state.gs);
if (TestBit(&m_mask.PS, 0)) m_device->PSGetShader(&m_state.ps);
for (uint32_t i = 0; i < D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) {
if (TestBit(m_mask.VSSamplers, i)) m_device->VSGetSamplers(i, 1, &m_state.vsSso[i]);
if (TestBit(m_mask.GSSamplers, i)) m_device->GSGetSamplers(i, 1, &m_state.gsSso[i]);
if (TestBit(m_mask.PSSamplers, i)) m_device->PSGetSamplers(i, 1, &m_state.psSso[i]);
}
for (uint32_t i = 0; i < D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) {
if (TestBit(m_mask.VSShaderResources, i)) m_device->VSGetShaderResources(i, 1, &m_state.vsSrv[i]);
if (TestBit(m_mask.GSShaderResources, i)) m_device->GSGetShaderResources(i, 1, &m_state.gsSrv[i]);
if (TestBit(m_mask.PSShaderResources, i)) m_device->PSGetShaderResources(i, 1, &m_state.psSrv[i]);
}
for (uint32_t i = 0; i < D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) {
if (TestBit(m_mask.VSConstantBuffers, i)) m_device->VSGetConstantBuffers(i, 1, &m_state.vsCbo[i]);
if (TestBit(m_mask.GSConstantBuffers, i)) m_device->GSGetConstantBuffers(i, 1, &m_state.gsCbo[i]);
if (TestBit(m_mask.PSConstantBuffers, i)) m_device->PSGetConstantBuffers(i, 1, &m_state.psCbo[i]);
}
for (uint32_t i = 0; i < D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) {
if (TestBit(m_mask.IAVertexBuffers, i)) {
m_device->IAGetVertexBuffers(i, 1,
&m_state.iaVertexBuffers[i],
&m_state.iaVertexOffsets[i],
&m_state.iaVertexStrides[i]);
}
}
if (TestBit(&m_mask.IAIndexBuffer, 0)) {
m_device->IAGetIndexBuffer(
&m_state.iaIndexBuffer,
&m_state.iaIndexFormat,
&m_state.iaIndexOffset);
}
if (TestBit(&m_mask.IAInputLayout, 0))
m_device->IAGetInputLayout(&m_state.iaInputLayout);
if (TestBit(&m_mask.IAPrimitiveTopology, 0))
m_device->IAGetPrimitiveTopology(&m_state.iaTopology);
if (TestBit(&m_mask.OMRenderTargets, 0)) {
m_device->OMGetRenderTargets(
D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT,
&m_state.omRtv[0], &m_state.omDsv);
}
if (TestBit(&m_mask.OMDepthStencilState, 0)) {
m_device->OMGetDepthStencilState(
&m_state.omDepthStencilState,
&m_state.omStencilRef);
}
if (TestBit(&m_mask.OMBlendState, 0)) {
m_device->OMGetBlendState(
&m_state.omBlendState,
m_state.omBlendFactor,
&m_state.omSampleMask);
}
if (TestBit(&m_mask.RSViewports, 0)) {
m_device->RSGetViewports(&m_state.rsViewportCount, nullptr);
m_device->RSGetViewports(&m_state.rsViewportCount, m_state.rsViewports);
}
if (TestBit(&m_mask.RSScissorRects, 0)) {
m_device->RSGetScissorRects(&m_state.rsScissorCount, nullptr);
m_device->RSGetScissorRects(&m_state.rsScissorCount, m_state.rsScissors);
}
if (TestBit(&m_mask.RSRasterizerState, 0))
m_device->RSGetState(&m_state.rsState);
if (TestBit(&m_mask.SOBuffers, 0)) {
m_device->SOGetTargets(
D3D10_SO_BUFFER_SLOT_COUNT,
&m_state.soBuffers[0],
&m_state.soOffsets[0]);
}
if (TestBit(&m_mask.Predication, 0))
m_device->GetPredication(&m_state.predicate, &m_state.predicateInvert);
return S_OK;
}
HRESULT STDMETHODCALLTYPE D3D10StateBlock::Apply() {
if (TestBit(&m_mask.VS, 0)) m_device->VSSetShader(m_state.vs.ptr());
if (TestBit(&m_mask.GS, 0)) m_device->GSSetShader(m_state.gs.ptr());
if (TestBit(&m_mask.PS, 0)) m_device->PSSetShader(m_state.ps.ptr());
for (uint32_t i = 0; i < D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) {
if (TestBit(m_mask.VSSamplers, i)) m_device->VSSetSamplers(i, 1, &m_state.vsSso[i]);
if (TestBit(m_mask.GSSamplers, i)) m_device->GSSetSamplers(i, 1, &m_state.gsSso[i]);
if (TestBit(m_mask.PSSamplers, i)) m_device->PSSetSamplers(i, 1, &m_state.psSso[i]);
}
for (uint32_t i = 0; i < D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) {
if (TestBit(m_mask.VSShaderResources, i)) m_device->VSSetShaderResources(i, 1, &m_state.vsSrv[i]);
if (TestBit(m_mask.GSShaderResources, i)) m_device->GSSetShaderResources(i, 1, &m_state.gsSrv[i]);
if (TestBit(m_mask.PSShaderResources, i)) m_device->PSSetShaderResources(i, 1, &m_state.psSrv[i]);
}
for (uint32_t i = 0; i < D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) {
if (TestBit(m_mask.VSConstantBuffers, i)) m_device->VSSetConstantBuffers(i, 1, &m_state.vsCbo[i]);
if (TestBit(m_mask.GSConstantBuffers, i)) m_device->GSSetConstantBuffers(i, 1, &m_state.gsCbo[i]);
if (TestBit(m_mask.PSConstantBuffers, i)) m_device->PSSetConstantBuffers(i, 1, &m_state.psCbo[i]);
}
for (uint32_t i = 0; i < D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) {
if (TestBit(m_mask.IAVertexBuffers, i)) {
m_device->IASetVertexBuffers(i, 1,
&m_state.iaVertexBuffers[i],
&m_state.iaVertexOffsets[i],
&m_state.iaVertexStrides[i]);
}
}
if (TestBit(&m_mask.IAIndexBuffer, 0)) {
m_device->IASetIndexBuffer(
m_state.iaIndexBuffer.ptr(),
m_state.iaIndexFormat,
m_state.iaIndexOffset);
}
if (TestBit(&m_mask.IAInputLayout, 0))
m_device->IASetInputLayout(m_state.iaInputLayout.ptr());
if (TestBit(&m_mask.IAPrimitiveTopology, 0))
m_device->IASetPrimitiveTopology(m_state.iaTopology);
if (TestBit(&m_mask.OMRenderTargets, 0)) {
m_device->OMSetRenderTargets(
D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT,
&m_state.omRtv[0], m_state.omDsv.ptr());
}
if (TestBit(&m_mask.OMDepthStencilState, 0)) {
m_device->OMSetDepthStencilState(
m_state.omDepthStencilState.ptr(),
m_state.omStencilRef);
}
if (TestBit(&m_mask.OMBlendState, 0)) {
m_device->OMSetBlendState(
m_state.omBlendState.ptr(),
m_state.omBlendFactor,
m_state.omSampleMask);
}
if (TestBit(&m_mask.RSViewports, 0))
m_device->RSSetViewports(m_state.rsViewportCount, m_state.rsViewports);
if (TestBit(&m_mask.RSScissorRects, 0))
m_device->RSSetScissorRects(m_state.rsScissorCount, m_state.rsScissors);
if (TestBit(&m_mask.RSRasterizerState, 0))
m_device->RSSetState(m_state.rsState.ptr());
if (TestBit(&m_mask.SOBuffers, 0)) {
m_device->SOSetTargets(
D3D10_SO_BUFFER_SLOT_COUNT,
&m_state.soBuffers[0],
&m_state.soOffsets[0]);
}
if (TestBit(&m_mask.Predication, 0))
m_device->SetPredication(m_state.predicate.ptr(), m_state.predicateInvert);
return S_OK;
}
HRESULT STDMETHODCALLTYPE D3D10StateBlock::GetDevice(
ID3D10Device** ppDevice) {
Logger::err("D3D10StateBlock::GetDevice: Stub");
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE D3D10StateBlock::ReleaseAllDeviceObjects() {
// Not entirely sure if this is correct?
m_state = D3D10_STATE_BLOCK_STATE();
return S_OK;
}
BOOL D3D10StateBlock::TestBit(
const BYTE* pMask,
UINT Idx) {
uint32_t byte = Idx / 8;
uint32_t bit = Idx % 8;
return (pMask[byte] & (1 << bit)) != 0;
}
}
extern "C" {
using namespace dxvk;
HRESULT STDMETHODCALLTYPE D3D10CreateStateBlock(
ID3D10Device* pDevice,
D3D10_STATE_BLOCK_MASK* pStateBlockMask,
ID3D10StateBlock** ppStateBlock) {
InitReturnPtr(ppStateBlock);
if (!pDevice || !pStateBlockMask || !ppStateBlock)
return E_INVALIDARG;
*ppStateBlock = ref(new D3D10StateBlock(pDevice, pStateBlockMask));
return S_OK;
}
HRESULT STDMETHODCALLTYPE D3D10StateBlockMaskEnableCapture(
D3D10_STATE_BLOCK_MASK* pMask,
D3D10_DEVICE_STATE_TYPES StateType,
UINT StartIdx,
UINT Count) {
if (!pMask || !StateType || StateType > g_stateTypes.size())
return E_INVALIDARG;
auto pair = g_stateTypes[uint32_t(StateType) - 1];
auto mask = reinterpret_cast<BYTE*>(pMask) + pair.first;
if (StartIdx + Count > pair.second)
return E_INVALIDARG;
for (uint32_t i = StartIdx; i < StartIdx + Count; i++) {
uint32_t byte = i / 8;
uint32_t bit = i % 8;
mask[byte] |= 1 << bit;
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE D3D10StateBlockMaskDisableCapture(
D3D10_STATE_BLOCK_MASK* pMask,
D3D10_DEVICE_STATE_TYPES StateType,
UINT StartIdx,
UINT Count) {
if (!pMask || !StateType || StateType > g_stateTypes.size())
return E_INVALIDARG;
auto pair = g_stateTypes[uint32_t(StateType) - 1];
auto mask = reinterpret_cast<BYTE*>(pMask) + pair.first;
if (StartIdx + Count > pair.second)
return E_INVALIDARG;
for (uint32_t i = StartIdx; i < StartIdx + Count; i++) {
uint32_t byte = i / 8;
uint32_t bit = i % 8;
mask[byte] &= ~(1 << bit);
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE D3D10StateBlockMaskEnableAll(
D3D10_STATE_BLOCK_MASK* pMask) {
if (!pMask)
return E_INVALIDARG;
*pMask = D3D10_STATE_BLOCK_MASK();
for (size_t i = 0; i < g_stateTypes.size(); i++) {
D3D10StateBlockMaskEnableCapture(pMask,
D3D10_DEVICE_STATE_TYPES(i + 1),
0, g_stateTypes[i].second);
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE D3D10StateBlockMaskDisableAll(
D3D10_STATE_BLOCK_MASK* pMask) {
if (!pMask)
return E_INVALIDARG;
*pMask = D3D10_STATE_BLOCK_MASK();
return S_OK;
}
BOOL STDMETHODCALLTYPE D3D10StateBlockMaskGetSetting(
D3D10_STATE_BLOCK_MASK* pMask,
D3D10_DEVICE_STATE_TYPES StateType,
UINT Idx) {
if (!pMask || !StateType || StateType > g_stateTypes.size())
return FALSE;
auto pair = g_stateTypes[uint32_t(StateType) - 1];
auto mask = reinterpret_cast<BYTE*>(pMask) + pair.first;
if (Idx >= pair.second)
return FALSE;
uint32_t byte = Idx / 8;
uint32_t bit = Idx % 8;
return (mask[byte] & (1 << bit)) != 0;
}
HRESULT STDMETHODCALLTYPE D3D10StateBlockMaskDifference(
D3D10_STATE_BLOCK_MASK* pA,
D3D10_STATE_BLOCK_MASK* pB,
D3D10_STATE_BLOCK_MASK* pResult) {
if (!pA || !pB || !pResult)
return E_INVALIDARG;
auto a = reinterpret_cast<const BYTE*>(pA);
auto b = reinterpret_cast<const BYTE*>(pB);
auto r = reinterpret_cast<BYTE*>(pResult);
for (size_t i = 0; i < sizeof(D3D10_STATE_BLOCK_MASK); i++)
r[i] = a[i] ^ b[i];
return S_OK;
}
HRESULT STDMETHODCALLTYPE D3D10StateBlockMaskIntersect(
D3D10_STATE_BLOCK_MASK* pA,
D3D10_STATE_BLOCK_MASK* pB,
D3D10_STATE_BLOCK_MASK* pResult) {
if (!pA || !pB || !pResult)
return E_INVALIDARG;
auto a = reinterpret_cast<const BYTE*>(pA);
auto b = reinterpret_cast<const BYTE*>(pB);
auto r = reinterpret_cast<BYTE*>(pResult);
for (size_t i = 0; i < sizeof(D3D10_STATE_BLOCK_MASK); i++)
r[i] = a[i] & b[i];
return S_OK;
}
HRESULT STDMETHODCALLTYPE D3D10StateBlockMaskUnion(
D3D10_STATE_BLOCK_MASK* pA,
D3D10_STATE_BLOCK_MASK* pB,
D3D10_STATE_BLOCK_MASK* pResult) {
if (!pA || !pB || !pResult)
return E_INVALIDARG;
auto a = reinterpret_cast<const BYTE*>(pA);
auto b = reinterpret_cast<const BYTE*>(pB);
auto r = reinterpret_cast<BYTE*>(pResult);
for (size_t i = 0; i < sizeof(D3D10_STATE_BLOCK_MASK); i++)
r[i] = a[i] | b[i];
return S_OK;
}
}

View File

@ -1,82 +0,0 @@
#pragma once
#include "d3d10_include.h"
#include "d3d10_interfaces.h"
namespace dxvk {
struct D3D10_STATE_BLOCK_STATE {
Com<ID3D10VertexShader> vs = { };
Com<ID3D10SamplerState> vsSso[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT] = { };
Com<ID3D10ShaderResourceView> vsSrv[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = { };
Com<ID3D10Buffer> vsCbo[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = { };
Com<ID3D10GeometryShader> gs = { };
Com<ID3D10SamplerState> gsSso[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT] = { };
Com<ID3D10ShaderResourceView> gsSrv[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = { };
Com<ID3D10Buffer> gsCbo[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = { };
Com<ID3D10PixelShader> ps = { };
Com<ID3D10SamplerState> psSso[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT] = { };
Com<ID3D10ShaderResourceView> psSrv[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = { };
Com<ID3D10Buffer> psCbo[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = { };
Com<ID3D10Buffer> iaVertexBuffers[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT] = { };
UINT iaVertexOffsets[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT] = { };
UINT iaVertexStrides[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT] = { };
Com<ID3D10Buffer> iaIndexBuffer = { };
DXGI_FORMAT iaIndexFormat = DXGI_FORMAT_UNKNOWN;
UINT iaIndexOffset = 0;
Com<ID3D10InputLayout> iaInputLayout = nullptr;
D3D10_PRIMITIVE_TOPOLOGY iaTopology = D3D10_PRIMITIVE_TOPOLOGY_UNDEFINED;
Com<ID3D10RenderTargetView> omRtv[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT] = { };
Com<ID3D10DepthStencilView> omDsv = { };
Com<ID3D10DepthStencilState> omDepthStencilState = { };
UINT omStencilRef = 0;
Com<ID3D10BlendState> omBlendState = { };
FLOAT omBlendFactor[4] = { };
UINT omSampleMask = 0;
UINT rsViewportCount = 0;
D3D10_VIEWPORT rsViewports[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE] = { };
UINT rsScissorCount = 0;
RECT rsScissors [D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE] = { };
Com<ID3D10RasterizerState> rsState = { };
Com<ID3D10Buffer> soBuffers[D3D10_SO_BUFFER_SLOT_COUNT] = { };
UINT soOffsets[D3D10_SO_BUFFER_SLOT_COUNT] = { };
Com<ID3D10Predicate> predicate = { };
BOOL predicateInvert = FALSE;
};
class D3D10StateBlock : public ComObject<ID3D10StateBlock> {
public:
D3D10StateBlock(
ID3D10Device* pDevice,
const D3D10_STATE_BLOCK_MASK* pMask);
~D3D10StateBlock();
HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid,
void** ppvObject);
HRESULT STDMETHODCALLTYPE Capture();
HRESULT STDMETHODCALLTYPE Apply();
HRESULT STDMETHODCALLTYPE GetDevice(
ID3D10Device** ppDevice);
HRESULT STDMETHODCALLTYPE ReleaseAllDeviceObjects();
private:
Com<ID3D10Device> m_device;
D3D10_STATE_BLOCK_MASK m_mask;
D3D10_STATE_BLOCK_STATE m_state;
static BOOL TestBit(
const BYTE* pMask,
UINT Idx);
};
}

9
src/d3d10/d3d10core.sym Normal file
View File

@ -0,0 +1,9 @@
{
global:
D3D10CoreCreateDevice;
D3D10CoreGetVersion;
D3D10CoreRegisterLayers;
local:
*;
};

View File

@ -1,48 +1,30 @@
d3d10_res = wrc_generator.process('version10.rc')
d3d10_1_res = wrc_generator.process('version10_1.rc')
d3d10_core_res = wrc_generator.process('version10_core.rc')
d3d10_core_src = [
'd3d10_core.cpp',
]
d3d10_main_src = [
'd3d10_main.cpp',
'd3d10_reflection.cpp',
'd3d10_state_block.cpp',
]
d3d10_core_ld_args = []
d3d10_core_link_depends = []
if platform == 'windows'
d3d10_d3d11_dep = lib_d3d11
else
d3d10_core_ld_args += [ '-Wl,--version-script', join_paths(meson.current_source_dir(), 'd3d10core.sym') ]
d3d10_core_link_depends += files('d3d10core.sym')
d3d10_d3d11_dep = d3d11_dep
endif
d3d10_core_dll = shared_library('d3d10core'+dll_ext, d3d10_core_src, d3d10_core_res,
name_prefix : '',
dependencies : [ d3d11_dep ],
name_prefix : dxvk_name_prefix,
dependencies : [ d3d10_d3d11_dep ],
include_directories : dxvk_include_path,
install : true,
vs_module_defs : 'd3d10core'+def_spec_ext,
link_args : d3d10_core_ld_args,
link_depends : [ d3d10_core_link_depends ],
)
d3d10_core_dep = declare_dependency(
link_with : [ d3d10_core_dll ],
)
d3d10_deps = [ lib_d3dcompiler_43, lib_dxgi, dxbc_dep, dxvk_dep, d3d10_core_dep ]
d3d10_dll = shared_library('d3d10'+dll_ext, d3d10_main_src, d3d10_res,
name_prefix : '',
dependencies : [ d3d10_deps ],
include_directories : dxvk_include_path,
install : true,
vs_module_defs : 'd3d10'+def_spec_ext,
)
d3d10_1_dll = shared_library('d3d10_1'+dll_ext, d3d10_main_src, d3d10_1_res,
name_prefix : '',
dependencies : [ d3d10_deps ],
include_directories : dxvk_include_path,
install : true,
vs_module_defs : 'd3d10_1'+def_spec_ext,
)
d3d10_dep = declare_dependency(
link_with : [ d3d10_dll, d3d10_1_dll, d3d10_core_dll ],
include_directories : [ dxvk_include_path ],
)

View File

@ -1,32 +0,0 @@
#include <windows.h>
// DLL version information.
VS_VERSION_INFO VERSIONINFO
FILEVERSION 10,0,17763,1
PRODUCTVERSION 10,0,17763,1
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080904b0"
BEGIN
VALUE "CompanyName", "DXVK"
VALUE "FileDescription", "Direct3D 10 Runtime"
VALUE "FileVersion", "10.0.17763.1 (WinBuild.160101.0800)"
VALUE "InternalName", "D3D10.dll"
VALUE "LegalCopyright", "zlib/libpng license"
VALUE "OriginalFilename", "D3D10.dll"
VALUE "ProductName", "DXVK"
VALUE "ProductVersion", "10.0.17763.1"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0809, 1200
END
END

View File

@ -1,32 +0,0 @@
#include <windows.h>
// DLL version information.
VS_VERSION_INFO VERSIONINFO
FILEVERSION 10,0,17763,1
PRODUCTVERSION 10,0,17763,1
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080904b0"
BEGIN
VALUE "CompanyName", "DXVK"
VALUE "FileDescription", "Direct3D 10.1 Runtime"
VALUE "FileVersion", "10.0.17763.1 (WinBuild.160101.0800)"
VALUE "InternalName", "D3D10_1.dll"
VALUE "LegalCopyright", "zlib/libpng license"
VALUE "OriginalFilename", "D3D10_1.dll"
VALUE "ProductName", "DXVK"
VALUE "ProductVersion", "10.0.17763.1"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0809, 1200
END
END

10
src/d3d11/d3d11.sym Normal file
View File

@ -0,0 +1,10 @@
{
global:
D3D11CoreCreateDevice;
D3D11CreateDevice;
D3D11CreateDeviceAndSwapChain;
D3D11On12CreateDevice;
local:
*;
};

View File

@ -1,8 +1,10 @@
#include "d3d11_annotation.h"
#include "d3d11_context.h"
#include "d3d11_context_def.h"
#include "d3d11_context_imm.h"
#include "d3d11_device.h"
#include "../util/util_misc.h"
#include "../util/util_win32_compat.h"
namespace dxvk {
@ -30,46 +32,50 @@ namespace dxvk {
registrationFunction(annotation);
}
D3D11UserDefinedAnnotation::D3D11UserDefinedAnnotation(D3D11DeviceContext* ctx)
: m_container(ctx),
m_eventDepth(0) {
if (m_container->IsAnnotationEnabled())
template<typename ContextType>
D3D11UserDefinedAnnotation<ContextType>::D3D11UserDefinedAnnotation(
ContextType* container,
const Rc<DxvkDevice>& dxvkDevice)
: m_container(container), m_eventDepth(0),
m_annotationsEnabled(dxvkDevice->instance()->extensions().extDebugUtils) {
if (!IsDeferred && m_annotationsEnabled)
RegisterUserDefinedAnnotation<true>(this);
}
D3D11UserDefinedAnnotation::D3D11UserDefinedAnnotation(const D3D11UserDefinedAnnotation&)
{
if (m_container->IsAnnotationEnabled())
RegisterUserDefinedAnnotation<true>(this);
}
D3D11UserDefinedAnnotation::~D3D11UserDefinedAnnotation() {
if (m_container->IsAnnotationEnabled())
template<typename ContextType>
D3D11UserDefinedAnnotation<ContextType>::~D3D11UserDefinedAnnotation() {
if (!IsDeferred && m_annotationsEnabled)
RegisterUserDefinedAnnotation<false>(this);
}
ULONG STDMETHODCALLTYPE D3D11UserDefinedAnnotation::AddRef() {
template<typename ContextType>
ULONG STDMETHODCALLTYPE D3D11UserDefinedAnnotation<ContextType>::AddRef() {
return m_container->AddRef();
}
ULONG STDMETHODCALLTYPE D3D11UserDefinedAnnotation::Release() {
template<typename ContextType>
ULONG STDMETHODCALLTYPE D3D11UserDefinedAnnotation<ContextType>::Release() {
return m_container->Release();
}
HRESULT STDMETHODCALLTYPE D3D11UserDefinedAnnotation::QueryInterface(
template<typename ContextType>
HRESULT STDMETHODCALLTYPE D3D11UserDefinedAnnotation<ContextType>::QueryInterface(
REFIID riid,
void** ppvObject) {
return m_container->QueryInterface(riid, ppvObject);
}
INT STDMETHODCALLTYPE D3D11UserDefinedAnnotation::BeginEvent(
template<typename ContextType>
INT STDMETHODCALLTYPE D3D11UserDefinedAnnotation<ContextType>::BeginEvent(
D3DCOLOR Color,
LPCWSTR Name) {
if (!m_container->IsAnnotationEnabled())
if (!m_annotationsEnabled)
return -1;
D3D10DeviceLock lock = m_container->LockContext();
@ -88,8 +94,9 @@ namespace dxvk {
}
INT STDMETHODCALLTYPE D3D11UserDefinedAnnotation::EndEvent() {
if (!m_container->IsAnnotationEnabled())
template<typename ContextType>
INT STDMETHODCALLTYPE D3D11UserDefinedAnnotation<ContextType>::EndEvent() {
if (!m_annotationsEnabled)
return -1;
D3D10DeviceLock lock = m_container->LockContext();
@ -102,10 +109,11 @@ namespace dxvk {
}
void STDMETHODCALLTYPE D3D11UserDefinedAnnotation::SetMarker(
template<typename ContextType>
void STDMETHODCALLTYPE D3D11UserDefinedAnnotation<ContextType>::SetMarker(
D3DCOLOR Color,
LPCWSTR Name) {
if (!m_container->IsAnnotationEnabled())
if (!m_annotationsEnabled)
return;
D3D10DeviceLock lock = m_container->LockContext();
@ -122,8 +130,13 @@ namespace dxvk {
}
BOOL STDMETHODCALLTYPE D3D11UserDefinedAnnotation::GetStatus() {
return m_container->IsAnnotationEnabled();
template<typename ContextType>
BOOL STDMETHODCALLTYPE D3D11UserDefinedAnnotation<ContextType>::GetStatus() {
return m_annotationsEnabled;
}
template class D3D11UserDefinedAnnotation<D3D11DeferredContext>;
template class D3D11UserDefinedAnnotation<D3D11ImmediateContext>;
}

View File

@ -1,20 +1,31 @@
#pragma once
#include <type_traits>
#include "d3d11_include.h"
#include "../dxvk/dxvk_annotation.h"
#include "../dxvk/dxvk_device.h"
namespace dxvk {
class D3D11DeviceContext;
class D3D11DeferredContext;
class D3D11ImmediateContext;
template<typename ContextType>
class D3D11UserDefinedAnnotation final : public IDXVKUserDefinedAnnotation {
constexpr static bool IsDeferred = std::is_same_v<ContextType, D3D11DeferredContext>;
public:
D3D11UserDefinedAnnotation(D3D11DeviceContext* ctx);
D3D11UserDefinedAnnotation(const D3D11UserDefinedAnnotation&);
D3D11UserDefinedAnnotation(
ContextType* container,
const Rc<DxvkDevice>& dxvkDevice);
~D3D11UserDefinedAnnotation();
D3D11UserDefinedAnnotation (const D3D11UserDefinedAnnotation&) = delete;
D3D11UserDefinedAnnotation& operator = (const D3D11UserDefinedAnnotation&) = delete;
ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
@ -37,10 +48,9 @@ namespace dxvk {
private:
D3D11DeviceContext* m_container;
// Stack depth for non-finalized BeginEvent calls
int32_t m_eventDepth;
ContextType* m_container;
int32_t m_eventDepth;
bool m_annotationsEnabled;
};
}

View File

@ -58,8 +58,11 @@ namespace dxvk {
return S_OK;
}
Logger::warn("D3D11BlendState::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
if (logQueryInterfaceError(__uuidof(ID3D11BlendState), riid)) {
Logger::warn("D3D11BlendState::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
}
return E_NOINTERFACE;
}
@ -87,7 +90,7 @@ namespace dxvk {
void D3D11BlendState::BindToContext(
const Rc<DxvkContext>& ctx,
DxvkContext* ctx,
uint32_t sampleMask) const {
// We handled Independent Blend during object creation
// already, so if it is disabled, all elements in the

View File

@ -33,7 +33,7 @@ namespace dxvk {
D3D11_BLEND_DESC1* pDesc) final;
void BindToContext(
const Rc<DxvkContext>& ctx,
DxvkContext* ctx,
UINT sampleMask) const;
D3D10BlendState* GetD3D10Iface() {

View File

@ -8,12 +8,14 @@ namespace dxvk {
D3D11Buffer::D3D11Buffer(
D3D11Device* pDevice,
const D3D11_BUFFER_DESC* pDesc)
const D3D11_BUFFER_DESC* pDesc,
const D3D11_ON_12_RESOURCE_INFO* p11on12Info)
: D3D11DeviceChild<ID3D11Buffer>(pDevice),
m_desc (*pDesc),
m_resource (this),
m_d3d10 (this) {
DxvkBufferCreateInfo info;
DxvkBufferCreateInfo info;
info.flags = 0;
info.size = pDesc->ByteWidth;
info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
| VK_BUFFER_USAGE_TRANSFER_DST_BIT;
@ -37,9 +39,6 @@ namespace dxvk {
info.usage |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
info.stages |= m_parent->GetEnabledShaderStages();
info.access |= VK_ACCESS_UNIFORM_READ_BIT;
if (m_parent->GetOptions()->constantBufferRangeCheck)
info.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
}
if (pDesc->BindFlags & D3D11_BIND_SHADER_RESOURCE) {
@ -69,12 +68,50 @@ namespace dxvk {
info.access |= VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
}
// Create the buffer and set the entire buffer slice as mapped,
// so that we only have to update it when invalidating th buffer
m_buffer = m_parent->GetDXVKDevice()->createBuffer(info, GetMemoryFlags());
m_mapped = m_buffer->getSliceHandle();
if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILED) {
info.flags |= VK_BUFFER_CREATE_SPARSE_BINDING_BIT
| VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT
| VK_BUFFER_CREATE_SPARSE_ALIASED_BIT;
}
m_mapMode = DetermineMapMode();
// Set host read bit as necessary. We may internally read staging
// buffer contents even if the buffer is not marked for reading.
if (pDesc->CPUAccessFlags && pDesc->Usage != D3D11_USAGE_DYNAMIC) {
info.stages |= VK_PIPELINE_STAGE_HOST_BIT;
info.access |= VK_ACCESS_HOST_READ_BIT;
if (pDesc->CPUAccessFlags & D3D11_CPU_ACCESS_WRITE)
info.access |= VK_ACCESS_HOST_WRITE_BIT;
}
if (p11on12Info) {
m_11on12 = *p11on12Info;
DxvkBufferImportInfo importInfo;
importInfo.buffer = VkBuffer(m_11on12.VulkanHandle);
importInfo.offset = m_11on12.VulkanOffset;
if (m_desc.CPUAccessFlags)
m_11on12.Resource->Map(0, nullptr, &importInfo.mapPtr);
m_buffer = m_parent->GetDXVKDevice()->importBuffer(info, importInfo, GetMemoryFlags());
m_mapped = m_buffer->getSliceHandle();
m_mapMode = DetermineMapMode();
} else if (!(pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL)) {
// Create the buffer and set the entire buffer slice as mapped,
// so that we only have to update it when invalidating the buffer
m_buffer = m_parent->GetDXVKDevice()->createBuffer(info, GetMemoryFlags());
m_mapped = m_buffer->getSliceHandle();
m_mapMode = DetermineMapMode();
} else {
m_sparseAllocator = m_parent->GetDXVKDevice()->createSparsePageAllocator();
m_sparseAllocator->setCapacity(info.size / SparseMemoryPageSize);
m_mapped = DxvkBufferSliceHandle();
m_mapMode = D3D11_COMMON_BUFFER_MAP_MODE_NONE;
}
// For Stream Output buffers we need a counter
if (pDesc->BindFlags & D3D11_BIND_STREAM_OUTPUT)
@ -83,7 +120,8 @@ namespace dxvk {
D3D11Buffer::~D3D11Buffer() {
if (m_desc.CPUAccessFlags && m_11on12.Resource != nullptr)
m_11on12.Resource->Unmap(0, nullptr);
}
@ -116,8 +154,11 @@ namespace dxvk {
return S_OK;
}
Logger::warn("D3D11Buffer::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
if (logQueryInterfaceError(__uuidof(ID3D11Buffer), riid)) {
Logger::warn("D3D11Buffer::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
}
return E_NOINTERFACE;
}
@ -159,7 +200,7 @@ namespace dxvk {
// Check whether the given combination of buffer view
// type and view format is supported by the device
DXGI_VK_FORMAT_INFO viewFormat = m_parent->LookupFormat(Format, DXGI_VK_FORMAT_MODE_ANY);
VkFormatFeatureFlags features = GetBufferFormatFeatures(BindFlags);
VkFormatFeatureFlags2 features = GetBufferFormatFeatures(BindFlags);
return CheckFormatFeatureSupport(viewFormat.Format, features);
}
@ -167,13 +208,9 @@ namespace dxvk {
HRESULT D3D11Buffer::NormalizeBufferProperties(D3D11_BUFFER_DESC* pDesc) {
// Zero-sized buffers are illegal
if (!pDesc->ByteWidth)
if (!pDesc->ByteWidth && !(pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL))
return E_INVALIDARG;
// We don't support tiled resources
if (pDesc->MiscFlags & (D3D11_RESOURCE_MISC_TILE_POOL | D3D11_RESOURCE_MISC_TILED))
return E_INVALIDARG;
// Constant buffer size must be a multiple of 16
if ((pDesc->BindFlags & D3D11_BIND_CONSTANT_BUFFER)
&& (pDesc->ByteWidth & 0xF))
@ -194,7 +231,25 @@ namespace dxvk {
// Mip generation obviously doesn't work for buffers
if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS)
return E_INVALIDARG;
// Basic validation for tiled buffers
if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILED) {
if ((pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL)
|| (pDesc->Usage != D3D11_USAGE_DEFAULT)
|| (pDesc->CPUAccessFlags))
return E_INVALIDARG;
}
// Basic validation for tile pools
if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL) {
if ((pDesc->MiscFlags & ~D3D11_RESOURCE_MISC_TILE_POOL)
|| (pDesc->ByteWidth % SparseMemoryPageSize)
|| (pDesc->Usage != D3D11_USAGE_DEFAULT)
|| (pDesc->BindFlags)
|| (pDesc->CPUAccessFlags))
return E_INVALIDARG;
}
if (!(pDesc->MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED))
pDesc->StructureByteStride = 0;
@ -202,17 +257,50 @@ namespace dxvk {
}
HRESULT D3D11Buffer::GetDescFromD3D12(
ID3D12Resource* pResource,
const D3D11_RESOURCE_FLAGS* pResourceFlags,
D3D11_BUFFER_DESC* pBufferDesc) {
D3D12_RESOURCE_DESC desc12 = pResource->GetDesc();
pBufferDesc->ByteWidth = desc12.Width;
pBufferDesc->Usage = D3D11_USAGE_DEFAULT;
pBufferDesc->BindFlags = D3D11_BIND_SHADER_RESOURCE;
pBufferDesc->MiscFlags = 0;
pBufferDesc->CPUAccessFlags = 0;
pBufferDesc->StructureByteStride = 0;
if (desc12.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET)
pBufferDesc->BindFlags |= D3D11_BIND_RENDER_TARGET;
if (desc12.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)
pBufferDesc->BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
if (pResourceFlags) {
pBufferDesc->BindFlags = pResourceFlags->BindFlags;
pBufferDesc->MiscFlags |= pResourceFlags->MiscFlags;
pBufferDesc->CPUAccessFlags = pResourceFlags->CPUAccessFlags;
pBufferDesc->StructureByteStride = pResourceFlags->StructureByteStride;
}
return S_OK;
}
BOOL D3D11Buffer::CheckFormatFeatureSupport(
VkFormat Format,
VkFormatFeatureFlags Features) const {
VkFormatProperties properties = m_parent->GetDXVKDevice()->adapter()->formatProperties(Format);
return (properties.bufferFeatures & Features) == Features;
VkFormatFeatureFlags2 Features) const {
DxvkFormatFeatures support = m_parent->GetDXVKDevice()->getFormatFeatures(Format);
return (support.buffer & Features) == Features;
}
VkMemoryPropertyFlags D3D11Buffer::GetMemoryFlags() const {
VkMemoryPropertyFlags memoryFlags = 0;
if (m_desc.MiscFlags & (D3D11_RESOURCE_MISC_TILE_POOL | D3D11_RESOURCE_MISC_TILED))
return VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
switch (m_desc.Usage) {
case D3D11_USAGE_IMMUTABLE:
memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
@ -251,6 +339,7 @@ namespace dxvk {
|| (m_parent->GetOptions()->cachedDynamicResources & m_desc.BindFlags);
if ((memoryFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) && useCached) {
memoryFlags &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
memoryFlags |= VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
| VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
}

View File

@ -7,12 +7,12 @@
#include "d3d11_device_child.h"
#include "d3d11_interfaces.h"
#include "d3d11_on_12.h"
#include "d3d11_resource.h"
namespace dxvk {
class D3D11Device;
class D3D11DeviceContext;
/**
@ -42,7 +42,9 @@ namespace dxvk {
D3D11Buffer(
D3D11Device* pDevice,
const D3D11_BUFFER_DESC* pDesc);
const D3D11_BUFFER_DESC* pDesc,
const D3D11_ON_12_RESOURCE_INFO* p11on12Info);
~D3D11Buffer();
HRESULT STDMETHODCALLTYPE QueryInterface(
@ -67,6 +69,10 @@ namespace dxvk {
return &m_desc;
}
BOOL IsTilePool() const {
return bool(m_desc.MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL);
}
D3D11_COMMON_BUFFER_MAP_MODE GetMapMode() const {
return m_mapMode;
}
@ -74,6 +80,10 @@ namespace dxvk {
Rc<DxvkBuffer> GetBuffer() const {
return m_buffer;
}
Rc<DxvkSparsePageAllocator> GetSparseAllocator() const {
return m_sparseAllocator;
}
DxvkBufferSlice GetBufferSlice() const {
return DxvkBufferSlice(m_buffer, 0, m_desc.ByteWidth);
@ -81,18 +91,20 @@ namespace dxvk {
DxvkBufferSlice GetBufferSlice(VkDeviceSize offset) const {
VkDeviceSize size = m_desc.ByteWidth;
return likely(offset < size)
? DxvkBufferSlice(m_buffer, offset, size - offset)
: DxvkBufferSlice();
offset = std::min(offset, size);
return DxvkBufferSlice(m_buffer, offset, size - offset);
}
DxvkBufferSlice GetBufferSlice(VkDeviceSize offset, VkDeviceSize length) const {
VkDeviceSize size = m_desc.ByteWidth;
offset = std::min(offset, size);
return DxvkBufferSlice(m_buffer, offset, std::min(length, size - offset));
}
return likely(offset < size)
? DxvkBufferSlice(m_buffer, offset, std::min(length, size - offset))
: DxvkBufferSlice();
VkDeviceSize GetRemainingSize(VkDeviceSize offset) const {
VkDeviceSize size = m_desc.ByteWidth;
offset = std::min(offset, size);
return size - offset;
}
DxvkBufferSlice GetSOCounter() {
@ -133,6 +145,14 @@ namespace dxvk {
: DxvkCsThread::SynchronizeAll;
}
/**
* \brief Retrieves D3D11on12 resource info
* \returns 11on12 resource info
*/
D3D11_ON_12_RESOURCE_INFO Get11on12Info() const {
return m_11on12;
}
/**
* \brief Normalizes buffer description
*
@ -142,13 +162,28 @@ namespace dxvk {
static HRESULT NormalizeBufferProperties(
D3D11_BUFFER_DESC* pDesc);
/**
* \brief Initializes D3D11 buffer description from D3D12
*
* \param [in] pResource D3D12 resource
* \param [in] pResourceFlags D3D11 flag overrides
* \param [out] pBufferDesc D3D11 buffer description
* \returns \c S_OK if the parameters are valid
*/
static HRESULT GetDescFromD3D12(
ID3D12Resource* pResource,
const D3D11_RESOURCE_FLAGS* pResourceFlags,
D3D11_BUFFER_DESC* pBufferDesc);
private:
D3D11_BUFFER_DESC m_desc;
D3D11_ON_12_RESOURCE_INFO m_11on12;
D3D11_COMMON_BUFFER_MAP_MODE m_mapMode;
Rc<DxvkBuffer> m_buffer;
Rc<DxvkBuffer> m_soCounter;
Rc<DxvkSparsePageAllocator> m_sparseAllocator;
DxvkBufferSliceHandle m_mapped;
uint64_t m_seq = 0ull;
@ -157,7 +192,7 @@ namespace dxvk {
BOOL CheckFormatFeatureSupport(
VkFormat Format,
VkFormatFeatureFlags Features) const;
VkFormatFeatureFlags2 Features) const;
VkMemoryPropertyFlags GetMemoryFlags() const;

View File

@ -28,8 +28,11 @@ namespace dxvk {
return S_OK;
}
Logger::warn("D3D11ClassLinkage::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
if (logQueryInterfaceError(__uuidof(ID3D11ClassLinkage), riid)) {
Logger::warn("D3D11ClassLinkage::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
}
return E_NOINTERFACE;
}

View File

@ -30,8 +30,11 @@ namespace dxvk {
return S_OK;
}
Logger::warn("D3D11CommandList::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
if (logQueryInterfaceError(__uuidof(ID3D11CommandList), riid)) {
Logger::warn("D3D11CommandList::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
}
return E_NOINTERFACE;
}
@ -41,54 +44,79 @@ namespace dxvk {
}
void D3D11CommandList::AddChunk(DxvkCsChunkRef&& Chunk) {
m_chunks.push_back(std::move(Chunk));
}
void D3D11CommandList::AddQuery(D3D11Query* pQuery) {
m_queries.emplace_back(pQuery);
}
void D3D11CommandList::EmitToCommandList(ID3D11CommandList* pCommandList) {
auto cmdList = static_cast<D3D11CommandList*>(pCommandList);
for (const auto& chunk : m_chunks)
cmdList->m_chunks.push_back(chunk);
for (const auto& query : m_queries)
cmdList->m_queries.push_back(query);
for (const auto& resource : m_resources)
cmdList->m_resources.push_back(resource);
MarkSubmitted();
uint64_t D3D11CommandList::AddChunk(DxvkCsChunkRef&& Chunk) {
m_chunks.push_back(std::move(Chunk));
return m_chunks.size() - 1;
}
uint64_t D3D11CommandList::EmitToCsThread(DxvkCsThread* CsThread) {
uint64_t seq = 0;
uint64_t D3D11CommandList::AddCommandList(
D3D11CommandList* pCommandList) {
// This will be the chunk ID of the first chunk
// added, for the purpose of resource tracking.
uint64_t baseChunkId = m_chunks.size();
for (const auto& chunk : pCommandList->m_chunks)
m_chunks.push_back(chunk);
for (const auto& query : pCommandList->m_queries)
m_queries.push_back(query);
for (const auto& resource : pCommandList->m_resources) {
TrackedResource entry = resource;
entry.chunkId += baseChunkId;
m_resources.push_back(std::move(entry));
}
pCommandList->MarkSubmitted();
// Return ID of the last chunk added. The command list
// added can never be empty, so do not handle zero.
return m_chunks.size() - 1;
}
void D3D11CommandList::EmitToCsThread(
const D3D11ChunkDispatchProc& DispatchProc) {
for (const auto& query : m_queries)
query->DoDeferredEnd();
for (const auto& chunk : m_chunks)
seq = CsThread->dispatchChunk(DxvkCsChunkRef(chunk));
for (const auto& resource : m_resources)
TrackResourceSequenceNumber(resource, seq);
for (size_t i = 0, j = 0; i < m_chunks.size(); i++) {
// If there are resources to track for the current chunk,
// use a strong flush hint to dispatch GPU work quickly.
GpuFlushType flushType = GpuFlushType::ImplicitWeakHint;
if (j < m_resources.size() && m_resources[j].chunkId == i)
flushType = GpuFlushType::ImplicitStrongHint;
// Dispatch the chunk and capture its sequence number
uint64_t seq = DispatchProc(DxvkCsChunkRef(m_chunks[i]), flushType);
// Track resource sequence numbers for the added chunk
while (j < m_resources.size() && m_resources[j].chunkId == i)
TrackResourceSequenceNumber(m_resources[j++].ref, seq);
}
MarkSubmitted();
return seq;
}
void D3D11CommandList::TrackResourceUsage(
ID3D11Resource* pResource,
D3D11_RESOURCE_DIMENSION ResourceType,
UINT Subresource) {
m_resources.emplace_back(pResource, Subresource, ResourceType);
UINT Subresource,
uint64_t ChunkId) {
TrackedResource entry;
entry.ref = D3D11ResourceRef(pResource, Subresource, ResourceType);
entry.chunkId = ChunkId;
m_resources.push_back(std::move(entry));
}
@ -96,7 +124,6 @@ namespace dxvk {
const D3D11ResourceRef& Resource,
uint64_t Seq) {
ID3D11Resource* iface = Resource.Get();
UINT subresource = Resource.GetSubresource();
switch (Resource.GetType()) {
case D3D11_RESOURCE_DIMENSION_UNKNOWN:
@ -109,17 +136,17 @@ namespace dxvk {
case D3D11_RESOURCE_DIMENSION_TEXTURE1D: {
auto impl = static_cast<D3D11Texture1D*>(iface)->GetCommonTexture();
impl->TrackSequenceNumber(subresource, Seq);
impl->TrackSequenceNumber(Resource.GetSubresource(), Seq);
} break;
case D3D11_RESOURCE_DIMENSION_TEXTURE2D: {
auto impl = static_cast<D3D11Texture2D*>(iface)->GetCommonTexture();
impl->TrackSequenceNumber(subresource, Seq);
impl->TrackSequenceNumber(Resource.GetSubresource(), Seq);
} break;
case D3D11_RESOURCE_DIMENSION_TEXTURE3D: {
auto impl = static_cast<D3D11Texture3D*>(iface)->GetCommonTexture();
impl->TrackSequenceNumber(subresource, Seq);
impl->TrackSequenceNumber(Resource.GetSubresource(), Seq);
} break;
}
}

View File

@ -1,9 +1,13 @@
#pragma once
#include <functional>
#include "d3d11_context.h"
namespace dxvk {
using D3D11ChunkDispatchProc = std::function<uint64_t (DxvkCsChunkRef&&, GpuFlushType)>;
class D3D11CommandList : public D3D11DeviceChild<ID3D11CommandList> {
public:
@ -20,30 +24,36 @@ namespace dxvk {
UINT STDMETHODCALLTYPE GetContextFlags() final;
void AddChunk(
DxvkCsChunkRef&& Chunk);
void AddQuery(
D3D11Query* pQuery);
void EmitToCommandList(
ID3D11CommandList* pCommandList);
uint64_t EmitToCsThread(
DxvkCsThread* CsThread);
uint64_t AddChunk(
DxvkCsChunkRef&& Chunk);
uint64_t AddCommandList(
D3D11CommandList* pCommandList);
void EmitToCsThread(
const D3D11ChunkDispatchProc& DispatchProc);
void TrackResourceUsage(
ID3D11Resource* pResource,
D3D11_RESOURCE_DIMENSION ResourceType,
UINT Subresource);
UINT Subresource,
uint64_t ChunkId);
private:
UINT const m_contextFlags;
struct TrackedResource {
D3D11ResourceRef ref;
uint64_t chunkId;
};
UINT m_contextFlags;
std::vector<DxvkCsChunkRef> m_chunks;
std::vector<Com<D3D11Query, false>> m_queries;
std::vector<D3D11ResourceRef> m_resources;
std::vector<TrackedResource> m_resources;
std::atomic<bool> m_submitted = { false };
std::atomic<bool> m_warned = { false };

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,20 +7,9 @@ namespace dxvk {
D3D11Device* pParent,
const Rc<DxvkDevice>& Device,
UINT ContextFlags)
: D3D11DeviceContext(pParent, Device, GetCsChunkFlags(pParent)),
m_contextFlags(ContextFlags),
: D3D11CommonContext<D3D11DeferredContext>(pParent, Device, ContextFlags, GetCsChunkFlags(pParent)),
m_commandList (CreateCommandList()) {
ClearState();
}
D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE D3D11DeferredContext::GetType() {
return D3D11_DEVICE_CONTEXT_DEFERRED;
}
UINT STDMETHODCALLTYPE D3D11DeferredContext::GetContextFlags() {
return m_contextFlags;
ResetContextState();
}
@ -146,14 +135,26 @@ namespace dxvk {
BOOL RestoreContextState) {
D3D10DeviceLock lock = LockContext();
// Clear state so that the command list can't observe any
// current context state. The command list itself will clean
// up after execution to ensure that no state changes done
// by the command list are visible to the immediate context.
ResetCommandListState();
// Flush any outstanding commands so that
// we don't mess up the execution order
FlushCsChunk();
static_cast<D3D11CommandList*>(pCommandList)->EmitToCommandList(m_commandList.ptr());
// Record any chunks from the given command list into the
// current command list and deal with context state
auto commandList = static_cast<D3D11CommandList*>(pCommandList);
m_chunkId = m_commandList->AddCommandList(commandList);
// Restore deferred context state
if (RestoreContextState)
RestoreState();
RestoreCommandListState();
else
ClearState();
ResetContextState();
}
@ -162,17 +163,31 @@ namespace dxvk {
ID3D11CommandList **ppCommandList) {
D3D10DeviceLock lock = LockContext();
// End all queries that were left active by the app
FinalizeQueries();
// Clean up command list state so that the any state changed
// by this command list does not affect the calling context.
// This also ensures that the command list is never empty.
ResetCommandListState();
// Make sure all commands are visible to the command list
FlushCsChunk();
if (ppCommandList != nullptr)
if (ppCommandList)
*ppCommandList = m_commandList.ref();
// Create a clean command list, and if requested, restore all
// previously set context state. Otherwise, reset the context.
// Any use of ExecuteCommandList will reset command list state
// before the command list is actually executed.
m_commandList = CreateCommandList();
m_chunkId = 0;
if (RestoreDeferredContextState)
RestoreState();
RestoreCommandListState();
else
ClearState();
ResetContextState();
m_mappedResources.clear();
ResetStagingBuffer();
@ -236,31 +251,6 @@ namespace dxvk {
}
void STDMETHODCALLTYPE D3D11DeferredContext::UpdateSubresource(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch) {
UpdateResource<D3D11DeferredContext>(this, pDstResource,
DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch, 0);
}
void STDMETHODCALLTYPE D3D11DeferredContext::UpdateSubresource1(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch,
UINT CopyFlags) {
UpdateResource<D3D11DeferredContext>(this, pDstResource,
DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch, CopyFlags);
}
void STDMETHODCALLTYPE D3D11DeferredContext::SwapDeviceContextState(
ID3DDeviceContextState* pState,
ID3DDeviceContextState** ppPreviousState) {
@ -333,7 +323,7 @@ namespace dxvk {
VkFormat packedFormat = pTexture->GetPackedFormat();
auto formatInfo = imageFormatInfo(packedFormat);
auto formatInfo = lookupFormatInfo(packedFormat);
auto subresource = pTexture->GetSubresourceFromIndex(
formatInfo->aspectMask, Subresource);
@ -396,12 +386,17 @@ namespace dxvk {
Com<D3D11CommandList> D3D11DeferredContext::CreateCommandList() {
return new D3D11CommandList(m_parent, m_contextFlags);
return new D3D11CommandList(m_parent, m_flags);
}
void D3D11DeferredContext::EmitCsChunk(DxvkCsChunkRef&& chunk) {
m_commandList->AddChunk(std::move(chunk));
m_chunkId = m_commandList->AddChunk(std::move(chunk));
}
uint64_t D3D11DeferredContext::GetCurrentChunkId() const {
return m_csChunk->empty() ? m_chunkId : m_chunkId + 1;
}
@ -411,14 +406,15 @@ namespace dxvk {
m_commandList->TrackResourceUsage(
pResource->GetInterface(),
pResource->GetDimension(),
Subresource);
Subresource, GetCurrentChunkId());
}
void D3D11DeferredContext::TrackBufferSequenceNumber(
D3D11Buffer* pResource) {
m_commandList->TrackResourceUsage(
pResource, D3D11_RESOURCE_DIMENSION_BUFFER, 0);
m_commandList->TrackResourceUsage(pResource,
D3D11_RESOURCE_DIMENSION_BUFFER, 0,
GetCurrentChunkId());
}

View File

@ -1,9 +1,7 @@
#pragma once
#include "d3d11_buffer.h"
#include "d3d11_cmdlist.h"
#include "d3d11_context.h"
#include "d3d11_texture.h"
#include <vector>
@ -23,8 +21,8 @@ namespace dxvk {
D3D11_MAPPED_SUBRESOURCE MapInfo;
};
class D3D11DeferredContext : public D3D11DeviceContext {
friend class D3D11DeviceContext;
class D3D11DeferredContext : public D3D11CommonContext<D3D11DeferredContext> {
friend class D3D11CommonContext<D3D11DeferredContext>;
public:
D3D11DeferredContext(
@ -32,10 +30,6 @@ namespace dxvk {
const Rc<DxvkDevice>& Device,
UINT ContextFlags);
D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE GetType();
UINT STDMETHODCALLTYPE GetContextFlags();
HRESULT STDMETHODCALLTYPE GetData(
ID3D11Asynchronous* pAsync,
void* pData,
@ -81,31 +75,16 @@ namespace dxvk {
ID3D11Resource* pResource,
UINT Subresource);
void STDMETHODCALLTYPE UpdateSubresource(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch);
void STDMETHODCALLTYPE UpdateSubresource1(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch,
UINT CopyFlags);
void STDMETHODCALLTYPE SwapDeviceContextState(
ID3DDeviceContextState* pState,
ID3DDeviceContextState** ppPreviousState);
D3D10DeviceLock LockContext() {
return D3D10DeviceLock();
}
private:
const UINT m_contextFlags;
// Command list that we're recording
Com<D3D11CommandList> m_commandList;
@ -117,6 +96,9 @@ namespace dxvk {
// Begun and ended queries, will also be stored in command list
std::vector<Com<D3D11Query, false>> m_queriesBegun;
// Chunk ID within the current command list
uint64_t m_chunkId = 0ull;
HRESULT MapBuffer(
ID3D11Resource* pResource,
D3D11_MAPPED_SUBRESOURCE* pMappedResource);
@ -139,6 +121,8 @@ namespace dxvk {
void EmitCsChunk(DxvkCsChunkRef&& chunk);
uint64_t GetCurrentChunkId() const;
void TrackTextureSequenceNumber(
D3D11CommonTexture* pResource,
UINT Subresource);

View File

@ -3,38 +3,44 @@
#include <cstring>
#include "d3d11_device.h"
#include "d3d11_context.h"
#include "d3d11_context_imm.h"
#include "d3d11_context_def.h"
#include "d3d11_cuda.h"
#include "../util/log/log.h"
namespace dxvk {
D3D11DeviceContextExt::D3D11DeviceContextExt(
D3D11DeviceContext* pContext)
template<typename ContextType>
D3D11DeviceContextExt<ContextType>::D3D11DeviceContextExt(
ContextType* pContext)
: m_ctx(pContext) {
}
ULONG STDMETHODCALLTYPE D3D11DeviceContextExt::AddRef() {
template<typename ContextType>
ULONG STDMETHODCALLTYPE D3D11DeviceContextExt<ContextType>::AddRef() {
return m_ctx->AddRef();
}
ULONG STDMETHODCALLTYPE D3D11DeviceContextExt::Release() {
template<typename ContextType>
ULONG STDMETHODCALLTYPE D3D11DeviceContextExt<ContextType>::Release() {
return m_ctx->Release();
}
HRESULT STDMETHODCALLTYPE D3D11DeviceContextExt::QueryInterface(
template<typename ContextType>
HRESULT STDMETHODCALLTYPE D3D11DeviceContextExt<ContextType>::QueryInterface(
REFIID riid,
void** ppvObject) {
return m_ctx->QueryInterface(riid, ppvObject);
}
void STDMETHODCALLTYPE D3D11DeviceContextExt::MultiDrawIndirect(
template<typename ContextType>
void STDMETHODCALLTYPE D3D11DeviceContextExt<ContextType>::MultiDrawIndirect(
UINT DrawCount,
ID3D11Buffer* pBufferForArgs,
UINT ByteOffsetForArgs,
@ -52,7 +58,8 @@ namespace dxvk {
}
void STDMETHODCALLTYPE D3D11DeviceContextExt::MultiDrawIndexedIndirect(
template<typename ContextType>
void STDMETHODCALLTYPE D3D11DeviceContextExt<ContextType>::MultiDrawIndexedIndirect(
UINT DrawCount,
ID3D11Buffer* pBufferForArgs,
UINT ByteOffsetForArgs,
@ -70,7 +77,8 @@ namespace dxvk {
}
void STDMETHODCALLTYPE D3D11DeviceContextExt::MultiDrawIndirectCount(
template<typename ContextType>
void STDMETHODCALLTYPE D3D11DeviceContextExt<ContextType>::MultiDrawIndirectCount(
UINT MaxDrawCount,
ID3D11Buffer* pBufferForCount,
UINT ByteOffsetForCount,
@ -91,7 +99,8 @@ namespace dxvk {
}
void STDMETHODCALLTYPE D3D11DeviceContextExt::MultiDrawIndexedIndirectCount(
template<typename ContextType>
void STDMETHODCALLTYPE D3D11DeviceContextExt<ContextType>::MultiDrawIndexedIndirectCount(
UINT MaxDrawCount,
ID3D11Buffer* pBufferForCount,
UINT ByteOffsetForCount,
@ -112,7 +121,8 @@ namespace dxvk {
}
void STDMETHODCALLTYPE D3D11DeviceContextExt::SetDepthBoundsTest(
template<typename ContextType>
void STDMETHODCALLTYPE D3D11DeviceContextExt<ContextType>::SetDepthBoundsTest(
BOOL Enable,
FLOAT MinDepthBounds,
FLOAT MaxDepthBounds) {
@ -129,7 +139,8 @@ namespace dxvk {
}
void STDMETHODCALLTYPE D3D11DeviceContextExt::SetBarrierControl(
template<typename ContextType>
void STDMETHODCALLTYPE D3D11DeviceContextExt<ContextType>::SetBarrierControl(
UINT ControlFlags) {
D3D10DeviceLock lock = m_ctx->LockContext();
DxvkBarrierControlFlags flags;
@ -146,7 +157,8 @@ namespace dxvk {
}
bool STDMETHODCALLTYPE D3D11DeviceContextExt::LaunchCubinShaderNVX(IUnknown* hShader, uint32_t GridX, uint32_t GridY, uint32_t GridZ,
template<typename ContextType>
bool STDMETHODCALLTYPE D3D11DeviceContextExt<ContextType>::LaunchCubinShaderNVX(IUnknown* hShader, uint32_t GridX, uint32_t GridY, uint32_t GridZ,
const void* pParams, uint32_t ParamSize, void* const* pReadResources, uint32_t NumReadResources, void* const* pWriteResources, uint32_t NumWriteResources) {
D3D10DeviceLock lock = m_ctx->LockContext();
@ -202,4 +214,9 @@ namespace dxvk {
return true;
}
template class D3D11DeviceContextExt<D3D11DeferredContext>;
template class D3D11DeviceContextExt<D3D11ImmediateContext>;
}

View File

@ -4,14 +4,16 @@
namespace dxvk {
class D3D11DeviceContext;
class D3D11DeferredContext;
class D3D11ImmediateContext;
template<typename ContextType>
class D3D11DeviceContextExt : public ID3D11VkExtContext1 {
public:
D3D11DeviceContextExt(
D3D11DeviceContext* pContext);
ContextType* pContext);
ULONG STDMETHODCALLTYPE AddRef();
@ -71,7 +73,7 @@ namespace dxvk {
private:
D3D11DeviceContext* m_ctx;
ContextType* m_ctx;
};

View File

@ -1,8 +1,11 @@
#include "d3d11_cmdlist.h"
#include "d3d11_context_imm.h"
#include "d3d11_device.h"
#include "d3d11_fence.h"
#include "d3d11_texture.h"
#include "../util/util_win32_compat.h"
constexpr static uint32_t MinFlushIntervalUs = 750;
constexpr static uint32_t IncFlushIntervalUs = 250;
constexpr static uint32_t MaxPendingSubmits = 6;
@ -12,9 +15,11 @@ namespace dxvk {
D3D11ImmediateContext::D3D11ImmediateContext(
D3D11Device* pParent,
const Rc<DxvkDevice>& Device)
: D3D11DeviceContext(pParent, Device, DxvkCsChunkFlag::SingleUse),
m_csThread(Device, Device->createContext()),
: D3D11CommonContext<D3D11ImmediateContext>(pParent, Device, 0, DxvkCsChunkFlag::SingleUse),
m_csThread(Device, Device->createContext(DxvkContextType::Primary)),
m_maxImplicitDiscardSize(pParent->GetOptions()->maxImplicitDiscardSize),
m_submissionFence(new sync::CallbackFence()),
m_multithread(this, false, pParent->GetOptions()->enableContextLock),
m_videoContext(this, Device) {
EmitCs([
cDevice = m_device,
@ -39,32 +44,32 @@ namespace dxvk {
D3D11ImmediateContext::~D3D11ImmediateContext() {
Flush();
// Avoids hanging when in this state, see comment
// in DxvkDevice::~DxvkDevice.
if (this_thread::isInModuleDetachment())
return;
ExecuteFlush(GpuFlushType::ExplicitFlush, nullptr, true);
SynchronizeCsThread(DxvkCsThread::SynchronizeAll);
SynchronizeDevice();
}
HRESULT STDMETHODCALLTYPE D3D11ImmediateContext::QueryInterface(REFIID riid, void** ppvObject) {
if (riid == __uuidof(ID3D10Multithread)) {
*ppvObject = ref(&m_multithread);
return S_OK;
}
if (riid == __uuidof(ID3D11VideoContext)) {
*ppvObject = ref(&m_videoContext);
return S_OK;
}
return D3D11DeviceContext::QueryInterface(riid, ppvObject);
return D3D11CommonContext<D3D11ImmediateContext>::QueryInterface(riid, ppvObject);
}
D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE D3D11ImmediateContext::GetType() {
return D3D11_DEVICE_CONTEXT_IMMEDIATE;
}
UINT STDMETHODCALLTYPE D3D11ImmediateContext::GetContextFlags() {
return 0;
}
HRESULT STDMETHODCALLTYPE D3D11ImmediateContext::GetData(
ID3D11Asynchronous* pAsync,
void* pData,
@ -95,7 +100,8 @@ namespace dxvk {
// Ignore the DONOTFLUSH flag here as some games will spin
// on queries without ever flushing the context otherwise.
FlushImplicit(FALSE);
D3D10DeviceLock lock = LockContext();
ConsiderFlush(GpuFlushType::ImplicitSynchronization);
}
return hr;
@ -144,57 +150,69 @@ namespace dxvk {
query->NotifyEnd();
if (query->IsStalling())
Flush();
ExecuteFlush(GpuFlushType::ImplicitSynchronization, nullptr, false);
else if (query->IsEvent())
FlushImplicit(TRUE);
ConsiderFlush(GpuFlushType::ImplicitStrongHint);
}
}
void STDMETHODCALLTYPE D3D11ImmediateContext::Flush() {
Flush1(D3D11_CONTEXT_TYPE_ALL, nullptr);
D3D10DeviceLock lock = LockContext();
ExecuteFlush(GpuFlushType::ExplicitFlush, nullptr, true);
}
void STDMETHODCALLTYPE D3D11ImmediateContext::Flush1(
D3D11_CONTEXT_TYPE ContextType,
HANDLE hEvent) {
m_parent->FlushInitContext();
if (hEvent)
SignalEvent(hEvent);
D3D10DeviceLock lock = LockContext();
if (m_csIsBusy || !m_csChunk->empty()) {
// Add commands to flush the threaded
// context, then flush the command list
EmitCs([] (DxvkContext* ctx) {
ctx->flushCommandList();
});
FlushCsChunk();
// Reset flush timer used for implicit flushes
m_lastFlush = dxvk::high_resolution_clock::now();
m_csIsBusy = false;
}
ExecuteFlush(GpuFlushType::ExplicitFlush, hEvent, true);
}
HRESULT STDMETHODCALLTYPE D3D11ImmediateContext::Signal(
ID3D11Fence* pFence,
UINT64 Value) {
Logger::err("D3D11ImmediateContext::Signal: Not implemented");
return E_NOTIMPL;
D3D10DeviceLock lock = LockContext();
auto fence = static_cast<D3D11Fence*>(pFence);
if (!fence)
return E_INVALIDARG;
EmitCs([
cFence = fence->GetFence(),
cValue = Value
] (DxvkContext* ctx) {
ctx->signalFence(cFence, cValue);
});
ExecuteFlush(GpuFlushType::ExplicitFlush, nullptr, true);
return S_OK;
}
HRESULT STDMETHODCALLTYPE D3D11ImmediateContext::Wait(
ID3D11Fence* pFence,
UINT64 Value) {
Logger::err("D3D11ImmediateContext::Wait: Not implemented");
return E_NOTIMPL;
D3D10DeviceLock lock = LockContext();
auto fence = static_cast<D3D11Fence*>(pFence);
if (!fence)
return E_INVALIDARG;
ExecuteFlush(GpuFlushType::ExplicitFlush, nullptr, true);
EmitCs([
cFence = fence->GetFence(),
cValue = Value
] (DxvkContext* ctx) {
ctx->waitFence(cFence, cValue);
});
return S_OK;
}
@ -205,27 +223,39 @@ namespace dxvk {
auto commandList = static_cast<D3D11CommandList*>(pCommandList);
// Clear state so that the command list can't observe any
// current context state. The command list itself will clean
// up after execution to ensure that no state changes done
// by the command list are visible to the immediate context.
ResetCommandListState();
// Flush any outstanding commands so that
// we don't mess up the execution order
FlushCsChunk();
// As an optimization, flush everything if the
// number of pending draw calls is high enough.
FlushImplicit(FALSE);
// Dispatch command list to the CS thread and
// restore the immediate context's state
uint64_t csSeqNum = commandList->EmitToCsThread(&m_csThread);
m_csSeqNum = std::max(m_csSeqNum, csSeqNum);
ConsiderFlush(GpuFlushType::ImplicitWeakHint);
// Dispatch command list to the CS thread
commandList->EmitToCsThread([this] (DxvkCsChunkRef&& chunk, GpuFlushType flushType) {
EmitCsChunk(std::move(chunk));
// Return the sequence number from before the flush since
// that is actually going to be needed for resource tracking
uint64_t csSeqNum = m_csSeqNum;
// Consider a flush after every chunk in case the app
// submits a very large command list or the GPU is idle
ConsiderFlush(flushType);
return csSeqNum;
});
// Restore the immediate context's state
if (RestoreContextState)
RestoreState();
RestoreCommandListState();
else
ClearState();
// Mark CS thread as busy so that subsequent
// flush operations get executed correctly.
m_csIsBusy = true;
ResetContextState();
}
@ -290,59 +320,7 @@ namespace dxvk {
}
}
void STDMETHODCALLTYPE D3D11ImmediateContext::UpdateSubresource(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch) {
UpdateResource<D3D11ImmediateContext>(this, pDstResource,
DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch, 0);
}
void STDMETHODCALLTYPE D3D11ImmediateContext::UpdateSubresource1(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch,
UINT CopyFlags) {
UpdateResource<D3D11ImmediateContext>(this, pDstResource,
DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch, CopyFlags);
}
void STDMETHODCALLTYPE D3D11ImmediateContext::OMSetRenderTargets(
UINT NumViews,
ID3D11RenderTargetView* const* ppRenderTargetViews,
ID3D11DepthStencilView* pDepthStencilView) {
FlushImplicit(TRUE);
D3D11DeviceContext::OMSetRenderTargets(
NumViews, ppRenderTargetViews, pDepthStencilView);
}
void STDMETHODCALLTYPE D3D11ImmediateContext::OMSetRenderTargetsAndUnorderedAccessViews(
UINT NumRTVs,
ID3D11RenderTargetView* const* ppRenderTargetViews,
ID3D11DepthStencilView* pDepthStencilView,
UINT UAVStartSlot,
UINT NumUAVs,
ID3D11UnorderedAccessView* const* ppUnorderedAccessViews,
const UINT* pUAVInitialCounts) {
FlushImplicit(TRUE);
D3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews(
NumRTVs, ppRenderTargetViews, pDepthStencilView,
UAVStartSlot, NumUAVs, ppUnorderedAccessViews,
pUAVInitialCounts);
}
HRESULT D3D11ImmediateContext::MapBuffer(
D3D11Buffer* pResource,
D3D11_MAP MapType,
@ -407,8 +385,6 @@ namespace dxvk {
}
if (doInvalidatePreserve) {
FlushImplicit(TRUE);
auto prevSlice = pResource->GetMappedSlice();
auto physSlice = pResource->DiscardSlice();
@ -472,7 +448,7 @@ namespace dxvk {
uint64_t sequenceNumber = pResource->GetSequenceNumber(Subresource);
auto formatInfo = imageFormatInfo(packedFormat);
auto formatInfo = lookupFormatInfo(packedFormat);
void* mapPtr;
if (mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) {
@ -495,6 +471,20 @@ namespace dxvk {
constexpr uint32_t DoWait = (1u << 2);
uint32_t doFlags;
if (mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER) {
// If the image can be written by the GPU, we need to update the
// mapped staging buffer to reflect the current image contents.
if (pResource->Desc()->Usage == D3D11_USAGE_DEFAULT) {
bool needsReadback = !pResource->NeedsDirtyRegionTracking();
needsReadback |= MapType == D3D11_MAP_READ
|| MapType == D3D11_MAP_READ_WRITE;
if (needsReadback)
ReadbackImageBuffer(pResource, Subresource);
}
}
if (MapType == D3D11_MAP_READ) {
// Reads will not change the image content, so we only need
// to wait for the GPU to finish writing to the mapped buffer.
@ -540,8 +530,6 @@ namespace dxvk {
}
if (doFlags & DoInvalidate) {
FlushImplicit(TRUE);
DxvkBufferSliceHandle prevSlice = pResource->GetMappedSlice(Subresource);
DxvkBufferSliceHandle physSlice = pResource->DiscardSlice(Subresource);
@ -600,20 +588,116 @@ namespace dxvk {
// the given subresource is actually mapped right now
m_mappedImageCount -= 1;
if ((mapType != D3D11_MAP_READ) &&
(pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER)) {
// Now that data has been written into the buffer,
// we need to copy its contents into the image
VkImageAspectFlags aspectMask = imageFormatInfo(pResource->GetPackedFormat())->aspectMask;
VkImageSubresource subresource = pResource->GetSubresourceFromIndex(aspectMask, Subresource);
if ((mapType != D3D11_MAP_READ) && (pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER)) {
if (pResource->NeedsDirtyRegionTracking()) {
for (uint32_t i = 0; i < pResource->GetDirtyRegionCount(Subresource); i++) {
D3D11_COMMON_TEXTURE_REGION region = pResource->GetDirtyRegion(Subresource, i);
UpdateDirtyImageRegion(pResource, Subresource, &region);
}
UpdateImage(pResource, &subresource, VkOffset3D { 0, 0, 0 },
pResource->MipLevelExtent(subresource.mipLevel),
DxvkBufferSlice(pResource->GetMappedBuffer(Subresource)));
pResource->ClearDirtyRegions(Subresource);
} else {
UpdateDirtyImageRegion(pResource, Subresource, nullptr);
}
}
}
void D3D11ImmediateContext::ReadbackImageBuffer(
D3D11CommonTexture* pResource,
UINT Subresource) {
VkImageAspectFlags aspectMask = lookupFormatInfo(pResource->GetPackedFormat())->aspectMask;
VkImageSubresource subresource = pResource->GetSubresourceFromIndex(aspectMask, Subresource);
EmitCs([
cSrcImage = pResource->GetImage(),
cSrcSubresource = vk::makeSubresourceLayers(subresource),
cDstBuffer = pResource->GetMappedBuffer(Subresource),
cPackedFormat = pResource->GetPackedFormat()
] (DxvkContext* ctx) {
VkOffset3D offset = { 0, 0, 0 };
VkExtent3D extent = cSrcImage->mipLevelExtent(cSrcSubresource.mipLevel);
if (cSrcSubresource.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
ctx->copyImageToBuffer(cDstBuffer, 0, 0, 0,
cSrcImage, cSrcSubresource, offset, extent);
} else {
ctx->copyDepthStencilImageToPackedBuffer(cDstBuffer, 0,
VkOffset2D { 0, 0 },
VkExtent2D { extent.width, extent.height },
cSrcImage, cSrcSubresource,
VkOffset2D { 0, 0 },
VkExtent2D { extent.width, extent.height },
cPackedFormat);
}
});
if (pResource->HasSequenceNumber())
TrackTextureSequenceNumber(pResource, Subresource);
}
void D3D11ImmediateContext::UpdateDirtyImageRegion(
D3D11CommonTexture* pResource,
UINT Subresource,
const D3D11_COMMON_TEXTURE_REGION* pRegion) {
auto formatInfo = lookupFormatInfo(pResource->GetPackedFormat());
auto subresource = vk::makeSubresourceLayers(
pResource->GetSubresourceFromIndex(formatInfo->aspectMask, Subresource));
// Update the entire image if no dirty region was specified
D3D11_COMMON_TEXTURE_REGION region;
if (pRegion) {
region = *pRegion;
} else {
region.Offset = VkOffset3D { 0, 0, 0 };
region.Extent = pResource->MipLevelExtent(subresource.mipLevel);
}
auto subresourceLayout = pResource->GetSubresourceLayout(formatInfo->aspectMask, Subresource);
// Update dirty region one aspect at a time, due to
// how the data is laid out in the staging buffer.
for (uint32_t i = 0; i < pResource->GetPlaneCount(); i++) {
subresource.aspectMask = formatInfo->aspectMask;
if (formatInfo->flags.test(DxvkFormatFlag::MultiPlane))
subresource.aspectMask = vk::getPlaneAspect(i);
EmitCs([
cDstImage = pResource->GetImage(),
cDstSubresource = subresource,
cDstOffset = region.Offset,
cDstExtent = region.Extent,
cSrcBuffer = pResource->GetMappedBuffer(Subresource),
cSrcOffset = pResource->ComputeMappedOffset(Subresource, i, region.Offset),
cSrcRowPitch = subresourceLayout.RowPitch,
cSrcDepthPitch = subresourceLayout.DepthPitch,
cPackedFormat = pResource->GetPackedFormat()
] (DxvkContext* ctx) {
if (cDstSubresource.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
ctx->copyBufferToImage(
cDstImage, cDstSubresource, cDstOffset, cDstExtent,
cSrcBuffer, cSrcOffset, cSrcRowPitch, cSrcDepthPitch);
} else {
ctx->copyPackedBufferToDepthStencilImage(
cDstImage, cDstSubresource,
VkOffset2D { cDstOffset.x, cDstOffset.y },
VkExtent2D { cDstExtent.width, cDstExtent.height },
cSrcBuffer, 0,
VkOffset2D { cDstOffset.x, cDstOffset.y },
VkExtent2D { cDstExtent.width, cDstExtent.height },
cPackedFormat);
}
});
}
if (pResource->HasSequenceNumber())
TrackTextureSequenceNumber(pResource, Subresource);
}
void D3D11ImmediateContext::UpdateMappedBuffer(
D3D11Buffer* pDstBuffer,
UINT Offset,
@ -646,9 +730,12 @@ namespace dxvk {
if (!pState)
return;
Com<D3D11DeviceContextState> oldState = std::move(m_stateObject);
Com<D3D11DeviceContextState> newState = static_cast<D3D11DeviceContextState*>(pState);
// Reset all state affected by the current context state
ResetCommandListState();
Com<D3D11DeviceContextState, false> oldState = std::move(m_stateObject);
Com<D3D11DeviceContextState, false> newState = static_cast<D3D11DeviceContextState*>(pState);
if (oldState == nullptr)
oldState = new D3D11DeviceContextState(m_parent);
@ -661,7 +748,76 @@ namespace dxvk {
oldState->SetState(m_state);
newState->GetState(m_state);
RestoreState();
// Restore all state affected by the new context state
RestoreCommandListState();
}
void D3D11ImmediateContext::Acquire11on12Resource(
ID3D11Resource* pResource,
VkImageLayout SrcLayout) {
D3D10DeviceLock lock = LockContext();
auto texture = GetCommonTexture(pResource);
auto buffer = GetCommonBuffer(pResource);
if (buffer) {
EmitCs([
cBuffer = buffer->GetBuffer()
] (DxvkContext* ctx) {
ctx->emitBufferBarrier(cBuffer,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_MEMORY_READ_BIT,
cBuffer->info().stages,
cBuffer->info().access);
});
} else if (texture) {
EmitCs([
cImage = texture->GetImage(),
cLayout = SrcLayout
] (DxvkContext* ctx) {
ctx->emitImageBarrier(cImage, cLayout,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_MEMORY_READ_BIT,
cImage->info().layout,
cImage->info().stages,
cImage->info().access);
});
}
}
void D3D11ImmediateContext::Release11on12Resource(
ID3D11Resource* pResource,
VkImageLayout DstLayout) {
D3D10DeviceLock lock = LockContext();
auto texture = GetCommonTexture(pResource);
auto buffer = GetCommonBuffer(pResource);
if (buffer) {
EmitCs([
cBuffer = buffer->GetBuffer()
] (DxvkContext* ctx) {
ctx->emitBufferBarrier(cBuffer,
cBuffer->info().stages,
cBuffer->info().access,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_MEMORY_READ_BIT);
});
} else if (texture) {
EmitCs([
cImage = texture->GetImage(),
cLayout = DstLayout
] (DxvkContext* ctx) {
ctx->emitImageBarrier(cImage,
cImage->info().layout,
cImage->info().stages,
cImage->info().access,
cLayout, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_MEMORY_READ_BIT);
});
}
}
@ -682,6 +838,15 @@ namespace dxvk {
}
void D3D11ImmediateContext::EndFrame() {
D3D10DeviceLock lock = LockContext();
EmitCs<false>([] (DxvkContext* ctx) {
ctx->endFrame();
});
}
bool D3D11ImmediateContext::WaitForResource(
const Rc<DxvkResource>& Resource,
uint64_t SequenceNumber,
@ -707,14 +872,14 @@ namespace dxvk {
// We don't have to wait, but misbehaving games may
// still try to spin on `Map` until the resource is
// idle, so we should flush pending commands
FlushImplicit(FALSE);
ConsiderFlush(GpuFlushType::ImplicitSynchronization);
return false;
}
} else {
if (isInUse) {
// Make sure pending commands using the resource get
// executed on the the GPU if we have to wait for it
Flush();
ExecuteFlush(GpuFlushType::ImplicitSynchronization, nullptr, false);
SynchronizeCsThread(SequenceNumber);
m_device->waitForResource(Resource, access);
@ -727,7 +892,6 @@ namespace dxvk {
void D3D11ImmediateContext::EmitCsChunk(DxvkCsChunkRef&& chunk) {
m_csSeqNum = m_csThread.dispatchChunk(std::move(chunk));
m_csIsBusy = true;
}
@ -737,7 +901,7 @@ namespace dxvk {
uint64_t sequenceNumber = GetCurrentSequenceNumber();
pResource->TrackSequenceNumber(Subresource, sequenceNumber);
FlushImplicit(TRUE);
ConsiderFlush(GpuFlushType::ImplicitStrongHint);
}
@ -746,7 +910,7 @@ namespace dxvk {
uint64_t sequenceNumber = GetCurrentSequenceNumber();
pResource->TrackSequenceNumber(sequenceNumber);
FlushImplicit(TRUE);
ConsiderFlush(GpuFlushType::ImplicitStrongHint);
}
@ -758,40 +922,67 @@ namespace dxvk {
}
void D3D11ImmediateContext::FlushImplicit(BOOL StrongHint) {
// Flush only if the GPU is about to go idle, in
// order to keep the number of submissions low.
uint32_t pending = m_device->pendingSubmissions();
if (StrongHint || pending <= MaxPendingSubmits) {
auto now = dxvk::high_resolution_clock::now();
uint32_t delay = MinFlushIntervalUs
+ IncFlushIntervalUs * pending;
// Prevent flushing too often in short intervals.
if (now - m_lastFlush >= std::chrono::microseconds(delay))
Flush();
}
uint64_t D3D11ImmediateContext::GetPendingCsChunks() {
return GetCurrentSequenceNumber() - m_flushSeqNum;
}
void D3D11ImmediateContext::SignalEvent(HANDLE hEvent) {
uint64_t value = ++m_eventCount;
void D3D11ImmediateContext::ConsiderFlush(
GpuFlushType FlushType) {
uint64_t chunkId = GetCurrentSequenceNumber();
uint64_t submissionId = m_submissionFence->value();
if (m_eventSignal == nullptr)
m_eventSignal = new sync::CallbackFence();
if (m_flushTracker.considerFlush(FlushType, chunkId, submissionId))
ExecuteFlush(FlushType, nullptr, false);
}
m_eventSignal->setCallback(value, [hEvent] {
SetEvent(hEvent);
});
EmitCs([
cSignal = m_eventSignal,
cValue = value
void D3D11ImmediateContext::ExecuteFlush(
GpuFlushType FlushType,
HANDLE hEvent,
BOOL Synchronize) {
bool synchronizeSubmission = Synchronize && m_parent->Is11on12Device();
if (synchronizeSubmission)
m_submitStatus.result = VK_NOT_READY;
// Flush init context so that new resources are fully initialized
// before the app can access them in any way. This has to happen
// unconditionally since we may otherwise deadlock on Map.
m_parent->FlushInitContext();
// Exit early if there's nothing to do
if (!GetPendingCsChunks() && !hEvent)
return;
// Signal the submission fence and flush the command list
uint64_t submissionId = ++m_submissionId;
if (hEvent) {
m_submissionFence->setCallback(submissionId, [hEvent] {
SetEvent(hEvent);
});
}
EmitCs<false>([
cSubmissionFence = m_submissionFence,
cSubmissionId = submissionId,
cSubmissionStatus = synchronizeSubmission ? &m_submitStatus : nullptr
] (DxvkContext* ctx) {
ctx->signal(cSignal, cValue);
ctx->signal(cSubmissionFence, cSubmissionId);
ctx->flushCommandList(cSubmissionStatus);
});
FlushCsChunk();
// Notify flush tracker about the flush
m_flushSeqNum = m_csSeqNum;
m_flushTracker.notifyFlush(m_flushSeqNum, submissionId);
// If necessary, block calling thread until the
// Vulkan queue submission is performed.
if (synchronizeSubmission)
m_device->waitForSubmission(&m_submitStatus);
}
}

View File

@ -12,11 +12,12 @@ namespace dxvk {
class D3D11Buffer;
class D3D11CommonTexture;
class D3D11ImmediateContext : public D3D11DeviceContext {
class D3D11ImmediateContext : public D3D11CommonContext<D3D11ImmediateContext> {
friend class D3D11CommonContext<D3D11ImmediateContext>;
friend class D3D11SwapChain;
friend class D3D11VideoContext;
friend class D3D11DeviceContext;
friend class D3D11DXGIKeyedMutex;
public:
D3D11ImmediateContext(
@ -28,10 +29,6 @@ namespace dxvk {
REFIID riid,
void** ppvObject);
D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE GetType();
UINT STDMETHODCALLTYPE GetContextFlags();
HRESULT STDMETHODCALLTYPE GetData(
ID3D11Asynchronous* pAsync,
void* pData,
@ -77,61 +74,45 @@ namespace dxvk {
ID3D11Resource* pResource,
UINT Subresource);
void STDMETHODCALLTYPE UpdateSubresource(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch);
void STDMETHODCALLTYPE UpdateSubresource1(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch,
UINT CopyFlags);
void STDMETHODCALLTYPE OMSetRenderTargets(
UINT NumViews,
ID3D11RenderTargetView* const* ppRenderTargetViews,
ID3D11DepthStencilView* pDepthStencilView);
void STDMETHODCALLTYPE OMSetRenderTargetsAndUnorderedAccessViews(
UINT NumRTVs,
ID3D11RenderTargetView* const* ppRenderTargetViews,
ID3D11DepthStencilView* pDepthStencilView,
UINT UAVStartSlot,
UINT NumUAVs,
ID3D11UnorderedAccessView* const* ppUnorderedAccessViews,
const UINT* pUAVInitialCounts);
void STDMETHODCALLTYPE SwapDeviceContextState(
ID3DDeviceContextState* pState,
ID3DDeviceContextState** ppPreviousState);
void Acquire11on12Resource(
ID3D11Resource* pResource,
VkImageLayout SrcLayout);
void Release11on12Resource(
ID3D11Resource* pResource,
VkImageLayout DstLayout);
void SynchronizeCsThread(
uint64_t SequenceNumber);
D3D10DeviceLock LockContext() {
return m_multithread.AcquireLock();
}
private:
DxvkCsThread m_csThread;
uint64_t m_csSeqNum = 0ull;
bool m_csIsBusy = false;
Rc<sync::CallbackFence> m_eventSignal;
uint64_t m_eventCount = 0ull;
uint32_t m_mappedImageCount = 0u;
VkDeviceSize m_maxImplicitDiscardSize = 0ull;
dxvk::high_resolution_clock::time_point m_lastFlush
= dxvk::high_resolution_clock::now();
D3D11VideoContext m_videoContext;
Com<D3D11DeviceContextState> m_stateObject;
Rc<sync::CallbackFence> m_submissionFence;
uint64_t m_submissionId = 0ull;
DxvkSubmitStatus m_submitStatus;
uint64_t m_flushSeqNum = 0ull;
GpuFlushTracker m_flushTracker;
D3D10Multithread m_multithread;
D3D11VideoContext m_videoContext;
Com<D3D11DeviceContextState, false> m_stateObject;
HRESULT MapBuffer(
D3D11Buffer* pResource,
@ -150,20 +131,31 @@ namespace dxvk {
D3D11CommonTexture* pResource,
UINT Subresource);
void ReadbackImageBuffer(
D3D11CommonTexture* pResource,
UINT Subresource);
void UpdateDirtyImageRegion(
D3D11CommonTexture* pResource,
UINT Subresource,
const D3D11_COMMON_TEXTURE_REGION* pRegion);
void UpdateMappedBuffer(
D3D11Buffer* pDstBuffer,
UINT Offset,
UINT Length,
const void* pSrcData,
UINT CopyFlags);
D3D11Buffer* pDstBuffer,
UINT Offset,
UINT Length,
const void* pSrcData,
UINT CopyFlags);
void SynchronizeDevice();
void EndFrame();
bool WaitForResource(
const Rc<DxvkResource>& Resource,
uint64_t SequenceNumber,
D3D11_MAP MapType,
UINT MapFlags);
const Rc<DxvkResource>& Resource,
uint64_t SequenceNumber,
D3D11_MAP MapType,
UINT MapFlags);
void EmitCsChunk(DxvkCsChunkRef&& chunk);
@ -176,10 +168,16 @@ namespace dxvk {
uint64_t GetCurrentSequenceNumber();
void FlushImplicit(BOOL StrongHint);
uint64_t GetPendingCsChunks();
void ConsiderFlush(
GpuFlushType FlushType);
void ExecuteFlush(
GpuFlushType FlushType,
HANDLE hEvent,
BOOL Synchronize);
void SignalEvent(HANDLE hEvent);
};
}

View File

@ -15,128 +15,237 @@
namespace dxvk {
/**
* \brief Per-stage state
*
* Stores an object of the given type for each shader stage.
* \tparam Object type
*/
template<typename T>
class D3D11ShaderStageState {
public:
T& operator [] (DxbcProgramType type) { return m_state[uint32_t(type)]; }
const T& operator [] (DxbcProgramType type) const { return m_state[uint32_t(type)]; }
/**
* \brief Calls reset method on all objects
*/
void reset() {
for (auto& state : m_state)
state.reset();
}
private:
std::array<T, 6> m_state = { };
};
/**
* \brief Constant buffer bindings
*
* Stores the bound buffer range from a runtime point of view,
* as well as the range that is actually bound to the context.
*/
struct D3D11ConstantBufferBinding {
Com<D3D11Buffer> buffer = nullptr;
Com<D3D11Buffer, false> buffer = nullptr;
UINT constantOffset = 0;
UINT constantCount = 0;
UINT constantBound = 0;
};
using D3D11ConstantBufferBindings = std::array<
D3D11ConstantBufferBinding, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT>;
using D3D11SamplerBindings = std::array<
D3D11SamplerState*, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT>;
struct D3D11ShaderResourceBindings {
std::array<Com<D3D11ShaderResourceView>, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> views = { };
DxvkBindingSet<D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> hazardous = { };
};
using D3D11UnorderedAccessBindings = std::array<
Com<D3D11UnorderedAccessView>, D3D11_1_UAV_SLOT_COUNT>;
struct D3D11ContextStateVS {
Com<D3D11VertexShader> shader = nullptr;
D3D11ConstantBufferBindings constantBuffers = { };
D3D11SamplerBindings samplers = { };
D3D11ShaderResourceBindings shaderResources = { };
};
struct D3D11ContextStateHS {
Com<D3D11HullShader> shader = nullptr;
D3D11ConstantBufferBindings constantBuffers = { };
D3D11SamplerBindings samplers = { };
D3D11ShaderResourceBindings shaderResources = { };
};
struct D3D11ContextStateDS {
Com<D3D11DomainShader> shader = nullptr;
D3D11ConstantBufferBindings constantBuffers = { };
D3D11SamplerBindings samplers = { };
D3D11ShaderResourceBindings shaderResources = { };
};
struct D3D11ContextStateGS {
Com<D3D11GeometryShader> shader = nullptr;
D3D11ConstantBufferBindings constantBuffers = { };
D3D11SamplerBindings samplers = { };
D3D11ShaderResourceBindings shaderResources = { };
};
struct D3D11ContextStatePS {
Com<D3D11PixelShader> shader = nullptr;
D3D11ConstantBufferBindings constantBuffers = { };
D3D11SamplerBindings samplers = { };
D3D11ShaderResourceBindings shaderResources = { };
D3D11UnorderedAccessBindings unorderedAccessViews = { };
};
struct D3D11ContextStateCS {
Com<D3D11ComputeShader> shader = nullptr;
D3D11ConstantBufferBindings constantBuffers = { };
D3D11SamplerBindings samplers = { };
D3D11ShaderResourceBindings shaderResources = { };
D3D11UnorderedAccessBindings unorderedAccessViews = { };
struct D3D11ShaderStageCbvBinding {
std::array<D3D11ConstantBufferBinding, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT> buffers = { };
DxvkBindingSet<D3D11_1_UAV_SLOT_COUNT> uavMask = { };
uint32_t maxCount = 0;
void reset() {
for (uint32_t i = 0; i < maxCount; i++)
buffers[i] = D3D11ConstantBufferBinding();
maxCount = 0;
}
};
using D3D11CbvBindings = D3D11ShaderStageState<D3D11ShaderStageCbvBinding>;
/**
* \brief Shader resource bindings
*
* Stores bound shader resource views, as well as a bit
* set of views that are potentially hazardous.
*/
struct D3D11ShaderStageSrvBinding {
std::array<Com<D3D11ShaderResourceView, false>, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> views = { };
DxvkBindingSet<D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> hazardous = { };
uint32_t maxCount = 0;
void reset() {
for (uint32_t i = 0; i < maxCount; i++)
views[i] = nullptr;
hazardous.clear();
maxCount = 0;
}
};
using D3D11SrvBindings = D3D11ShaderStageState<D3D11ShaderStageSrvBinding>;
/**
* \brief Sampler bindings
*
* Stores bound samplers.
*/
struct D3D11ShaderStageSamplerBinding {
std::array<D3D11SamplerState*, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT> samplers = { };
uint32_t maxCount = 0;
void reset() {
for (uint32_t i = 0; i < maxCount; i++)
samplers[i] = nullptr;
maxCount = 0;
}
};
using D3D11SamplerBindings = D3D11ShaderStageState<D3D11ShaderStageSamplerBinding>;
/**
* \brief UAV bindings
*
* Stores bound UAVs. For compute shader UAVs,
* we also store a bit mask of bound UAVs.
*/
using D3D11ShaderStageUavBinding = std::array<Com<D3D11UnorderedAccessView, false>, D3D11_1_UAV_SLOT_COUNT>;
struct D3D11UavBindings {
D3D11ShaderStageUavBinding views = { };
DxvkBindingSet<D3D11_1_UAV_SLOT_COUNT> mask = { };
uint32_t maxCount = 0;
void reset() {
for (uint32_t i = 0; i < maxCount; i++)
views[i] = nullptr;
mask.clear();
maxCount = 0;
}
};
/**
* \brief Input assembly state
*
* Stores vertex buffers, the index buffer, the
* input layout, and the dynamic primitive topology.
*/
struct D3D11VertexBufferBinding {
Com<D3D11Buffer> buffer = nullptr;
UINT offset = 0;
UINT stride = 0;
Com<D3D11Buffer, false> buffer = nullptr;
UINT offset = 0;
UINT stride = 0;
};
struct D3D11IndexBufferBinding {
Com<D3D11Buffer> buffer = nullptr;
UINT offset = 0;
DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
Com<D3D11Buffer, false> buffer = nullptr;
UINT offset = 0;
DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
};
struct D3D11ContextStateID {
Com<D3D11Buffer> argBuffer = nullptr;
Com<D3D11Buffer> cntBuffer = nullptr;
};
struct D3D11ContextStateIA {
Com<D3D11InputLayout> inputLayout = nullptr;
D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
Com<D3D11InputLayout, false> inputLayout = nullptr;
D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
std::array<D3D11VertexBufferBinding, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT> vertexBuffers = { };
D3D11IndexBufferBinding indexBuffer = { };
uint32_t maxVbCount = 0;
void reset() {
inputLayout = nullptr;
primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
for (uint32_t i = 0; i < maxVbCount; i++)
vertexBuffers[i] = D3D11VertexBufferBinding();
indexBuffer = D3D11IndexBufferBinding();
}
};
/**
* \brief Output merger state
*
* Stores RTV, DSV, and graphics UAV bindings, as well as related state.
*/
using D3D11RenderTargetViewBinding = std::array<Com<D3D11RenderTargetView, false>, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT>;
struct D3D11ContextStateOM {
std::array<Com<D3D11RenderTargetView, false>, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT> renderTargetViews = { };
Com<D3D11DepthStencilView, false> depthStencilView = { };
D3D11ShaderStageUavBinding uavs = { };
D3D11RenderTargetViewBinding rtvs = { };
Com<D3D11DepthStencilView, false> dsv = { };
D3D11BlendState* cbState = nullptr;
D3D11DepthStencilState* dsState = nullptr;
FLOAT blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
UINT sampleMask = 0xFFFFFFFFu;
UINT stencilRef = 0u;
UINT sampleCount = 0u;
UINT sampleMask = D3D11_DEFAULT_SAMPLE_MASK;
UINT stencilRef = D3D11_DEFAULT_STENCIL_REFERENCE;
UINT maxRtv = 0u;
UINT maxUav = 0u;
void reset() {
for (uint32_t i = 0; i < maxUav; i++)
uavs[i] = nullptr;
for (uint32_t i = 0; i < maxRtv; i++)
rtvs[i] = nullptr;
dsv = nullptr;
cbState = nullptr;
dsState = nullptr;
for (uint32_t i = 0; i < 4; i++)
blendFactor[i] = 1.0f;
sampleCount = 0u;
sampleMask = D3D11_DEFAULT_SAMPLE_MASK;
stencilRef = D3D11_DEFAULT_STENCIL_REFERENCE;
maxRtv = 0;
maxUav = 0;
}
};
/**
* \brief Indirect draw state
*
* Stores the current indirct draw
* argument and draw count buffer.
*/
struct D3D11ContextStateID {
Com<D3D11Buffer, false> argBuffer = nullptr;
Com<D3D11Buffer, false> cntBuffer = nullptr;
void reset() {
argBuffer = nullptr;
cntBuffer = nullptr;
}
};
/**
* \brief Rasterizer state
*
* Stores viewport info and the rasterizer state object.
*/
struct D3D11ContextStateRS {
uint32_t numViewports = 0;
uint32_t numScissors = 0;
@ -145,43 +254,97 @@ namespace dxvk {
std::array<D3D11_RECT, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE> scissors = { };
D3D11RasterizerState* state = nullptr;
void reset() {
for (uint32_t i = 0; i < numViewports; i++)
viewports[i] = D3D11_VIEWPORT();
for (uint32_t i = 0; i < numScissors; i++)
scissors[i] = D3D11_RECT();
numViewports = 0;
numScissors = 0;
state = nullptr;
}
};
/**
* \brief Stream output binding
*
* Stores stream output buffers with offset.
*/
struct D3D11ContextSoTarget {
Com<D3D11Buffer> buffer = nullptr;
UINT offset = 0;
Com<D3D11Buffer, false> buffer = nullptr;
UINT offset = 0;
};
struct D3D11ContextStateSO {
std::array<D3D11ContextSoTarget, D3D11_SO_BUFFER_SLOT_COUNT> targets = { };
void reset() {
for (uint32_t i = 0; i < targets.size(); i++)
targets[i] = D3D11ContextSoTarget();
}
};
/**
* \brief Predication state
*
* Stores predication info.
*/
struct D3D11ContextStatePR {
Com<D3D11Query> predicateObject = nullptr;
BOOL predicateValue = FALSE;
Com<D3D11Query, false> predicateObject = nullptr;
BOOL predicateValue = false;
void reset() {
predicateObject = nullptr;
predicateValue = false;
}
};
/**
* \brief Context state
*/
struct D3D11ContextState {
D3D11ContextStateCS cs;
D3D11ContextStateDS ds;
D3D11ContextStateGS gs;
D3D11ContextStateHS hs;
D3D11ContextStatePS ps;
D3D11ContextStateVS vs;
Com<D3D11VertexShader, false> vs;
Com<D3D11HullShader, false> hs;
Com<D3D11DomainShader, false> ds;
Com<D3D11GeometryShader, false> gs;
Com<D3D11PixelShader, false> ps;
Com<D3D11ComputeShader, false> cs;
D3D11ContextStateID id;
D3D11ContextStateIA ia;
D3D11ContextStateOM om;
D3D11ContextStateRS rs;
D3D11ContextStateSO so;
D3D11ContextStatePR pr;
D3D11CbvBindings cbv;
D3D11SrvBindings srv;
D3D11UavBindings uav;
D3D11SamplerBindings samplers;
};
/**
* \brief Maximum used binding numbers in a shader stage
*/
struct D3D11MaxUsedStageBindings {
uint32_t cbvCount : 5;
uint32_t srvCount : 9;
uint32_t uavCount : 7;
uint32_t samplerCount : 5;
uint32_t reserved : 6;
};
/**
* \brief Maximum used binding numbers for all context state
*/
struct D3D11MaxUsedBindings {
std::array<D3D11MaxUsedStageBindings, 6> stages;
uint32_t vbCount;
uint32_t soCount;
};
}

View File

@ -37,12 +37,15 @@ namespace dxvk {
if (riid == __uuidof(ID3D10DeviceChild)
|| riid == __uuidof(ID3D10DepthStencilState)) {
*ppvObject = ref(this);
*ppvObject = ref(&m_d3d10);
return S_OK;
}
Logger::warn("D3D11DepthStencilState::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
if (logQueryInterfaceError(__uuidof(ID3D11DepthStencilState), riid)) {
Logger::warn("D3D11DepthStencilState::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
}
return E_NOINTERFACE;
}
@ -52,7 +55,7 @@ namespace dxvk {
}
void D3D11DepthStencilState::BindToContext(const Rc<DxvkContext>& ctx) {
void D3D11DepthStencilState::BindToContext(DxvkContext* ctx) {
ctx->setDepthStencilState(m_state);
}

View File

@ -29,8 +29,7 @@ namespace dxvk {
void STDMETHODCALLTYPE GetDesc(
D3D11_DEPTH_STENCIL_DESC* pDesc) final;
void BindToContext(
const Rc<DxvkContext>& ctx);
void BindToContext(DxvkContext* ctx);
D3D10DepthStencilState* GetD3D10Iface() {
return &m_d3d10;

File diff suppressed because it is too large Load Diff

View File

@ -16,9 +16,11 @@
#include "d3d11_cmdlist.h"
#include "d3d11_cuda.h"
#include "d3d11_features.h"
#include "d3d11_initializer.h"
#include "d3d11_interfaces.h"
#include "d3d11_interop.h"
#include "d3d11_on_12.h"
#include "d3d11_options.h"
#include "d3d11_shader.h"
#include "d3d11_state.h"
@ -31,7 +33,6 @@ namespace dxvk {
class D3D11CommonShader;
class D3D11CommonTexture;
class D3D11Counter;
class D3D11DeviceContext;
class D3D11DXGIDevice;
class D3D11ImmediateContext;
class D3D11Predicate;
@ -260,7 +261,7 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE CreateFence(
UINT64 InitialValue,
D3D11_FENCE_FLAG Flags,
REFIID ReturnedInterface,
REFIID riid,
void** ppFence);
void STDMETHODCALLTYPE ReadFromSubresource(
@ -420,19 +421,23 @@ namespace dxvk {
D3D10Device* GetD3D10Interface() const {
return m_d3d10Device;
}
static bool CheckFeatureLevelSupport(
const Rc<DxvkInstance>& instance,
const Rc<DxvkAdapter>& adapter,
D3D_FEATURE_LEVEL featureLevel);
D3D11ImmediateContext* GetContext() const {
return m_context.ptr();
}
bool Is11on12Device() const;
static D3D_FEATURE_LEVEL GetMaxFeatureLevel(
const Rc<DxvkInstance>& Instance,
const Rc<DxvkAdapter>& Adapter);
static DxvkDeviceFeatures GetDeviceFeatures(
const Rc<DxvkAdapter>& adapter,
D3D_FEATURE_LEVEL featureLevel);
const Rc<DxvkAdapter>& Adapter);
private:
IDXGIObject* m_container;
D3D11DXGIDevice* m_container;
D3D_FEATURE_LEVEL m_featureLevel;
UINT m_featureFlags;
@ -455,7 +460,10 @@ namespace dxvk {
D3D11StateObjectSet<D3D11RasterizerState> m_rsStateObjects;
D3D11StateObjectSet<D3D11SamplerState> m_samplerObjects;
D3D11ShaderModuleSet m_shaderModules;
D3D_FEATURE_LEVEL m_maxFeatureLevel;
D3D11DeviceFeatures m_deviceFeatures;
HRESULT CreateShaderModule(
D3D11CommonShader* pShaderModule,
DxvkShaderKey ShaderKey,
@ -465,13 +473,14 @@ namespace dxvk {
const DxbcModuleInfo* pModuleInfo);
HRESULT GetFormatSupportFlags(
DXGI_FORMAT Format,
UINT* pFlags1,
UINT* pFlags2) const;
DXGI_FORMAT Format,
UINT* pFlags1,
UINT* pFlags2) const;
BOOL GetImageTypeSupport(
VkFormat Format,
VkImageType Type) const;
VkFormat Format,
VkImageType Type,
VkImageCreateFlags Flags) const;
template<bool IsKmtHandle>
HRESULT OpenSharedResourceGeneric(
@ -488,13 +497,10 @@ namespace dxvk {
Void* pData,
UINT RowPitch,
UINT DepthPitch,
ID3D11Resource* pResource,
D3D11CommonTexture* pTexture,
UINT Subresource,
const D3D11_BOX* pBox);
static D3D_FEATURE_LEVEL GetMaxFeatureLevel(
const Rc<DxvkInstance>& pInstance);
};
@ -692,39 +698,36 @@ namespace dxvk {
/**
* \brief DXGI swap chain factory
* \brief DXVK swap chain factory
*/
class WineDXGISwapChainFactory : public IWineDXGISwapChainFactory {
class DXGIVkSwapChainFactory : public IDXGIVkSwapChainFactory {
public:
WineDXGISwapChainFactory(
DXGIVkSwapChainFactory(
D3D11DXGIDevice* pContainer,
D3D11Device* pDevice);
ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid,
void** ppvObject);
HRESULT STDMETHODCALLTYPE CreateSwapChainForHwnd(
IDXGIFactory* pFactory,
HWND hWnd,
const DXGI_SWAP_CHAIN_DESC1* pDesc,
const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc,
IDXGIOutput* pRestrictToOutput,
IDXGISwapChain1** ppSwapChain);
HRESULT STDMETHODCALLTYPE CreateSwapChain(
IDXGIVkSurfaceFactory* pSurfaceFactory,
const DXGI_SWAP_CHAIN_DESC1* pDesc,
IDXGIVkSwapChain** ppSwapChain);
private:
D3D11DXGIDevice* m_container;
D3D11Device* m_device;
};
/**
* \brief D3D11 device metadata shenanigans
@ -768,8 +771,11 @@ namespace dxvk {
D3D11DXGIDevice(
IDXGIAdapter* pAdapter,
const Rc<DxvkInstance>& pDxvkInstance,
const Rc<DxvkAdapter>& pDxvkAdapter,
ID3D12Device* pD3D12Device,
ID3D12CommandQueue* pD3D12Queue,
Rc<DxvkInstance> pDxvkInstance,
Rc<DxvkAdapter> pDxvkAdapter,
Rc<DxvkDevice> pDxvkDevice,
D3D_FEATURE_LEVEL FeatureLevel,
UINT FeatureFlags);
@ -838,6 +844,10 @@ namespace dxvk {
Rc<DxvkDevice> STDMETHODCALLTYPE GetDXVKDevice();
BOOL Is11on12Device() const {
return m_d3d11on12.Is11on12Device();
}
private:
Com<IDXGIAdapter> m_dxgiAdapter;
@ -850,14 +860,13 @@ namespace dxvk {
D3D11DeviceExt m_d3d11DeviceExt;
D3D11VkInterop m_d3d11Interop;
D3D11VideoDevice m_d3d11Video;
D3D11on12Device m_d3d11on12;
DXGIDXVKDevice m_metaDevice;
WineDXGISwapChainFactory m_wineFactory;
DXGIVkSwapChainFactory m_dxvkFactory;
uint32_t m_frameLatency = DefaultFrameLatency;
Rc<DxvkDevice> CreateDevice(D3D_FEATURE_LEVEL FeatureLevel);
};
}

View File

@ -0,0 +1,399 @@
#include <array>
#include "d3d11_features.h"
namespace dxvk {
D3D11DeviceFeatures::D3D11DeviceFeatures() {
}
D3D11DeviceFeatures::D3D11DeviceFeatures(
const Rc<DxvkInstance>& Instance,
const Rc<DxvkAdapter>& Adapter,
D3D_FEATURE_LEVEL FeatureLevel)
: m_features (Adapter->features()),
m_properties (Adapter->devicePropertiesExt()) {
// Assume no TBDR. DXVK does not optimize for TBDR architectures
// anyway, and D3D11 does not really provide meaningful support.
m_architectureInfo.TileBasedDeferredRenderer = FALSE;
// D3D9 options. We unconditionally support all of these.
m_d3d9Options.FullNonPow2TextureSupport = TRUE;
m_d3d9Options1.FullNonPow2TextureSupported = TRUE;
m_d3d9Options1.DepthAsTextureWithLessEqualComparisonFilterSupported = TRUE;
m_d3d9Options1.SimpleInstancingSupported = TRUE;
m_d3d9Options1.TextureCubeFaceRenderTargetWithNonCubeDepthStencilSupported = TRUE;
m_d3d9Shadow.SupportsDepthAsTextureWithLessEqualComparisonFilter = TRUE;
m_d3d9SimpleInstancing.SimpleInstancingSupported = TRUE;
// D3D10 options. We unconditionally support compute shaders.
m_d3d10Options.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x = TRUE;
// D3D11.1 options. All of these are required for Feature Level 11_1.
auto sharedResourceTier = DetermineSharedResourceTier(Adapter, FeatureLevel);
bool hasDoublePrecisionSupport = m_features.core.features.shaderFloat64
&& m_features.core.features.shaderInt64;
m_d3d11Options.DiscardAPIsSeenByDriver = TRUE;
m_d3d11Options.FlagsForUpdateAndCopySeenByDriver = TRUE;
m_d3d11Options.ClearView = TRUE;
m_d3d11Options.CopyWithOverlap = TRUE;
m_d3d11Options.ConstantBufferPartialUpdate = TRUE;
m_d3d11Options.ConstantBufferOffsetting = TRUE;
m_d3d11Options.MapNoOverwriteOnDynamicConstantBuffer = TRUE;
m_d3d11Options.MapNoOverwriteOnDynamicBufferSRV = TRUE;
m_d3d11Options.ExtendedResourceSharing = sharedResourceTier > D3D11_SHARED_RESOURCE_TIER_0;
if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0) {
m_d3d11Options.OutputMergerLogicOp = m_features.core.features.logicOp;
m_d3d11Options.MultisampleRTVWithForcedSampleCountOne = TRUE; // Not really
}
if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0) {
m_d3d11Options.UAVOnlyRenderingForcedSampleCount = TRUE;
m_d3d11Options.SAD4ShaderInstructions = TRUE;
m_d3d11Options.ExtendedDoublesShaderInstructions = hasDoublePrecisionSupport;
}
// D3D11.2 options.
auto tiledResourcesTier = DetermineTiledResourcesTier(FeatureLevel);
m_d3d11Options1.TiledResourcesTier = tiledResourcesTier;
m_d3d11Options1.MinMaxFiltering = tiledResourcesTier >= D3D11_TILED_RESOURCES_TIER_2;
m_d3d11Options1.ClearViewAlsoSupportsDepthOnlyFormats = TRUE;
if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0)
m_d3d11Options1.MapOnDefaultBuffers = TRUE;
// D3D11.3 options
m_d3d11Options2.TypedUAVLoadAdditionalFormats = DetermineUavExtendedTypedLoadSupport(Adapter, FeatureLevel);
m_d3d11Options2.ConservativeRasterizationTier = DetermineConservativeRasterizationTier(FeatureLevel);
m_d3d11Options2.TiledResourcesTier = tiledResourcesTier;
m_d3d11Options2.StandardSwizzle = FALSE;
m_d3d11Options2.UnifiedMemoryArchitecture = FALSE;
if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0)
m_d3d11Options2.MapOnDefaultTextures = TRUE;
if (FeatureLevel >= D3D_FEATURE_LEVEL_11_1) {
m_d3d11Options2.ROVsSupported = m_features.extFragmentShaderInterlock.fragmentShaderPixelInterlock;
m_d3d11Options2.PSSpecifiedStencilRefSupported = m_features.extShaderStencilExport;
}
// More D3D11.3 options
if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0) {
m_d3d11Options3.VPAndRTArrayIndexFromAnyShaderFeedingRasterizer =
m_features.vk12.shaderOutputViewportIndex &&
m_features.vk12.shaderOutputLayer;
}
// D3D11.4 options
m_d3d11Options4.ExtendedNV12SharedTextureSupported = sharedResourceTier > D3D11_SHARED_RESOURCE_TIER_0;
// More D3D11.4 options
m_d3d11Options5.SharedResourceTier = sharedResourceTier;
// Double-precision support
if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0)
m_doubles.DoublePrecisionFloatShaderOps = hasDoublePrecisionSupport;
// These numbers are not accurate, but we have no real way to query these
m_gpuVirtualAddress.MaxGPUVirtualAddressBitsPerResource = 32;
m_gpuVirtualAddress.MaxGPUVirtualAddressBitsPerProcess = 40;
// Marker support only depends on the debug utils extension
m_marker.Profile = Instance->extensions().extDebugUtils;
// DXVK will keep all shaders in memory once created, and all Vulkan
// drivers that we know of that can run DXVK have an on-disk cache.
m_shaderCache.SupportFlags = D3D11_SHADER_CACHE_SUPPORT_AUTOMATIC_INPROC_CACHE
| D3D11_SHADER_CACHE_SUPPORT_AUTOMATIC_DISK_CACHE;
// DXVK does not support min precision
m_shaderMinPrecision.PixelShaderMinPrecision = 0;
m_shaderMinPrecision.AllOtherShaderStagesMinPrecision = 0;
// Report native support for command lists here so that we do not actually have
// to re-implement the UpdateSubresource bug from the D3D11 runtime, see MSDN:
// https://msdn.microsoft.com/en-us/library/windows/desktop/ff476486(v=vs.85).aspx)
m_threading.DriverConcurrentCreates = TRUE;
m_threading.DriverCommandLists = TRUE;
}
D3D11DeviceFeatures::~D3D11DeviceFeatures() {
}
HRESULT D3D11DeviceFeatures::GetFeatureData(
D3D11_FEATURE Feature,
UINT FeatureDataSize,
void* pFeatureData) const {
switch (Feature) {
case D3D11_FEATURE_ARCHITECTURE_INFO:
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_architectureInfo);
case D3D11_FEATURE_D3D9_OPTIONS:
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d9Options);
case D3D11_FEATURE_D3D9_OPTIONS1:
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d9Options1);
case D3D11_FEATURE_D3D9_SHADOW_SUPPORT:
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d9Shadow);
case D3D11_FEATURE_D3D9_SIMPLE_INSTANCING_SUPPORT:
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d9SimpleInstancing);
case D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS:
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d10Options);
case D3D11_FEATURE_D3D11_OPTIONS:
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d11Options);
case D3D11_FEATURE_D3D11_OPTIONS1:
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d11Options1);
case D3D11_FEATURE_D3D11_OPTIONS2:
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d11Options2);
case D3D11_FEATURE_D3D11_OPTIONS3:
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d11Options3);
case D3D11_FEATURE_D3D11_OPTIONS4:
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d11Options4);
case D3D11_FEATURE_D3D11_OPTIONS5:
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d11Options5);
case D3D11_FEATURE_DOUBLES:
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_doubles);
case D3D11_FEATURE_GPU_VIRTUAL_ADDRESS_SUPPORT:
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_gpuVirtualAddress);
case D3D11_FEATURE_MARKER_SUPPORT:
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_marker);
case D3D11_FEATURE_SHADER_CACHE:
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_shaderCache);
case D3D11_FEATURE_SHADER_MIN_PRECISION_SUPPORT:
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_shaderMinPrecision);
case D3D11_FEATURE_THREADING:
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_threading);
default:
Logger::err(str::format("D3D11: Unknown feature: ", Feature));
return E_INVALIDARG;
}
}
D3D_FEATURE_LEVEL D3D11DeviceFeatures::GetMaxFeatureLevel(
const Rc<DxvkInstance>& Instance,
const Rc<DxvkAdapter>& Adapter) {
D3D11DeviceFeatures features(Instance, Adapter, D3D_FEATURE_LEVEL_12_1);
return features.GetMaxFeatureLevel();
}
D3D11_CONSERVATIVE_RASTERIZATION_TIER D3D11DeviceFeatures::DetermineConservativeRasterizationTier(
D3D_FEATURE_LEVEL FeatureLevel) {
if (FeatureLevel < D3D_FEATURE_LEVEL_11_1
|| !m_features.extConservativeRasterization)
return D3D11_CONSERVATIVE_RASTERIZATION_NOT_SUPPORTED;
// We don't really have a way to query uncertainty regions,
// so just check degenerate triangle behaviour
if (!m_properties.extConservativeRasterization.degenerateTrianglesRasterized)
return D3D11_CONSERVATIVE_RASTERIZATION_TIER_1;
// Inner coverage is required for Tier 3 support
if (!m_properties.extConservativeRasterization.fullyCoveredFragmentShaderInputVariable)
return D3D11_CONSERVATIVE_RASTERIZATION_TIER_2;
return D3D11_CONSERVATIVE_RASTERIZATION_TIER_3;
}
D3D11_SHARED_RESOURCE_TIER D3D11DeviceFeatures::DetermineSharedResourceTier(
const Rc<DxvkAdapter>& Adapter,
D3D_FEATURE_LEVEL FeatureLevel) {
static std::atomic<bool> s_errorShown = { false };
// Lie about supporting Tier 1 since that's the
// minimum required tier for Feature Level 11_1
if (!Adapter->features().khrExternalMemoryWin32) {
if (!s_errorShown.exchange(true))
Logger::warn("D3D11DeviceFeatures: External memory features not supported");
return D3D11_SHARED_RESOURCE_TIER_1;
}
// Check support for extended formats. Ignore multi-plane
// formats here since driver support varies too much.
std::array<VkFormat, 30> requiredFormats = {{
VK_FORMAT_R16G16B16A16_SFLOAT,
VK_FORMAT_R32G32B32A32_SFLOAT,
VK_FORMAT_R32G32B32A32_UINT,
VK_FORMAT_R32G32B32A32_SINT,
VK_FORMAT_R16G16B16A16_SFLOAT,
VK_FORMAT_R16G16B16A16_UNORM,
VK_FORMAT_R16G16B16A16_UINT,
VK_FORMAT_R16G16B16A16_SNORM,
VK_FORMAT_R16G16B16A16_SINT,
VK_FORMAT_A2B10G10R10_UNORM_PACK32,
VK_FORMAT_A2B10G10R10_UINT_PACK32,
VK_FORMAT_R8G8B8A8_UNORM,
VK_FORMAT_R8G8B8A8_SRGB,
VK_FORMAT_R8G8B8A8_UINT,
VK_FORMAT_R8G8B8A8_SNORM,
VK_FORMAT_R8G8B8A8_SINT,
VK_FORMAT_B8G8R8A8_UNORM,
VK_FORMAT_B8G8R8A8_SRGB,
VK_FORMAT_R32_SFLOAT,
VK_FORMAT_R32_UINT,
VK_FORMAT_R32_SINT,
VK_FORMAT_R16_SFLOAT,
VK_FORMAT_R16_UNORM,
VK_FORMAT_R16_UINT,
VK_FORMAT_R16_SNORM,
VK_FORMAT_R16_SINT,
VK_FORMAT_R8_UNORM,
VK_FORMAT_R8_UINT,
VK_FORMAT_R8_SNORM,
VK_FORMAT_R8_SINT,
}};
bool allKmtHandlesSupported = true;
bool allNtHandlesSupported = true;
for (auto f : requiredFormats) {
allKmtHandlesSupported &= CheckFormatSharingSupport(Adapter, f, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT);
allNtHandlesSupported &= CheckFormatSharingSupport(Adapter, f, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT);
}
// Again, lie about at least tier 1 support
if (!allKmtHandlesSupported) {
if (!s_errorShown.exchange(true))
Logger::warn("D3D11DeviceFeatures: Some formats not supported for resource sharing");
return D3D11_SHARED_RESOURCE_TIER_1;
}
// Tier 2 requires all the above formats to be shareable
// with NT handles in order to support D3D12 interop
if (!allNtHandlesSupported)
return D3D11_SHARED_RESOURCE_TIER_1;
// Tier 3 additionally requires R11G11B10 to be
// shareable with D3D12
if (!CheckFormatSharingSupport(Adapter, VK_FORMAT_B10G11R11_UFLOAT_PACK32, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT))
return D3D11_SHARED_RESOURCE_TIER_2;
return D3D11_SHARED_RESOURCE_TIER_3;
}
D3D11_TILED_RESOURCES_TIER D3D11DeviceFeatures::DetermineTiledResourcesTier(
D3D_FEATURE_LEVEL FeatureLevel) {
if (FeatureLevel < D3D_FEATURE_LEVEL_11_0
|| !m_features.core.features.sparseBinding
|| !m_features.core.features.sparseResidencyBuffer
|| !m_features.core.features.sparseResidencyImage2D
|| !m_features.core.features.sparseResidencyAliased
|| !m_properties.core.properties.sparseProperties.residencyStandard2DBlockShape)
return D3D11_TILED_RESOURCES_NOT_SUPPORTED;
if (FeatureLevel < D3D_FEATURE_LEVEL_11_1
|| !m_features.core.features.shaderResourceResidency
|| !m_features.core.features.shaderResourceMinLod
|| !m_features.vk12.samplerFilterMinmax
|| !m_properties.vk12.filterMinmaxSingleComponentFormats
|| !m_properties.core.properties.sparseProperties.residencyNonResidentStrict
|| m_properties.core.properties.sparseProperties.residencyAlignedMipSize)
return D3D11_TILED_RESOURCES_TIER_1;
if (!m_features.core.features.sparseResidencyImage3D
|| !m_properties.core.properties.sparseProperties.residencyStandard3DBlockShape)
return D3D11_TILED_RESOURCES_TIER_2;
return D3D11_TILED_RESOURCES_TIER_3;
}
BOOL D3D11DeviceFeatures::DetermineUavExtendedTypedLoadSupport(
const Rc<DxvkAdapter>& Adapter,
D3D_FEATURE_LEVEL FeatureLevel) {
static const std::array<VkFormat, 18> s_formats = {{
VK_FORMAT_R32_SFLOAT,
VK_FORMAT_R32_UINT,
VK_FORMAT_R32_SINT,
VK_FORMAT_R32G32B32A32_SFLOAT,
VK_FORMAT_R32G32B32A32_UINT,
VK_FORMAT_R32G32B32A32_SINT,
VK_FORMAT_R16G16B16A16_SFLOAT,
VK_FORMAT_R16G16B16A16_UINT,
VK_FORMAT_R16G16B16A16_SINT,
VK_FORMAT_R8G8B8A8_UNORM,
VK_FORMAT_R8G8B8A8_UINT,
VK_FORMAT_R8G8B8A8_SINT,
VK_FORMAT_R16_SFLOAT,
VK_FORMAT_R16_UINT,
VK_FORMAT_R16_SINT,
VK_FORMAT_R8_UNORM,
VK_FORMAT_R8_UINT,
VK_FORMAT_R8_SINT,
}};
if (FeatureLevel < D3D_FEATURE_LEVEL_11_0)
return FALSE;
for (auto f : s_formats) {
DxvkFormatFeatures features = Adapter->getFormatFeatures(f);
VkFormatFeatureFlags2 imgFeatures = features.optimal | features.linear;
if (!(imgFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT))
return FALSE;
}
return TRUE;
}
BOOL D3D11DeviceFeatures::CheckFormatSharingSupport(
const Rc<DxvkAdapter>& Adapter,
VkFormat Format,
VkExternalMemoryHandleTypeFlagBits HandleType) {
DxvkFormatQuery query = { };
query.format = Format;
query.type = VK_IMAGE_TYPE_2D;
query.tiling = VK_IMAGE_TILING_OPTIMAL;
query.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
query.handleType = HandleType;
constexpr VkExternalMemoryFeatureFlags featureMask
= VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT
| VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
auto limits = Adapter->getFormatLimits(query);
return limits && (limits->externalFeatures & featureMask);
}
D3D_FEATURE_LEVEL D3D11DeviceFeatures::GetMaxFeatureLevel() const {
// Check Feature Level 11_0 features
if (!m_features.core.features.drawIndirectFirstInstance
|| !m_features.core.features.fragmentStoresAndAtomics
|| !m_features.core.features.multiDrawIndirect
|| !m_features.core.features.tessellationShader)
return D3D_FEATURE_LEVEL_10_1;
// Check Feature Level 11_1 features
if (!m_d3d11Options.OutputMergerLogicOp
|| !m_features.core.features.vertexPipelineStoresAndAtomics)
return D3D_FEATURE_LEVEL_11_0;
// Check Feature Level 12_0 features
if (m_d3d11Options2.TiledResourcesTier < D3D11_TILED_RESOURCES_TIER_2
|| !m_d3d11Options2.TypedUAVLoadAdditionalFormats)
return D3D_FEATURE_LEVEL_11_1;
// Check Feature Level 12_1 features
if (!m_d3d11Options2.ConservativeRasterizationTier
|| !m_d3d11Options2.ROVsSupported)
return D3D_FEATURE_LEVEL_12_0;
return D3D_FEATURE_LEVEL_12_1;
}
}

124
src/d3d11/d3d11_features.h Normal file
View File

@ -0,0 +1,124 @@
#pragma once
#include "d3d11_include.h"
#include "../dxvk/dxvk_adapter.h"
#include "../dxvk/dxvk_instance.h"
namespace dxvk {
/**
* \brief Device features
*
* Stores D3D device feature structs.
*/
class D3D11DeviceFeatures {
public:
D3D11DeviceFeatures();
D3D11DeviceFeatures(
const Rc<DxvkInstance>& Instance,
const Rc<DxvkAdapter>& Adapter,
D3D_FEATURE_LEVEL FeatureLevel);
~D3D11DeviceFeatures();
/**
* \brief Retrieves feature support data
*
* \param [in] Feature D3D feature to query
* \param [in] FeatureDataSize Data size, in bytes
* \param [out] pFeatureData Data
* \returns Status of the operation
*/
HRESULT GetFeatureData(
D3D11_FEATURE Feature,
UINT FeatureDataSize,
void* pFeatureData) const;
/**
* \brief Queries tiled resources tier
* \returns Tiled resources tier
*/
D3D11_TILED_RESOURCES_TIER GetTiledResourcesTier() const {
return m_d3d11Options2.TiledResourcesTier;
}
/**
* \brief Queries conservative rasterization tier
* \returns Conservative rasterization tier
*/
D3D11_CONSERVATIVE_RASTERIZATION_TIER GetConservativeRasterizationTier() const {
return m_d3d11Options2.ConservativeRasterizationTier;
}
/**
* \brief Tests maximum supported feature level
*
* \param [in] Instance DXVK instance
* \param [in] Adapter DXVK adapter
* \returns Highest supported feature level
*/
static D3D_FEATURE_LEVEL GetMaxFeatureLevel(
const Rc<DxvkInstance>& Instance,
const Rc<DxvkAdapter>& Adapter);
private:
DxvkDeviceFeatures m_features;
DxvkDeviceInfo m_properties;
D3D11_FEATURE_DATA_ARCHITECTURE_INFO m_architectureInfo = { };
D3D11_FEATURE_DATA_D3D9_OPTIONS m_d3d9Options = { };
D3D11_FEATURE_DATA_D3D9_OPTIONS1 m_d3d9Options1 = { };
D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT m_d3d9Shadow = { };
D3D11_FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT m_d3d9SimpleInstancing = { };
D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS m_d3d10Options = { };
D3D11_FEATURE_DATA_D3D11_OPTIONS m_d3d11Options = { };
D3D11_FEATURE_DATA_D3D11_OPTIONS1 m_d3d11Options1 = { };
D3D11_FEATURE_DATA_D3D11_OPTIONS2 m_d3d11Options2 = { };
D3D11_FEATURE_DATA_D3D11_OPTIONS3 m_d3d11Options3 = { };
D3D11_FEATURE_DATA_D3D11_OPTIONS4 m_d3d11Options4 = { };
D3D11_FEATURE_DATA_D3D11_OPTIONS5 m_d3d11Options5 = { };
D3D11_FEATURE_DATA_DOUBLES m_doubles = { };
D3D11_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT m_gpuVirtualAddress = { };
D3D11_FEATURE_DATA_MARKER_SUPPORT m_marker = { };
D3D11_FEATURE_DATA_SHADER_CACHE m_shaderCache = { };
D3D11_FEATURE_DATA_SHADER_MIN_PRECISION_SUPPORT m_shaderMinPrecision = { };
D3D11_FEATURE_DATA_THREADING m_threading = { };
template<typename T>
static HRESULT GetTypedFeatureData(UINT Size, void* pDstData, const T* pSrcData) {
if (Size != sizeof(T))
return E_INVALIDARG;
*(reinterpret_cast<T*>(pDstData)) = *pSrcData;
return S_OK;
}
D3D11_CONSERVATIVE_RASTERIZATION_TIER DetermineConservativeRasterizationTier(
D3D_FEATURE_LEVEL FeatureLevel);
D3D11_SHARED_RESOURCE_TIER DetermineSharedResourceTier(
const Rc<DxvkAdapter>& Adapter,
D3D_FEATURE_LEVEL FeatureLevel);
D3D11_TILED_RESOURCES_TIER DetermineTiledResourcesTier(
D3D_FEATURE_LEVEL FeatureLevel);
BOOL DetermineUavExtendedTypedLoadSupport(
const Rc<DxvkAdapter>& Adapter,
D3D_FEATURE_LEVEL FeatureLevel);
BOOL CheckFormatSharingSupport(
const Rc<DxvkAdapter>& Adapter,
VkFormat Format,
VkExternalMemoryHandleTypeFlagBits HandleType);
D3D_FEATURE_LEVEL GetMaxFeatureLevel() const;
};
}

105
src/d3d11/d3d11_fence.cpp Normal file
View File

@ -0,0 +1,105 @@
#include "d3d11_fence.h"
#include "d3d11_device.h"
#include "../util/util_win32_compat.h"
namespace dxvk {
D3D11Fence::D3D11Fence(
D3D11Device* pDevice,
UINT64 InitialValue,
D3D11_FENCE_FLAG Flags,
HANDLE hFence)
: D3D11DeviceChild<ID3D11Fence>(pDevice) {
DxvkFenceCreateInfo fenceInfo;
fenceInfo.initialValue = InitialValue;
m_flags = Flags;
if (Flags & D3D11_FENCE_FLAG_SHARED) {
fenceInfo.sharedType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_FENCE_BIT;
if (hFence == nullptr)
hFence = INVALID_HANDLE_VALUE;
fenceInfo.sharedHandle = hFence;
}
if (Flags & ~D3D11_FENCE_FLAG_SHARED)
Logger::err(str::format("Fence flags 0x", std::hex, Flags, " not supported"));
m_fence = pDevice->GetDXVKDevice()->createFence(fenceInfo);
}
D3D11Fence::~D3D11Fence() {
}
HRESULT STDMETHODCALLTYPE D3D11Fence::QueryInterface(
REFIID riid,
void** ppvObject) {
if (ppvObject == nullptr)
return E_POINTER;
*ppvObject = nullptr;
if (riid == __uuidof(IUnknown)
|| riid == __uuidof(ID3D11DeviceChild)
|| riid == __uuidof(ID3D11Fence)) {
*ppvObject = ref(this);
return S_OK;
}
if (logQueryInterfaceError(__uuidof(ID3D11Fence), riid)) {
Logger::warn("D3D11Fence: Unknown interface query");
Logger::warn(str::format(riid));
}
return E_NOINTERFACE;
}
HRESULT STDMETHODCALLTYPE D3D11Fence::CreateSharedHandle(
const SECURITY_ATTRIBUTES* pAttributes,
DWORD dwAccess,
LPCWSTR lpName,
HANDLE* pHandle) {
if (!(m_flags & D3D11_FENCE_FLAG_SHARED))
return E_INVALIDARG;
if (pAttributes)
Logger::warn(str::format("CreateSharedHandle: attributes ", pAttributes, " not handled"));
if (dwAccess)
Logger::warn(str::format("CreateSharedHandle: access ", dwAccess, " not handled"));
if (lpName)
Logger::warn(str::format("CreateSharedHandle: name ", dxvk::str::fromws(lpName), " not handled"));
HANDLE sharedHandle = m_fence->sharedHandle();
if (sharedHandle == INVALID_HANDLE_VALUE)
return E_INVALIDARG;
*pHandle = sharedHandle;
return S_OK;
}
HRESULT STDMETHODCALLTYPE D3D11Fence::SetEventOnCompletion(
UINT64 Value,
HANDLE hEvent) {
if (hEvent) {
m_fence->enqueueWait(Value, [hEvent] {
SetEvent(hEvent);
});
} else {
m_fence->wait(Value);
}
return S_OK;
}
UINT64 STDMETHODCALLTYPE D3D11Fence::GetCompletedValue() {
// TODO in the case of rewinds, the stored value may be higher.
// For shared fences, calling vkGetSemaphoreCounterValue here could alleviate the issue.
return m_fence->getValue();
}
}

49
src/d3d11/d3d11_fence.h Normal file
View File

@ -0,0 +1,49 @@
#pragma once
#include "../dxvk/dxvk_fence.h"
#include "../dxvk/dxvk_gpu_query.h"
#include "d3d11_device_child.h"
namespace dxvk {
class D3D11Fence : public D3D11DeviceChild<ID3D11Fence> {
public:
D3D11Fence(
D3D11Device* pDevice,
UINT64 InitialValue,
D3D11_FENCE_FLAG Flags,
HANDLE hFence);
~D3D11Fence();
HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid,
void** ppvObject);
HRESULT STDMETHODCALLTYPE CreateSharedHandle(
const SECURITY_ATTRIBUTES* pAttributes,
DWORD dwAccess,
LPCWSTR lpName,
HANDLE* pHandle);
HRESULT STDMETHODCALLTYPE SetEventOnCompletion(
UINT64 Value,
HANDLE hEvent);
UINT64 STDMETHODCALLTYPE GetCompletedValue();
Rc<DxvkFence> GetFence() const {
return m_fence;
}
private:
Rc<DxvkFence> m_fence;
D3D11_FENCE_FLAG m_flags;
};
}

View File

@ -3,6 +3,7 @@
#include "d3d11_gdi.h"
#include "../util/util_gdi.h"
#include "../util/util_win32_compat.h"
namespace dxvk {
@ -149,11 +150,8 @@ namespace dxvk {
HRESULT D3D11GDISurface::CreateReadbackResource() {
auto tex = GetCommonTexture(m_resource);
Com<ID3D11Device> device;
Com<ID3D11DeviceContext> context;
Com<ID3D11Device> device;
m_resource->GetDevice(&device);
device->GetImmediateContext(&context);
D3D11_RESOURCE_DIMENSION dim = { };
m_resource->GetType(&dim);

View File

@ -3,44 +3,3 @@
#include "../dxgi/dxgi_include.h"
#include <d3d11_4.h>
// This is not defined in the mingw headers
#ifndef D3D11_1_UAV_SLOT_COUNT
#define D3D11_1_UAV_SLOT_COUNT 64
#endif
#ifndef D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL
#define D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL 0xFFFFFFFF
#endif
#ifndef D3D11_KEEP_UNORDERED_ACCESS_VIEWS
#define D3D11_KEEP_UNORDERED_ACCESS_VIEWS 0xFFFFFFFF
#endif
#define D3D11_DXVK_USE_REMAINING_LAYERS 0xFFFFFFFF
#define D3D11_DXVK_USE_REMAINING_LEVELS 0xFFFFFFFF
// Most of these were copied from d3d11.h
// For some strange reason, we cannot use the structures
// directly, although others from the same header work.
// Some structures are missing from the mingw headers.
#ifndef _MSC_VER
#if !defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 9
typedef enum D3D11_FORMAT_SUPPORT2 {
D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_ADD = 0x1,
D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_BITWISE_OPS = 0x2,
D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_COMPARE_STORE_OR_COMPARE_EXCHANGE = 0x4,
D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_EXCHANGE = 0x8,
D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_SIGNED_MIN_OR_MAX = 0x10,
D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_UNSIGNED_MIN_OR_MAX = 0x20,
D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD = 0x40,
D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE = 0x80,
D3D11_FORMAT_SUPPORT2_OUTPUT_MERGER_LOGIC_OP = 0x100,
D3D11_FORMAT_SUPPORT2_TILED = 0x200,
D3D11_FORMAT_SUPPORT2_SHAREABLE = 0x400,
D3D11_FORMAT_SUPPORT2_MULTIPLANE_OVERLAY = 0x4000
} D3D11_FORMAT_SUPPORT2;
#define D3D11_RESOURCE_MISC_TILE_POOL (0x20000)
#define D3D11_RESOURCE_MISC_TILED (0x40000)
#endif // !defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 9
#endif // _MSC_VER

View File

@ -9,7 +9,7 @@ namespace dxvk {
D3D11Device* pParent)
: m_parent(pParent),
m_device(pParent->GetDXVKDevice()),
m_context(m_device->createContext()) {
m_context(m_device->createContext(DxvkContextType::Supplementary)) {
m_context->beginRecording(
m_device->createCommandList());
}
@ -30,37 +30,47 @@ namespace dxvk {
void D3D11Initializer::InitBuffer(
D3D11Buffer* pBuffer,
const D3D11_SUBRESOURCE_DATA* pInitialData) {
VkMemoryPropertyFlags memFlags = pBuffer->GetBuffer()->memFlags();
if (!(pBuffer->Desc()->MiscFlags & D3D11_RESOURCE_MISC_TILED)) {
VkMemoryPropertyFlags memFlags = pBuffer->GetBuffer()->memFlags();
(memFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
? InitHostVisibleBuffer(pBuffer, pInitialData)
: InitDeviceLocalBuffer(pBuffer, pInitialData);
(memFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
? InitHostVisibleBuffer(pBuffer, pInitialData)
: InitDeviceLocalBuffer(pBuffer, pInitialData);
}
}
void D3D11Initializer::InitTexture(
D3D11CommonTexture* pTexture,
const D3D11_SUBRESOURCE_DATA* pInitialData) {
(pTexture->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT)
? InitHostVisibleTexture(pTexture, pInitialData)
: InitDeviceLocalTexture(pTexture, pInitialData);
if (pTexture->Desc()->MiscFlags & D3D11_RESOURCE_MISC_TILED)
InitTiledTexture(pTexture);
else if (pTexture->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT)
InitHostVisibleTexture(pTexture, pInitialData);
else
InitDeviceLocalTexture(pTexture, pInitialData);
SyncKeyedMutex(pTexture->GetInterface());
}
void D3D11Initializer::InitUavCounter(
D3D11UnorderedAccessView* pUav) {
auto counterBuffer = pUav->GetCounterSlice();
auto counterView = pUav->GetCounterView();
if (!counterBuffer.defined())
if (counterView == nullptr)
return;
auto counterSlice = counterView->slice();
std::lock_guard<dxvk::mutex> lock(m_mutex);
m_transferCommands += 1;
const uint32_t zero = 0;
m_context->updateBuffer(
counterBuffer.buffer(),
0, sizeof(zero), &zero);
counterSlice.buffer(),
counterSlice.offset(),
sizeof(zero), &zero);
FlushImplicit();
}
@ -123,7 +133,7 @@ namespace dxvk {
auto desc = pTexture->Desc();
VkFormat packedFormat = m_parent->LookupPackedFormat(desc->Format, pTexture->GetFormatMode()).Format;
auto formatInfo = imageFormatInfo(packedFormat);
auto formatInfo = lookupFormatInfo(packedFormat);
if (pInitialData != nullptr && pInitialData->pSysMem != nullptr) {
// pInitialData is an array that stores an entry for
@ -253,6 +263,15 @@ namespace dxvk {
}
void D3D11Initializer::InitTiledTexture(
D3D11CommonTexture* pTexture) {
m_context->initSparseImage(pTexture->GetImage());
m_transferCommands += 1;
FlushImplicit();
}
void D3D11Initializer::FlushImplicit() {
if (m_transferCommands > MaxTransferCommands
|| m_transferMemory > MaxTransferMemory)
@ -261,10 +280,20 @@ namespace dxvk {
void D3D11Initializer::FlushInternal() {
m_context->flushCommandList();
m_context->flushCommandList(nullptr);
m_transferCommands = 0;
m_transferMemory = 0;
}
void D3D11Initializer::SyncKeyedMutex(ID3D11Resource *pResource) {
Com<IDXGIKeyedMutex> keyedMutex;
if (pResource->QueryInterface(__uuidof(IDXGIKeyedMutex), reinterpret_cast<void**>(&keyedMutex)) != S_OK)
return;
keyedMutex->AcquireSync(0, 0);
keyedMutex->ReleaseSync(0);
}
}

View File

@ -64,10 +64,15 @@ namespace dxvk {
void InitHostVisibleTexture(
D3D11CommonTexture* pTexture,
const D3D11_SUBRESOURCE_DATA* pInitialData);
void InitTiledTexture(
D3D11CommonTexture* pTexture);
void FlushImplicit();
void FlushInternal();
void SyncKeyedMutex(ID3D11Resource *pResource);
};
}

View File

@ -46,13 +46,16 @@ namespace dxvk {
return S_OK;
}
Logger::warn("D3D11InputLayout::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
if (logQueryInterfaceError(__uuidof(ID3D11InputLayout), riid)) {
Logger::warn("D3D11InputLayout::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
}
return E_NOINTERFACE;
}
void D3D11InputLayout::BindToContext(const Rc<DxvkContext>& ctx) {
void D3D11InputLayout::BindToContext(DxvkContext* ctx) {
ctx->setInputLayout(
m_attributes.size(),
m_attributes.data(),

View File

@ -25,8 +25,7 @@ namespace dxvk {
REFIID riid,
void** ppvObject) final;
void BindToContext(
const Rc<DxvkContext>& ctx);
void BindToContext(DxvkContext* ctx);
bool Compare(
const D3D11InputLayout* pOther) const;

View File

@ -28,6 +28,26 @@ enum D3D11_VK_BARRIER_CONTROL : uint32_t {
};
/**
* \brief Extended shader interface
*/
MIDL_INTERFACE("bb8a4fb9-3935-4762-b44b-35189a26414a")
ID3D11VkExtShader : public IUnknown {
/**
* \brief Retrieves SPIR-V code from a shader object
*
* \param [in,out] pCodeSize Shader code size, in bytes. If
* \ref pCode is \c nullptr, this will return the total
* code size, otherwise the number of bytes written.
* \param [out] pCode SPIR-V shader code
* \returns \c S_OK, or \c S_FALSE if the buffer was too small
*/
virtual HRESULT STDMETHODCALLTYPE GetSpirvCode(
SIZE_T* pCodeSize,
void* pCode) = 0;
};
/**
* \brief Extended D3D11 device
*
@ -164,11 +184,13 @@ ID3D11VkExtContext1 : public ID3D11VkExtContext {
#ifdef _MSC_VER
struct __declspec(uuid("bb8a4fb9-3935-4762-b44b-35189a26414a")) ID3D11VkExtShader;
struct __declspec(uuid("8a6e3c42-f74c-45b7-8265-a231b677ca17")) ID3D11VkExtDevice;
struct __declspec(uuid("cfcf64ef-9586-46d0-bca4-97cf2ca61b06")) ID3D11VkExtDevice1;
struct __declspec(uuid("fd0bca13-5cb6-4c3a-987e-4750de2ca791")) ID3D11VkExtContext;
struct __declspec(uuid("874b09b2-ae0b-41d8-8476-5f3b7a0e879d")) ID3D11VkExtContext1;
#else
__CRT_UUID_DECL(ID3D11VkExtShader, 0xbb8a4fb9,0x3935,0x4762,0xb4,0x4b,0x35,0x18,0x9a,0x26,0x41,0x4a);
__CRT_UUID_DECL(ID3D11VkExtDevice, 0x8a6e3c42,0xf74c,0x45b7,0x82,0x65,0xa2,0x31,0xb6,0x77,0xca,0x17);
__CRT_UUID_DECL(ID3D11VkExtDevice1, 0xcfcf64ef,0x9586,0x46d0,0xbc,0xa4,0x97,0xcf,0x2c,0xa6,0x1b,0x06);
__CRT_UUID_DECL(ID3D11VkExtContext, 0xfd0bca13,0x5cb6,0x4c3a,0x98,0x7e,0x47,0x50,0xde,0x2c,0xa7,0x91);

View File

@ -75,21 +75,15 @@ namespace dxvk {
const VkImageSubresourceRange* pSubresources,
VkImageLayout OldLayout,
VkImageLayout NewLayout) {
Com<ID3D11DeviceContext> deviceContext = nullptr;
m_device->GetImmediateContext(&deviceContext);
auto immediateContext = static_cast<D3D11ImmediateContext*>(deviceContext.ptr());
auto immediateContext = m_device->GetContext();
immediateContext->TransitionSurfaceLayout(
pSurface, pSubresources, OldLayout, NewLayout);
}
void STDMETHODCALLTYPE D3D11VkInterop::FlushRenderingCommands() {
Com<ID3D11DeviceContext> deviceContext = nullptr;
m_device->GetImmediateContext(&deviceContext);
auto immediateContext = static_cast<D3D11ImmediateContext*>(deviceContext.ptr());
auto immediateContext = m_device->GetContext();
immediateContext->Flush();
immediateContext->SynchronizeCsThread(DxvkCsThread::SynchronizeAll);
}

View File

@ -15,7 +15,7 @@ namespace dxvk {
extern "C" {
using namespace dxvk;
DLLEXPORT HRESULT __stdcall D3D11CoreCreateDevice(
HRESULT D3D11InternalCreateDevice(
IDXGIFactory* pFactory,
IDXGIAdapter* pAdapter,
UINT Flags,
@ -34,7 +34,7 @@ extern "C" {
dxvkAdapter = dxgiVkAdapter->GetDXVKAdapter();
dxvkInstance = dxgiVkAdapter->GetDXVKInstance();
} else {
Logger::warn("D3D11CoreCreateDevice: Adapter is not a DXVK adapter");
Logger::warn("D3D11InternalCreateDevice: Adapter is not a DXVK adapter");
DXGI_ADAPTER_DESC desc;
pAdapter->GetDesc(&desc);
@ -59,40 +59,49 @@ extern "C" {
D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1,
};
if (pFeatureLevels == nullptr || FeatureLevels == 0) {
if (!pFeatureLevels || !FeatureLevels) {
pFeatureLevels = defaultFeatureLevels.data();
FeatureLevels = defaultFeatureLevels.size();
}
// Find the highest feature level supported by the device.
// This works because the feature level array is ordered.
UINT flId;
D3D_FEATURE_LEVEL maxFeatureLevel = D3D11Device::GetMaxFeatureLevel(dxvkInstance, dxvkAdapter);
D3D_FEATURE_LEVEL minFeatureLevel = D3D_FEATURE_LEVEL();
D3D_FEATURE_LEVEL devFeatureLevel = D3D_FEATURE_LEVEL();
for (flId = 0 ; flId < FeatureLevels; flId++) {
Logger::info(str::format("D3D11CoreCreateDevice: Probing ", pFeatureLevels[flId]));
if (D3D11Device::CheckFeatureLevelSupport(dxvkInstance, dxvkAdapter, pFeatureLevels[flId]))
Logger::info(str::format("D3D11InternalCreateDevice: Maximum supported feature level: ", maxFeatureLevel));
for (uint32_t flId = 0 ; flId < FeatureLevels; flId++) {
minFeatureLevel = pFeatureLevels[flId];
if (minFeatureLevel <= maxFeatureLevel) {
devFeatureLevel = minFeatureLevel;
break;
}
}
if (flId == FeatureLevels) {
Logger::err("D3D11CoreCreateDevice: Requested feature level not supported");
if (!devFeatureLevel) {
Logger::err(str::format("D3D11InternalCreateDevice: Minimum required feature level ", minFeatureLevel, " not supported"));
return E_INVALIDARG;
}
// Try to create the device with the given parameters.
const D3D_FEATURE_LEVEL fl = pFeatureLevels[flId];
try {
Logger::info(str::format("D3D11CoreCreateDevice: Using feature level ", fl));
Logger::info(str::format("D3D11InternalCreateDevice: Using feature level ", devFeatureLevel));
DxvkDeviceFeatures deviceFeatures = D3D11Device::GetDeviceFeatures(dxvkAdapter);
Rc<DxvkDevice> dxvkDevice = dxvkAdapter->createDevice(dxvkInstance, deviceFeatures);
Com<D3D11DXGIDevice> device = new D3D11DXGIDevice(
pAdapter, dxvkInstance, dxvkAdapter, fl, Flags);
pAdapter, nullptr, nullptr,
dxvkInstance, dxvkAdapter, dxvkDevice,
devFeatureLevel, Flags);
return device->QueryInterface(
__uuidof(ID3D11Device),
reinterpret_cast<void**>(ppDevice));
} catch (const DxvkError& e) {
Logger::err("D3D11CoreCreateDevice: Failed to create D3D11 device");
Logger::err("D3D11InternalCreateDevice: Failed to create D3D11 device");
return E_FAIL;
}
}
@ -164,7 +173,7 @@ extern "C" {
}
// Create the actual device
hr = D3D11CoreCreateDevice(
hr = D3D11InternalCreateDevice(
dxgiFactory.ptr(), dxgiAdapter.ptr(),
Flags, pFeatureLevels, FeatureLevels,
&device);
@ -203,6 +212,25 @@ extern "C" {
}
DLLEXPORT HRESULT __stdcall D3D11CoreCreateDevice(
IDXGIFactory* pFactory,
IDXGIAdapter* pAdapter,
D3D_DRIVER_TYPE DriverType,
HMODULE Software,
UINT Flags,
const D3D_FEATURE_LEVEL* pFeatureLevels,
UINT FeatureLevels,
UINT SDKVersion,
ID3D11Device** ppDevice,
D3D_FEATURE_LEVEL* pFeatureLevel) {
return D3D11InternalCreateDeviceAndSwapChain(
pAdapter, DriverType, Software, Flags,
pFeatureLevels, FeatureLevels, SDKVersion,
nullptr, nullptr,
ppDevice, pFeatureLevel, nullptr);
}
DLLEXPORT HRESULT __stdcall D3D11CreateDevice(
IDXGIAdapter* pAdapter,
D3D_DRIVER_TYPE DriverType,
@ -254,12 +282,169 @@ extern "C" {
ID3D11Device** ppDevice,
ID3D11DeviceContext** ppImmediateContext,
D3D_FEATURE_LEVEL* pChosenFeatureLevel) {
static bool s_errorShown = false;
InitReturnPtr(ppDevice);
InitReturnPtr(ppImmediateContext);
if (!std::exchange(s_errorShown, true))
Logger::err("D3D11On12CreateDevice: Not implemented");
if (pChosenFeatureLevel)
*pChosenFeatureLevel = D3D_FEATURE_LEVEL(0);
return E_NOTIMPL;
if (!pDevice)
return E_INVALIDARG;
// Figure out D3D12 objects
Com<ID3D12Device> d3d12Device;
Com<ID3D12CommandQueue> d3d12Queue;
if (FAILED(pDevice->QueryInterface(__uuidof(ID3D12Device), reinterpret_cast<void**>(&d3d12Device)))) {
Logger::err("D3D11On12CreateDevice: Device is not a valid D3D12 device");
return E_INVALIDARG;
}
if (NodeMask & (NodeMask - 1)) {
Logger::err("D3D11On12CreateDevice: Invalid node mask");
return E_INVALIDARG;
}
if (!NumQueues || !ppCommandQueues || !ppCommandQueues[0]) {
Logger::err("D3D11On12CreateDevice: No command queue specified");
return E_INVALIDARG;
}
if (NumQueues > 1) {
// Not sure what to do with more than one graphics queue
Logger::warn("D3D11On12CreateDevice: Only one queue supported");
}
if (FAILED(ppCommandQueues[0]->QueryInterface(__uuidof(ID3D12CommandQueue), reinterpret_cast<void**>(&d3d12Queue)))) {
Logger::err("D3D11On12CreateDevice: Queue is not a valid D3D12 command queue");
return E_INVALIDARG;
}
// Determine feature level for the D3D11 device
std::array<D3D_FEATURE_LEVEL, 4> defaultFeatureLevels = {{
D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_12_0, D3D_FEATURE_LEVEL_12_1,
}};
D3D12_FEATURE_DATA_FEATURE_LEVELS featureLevel = { };
if (!FeatureLevels || !pFeatureLevels) {
featureLevel.NumFeatureLevels = defaultFeatureLevels.size();
featureLevel.pFeatureLevelsRequested = defaultFeatureLevels.data();
} else {
featureLevel.NumFeatureLevels = FeatureLevels;
featureLevel.pFeatureLevelsRequested = pFeatureLevels;
}
HRESULT hr = d3d12Device->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS, &featureLevel, sizeof(featureLevel));
if (FAILED(hr) || !featureLevel.MaxSupportedFeatureLevel) {
Logger::err(str::format("D3D11On12CreateDevice: Minimum required feature level not supported"));
return hr;
}
Logger::info(str::format("D3D11On12CreateDevice: Chosen feature level: ", featureLevel.MaxSupportedFeatureLevel));
Com<ID3D12DXVKInteropDevice> interopDevice;
if (FAILED(d3d12Device->QueryInterface(__uuidof(ID3D12DXVKInteropDevice), reinterpret_cast<void**>(&interopDevice)))) {
Logger::err("D3D11On12CreateDevice: Device not a vkd3d-proton device.");
return E_INVALIDARG;
}
Com<IDXGIAdapter> dxgiAdapter;
if (FAILED(interopDevice->GetDXGIAdapter(IID_PPV_ARGS(&dxgiAdapter)))) {
Logger::err("D3D11On12CreateDevice: Failed to query DXGI adapter.");
return E_INVALIDARG;
}
try {
// Initialize DXVK instance
DxvkInstanceImportInfo instanceInfo = { };
DxvkDeviceImportInfo deviceInfo = { };
VkPhysicalDevice vulkanAdapter = VK_NULL_HANDLE;
interopDevice->GetVulkanHandles(&instanceInfo.instance, &vulkanAdapter, &deviceInfo.device);
uint32_t instanceExtensionCount = 0;
interopDevice->GetInstanceExtensions(&instanceExtensionCount, nullptr);
std::vector<const char*> instanceExtensions(instanceExtensionCount);
interopDevice->GetInstanceExtensions(&instanceExtensionCount, instanceExtensions.data());
instanceInfo.extensionCount = instanceExtensions.size();
instanceInfo.extensionNames = instanceExtensions.data();
Rc<DxvkInstance> dxvkInstance = new DxvkInstance(instanceInfo);
// Find adapter by physical device handle
Rc<DxvkAdapter> dxvkAdapter;
for (uint32_t i = 0; i < dxvkInstance->adapterCount(); i++) {
Rc<DxvkAdapter> curr = dxvkInstance->enumAdapters(i);
if (curr->handle() == vulkanAdapter)
dxvkAdapter = std::move(curr);
}
if (dxvkAdapter == nullptr) {
Logger::err("D3D11On12CreateDevice: No matching adapter found");
return E_INVALIDARG;
}
interopDevice->GetVulkanQueueInfo(d3d12Queue.ptr(), &deviceInfo.queue, &deviceInfo.queueFamily);
interopDevice->GetDeviceFeatures(&deviceInfo.features);
uint32_t deviceExtensionCount = 0;
interopDevice->GetDeviceExtensions(&deviceExtensionCount, nullptr);
std::vector<const char*> deviceExtensions(deviceExtensionCount);
interopDevice->GetDeviceExtensions(&deviceExtensionCount, deviceExtensions.data());
deviceInfo.extensionCount = deviceExtensions.size();
deviceInfo.extensionNames = deviceExtensions.data();
deviceInfo.queueCallback = [
cDevice = interopDevice,
cQueue = d3d12Queue
] (bool doLock) {
HRESULT hr = doLock
? cDevice->LockCommandQueue(cQueue.ptr())
: cDevice->UnlockCommandQueue(cQueue.ptr());
if (FAILED(hr))
Logger::err(str::format("Failed to lock vkd3d-proton device queue: ", hr));
};
Rc<DxvkDevice> dxvkDevice = dxvkAdapter->importDevice(dxvkInstance, deviceInfo);
// Create and return the actual D3D11 device
Com<D3D11DXGIDevice> device = new D3D11DXGIDevice(
dxgiAdapter.ptr(), d3d12Device.ptr(), d3d12Queue.ptr(),
dxvkInstance, dxvkAdapter, dxvkDevice,
featureLevel.MaxSupportedFeatureLevel, Flags);
Com<ID3D11Device> d3d11Device;
device->QueryInterface(__uuidof(ID3D11Device), reinterpret_cast<void**>(&d3d11Device));
if (ppDevice)
*ppDevice = d3d11Device.ref();
if (ppImmediateContext)
d3d11Device->GetImmediateContext(ppImmediateContext);
if (pChosenFeatureLevel)
*pChosenFeatureLevel = d3d11Device->GetFeatureLevel();
if (!ppDevice && !ppImmediateContext)
return S_FALSE;
return S_OK;
} catch (const DxvkError& e) {
Logger::err("D3D11On12CreateDevice: Failed to create D3D11 device");
return E_FAIL;
}
}
}

150
src/d3d11/d3d11_on_12.cpp Normal file
View File

@ -0,0 +1,150 @@
#include "d3d11_context_imm.h"
#include "d3d11_device.h"
#include "d3d11_on_12.h"
namespace dxvk {
D3D11on12Device::D3D11on12Device(
D3D11DXGIDevice* pContainer,
D3D11Device* pDevice,
ID3D12Device* pD3D12Device,
ID3D12CommandQueue* pD3D12Queue)
: m_container (pContainer),
m_device (pDevice),
m_d3d12Device (pD3D12Device),
m_d3d12Queue (pD3D12Queue) {
}
D3D11on12Device::~D3D11on12Device() {
}
ULONG STDMETHODCALLTYPE D3D11on12Device::AddRef() {
return m_container->AddRef();
}
ULONG STDMETHODCALLTYPE D3D11on12Device::Release() {
return m_container->Release();
}
HRESULT STDMETHODCALLTYPE D3D11on12Device::QueryInterface(
REFIID riid,
void** ppvObject) {
return m_container->QueryInterface(riid, ppvObject);
}
HRESULT STDMETHODCALLTYPE D3D11on12Device::CreateWrappedResource(
IUnknown* pResource12,
const D3D11_RESOURCE_FLAGS* pResourceFlags,
D3D12_RESOURCE_STATES InputState,
D3D12_RESOURCE_STATES OutputState,
REFIID riid,
void** ppResource11) {
Com<ID3D12DXVKInteropDevice> interopDevice;
m_d3d12Device->QueryInterface(__uuidof(ID3D12DXVKInteropDevice), reinterpret_cast<void**>(&interopDevice));
D3D11_ON_12_RESOURCE_INFO info = { };
info.InputState = InputState;
info.OutputState = OutputState;
info.IsWrappedResource = TRUE;
// 11on12 technically allows importing D3D12 heaps as tile pools,
// but we don't support importing sparse resources at this time.
if (FAILED(pResource12->QueryInterface(__uuidof(ID3D12Resource), reinterpret_cast<void**>(&info.Resource)))) {
Logger::err("D3D11on12Device::CreateWrappedResource: Resource not a valid D3D12 resource");
return E_INVALIDARG;
}
// Query Vulkan resource handle and buffer offset as necessary
if (FAILED(interopDevice->GetVulkanResourceInfo(info.Resource.ptr(), &info.VulkanHandle, &info.VulkanOffset))) {
Logger::err("D3D11on12Device::CreateWrappedResource: Failed to retrieve Vulkan resource info");
return E_INVALIDARG;
}
Com<ID3D11Resource> resource;
D3D12_RESOURCE_DESC desc = info.Resource->GetDesc();
if (desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) {
D3D11_BUFFER_DESC bufferDesc;
if (FAILED(D3D11Buffer::GetDescFromD3D12(info.Resource.ptr(), pResourceFlags, &bufferDesc)))
return E_INVALIDARG;
resource = new D3D11Buffer(m_device, &bufferDesc, &info);
} else {
D3D11_COMMON_TEXTURE_DESC textureDesc;
if (FAILED(D3D11CommonTexture::GetDescFromD3D12(info.Resource.ptr(), pResourceFlags, &textureDesc)))
return E_INVALIDARG;
switch (desc.Dimension) {
case D3D12_RESOURCE_DIMENSION_TEXTURE1D:
resource = new D3D11Texture1D(m_device, &textureDesc, &info);
break;
case D3D12_RESOURCE_DIMENSION_TEXTURE2D:
resource = new D3D11Texture2D(m_device, &textureDesc, &info, nullptr);
break;
case D3D12_RESOURCE_DIMENSION_TEXTURE3D:
resource = new D3D11Texture3D(m_device, &textureDesc, &info);
break;
default:
Logger::err("D3D11on12Device::CreateWrappedResource: Unhandled resource dimension");
return E_INVALIDARG;
}
}
return resource->QueryInterface(riid, ppResource11);
}
void STDMETHODCALLTYPE D3D11on12Device::ReleaseWrappedResources(
ID3D11Resource* const* ppResources,
UINT ResourceCount) {
Com<ID3D12DXVKInteropDevice> interopDevice;
m_d3d12Device->QueryInterface(__uuidof(ID3D12DXVKInteropDevice), reinterpret_cast<void**>(&interopDevice));
for (uint32_t i = 0; i < ResourceCount; i++) {
D3D11_ON_12_RESOURCE_INFO info;
if (FAILED(GetResource11on12Info(ppResources[i], &info)) || !info.IsWrappedResource) {
Logger::warn("D3D11on12Device::ReleaseWrappedResources: Resource not a wrapped resource, skipping");
continue;
}
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
interopDevice->GetVulkanImageLayout(info.Resource.ptr(), info.OutputState, &layout);
m_device->GetContext()->Release11on12Resource(ppResources[i], layout);
}
}
void STDMETHODCALLTYPE D3D11on12Device::AcquireWrappedResources(
ID3D11Resource* const* ppResources,
UINT ResourceCount) {
Com<ID3D12DXVKInteropDevice> interopDevice;
m_d3d12Device->QueryInterface(__uuidof(ID3D12DXVKInteropDevice), reinterpret_cast<void**>(&interopDevice));
for (uint32_t i = 0; i < ResourceCount; i++) {
D3D11_ON_12_RESOURCE_INFO info;
if (FAILED(GetResource11on12Info(ppResources[i], &info)) || !info.IsWrappedResource) {
Logger::warn("D3D11on12Device::AcquireWrappedResources: Resource not a wrapped resource, skipping");
continue;
}
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
interopDevice->GetVulkanImageLayout(info.Resource.ptr(), info.InputState, &layout);
m_device->GetContext()->Acquire11on12Resource(ppResources[i], layout);
}
}
}

75
src/d3d11/d3d11_on_12.h Normal file
View File

@ -0,0 +1,75 @@
#pragma once
#include "d3d11_on_12_interfaces.h"
#include "../util/log/log.h"
namespace dxvk {
class D3D11Device;
class D3D11DXGIDevice;
/**
* \brief Resource info for 11on12 resources
*/
struct D3D11_ON_12_RESOURCE_INFO {
Com<ID3D12Resource> Resource;
UINT64 VulkanHandle = 0;
UINT64 VulkanOffset = 0;
BOOL IsWrappedResource = FALSE;
D3D12_RESOURCE_STATES InputState = D3D12_RESOURCE_STATE_COMMON;
D3D12_RESOURCE_STATES OutputState = D3D12_RESOURCE_STATE_COMMON;
};
class D3D11on12Device : public ID3D11On12Device {
public:
D3D11on12Device(
D3D11DXGIDevice* pContainer,
D3D11Device* pDevice,
ID3D12Device* pD3D12Device,
ID3D12CommandQueue* pD3D12Queue);
~D3D11on12Device();
ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid,
void** ppvObject);
HRESULT STDMETHODCALLTYPE CreateWrappedResource(
IUnknown* pResource12,
const D3D11_RESOURCE_FLAGS* pResourceFlags,
D3D12_RESOURCE_STATES InputState,
D3D12_RESOURCE_STATES OutputState,
REFIID riid,
void** ppResource11);
void STDMETHODCALLTYPE ReleaseWrappedResources(
ID3D11Resource* const* ppResources,
UINT ResourceCount);
void STDMETHODCALLTYPE AcquireWrappedResources(
ID3D11Resource* const* ppResources,
UINT ResourceCount);
bool Is11on12Device() const {
return m_d3d12Device != nullptr;
}
private:
D3D11DXGIDevice* m_container;
D3D11Device* m_device;
Com<ID3D12Device> m_d3d12Device;
Com<ID3D12CommandQueue> m_d3d12Queue;
};
}

View File

@ -0,0 +1,56 @@
#pragma once
#include "../vulkan/vulkan_loader.h"
#include <d3d11on12.h>
MIDL_INTERFACE("39da4e09-bd1c-4198-9fae-86bbe3be41fd")
ID3D12DXVKInteropDevice : public IUnknown {
virtual HRESULT STDMETHODCALLTYPE GetDXGIAdapter(
REFIID iid,
void** ppvObject) = 0;
virtual HRESULT STDMETHODCALLTYPE GetInstanceExtensions(
UINT* pExtensionCount,
const char** ppExtensions) = 0;
virtual HRESULT STDMETHODCALLTYPE GetDeviceExtensions(
UINT* pExtensionCount,
const char** ppExtensions) = 0;
virtual HRESULT STDMETHODCALLTYPE GetDeviceFeatures(
const VkPhysicalDeviceFeatures2** ppFeatures) = 0;
virtual HRESULT STDMETHODCALLTYPE GetVulkanHandles(
VkInstance* pVkInstance,
VkPhysicalDevice* pVkPhysicalDevice,
VkDevice* pVkDevice) = 0;
virtual HRESULT STDMETHODCALLTYPE GetVulkanQueueInfo(
ID3D12CommandQueue* pCommandQueue,
VkQueue* pVkQueue,
UINT32* pVkQueueFamily) = 0;
virtual void STDMETHODCALLTYPE GetVulkanImageLayout(
ID3D12Resource* pResource,
D3D12_RESOURCE_STATES State,
VkImageLayout* pVkLayout) = 0;
virtual HRESULT STDMETHODCALLTYPE GetVulkanResourceInfo(
ID3D12Resource* pResource,
UINT64* pVkHandle,
UINT64* pBufferOffset) = 0;
virtual HRESULT STDMETHODCALLTYPE LockCommandQueue(
ID3D12CommandQueue* pCommandQueue) = 0;
virtual HRESULT STDMETHODCALLTYPE UnlockCommandQueue(
ID3D12CommandQueue* pCommandQueue) = 0;
};
#ifdef _MSC_VER
struct __declspec(uuid("39da4e09-bd1c-4198-9fae-86bbe3be41fd")) ID3D12DXVKInteropDevice;
#else
__CRT_UUID_DECL(ID3D12DXVKInteropDevice, 0x39da4e09, 0xbd1c, 0x4198, 0x9f,0xae, 0x86,0xbb,0xe3,0xbe,0x41,0xfd)
#endif

View File

@ -1,29 +1,40 @@
#include <unordered_map>
#include "../util/util_math.h"
#include "d3d11_options.h"
namespace dxvk {
D3D11Options::D3D11Options(const Config& config, const Rc<DxvkDevice>& device) {
const DxvkDeviceInfo& devInfo = device->properties();
static bool IsAPITracingDXGI() {
#ifdef _WIN32
return !!::GetModuleHandle("dxgitrace.dll");
#else
return false;
#endif
}
D3D11Options::D3D11Options(const Config& config, const Rc<DxvkDevice>& device) {
this->dcSingleUseMode = config.getOption<bool>("d3d11.dcSingleUseMode", true);
this->enableRtOutputNanFixup = config.getOption<bool>("d3d11.enableRtOutputNanFixup", false);
this->zeroInitWorkgroupMemory = config.getOption<bool>("d3d11.zeroInitWorkgroupMemory", false);
this->forceTgsmBarriers = config.getOption<bool>("d3d11.forceTgsmBarriers", false);
this->forceVolatileTgsmAccess = config.getOption<bool>("d3d11.forceVolatileTgsmAccess", false);
this->relaxedBarriers = config.getOption<bool>("d3d11.relaxedBarriers", false);
this->ignoreGraphicsBarriers = config.getOption<bool>("d3d11.ignoreGraphicsBarriers", false);
this->maxTessFactor = config.getOption<int32_t>("d3d11.maxTessFactor", 0);
this->samplerAnisotropy = config.getOption<int32_t>("d3d11.samplerAnisotropy", -1);
this->samplerLodBias = config.getOption<float>("d3d11.samplerLodBias", 0.0f);
this->clampNegativeLodBias = config.getOption<bool>("d3d11.clampNegativeLodBias", false);
this->invariantPosition = config.getOption<bool>("d3d11.invariantPosition", true);
this->floatControls = config.getOption<bool>("d3d11.floatControls", true);
this->forceSampleRateShading = config.getOption<bool>("d3d11.forceSampleRateShading", false);
this->disableMsaa = config.getOption<bool>("d3d11.disableMsaa", false);
this->enableContextLock = config.getOption<bool>("d3d11.enableContextLock", false);
this->deferSurfaceCreation = config.getOption<bool>("dxgi.deferSurfaceCreation", false);
this->numBackBuffers = config.getOption<int32_t>("dxgi.numBackBuffers", 0);
this->maxFrameLatency = config.getOption<int32_t>("dxgi.maxFrameLatency", 0);
this->maxFrameRate = config.getOption<int32_t>("dxgi.maxFrameRate", 0);
this->syncInterval = config.getOption<int32_t>("dxgi.syncInterval", -1);
this->tearFree = config.getOption<Tristate>("dxgi.tearFree", Tristate::Auto);
// Clamp LOD bias so that people don't abuse this in unintended ways
this->samplerLodBias = dxvk::fclamp(this->samplerLodBias, -2.0f, 1.0f);
int32_t maxImplicitDiscardSize = config.getOption<int32_t>("d3d11.maxImplicitDiscardSize", 256);
this->maxImplicitDiscardSize = maxImplicitDiscardSize >= 0
@ -35,12 +46,9 @@ namespace dxvk {
? VkDeviceSize(maxDynamicImageBufferSize) << 10
: VkDeviceSize(~0ull);
this->constantBufferRangeCheck = config.getOption<bool>("d3d11.constantBufferRangeCheck", false)
&& DxvkGpuVendor(devInfo.core.properties.vendorID) != DxvkGpuVendor::Amd;
auto cachedDynamicResources = config.getOption<std::string>("d3d11.cachedDynamicResources", std::string());
if (::GetModuleHandle("dxgitrace.dll")) {
if (IsAPITracingDXGI()) {
// apitrace reads back all mapped resources on the CPU, so
// allocating everything in cached memory is necessary to
// achieve acceptable performance
@ -59,6 +67,9 @@ namespace dxvk {
}
}
}
// Shader dump path is only available via an environment variable
this->shaderDumpPath = env::getEnvVar("DXVK_SHADER_DUMP_PATH");
}
}

Some files were not shown because too many files have changed in this diff Show More