reflect(d3d12): fakesign dxil blobs to avoid needing dxil.dll

This commit is contained in:
chyyran 2024-02-18 16:19:36 -05:00 committed by Ronny Chan
parent e8eee02bfb
commit 50aa582fa8
14 changed files with 107 additions and 86 deletions

45
Cargo.lock generated
View file

@ -37,9 +37,9 @@ dependencies = [
[[package]]
name = "ahash"
version = "0.8.7"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01"
checksum = "42cd52102d3df161c77a887b608d7a4897d7cc112886a9537b738a887a03aaff"
dependencies = [
"cfg-if",
"getrandom",
@ -1224,7 +1224,7 @@ version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
dependencies = [
"ahash 0.8.7",
"ahash 0.8.8",
]
[[package]]
@ -1233,7 +1233,7 @@ version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
dependencies = [
"ahash 0.8.7",
"ahash 0.8.8",
"allocator-api2",
]
@ -1654,6 +1654,7 @@ dependencies = [
"librashader-presets",
"librashader-reflect",
"librashader-runtime",
"mach-siegbert-vogt-dxcsa",
"parking_lot",
"rayon",
"thiserror",
@ -1806,6 +1807,15 @@ version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "mach-siegbert-vogt-dxcsa"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d3e62358869047ad84e507d5bcd47e7f3917629947ba34ac0b3e5969db00a7b"
dependencies = [
"bytemuck",
]
[[package]]
name = "malloc_buf"
version = "0.0.6"
@ -2271,9 +2281,9 @@ dependencies = [
[[package]]
name = "png"
version = "0.17.11"
version = "0.17.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f6c3c3e617595665b8ea2ff95a86066be38fb121ff920a9c0eb282abcd1da5a"
checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1"
dependencies = [
"bitflags 1.3.2",
"crc32fast",
@ -2284,9 +2294,9 @@ dependencies = [
[[package]]
name = "polling"
version = "3.4.0"
version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30054e72317ab98eddd8561db0f6524df3367636884b7b21b703e4b280a84a14"
checksum = "24f040dee2588b4963afb4e420540439d126f73fdacf4a9c486a96d840bac3c9"
dependencies = [
"cfg-if",
"concurrent-queue",
@ -2358,9 +2368,9 @@ dependencies = [
[[package]]
name = "profiling"
version = "1.0.14"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f0f7f43585c34e4fdd7497d746bc32e14458cf11c69341cc0587b1d825dde42"
checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58"
[[package]]
name = "qoi"
@ -2617,9 +2627,9 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
[[package]]
name = "ryu"
version = "1.0.16"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
[[package]]
name = "same-file"
@ -2802,11 +2812,12 @@ dependencies = [
[[package]]
name = "spirv-to-dxil"
version = "0.4.6"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aa1b4b592a3c01a5a443b0d80200f1ae0cf4706928e3d61e03ae570e4085d06"
checksum = "5a3fb4188c288f0bcf2d6e18a74647a6346ce974c7751ca075de89e4949d4b0e"
dependencies = [
"bytemuck",
"mach-siegbert-vogt-dxcsa",
"spirv-to-dxil-sys",
"thiserror",
]
@ -2897,9 +2908,9 @@ dependencies = [
[[package]]
name = "textwrap"
version = "0.16.0"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
[[package]]
name = "thiserror"
@ -3672,7 +3683,7 @@ version = "0.29.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c824f11941eeae66ec71111cc2674373c772f482b58939bb4066b642aa2ffcf"
dependencies = [
"ahash 0.8.7",
"ahash 0.8.8",
"android-activity",
"atomic-waker",
"bitflags 2.4.2",

View file

@ -166,7 +166,7 @@ Please report an issue if you run into a shader that works in RetroArch, but not
which was released in late 2018.
* For maximum compatibility with shaders, a shader compile pipeline based on [`spirv-to-dxil`](https://github.com/SnowflakePowered/spirv-to-dxil-rs) is used, with the SPIRV-Cross HLSL pipeline used as a fallback.
This brings shader compatibility beyond what the RetroArch Direct3D 12 driver provides. The HLSL pipeline fallback may be removed in the future as `spirv-to-dxil` improves.
* The Direct3D 12 runtime requires `dxil.dll` and `dxcompiler.dll` from the [DirectX Shader Compiler](https://github.com/microsoft/DirectXShaderCompiler).
* The Direct3D 12 runtime requires `dxcompiler.dll` from the [DirectX Shader Compiler](https://github.com/microsoft/DirectXShaderCompiler), which may already be installed as part of Direct3D12. `dxil.dll` is not required.
* Metal
* The Metal runtime uses the same VBOs as the other runtimes as well as the identity matrix MVP for intermediate passes. RetroArch's Metal driver uses only the final VBO.

View file

@ -36,7 +36,7 @@ matches = { version = "0.1.10", features = [] }
rustc-hash = "1.1.0"
[target.'cfg(windows)'.dependencies.spirv-to-dxil]
version = "0.4"
version = "0.4.7"
optional = true
[features]

View file

@ -1,17 +1,16 @@
use crate::back::spirv::WriteSpirV;
use crate::back::{CompileShader, CompilerBackend, FromCompilation, ShaderCompilerOutput};
pub use spirv_to_dxil::DxilObject;
pub use spirv_to_dxil::ShaderModel;
use spirv_to_dxil::{
PushConstantBufferConfig, RuntimeConfig, RuntimeDataBufferConfig, ShaderStage, ValidatorVersion,
};
use crate::back::targets::{OutputTarget, DXIL};
use crate::back::{CompileShader, CompilerBackend, FromCompilation, ShaderCompilerOutput};
use crate::error::{ShaderCompileError, ShaderReflectError};
use crate::front::SpirvCompilation;
use crate::reflect::cross::glsl::GlslReflect;
use crate::reflect::cross::SpirvCross;
use crate::reflect::ReflectShader;
pub use spirv_to_dxil::DxilObject;
pub use spirv_to_dxil::ShaderModel;
use spirv_to_dxil::{
PushConstantBufferConfig, RuntimeConfig, RuntimeDataBufferConfig, ShaderStage, ValidatorVersion,
};
impl OutputTarget for DXIL {
type Output = DxilObject;
@ -28,14 +27,12 @@ impl FromCompilation<SpirvCompilation, SpirvCross> for DXIL {
compile: SpirvCompilation,
) -> Result<CompilerBackend<Self::Output>, ShaderReflectError> {
let reflect = GlslReflect::try_from(&compile)?;
let vertex = compile.vertex;
let fragment = compile.fragment;
Ok(CompilerBackend {
// we can just reuse WriteSpirV as the backend.
backend: WriteSpirV {
reflect,
vertex,
fragment,
vertex: compile.vertex,
fragment: compile.fragment,
},
})
}

View file

@ -110,6 +110,7 @@ mod test {
use crate::reflect::semantics::{Semantic, ShaderSemantics, UniformSemantic, UniqueSemantics};
use crate::reflect::ReflectShader;
use bitflags::Flags;
use librashader_common::map::FastHashMap;
use librashader_preprocess::ShaderSource;
use rustc_hash::FxHashMap;
use spirv_cross::msl;
@ -121,7 +122,7 @@ mod test {
// let result = ShaderSource::load("../test/shaders_slang/crt/shaders/crt-royale/src/crt-royale-scanlines-horizontal-apply-mask.slang").unwrap();
let result = ShaderSource::load("../test/basic.slang").unwrap();
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
let mut uniform_semantics: FastHashMap<String, UniformSemantic> = Default::default();
for (_index, param) in result.parameters.iter().enumerate() {
uniform_semantics.insert(

View file

@ -13,7 +13,7 @@ use librashader_runtime_d3d11::options::FilterChainOptionsD3D11;
// "../test/Mega_Bezel_Packs/Duimon-Mega-Bezel/Presets/Advanced/Nintendo_GBA_SP/GBA_SP-[ADV]-[LCD-GRID].slangp";
const FILTER_PATH: &str =
"../test/shaders-slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp";
"../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp";
// const FILTER_PATH: &str = "../test/slang-shaders/test/history.slangp";
// const FILTER_PATH: &str = "../test/slang-shaders/test/feedback.slangp";

View file

@ -27,6 +27,7 @@ array-init = "2.1.0"
bitvec = "1.0.1"
widestring = "1.0.2"
array-concat = "0.5.2"
mach-siegbert-vogt-dxcsa = "0.1.3"
rayon = "1.6.1"

Binary file not shown.

View file

@ -0,0 +1,42 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
//
// http://go.microsoft.com/fwlink/?LinkID=615561
#define GenerateMipsRS
"RootFlags ( DENY_VERTEX_SHADER_ROOT_ACCESS |"
" DENY_DOMAIN_SHADER_ROOT_ACCESS |"
" DENY_GEOMETRY_SHADER_ROOT_ACCESS |"
" DENY_HULL_SHADER_ROOT_ACCESS |"
" DENY_PIXEL_SHADER_ROOT_ACCESS ),"
"DescriptorTable ( SRV(t0, flags=DATA_VOLATILE|DESCRIPTORS_VOLATILE) ),"
"DescriptorTable ( UAV(u0, flags=DATA_VOLATILE|DESCRIPTORS_VOLATILE) ),"
"RootConstants(num32BitConstants=3, b0),"
"StaticSampler(s0,"
" filter = FILTER_MIN_MAG_LINEAR_MIP_POINT,"
" addressU = TEXTURE_ADDRESS_CLAMP,"
" addressV = TEXTURE_ADDRESS_CLAMP,"
" addressW = TEXTURE_ADDRESS_CLAMP )"
SamplerState Sampler : register(s0);
Texture2D<float4> SrcMip : register(t0);
RWTexture2D<float4> OutMip : register(u0);
cbuffer MipConstants : register(b0)
{
float2 InvOutTexelSize; // texel size for OutMip (NOT SrcMip)
uint SrcMipIndex;
}
float4 Mip(uint2 coord)
{
float2 uv = (coord.xy + 0.5) * InvOutTexelSize;
return SrcMip.SampleLevel(Sampler, uv, SrcMipIndex);
}
[RootSignature(GenerateMipsRS)]
[numthreads(8, 8, 1)]
void main(uint3 DTid : SV_DispatchThreadID)
{
OutMip[DTid.xy] = Mip(DTid.xy);
}

View file

@ -489,8 +489,7 @@ impl FilterChainD3D12 {
.into();
// incredibly cursed.
let (reflection, graphics_pipeline) = if !force_hlsl
&& let Ok(graphics_pipeline) = D3D12GraphicsPipeline::new_from_dxil(
let (reflection, graphics_pipeline) = if let Ok(graphics_pipeline) = D3D12GraphicsPipeline::new_from_dxil(
device,
library,
validator,
@ -498,7 +497,7 @@ impl FilterChainD3D12 {
root_signature,
render_format,
disable_cache,
) {
) && !force_hlsl {
(dxil_reflection, graphics_pipeline)
} else {
let hlsl_reflection = hlsl.reflect(index, semantics)?;

View file

@ -1,15 +1,12 @@
use crate::descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, ResourceWorkHeap};
use crate::util::dxc_compile_shader;
use crate::util::dxc_validate_shader;
use crate::{error, util};
use bytemuck::{Pod, Zeroable};
use librashader_common::Size;
use librashader_runtime::scaling::MipmapSize;
use std::mem::ManuallyDrop;
use std::ops::Deref;
use widestring::u16cstr;
use windows::Win32::Graphics::Direct3D::Dxc::{
CLSID_DxcCompiler, CLSID_DxcLibrary, DxcCreateInstance,
};
use windows::Win32::Graphics::Direct3D::Dxc::{CLSID_DxcLibrary, CLSID_DxcValidator, DxcCreateInstance};
use windows::Win32::Graphics::Direct3D12::{
ID3D12DescriptorHeap, ID3D12Device, ID3D12GraphicsCommandList, ID3D12PipelineState,
ID3D12Resource, ID3D12RootSignature, D3D12_COMPUTE_PIPELINE_STATE_DESC,
@ -22,49 +19,7 @@ use windows::Win32::Graphics::Direct3D12::{
};
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT;
static GENERATE_MIPS_SRC: &[u8] = b"
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
//
// http://go.microsoft.com/fwlink/?LinkID=615561
#define GenerateMipsRS \\
\"RootFlags ( DENY_VERTEX_SHADER_ROOT_ACCESS |\" \\
\" DENY_DOMAIN_SHADER_ROOT_ACCESS |\" \\
\" DENY_GEOMETRY_SHADER_ROOT_ACCESS |\" \\
\" DENY_HULL_SHADER_ROOT_ACCESS |\" \\
\" DENY_PIXEL_SHADER_ROOT_ACCESS ),\" \\
\"DescriptorTable ( SRV(t0, flags=DATA_VOLATILE|DESCRIPTORS_VOLATILE) ),\" \\
\"DescriptorTable ( UAV(u0, flags=DATA_VOLATILE|DESCRIPTORS_VOLATILE) ),\" \\
\"RootConstants(num32BitConstants=3, b0),\" \\
\"StaticSampler(s0,\"\\
\" filter = FILTER_MIN_MAG_LINEAR_MIP_POINT,\"\\
\" addressU = TEXTURE_ADDRESS_CLAMP,\"\\
\" addressV = TEXTURE_ADDRESS_CLAMP,\"\\
\" addressW = TEXTURE_ADDRESS_CLAMP )\"
SamplerState Sampler : register(s0);
Texture2D<float4> SrcMip : register(t0);
RWTexture2D<float4> OutMip : register(u0);
cbuffer MipConstants : register(b0)
{
float2 InvOutTexelSize; // texel size for OutMip (NOT SrcMip)
uint SrcMipIndex;
}
float4 Mip(uint2 coord)
{
float2 uv = (coord.xy + 0.5) * InvOutTexelSize;
return SrcMip.SampleLevel(Sampler, uv, SrcMipIndex);
}
[RootSignature(GenerateMipsRS)]
[numthreads(8, 8, 1)]
void main(uint3 DTid : SV_DispatchThreadID)
{
OutMip[DTid.xy] = Mip(DTid.xy);
}\0";
const GENERATE_MIPMAPS_CS: &[u8] = include_bytes!("../shader/mipmap.dxil");
pub struct D3D12MipmapGen {
device: ID3D12Device,
@ -137,12 +92,14 @@ impl D3D12MipmapGen {
pub fn new(device: &ID3D12Device, own_heaps: bool) -> error::Result<D3D12MipmapGen> {
unsafe {
let library = DxcCreateInstance(&CLSID_DxcLibrary)?;
let compiler = DxcCreateInstance(&CLSID_DxcCompiler)?;
let validator = DxcCreateInstance(&CLSID_DxcValidator)?;
let blob =
dxc_compile_shader(&library, &compiler, GENERATE_MIPS_SRC, u16cstr!("cs_6_0"))?;
dxc_validate_shader(&library, &validator, GENERATE_MIPMAPS_CS)?;
let blob =
std::slice::from_raw_parts(blob.GetBufferPointer().cast(), blob.GetBufferSize());
let root_signature: ID3D12RootSignature = device.CreateRootSignature(0, blob)?;
let desc = D3D12_COMPUTE_PIPELINE_STATE_DESC {

View file

@ -153,6 +153,12 @@ pub fn dxc_compile_shader(
)?;
let result = result.GetResult()?;
{
let blob = std::slice::from_raw_parts_mut(result.GetBufferPointer() as *mut u8, result.GetBufferSize());
mach_siegbert_vogt_dxcsa::sign_in_place(blob);
}
Ok(result)
}
}

View file

@ -290,7 +290,12 @@ pub mod d3d12_hello_triangle {
}
let filter =
unsafe { FilterChainD3D12::load_from_path(filter, &device, None).unwrap() };
unsafe { FilterChainD3D12::load_from_path(filter, &device, Some(&librashader_runtime_d3d12::options::FilterChainOptionsD3D12 {
disable_cache: true,
force_hlsl_pipeline: false,
force_no_mipmaps: false,
..Default::default()
})).unwrap() };
Ok(Sample {
dxgi_factory,

View file

@ -5,6 +5,8 @@ use crate::hello_triangle::{DXSample, SampleCommandLine};
#[test]
fn triangle_d3d12() {
let sample = hello_triangle::d3d12_hello_triangle::Sample::new(
"../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
// "../test/shaders_slang/crt/crt-lottes.slangp",
// "../test/basic.slangp",
// "../test/shaders_slang/handheld/console-border/gbc-lcd-grid-v2.slangp",