d3d11: load shaders and buffers
This commit is contained in:
parent
2e5c9c835a
commit
f0bc2d92af
|
@ -53,8 +53,10 @@ Please report an issue if you run into a shader that works in RetroArch, but not
|
||||||
* Copying of in-flight framebuffer contents is done via `glBlitFramebuffer` rather than drawing a quad into an intermediate FBO.
|
* Copying of in-flight framebuffer contents is done via `glBlitFramebuffer` rather than drawing a quad into an intermediate FBO.
|
||||||
* Sampler objects are used rather than `glTexParameter`.
|
* Sampler objects are used rather than `glTexParameter`.
|
||||||
* Sampler inputs and outputs are not renamed. This is useful for debugging shaders in RenderDoc.
|
* Sampler inputs and outputs are not renamed. This is useful for debugging shaders in RenderDoc.
|
||||||
|
* UBO and Push Constant Buffer sizes are padded to 16-byte boundaries.
|
||||||
* Direct3D 11
|
* Direct3D 11
|
||||||
* The staging buffer is not kept around when loading static textures (LUTs).
|
* The staging buffer is not kept around when loading static textures (LUTs).
|
||||||
|
* HDR10 support is not part of the shader runtime and is not supported.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
The core parts of librashader such as the preprocessor, the preset parser,
|
The core parts of librashader such as the preprocessor, the preset parser,
|
||||||
|
|
|
@ -142,12 +142,15 @@ impl BindingStage {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UboReflection {
|
pub struct UboReflection {
|
||||||
pub binding: u32,
|
pub binding: u32,
|
||||||
|
/// Get this size of this UBO buffer.
|
||||||
|
/// The size returned by reflection is always aligned to a 16 byte boundary.
|
||||||
pub size: u32,
|
pub size: u32,
|
||||||
pub stage_mask: BindingStage,
|
pub stage_mask: BindingStage,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PushReflection {
|
pub struct PushReflection {
|
||||||
|
/// The size returned by reflection is always aligned to a 16 byte boundary.
|
||||||
pub size: u32,
|
pub size: u32,
|
||||||
pub stage_mask: BindingStage,
|
pub stage_mask: BindingStage,
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ use windows::core::PCSTR;
|
||||||
use windows::s;
|
use windows::s;
|
||||||
use windows::Win32::Graphics::Direct3D11::{D3D11_BIND_CONSTANT_BUFFER, D3D11_BIND_SHADER_RESOURCE, D3D11_BUFFER_DESC, D3D11_CPU_ACCESS_WRITE, D3D11_INPUT_ELEMENT_DESC, D3D11_INPUT_PER_VERTEX_DATA, D3D11_RESOURCE_MISC_FLAG, D3D11_RESOURCE_MISC_GENERATE_MIPS, D3D11_SAMPLER_DESC, D3D11_TEXTURE2D_DESC, D3D11_USAGE_DEFAULT, D3D11_USAGE_DYNAMIC, ID3D11Buffer, ID3D11Device, ID3D11DeviceContext};
|
use windows::Win32::Graphics::Direct3D11::{D3D11_BIND_CONSTANT_BUFFER, D3D11_BIND_SHADER_RESOURCE, D3D11_BUFFER_DESC, D3D11_CPU_ACCESS_WRITE, D3D11_INPUT_ELEMENT_DESC, D3D11_INPUT_PER_VERTEX_DATA, D3D11_RESOURCE_MISC_FLAG, D3D11_RESOURCE_MISC_GENERATE_MIPS, D3D11_SAMPLER_DESC, D3D11_TEXTURE2D_DESC, D3D11_USAGE_DEFAULT, D3D11_USAGE_DYNAMIC, ID3D11Buffer, ID3D11Device, ID3D11DeviceContext};
|
||||||
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SAMPLE_DESC};
|
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SAMPLE_DESC};
|
||||||
use crate::filter_pass::{ConstantBuffer, FilterPass};
|
use crate::filter_pass::{ConstantBuffer, ConstantBufferBinding, FilterPass};
|
||||||
use crate::samplers::SamplerSet;
|
use crate::samplers::SamplerSet;
|
||||||
use crate::util;
|
use crate::util;
|
||||||
use crate::util::d3d11_compile_bound_shader;
|
use crate::util::d3d11_compile_bound_shader;
|
||||||
|
@ -40,6 +40,7 @@ struct D3D11VertexLayout {
|
||||||
|
|
||||||
pub struct FilterChain {
|
pub struct FilterChain {
|
||||||
pub common: FilterCommon,
|
pub common: FilterCommon,
|
||||||
|
pub passes: Vec<FilterPass>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Direct3D11 {
|
pub struct Direct3D11 {
|
||||||
|
@ -104,7 +105,7 @@ impl FilterChain {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_constant_buffer(device: &ID3D11Device, size: u32) -> util::Result<ID3D11Buffer> {
|
fn create_constant_buffer(device: &ID3D11Device, size: u32) -> util::Result<ID3D11Buffer> {
|
||||||
|
eprintln!("{size}");
|
||||||
unsafe {
|
unsafe {
|
||||||
let buffer = device.CreateBuffer(&D3D11_BUFFER_DESC {
|
let buffer = device.CreateBuffer(&D3D11_BUFFER_DESC {
|
||||||
ByteWidth: size,
|
ByteWidth: size,
|
||||||
|
@ -123,7 +124,7 @@ impl FilterChain {
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
passes: Vec<ShaderPassMeta>,
|
passes: Vec<ShaderPassMeta>,
|
||||||
semantics: &ReflectSemantics,
|
semantics: &ReflectSemantics,
|
||||||
) -> util::Result<()>
|
) -> util::Result<Vec<FilterPass>>
|
||||||
{
|
{
|
||||||
// let mut filters = Vec::new();
|
// let mut filters = Vec::new();
|
||||||
let mut filters = Vec::new();
|
let mut filters = Vec::new();
|
||||||
|
@ -172,28 +173,24 @@ impl FilterChain {
|
||||||
|
|
||||||
|
|
||||||
let ubo_cbuffer = if let Some(ubo) = &reflection.ubo && ubo.size != 0 {
|
let ubo_cbuffer = if let Some(ubo) = &reflection.ubo && ubo.size != 0 {
|
||||||
let size = (ubo.size + 0xf) & !0xf;
|
let buffer = FilterChain::create_constant_buffer(device, ubo.size)?;
|
||||||
let buffer = FilterChain::create_constant_buffer(device, size)?;
|
Some(ConstantBufferBinding {
|
||||||
Some(ConstantBuffer {
|
|
||||||
binding: ubo.binding,
|
binding: ubo.binding,
|
||||||
size: ubo.size,
|
size: ubo.size,
|
||||||
stage_mask: ubo.stage_mask,
|
stage_mask: ubo.stage_mask,
|
||||||
buffer,
|
buffer,
|
||||||
storage: vec![0u8; size as usize].into_boxed_slice(),
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let push_cbuffer = if let Some(push) = &reflection.push_constant && push.size != 0 {
|
let push_cbuffer = if let Some(push) = &reflection.push_constant && push.size != 0 {
|
||||||
let size = (push.size + 0xf) & !0xf;
|
let buffer = FilterChain::create_constant_buffer(device, push.size)?;
|
||||||
let buffer = FilterChain::create_constant_buffer(device, size)?;
|
Some(ConstantBufferBinding {
|
||||||
Some(ConstantBuffer {
|
|
||||||
binding: if ubo_cbuffer.is_some() { 1 } else { 0 },
|
binding: if ubo_cbuffer.is_some() { 1 } else { 0 },
|
||||||
size: push.size,
|
size: push.size,
|
||||||
stage_mask: push.stage_mask,
|
stage_mask: push.stage_mask,
|
||||||
buffer,
|
buffer,
|
||||||
storage: vec![0u8; size as usize].into_boxed_slice(),
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -228,14 +225,14 @@ impl FilterChain {
|
||||||
vertex_layout: vertex_ia,
|
vertex_layout: vertex_ia,
|
||||||
pixel_shader: ps,
|
pixel_shader: ps,
|
||||||
uniform_bindings,
|
uniform_bindings,
|
||||||
uniform_buffer: ubo_cbuffer,
|
uniform_buffer: ConstantBuffer::new(ubo_cbuffer),
|
||||||
push_buffer: push_cbuffer,
|
push_buffer: ConstantBuffer::new(push_cbuffer),
|
||||||
source,
|
source,
|
||||||
config: config.clone(),
|
config: config.clone(),
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(filters)
|
||||||
}
|
}
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
pub fn load_from_preset(device: &ID3D11Device, preset: ShaderPreset) -> util::Result<FilterChain> {
|
pub fn load_from_preset(device: &ID3D11Device, preset: ShaderPreset) -> util::Result<FilterChain> {
|
||||||
|
@ -244,7 +241,7 @@ impl FilterChain {
|
||||||
let samplers = SamplerSet::new(device)?;
|
let samplers = SamplerSet::new(device)?;
|
||||||
|
|
||||||
// initialize passes
|
// initialize passes
|
||||||
let filters = FilterChain::init_passes(device, passes, &semantics)?;
|
let filters = FilterChain::init_passes(device, passes, &semantics).unwrap();
|
||||||
|
|
||||||
// let default_filter = filters.first().map(|f| f.config.filter).unwrap_or_default();
|
// let default_filter = filters.first().map(|f| f.config.filter).unwrap_or_default();
|
||||||
// let default_wrap = filters
|
// let default_wrap = filters
|
||||||
|
@ -271,7 +268,7 @@ impl FilterChain {
|
||||||
// FilterChain::init_history(&filters, default_filter, default_wrap);
|
// FilterChain::init_history(&filters, default_filter, default_wrap);
|
||||||
|
|
||||||
Ok(FilterChain {
|
Ok(FilterChain {
|
||||||
// passes: filters,
|
passes: filters,
|
||||||
// output_framebuffers: output_framebuffers.into_boxed_slice(),
|
// output_framebuffers: output_framebuffers.into_boxed_slice(),
|
||||||
// feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
|
// feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
|
||||||
// history_framebuffers,
|
// history_framebuffers,
|
||||||
|
@ -285,7 +282,6 @@ impl FilterChain {
|
||||||
// we don't need the reflect semantics once all locations have been bound per pass.
|
// we don't need the reflect semantics once all locations have been bound per pass.
|
||||||
// semantics,
|
// semantics,
|
||||||
preset,
|
preset,
|
||||||
// luts,
|
|
||||||
// output_textures: output_textures.into_boxed_slice(),
|
// output_textures: output_textures.into_boxed_slice(),
|
||||||
// feedback_textures: feedback_textures.into_boxed_slice(),
|
// feedback_textures: feedback_textures.into_boxed_slice(),
|
||||||
// history_textures,
|
// history_textures,
|
||||||
|
|
|
@ -12,17 +12,32 @@ use librashader_reflect::reflect::semantics::{
|
||||||
use librashader_reflect::reflect::ShaderReflection;
|
use librashader_reflect::reflect::ShaderReflection;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use windows::core::ConstBuffer;
|
||||||
use windows::Win32::Graphics::Direct3D::ID3DBlob;
|
use windows::Win32::Graphics::Direct3D::ID3DBlob;
|
||||||
use windows::Win32::Graphics::Direct3D11::{ID3D11Buffer, ID3D11PixelShader, ID3D11SamplerState, ID3D11ShaderResourceView, ID3D11VertexShader, D3D11_MAP_WRITE_DISCARD, ID3D11InputLayout};
|
use windows::Win32::Graphics::Direct3D11::{ID3D11Buffer, ID3D11PixelShader, ID3D11SamplerState, ID3D11ShaderResourceView, ID3D11VertexShader, D3D11_MAP_WRITE_DISCARD, ID3D11InputLayout};
|
||||||
|
|
||||||
pub struct ConstantBuffer {
|
pub struct ConstantBufferBinding {
|
||||||
pub binding: u32,
|
pub binding: u32,
|
||||||
pub size: u32,
|
pub size: u32,
|
||||||
pub stage_mask: BindingStage,
|
pub stage_mask: BindingStage,
|
||||||
pub buffer: ID3D11Buffer,
|
pub buffer: ID3D11Buffer,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ConstantBuffer {
|
||||||
|
pub binding: Option<ConstantBufferBinding>,
|
||||||
pub storage: Box<[u8]>,
|
pub storage: Box<[u8]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ConstantBuffer {
|
||||||
|
pub fn new(binding: Option<ConstantBufferBinding>) -> Self {
|
||||||
|
let storage = vec![0u8; binding.as_ref().map(|c| c.size as usize).unwrap_or(0)].into_boxed_slice();
|
||||||
|
Self {
|
||||||
|
binding,
|
||||||
|
storage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// slang_process.cpp 141
|
// slang_process.cpp 141
|
||||||
pub struct FilterPass {
|
pub struct FilterPass {
|
||||||
pub reflection: ShaderReflection,
|
pub reflection: ShaderReflection,
|
||||||
|
@ -33,8 +48,8 @@ pub struct FilterPass {
|
||||||
|
|
||||||
pub uniform_bindings: FxHashMap<UniformBinding, MemberOffset>,
|
pub uniform_bindings: FxHashMap<UniformBinding, MemberOffset>,
|
||||||
|
|
||||||
pub uniform_buffer: Option<ConstantBuffer>,
|
pub uniform_buffer: ConstantBuffer,
|
||||||
pub push_buffer: Option<ConstantBuffer>,
|
pub push_buffer: ConstantBuffer,
|
||||||
pub source: ShaderSource,
|
pub source: ShaderSource,
|
||||||
pub config: ShaderPassConfig,
|
pub config: ShaderPassConfig,
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,14 +70,9 @@ impl OwnedTexture {
|
||||||
format_support |= D3D11_FORMAT_SUPPORT_RENDER_TARGET.0;
|
format_support |= D3D11_FORMAT_SUPPORT_RENDER_TARGET.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
eprintln!("s {:?}, p {:?}, l {:?}", source.size, source.pitch, source.bytes.len());
|
// eprintln!("s {:?}, p {:?}, l {:?}", source.size, source.pitch, source.bytes.len());
|
||||||
eprintln!("{:#?}", desc);
|
// eprintln!("{:#?}", desc);
|
||||||
|
|
||||||
// let data = Some(&D3D11_SUBRESOURCE_DATA {
|
|
||||||
// pSysMem: source.bytes.as_ptr().cast(),
|
|
||||||
// SysMemPitch: source.pitch as u32,
|
|
||||||
// SysMemSlicePitch: 0
|
|
||||||
// });
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let handle = device.CreateTexture2D(&desc, None).unwrap();
|
let handle = device.CreateTexture2D(&desc, None).unwrap();
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ mod tests {
|
||||||
fn triangle_gl() {
|
fn triangle_gl() {
|
||||||
let (glfw, window, events, shader, vao) = hello_triangle::setup();
|
let (glfw, window, events, shader, vao) = hello_triangle::setup();
|
||||||
let mut filter =
|
let mut filter =
|
||||||
FilterChain::load_from_path("../test/slang-shaders/vhs/VHSPro.slangp")
|
FilterChain::load_from_path("../test/slang-shaders/crt/crt-royale.slangp")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
hello_triangle::do_loop(glfw, window, events, shader, vao, &mut filter);
|
hello_triangle::do_loop(glfw, window, events, shader, vao, &mut filter);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue