Compare commits

..

No commits in common. "master" and "v1.2.3" have entirely different histories.

616 changed files with 35787 additions and 96140 deletions

View File

@ -1,31 +0,0 @@
---
name: Bug report
about: Report crashes, rendering issues etc.
title: ''
labels: ''
assignees: ''
---
Please describe your issue as accurately as possible.
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.
### System information
- GPU:
- Driver:
- Wine version:
- DXVK version:
### 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
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

@ -1,83 +0,0 @@
name: Artifacts (Package)
on: [push, pull_request, workflow_dispatch]
jobs:
artifacts-mingw-w64:
runs-on: ubuntu-20.04
steps:
- name: Checkout code
id: checkout-code
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
- name: Setup problem matcher
uses: Joshua-Ashton/gcc-problem-matcher@v3
- name: Build release
id: build-release
uses: Joshua-Ashton/arch-mingw-github-action@v8
with:
command: |
export VERSION_NAME="${GITHUB_REF##*/}-${GITHUB_SHA##*/}"
./package-release.sh ${VERSION_NAME} build --no-package
echo "VERSION_NAME=${VERSION_NAME}" >> $GITHUB_ENV
- name: Upload artifacts
id: upload-artifacts
uses: actions/upload-artifact@v4
with:
name: dxvk-win-${{ 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@v4
with:
submodules: recursive
fetch-depth: 0
- name: Setup problem matcher
uses: Joshua-Ashton/gcc-problem-matcher@v3
- name: Build release
id: build-release
shell: bash
run: |
export VERSION_NAME="${GITHUB_REF##*/}-${GITHUB_SHA##*/}"
./package-native.sh ${VERSION_NAME} build
echo "VERSION_NAME=${VERSION_NAME}" >> $GITHUB_ENV
- name: Upload artifacts
id: upload-artifacts
uses: actions/upload-artifact@v4
with:
name: dxvk-native-${{ env.VERSION_NAME }}
path: build/dxvk-native-${{ env.VERSION_NAME }}.tar.gz
if-no-files-found: error
merge-artifacts:
runs-on: ubuntu-20.04
needs: [artifacts-mingw-w64, artifacts-steamrt-sniper]
steps:
- name: Get version
id: get-version
shell: bash
run: |
echo "VERSION_NAME=${GITHUB_REF##*/}-${GITHUB_SHA##*/}" >> $GITHUB_ENV
- name: Merge Artifacts
uses: actions/upload-artifact/merge@v4
with:
name: dxvk-${{ env.VERSION_NAME }}
pattern: dxvk*
delete-merged: true

View File

@ -1,51 +0,0 @@
name: Test Builds on Windows
on: [push, pull_request, workflow_dispatch]
jobs:
build-set-windows:
runs-on: windows-2022
steps:
- name: Checkout code
id: checkout-code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup glslangValidator
shell: pwsh
run: |
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
run: pip install meson
- name: Find Visual Studio
shell: pwsh
run: |
$installationPath = Get-VSSetupInstance `
| Select-VSSetupInstance -Require Microsoft.VisualStudio.Workload.NativeDesktop -Latest `
| Select-Object -ExpandProperty InstallationPath
Write-Output "VSDEVCMD=${installationPath}\Common7\Tools\VsDevCmd.bat" `
| Out-File -FilePath "${Env:GITHUB_ENV}" -Append
- name: Build MSVC x86
shell: pwsh
run: |
& "${Env:COMSPEC}" /s /c "`"${Env:VSDEVCMD}`" -arch=x86 -host_arch=x64 -no_logo && set" `
| % { , ($_ -Split '=', 2) } `
| % { [System.Environment]::SetEnvironmentVariable($_[0], $_[1]) }
meson --buildtype release --backend vs2022 build-msvc-x86
msbuild -m build-msvc-x86/dxvk.sln
- name: Build MSVC x64
shell: pwsh
run: |
& "${Env:COMSPEC}" /s /c "`"${Env:VSDEVCMD}`" -arch=x64 -host_arch=x64 -no_logo && set" `
| % { , ($_ -Split '=', 2) } `
| % { [System.Environment]::SetEnvironmentVariable($_[0], $_[1]) }
meson --buildtype release --backend vs2022 build-msvc-x64
msbuild -m build-msvc-x64/dxvk.sln

13
.gitmodules vendored
View File

@ -1,13 +0,0 @@
[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,4 @@
Copyright (c) 2017 Philip Rebohle
Copyright (c) 2019 Joshua Ashton
Copyright (c) 2017-2019 Philip Rebohle
zlib/libpng license

131
README.md
View File

@ -1,53 +1,38 @@
# DXVK
A Vulkan-based translation layer for Direct3D 9/10/11 which allows running 3D applications on Linux using Wine.
A Vulkan-based translation layer for Direct3D 10/11 which allows running 3D applications on Linux using Wine.
For the current status of the project, please refer to the [project wiki](https://github.com/doitsujin/dxvk/wiki).
The most recent development builds can be found [here](https://github.com/doitsujin/dxvk/actions/workflows/artifacts.yml?query=branch%3Amaster).
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, 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 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 a default Wine prefix that would be as follows:
```
export WINEPREFIX=/path/to/wineprefix
cp x64/*.dll $WINEPREFIX/drive_c/windows/system32
cp x32/*.dll $WINEPREFIX/drive_c/windows/syswow64
winecfg
export WINEPREFIX=/path/to/.wine-prefix
./setup_dxvk.sh install
```
For a pure 32-bit Wine prefix (non default) the 32-bit DLLs instead go to the `system32` directory:
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.
- `--without-dxgi`: Do not install DXVK's DXGI implementation and use the one provided by wine instead. This is necessary for both vkd3d and DXVK to work within the same wine prefix.
Verify that your application uses DXVK instead of wined3d by checking for the presence of the log file `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:
```
export WINEPREFIX=/path/to/wineprefix
cp x32/*.dll $WINEPREFIX/drive_c/windows/system32
winecfg
export WINEPREFIX=/path/to/.wine-prefix
./setup_dxvk.sh uninstall
```
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 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)
- [wine 3.10](https://www.winehq.org/) or newer
- [Meson](http://mesonbuild.com/) build system (at least version 0.43)
- [MinGW64](http://mingw-w64.org/) 6.0 compiler and headers
- [glslang](https://github.com/KhronosGroup/glslang) compiler
### Building DLLs
@ -67,25 +52,25 @@ cd /your/target/directory/build.64
ninja install
```
A winelib build can be created by adding the `--winelib` argument.
#### Compiling manually
```
# 64-bit build. For 32-bit builds, replace
# build-win64.txt with build-win32.txt
meson setup --cross-file build-win64.txt --buildtype release --prefix /your/dxvk/directory build.w64
meson --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.
The 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.
@ -94,91 +79,39 @@ 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.
- `api`: Shows the D3D feature level used by the application.
- `cs`: Shows worker thread statistics.
- `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).
- `api`: Shows the D3D feature level used by the application. Does not work correctly for D3D10 at the moment.
Additionally, `DXVK_HUD=1` has the same effect as `DXVK_HUD=devinfo,fps`, and `DXVK_HUD=full` enables all available HUD elements.
### Frame rate limit
The `DXVK_FRAME_RATE` environment variable can be used to limit the frame rate. A value of `0` uncaps the frame rate, while any positive value will limit rendering to the given number of frames per second. Alternatively, the configuration file can be used.
### Device filter
Some applications do not provide a method to select a different GPU. In that case, DXVK can be forced to use a given device:
- `DXVK_FILTER_DEVICE_NAME="Device Name"` Selects devices with a matching Vulkan device name, which can be retrieved with tools such as `vulkaninfo`. Matches on substrings, so "VEGA" or "AMD RADV VEGA10" is supported if the full device name is "AMD RADV VEGA10 (LLVM 9.0.0)", for example. If the substring matches more than one device, the first device matched will be used.
**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`: Controls the state cache. The following values are supported:
- `disable`: Disables the cache entirely.
- `reset`: Clears the cache file.
- `DXVK_STATE_CACHE=0` Disables the state cache.
- `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.
- `VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_standard_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_LOG_PATH=/some/directory` Changes path where log files are stored.
- `DXVK_CONFIG_FILE=/xxx/dxvk.conf` Sets path to the configuration file.
- `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
are missing this, you may see "error: std::cv_status has not been declared"
or similar threading related errors.
On Debian and Ubuntu, this can be resolved by using the posix alternate, which
are missing this, you may see "error: 'mutex' is not a member of 'std'". On
Debian and Ubuntu, this can usually be resolved by using the posix alternate, which
supports threading. For example, choose the posix alternate from these
commands:
commands (use i686 for 32-bit):
```
update-alternatives --config x86_64-w64-mingw32-gcc
update-alternatives --config x86_64-w64-mingw32-g++
update-alternatives --config i686-w64-mingw32-gcc
update-alternatives --config i686-w64-mingw32-g++
```
For non debian based distros, make sure that your mingw-w64-gcc cross compiler
does have `--enable-threads=posix` enabled during configure. If your distro does
ship its mingw-w64-gcc binary with `--enable-threads=win32` you might have to
recompile locally or open a bug at your distro's bugtracker to ask for it.
# DXVK Native
DXVK Native is a version of DXVK which allows it to be used natively without Wine.
This is primarily useful for game and application ports to either avoid having to write another rendering backend, or to help with port bringup during development.
[Release builds](https://github.com/doitsujin/dxvk/releases) are built using the Steam Runtime.
### How does it work?
DXVK Native replaces certain Windows-isms with a platform and framework-agnostic replacement, for example, `HWND`s can become `SDL_Window*`s, etc.
All it takes to do that is to add another WSI backend.
**Note:** DXVK Native requires a backend to be explicitly set via the `DXVK_WSI_DRIVER` environment variable. The current built-in options are `SDL2` and `GLFW`.
DXVK Native comes with a slim set of Windows header definitions required for D3D9/11 and the MinGW headers for D3D9/11.
In most cases, it will end up being plug and play with your renderer, but there may be certain teething issues such as:
- `__uuidof(type)` is supported, but `__uuidof(variable)` is not supported. Use `__uuidof_var(variable)` instead.

View File

@ -1 +1 @@
2.3.1
1.2.3

View File

@ -1,415 +0,0 @@
{
"$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"
}
]
}

View File

@ -3,9 +3,12 @@ c = 'i686-w64-mingw32-gcc'
cpp = 'i686-w64-mingw32-g++'
ar = 'i686-w64-mingw32-ar'
strip = 'i686-w64-mingw32-strip'
windres = 'i686-w64-mingw32-windres'
[properties]
c_args=['-msse', '-msse2']
cpp_args=['-msse', '-msse2']
c_link_args = ['-static', '-static-libgcc']
cpp_link_args = ['-static', '-static-libgcc', '-static-libstdc++', '-Wl,--add-stdcall-alias,--enable-stdcall-fixup']
needs_exe_wrapper = true
[host_machine]

View File

@ -3,9 +3,10 @@ c = 'x86_64-w64-mingw32-gcc'
cpp = 'x86_64-w64-mingw32-g++'
ar = 'x86_64-w64-mingw32-ar'
strip = 'x86_64-w64-mingw32-strip'
windres = 'x86_64-w64-mingw32-windres'
[properties]
c_link_args = ['-static', '-static-libgcc']
cpp_link_args = ['-static', '-static-libgcc', '-static-libstdc++']
needs_exe_wrapper = true
[host_machine]

19
build-wine32.txt Normal file
View File

@ -0,0 +1,19 @@
[binaries]
c = 'winegcc'
cpp = 'wineg++'
ar = 'ar'
strip = 'strip'
[properties]
needs_exe_wrapper = true
c_args=['-m32', '-msse', '-msse2', '-fvisibility=hidden']
cpp_args=['-m32', '--no-gnu-unique', '-msse', '-msse2', '-fvisibility=hidden', '-fvisibility-inlines-hidden']
cpp_link_args=['-m32', '-mwindows']
[host_machine]
system = 'linux'
cpu_family = 'x86'
cpu = 'i686'
endian = 'little'

19
build-wine64.txt Normal file
View File

@ -0,0 +1,19 @@
[binaries]
c = 'winegcc'
cpp = 'wineg++'
ar = 'ar'
strip = 'strip'
[properties]
needs_exe_wrapper = true
c_args=['-m64', '-fvisibility=hidden']
cpp_args=['-m64', '--no-gnu-unique', '-fvisibility=hidden', '-fvisibility-inlines-hidden']
cpp_link_args=['-m64', '-mwindows']
[host_machine]
system = 'linux'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'

602
dxvk.conf
View File

@ -1,23 +1,3 @@
# Device filter. Only exposes devices whose Vulkan device name contains
# the given string. May be useful to force an application to run on a
# specific GPU, but not applications launched by that application.
# dxvk.deviceFilter = ""
# 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,
@ -26,7 +6,6 @@
# Supported values: True, False
# dxgi.deferSurfaceCreation = False
# d3d9.deferSurfaceCreation = False
# Enforce a stricter maximum frame latency. Overrides the application
@ -36,22 +15,6 @@
# Supported values : 0 - 16
# dxgi.maxFrameLatency = 0
# d3d9.maxFrameLatency = 0
# 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
# -1: Always disables the limiter
# 0: Default behaviour. Limits the frame rate to the selected display
# refresh rate when vertical synchronization is enabled if the
# actual display mode does not match the game's one.
# n: Limit to n frames per second.
# dxgi.maxFrameRate = 0
# d3d9.maxFrameRate = 0
# Override PCI vendor and device IDs reported to the application. Can
@ -62,55 +25,19 @@
# dxgi.customDeviceId = 0000
# dxgi.customVendorId = 0000
# d3d9.customDeviceId = 0000
# d3d9.customVendorId = 0000
# Override the reported device description
# 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.
#
# Supported values: Any string.
# Supported values: True, False
# dxgi.customDeviceDesc = ""
# d3d9.customDeviceDesc = ""
# dxgi.nvapiHack = True
# 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: Auto, True, False
# dxgi.hideNvidiaGpu = Auto
# Report Nvidia GPUs running on NVK as AMD GPUs.
#
# Supported values: Auto, True, False
# dxgi.hideNvkGpu = 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
# in games that do not support cards with large amounts of VRAM.
# This is not a hard cap and applications can choose to ignore it.
#
# Supported values: Any number in Megabytes.
@ -118,22 +45,12 @@
# dxgi.maxSharedMemory = 0
# Some games think we are on Intel given a lack of NVAPI or
# AGS/atiadlxx support. Report our device memory as shared memory,
# and some small amount for a "carveout".
# Supported values: True, False
# dxgi.emulateUMA = False
# Override back buffer count for the Vulkan swap chain.
# Setting this to 0 or less will have no effect.
#
# Supported values: Any number greater than or equal to 2.
# dxgi.numBackBuffers = 0
# d3d9.numBackBuffers = 0
# Overrides synchronization interval (Vsync) for presentation.
@ -144,23 +61,31 @@
# Supported values: Any non-negative number
# dxgi.syncInterval = -1
# d3d9.presentInterval = -1
# True enables the mailbox present mode in case regular Vsync is disabled.
# This should avoid tearing, but may be unsupported on some systems
# or require setting dxgi.numBackBuffers to a higher value in order
# to work properly.
#
# False enables the relaxed fifo present mode in case regular Vsync is enabled.
# This should result in tearing but reduce stutter if FPS are too low,
# but may be unsupported on some systems.
#
# Please do not report issues with this option.
#
# Supported values: Auto, True, False
# Enables or dsables d3d10 support.
#
# Supported values: True, False
# dxvk.tearFree = Auto
# d3d10.enable = True
# Handle D3D11_MAP_FLAG_DO_NOT_WAIT correctly when D3D11DeviceContext::Map()
# is called. Enabling this can potentially improve performance, but breaks
# games which do not expect Map() to return an error despite using the flag.
#
# Supported values: True, False
# d3d11.allowMapFlagNoWait = False
# 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
# Assume single-use mode for command lists created on deferred contexts.
@ -176,9 +101,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, 12_0, 12_1
# Supported values: 9_1, 9_2, 9_3, 10_0, 10_1, 11_0, 11_1
# d3d11.maxFeatureLevel = 12_1
# d3d11.maxFeatureLevel = 11_1
# Overrides the maximum allowed tessellation factor. This can be used to
@ -199,16 +124,6 @@
# d3d11.relaxedBarriers = False
# Ignores barriers around UAV writes from fragment shaders.
#
# This may improve performance in some games, but may also introduce
# rendering issues. Please don't report bugs with the option enabled.
#
# Supported values: True, False
# d3d11.ignoreGraphicsBarriers = False
# Overrides anisotropic filtering for all samplers. Set this to a positive
# value to enable AF for all samplers in the game, or to 0 in order to
# disable AF entirely. Negative values will have no effect.
@ -216,54 +131,15 @@
# Supported values: Any number between 0 and 16
# d3d11.samplerAnisotropy = -1
# 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.
# Enables SM4-compliant division-by-zero behaviour. Enabling may reduce
# performance and / or cause issues in games that expect the default
# behaviour of Windows drivers, which also is not SM4-compliant.
#
# 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.
#
# Supported values: True, False
# d3d11.invariantPosition = True
# 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.
#
# Supported values: True, False
# d3d11.disableMsaa = False
# d3d11.strictDivision = False
# Clears workgroup memory in compute shaders to zero. Some games don't do
@ -274,79 +150,10 @@
# d3d11.zeroWorkgroupMemory = False
# Resource size limit for implicit discards, in kilobytes. For small staging
# resources mapped with MAP_WRITE, DXVK will sometimes allocate new backing
# storage in order to avoid GPU synchronization, so setting this too high
# may cause memory issues, setting it to -1 disables the feature.
# d3d11.maxImplicitDiscardSize = 256
# Resource size limit for buffer-mapped dynamic images, in kilobytes.
# A higher threshold may reduce memory usage and PCI-E bandwidth in
# some games, but may also increase GPU synchronizations. Setting it
# to -1 disables the feature.
# d3d11.maxDynamicImageBufferSize = -1
# Allocates dynamic resources with the given set of bind flags 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: Any combination of the following:
# - v: Vertex buffers
# - i: Index buffers
# - c: Constant buffers
# - r: Shader resources
# - a: All dynamic resources
# 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
# Exposes or hides support for driver command lists
#
# Some games use the feature flag to decide whether to use deferred
# contexts or not. We enable this by default, but in some situations
# this can lead to issues if games detect an AMD GPU where command
# lists are not natively supported on Windows.
#
# Supported values: True, False
# d3d11.exposeDriverCommandLists = True
# Reproducible Command Stream
#
# Ensure that for the same D3D commands the output VK commands
# don't change between runs. Useful for comparative benchmarking,
# can negatively affect performance and can break some games
# that don't use queries correctly.
#
# Supported values:
# - True/False
# d3d11.reproducibleCommandStream = False
# d3d9.reproducibleCommandStream = 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 use all available CPU cores
# - 0 to automatically determine the number of threads to use
# - any positive number to enforce the thread count
# dxvk.numCompilerThreads = 0
@ -367,343 +174,16 @@
# dxvk.useRawSsbo = Auto
# Changes memory chunk size.
#
# Can be used to override the maximum memory chunk size.
#
# Supported values:
# - 0 to use the defaults
# - any positive integer to limit the chunk size, in MiB
# 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
# Toggles early discard.
#
# Behaves like the DXVK_HUD environment variable if the
# environment variable is not set, otherwise it will be
# ignored. The syntax is identical.
# dxvk.hud =
# Reported shader model
#
# The shader model to state that we support in the device
# capabilities that the applicatation queries.
# Uses subgroup operations to determine whether it is safe to
# discard fragments before the end of a fragment shader. This
# is enabled by default on all drivers except RADV and Nvidia.
# Enabling this may improve or degrade performance depending
# on the game and hardware, or cause other issues.
#
# Supported values:
# - 1: Shader Model 1
# - 2: Shader Model 2
# - 3: Shader Model 3
# d3d9.shaderModel = 3
# DPI Awareness
#
# Decides whether we should call SetProcessDPIAware on device
# creation. Helps avoid upscaling blur in modern Windows on
# Hi-DPI screens/devices.
#
# Supported values:
# - Auto: Don't change the default
# - True, False: Always enable / disable
# d3d9.dpiAware = True
# Strict Constant Copies
#
# Decides whether we should always copy defined constants to
# the UBO when relative addressing is used, or only when the
# relative addressing starts a defined constant.
#
# Supported values:
# - True, False: Always enable / disable
# d3d9.strictConstantCopies = False
# Strict Pow
#
# Decides whether we have an opSelect for handling pow(0,0) = 0
# otherwise it becomes undefined.
#
# Supported values:
# - True, False: Always enable / disable
# d3d9.strictPow = True
# Lenient Clear
#
# Decides whether or not we fastpath clear anyway if we are close enough to
# clearing a full render target.
#
# Supported values:
# - True, False: Always enable / disable
# d3d9.lenientClear = False
# Max available memory
#
# Changes the max initial value used in tracking and GetAvailableTextureMem
# Value in Megabytes
#
# Supported values:
# - Max Available Memory: Any int32_t
# - Memory Tracking Testing: True, False
# d3d9.maxAvailableMemory = 4096
# d3d9.memoryTrackTest = False
# Force enable/disable floating point quirk emulation
#
# Force toggle anything * 0 emulation
# Setting it to True will use a faster but less accurate approach that works for most games.
# Supported values:
# - True: Use a faster but less accurate approach. Good enough for most games
# - False: Disable float emulation completely
# - Strict: Use a slower but more correct approach. Necessary for some games
# - Auto: DXVK will pick automatically
# d3d9.floatEmulation = Auto
# Enable dialog box mode
#
# Changes the default state of dialog box mode.
# *Disables* exclusive fullscreen when enabled.
#
# Supported values:
# - True, False: Always enable / disable
# d3d9.enableDialogMode = False
# Overrides the application's MSAA level on the swapchain
#
# Supported values: -1 (application) and 0 to 16 (user override)
# d3d9.forceSwapchainMSAA = -1
# Long Mad
#
# Should we make our Mads a FFma or do it the long way with an FMul and an FAdd?
# This solves some rendering bugs in games that have z-pass shaders which
# don't match entirely to the regular vertex shader in this way.
#
# Supported values:
# - True/False
# d3d11.longMad = False
# d3d9.longMad = False
# Device Local Constant Buffers
#
# Enables using device local, host accessible memory for constant buffers in D3D9.
# This tends to actually be slower for some reason on AMD,
# and the exact same performance on NVIDIA.
#
# Supported values:
# - True/False
# d3d9.deviceLocalConstantBuffers = False
# Support DF formats
#
# Support the vendor extension DF floating point depth formats on AMD and Intel.
# Note that this config is ignored and disabled by default on Nvidia, or when
# spoofing a Nvidia GPU, as it does not support these formats natively.
#
# Supported values:
# - True/False
# 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 very broken game.
#
# Supported values:
# - True/False
# d3d9.supportX4R4G4B4 = True
# Support D32
#
# Support the D32 format.
#
# Supported values:
# - True/False
# d3d9.supportD32 = True
# Disable A8 as a Render Target
#
# Disable support for A8 format render targets
# Once again, The Sims 2 is a very broken game.
#
# Supported values:
# - True/False
# d3d9.disableA8RT = False
# Support for VCache Query
#
# Support for the vcache query
# Not very important as a user config.
# Used internally.
#
# Supported values:
# - True/False
# Defaults to True if vendorId == 0x10de
# d3d9.supportVCache = True
# Force Sampler Type Spec Constants
#
# Useful if games use the wrong image and sampler
# type combo like Halo: CE or Spellforce.
# Can fix rendering in older, broken games in some instances.
#
# Supported values:
# - True/False
# d3d9.forceSamplerTypeSpecConstants = False
# Force Aspect Ratio
#
# Only exposes modes with a given aspect ratio.
# Useful for titles that break if they see ultra-wide.
#
# Supported values:
# - Any ratio, ie. "16:9", "4:3"
# d3d9.forceAspectRatio = ""
# Enumerate by Displays
#
# Whether we should enumerate D3D9 adapters by display (windows behaviour)
# or by physical adapter.
# May be useful in PRIME setups.
#
# Supported values:
# - True/False
# d3d9.enumerateByDisplays = True
# Cached Dynamic Buffers
#
# 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.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_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
# Hide integrated graphics from applications
#
# Only has an effect when dedicated GPUs are present on the system. It is
# not recommended to use this option at all unless absolutely necessary for
# a game to work; prefer using DXVK_FILTER_DEVICE_NAME whenever possible.
#
# Supported values:
# - True/False
# dxvk.hideIntegratedGraphics = False
# Trigger DEVICELOST when losing focus
#
# D3D9 requires the application to call Device::Reset after
# it loses focus in fullscreen.
# Some games rely on observing a D3DERR_DEVICELOST or D3DERR_NOTRESET.
# Others don't handle it correctly.
#
# Supported values:
# - True/False
# d3d9.deviceLossOnFocusLoss = False
# Reject Device::Reset if any losable resource is still alive
#
# D3D9 rejects Device::Reset if there's still any alive resources of specific types.
# (State blocks, additional swapchains, D3DPOOL_DEFAULT resources)
# Some games leak resources leading to a hang.
#
# Supported values:
# - True/False
# d3d9.countLosableResources = True
# dxvk.useEarlyDiscard = Auto

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

View File

@ -1,19 +0,0 @@
install_subdir(
'directx',
install_dir: get_option('includedir') / 'dxvk',
strip_directory: true,
exclude_files: '.git'
)
install_subdir(
'windows',
install_dir: get_option('includedir') / 'dxvk',
strip_directory: true,
)
install_headers(
'wsi/native_wsi.h',
'wsi/native_sdl2.h',
'wsi/native_glfw.h',
subdir: 'dxvk/wsi',
)

View File

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

View File

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

View File

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

View File

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

View File

@ -1,8 +0,0 @@
/**
* 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

@ -1,8 +0,0 @@
/**
* 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

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

View File

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

View File

@ -1,52 +0,0 @@
#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

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

View File

@ -1,398 +0,0 @@
#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 int64_t INT64;
typedef uint64_t ULONGLONG;
typedef uint64_t UINT64;
typedef intptr_t LONG_PTR;
typedef uintptr_t ULONG_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
#ifdef CONST_VTABLE
#define DECLARE_INTERFACE(x) \
typedef interface x { \
const struct x##Vtbl *lpVtbl; \
} x; \
typedef const struct x##Vtbl x##Vtbl; \
const struct x##Vtbl
#else
#define DECLARE_INTERFACE(x) \
typedef interface x { \
struct x##Vtbl *lpVtbl; \
} x; \
typedef struct x##Vtbl x##Vtbl; \
struct x##Vtbl
#endif // CONST_VTABLE
#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

@ -1,25 +0,0 @@
#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

@ -1,25 +0,0 @@
#include <windows.h>
#include <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

@ -1,11 +0,0 @@
#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 +0,0 @@
Subproject commit 8b246ff75c6615ba4532fe4fde20f1be090c3764

View File

@ -0,0 +1,131 @@
/*
** 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

@ -0,0 +1,135 @@
/*
** 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

1126
include/spirv/spirv.hpp Normal file

File diff suppressed because it is too large Load Diff

@ -1 +0,0 @@
Subproject commit 46dc0f6e514f5730784bb2cac2a7c731636839e8

View File

@ -0,0 +1,92 @@
//
// File: vk_platform.h
//
/*
** Copyright (c) 2014-2017 The Khronos Group Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#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
#include <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

79
include/vulkan/vulkan.h Normal file
View File

@ -0,0 +1,79 @@
#ifndef VULKAN_H_
#define VULKAN_H_ 1
/*
** Copyright (c) 2015-2018 The Khronos Group Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#include "vk_platform.h"
#include "vulkan_core.h"
#ifdef VK_USE_PLATFORM_ANDROID_KHR
#include "vulkan_android.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_MIR_KHR
#include <mir_toolkit/client_types.h>
#include "vulkan_mir.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_XLIB_XRANDR_EXT
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#include "vulkan_xlib_xrandr.h"
#endif
#endif // VULKAN_H_

9184
include/vulkan/vulkan_core.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,276 @@
#ifndef VULKAN_WIN32_H_
#define VULKAN_WIN32_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright (c) 2015-2018 The Khronos Group Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#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 1
#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;
#ifdef __cplusplus
}
#endif
#endif

19
issue_template.md Normal file
View File

@ -0,0 +1,19 @@
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.
**Important:** When reporting an issue with a specific game or application, such as crashes or rendering issues, please include log files and a D3D11 Apitrace (see https://github.com/apitrace/apitrace) so that the issue can be reproduced. In order to create a trace, run `wine apitrace.exe trace -a dxgi YOURGAME.exe`. DO NOT use DXVK together with apitrace!
### Software information
Name of the game, settings used etc.
### System information
- GPU:
- Driver:
- Wine version:
- DXVK version:
### Apitrace file(s)
- Put a link here
### Log files
- d3d11.log:
- dxgi.log:

BIN
lib/d3dcompiler_43.lib Normal file

Binary file not shown.

17
lib/libd3dcompiler_43.def Normal file
View File

@ -0,0 +1,17 @@
; 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

BIN
lib/vulkan-1.lib Executable file

Binary file not shown.

BIN
lib32/d3dcompiler_43.lib Normal file

Binary file not shown.

View File

@ -0,0 +1,17 @@
; 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

BIN
lib32/vulkan-1.lib Executable file

Binary file not shown.

View File

@ -1,194 +1,103 @@
project('dxvk', ['c', 'cpp'], version : 'v2.3.1', meson_version : '>= 0.58', default_options : [ 'cpp_std=c++17', 'warning_level=2' ])
project('dxvk', ['c', 'cpp'], version : 'v1.2.3', meson_version : '>= 0.43')
pkg = import('pkgconfig')
cpu_family = target_machine.cpu_family()
platform = target_machine.system()
fs = import('fs')
cpp = meson.get_compiler('cpp')
cc = meson.get_compiler('c')
dxvk_is_msvc = cpp.get_argument_syntax() == 'msvc'
add_project_arguments('-DNOMINMAX', language : 'cpp')
compiler_args = [
'-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 = []
if get_option('build_id')
link_args += [
'-Wl,--build-id',
]
dxvk_compiler = meson.get_compiler('cpp')
if dxvk_compiler.get_id() == 'msvc'
dxvk_cpp_std='c++latest'
dxvk_msvc=true
else
dxvk_cpp_std='c++1z'
dxvk_msvc=false
endif
dxvk_include_dirs = ['./include']
if fs.is_dir('./include/vulkan/include')
dxvk_include_dirs += ['./include/vulkan/include']
elif not cpp.check_header('vulkan/vulkan.h')
error('Missing Vulkan-Headers')
endif
if fs.is_dir('./include/spirv/include')
dxvk_include_dirs += ['./include/spirv/include']
elif not cpp.check_header('spirv/unified1/spirv.hpp')
error('Missing SPIRV-Headers')
if dxvk_compiler.get_id() == 'msvc'
add_project_arguments('/std:' + dxvk_cpp_std, language : 'cpp')
endif
dep_displayinfo = dependency(
'libdisplay-info',
version: ['>= 0.0.0', '< 0.2.0'],
fallback: ['libdisplay-info', 'di_dep'],
default_options: ['default_library=static'],
)
dxvk_include_path = include_directories('./include')
if platform == 'windows'
dxvk_so_version = {'name_prefix': ''}
if (cpu_family == 'x86_64')
dxvk_library_path = meson.source_root() + '/lib'
else
dxvk_library_path = meson.source_root() + '/lib32'
endif
compiler_args += [
'-DNOMINMAX',
'-D_WIN32_WINNT=0xa00',
]
code = '''#ifndef __WINE__
#error 1
#endif'''
if not dxvk_is_msvc
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',
]
dxvk_winelib = dxvk_compiler.compiles(code, name: 'winelib check')
dxvk_extradep = [ ]
# 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
else
link_args += [
'/FILEALIGN:4096',
]
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'
if dxvk_winelib
wrc = find_program('wrc')
lib_vulkan = declare_dependency(link_args: [ '-lwinevulkan' ])
lib_d3d11 = declare_dependency(link_args: [ '-ld3d11' ])
lib_dxgi = declare_dependency(link_args: [ '-ldxgi' ])
lib_d3dcompiler_43 = declare_dependency(link_args: [ '-L'+dxvk_library_path, '-ld3dcompiler_43' ])
lib_d3dcompiler_47 = declare_dependency(link_args: [ '-ld3dcompiler' ])
dxvk_extradep += [ declare_dependency(link_args: [ '-ldl' ]) ]
exe_ext = '.exe.so'
dll_ext = '.dll'
res_ext = '.res'
def_spec_ext = '.spec'
else
if dxvk_compiler.get_id() == 'msvc'
wrc = find_program('rc')
wrc_generator = generator(wrc,
output : [ '@BASENAME@' + res_ext ],
arguments : [ '/fo', '@OUTPUT@', '@INPUT@' ],
)
else
wrc = cpu_family == 'x86_64' ? find_program('x86_64-w64-mingw32-windres') : find_program('i686-w64-mingw32-windres')
endif
lib_vulkan = dxvk_compiler.find_library('vulkan-1', dirs : dxvk_library_path)
lib_d3d11 = dxvk_compiler.find_library('d3d11')
lib_dxgi = dxvk_compiler.find_library('dxgi')
lib_d3dcompiler_43 = dxvk_compiler.find_library('d3dcompiler_43', dirs : dxvk_library_path)
if dxvk_compiler.get_id() == 'msvc'
lib_d3dcompiler_47 = dxvk_compiler.find_library('d3dcompiler')
else
lib_d3dcompiler_47 = dxvk_compiler.find_library('d3dcompiler_47')
endif
exe_ext = ''
dll_ext = ''
if dxvk_compiler.get_id() == 'msvc'
res_ext = '.res'
else
res_ext = '.o'
wrc = find_program('windres')
wrc_generator = generator(wrc,
output : [ '@BASENAME@' + res_ext ],
arguments : [ '-i', '@INPUT@', '-o', '@OUTPUT@' ],
)
endif
dxvk_name_prefix = ''
compiler_args += ['-DDXVK_WSI_WIN32']
else
dxvk_abi_version = '0'
dxvk_version = meson.project_version().strip('v').split('.')
dxvk_so_version = {'version': dxvk_abi_version + '.' + dxvk_version[0] + dxvk_version[1] + dxvk_version[2]}
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'
]
lib_sdl2 = dependency('SDL2', required: false)
lib_glfw = dependency('glfw', required: false)
if lib_sdl2.found()
compiler_args += ['-DDXVK_WSI_SDL2']
endif
if lib_glfw.found()
compiler_args += ['-DDXVK_WSI_GLFW']
endif
if (not lib_sdl2.found() and not lib_glfw.found())
error('SDL2 or GLFW are required to build dxvk-native')
endif
dxvk_name_prefix = 'dxvk_'
dxvk_pkg_prefix = 'dxvk-'
link_args += [
'-static-libgcc',
'-static-libstdc++',
]
def_spec_ext = '.def'
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')
exe_ext = ''
def_spec_ext = '.def'
glsl_compiler = find_program('glslang', 'glslangValidator')
glsl_args = [
'--quiet',
'--target-env', 'vulkan1.3',
'--vn', '@BASENAME@',
'--depfile', '@DEPFILE@',
'@INPUT@',
'-o', '@OUTPUT@',
]
glsl_generator = generator(
glsl_compiler,
glsl_compiler = find_program('glslangValidator')
glsl_generator = generator(glsl_compiler,
output : [ '@BASENAME@.h' ],
depfile : '@BASENAME@.h.d',
arguments : glsl_args,
)
arguments : [ '-V', '--vn', '@BASENAME@', '@INPUT@', '-o', '@OUTPUT@' ])
if dxvk_compiler.get_id() == 'msvc'
wrc_generator = generator(wrc,
output : [ '@BASENAME@' + res_ext ],
arguments : [ '/fo', '@OUTPUT@', '@INPUT@' ])
else
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',
output: 'version.h',
)
if platform != 'windows'
subdir('include/native')
endif
output: 'version.h')
subdir('src')
enable_tests = get_option('enable_tests')
if enable_tests
subdir('tests')
endif

View File

@ -1,7 +1,4 @@
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.')

View File

@ -1,89 +0,0 @@
#!/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 \
--force-fallback-for=libdisplay-info \
"$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

@ -1,17 +1,16 @@
#!/usr/bin/env bash
#!/bin/bash
set -e
shopt -s extglob
if [ -z "$1" ] || [ -z "$2" ]; then
echo "Usage: $0 version destdir [--no-package] [--dev-build]"
echo "Usage: $0 version destdir [--no-package] [--dev-build] [--winelib]"
exit 1
fi
DXVK_VERSION="$1"
DXVK_SRC_DIR=$(readlink -f "$0")
DXVK_SRC_DIR=$(dirname "$DXVK_SRC_DIR")
DXVK_SRC_DIR=`dirname $(readlink -f $0)`
DXVK_BUILD_DIR=$(realpath "$2")"/dxvk-$DXVK_VERSION"
DXVK_ARCHIVE_PATH=$(realpath "$2")"/dxvk-$DXVK_VERSION.tar.gz"
@ -24,7 +23,7 @@ shift 2
opt_nopackage=0
opt_devbuild=0
opt_buildid=false
opt_winelib=0
crossfile="build-win"
@ -37,8 +36,9 @@ while [ $# -gt 0 ]; do
opt_nopackage=1
opt_devbuild=1
;;
"--build-id")
opt_buildid=true
"--winelib")
opt_winelib=1
crossfile="build-wine"
;;
*)
echo "Unrecognized option: $1" >&2
@ -53,30 +53,32 @@ function build_arch {
cd "$DXVK_SRC_DIR"
opt_strip=
if [ $opt_devbuild -eq 0 ]; then
opt_strip=--strip
fi
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 \
meson --cross-file "$DXVK_SRC_DIR/$crossfile$1.txt" \
--buildtype "release" \
--prefix "$DXVK_BUILD_DIR" \
--strip \
--bindir "x$1" \
--libdir "x$1" \
-Denable_tests=false \
"$DXVK_BUILD_DIR/build.$1"
cd "$DXVK_BUILD_DIR/build.$1"
ninja install
if [ $opt_devbuild -eq 0 ]; then
# get rid of some useless .a files
rm "$DXVK_BUILD_DIR/x$1/"*.!(dll)
if [ $opt_winelib -eq 0 ]; then
# get rid of some useless .a files
rm "$DXVK_BUILD_DIR/x$1/"*.!(dll)
fi
rm -R "$DXVK_BUILD_DIR/build.$1"
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"
@ -85,6 +87,7 @@ function package {
build_arch 64
build_arch 32
build_script
if [ $opt_nopackage -eq 0 ]; then
package

178
setup_dxvk.sh Normal file
View File

@ -0,0 +1,178 @@
#!/bin/bash
# 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] [--symlink]"
exit 1
esac
# process arguments
shift
with_dxgi=1
file_cmd="cp"
while [ $# -gt 0 ]; do
case "$1" in
"--without-dxgi")
with_dxgi=0
;;
"--symlink")
file_cmd="ln -s"
;;
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
if [ -z "$wine" ]; then
wine="wine"
fi
wine64="${wine}64"
wineboot="${wine}boot"
# 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
win32_sys_path=$($wine winepath -u 'C:\windows\system32' 2> /dev/null)
win64_sys_path=$($wine64 winepath -u 'C:\windows\system32' 2> /dev/null)
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 "${dstfile}" "${dstfile}.old"
else
rm "${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 "${dstfile}"
mv "${dstfile}.old" "${dstfile}"
return 0
else
return 1
fi
}
install() {
installFile "$win32_sys_path" "x32" "$1"
inst32_ret="$?"
installFile "$win64_sys_path" "x64" "$1"
inst64_ret="$?"
if [ "$inst32_ret" -eq 0 ] || [ "$inst64_ret" -eq 0 ]; then
overrideDll "$1"
fi
}
uninstall() {
uninstallFile "$win32_sys_path" "x32" "$1"
uninst32_ret="$?"
uninstallFile "$win64_sys_path" "x64" "$1"
uninst64_ret="$?"
if [ "$uninst32_ret" -eq 0 ] || [ "$uninst64_ret" -eq 0 ]; then
restoreDll "$1"
fi
}
# skip dxgi during install if not explicitly
# enabled, but always try to uninstall it
if [ $with_dxgi -ne 0 ] || [ "$action" == "uninstall" ]; then
$action dxgi
fi
$action d3d10
$action d3d10_1
$action d3d10core
$action d3d11

27
src/d3d10/d3d10.def Normal file
View File

@ -0,0 +1,27 @@
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

31
src/d3d10/d3d10.spec Normal file
View File

@ -0,0 +1,31 @@
@ stdcall D3D10CreateDevice(ptr long ptr long long ptr)
@ stdcall D3D10CreateDeviceAndSwapChain(ptr long ptr long long ptr ptr ptr)
@ stdcall D3D10GetVertexShaderProfile(ptr)
@ stdcall D3D10GetGeometryShaderProfile(ptr)
@ stdcall D3D10GetPixelShaderProfile(ptr)
@ stdcall D3D10CreateBlob(long ptr)
@ stdcall D3D10GetInputSignatureBlob(ptr long ptr)
@ stdcall D3D10GetOutputSignatureBlob(ptr long ptr)
@ stdcall D3D10ReflectShader(ptr long ptr)
@ stdcall D3D10CompileShader(ptr long str ptr ptr str str long ptr ptr)
@ stdcall D3D10CreateEffectFromMemory(ptr long long ptr ptr ptr)
@ stdcall D3D10CreateEffectPoolFromMemory(ptr long long ptr ptr)
@ stdcall D3D10CompileEffectFromMemory(ptr long ptr ptr ptr long long ptr ptr)
@ stub D3D10DisassembleEffect
@ stdcall D3D10DisassembleShader(ptr long long ptr ptr)
@ stub D3D10PreprocessShader
@ stdcall D3D10CreateStateBlock(ptr ptr ptr)
@ stdcall D3D10StateBlockMaskDifference(ptr ptr ptr)
@ stdcall D3D10StateBlockMaskDisableAll(ptr)
@ stdcall D3D10StateBlockMaskDisableCapture(ptr long long long)
@ stdcall D3D10StateBlockMaskEnableAll(ptr)
@ stdcall D3D10StateBlockMaskEnableCapture(ptr long long long)
@ stdcall D3D10StateBlockMaskGetSetting(ptr long long)
@ stdcall D3D10StateBlockMaskIntersect(ptr ptr ptr)
@ stdcall D3D10StateBlockMaskUnion(ptr ptr ptr)

27
src/d3d10/d3d10_1.def Normal file
View File

@ -0,0 +1,27 @@
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

31
src/d3d10/d3d10_1.spec Normal file
View File

@ -0,0 +1,31 @@
@ stdcall D3D10CreateDevice1(ptr long ptr long long long ptr)
@ stdcall D3D10CreateDeviceAndSwapChain1(ptr long ptr long long long ptr ptr ptr)
@ stdcall D3D10GetVertexShaderProfile(ptr)
@ stdcall D3D10GetGeometryShaderProfile(ptr)
@ stdcall D3D10GetPixelShaderProfile(ptr)
@ stdcall D3D10CreateBlob(long ptr)
@ stdcall D3D10GetInputSignatureBlob(ptr long ptr)
@ stdcall D3D10GetOutputSignatureBlob(ptr long ptr)
@ stdcall D3D10ReflectShader(ptr long ptr)
@ stdcall D3D10CompileShader(ptr long str ptr ptr str str long ptr ptr)
@ stdcall D3D10CreateEffectFromMemory(ptr long long ptr ptr ptr)
@ stdcall D3D10CreateEffectPoolFromMemory(ptr long long ptr ptr)
@ stdcall D3D10CompileEffectFromMemory(ptr long ptr ptr ptr long long ptr ptr)
@ stub D3D10DisassembleEffect
@ stdcall D3D10DisassembleShader(ptr long long ptr ptr)
@ stub D3D10PreprocessShader
@ stdcall D3D10CreateStateBlock(ptr ptr ptr)
@ stdcall D3D10StateBlockMaskDifference(ptr ptr ptr)
@ stdcall D3D10StateBlockMaskDisableAll(ptr)
@ stdcall D3D10StateBlockMaskDisableCapture(ptr long long long)
@ stdcall D3D10StateBlockMaskEnableAll(ptr)
@ stdcall D3D10StateBlockMaskEnableCapture(ptr long long long)
@ stdcall D3D10StateBlockMaskGetSetting(ptr long long)
@ stdcall D3D10StateBlockMaskIntersect(ptr ptr ptr)
@ stdcall D3D10StateBlockMaskUnion(ptr ptr ptr)

View File

@ -105,7 +105,7 @@ namespace dxvk {
pDesc->ByteWidth = d3d11Desc.ByteWidth;
pDesc->Usage = D3D10_USAGE(d3d11Desc.Usage);
pDesc->BindFlags = d3d11Desc.BindFlags;
pDesc->BindFlags = d3d11Desc.BindFlags & 0x7F;
pDesc->CPUAccessFlags = d3d11Desc.CPUAccessFlags;
pDesc->MiscFlags = ConvertD3D11ResourceFlags(d3d11Desc.MiscFlags);
}

View File

@ -12,8 +12,8 @@ namespace dxvk {
public:
D3D10Buffer(D3D11Buffer* pParent)
: m_d3d11(pParent) { }
D3D10Buffer(D3D11Buffer* pParent, D3D10Device* pDevice)
: m_device(pDevice), m_d3d11(pParent) { }
HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid,
@ -64,6 +64,7 @@ namespace dxvk {
private:
D3D10Device* m_device;
D3D11Buffer* m_d3d11;
};

View File

@ -1,71 +0,0 @@
#include <d3d11.h>
#include <d3d10_1.h>
#include "../dxgi/dxgi_interfaces.h"
extern "C" {
using namespace dxvk;
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);
DLLEXPORT HRESULT __stdcall D3D10CoreCreateDevice(
IDXGIFactory* pFactory,
IDXGIAdapter* pAdapter,
UINT Flags,
D3D_FEATURE_LEVEL FeatureLevel,
ID3D10Device** ppDevice) {
InitReturnPtr(ppDevice);
Com<ID3D11Device> d3d11Device;
HRESULT hr = pAdapter->CheckInterfaceSupport(
__uuidof(ID3D10Device), nullptr);
if (FAILED(hr))
return hr;
hr = D3D11CoreCreateDevice(pFactory, pAdapter, D3D_DRIVER_TYPE_UNKNOWN,
nullptr, Flags, &FeatureLevel, 1, D3D11_SDK_VERSION, &d3d11Device, nullptr);
if (FAILED(hr))
return hr;
Com<ID3D10Multithread> multithread;
d3d11Device->QueryInterface(__uuidof(ID3D10Multithread), reinterpret_cast<void**>(&multithread));
multithread->SetMultithreadProtected(!(Flags & D3D10_CREATE_DEVICE_SINGLETHREADED));
Com<IDXGIDXVKDevice> dxvkDevice;
d3d11Device->QueryInterface(__uuidof(IDXGIDXVKDevice), reinterpret_cast<void**>(&dxvkDevice));
dxvkDevice->SetAPIVersion(10);
if (FAILED(d3d11Device->QueryInterface(
__uuidof(ID3D10Device), reinterpret_cast<void**>(ppDevice))))
return E_FAIL;
return S_OK;
}
UINT64 STDMETHODCALLTYPE D3D10CoreGetVersion() {
// Match the Windows 10 return value, but we
// don't know the exact function signature
return 0xa000100041770ull;
}
HRESULT STDMETHODCALLTYPE D3D10CoreRegisterLayers() {
return E_NOTIMPL;
}
}

View File

@ -110,10 +110,11 @@ namespace dxvk {
reinterpret_cast<const D3D11_SUBRESOURCE_DATA*>(pInitialData),
ppBuffer != nullptr ? &d3d11Buffer : nullptr);
if (hr != S_OK)
if (FAILED(hr) || hr == S_FALSE)
return hr;
*ppBuffer = static_cast<D3D11Buffer*>(d3d11Buffer)->GetD3D10Iface();
return S_OK;
}
@ -142,10 +143,11 @@ namespace dxvk {
reinterpret_cast<const D3D11_SUBRESOURCE_DATA*>(pInitialData),
ppTexture1D != nullptr ? &d3d11Texture1D : nullptr);
if (hr != S_OK)
if (FAILED(hr) || hr == S_FALSE)
return hr;
*ppTexture1D = static_cast<D3D11Texture1D*>(d3d11Texture1D)->GetD3D10Iface();
return S_OK;
}
@ -176,10 +178,11 @@ namespace dxvk {
reinterpret_cast<const D3D11_SUBRESOURCE_DATA*>(pInitialData),
ppTexture2D != nullptr ? &d3d11Texture2D : nullptr);
if (hr != S_OK)
if (FAILED(hr) || hr == S_FALSE)
return hr;
*ppTexture2D = static_cast<D3D11Texture2D*>(d3d11Texture2D)->GetD3D10Iface();
return S_OK;
}
@ -209,10 +212,11 @@ namespace dxvk {
reinterpret_cast<const D3D11_SUBRESOURCE_DATA*>(pInitialData),
ppTexture3D != nullptr ? &d3d11Texture3D : nullptr);
if (hr != S_OK)
if (FAILED(hr) || hr == S_FALSE)
return hr;
*ppTexture3D = static_cast<D3D11Texture3D*>(d3d11Texture3D)->GetD3D10Iface();
return S_OK;
}
@ -223,7 +227,7 @@ namespace dxvk {
ID3D10ShaderResourceView** ppSRView) {
InitReturnPtr(ppSRView);
if (!pResource)
if (pResource == nullptr)
return E_INVALIDARG;
Com<ID3D11Resource> d3d11Resource;
@ -234,10 +238,11 @@ namespace dxvk {
reinterpret_cast<const D3D11_SHADER_RESOURCE_VIEW_DESC*>(pDesc),
ppSRView ? &d3d11Srv : nullptr);
if (hr != S_OK)
if (FAILED(hr) || hr == S_FALSE)
return hr;
*ppSRView = static_cast<D3D11ShaderResourceView*>(d3d11Srv)->GetD3D10Iface();
return S_OK;
}
@ -248,7 +253,7 @@ namespace dxvk {
ID3D10ShaderResourceView1** ppSRView) {
InitReturnPtr(ppSRView);
if (!pResource)
if (pResource == nullptr)
return E_INVALIDARG;
Com<ID3D11Resource> d3d11Resource;
@ -259,10 +264,11 @@ namespace dxvk {
reinterpret_cast<const D3D11_SHADER_RESOURCE_VIEW_DESC*>(pDesc),
ppSRView ? &d3d11View : nullptr);
if (hr != S_OK)
if (FAILED(hr) || hr == S_FALSE)
return hr;
*ppSRView = static_cast<D3D11ShaderResourceView*>(d3d11View)->GetD3D10Iface();
return S_OK;
}
@ -273,7 +279,7 @@ namespace dxvk {
ID3D10RenderTargetView** ppRTView) {
InitReturnPtr(ppRTView);
if (!pResource)
if (pResource == nullptr)
return E_INVALIDARG;
Com<ID3D11Resource> d3d11Resource;
@ -284,10 +290,11 @@ namespace dxvk {
reinterpret_cast<const D3D11_RENDER_TARGET_VIEW_DESC*>(pDesc),
ppRTView ? &d3d11View : nullptr);
if (hr != S_OK)
if (FAILED(hr) || hr == S_FALSE)
return hr;
*ppRTView = static_cast<D3D11RenderTargetView*>(d3d11View)->GetD3D10Iface();
return S_OK;
}
@ -298,7 +305,7 @@ namespace dxvk {
ID3D10DepthStencilView** ppDepthStencilView) {
InitReturnPtr(ppDepthStencilView);
if (!pResource)
if (pResource == nullptr)
return E_INVALIDARG;
Com<ID3D11Resource> d3d11Resource;
@ -352,10 +359,11 @@ namespace dxvk {
d3d11Resource.ptr(), pDesc ? &d3d11Desc : nullptr,
ppDepthStencilView ? &d3d11View : nullptr);
if (hr != S_OK)
if (FAILED(hr) || hr == S_FALSE)
return hr;
*ppDepthStencilView = static_cast<D3D11DepthStencilView*>(d3d11View)->GetD3D10Iface();
return S_OK;
}
@ -377,10 +385,11 @@ namespace dxvk {
NumElements, pShaderBytecodeWithInputSignature, BytecodeLength,
ppInputLayout ? &d3d11InputLayout : nullptr);
if (hr != S_OK)
if (FAILED(hr) || hr == S_FALSE)
return hr;
*ppInputLayout = static_cast<D3D11InputLayout*>(d3d11InputLayout)->GetD3D10Iface();
return hr;
}
@ -397,10 +406,11 @@ namespace dxvk {
pShaderBytecode, BytecodeLength, nullptr,
ppVertexShader ? &d3d11Shader : nullptr);
if (hr != S_OK)
if (FAILED(hr) || hr == S_FALSE)
return hr;
*ppVertexShader = static_cast<D3D11VertexShader*>(d3d11Shader)->GetD3D10Iface();
return S_OK;
}
@ -417,10 +427,11 @@ namespace dxvk {
pShaderBytecode, BytecodeLength, nullptr,
ppGeometryShader ? &d3d11Shader : nullptr);
if (hr != S_OK)
if (FAILED(hr) || hr == S_FALSE)
return hr;
*ppGeometryShader = static_cast<D3D11GeometryShader*>(d3d11Shader)->GetD3D10Iface();
return S_OK;
}
@ -455,10 +466,11 @@ namespace dxvk {
D3D11_SO_NO_RASTERIZED_STREAM, nullptr,
ppGeometryShader ? &d3d11Shader : nullptr);
if (hr != S_OK)
if (FAILED(hr) || hr == S_FALSE)
return hr;
*ppGeometryShader = static_cast<D3D11GeometryShader*>(d3d11Shader)->GetD3D10Iface();
return S_OK;
}
@ -475,10 +487,11 @@ namespace dxvk {
pShaderBytecode, BytecodeLength, nullptr,
ppPixelShader ? &d3d11Shader : nullptr);
if (hr != S_OK)
if (FAILED(hr) || hr == S_FALSE)
return hr;
*ppPixelShader = static_cast<D3D11PixelShader*>(d3d11Shader)->GetD3D10Iface();
return S_OK;
}
@ -510,10 +523,11 @@ namespace dxvk {
HRESULT hr = m_device->CreateBlendState(&d3d11Desc,
ppBlendState ? &d3d11BlendState : nullptr);
if (hr != S_OK)
if (FAILED(hr) || hr == S_FALSE)
return hr;
*ppBlendState = static_cast<D3D11BlendState*>(d3d11BlendState)->GetD3D10Iface();
return S_OK;
}
@ -528,10 +542,11 @@ namespace dxvk {
reinterpret_cast<const D3D11_BLEND_DESC*>(pBlendStateDesc),
ppBlendState ? &d3d11BlendState : nullptr);
if (hr != S_OK)
if (FAILED(hr) || hr == S_FALSE)
return hr;
*ppBlendState = static_cast<D3D11BlendState*>(d3d11BlendState)->GetD3D10Iface();
return S_OK;
}
@ -546,10 +561,11 @@ namespace dxvk {
reinterpret_cast<const D3D11_DEPTH_STENCIL_DESC*>(pDepthStencilDesc),
ppDepthStencilState ? &d3d11DepthStencilState : nullptr);
if (hr != S_OK)
if (FAILED(hr) || hr == S_FALSE)
return hr;
*ppDepthStencilState = static_cast<D3D11DepthStencilState*>(d3d11DepthStencilState)->GetD3D10Iface();
return S_OK;
}
@ -564,10 +580,11 @@ namespace dxvk {
reinterpret_cast<const D3D11_RASTERIZER_DESC*>(pRasterizerDesc),
ppRasterizerState ? &d3d11RasterizerState : nullptr);
if (hr != S_OK)
if (FAILED(hr) || hr == S_FALSE)
return hr;
*ppRasterizerState = static_cast<D3D11RasterizerState*>(d3d11RasterizerState)->GetD3D10Iface();
return S_OK;
}
@ -598,10 +615,11 @@ namespace dxvk {
HRESULT hr = m_device->CreateSamplerState(&d3d11Desc,
ppSamplerState ? &d3d11SamplerState : nullptr);
if (hr != S_OK)
if (FAILED(hr) || hr == S_FALSE)
return hr;
*ppSamplerState = static_cast<D3D11SamplerState*>(d3d11SamplerState)->GetD3D10Iface();
return S_OK;
}
@ -622,10 +640,11 @@ namespace dxvk {
HRESULT hr = m_device->CreateQuery(&d3d11Desc,
ppQuery ? &d3d11Query : nullptr);
if (hr != S_OK)
if (FAILED(hr) || hr == S_FALSE)
return hr;
*ppQuery = static_cast<D3D11Query*>(d3d11Query)->GetD3D10Iface();
return S_OK;
}
@ -643,10 +662,11 @@ namespace dxvk {
HRESULT hr = m_device->CreatePredicate(&d3d11Desc,
ppPredicate ? &d3d11Predicate : nullptr);
if (hr != S_OK)
if (FAILED(hr) || hr == S_FALSE)
return hr;
*ppPredicate = D3D11Query::FromPredicate(d3d11Predicate)->GetD3D10Iface();
*ppPredicate = static_cast<D3D11Query*>(d3d11Predicate)->GetD3D10Iface();
return S_OK;
}
@ -705,7 +725,10 @@ namespace dxvk {
HANDLE hResource,
REFIID ReturnedInterface,
void** ppResource) {
return m_device->OpenSharedResource(hResource, ReturnedInterface, ppResource);
InitReturnPtr(ppResource);
Logger::err("D3D10Device::OpenSharedResource: Not implemented");
return E_NOTIMPL;
}
@ -737,7 +760,7 @@ namespace dxvk {
D3D10Query* d3d10Predicate = static_cast<D3D10Query*>(pPredicate);
D3D11Query* d3d11Predicate = d3d10Predicate ? d3d10Predicate->GetD3D11Iface() : nullptr;
m_context->SetPredication(D3D11Query::AsPredicate(d3d11Predicate), PredicateValue);
m_context->SetPredication(d3d11Predicate, PredicateValue);
}
@ -750,8 +773,8 @@ namespace dxvk {
ppPredicate ? &d3d11Predicate : nullptr,
pPredicateValue);
if (ppPredicate)
*ppPredicate = d3d11Predicate ? D3D11Query::FromPredicate(d3d11Predicate)->GetD3D10Iface() : nullptr;
if (ppPredicate != nullptr)
*ppPredicate = d3d11Predicate ? static_cast<D3D11Query*>(d3d11Predicate)->GetD3D10Iface() : nullptr;
}
@ -764,12 +787,9 @@ namespace dxvk {
ID3D10Resource* pSrcResource,
UINT SrcSubresource,
const D3D10_BOX* pSrcBox) {
if (!pDstResource || !pSrcResource)
return;
Com<ID3D11Resource> d3d11DstResource;
Com<ID3D11Resource> d3d11SrcResource;
GetD3D11Resource(pDstResource, &d3d11DstResource);
GetD3D11Resource(pSrcResource, &d3d11SrcResource);
@ -783,9 +803,6 @@ namespace dxvk {
void STDMETHODCALLTYPE D3D10Device::CopyResource(
ID3D10Resource* pDstResource,
ID3D10Resource* pSrcResource) {
if (!pDstResource || !pSrcResource)
return;
Com<ID3D11Resource> d3d11DstResource;
Com<ID3D11Resource> d3d11SrcResource;
@ -805,9 +822,6 @@ namespace dxvk {
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch) {
if (!pDstResource)
return;
Com<ID3D11Resource> d3d11DstResource;
GetD3D11Resource(pDstResource, &d3d11DstResource);
@ -833,9 +847,6 @@ namespace dxvk {
ID3D10Resource* pSrcResource,
UINT SrcSubresource,
DXGI_FORMAT Format) {
if (!pDstResource || !pSrcResource)
return;
Com<ID3D11Resource> d3d11DstResource;
Com<ID3D11Resource> d3d11SrcResource;
@ -955,9 +966,8 @@ namespace dxvk {
ID3D11InputLayout* d3d11InputLayout = nullptr;
m_context->IAGetInputLayout(&d3d11InputLayout);
*ppInputLayout = d3d11InputLayout
? static_cast<D3D11InputLayout*>(d3d11InputLayout)->GetD3D10Iface()
: nullptr;
*ppInputLayout = d3d11InputLayout ? static_cast<D3D11InputLayout*>(
d3d11InputLayout)->GetD3D10Iface() : nullptr;
}
@ -985,7 +995,7 @@ namespace dxvk {
ppVertexBuffers ? d3d11Buffers : nullptr,
pStrides, pOffsets);
if (ppVertexBuffers) {
if (ppVertexBuffers != nullptr) {
for (uint32_t i = 0; i < NumBuffers; i++) {
ppVertexBuffers[i] = d3d11Buffers[i]
? static_cast<D3D11Buffer*>(d3d11Buffers[i])->GetD3D10Iface()
@ -1005,7 +1015,7 @@ namespace dxvk {
pIndexBuffer ? &d3d11Buffer : nullptr,
Format, Offset);
if (pIndexBuffer)
if (pIndexBuffer != nullptr)
*pIndexBuffer = d3d11Buffer ? static_cast<D3D11Buffer*>(d3d11Buffer)->GetD3D10Iface() : nullptr;
}

View File

@ -1,9 +1,7 @@
#pragma once
#include "../dxgi/dxgi_include.h"
#include "../util/sync/sync_spinlock.h"
#include "../util/sync/sync_recursive.h"
#include <d3d10_1.h>
#include <d3d11_1.h>

361
src/d3d10/d3d10_main.cpp Normal file
View File

@ -0,0 +1,361 @@
#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 D3D11CoreCreateDevice(
IDXGIFactory* pFactory,
IDXGIAdapter* pAdapter,
UINT Flags,
const D3D_FEATURE_LEVEL* pFeatureLevels,
UINT FeatureLevels,
ID3D11Device** ppDevice);
DLLEXPORT HRESULT __stdcall D3D10CoreCreateDevice(
IDXGIFactory* pFactory,
IDXGIAdapter* pAdapter,
UINT Flags,
D3D_FEATURE_LEVEL FeatureLevel,
ID3D10Device** ppDevice) {
InitReturnPtr(ppDevice);
Com<ID3D11Device> d3d11Device;
HRESULT hr = pAdapter->CheckInterfaceSupport(
__uuidof(ID3D10Device), nullptr);
if (FAILED(hr))
return hr;
hr = D3D11CoreCreateDevice(pFactory, pAdapter,
Flags, &FeatureLevel, 1, &d3d11Device);
if (FAILED(hr))
return hr;
Com<ID3D10Multithread> multithread;
d3d11Device->QueryInterface(__uuidof(ID3D10Multithread), reinterpret_cast<void**>(&multithread));
multithread->SetMultithreadProtected(!(Flags & D3D10_CREATE_DEVICE_SINGLETHREADED));
if (FAILED(d3d11Device->QueryInterface(
__uuidof(ID3D10Device), reinterpret_cast<void**>(ppDevice))))
return E_FAIL;
return S_OK;
}
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);
}
}

View File

@ -1,17 +1,44 @@
#include <utility>
#include "d3d10_device.h"
namespace dxvk {
void D3D10DeviceMutex::lock() {
while (!try_lock())
dxvk::this_thread::yield();
}
void D3D10DeviceMutex::unlock() {
if (likely(m_counter == 0))
m_owner.store(0, std::memory_order_release);
else
m_counter -= 1;
}
bool D3D10DeviceMutex::try_lock() {
uint32_t threadId = GetCurrentThreadId();
uint32_t expected = 0;
bool status = m_owner.compare_exchange_weak(
expected, threadId, std::memory_order_acquire);
if (status)
return true;
if (expected != threadId)
return false;
m_counter += 1;
return true;
}
D3D10Multithread::D3D10Multithread(
IUnknown* pParent,
BOOL Protected,
BOOL Force)
BOOL Protected)
: m_parent (pParent),
m_protected (Protected || Force),
m_enabled (Protected),
m_forced (Force) {
m_protected (Protected) {
}
@ -52,18 +79,12 @@ namespace dxvk {
BOOL STDMETHODCALLTYPE D3D10Multithread::SetMultithreadProtected(
BOOL bMTProtect) {
BOOL result = m_enabled;
m_enabled = bMTProtect;
if (!m_forced)
m_protected = m_enabled;
return result;
return std::exchange(m_protected, bMTProtect);
}
BOOL STDMETHODCALLTYPE D3D10Multithread::GetMultithreadProtected() {
return m_enabled;
return m_protected;
}
}
}

View File

@ -4,6 +4,30 @@
namespace dxvk {
/**
* \brief Device mutex
*
* Effectively implements a recursive spinlock
* which is used to lock the D3D10 device.
*/
class D3D10DeviceMutex {
public:
void lock();
void unlock();
bool try_lock();
private:
std::atomic<uint32_t> m_owner = { 0u };
uint32_t m_counter = { 0u };
};
/**
* \brief Device lock
*
@ -19,7 +43,7 @@ namespace dxvk {
D3D10DeviceLock()
: m_mutex(nullptr) { }
D3D10DeviceLock(sync::RecursiveSpinlock& mutex)
D3D10DeviceLock(D3D10DeviceMutex& mutex)
: m_mutex(&mutex) {
mutex.lock();
}
@ -45,7 +69,7 @@ namespace dxvk {
private:
sync::RecursiveSpinlock* m_mutex;
D3D10DeviceMutex* m_mutex;
};
@ -64,8 +88,7 @@ namespace dxvk {
D3D10Multithread(
IUnknown* pParent,
BOOL Protected,
BOOL Force);
BOOL Protected);
~D3D10Multithread();
@ -96,10 +119,8 @@ namespace dxvk {
IUnknown* m_parent;
BOOL m_protected;
BOOL m_enabled;
BOOL m_forced;
sync::RecursiveSpinlock m_mutex;
D3D10DeviceMutex m_mutex;
};

View File

@ -6,14 +6,15 @@ namespace dxvk {
class D3D10Device;
class D3D11Device;
class D3D11DeviceContext;
class D3D11Query;
class D3D10Query : public ID3D10Predicate {
public:
D3D10Query(D3D11Query* pParent)
: m_d3d11(pParent) { }
D3D10Query(D3D11Query* pParent, D3D10Device* pDevice)
: m_device(pDevice), m_d3d11(pParent) { }
HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid,
@ -60,6 +61,7 @@ namespace dxvk {
private:
D3D10Device* m_device;
D3D11Query* m_d3d11;
};

View File

@ -0,0 +1,319 @@
#include "d3d10_reflection.h"
namespace dxvk {
D3D10ShaderReflectionType::D3D10ShaderReflectionType(
ID3D11ShaderReflectionType* d3d11)
: m_d3d11(d3d11) {
D3D11_SHADER_TYPE_DESC d3d11Desc;
m_d3d11->GetDesc(&d3d11Desc);
for (uint32_t i = 0; i < d3d11Desc.Members; i++)
m_members.emplace_back(m_d3d11->GetMemberTypeByIndex(i));
}
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) {
for (size_t i = 0; i < m_members.size(); i++) {
if (m_members[i].GetD3D11Iface() == pMemberType)
return &m_members[i];
}
return nullptr;
}
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) {
D3D11_SHADER_BUFFER_DESC d3d11Desc;
m_d3d11->GetDesc(&d3d11Desc);
for (uint32_t i = 0; i < d3d11Desc.Variables; i++)
m_variables.emplace_back(m_d3d11->GetVariableByIndex(i));
}
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) {
for (size_t i = 0; i < m_variables.size(); i++) {
if (m_variables[i].GetD3D11Iface() == pVariable)
return &m_variables[i];
}
return nullptr;
}
D3D10ShaderReflection::D3D10ShaderReflection(ID3D11ShaderReflection* d3d11)
: m_d3d11(d3d11) {
D3D11_SHADER_DESC d3d11Desc;
m_d3d11->GetDesc(&d3d11Desc);
for (uint32_t i = 0; i < d3d11Desc.ConstantBuffers; i++)
m_constantBuffers.emplace_back(m_d3d11->GetConstantBufferByIndex(i));
}
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) {
for (size_t i = 0; i < m_constantBuffers.size(); i++) {
if (m_constantBuffers[i].GetD3D11Iface() == pConstantBuffer)
return &m_constantBuffers[i];
}
return nullptr;
}
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

@ -0,0 +1,155 @@
#pragma once
#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::vector<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::vector<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::vector<D3D10ShaderReflectionConstantBuffer> m_constantBuffers;
ID3D10ShaderReflectionConstantBuffer* FindConstantBuffer(
ID3D11ShaderReflectionConstantBuffer* pConstantBuffer);
void ConvertSignatureParameterDesc(
const D3D11_SIGNATURE_PARAMETER_DESC* pSrcDesc,
D3D10_SIGNATURE_PARAMETER_DESC* pDstDesc);
};
}

View File

@ -0,0 +1,435 @@
#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),
}};
// MinGW fails on __uuidof(ID3D10StateBlock), winelib builds fail to link
const GUID D3D10StateBlock::guid = {0x0803425a,0x57f5,0x4dd6,{0x94,0x65,0xa8,0x75,0x70,0x83,0x4a,0x08}};
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 == D3D10StateBlock::guid) {
*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

@ -0,0 +1,83 @@
#pragma once
#include "d3d10_include.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:
static const GUID guid;
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);
};
}

View File

@ -111,7 +111,7 @@ namespace dxvk {
pDesc->ArraySize = d3d11Desc.ArraySize;
pDesc->Format = d3d11Desc.Format;
pDesc->Usage = D3D10_USAGE(d3d11Desc.Usage);
pDesc->BindFlags = d3d11Desc.BindFlags;
pDesc->BindFlags = d3d11Desc.BindFlags & 0x7F;
pDesc->CPUAccessFlags = d3d11Desc.CPUAccessFlags;
pDesc->MiscFlags = ConvertD3D11ResourceFlags(d3d11Desc.MiscFlags);
}
@ -224,7 +224,7 @@ namespace dxvk {
pDesc->Format = d3d11Desc.Format;
pDesc->SampleDesc = d3d11Desc.SampleDesc;
pDesc->Usage = D3D10_USAGE(d3d11Desc.Usage);
pDesc->BindFlags = d3d11Desc.BindFlags;
pDesc->BindFlags = d3d11Desc.BindFlags & 0x7F;
pDesc->CPUAccessFlags = d3d11Desc.CPUAccessFlags;
pDesc->MiscFlags = ConvertD3D11ResourceFlags(d3d11Desc.MiscFlags);
}
@ -337,7 +337,7 @@ namespace dxvk {
pDesc->MipLevels = d3d11Desc.MipLevels;
pDesc->Format = d3d11Desc.Format;
pDesc->Usage = D3D10_USAGE(d3d11Desc.Usage);
pDesc->BindFlags = d3d11Desc.BindFlags;
pDesc->BindFlags = d3d11Desc.BindFlags & 0x7F;
pDesc->CPUAccessFlags = d3d11Desc.CPUAccessFlags;
pDesc->MiscFlags = ConvertD3D11ResourceFlags(d3d11Desc.MiscFlags);
}

View File

@ -16,8 +16,8 @@ namespace dxvk {
public:
D3D10Texture1D(D3D11Texture1D* pParent)
: m_d3d11(pParent) { }
D3D10Texture1D(D3D11Texture1D* pParent, D3D10Device* pDevice)
: m_device(pDevice), m_d3d11(pParent) { }
HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid,
@ -70,6 +70,7 @@ namespace dxvk {
private:
D3D10Device* m_device;
D3D11Texture1D* m_d3d11;
};
@ -81,8 +82,8 @@ namespace dxvk {
public:
D3D10Texture2D(D3D11Texture2D* pParent)
: m_d3d11(pParent) { }
D3D10Texture2D(D3D11Texture2D* pParent, D3D10Device* pDevice)
: m_device(pDevice), m_d3d11(pParent) { }
HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid,
@ -135,6 +136,7 @@ namespace dxvk {
private:
D3D10Device* m_device;
D3D11Texture2D* m_d3d11;
};
@ -146,8 +148,8 @@ namespace dxvk {
public:
D3D10Texture3D(D3D11Texture3D* pParent)
: m_d3d11(pParent) { }
D3D10Texture3D(D3D11Texture3D* pParent, D3D10Device* pDevice)
: m_device(pDevice), m_d3d11(pParent) { }
HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid,
@ -200,6 +202,7 @@ namespace dxvk {
private:
D3D10Device* m_device;
D3D11Texture3D* m_d3d11;
};

View File

@ -1,5 +1,3 @@
LIBRARY D3D10CORE.DLL
EXPORTS
D3D10CoreCreateDevice
D3D10CoreGetVersion
D3D10CoreRegisterLayers

1
src/d3d10/d3d10core.spec Normal file
View File

@ -0,0 +1 @@
@ stdcall D3D10CoreCreateDevice(ptr ptr long long ptr)

View File

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

View File

@ -1,37 +1,43 @@
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 = []
d3d10_deps = [ lib_d3dcompiler_43, lib_dxgi ]
d3d10_deps += dxvk_winelib ? lib_d3d11 : d3d11_dep
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(dxvk_name_prefix+'d3d10core', d3d10_core_src, d3d10_core_res,
dependencies : [ d3d10_d3d11_dep ],
d3d10_core_dll = shared_library('d3d10core'+dll_ext, d3d10_main_src, d3d10_core_res,
name_prefix : '',
dependencies : [ d3d10_deps, dxbc_dep, dxvk_dep ],
include_directories : dxvk_include_path,
install : true,
objects : not dxvk_msvc ? 'd3d10core'+def_spec_ext : [],
vs_module_defs : 'd3d10core'+def_spec_ext,
link_args : d3d10_core_ld_args,
link_depends : [ d3d10_core_link_depends ],
kwargs : dxvk_so_version,
)
override_options : ['cpp_std='+dxvk_cpp_std])
d3d10_core_dep = declare_dependency(
link_with : [ d3d10_core_dll ],
)
d3d10_dll = shared_library('d3d10'+dll_ext, d3d10_main_src, d3d10_res,
name_prefix : '',
dependencies : [ d3d10_deps, dxbc_dep, dxvk_dep ],
include_directories : dxvk_include_path,
install : true,
objects : not dxvk_msvc ? 'd3d10'+def_spec_ext : [],
vs_module_defs : 'd3d10'+def_spec_ext,
override_options : ['cpp_std='+dxvk_cpp_std])
if platform != 'windows'
pkg.generate(d3d10_core_dll,
filebase: dxvk_pkg_prefix + 'd3d10core',
subdirs: 'dxvk',
)
endif
d3d10_1_dll = shared_library('d3d10_1'+dll_ext, d3d10_main_src, d3d10_1_res,
name_prefix : '',
dependencies : [ d3d10_deps, dxbc_dep, dxvk_dep ],
include_directories : dxvk_include_path,
install : true,
objects : not dxvk_msvc ? 'd3d10_1'+def_spec_ext : [],
vs_module_defs : 'd3d10_1'+def_spec_ext,
override_options : ['cpp_std='+dxvk_cpp_std])
d3d10_dep = declare_dependency(
link_with : [ d3d10_dll, d3d10_1_dll, d3d10_core_dll ],
include_directories : [ dxvk_include_path ])

View File

@ -15,11 +15,11 @@ BEGIN
BLOCK "080904b0"
BEGIN
VALUE "CompanyName", "DXVK"
VALUE "FileDescription", "Direct3D 9 Runtime"
VALUE "FileDescription", "Direct3D 10 Runtime"
VALUE "FileVersion", "10.0.17763.1 (WinBuild.160101.0800)"
VALUE "InternalName", "D3D9.dll"
VALUE "InternalName", "D3D10.dll"
VALUE "LegalCopyright", "zlib/libpng license"
VALUE "OriginalFilename", "D3D9.dll"
VALUE "OriginalFilename", "D3D10.dll"
VALUE "ProductName", "DXVK"
VALUE "ProductVersion", "10.0.17763.1"
END
@ -29,3 +29,4 @@ BEGIN
VALUE "Translation", 0x0809, 1200
END
END

32
src/d3d10/version10_1.rc Normal file
View File

@ -0,0 +1,32 @@
#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

View File

@ -1,6 +1,5 @@
LIBRARY D3D11.DLL
EXPORTS
D3D11CoreCreateDevice @18
D3D11CreateDevice @22
D3D11CreateDeviceAndSwapChain @23
D3D11On12CreateDevice @24
D3D11CoreCreateDevice
D3D11CreateDevice
D3D11CreateDeviceAndSwapChain

3
src/d3d11/d3d11.spec Normal file
View File

@ -0,0 +1,3 @@
@ stdcall D3D11CreateDevice(ptr long ptr long ptr long long ptr ptr ptr)
@ stdcall D3D11CreateDeviceAndSwapChain(ptr long ptr long ptr long long ptr ptr ptr ptr ptr)
@ stdcall D3D11CoreCreateDevice(ptr ptr long ptr long ptr)

View File

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

View File

@ -1,142 +1,55 @@
#include "d3d11_annotation.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 {
template <bool Register>
static void RegisterUserDefinedAnnotation(IDXVKUserDefinedAnnotation* annotation) {
using RegistrationFunctionType = void(__stdcall *)(IDXVKUserDefinedAnnotation*);
static const int16_t RegisterOrdinal = 28257;
static const int16_t UnregisterOrdinal = 28258;
D3D11UserDefinedAnnotation::D3D11UserDefinedAnnotation(ID3D11DeviceContext* ctx)
: m_container(ctx) { }
HMODULE d3d9Module = ::LoadLibraryA("d3d9.dll");
if (!d3d9Module) {
Logger::info("Unable to find d3d9, some annotations may be missed.");
return;
}
const int16_t ordinal = Register ? RegisterOrdinal : UnregisterOrdinal;
auto registrationFunction = reinterpret_cast<RegistrationFunctionType>(::GetProcAddress(d3d9Module,
reinterpret_cast<const char*>(static_cast<uintptr_t>(ordinal))));
D3D11UserDefinedAnnotation::~D3D11UserDefinedAnnotation() {
if (!registrationFunction) {
Logger::info("Unable to find DXVK_RegisterAnnotation, some annotations may be missed.");
return;
}
registrationFunction(annotation);
}
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);
}
template<typename ContextType>
D3D11UserDefinedAnnotation<ContextType>::~D3D11UserDefinedAnnotation() {
if (!IsDeferred && m_annotationsEnabled)
RegisterUserDefinedAnnotation<false>(this);
}
template<typename ContextType>
ULONG STDMETHODCALLTYPE D3D11UserDefinedAnnotation<ContextType>::AddRef() {
ULONG STDMETHODCALLTYPE D3D11UserDefinedAnnotation::AddRef() {
return m_container->AddRef();
}
template<typename ContextType>
ULONG STDMETHODCALLTYPE D3D11UserDefinedAnnotation<ContextType>::Release() {
ULONG STDMETHODCALLTYPE D3D11UserDefinedAnnotation::Release() {
return m_container->Release();
}
template<typename ContextType>
HRESULT STDMETHODCALLTYPE D3D11UserDefinedAnnotation<ContextType>::QueryInterface(
HRESULT STDMETHODCALLTYPE D3D11UserDefinedAnnotation::QueryInterface(
REFIID riid,
void** ppvObject) {
return m_container->QueryInterface(riid, ppvObject);
}
template<typename ContextType>
INT STDMETHODCALLTYPE D3D11UserDefinedAnnotation<ContextType>::BeginEvent(
D3DCOLOR Color,
INT STDMETHODCALLTYPE D3D11UserDefinedAnnotation::BeginEvent(
LPCWSTR Name) {
if (!m_annotationsEnabled)
return -1;
D3D10DeviceLock lock = m_container->LockContext();
m_container->EmitCs([color = Color, labelName = dxvk::str::fromws(Name)](DxvkContext *ctx) {
VkDebugUtilsLabelEXT label;
label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
label.pNext = nullptr;
label.pLabelName = labelName.c_str();
DecodeD3DCOLOR(color, label.color);
ctx->beginDebugLabel(&label);
});
return m_eventDepth++;
// Currently not implemented
return -1;
}
template<typename ContextType>
INT STDMETHODCALLTYPE D3D11UserDefinedAnnotation<ContextType>::EndEvent() {
if (!m_annotationsEnabled)
return -1;
D3D10DeviceLock lock = m_container->LockContext();
m_container->EmitCs([](DxvkContext *ctx) {
ctx->endDebugLabel();
});
return m_eventDepth--;
INT STDMETHODCALLTYPE D3D11UserDefinedAnnotation::EndEvent() {
// Currently not implemented
return -1;
}
template<typename ContextType>
void STDMETHODCALLTYPE D3D11UserDefinedAnnotation<ContextType>::SetMarker(
D3DCOLOR Color,
void STDMETHODCALLTYPE D3D11UserDefinedAnnotation::SetMarker(
LPCWSTR Name) {
if (!m_annotationsEnabled)
return;
D3D10DeviceLock lock = m_container->LockContext();
m_container->EmitCs([color = Color, labelName = dxvk::str::fromws(Name)](DxvkContext *ctx) {
VkDebugUtilsLabelEXT label;
label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
label.pNext = nullptr;
label.pLabelName = labelName.c_str();
DecodeD3DCOLOR(color, label.color);
ctx->insertDebugLabel(&label);
});
// Currently not implemented
}
template<typename ContextType>
BOOL STDMETHODCALLTYPE D3D11UserDefinedAnnotation<ContextType>::GetStatus() {
return m_annotationsEnabled;
BOOL STDMETHODCALLTYPE D3D11UserDefinedAnnotation::GetStatus() {
// Currently not implemented
return FALSE;
}
template class D3D11UserDefinedAnnotation<D3D11DeferredContext>;
template class D3D11UserDefinedAnnotation<D3D11ImmediateContext>;
}
}

View File

@ -1,31 +1,16 @@
#pragma once
#include <type_traits>
#include "d3d11_include.h"
#include "../dxvk/dxvk_annotation.h"
#include "../dxvk/dxvk_device.h"
namespace dxvk {
class D3D11DeferredContext;
class D3D11ImmediateContext;
class D3D11UserDefinedAnnotation : ID3DUserDefinedAnnotation {
template<typename ContextType>
class D3D11UserDefinedAnnotation final : public IDXVKUserDefinedAnnotation {
constexpr static bool IsDeferred = std::is_same_v<ContextType, D3D11DeferredContext>;
public:
D3D11UserDefinedAnnotation(
ContextType* container,
const Rc<DxvkDevice>& dxvkDevice);
D3D11UserDefinedAnnotation(ID3D11DeviceContext* ctx);
~D3D11UserDefinedAnnotation();
D3D11UserDefinedAnnotation (const D3D11UserDefinedAnnotation&) = delete;
D3D11UserDefinedAnnotation& operator = (const D3D11UserDefinedAnnotation&) = delete;
ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
@ -35,22 +20,19 @@ namespace dxvk {
void** ppvObject);
INT STDMETHODCALLTYPE BeginEvent(
D3DCOLOR Color,
LPCWSTR Name);
INT STDMETHODCALLTYPE EndEvent();
void STDMETHODCALLTYPE SetMarker(
D3DCOLOR Color,
LPCWSTR Name);
BOOL STDMETHODCALLTYPE GetStatus();
private:
ContextType* m_container;
int32_t m_eventDepth;
bool m_annotationsEnabled;
ID3D11DeviceContext* m_container;
};
}
}

View File

@ -6,8 +6,7 @@ namespace dxvk {
D3D11BlendState::D3D11BlendState(
D3D11Device* device,
const D3D11_BLEND_DESC1& desc)
: D3D11StateObject<ID3D11BlendState1>(device),
m_desc(desc), m_d3d10(this) {
: m_device(device), m_desc(desc), m_d3d10(this) {
// If Independent Blend is disabled, we must ignore the
// blend modes for render target 1 to 7. In Vulkan, all
// blend modes need to be identical in that case.
@ -35,8 +34,8 @@ namespace dxvk {
D3D11BlendState::~D3D11BlendState() {
}
HRESULT STDMETHODCALLTYPE D3D11BlendState::QueryInterface(REFIID riid, void** ppvObject) {
if (ppvObject == nullptr)
return E_POINTER;
@ -58,15 +57,17 @@ namespace dxvk {
return S_OK;
}
if (logQueryInterfaceError(__uuidof(ID3D11BlendState), riid)) {
Logger::warn("D3D11BlendState::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
}
Logger::warn("D3D11BlendState::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
return E_NOINTERFACE;
}
void STDMETHODCALLTYPE D3D11BlendState::GetDevice(ID3D11Device** ppDevice) {
*ppDevice = ref(m_device);
}
void STDMETHODCALLTYPE D3D11BlendState::GetDesc(D3D11_BLEND_DESC* pDesc) {
pDesc->AlphaToCoverageEnable = m_desc.AlphaToCoverageEnable;
pDesc->IndependentBlendEnable = m_desc.IndependentBlendEnable;
@ -90,7 +91,7 @@ namespace dxvk {
void D3D11BlendState::BindToContext(
DxvkContext* ctx,
const Rc<DxvkContext>& ctx,
uint32_t sampleMask) const {
// We handled Independent Blend during object creation
// already, so if it is disabled, all elements in the
@ -108,6 +109,31 @@ namespace dxvk {
}
D3D11_BLEND_DESC1 D3D11BlendState::DefaultDesc() {
D3D11_BLEND_DESC1 dstDesc;
dstDesc.AlphaToCoverageEnable = FALSE;
dstDesc.IndependentBlendEnable = FALSE;
// 1-7 must be ignored if IndependentBlendEnable is disabled so
// technically this is not needed, but since this structure is
// going to be copied around we'll initialize it nonetheless
for (uint32_t i = 0; i < 8; i++) {
dstDesc.RenderTarget[i].BlendEnable = FALSE;
dstDesc.RenderTarget[i].LogicOpEnable = FALSE;
dstDesc.RenderTarget[i].SrcBlend = D3D11_BLEND_ONE;
dstDesc.RenderTarget[i].DestBlend = D3D11_BLEND_ZERO;
dstDesc.RenderTarget[i].BlendOp = D3D11_BLEND_OP_ADD;
dstDesc.RenderTarget[i].SrcBlendAlpha = D3D11_BLEND_ONE;
dstDesc.RenderTarget[i].DestBlendAlpha = D3D11_BLEND_ZERO;
dstDesc.RenderTarget[i].BlendOpAlpha = D3D11_BLEND_OP_ADD;
dstDesc.RenderTarget[i].LogicOp = D3D11_LOGIC_OP_NOOP;
dstDesc.RenderTarget[i].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
}
return dstDesc;
}
D3D11_BLEND_DESC1 D3D11BlendState::PromoteDesc(const D3D11_BLEND_DESC* pSrcDesc) {
D3D11_BLEND_DESC1 dstDesc;
dstDesc.AlphaToCoverageEnable = pSrcDesc->AlphaToCoverageEnable;
@ -131,6 +157,8 @@ namespace dxvk {
HRESULT D3D11BlendState::NormalizeDesc(D3D11_BLEND_DESC1* pDesc) {
const D3D11_BLEND_DESC1 defaultDesc = DefaultDesc();
if (pDesc->AlphaToCoverageEnable)
pDesc->AlphaToCoverageEnable = TRUE;
@ -154,12 +182,12 @@ namespace dxvk {
rt->BlendOp, rt->BlendOpAlpha))
return E_INVALIDARG;
} else {
rt->SrcBlend = D3D11_BLEND_ONE;
rt->DestBlend = D3D11_BLEND_ZERO;
rt->BlendOp = D3D11_BLEND_OP_ADD;
rt->SrcBlendAlpha = D3D11_BLEND_ONE;
rt->DestBlendAlpha = D3D11_BLEND_ZERO;
rt->BlendOpAlpha = D3D11_BLEND_OP_ADD;
rt->SrcBlend = defaultDesc.RenderTarget[0].SrcBlend;
rt->DestBlend = defaultDesc.RenderTarget[0].DestBlend;
rt->BlendOp = defaultDesc.RenderTarget[0].BlendOp;
rt->SrcBlendAlpha = defaultDesc.RenderTarget[0].SrcBlendAlpha;
rt->DestBlendAlpha = defaultDesc.RenderTarget[0].DestBlendAlpha;
rt->BlendOpAlpha = defaultDesc.RenderTarget[0].BlendOpAlpha;
}
if (rt->LogicOpEnable) {
@ -172,7 +200,7 @@ namespace dxvk {
|| !ValidateLogicOp(rt->LogicOp))
return E_INVALIDARG;
} else {
rt->LogicOp = D3D11_LOGIC_OP_NOOP;
rt->LogicOp = defaultDesc.RenderTarget[0].LogicOp;
}
if (rt->RenderTargetWriteMask > D3D11_COLOR_WRITE_ENABLE_ALL)

View File

@ -11,7 +11,7 @@ namespace dxvk {
class D3D11Device;
class D3D11BlendState : public D3D11StateObject<ID3D11BlendState1> {
class D3D11BlendState : public D3D11DeviceChild<ID3D11BlendState1> {
public:
@ -21,11 +21,14 @@ namespace dxvk {
D3D11Device* device,
const D3D11_BLEND_DESC1& desc);
~D3D11BlendState();
HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid,
void** ppvObject) final;
void STDMETHODCALLTYPE GetDevice(
ID3D11Device **ppDevice) final;
void STDMETHODCALLTYPE GetDesc(
D3D11_BLEND_DESC* pDesc) final;
@ -33,13 +36,15 @@ namespace dxvk {
D3D11_BLEND_DESC1* pDesc) final;
void BindToContext(
DxvkContext* ctx,
const Rc<DxvkContext>& ctx,
UINT sampleMask) const;
D3D10BlendState* GetD3D10Iface() {
return &m_d3d10;
}
static D3D11_BLEND_DESC1 DefaultDesc();
static D3D11_BLEND_DESC1 PromoteDesc(
const D3D11_BLEND_DESC* pSrcDesc);
@ -48,6 +53,7 @@ namespace dxvk {
private:
D3D11Device* const m_device;
D3D11_BLEND_DESC1 m_desc;
std::array<DxvkBlendMode, 8> m_blendModes;

View File

@ -8,14 +8,12 @@ namespace dxvk {
D3D11Buffer::D3D11Buffer(
D3D11Device* pDevice,
const D3D11_BUFFER_DESC* pDesc,
const D3D11_ON_12_RESOURCE_INFO* p11on12Info)
: D3D11DeviceChild<ID3D11Buffer>(pDevice),
const D3D11_BUFFER_DESC* pDesc)
: m_device (pDevice),
m_desc (*pDesc),
m_resource (this, pDevice),
m_d3d10 (this) {
DxvkBufferCreateInfo info;
info.flags = 0;
m_resource (this),
m_d3d10 (this, pDevice->GetD3D10Interface()) {
DxvkBufferCreateInfo info;
info.size = pDesc->ByteWidth;
info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
| VK_BUFFER_USAGE_TRANSFER_DST_BIT;
@ -37,14 +35,13 @@ namespace dxvk {
if (pDesc->BindFlags & D3D11_BIND_CONSTANT_BUFFER) {
info.usage |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
info.stages |= m_parent->GetEnabledShaderStages();
info.stages |= m_device->GetEnabledShaderStages();
info.access |= VK_ACCESS_UNIFORM_READ_BIT;
}
if (pDesc->BindFlags & D3D11_BIND_SHADER_RESOURCE) {
info.usage |= VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
| VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
info.stages |= m_parent->GetEnabledShaderStages();
info.usage |= VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
info.stages |= m_device->GetEnabledShaderStages();
info.access |= VK_ACCESS_SHADER_READ_BIT;
}
@ -55,73 +52,64 @@ namespace dxvk {
}
if (pDesc->BindFlags & D3D11_BIND_UNORDERED_ACCESS) {
info.usage |= VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT
| VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
info.stages |= m_parent->GetEnabledShaderStages();
info.usage |= VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
info.stages |= m_device->GetEnabledShaderStages();
info.access |= VK_ACCESS_SHADER_READ_BIT
| VK_ACCESS_SHADER_WRITE_BIT;
}
if (pDesc->CPUAccessFlags & D3D11_CPU_ACCESS_WRITE) {
info.stages |= VK_PIPELINE_STAGE_HOST_BIT;
info.access |= VK_ACCESS_HOST_WRITE_BIT;
}
if (pDesc->CPUAccessFlags & D3D11_CPU_ACCESS_READ) {
info.stages |= VK_PIPELINE_STAGE_HOST_BIT;
info.access |= VK_ACCESS_HOST_READ_BIT;
}
if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS) {
info.usage |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
info.stages |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
info.access |= VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
}
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;
}
if (pDesc->MiscFlags & (
D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS |
D3D11_RESOURCE_MISC_BUFFER_STRUCTURED))
info.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
// Default constant buffers may get updated frequently, in which
// case mapping the buffer is faster than using update commands.
VkMemoryPropertyFlags memoryFlags = GetMemoryFlagsForUsage(pDesc->Usage);
// 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) {
if ((pDesc->Usage == D3D11_USAGE_DEFAULT) && (pDesc->BindFlags & D3D11_BIND_CONSTANT_BUFFER)) {
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;
info.access |= VK_ACCESS_HOST_WRITE_BIT;
memoryFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
}
// AMD cards have a device-local, host-visible memory type where
// we can put dynamic resources that need fast access by the GPU
if (pDesc->Usage == D3D11_USAGE_DYNAMIC && pDesc->BindFlags)
memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_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;
}
// 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_device->GetDXVKDevice()->createBuffer(info, memoryFlags);
m_mapped = m_buffer->getSliceHandle();
// For Stream Output buffers we need a counter
if (pDesc->BindFlags & D3D11_BIND_STREAM_OUTPUT)
m_soCounter = CreateSoCounterBuffer();
m_soCounter = m_device->AllocXfbCounterSlice();
}
D3D11Buffer::~D3D11Buffer() {
if (m_desc.CPUAccessFlags && m_11on12.Resource != nullptr)
m_11on12.Resource->Unmap(0, nullptr);
if (m_soCounter.defined())
m_device->FreeXfbCounterSlice(m_soCounter);
}
@ -154,15 +142,17 @@ namespace dxvk {
return S_OK;
}
if (logQueryInterfaceError(__uuidof(ID3D11Buffer), riid)) {
Logger::warn("D3D11Buffer::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
}
Logger::warn("D3D11Buffer::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
return E_NOINTERFACE;
}
void STDMETHODCALLTYPE D3D11Buffer::GetDevice(ID3D11Device** ppDevice) {
*ppDevice = m_device.ref();
}
UINT STDMETHODCALLTYPE D3D11Buffer::GetEvictionPriority() {
return DXGI_RESOURCE_PRIORITY_NORMAL;
}
@ -190,7 +180,9 @@ namespace dxvk {
UINT BindFlags,
DXGI_FORMAT Format) const {
// Check whether the given bind flags are supported
if ((m_desc.BindFlags & BindFlags) != BindFlags)
VkBufferUsageFlags usage = GetBufferUsageFlags(BindFlags);
if ((m_buffer->info().usage & usage) != usage)
return false;
// Structured buffer views use no format
@ -199,180 +191,34 @@ 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);
VkFormatFeatureFlags2 features = GetBufferFormatFeatures(BindFlags);
DXGI_VK_FORMAT_INFO viewFormat = m_device->LookupFormat(Format, DXGI_VK_FORMAT_MODE_ANY);
VkFormatFeatureFlags features = GetBufferFormatFeatures(BindFlags);
return CheckFormatFeatureSupport(viewFormat.Format, features);
}
HRESULT D3D11Buffer::NormalizeBufferProperties(D3D11_BUFFER_DESC* pDesc) {
// Zero-sized buffers are illegal
if (!pDesc->ByteWidth && !(pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL))
return E_INVALIDARG;
// Constant buffer size must be a multiple of 16
if ((pDesc->BindFlags & D3D11_BIND_CONSTANT_BUFFER)
&& (pDesc->ByteWidth & 0xF))
return E_INVALIDARG;
HRESULT D3D11Buffer::ValidateBufferProperties(
const D3D11_BUFFER_DESC* pDesc) {
// Basic validation for structured buffers
if ((pDesc->MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED)
&& ((pDesc->MiscFlags & D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS)
|| (pDesc->StructureByteStride == 0)
&& ((pDesc->StructureByteStride == 0)
|| (pDesc->StructureByteStride & 0x3)))
return E_INVALIDARG;
// Basic validation for raw buffers
if ((pDesc->MiscFlags & D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS)
&& (!(pDesc->BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS))))
return E_INVALIDARG;
// 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;
return S_OK;
}
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,
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;
break;
case D3D11_USAGE_DEFAULT:
memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
if ((m_desc.BindFlags & D3D11_BIND_CONSTANT_BUFFER) || m_desc.CPUAccessFlags) {
memoryFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
}
if (m_desc.CPUAccessFlags & D3D11_CPU_ACCESS_READ) {
memoryFlags |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
memoryFlags &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
}
break;
case D3D11_USAGE_DYNAMIC:
memoryFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
if (m_desc.BindFlags)
memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
break;
case D3D11_USAGE_STAGING:
memoryFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
| VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
break;
}
bool useCached = (m_parent->GetOptions()->cachedDynamicResources == ~0u)
|| (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;
}
return memoryFlags;
}
Rc<DxvkBuffer> D3D11Buffer::CreateSoCounterBuffer() {
Rc<DxvkDevice> device = m_parent->GetDXVKDevice();
DxvkBufferCreateInfo info;
info.size = sizeof(D3D11SOCounter);
info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT
| VK_BUFFER_USAGE_TRANSFER_SRC_BIT
| VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT
| VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT
| VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
| VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT;
info.access = VK_ACCESS_TRANSFER_READ_BIT
| VK_ACCESS_TRANSFER_WRITE_BIT
| VK_ACCESS_INDIRECT_COMMAND_READ_BIT
| VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT
| VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT;
return device->createBuffer(info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
}
D3D11_COMMON_BUFFER_MAP_MODE D3D11Buffer::DetermineMapMode() {
return (m_buffer->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
? D3D11_COMMON_BUFFER_MAP_MODE_DIRECT
: D3D11_COMMON_BUFFER_MAP_MODE_NONE;
VkFormatFeatureFlags Features) const {
VkFormatProperties properties = m_device->GetDXVKDevice()->adapter()->formatProperties(Format);
return (properties.bufferFeatures & Features) == Features;
}

View File

@ -1,18 +1,17 @@
#pragma once
#include "../dxvk/dxvk_cs.h"
#include "../dxvk/dxvk_device.h"
#include "../d3d10/d3d10_buffer.h"
#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,15 +41,16 @@ namespace dxvk {
D3D11Buffer(
D3D11Device* pDevice,
const D3D11_BUFFER_DESC* pDesc,
const D3D11_ON_12_RESOURCE_INFO* p11on12Info);
const D3D11_BUFFER_DESC* pDesc);
~D3D11Buffer();
HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid,
void** ppvObject) final;
void STDMETHODCALLTYPE GetDevice(
ID3D11Device **ppDevice) final;
void STDMETHODCALLTYPE GetType(
D3D11_RESOURCE_DIMENSION *pResourceDimension) final;
@ -69,48 +69,30 @@ 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;
return (m_buffer->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
? D3D11_COMMON_BUFFER_MAP_MODE_DIRECT
: D3D11_COMMON_BUFFER_MAP_MODE_NONE;
}
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);
return GetBufferSlice(0, m_desc.ByteWidth);
}
DxvkBufferSlice GetBufferSlice(VkDeviceSize offset) const {
VkDeviceSize size = m_desc.ByteWidth;
offset = std::min(offset, size);
return DxvkBufferSlice(m_buffer, offset, size - offset);
return GetBufferSlice(offset, m_desc.ByteWidth - 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));
}
VkDeviceSize GetRemainingSize(VkDeviceSize offset) const {
VkDeviceSize size = m_desc.ByteWidth;
offset = std::min(offset, size);
return size - offset;
return DxvkBufferSlice(m_buffer, offset, length);
}
DxvkBufferSlice GetSOCounter() {
return m_soCounter != nullptr
? DxvkBufferSlice(m_soCounter)
: DxvkBufferSlice();
return m_soCounter;
}
DxvkBufferSliceHandle AllocSlice() {
@ -130,76 +112,31 @@ namespace dxvk {
return &m_d3d10;
}
bool HasSequenceNumber() const {
return m_mapMode != D3D11_COMMON_BUFFER_MAP_MODE_NONE
&& !(m_desc.MiscFlags & D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS)
&& !(m_desc.BindFlags);
}
void TrackSequenceNumber(uint64_t Seq) {
m_seq = Seq;
}
uint64_t GetSequenceNumber() {
return HasSequenceNumber() ? m_seq
: 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
* \brief Validates buffer description
*
* \param [in] pDesc Buffer description
* \returns \c S_OK if the parameters are valid
*/
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);
static HRESULT ValidateBufferProperties(
const D3D11_BUFFER_DESC* pDesc);
private:
D3D11_BUFFER_DESC m_desc;
D3D11_ON_12_RESOURCE_INFO m_11on12;
D3D11_COMMON_BUFFER_MAP_MODE m_mapMode;
const Com<D3D11Device> m_device;
const D3D11_BUFFER_DESC m_desc;
Rc<DxvkBuffer> m_buffer;
Rc<DxvkBuffer> m_soCounter;
Rc<DxvkSparsePageAllocator> m_sparseAllocator;
DxvkBufferSliceHandle m_mapped;
uint64_t m_seq = 0ull;
Rc<DxvkBuffer> m_buffer;
DxvkBufferSlice m_soCounter;
DxvkBufferSliceHandle m_mapped;
D3D11DXGIResource m_resource;
D3D10Buffer m_d3d10;
D3D11DXGIResource m_resource;
D3D10Buffer m_d3d10;
BOOL CheckFormatFeatureSupport(
VkFormat Format,
VkFormatFeatureFlags2 Features) const;
VkFormatFeatureFlags Features) const;
VkMemoryPropertyFlags GetMemoryFlags() const;
Rc<DxvkBuffer> CreateSoCounterBuffer();
D3D11_COMMON_BUFFER_MAP_MODE DetermineMapMode();
};

View File

@ -5,7 +5,7 @@ namespace dxvk {
D3D11ClassLinkage::D3D11ClassLinkage(
D3D11Device* pDevice)
: D3D11DeviceChild<ID3D11ClassLinkage>(pDevice) {
: m_device(pDevice) {
}
@ -28,15 +28,17 @@ namespace dxvk {
return S_OK;
}
if (logQueryInterfaceError(__uuidof(ID3D11ClassLinkage), riid)) {
Logger::warn("D3D11ClassLinkage::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
}
Logger::warn("D3D11ClassLinkage::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
return E_NOINTERFACE;
}
void STDMETHODCALLTYPE D3D11ClassLinkage::GetDevice(ID3D11Device** ppDevice) {
*ppDevice = m_device.ref();
}
HRESULT STDMETHODCALLTYPE D3D11ClassLinkage::CreateClassInstance(
LPCSTR pClassTypeName,
UINT ConstantBufferOffset,

View File

@ -20,6 +20,9 @@ namespace dxvk {
REFIID riid,
void** ppvObject) final;
void STDMETHODCALLTYPE GetDevice(
ID3D11Device **ppDevice) final;
HRESULT STDMETHODCALLTYPE CreateClassInstance(
LPCSTR pClassTypeName,
UINT ConstantBufferOffset,
@ -33,6 +36,10 @@ namespace dxvk {
UINT InstanceIndex,
ID3D11ClassInstance **ppInstance);
private:
Com<D3D11Device> m_device;
};
}

View File

@ -37,7 +37,6 @@ namespace dxvk {
struct D3D11CmdDrawIndirectData : public D3D11CmdData {
uint32_t offset;
uint32_t count;
uint32_t stride;
};
}

View File

@ -1,14 +1,12 @@
#include "d3d11_cmdlist.h"
#include "d3d11_device.h"
#include "d3d11_buffer.h"
#include "d3d11_texture.h"
namespace dxvk {
D3D11CommandList::D3D11CommandList(
D3D11Device* pDevice,
UINT ContextFlags)
: D3D11DeviceChild<ID3D11CommandList>(pDevice),
: m_device (pDevice),
m_contextFlags(ContextFlags) { }
@ -30,135 +28,52 @@ namespace dxvk {
return S_OK;
}
if (logQueryInterfaceError(__uuidof(ID3D11CommandList), riid)) {
Logger::warn("D3D11CommandList::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
}
Logger::warn("D3D11CommandList::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
return E_NOINTERFACE;
}
void STDMETHODCALLTYPE D3D11CommandList::GetDevice(ID3D11Device **ppDevice) {
*ppDevice = ref(m_device);
}
UINT STDMETHODCALLTYPE D3D11CommandList::GetContextFlags() {
return m_contextFlags;
}
void D3D11CommandList::AddQuery(D3D11Query* pQuery) {
m_queries.emplace_back(pQuery);
}
uint64_t D3D11CommandList::AddChunk(DxvkCsChunkRef&& Chunk) {
void D3D11CommandList::AddChunk(DxvkCsChunkRef&& Chunk) {
m_chunks.push_back(std::move(Chunk));
return m_chunks.size() - 1;
}
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();
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& 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 (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();
}
void D3D11CommandList::TrackResourceUsage(
ID3D11Resource* pResource,
D3D11_RESOURCE_DIMENSION ResourceType,
UINT Subresource,
uint64_t ChunkId) {
TrackedResource entry;
entry.ref = D3D11ResourceRef(pResource, Subresource, ResourceType);
entry.chunkId = ChunkId;
m_resources.push_back(std::move(entry));
void D3D11CommandList::EmitToCsThread(DxvkCsThread* CsThread) {
for (const auto& chunk : m_chunks)
CsThread->dispatchChunk(DxvkCsChunkRef(chunk));
MarkSubmitted();
}
void D3D11CommandList::TrackResourceSequenceNumber(
const D3D11ResourceRef& Resource,
uint64_t Seq) {
ID3D11Resource* iface = Resource.Get();
switch (Resource.GetType()) {
case D3D11_RESOURCE_DIMENSION_UNKNOWN:
break;
case D3D11_RESOURCE_DIMENSION_BUFFER: {
auto impl = static_cast<D3D11Buffer*>(iface);
impl->TrackSequenceNumber(Seq);
} break;
case D3D11_RESOURCE_DIMENSION_TEXTURE1D: {
auto impl = static_cast<D3D11Texture1D*>(iface)->GetCommonTexture();
impl->TrackSequenceNumber(Resource.GetSubresource(), Seq);
} break;
case D3D11_RESOURCE_DIMENSION_TEXTURE2D: {
auto impl = static_cast<D3D11Texture2D*>(iface)->GetCommonTexture();
impl->TrackSequenceNumber(Resource.GetSubresource(), Seq);
} break;
case D3D11_RESOURCE_DIMENSION_TEXTURE3D: {
auto impl = static_cast<D3D11Texture3D*>(iface)->GetCommonTexture();
impl->TrackSequenceNumber(Resource.GetSubresource(), Seq);
} break;
}
}
void D3D11CommandList::MarkSubmitted() {
if (m_submitted.exchange(true) && !m_warned.exchange(true)
&& m_parent->GetOptions()->dcSingleUseMode) {
&& m_device->GetOptions()->dcSingleUseMode) {
Logger::warn(
"D3D11: Command list submitted multiple times,\n"
" but d3d11.dcSingleUseMode is enabled");
}
}
}
}

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,9 +7,20 @@ namespace dxvk {
D3D11Device* pParent,
const Rc<DxvkDevice>& Device,
UINT ContextFlags)
: D3D11CommonContext<D3D11DeferredContext>(pParent, Device, ContextFlags, GetCsChunkFlags(pParent)),
: D3D11DeviceContext(pParent, Device, GetCsChunkFlags(pParent)),
m_contextFlags(ContextFlags),
m_commandList (CreateCommandList()) {
ResetContextState();
ClearState();
}
D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE D3D11DeferredContext::GetType() {
return D3D11_DEVICE_CONTEXT_DEFERRED;
}
UINT STDMETHODCALLTYPE D3D11DeferredContext::GetContextFlags() {
return m_contextFlags;
}
@ -18,143 +29,29 @@ namespace dxvk {
void* pData,
UINT DataSize,
UINT GetDataFlags) {
static bool s_errorShown = false;
if (!std::exchange(s_errorShown, true))
Logger::warn("D3D11: GetData called on a deferred context");
Logger::err("D3D11: GetData called on a deferred context");
return DXGI_ERROR_INVALID_CALL;
}
void STDMETHODCALLTYPE D3D11DeferredContext::Begin(
ID3D11Asynchronous* pAsync) {
D3D10DeviceLock lock = LockContext();
if (unlikely(!pAsync))
return;
Com<D3D11Query, false> query(static_cast<D3D11Query*>(pAsync));
if (unlikely(!query->IsScoped()))
return;
auto entry = std::find(
m_queriesBegun.begin(),
m_queriesBegun.end(), query);
if (unlikely(entry != m_queriesBegun.end()))
return;
EmitCs([cQuery = query]
(DxvkContext* ctx) {
cQuery->Begin(ctx);
});
m_queriesBegun.push_back(std::move(query));
}
void STDMETHODCALLTYPE D3D11DeferredContext::End(
ID3D11Asynchronous* pAsync) {
D3D10DeviceLock lock = LockContext();
if (unlikely(!pAsync))
return;
Com<D3D11Query, false> query(static_cast<D3D11Query*>(pAsync));
if (query->IsScoped()) {
auto entry = std::find(
m_queriesBegun.begin(),
m_queriesBegun.end(), query);
if (likely(entry != m_queriesBegun.end())) {
m_queriesBegun.erase(entry);
} else {
EmitCs([cQuery = query]
(DxvkContext* ctx) {
cQuery->Begin(ctx);
});
}
}
m_commandList->AddQuery(query.ptr());
EmitCs([cQuery = std::move(query)]
(DxvkContext* ctx) {
cQuery->End(ctx);
});
}
void STDMETHODCALLTYPE D3D11DeferredContext::Flush() {
static bool s_errorShown = false;
if (!std::exchange(s_errorShown, true))
Logger::warn("D3D11: Flush called on a deferred context");
}
void STDMETHODCALLTYPE D3D11DeferredContext::Flush1(
D3D11_CONTEXT_TYPE ContextType,
HANDLE hEvent) {
static bool s_errorShown = false;
if (!std::exchange(s_errorShown, true))
Logger::warn("D3D11: Flush1 called on a deferred context");
Logger::err("D3D11: Flush called on a deferred context");
}
HRESULT STDMETHODCALLTYPE D3D11DeferredContext::Signal(
ID3D11Fence* pFence,
UINT64 Value) {
static bool s_errorShown = false;
if (!std::exchange(s_errorShown, true))
Logger::warn("D3D11: Signal called on a deferred context");
return DXGI_ERROR_INVALID_CALL;
}
HRESULT STDMETHODCALLTYPE D3D11DeferredContext::Wait(
ID3D11Fence* pFence,
UINT64 Value) {
static bool s_errorShown = false;
if (!std::exchange(s_errorShown, true))
Logger::warn("D3D11: Wait called on a deferred context");
return DXGI_ERROR_INVALID_CALL;
}
void STDMETHODCALLTYPE D3D11DeferredContext::ExecuteCommandList(
ID3D11CommandList* pCommandList,
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();
// 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);
static_cast<D3D11CommandList*>(pCommandList)->EmitToCommandList(m_commandList.ptr());
// Restore deferred context state
if (RestoreContextState)
RestoreCommandListState();
RestoreState();
else
ResetContextState();
ClearState();
}
@ -163,34 +60,18 @@ 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)
if (ppCommandList != nullptr)
*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)
RestoreCommandListState();
RestoreState();
else
ResetContextState();
ClearState();
m_mappedResources.clear();
ResetStagingBuffer();
return S_OK;
}
@ -206,35 +87,47 @@ namespace dxvk {
if (unlikely(!pResource || !pMappedResource))
return E_INVALIDARG;
D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN;
pResource->GetType(&resourceDim);
if (MapType == D3D11_MAP_WRITE_DISCARD) {
D3D11_RESOURCE_DIMENSION resourceDim;
pResource->GetType(&resourceDim);
D3D11_MAPPED_SUBRESOURCE mapInfo;
D3D11DeferredContextMapEntry entry;
HRESULT status = resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER
? MapBuffer(pResource, &mapInfo)
: MapImage (pResource, Subresource, &mapInfo);
? MapBuffer(pResource, MapType, MapFlags, &entry)
: MapImage (pResource, Subresource, MapType, MapFlags, &entry);
if (unlikely(FAILED(status))) {
*pMappedResource = D3D11_MAPPED_SUBRESOURCE();
return status;
}
AddMapEntry(pResource, Subresource, resourceDim, mapInfo);
*pMappedResource = mapInfo;
// Adding a new map entry actually overrides the
// old one in practice because the lookup function
// scans the array in reverse order
m_mappedResources.push_back(entry);
// Fill mapped resource structure
pMappedResource->pData = entry.MapPointer;
pMappedResource->RowPitch = entry.RowPitch;
pMappedResource->DepthPitch = entry.DepthPitch;
return S_OK;
} else if (MapType == D3D11_MAP_WRITE_NO_OVERWRITE) {
// The resource must be mapped with D3D11_MAP_WRITE_DISCARD
// before it can be mapped with D3D11_MAP_WRITE_NO_OVERWRITE.
auto entry = FindMapEntry(pResource, Subresource);
if (unlikely(!entry)) {
if (unlikely(entry == m_mappedResources.rend())) {
*pMappedResource = D3D11_MAPPED_SUBRESOURCE();
return E_INVALIDARG;
}
// Return same memory region as earlier
*pMappedResource = entry->MapInfo;
entry->MapType = D3D11_MAP_WRITE_NO_OVERWRITE;
pMappedResource->pData = entry->MapPointer;
pMappedResource->RowPitch = entry->RowPitch;
pMappedResource->DepthPitch = entry->DepthPitch;
return S_OK;
} else {
// Not allowed on deferred contexts
@ -247,23 +140,37 @@ namespace dxvk {
void STDMETHODCALLTYPE D3D11DeferredContext::Unmap(
ID3D11Resource* pResource,
UINT Subresource) {
// No-op, updates are committed in Map
D3D10DeviceLock lock = LockContext();
auto entry = FindMapEntry(pResource, Subresource);
if (unlikely(entry == m_mappedResources.rend())) {
Logger::err("D3D11DeferredContext::Unmap: Subresource not mapped");
return;
}
if (entry->MapType == D3D11_MAP_WRITE_DISCARD) {
D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN;
pResource->GetType(&resourceDim);
(resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER)
? UnmapBuffer(pResource, &(*entry))
: UnmapImage (pResource, Subresource, &(*entry));
}
}
void STDMETHODCALLTYPE D3D11DeferredContext::SwapDeviceContextState(
ID3DDeviceContextState* pState,
ID3DDeviceContextState** ppPreviousState) {
static bool s_errorShown = false;
if (!std::exchange(s_errorShown, true))
Logger::warn("D3D11: SwapDeviceContextState called on a deferred context");
Logger::err("D3D11: SwapDeviceContextState called on a deferred context");
}
HRESULT D3D11DeferredContext::MapBuffer(
ID3D11Resource* pResource,
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
D3D11_MAP MapType,
UINT MapFlags,
D3D11DeferredContextMapEntry* pMapEntry) {
D3D11Buffer* pBuffer = static_cast<D3D11Buffer*>(pResource);
if (unlikely(pBuffer->GetMapMode() == D3D11_COMMON_BUFFER_MAP_MODE_NONE)) {
@ -271,36 +178,23 @@ namespace dxvk {
return E_INVALIDARG;
}
pMappedResource->RowPitch = pBuffer->Desc()->ByteWidth;
pMappedResource->DepthPitch = pBuffer->Desc()->ByteWidth;
pMapEntry->pResource = pResource;
pMapEntry->Subresource = 0;
pMapEntry->MapType = D3D11_MAP_WRITE_DISCARD;
pMapEntry->RowPitch = pBuffer->Desc()->ByteWidth;
pMapEntry->DepthPitch = pBuffer->Desc()->ByteWidth;
if (likely(m_csFlags.test(DxvkCsChunkFlag::SingleUse))) {
if (likely(pBuffer->Desc()->Usage == D3D11_USAGE_DYNAMIC && m_csFlags.test(DxvkCsChunkFlag::SingleUse))) {
// For resources that cannot be written by the GPU,
// we may write to the buffer resource directly and
// just swap in the buffer slice as needed.
auto bufferSlice = pBuffer->AllocSlice();
pMappedResource->pData = bufferSlice.mapPtr;
EmitCs([
cDstBuffer = pBuffer->GetBuffer(),
cPhysSlice = bufferSlice
] (DxvkContext* ctx) {
ctx->invalidateBuffer(cDstBuffer, cPhysSlice);
});
pMapEntry->BufferSlice = pBuffer->AllocSlice();
pMapEntry->MapPointer = pMapEntry->BufferSlice.mapPtr;
} else {
// For GPU-writable resources, we need a data slice
// to perform the update operation at execution time.
auto dataSlice = AllocUpdateBufferSlice(pBuffer->Desc()->ByteWidth);
pMappedResource->pData = dataSlice.ptr();
EmitCs([
cDstBuffer = pBuffer->GetBuffer(),
cDataSlice = dataSlice
] (DxvkContext* ctx) {
DxvkBufferSliceHandle slice = cDstBuffer->allocSlice();
std::memcpy(slice.mapPtr, cDataSlice.ptr(), cDataSlice.length());
ctx->invalidateBuffer(cDstBuffer, slice);
});
pMapEntry->DataSlice = AllocUpdateBufferSlice(pBuffer->Desc()->ByteWidth);
pMapEntry->MapPointer = pMapEntry->DataSlice.ptr();
}
return S_OK;
@ -310,8 +204,11 @@ namespace dxvk {
HRESULT D3D11DeferredContext::MapImage(
ID3D11Resource* pResource,
UINT Subresource,
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
D3D11CommonTexture* pTexture = GetCommonTexture(pResource);
D3D11_MAP MapType,
UINT MapFlags,
D3D11DeferredContextMapEntry* pMapEntry) {
const D3D11CommonTexture* pTexture = GetCommonTexture(pResource);
const Rc<DxvkImage> image = pTexture->GetImage();
if (unlikely(pTexture->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_NONE)) {
Logger::err("D3D11: Cannot map a device-local image");
@ -321,129 +218,113 @@ namespace dxvk {
if (unlikely(Subresource >= pTexture->CountSubresources()))
return E_INVALIDARG;
VkFormat packedFormat = pTexture->GetPackedFormat();
VkFormat packedFormat = m_parent->LookupPackedFormat(
pTexture->Desc()->Format, pTexture->GetFormatMode()).Format;
auto formatInfo = lookupFormatInfo(packedFormat);
auto formatInfo = imageFormatInfo(packedFormat);
auto subresource = pTexture->GetSubresourceFromIndex(
formatInfo->aspectMask, Subresource);
VkExtent3D levelExtent = pTexture->MipLevelExtent(subresource.mipLevel);
VkExtent3D levelExtent = image->mipLevelExtent(subresource.mipLevel);
VkExtent3D blockCount = util::computeBlockCount(
levelExtent, formatInfo->blockSize);
auto layout = pTexture->GetSubresourceLayout(formatInfo->aspectMask, Subresource);
auto dataSlice = AllocStagingBuffer(util::computeImageDataSize(packedFormat, levelExtent));
VkDeviceSize eSize = formatInfo->elementSize;
VkDeviceSize xSize = blockCount.width * eSize;
VkDeviceSize ySize = blockCount.height * xSize;
VkDeviceSize zSize = blockCount.depth * ySize;
pMappedResource->RowPitch = layout.RowPitch;
pMappedResource->DepthPitch = layout.DepthPitch;
pMappedResource->pData = dataSlice.mapPtr(0);
UpdateImage(pTexture, &subresource,
VkOffset3D { 0, 0, 0 }, levelExtent,
std::move(dataSlice));
pMapEntry->pResource = pResource;
pMapEntry->Subresource = Subresource;
pMapEntry->MapType = D3D11_MAP_WRITE_DISCARD;
pMapEntry->RowPitch = xSize;
pMapEntry->DepthPitch = ySize;
pMapEntry->DataSlice = AllocUpdateBufferSlice(zSize);
pMapEntry->MapPointer = pMapEntry->DataSlice.ptr();
return S_OK;
}
void D3D11DeferredContext::UpdateMappedBuffer(
D3D11Buffer* pDstBuffer,
UINT Offset,
UINT Length,
const void* pSrcData,
UINT CopyFlags) {
void* mapPtr = nullptr;
if (unlikely(CopyFlags == D3D11_COPY_NO_OVERWRITE)) {
auto entry = FindMapEntry(pDstBuffer, 0);
if (entry)
mapPtr = entry->MapInfo.pData;
}
if (likely(!mapPtr)) {
// The caller validates the map mode, so we can
// safely ignore the MapBuffer return value here
D3D11_MAPPED_SUBRESOURCE mapInfo;
MapBuffer(pDstBuffer, &mapInfo);
AddMapEntry(pDstBuffer, 0, D3D11_RESOURCE_DIMENSION_BUFFER, mapInfo);
mapPtr = mapInfo.pData;
}
std::memcpy(reinterpret_cast<char*>(mapPtr) + Offset, pSrcData, Length);
}
void D3D11DeferredContext::FinalizeQueries() {
for (auto& query : m_queriesBegun) {
m_commandList->AddQuery(query.ptr());
EmitCs([cQuery = std::move(query)]
(DxvkContext* ctx) {
cQuery->End(ctx);
void D3D11DeferredContext::UnmapBuffer(
ID3D11Resource* pResource,
const D3D11DeferredContextMapEntry* pMapEntry) {
D3D11Buffer* pBuffer = static_cast<D3D11Buffer*>(pResource);
if (likely(pBuffer->Desc()->Usage == D3D11_USAGE_DYNAMIC && m_csFlags.test(DxvkCsChunkFlag::SingleUse))) {
EmitCs([
cDstBuffer = pBuffer->GetBuffer(),
cPhysSlice = pMapEntry->BufferSlice
] (DxvkContext* ctx) {
ctx->invalidateBuffer(cDstBuffer, cPhysSlice);
});
} else {
EmitCs([
cDstBuffer = pBuffer->GetBuffer(),
cDataSlice = pMapEntry->DataSlice
] (DxvkContext* ctx) {
DxvkBufferSliceHandle slice = cDstBuffer->allocSlice();
std::memcpy(slice.mapPtr, cDataSlice.ptr(), cDataSlice.length());
ctx->invalidateBuffer(cDstBuffer, slice);
});
}
m_queriesBegun.clear();
}
void D3D11DeferredContext::UnmapImage(
ID3D11Resource* pResource,
UINT Subresource,
const D3D11DeferredContextMapEntry* pMapEntry) {
// TODO If the texture itself is mapped to host-visible
// memory, write the data slice directly to the image.
const D3D11CommonTexture* pTexture = GetCommonTexture(pResource);
EmitCs([
cImage = pTexture->GetImage(),
cSubresource = pTexture->GetSubresourceFromIndex(
VK_IMAGE_ASPECT_COLOR_BIT, Subresource),
cDataSlice = pMapEntry->DataSlice,
cDataPitchPerRow = pMapEntry->RowPitch,
cDataPitchPerLayer = pMapEntry->DepthPitch,
cPackedFormat = GetPackedDepthStencilFormat(pTexture->Desc()->Format)
] (DxvkContext* ctx) {
VkImageSubresourceLayers srLayers;
srLayers.aspectMask = cSubresource.aspectMask;
srLayers.mipLevel = cSubresource.mipLevel;
srLayers.baseArrayLayer = cSubresource.arrayLayer;
srLayers.layerCount = 1;
VkOffset3D mipLevelOffset = { 0, 0, 0 };
VkExtent3D mipLevelExtent = cImage->mipLevelExtent(srLayers.mipLevel);
if (cPackedFormat == VK_FORMAT_UNDEFINED) {
ctx->updateImage(
cImage, srLayers,
mipLevelOffset,
mipLevelExtent,
cDataSlice.ptr(),
cDataPitchPerRow,
cDataPitchPerLayer);
} else {
ctx->updateDepthStencilImage(
cImage, srLayers,
VkOffset2D { mipLevelOffset.x, mipLevelOffset.y },
VkExtent2D { mipLevelExtent.width, mipLevelExtent.height },
cDataSlice.ptr(),
cDataPitchPerRow,
cDataPitchPerLayer,
cPackedFormat);
}
});
}
Com<D3D11CommandList> D3D11DeferredContext::CreateCommandList() {
return new D3D11CommandList(m_parent, m_flags);
return new D3D11CommandList(m_parent, m_contextFlags);
}
void D3D11DeferredContext::EmitCsChunk(DxvkCsChunkRef&& chunk) {
m_chunkId = m_commandList->AddChunk(std::move(chunk));
}
uint64_t D3D11DeferredContext::GetCurrentChunkId() const {
return m_csChunk->empty() ? m_chunkId : m_chunkId + 1;
}
void D3D11DeferredContext::TrackTextureSequenceNumber(
D3D11CommonTexture* pResource,
UINT Subresource) {
m_commandList->TrackResourceUsage(
pResource->GetInterface(),
pResource->GetDimension(),
Subresource, GetCurrentChunkId());
}
void D3D11DeferredContext::TrackBufferSequenceNumber(
D3D11Buffer* pResource) {
m_commandList->TrackResourceUsage(pResource,
D3D11_RESOURCE_DIMENSION_BUFFER, 0,
GetCurrentChunkId());
}
D3D11DeferredContextMapEntry* D3D11DeferredContext::FindMapEntry(
ID3D11Resource* pResource,
UINT Subresource) {
// Recently mapped resources as well as entries with
// up-to-date map infos will be located at the end
// of the resource array, so scan in reverse order.
size_t size = m_mappedResources.size();
for (size_t i = 1; i <= size; i++) {
auto entry = &m_mappedResources[size - i];
if (entry->Resource.Get() == pResource
&& entry->Resource.GetSubresource() == Subresource)
return entry;
}
return nullptr;
}
void D3D11DeferredContext::AddMapEntry(
ID3D11Resource* pResource,
UINT Subresource,
D3D11_RESOURCE_DIMENSION ResourceType,
const D3D11_MAPPED_SUBRESOURCE& MapInfo) {
m_mappedResources.emplace_back(pResource,
Subresource, ResourceType, MapInfo);
m_commandList->AddChunk(std::move(chunk));
}

View File

@ -1,28 +1,28 @@
#pragma once
#include "d3d11_buffer.h"
#include "d3d11_cmdlist.h"
#include "d3d11_context.h"
#include "d3d11_texture.h"
#include <algorithm>
#include <vector>
namespace dxvk {
struct D3D11DeferredContextMapEntry {
D3D11DeferredContextMapEntry() { }
D3D11DeferredContextMapEntry(
ID3D11Resource* pResource,
UINT Subresource,
D3D11_RESOURCE_DIMENSION ResourceType,
const D3D11_MAPPED_SUBRESOURCE& MappedResource)
: Resource(pResource, Subresource, ResourceType),
MapInfo(MappedResource) { }
D3D11ResourceRef Resource;
D3D11_MAPPED_SUBRESOURCE MapInfo;
Com<ID3D11Resource> pResource;
UINT Subresource;
D3D11_MAP MapType;
UINT RowPitch;
UINT DepthPitch;
DxvkDataSlice DataSlice;
DxvkBufferSliceHandle BufferSlice;
void* MapPointer;
};
class D3D11DeferredContext : public D3D11CommonContext<D3D11DeferredContext> {
friend class D3D11CommonContext<D3D11DeferredContext>;
class D3D11DeferredContext : public D3D11DeviceContext {
public:
D3D11DeferredContext(
@ -30,39 +30,25 @@ namespace dxvk {
const Rc<DxvkDevice>& Device,
UINT ContextFlags);
D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE GetType();
UINT STDMETHODCALLTYPE GetContextFlags();
HRESULT STDMETHODCALLTYPE GetData(
ID3D11Asynchronous* pAsync,
void* pData,
UINT DataSize,
UINT GetDataFlags);
ID3D11Asynchronous* pAsync,
void* pData,
UINT DataSize,
UINT GetDataFlags);
void STDMETHODCALLTYPE Begin(
ID3D11Asynchronous* pAsync);
void STDMETHODCALLTYPE End(
ID3D11Asynchronous* pAsync);
void STDMETHODCALLTYPE Flush();
void STDMETHODCALLTYPE Flush1(
D3D11_CONTEXT_TYPE ContextType,
HANDLE hEvent);
HRESULT STDMETHODCALLTYPE Signal(
ID3D11Fence* pFence,
UINT64 Value);
HRESULT STDMETHODCALLTYPE Wait(
ID3D11Fence* pFence,
UINT64 Value);
void STDMETHODCALLTYPE ExecuteCommandList(
ID3D11CommandList* pCommandList,
BOOL RestoreContextState);
ID3D11CommandList* pCommandList,
BOOL RestoreContextState);
HRESULT STDMETHODCALLTYPE FinishCommandList(
BOOL RestoreDeferredContextState,
ID3D11CommandList** ppCommandList);
BOOL RestoreDeferredContextState,
ID3D11CommandList **ppCommandList);
HRESULT STDMETHODCALLTYPE Map(
ID3D11Resource* pResource,
@ -79,12 +65,10 @@ namespace dxvk {
ID3DDeviceContextState* pState,
ID3DDeviceContextState** ppPreviousState);
D3D10DeviceLock LockContext() {
return D3D10DeviceLock();
}
private:
const UINT m_contextFlags;
// Command list that we're recording
Com<D3D11CommandList> m_commandList;
@ -93,56 +77,43 @@ namespace dxvk {
// number of mapped resources per command list.
std::vector<D3D11DeferredContextMapEntry> m_mappedResources;
// 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);
D3D11_MAP MapType,
UINT MapFlags,
D3D11DeferredContextMapEntry* pMapEntry);
HRESULT MapImage(
ID3D11Resource* pResource,
UINT Subresource,
D3D11_MAPPED_SUBRESOURCE* pMappedResource);
void UpdateMappedBuffer(
D3D11Buffer* pDstBuffer,
UINT Offset,
UINT Length,
const void* pSrcData,
UINT CopyFlags);
void FinalizeQueries();
D3D11_MAP MapType,
UINT MapFlags,
D3D11DeferredContextMapEntry* pMapEntry);
void UnmapBuffer(
ID3D11Resource* pResource,
const D3D11DeferredContextMapEntry* pMapEntry);
void UnmapImage(
ID3D11Resource* pResource,
UINT Subresource,
const D3D11DeferredContextMapEntry* pMapEntry);
Com<D3D11CommandList> CreateCommandList();
void EmitCsChunk(DxvkCsChunkRef&& chunk);
uint64_t GetCurrentChunkId() const;
void TrackTextureSequenceNumber(
D3D11CommonTexture* pResource,
UINT Subresource);
void TrackBufferSequenceNumber(
D3D11Buffer* pResource);
D3D11DeferredContextMapEntry* FindMapEntry(
ID3D11Resource* pResource,
UINT Subresource);
void AddMapEntry(
ID3D11Resource* pResource,
UINT Subresource,
D3D11_RESOURCE_DIMENSION ResourceType,
const D3D11_MAPPED_SUBRESOURCE& MapInfo);
static DxvkCsChunkFlags GetCsChunkFlags(
D3D11Device* pDevice);
auto FindMapEntry(ID3D11Resource* pResource, UINT Subresource) {
return std::find_if(m_mappedResources.rbegin(), m_mappedResources.rend(),
[pResource, Subresource] (const D3D11DeferredContextMapEntry& entry) {
return entry.pResource == pResource
&& entry.Subresource == Subresource;
});
}
};
}

View File

@ -1,46 +1,32 @@
#include <vector>
#include <utility>
#include <cstring>
#include "d3d11_device.h"
#include "d3d11_context_imm.h"
#include "d3d11_context_def.h"
#include "d3d11_cuda.h"
#include "../util/log/log.h"
#include "d3d11_context.h"
namespace dxvk {
template<typename ContextType>
D3D11DeviceContextExt<ContextType>::D3D11DeviceContextExt(
ContextType* pContext)
D3D11DeviceContextExt::D3D11DeviceContextExt(
D3D11DeviceContext* pContext)
: m_ctx(pContext) {
}
template<typename ContextType>
ULONG STDMETHODCALLTYPE D3D11DeviceContextExt<ContextType>::AddRef() {
ULONG STDMETHODCALLTYPE D3D11DeviceContextExt::AddRef() {
return m_ctx->AddRef();
}
template<typename ContextType>
ULONG STDMETHODCALLTYPE D3D11DeviceContextExt<ContextType>::Release() {
ULONG STDMETHODCALLTYPE D3D11DeviceContextExt::Release() {
return m_ctx->Release();
}
template<typename ContextType>
HRESULT STDMETHODCALLTYPE D3D11DeviceContextExt<ContextType>::QueryInterface(
HRESULT STDMETHODCALLTYPE D3D11DeviceContextExt::QueryInterface(
REFIID riid,
void** ppvObject) {
return m_ctx->QueryInterface(riid, ppvObject);
}
template<typename ContextType>
void STDMETHODCALLTYPE D3D11DeviceContextExt<ContextType>::MultiDrawIndirect(
void STDMETHODCALLTYPE D3D11DeviceContextExt::MultiDrawIndirect(
UINT DrawCount,
ID3D11Buffer* pBufferForArgs,
UINT ByteOffsetForArgs,
@ -58,8 +44,7 @@ namespace dxvk {
}
template<typename ContextType>
void STDMETHODCALLTYPE D3D11DeviceContextExt<ContextType>::MultiDrawIndexedIndirect(
void STDMETHODCALLTYPE D3D11DeviceContextExt::MultiDrawIndexedIndirect(
UINT DrawCount,
ID3D11Buffer* pBufferForArgs,
UINT ByteOffsetForArgs,
@ -77,8 +62,7 @@ namespace dxvk {
}
template<typename ContextType>
void STDMETHODCALLTYPE D3D11DeviceContextExt<ContextType>::MultiDrawIndirectCount(
void STDMETHODCALLTYPE D3D11DeviceContextExt::MultiDrawIndirectCount(
UINT MaxDrawCount,
ID3D11Buffer* pBufferForCount,
UINT ByteOffsetForCount,
@ -99,8 +83,7 @@ namespace dxvk {
}
template<typename ContextType>
void STDMETHODCALLTYPE D3D11DeviceContextExt<ContextType>::MultiDrawIndexedIndirectCount(
void STDMETHODCALLTYPE D3D11DeviceContextExt::MultiDrawIndexedIndirectCount(
UINT MaxDrawCount,
ID3D11Buffer* pBufferForCount,
UINT ByteOffsetForCount,
@ -121,8 +104,7 @@ namespace dxvk {
}
template<typename ContextType>
void STDMETHODCALLTYPE D3D11DeviceContextExt<ContextType>::SetDepthBoundsTest(
void STDMETHODCALLTYPE D3D11DeviceContextExt::SetDepthBoundsTest(
BOOL Enable,
FLOAT MinDepthBounds,
FLOAT MaxDepthBounds) {
@ -139,84 +121,17 @@ namespace dxvk {
}
template<typename ContextType>
void STDMETHODCALLTYPE D3D11DeviceContextExt<ContextType>::SetBarrierControl(
void STDMETHODCALLTYPE D3D11DeviceContextExt::SetBarrierControl(
UINT ControlFlags) {
D3D10DeviceLock lock = m_ctx->LockContext();
DxvkBarrierControlFlags flags;
if (ControlFlags & D3D11_VK_BARRIER_CONTROL_IGNORE_WRITE_AFTER_WRITE)
flags.set(DxvkBarrierControl::IgnoreWriteAfterWrite);
if (ControlFlags & D3D11_VK_BARRIER_CONTROL_IGNORE_GRAPHICS_UAV)
flags.set(DxvkBarrierControl::IgnoreGraphicsBarriers);
m_ctx->EmitCs([cFlags = flags] (DxvkContext* ctx) {
ctx->setBarrierControl(cFlags);
});
}
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();
CubinShaderWrapper* cubinShader = static_cast<CubinShaderWrapper*>(hShader);
CubinShaderLaunchInfo launchInfo;
const uint32_t maxResources = NumReadResources + NumWriteResources;
launchInfo.buffers.reserve(maxResources);
launchInfo.images.reserve(maxResources);
for (uint32_t i = 0; i < NumReadResources; i++)
launchInfo.insertResource(static_cast<ID3D11Resource*>(pReadResources[i]), DxvkAccess::Read);
for (uint32_t i = 0; i < NumWriteResources; i++)
launchInfo.insertResource(static_cast<ID3D11Resource*>(pWriteResources[i]), DxvkAccess::Write);
launchInfo.paramSize = ParamSize;
launchInfo.params.resize(launchInfo.paramSize);
std::memcpy(launchInfo.params.data(), pParams, ParamSize);
launchInfo.cuLaunchConfig[0] = reinterpret_cast<void*>(0x01); // CU_LAUNCH_PARAM_BUFFER_POINTER
launchInfo.cuLaunchConfig[1] = launchInfo.params.data();
launchInfo.cuLaunchConfig[2] = reinterpret_cast<void*>(0x02); // CU_LAUNCH_PARAM_BUFFER_SIZE
launchInfo.cuLaunchConfig[3] = &launchInfo.paramSize; // yes, this actually requires a pointer to a size_t containing the parameter size
launchInfo.cuLaunchConfig[4] = reinterpret_cast<void*>(0x00); // CU_LAUNCH_PARAM_END
launchInfo.nvxLaunchInfo.function = cubinShader->cuFunction();
launchInfo.nvxLaunchInfo.gridDimX = GridX;
launchInfo.nvxLaunchInfo.gridDimY = GridY;
launchInfo.nvxLaunchInfo.gridDimZ = GridZ;
launchInfo.nvxLaunchInfo.blockDimX = cubinShader->blockDim().width;
launchInfo.nvxLaunchInfo.blockDimY = cubinShader->blockDim().height;
launchInfo.nvxLaunchInfo.blockDimZ = cubinShader->blockDim().depth;
launchInfo.nvxLaunchInfo.sharedMemBytes = 0;
launchInfo.nvxLaunchInfo.paramCount = 0;
launchInfo.nvxLaunchInfo.pParams = nullptr;
launchInfo.nvxLaunchInfo.extraCount = 1;
launchInfo.nvxLaunchInfo.pExtras = launchInfo.cuLaunchConfig.data();
launchInfo.shader = cubinShader;
/* Need to capture by value in case this gets called from a deferred context */
m_ctx->EmitCs([cLaunchInfo = std::move(launchInfo)] (DxvkContext* ctx) {
ctx->launchCuKernelNVX(cLaunchInfo.nvxLaunchInfo, cLaunchInfo.buffers, cLaunchInfo.images);
});
// Track resource usage as necessary
for (uint32_t i = 0; i < NumReadResources; i++)
m_ctx->TrackResourceSequenceNumber(static_cast<ID3D11Resource*>(pReadResources[i]));
for (uint32_t i = 0; i < NumWriteResources; i++)
m_ctx->TrackResourceSequenceNumber(static_cast<ID3D11Resource*>(pWriteResources[i]));
return true;
}
template class D3D11DeviceContextExt<D3D11DeferredContext>;
template class D3D11DeviceContextExt<D3D11ImmediateContext>;
}

View File

@ -4,16 +4,14 @@
namespace dxvk {
class D3D11DeferredContext;
class D3D11ImmediateContext;
class D3D11DeviceContext;
template<typename ContextType>
class D3D11DeviceContextExt : public ID3D11VkExtContext1 {
class D3D11DeviceContextExt : public ID3D11VkExtContext {
public:
D3D11DeviceContextExt(
ContextType* pContext);
D3D11DeviceContext* pContext);
ULONG STDMETHODCALLTYPE AddRef();
@ -58,23 +56,11 @@ namespace dxvk {
void STDMETHODCALLTYPE SetBarrierControl(
UINT ControlFlags);
bool STDMETHODCALLTYPE 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);
private:
ContextType* m_ctx;
D3D11DeviceContext* m_ctx;
};
}

File diff suppressed because it is too large Load Diff

View File

@ -1,23 +1,16 @@
#pragma once
#include "../util/util_time.h"
#include "../util/sync/sync_signal.h"
#include <chrono>
#include "d3d11_context.h"
#include "d3d11_state_object.h"
#include "d3d11_video.h"
namespace dxvk {
class D3D11Buffer;
class D3D11CommonTexture;
class D3D11ImmediateContext : public D3D11CommonContext<D3D11ImmediateContext> {
friend class D3D11CommonContext<D3D11ImmediateContext>;
friend class D3D11SwapChain;
friend class D3D11VideoContext;
friend class D3D11DXGIKeyedMutex;
class D3D11ImmediateContext : public D3D11DeviceContext {
public:
D3D11ImmediateContext(
@ -25,36 +18,24 @@ namespace dxvk {
const Rc<DxvkDevice>& Device);
~D3D11ImmediateContext();
HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid,
void** ppvObject);
ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE GetType();
UINT STDMETHODCALLTYPE GetContextFlags();
HRESULT STDMETHODCALLTYPE GetData(
ID3D11Asynchronous* pAsync,
void* pData,
UINT DataSize,
UINT GetDataFlags);
ID3D11Asynchronous* pAsync,
void* pData,
UINT DataSize,
UINT GetDataFlags);
void STDMETHODCALLTYPE Begin(
ID3D11Asynchronous* pAsync);
void STDMETHODCALLTYPE End(
ID3D11Asynchronous* pAsync);
void STDMETHODCALLTYPE End(ID3D11Asynchronous *pAsync);
void STDMETHODCALLTYPE Flush();
void STDMETHODCALLTYPE Flush1(
D3D11_CONTEXT_TYPE ContextType,
HANDLE hEvent);
HRESULT STDMETHODCALLTYPE Signal(
ID3D11Fence* pFence,
UINT64 Value);
HRESULT STDMETHODCALLTYPE Wait(
ID3D11Fence* pFence,
UINT64 Value);
void STDMETHODCALLTYPE ExecuteCommandList(
ID3D11CommandList* pCommandList,
BOOL RestoreContextState);
@ -74,49 +55,52 @@ 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);
D3D10Multithread& GetMultithread() {
return m_multithread;
}
D3D10DeviceLock LockContext() {
return m_multithread.AcquireLock();
}
ID3DDeviceContextState* pState,
ID3DDeviceContextState** ppPreviousState);
void SynchronizeCsThread();
private:
DxvkCsThread m_csThread;
uint64_t m_csSeqNum = 0ull;
DxvkCsThread m_csThread;
bool m_csIsBusy = false;
uint32_t m_mappedImageCount = 0u;
VkDeviceSize m_maxImplicitDiscardSize = 0ull;
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;
std::chrono::high_resolution_clock::time_point m_lastFlush
= std::chrono::high_resolution_clock::now();
Com<D3D11DeviceContextState> m_stateObject;
HRESULT MapBuffer(
D3D11Buffer* pResource,
@ -135,53 +119,16 @@ 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);
void SynchronizeDevice();
void EndFrame();
bool WaitForResource(
const Rc<DxvkResource>& Resource,
uint64_t SequenceNumber,
D3D11_MAP MapType,
UINT MapFlags);
const Rc<DxvkResource>& Resource,
UINT MapFlags);
void EmitCsChunk(DxvkCsChunkRef&& chunk);
void TrackTextureSequenceNumber(
D3D11CommonTexture* pResource,
UINT Subresource);
void TrackBufferSequenceNumber(
D3D11Buffer* pResource);
uint64_t GetCurrentSequenceNumber();
uint64_t GetPendingCsChunks();
void ConsiderFlush(
GpuFlushType FlushType);
void ExecuteFlush(
GpuFlushType FlushType,
HANDLE hEvent,
BOOL Synchronize);
void FlushImplicit(BOOL StrongHint);
};
}

View File

@ -15,336 +15,166 @@
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, false> buffer = nullptr;
Com<D3D11Buffer> buffer = nullptr;
UINT constantOffset = 0;
UINT constantCount = 0;
UINT constantBound = 0;
};
struct D3D11ShaderStageCbvBinding {
std::array<D3D11ConstantBufferBinding, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT> buffers = { };
uint32_t maxCount = 0;
void reset() {
for (uint32_t i = 0; i < maxCount; i++)
buffers[i] = D3D11ConstantBufferBinding();
maxCount = 0;
}
};
using D3D11CbvBindings = D3D11ShaderStageState<D3D11ShaderStageCbvBinding>;
using D3D11ConstantBufferBindings = std::array<
D3D11ConstantBufferBinding, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT>;
/**
* \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;
}
using D3D11SamplerBindings = std::array<
Com<D3D11SamplerState>, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT>;
using D3D11ShaderResourceBindings = std::array<
Com<D3D11ShaderResourceView>, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT>;
using D3D11UnorderedAccessBindings = std::array<
Com<D3D11UnorderedAccessView>, D3D11_1_UAV_SLOT_COUNT>;
struct D3D11ContextStateVS {
Com<D3D11VertexShader> shader;
D3D11ConstantBufferBindings constantBuffers;
D3D11SamplerBindings samplers;
D3D11ShaderResourceBindings shaderResources;
};
/**
* \brief Input assembly state
*
* Stores vertex buffers, the index buffer, the
* input layout, and the dynamic primitive topology.
*/
struct D3D11ContextStateHS {
Com<D3D11HullShader> shader;
D3D11ConstantBufferBindings constantBuffers;
D3D11SamplerBindings samplers;
D3D11ShaderResourceBindings shaderResources;
};
struct D3D11ContextStateDS {
Com<D3D11DomainShader> shader;
D3D11ConstantBufferBindings constantBuffers;
D3D11SamplerBindings samplers;
D3D11ShaderResourceBindings shaderResources;
};
struct D3D11ContextStateGS {
Com<D3D11GeometryShader> shader;
D3D11ConstantBufferBindings constantBuffers;
D3D11SamplerBindings samplers;
D3D11ShaderResourceBindings shaderResources;
};
struct D3D11ContextStatePS {
Com<D3D11PixelShader> shader;
D3D11ConstantBufferBindings constantBuffers;
D3D11SamplerBindings samplers;
D3D11ShaderResourceBindings shaderResources;
D3D11UnorderedAccessBindings unorderedAccessViews;
};
struct D3D11ContextStateCS {
Com<D3D11ComputeShader> shader;
D3D11ConstantBufferBindings constantBuffers;
D3D11SamplerBindings samplers;
D3D11ShaderResourceBindings shaderResources;
D3D11UnorderedAccessBindings unorderedAccessViews;
};
struct D3D11VertexBufferBinding {
Com<D3D11Buffer, false> buffer = nullptr;
UINT offset = 0;
UINT stride = 0;
Com<D3D11Buffer> buffer = nullptr;
UINT offset = 0;
UINT stride = 0;
};
struct D3D11IndexBufferBinding {
Com<D3D11Buffer, false> buffer = nullptr;
UINT offset = 0;
DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
Com<D3D11Buffer> buffer = nullptr;
UINT offset = 0;
DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
};
struct D3D11ContextStateIA {
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();
}
struct D3D11ContextStateID {
Com<D3D11Buffer> argBuffer = nullptr;
Com<D3D11Buffer> cntBuffer = nullptr;
};
struct D3D11ContextStateIA {
Com<D3D11InputLayout> inputLayout;
D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
std::array<D3D11VertexBufferBinding, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT> vertexBuffers;
D3D11IndexBufferBinding indexBuffer;
};
/**
* \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 {
D3D11ShaderStageUavBinding uavs = { };
D3D11RenderTargetViewBinding rtvs = { };
Com<D3D11DepthStencilView, false> dsv = { };
std::array<Com<D3D11RenderTargetView, false>, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT> renderTargetViews;
Com<D3D11DepthStencilView, false> depthStencilView;
D3D11BlendState* cbState = nullptr;
D3D11DepthStencilState* dsState = nullptr;
Com<D3D11BlendState> cbState = nullptr;
Com<D3D11DepthStencilState> dsState = nullptr;
FLOAT blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
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;
}
UINT sampleMask = 0xFFFFFFFFu;
UINT stencilRef = 0u;
};
/**
* \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;
std::array<D3D11_VIEWPORT, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE> viewports = { };
std::array<D3D11_RECT, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE> scissors = { };
std::array<D3D11_VIEWPORT, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE> viewports;
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;
}
Com<D3D11RasterizerState> state;
};
/**
* \brief Stream output binding
*
* Stores stream output buffers with offset.
*/
struct D3D11ContextSoTarget {
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();
}
Com<D3D11Buffer> buffer;
UINT offset;
};
/**
* \brief Predication state
*
* Stores predication info.
*/
struct D3D11ContextStatePR {
Com<D3D11Query, false> predicateObject = nullptr;
BOOL predicateValue = false;
void reset() {
predicateObject = nullptr;
predicateValue = false;
}
struct D3D11ContextStateSO {
std::array<D3D11ContextSoTarget, D3D11_SO_BUFFER_SLOT_COUNT> targets;
};
struct D3D11ContextStatePR {
Com<D3D11Query> predicateObject = nullptr;
BOOL predicateValue = FALSE;
};
/**
* \brief Context state
*/
struct D3D11ContextState {
Com<D3D11VertexShader, false> vs;
Com<D3D11HullShader, false> hs;
Com<D3D11DomainShader, false> ds;
Com<D3D11GeometryShader, false> gs;
Com<D3D11PixelShader, false> ps;
Com<D3D11ComputeShader, false> cs;
D3D11ContextStateCS cs;
D3D11ContextStateDS ds;
D3D11ContextStateGS gs;
D3D11ContextStateHS hs;
D3D11ContextStatePS ps;
D3D11ContextStateVS vs;
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

@ -0,0 +1,52 @@
#include "d3d11_counter_buffer.h"
#include "d3d11_device.h"
namespace dxvk {
D3D11CounterBuffer::D3D11CounterBuffer(
const Rc<DxvkDevice>& Device,
const DxvkBufferCreateInfo& BufferInfo,
VkDeviceSize SliceLength)
: m_device (Device),
m_bufferInfo (BufferInfo),
m_sliceLength (SliceLength) {
}
D3D11CounterBuffer::~D3D11CounterBuffer() {
}
DxvkBufferSlice D3D11CounterBuffer::AllocSlice() {
std::lock_guard<std::mutex> lock(m_mutex);
if (m_freeSlices.size() == 0)
CreateBuffer();
DxvkBufferSlice slice = m_freeSlices.back();
m_freeSlices.pop_back();
return slice;
}
void D3D11CounterBuffer::FreeSlice(const DxvkBufferSlice& Slice) {
std::lock_guard<std::mutex> lock(m_mutex);
m_freeSlices.push_back(Slice);
}
void D3D11CounterBuffer::CreateBuffer() {
Rc<DxvkBuffer> buffer = m_device->createBuffer(m_bufferInfo,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
VkDeviceSize sliceCount = m_bufferInfo.size / m_sliceLength;
for (uint32_t i = 0; i < sliceCount; i++) {
m_freeSlices.push_back(DxvkBufferSlice(
buffer, m_sliceLength * i, m_sliceLength));
}
}
}

View File

@ -0,0 +1,63 @@
#pragma once
#include "d3d11_include.h"
#include "../dxvk/dxvk_buffer.h"
#include "../dxvk/dxvk_device.h"
namespace dxvk {
class D3D11Device;
/**
* \brief D3D11 UAV counter slice allocator
*
* Thread safe allocator for buffer slices of
* the same size, which are typically used to
* store counters (such as UAV counters).
*/
class D3D11CounterBuffer : public RcObject {
public:
D3D11CounterBuffer(
const Rc<DxvkDevice>& Device,
const DxvkBufferCreateInfo& BufferInfo,
VkDeviceSize SliceLength);
~D3D11CounterBuffer();
/**
* \brief Allocates a counter slice
*
* Picks a slice from the free list or
* creates a new buffer if necessary.
* \returns The counter slice
*/
DxvkBufferSlice AllocSlice();
/**
* \brief Frees a counter slice
*
* Adds the given slice back to the
* free list so that it can be reused.
* \param [in] Slice the slice to free
*/
void FreeSlice(
const DxvkBufferSlice& Slice);
private:
Rc<DxvkDevice> m_device;
DxvkBufferCreateInfo m_bufferInfo;
VkDeviceSize m_sliceLength;
std::mutex m_mutex;
std::vector<DxvkBufferSlice> m_freeSlices;
void CreateBuffer();
};
}

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