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.
|
||||
* Sampler objects are used rather than `glTexParameter`.
|
||||
* 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
|
||||
* 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
|
||||
The core parts of librashader such as the preprocessor, the preset parser,
|
||||
|
|
|
@ -142,12 +142,15 @@ impl BindingStage {
|
|||
#[derive(Debug)]
|
||||
pub struct UboReflection {
|
||||
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 stage_mask: BindingStage,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PushReflection {
|
||||
/// The size returned by reflection is always aligned to a 16 byte boundary.
|
||||
pub size: u32,
|
||||
pub stage_mask: BindingStage,
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ use windows::core::PCSTR;
|
|||
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::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::util;
|
||||
use crate::util::d3d11_compile_bound_shader;
|
||||
|
@ -40,6 +40,7 @@ struct D3D11VertexLayout {
|
|||
|
||||
pub struct FilterChain {
|
||||
pub common: FilterCommon,
|
||||
pub passes: Vec<FilterPass>,
|
||||
}
|
||||
|
||||
pub struct Direct3D11 {
|
||||
|
@ -104,7 +105,7 @@ impl FilterChain {
|
|||
}
|
||||
|
||||
fn create_constant_buffer(device: &ID3D11Device, size: u32) -> util::Result<ID3D11Buffer> {
|
||||
|
||||
eprintln!("{size}");
|
||||
unsafe {
|
||||
let buffer = device.CreateBuffer(&D3D11_BUFFER_DESC {
|
||||
ByteWidth: size,
|
||||
|
@ -123,7 +124,7 @@ impl FilterChain {
|
|||
device: &ID3D11Device,
|
||||
passes: Vec<ShaderPassMeta>,
|
||||
semantics: &ReflectSemantics,
|
||||
) -> util::Result<()>
|
||||
) -> util::Result<Vec<FilterPass>>
|
||||
{
|
||||
// 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 size = (ubo.size + 0xf) & !0xf;
|
||||
let buffer = FilterChain::create_constant_buffer(device, size)?;
|
||||
Some(ConstantBuffer {
|
||||
let buffer = FilterChain::create_constant_buffer(device, ubo.size)?;
|
||||
Some(ConstantBufferBinding {
|
||||
binding: ubo.binding,
|
||||
size: ubo.size,
|
||||
stage_mask: ubo.stage_mask,
|
||||
buffer,
|
||||
storage: vec![0u8; size as usize].into_boxed_slice(),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
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, size)?;
|
||||
Some(ConstantBuffer {
|
||||
let buffer = FilterChain::create_constant_buffer(device, push.size)?;
|
||||
Some(ConstantBufferBinding {
|
||||
binding: if ubo_cbuffer.is_some() { 1 } else { 0 },
|
||||
size: push.size,
|
||||
stage_mask: push.stage_mask,
|
||||
buffer,
|
||||
storage: vec![0u8; size as usize].into_boxed_slice(),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
|
@ -228,14 +225,14 @@ impl FilterChain {
|
|||
vertex_layout: vertex_ia,
|
||||
pixel_shader: ps,
|
||||
uniform_bindings,
|
||||
uniform_buffer: ubo_cbuffer,
|
||||
push_buffer: push_cbuffer,
|
||||
uniform_buffer: ConstantBuffer::new(ubo_cbuffer),
|
||||
push_buffer: ConstantBuffer::new(push_cbuffer),
|
||||
source,
|
||||
config: config.clone(),
|
||||
})
|
||||
|
||||
}
|
||||
Ok(())
|
||||
Ok(filters)
|
||||
}
|
||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||
pub fn load_from_preset(device: &ID3D11Device, preset: ShaderPreset) -> util::Result<FilterChain> {
|
||||
|
@ -244,7 +241,7 @@ impl FilterChain {
|
|||
let samplers = SamplerSet::new(device)?;
|
||||
|
||||
// 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_wrap = filters
|
||||
|
@ -271,7 +268,7 @@ impl FilterChain {
|
|||
// FilterChain::init_history(&filters, default_filter, default_wrap);
|
||||
|
||||
Ok(FilterChain {
|
||||
// passes: filters,
|
||||
passes: filters,
|
||||
// output_framebuffers: output_framebuffers.into_boxed_slice(),
|
||||
// feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
|
||||
// history_framebuffers,
|
||||
|
@ -285,7 +282,6 @@ impl FilterChain {
|
|||
// we don't need the reflect semantics once all locations have been bound per pass.
|
||||
// semantics,
|
||||
preset,
|
||||
// luts,
|
||||
// output_textures: output_textures.into_boxed_slice(),
|
||||
// feedback_textures: feedback_textures.into_boxed_slice(),
|
||||
// history_textures,
|
||||
|
|
|
@ -12,17 +12,32 @@ use librashader_reflect::reflect::semantics::{
|
|||
use librashader_reflect::reflect::ShaderReflection;
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::error::Error;
|
||||
use windows::core::ConstBuffer;
|
||||
use windows::Win32::Graphics::Direct3D::ID3DBlob;
|
||||
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 size: u32,
|
||||
pub stage_mask: BindingStage,
|
||||
pub buffer: ID3D11Buffer,
|
||||
}
|
||||
|
||||
pub struct ConstantBuffer {
|
||||
pub binding: Option<ConstantBufferBinding>,
|
||||
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
|
||||
pub struct FilterPass {
|
||||
pub reflection: ShaderReflection,
|
||||
|
@ -33,8 +48,8 @@ pub struct FilterPass {
|
|||
|
||||
pub uniform_bindings: FxHashMap<UniformBinding, MemberOffset>,
|
||||
|
||||
pub uniform_buffer: Option<ConstantBuffer>,
|
||||
pub push_buffer: Option<ConstantBuffer>,
|
||||
pub uniform_buffer: ConstantBuffer,
|
||||
pub push_buffer: ConstantBuffer,
|
||||
pub source: ShaderSource,
|
||||
pub config: ShaderPassConfig,
|
||||
}
|
||||
|
|
|
@ -70,14 +70,9 @@ impl OwnedTexture {
|
|||
format_support |= D3D11_FORMAT_SUPPORT_RENDER_TARGET.0;
|
||||
}
|
||||
|
||||
eprintln!("s {:?}, p {:?}, l {:?}", source.size, source.pitch, source.bytes.len());
|
||||
eprintln!("{:#?}", desc);
|
||||
// eprintln!("s {:?}, p {:?}, l {:?}", source.size, source.pitch, source.bytes.len());
|
||||
// eprintln!("{:#?}", desc);
|
||||
|
||||
// let data = Some(&D3D11_SUBRESOURCE_DATA {
|
||||
// pSysMem: source.bytes.as_ptr().cast(),
|
||||
// SysMemPitch: source.pitch as u32,
|
||||
// SysMemSlicePitch: 0
|
||||
// });
|
||||
unsafe {
|
||||
let handle = device.CreateTexture2D(&desc, None).unwrap();
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ mod tests {
|
|||
fn triangle_gl() {
|
||||
let (glfw, window, events, shader, vao) = hello_triangle::setup();
|
||||
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();
|
||||
hello_triangle::do_loop(glfw, window, events, shader, vao, &mut filter);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue