vk/d3d12: recompile pipelines on incompatible output format.
This also involves changes to the C API, since we're breaking API anyways might as well unify some type names. No breakages for D3D11.
This commit is contained in:
parent
771a0896d7
commit
5e99ddf73c
18 changed files with 334 additions and 163 deletions
|
@ -65,7 +65,7 @@ enum LIBRA_ERRNO
|
|||
#ifdef __cplusplus
|
||||
: int32_t
|
||||
#endif // __cplusplus
|
||||
{
|
||||
{
|
||||
LIBRA_ERRNO_UNKNOWN_ERROR = 0,
|
||||
LIBRA_ERRNO_INVALID_PARAMETER = 1,
|
||||
LIBRA_ERRNO_INVALID_STRING = 2,
|
||||
|
@ -181,14 +181,14 @@ typedef struct libra_viewport_t {
|
|||
|
||||
#if defined(LIBRA_RUNTIME_OPENGL)
|
||||
/// OpenGL parameters for the output framebuffer.
|
||||
typedef struct libra_draw_framebuffer_gl_t {
|
||||
typedef struct libra_output_framebuffer_gl_t {
|
||||
/// A framebuffer GLuint to the output framebuffer.
|
||||
uint32_t handle;
|
||||
/// A texture GLuint to the logical buffer of the output framebuffer.
|
||||
uint32_t texture;
|
||||
/// The format of the output framebuffer.
|
||||
uint32_t format;
|
||||
} libra_draw_framebuffer_gl_t;
|
||||
} libra_output_framebuffer_gl_t;
|
||||
#endif
|
||||
|
||||
/// Options for each OpenGL shader frame.
|
||||
|
@ -235,7 +235,7 @@ typedef struct _filter_chain_vk *libra_vk_filter_chain_t;
|
|||
|
||||
#if defined(LIBRA_RUNTIME_VULKAN)
|
||||
/// Vulkan parameters for the source image.
|
||||
typedef struct libra_image_vk_t {
|
||||
typedef struct libra_source_image_vk_t {
|
||||
/// A raw `VkImage` handle to the source image.
|
||||
VkImage handle;
|
||||
/// The `VkFormat` of the source image.
|
||||
|
@ -244,7 +244,17 @@ typedef struct libra_image_vk_t {
|
|||
uint32_t width;
|
||||
/// The height of the source image.
|
||||
uint32_t height;
|
||||
} libra_image_vk_t;
|
||||
} libra_source_image_vk_t;
|
||||
#endif
|
||||
|
||||
#if defined(LIBRA_RUNTIME_VULKAN)
|
||||
/// Vulkan parameters for the output image.
|
||||
typedef struct libra_output_image_vk_t {
|
||||
/// A raw `VkImage` handle to the output image.
|
||||
VkImage handle;
|
||||
/// The `VkFormat` of the output image.
|
||||
VkFormat format;
|
||||
} libra_output_image_vk_t;
|
||||
#endif
|
||||
|
||||
/// Options for each Vulkan shader frame.
|
||||
|
@ -310,7 +320,7 @@ typedef struct _filter_chain_d3d12 *libra_d3d12_filter_chain_t;
|
|||
#endif
|
||||
|
||||
#if defined(LIBRA_RUNTIME_D3D12)
|
||||
/// Direct3D 11 parameters for the source image.
|
||||
/// Direct3D 12 parameters for the source image.
|
||||
typedef struct libra_source_image_d3d12_t {
|
||||
/// The resource containing the image.
|
||||
const ID3D12Resource * resource;
|
||||
|
@ -325,6 +335,16 @@ typedef struct libra_source_image_d3d12_t {
|
|||
} libra_source_image_d3d12_t;
|
||||
#endif
|
||||
|
||||
#if defined(LIBRA_RUNTIME_D3D12)
|
||||
/// Direct3D 12 parameters for the output image.
|
||||
typedef struct libra_output_image_d3d12_t {
|
||||
/// A CPU descriptor handle to a shader resource view of the image.
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE descriptor;
|
||||
/// The format of the image.
|
||||
DXGI_FORMAT format;
|
||||
} libra_output_image_d3d12_t;
|
||||
#endif
|
||||
|
||||
/// Options for each Direct3D11 shader frame.
|
||||
typedef struct frame_d3d12_opt_t {
|
||||
/// Whether or not to clear the history buffers.
|
||||
|
@ -403,7 +423,7 @@ typedef libra_error_t (*PFN_libra_gl_filter_chain_frame)(libra_gl_filter_chain_t
|
|||
size_t frame_count,
|
||||
struct libra_source_image_gl_t image,
|
||||
struct libra_viewport_t viewport,
|
||||
struct libra_draw_framebuffer_gl_t out,
|
||||
struct libra_output_framebuffer_gl_t out,
|
||||
const float *mvp,
|
||||
const struct frame_gl_opt_t *opt);
|
||||
#endif
|
||||
|
@ -459,9 +479,9 @@ typedef libra_error_t (*PFN_libra_vk_filter_chain_create)(struct libra_device_vk
|
|||
typedef libra_error_t (*PFN_libra_vk_filter_chain_frame)(libra_vk_filter_chain_t *chain,
|
||||
VkCommandBuffer command_buffer,
|
||||
size_t frame_count,
|
||||
struct libra_image_vk_t image,
|
||||
struct libra_source_image_vk_t image,
|
||||
struct libra_viewport_t viewport,
|
||||
struct libra_image_vk_t out,
|
||||
struct libra_output_image_vk_t out,
|
||||
const float *mvp,
|
||||
const struct frame_vk_opt_t *opt);
|
||||
#endif
|
||||
|
@ -576,7 +596,7 @@ typedef libra_error_t (*PFN_libra_d3d12_filter_chain_frame)(libra_d3d12_filter_c
|
|||
size_t frame_count,
|
||||
struct libra_source_image_d3d12_t image,
|
||||
struct libra_viewport_t viewport,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE out,
|
||||
struct libra_output_image_d3d12_t out,
|
||||
const float *mvp,
|
||||
const struct frame_d3d12_opt_t *opt);
|
||||
#endif
|
||||
|
@ -777,7 +797,7 @@ libra_error_t libra_gl_filter_chain_frame(libra_gl_filter_chain_t *chain,
|
|||
size_t frame_count,
|
||||
struct libra_source_image_gl_t image,
|
||||
struct libra_viewport_t viewport,
|
||||
struct libra_draw_framebuffer_gl_t out,
|
||||
struct libra_output_framebuffer_gl_t out,
|
||||
const float *mvp,
|
||||
const struct frame_gl_opt_t *opt);
|
||||
#endif
|
||||
|
@ -870,9 +890,9 @@ libra_error_t libra_vk_filter_chain_create(struct libra_device_vk_t vulkan,
|
|||
libra_error_t libra_vk_filter_chain_frame(libra_vk_filter_chain_t *chain,
|
||||
VkCommandBuffer command_buffer,
|
||||
size_t frame_count,
|
||||
struct libra_image_vk_t image,
|
||||
struct libra_source_image_vk_t image,
|
||||
struct libra_viewport_t viewport,
|
||||
struct libra_image_vk_t out,
|
||||
struct libra_output_image_vk_t out,
|
||||
const float *mvp,
|
||||
const struct frame_vk_opt_t *opt);
|
||||
#endif
|
||||
|
@ -1053,7 +1073,7 @@ libra_error_t libra_d3d12_filter_chain_frame(libra_d3d12_filter_chain_t *chain,
|
|||
size_t frame_count,
|
||||
struct libra_source_image_d3d12_t image,
|
||||
struct libra_viewport_t viewport,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE out,
|
||||
struct libra_output_image_d3d12_t out,
|
||||
const float *mvp,
|
||||
const struct frame_d3d12_opt_t *opt);
|
||||
#endif
|
||||
|
|
|
@ -120,7 +120,7 @@ libra_error_t __librashader__noop_gl_filter_chain_create(
|
|||
libra_error_t __librashader__noop_gl_filter_chain_frame(
|
||||
libra_gl_filter_chain_t *chain, size_t frame_count,
|
||||
struct libra_source_image_gl_t image, struct libra_viewport_t viewport,
|
||||
struct libra_draw_framebuffer_gl_t out, const float *mvp,
|
||||
struct libra_output_framebuffer_gl_t out, const float *mvp,
|
||||
const struct frame_gl_opt_t *opt) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -160,8 +160,8 @@ libra_error_t __librashader__noop_vk_filter_chain_create(
|
|||
|
||||
libra_error_t __librashader__noop_vk_filter_chain_frame(
|
||||
libra_vk_filter_chain_t *chain, VkCommandBuffer command_buffer,
|
||||
size_t frame_count, struct libra_image_vk_t image,
|
||||
struct libra_viewport_t viewport, struct libra_image_vk_t out,
|
||||
size_t frame_count, struct libra_source_image_vk_t image,
|
||||
struct libra_viewport_t viewport, struct libra_output_image_vk_t out,
|
||||
const float *mvp, const struct frame_vk_opt_t *opt) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ libra_error_t __librashader__noop_d3d12_filter_chain_frame(
|
|||
libra_d3d12_filter_chain_t *chain,
|
||||
const ID3D12GraphicsCommandList *command_list, size_t frame_count,
|
||||
struct libra_source_image_d3d12_t image, struct libra_viewport_t viewport,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE out, const float *mvp,
|
||||
struct libra_output_image_d3d12_t out, const float *mvp,
|
||||
const struct frame_d3d12_opt_t *opt) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ pub use librashader::runtime::d3d12::capi::options::FrameOptionsD3D12;
|
|||
use librashader::runtime::d3d12::{D3D12InputImage, D3D12OutputView};
|
||||
use librashader::runtime::{FilterChainParameters, Size, Viewport};
|
||||
|
||||
/// Direct3D 11 parameters for the source image.
|
||||
/// Direct3D 12 parameters for the source image.
|
||||
#[repr(C)]
|
||||
pub struct libra_source_image_d3d12_t {
|
||||
/// The resource containing the image.
|
||||
|
@ -32,6 +32,15 @@ pub struct libra_source_image_d3d12_t {
|
|||
pub height: u32,
|
||||
}
|
||||
|
||||
/// Direct3D 12 parameters for the output image.
|
||||
#[repr(C)]
|
||||
pub struct libra_output_image_d3d12_t {
|
||||
/// A CPU descriptor handle to a shader resource view of the image.
|
||||
pub descriptor: D3D12_CPU_DESCRIPTOR_HANDLE,
|
||||
/// The format of the image.
|
||||
pub format: DXGI_FORMAT,
|
||||
}
|
||||
|
||||
impl TryFrom<libra_source_image_d3d12_t> for D3D12InputImage {
|
||||
type Error = LibrashaderError;
|
||||
|
||||
|
@ -111,7 +120,7 @@ extern_fn! {
|
|||
frame_count: usize,
|
||||
image: libra_source_image_d3d12_t,
|
||||
viewport: libra_viewport_t,
|
||||
out: D3D12_CPU_DESCRIPTOR_HANDLE,
|
||||
out: libra_output_image_d3d12_t,
|
||||
mvp: *const f32,
|
||||
opt: *const FrameOptionsD3D12
|
||||
) mut |chain| {
|
||||
|
@ -132,7 +141,7 @@ extern_fn! {
|
|||
let viewport = Viewport {
|
||||
x: viewport.x,
|
||||
y: viewport.y,
|
||||
output: unsafe { D3D12OutputView::new_from_raw(out, Size::new(viewport.width, viewport.height)) },
|
||||
output: unsafe { D3D12OutputView::new_from_raw(out.descriptor, Size::new(viewport.width, viewport.height), out.format) },
|
||||
mvp,
|
||||
};
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ pub struct libra_source_image_gl_t {
|
|||
|
||||
/// OpenGL parameters for the output framebuffer.
|
||||
#[repr(C)]
|
||||
pub struct libra_draw_framebuffer_gl_t {
|
||||
pub struct libra_output_framebuffer_gl_t {
|
||||
/// A framebuffer GLuint to the output framebuffer.
|
||||
pub handle: u32,
|
||||
/// A texture GLuint to the logical buffer of the output framebuffer.
|
||||
|
@ -125,7 +125,7 @@ extern_fn! {
|
|||
frame_count: usize,
|
||||
image: libra_source_image_gl_t,
|
||||
viewport: libra_viewport_t,
|
||||
out: libra_draw_framebuffer_gl_t,
|
||||
out: libra_output_framebuffer_gl_t,
|
||||
mvp: *const f32,
|
||||
opt: *const FrameOptionsGL
|
||||
) mut |chain| {
|
||||
|
|
|
@ -23,7 +23,7 @@ pub type libra_PFN_vkGetInstanceProcAddr =
|
|||
|
||||
/// Vulkan parameters for the source image.
|
||||
#[repr(C)]
|
||||
pub struct libra_image_vk_t {
|
||||
pub struct libra_source_image_vk_t {
|
||||
/// A raw `VkImage` handle to the source image.
|
||||
pub handle: vk::Image,
|
||||
/// The `VkFormat` of the source image.
|
||||
|
@ -34,6 +34,15 @@ pub struct libra_image_vk_t {
|
|||
pub height: u32,
|
||||
}
|
||||
|
||||
/// Vulkan parameters for the output image.
|
||||
#[repr(C)]
|
||||
pub struct libra_output_image_vk_t {
|
||||
/// A raw `VkImage` handle to the output image.
|
||||
pub handle: vk::Image,
|
||||
/// The `VkFormat` of the output image.
|
||||
pub format: vk::Format,
|
||||
}
|
||||
|
||||
/// Handles required to instantiate vulkan
|
||||
#[repr(C)]
|
||||
pub struct libra_device_vk_t {
|
||||
|
@ -50,8 +59,8 @@ pub struct libra_device_vk_t {
|
|||
pub entry: vk::PFN_vkGetInstanceProcAddr,
|
||||
}
|
||||
|
||||
impl From<libra_image_vk_t> for VulkanImage {
|
||||
fn from(value: libra_image_vk_t) -> Self {
|
||||
impl From<libra_source_image_vk_t> for VulkanImage {
|
||||
fn from(value: libra_source_image_vk_t) -> Self {
|
||||
VulkanImage {
|
||||
size: Size::new(value.width, value.height),
|
||||
image: value.handle,
|
||||
|
@ -134,15 +143,19 @@ extern_fn! {
|
|||
chain: *mut libra_vk_filter_chain_t,
|
||||
command_buffer: vk::CommandBuffer,
|
||||
frame_count: usize,
|
||||
image: libra_image_vk_t,
|
||||
image: libra_source_image_vk_t,
|
||||
viewport: libra_viewport_t,
|
||||
out: libra_image_vk_t,
|
||||
out: libra_output_image_vk_t,
|
||||
mvp: *const f32,
|
||||
opt: *const FrameOptionsVulkan
|
||||
) mut |chain| {
|
||||
assert_some_ptr!(mut chain);
|
||||
let image: VulkanImage = image.into();
|
||||
let output = out.into();
|
||||
let output = VulkanImage {
|
||||
image: out.handle,
|
||||
size: Size::new(viewport.width, viewport.height),
|
||||
format: out.format
|
||||
};
|
||||
let mvp = if mvp.is_null() {
|
||||
None
|
||||
} else {
|
||||
|
|
|
@ -407,7 +407,7 @@ impl FilterChainD3D12 {
|
|||
validator,
|
||||
&dxil,
|
||||
root_signature,
|
||||
render_format,
|
||||
render_format
|
||||
) {
|
||||
(dxil_reflection, graphics_pipeline)
|
||||
} else {
|
||||
|
@ -688,6 +688,15 @@ impl FilterChainD3D12 {
|
|||
// try to hint the optimizer
|
||||
assert_eq!(last.len(), 1);
|
||||
if let Some(pass) = last.iter_mut().next() {
|
||||
if pass.pipeline.format != viewport.output.format {
|
||||
// eprintln!("recompiling final pipeline");
|
||||
pass.pipeline.recompile(
|
||||
viewport.output.format,
|
||||
&self.common.root_signature,
|
||||
&self.common.d3d12,
|
||||
)?;
|
||||
}
|
||||
|
||||
source.filter = pass.config.filter;
|
||||
source.wrap_mode = pass.config.wrap_mode;
|
||||
|
||||
|
|
|
@ -281,7 +281,11 @@ impl OwnedImage {
|
|||
);
|
||||
}
|
||||
|
||||
Ok(D3D12OutputView::new(descriptor, self.size))
|
||||
Ok(D3D12OutputView::new(
|
||||
descriptor,
|
||||
self.size,
|
||||
self.format.into(),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn scale(
|
||||
|
|
|
@ -7,7 +7,9 @@ use librashader_reflect::back::dxil::DxilObject;
|
|||
use librashader_reflect::back::ShaderCompilerOutput;
|
||||
use librashader_reflect::reflect::semantics::BindingStage;
|
||||
use windows::Win32::Foundation::BOOL;
|
||||
use windows::Win32::Graphics::Direct3D::Dxc::{IDxcBlob, IDxcCompiler, IDxcUtils, IDxcValidator};
|
||||
use windows::Win32::Graphics::Direct3D::Dxc::{
|
||||
CLSID_DxcLibrary, DxcCreateInstance, IDxcBlob, IDxcCompiler, IDxcUtils, IDxcValidator, DXC_CP,
|
||||
};
|
||||
use windows::Win32::Graphics::Direct3D12::{
|
||||
D3D12SerializeVersionedRootSignature, ID3D12Device, ID3D12PipelineState, ID3D12RootSignature,
|
||||
D3D12_BLEND_DESC, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, D3D12_BLEND_SRC_ALPHA,
|
||||
|
@ -29,6 +31,9 @@ use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_FORMAT_UNKNOWN, D
|
|||
|
||||
pub struct D3D12GraphicsPipeline {
|
||||
pub(crate) handle: ID3D12PipelineState,
|
||||
pub(crate) format: DXGI_FORMAT,
|
||||
vertex: Vec<u8>,
|
||||
fragment: Vec<u8>,
|
||||
}
|
||||
|
||||
const D3D12_SLANG_ROOT_PARAMETERS: &[D3D12_ROOT_PARAMETER1; 4] = &[
|
||||
|
@ -218,10 +223,50 @@ impl D3D12GraphicsPipeline {
|
|||
device.CreateGraphicsPipelineState(&pipeline_desc)?
|
||||
};
|
||||
|
||||
unsafe {
|
||||
let vertex = Vec::from(std::slice::from_raw_parts(
|
||||
vertex_dxil.GetBufferPointer().cast(),
|
||||
vertex_dxil.GetBufferSize(),
|
||||
));
|
||||
let fragment = Vec::from(std::slice::from_raw_parts(
|
||||
fragment_dxil.GetBufferPointer().cast(),
|
||||
fragment_dxil.GetBufferSize(),
|
||||
));
|
||||
Ok(D3D12GraphicsPipeline {
|
||||
handle: pipeline_state,
|
||||
format: render_format,
|
||||
vertex,
|
||||
fragment,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn recompile(
|
||||
&mut self,
|
||||
format: DXGI_FORMAT,
|
||||
root_sig: &D3D12RootSignature,
|
||||
device: &ID3D12Device,
|
||||
) -> error::Result<()> {
|
||||
let (vertex, fragment) = unsafe {
|
||||
let library: IDxcUtils = DxcCreateInstance(&CLSID_DxcLibrary)?;
|
||||
let vertex = library.CreateBlobFromPinned(
|
||||
self.vertex.as_ptr().cast(),
|
||||
self.vertex.len() as u32,
|
||||
DXC_CP(0),
|
||||
)?;
|
||||
let fragment = library.CreateBlobFromPinned(
|
||||
self.fragment.as_ptr().cast(),
|
||||
self.fragment.len() as u32,
|
||||
DXC_CP(0),
|
||||
)?;
|
||||
(vertex, fragment)
|
||||
};
|
||||
let mut new_pipeline =
|
||||
Self::new_from_blobs(device, vertex.into(), fragment.into(), root_sig, format)?;
|
||||
|
||||
std::mem::swap(self, &mut new_pipeline);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn new_from_dxil(
|
||||
device: &ID3D12Device,
|
||||
|
|
|
@ -636,6 +636,7 @@ pub mod d3d12_hello_triangle {
|
|||
resources.viewport.Width as u32,
|
||||
resources.viewport.Height as u32,
|
||||
),
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
),
|
||||
},
|
||||
frame_count,
|
||||
|
|
|
@ -33,7 +33,7 @@ mod tests {
|
|||
fn triangle_d3d12() {
|
||||
let sample = hello_triangle::d3d12_hello_triangle::Sample::new(
|
||||
// "../test/slang-shaders/crt/crt-lottes.slangp",
|
||||
"../test/slang-shaders/bezel/Mega_Bezel/Presets/Variations/Megatron/ADV/crt-sony-megatron-aeg-CTV-4800-VT-sdr.slangp",
|
||||
"../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV-GLASS.slangp",
|
||||
// "../test/slang-shaders/crt/crt-royale.slangp",
|
||||
// "../test/slang-shaders/vhs/VHSPro.slangp",
|
||||
&SampleCommandLine {
|
||||
|
|
|
@ -49,24 +49,35 @@ impl AsRef<D3D12_CPU_DESCRIPTOR_HANDLE> for OutputDescriptor {
|
|||
pub struct D3D12OutputView {
|
||||
pub(crate) descriptor: OutputDescriptor,
|
||||
pub(crate) size: Size<u32>,
|
||||
pub(crate) format: DXGI_FORMAT,
|
||||
}
|
||||
|
||||
impl D3D12OutputView {
|
||||
pub(crate) fn new(
|
||||
handle: D3D12DescriptorHeapSlot<RenderTargetHeap>,
|
||||
size: Size<u32>,
|
||||
format: DXGI_FORMAT,
|
||||
) -> D3D12OutputView {
|
||||
let descriptor = OutputDescriptor::Owned(handle);
|
||||
D3D12OutputView { descriptor, size }
|
||||
D3D12OutputView {
|
||||
descriptor,
|
||||
size,
|
||||
format,
|
||||
}
|
||||
}
|
||||
|
||||
// unsafe since the lifetime of the handle has to survive
|
||||
pub unsafe fn new_from_raw(
|
||||
handle: D3D12_CPU_DESCRIPTOR_HANDLE,
|
||||
size: Size<u32>,
|
||||
format: DXGI_FORMAT,
|
||||
) -> D3D12OutputView {
|
||||
let descriptor = OutputDescriptor::Raw(handle);
|
||||
D3D12OutputView { descriptor, size }
|
||||
D3D12OutputView {
|
||||
descriptor,
|
||||
size,
|
||||
format,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,13 +2,13 @@ use crate::draw_quad::DrawQuad;
|
|||
use crate::error::FilterChainError;
|
||||
use crate::filter_pass::FilterPass;
|
||||
use crate::framebuffer::OutputImage;
|
||||
use crate::graphics_pipeline::VulkanGraphicsPipeline;
|
||||
use crate::luts::LutTexture;
|
||||
use crate::options::{FilterChainOptionsVulkan, FrameOptionsVulkan};
|
||||
use crate::queue_selection::get_graphics_queue;
|
||||
use crate::samplers::SamplerSet;
|
||||
use crate::texture::{InputImage, OwnedImage, OwnedImageLayout, VulkanImage};
|
||||
use crate::vulkan_primitives::RawVulkanBuffer;
|
||||
use crate::vulkan_state::VulkanGraphicsPipeline;
|
||||
use crate::{error, util};
|
||||
use ash::vk;
|
||||
use librashader_common::{ImageFormat, Size, Viewport};
|
||||
|
@ -682,6 +682,12 @@ impl FilterChainVulkan {
|
|||
// try to hint the optimizer
|
||||
assert_eq!(last.len(), 1);
|
||||
if let Some(pass) = last.iter_mut().next() {
|
||||
if let Some(format) = pass.graphics_pipeline.render_pass.as_ref().map(|r| r.format)
|
||||
&& format != viewport.output.format {
|
||||
// need to recompile
|
||||
pass.graphics_pipeline.recompile(viewport.output.format)?;
|
||||
}
|
||||
|
||||
source.filter_mode = pass.config.filter;
|
||||
source.wrap_mode = pass.config.wrap_mode;
|
||||
source.mip_filter = pass.config.filter;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::filter_chain::FilterCommon;
|
||||
use crate::framebuffer::OutputImage;
|
||||
use crate::graphics_pipeline::VulkanGraphicsPipeline;
|
||||
use crate::samplers::SamplerSet;
|
||||
use crate::texture::InputImage;
|
||||
use crate::vulkan_primitives::RawVulkanBuffer;
|
||||
use crate::vulkan_state::VulkanGraphicsPipeline;
|
||||
use crate::{error, VulkanImage};
|
||||
use ash::vk;
|
||||
use librashader_common::{ImageFormat, Size, Viewport};
|
||||
|
|
|
@ -8,6 +8,7 @@ use librashader_reflect::reflect::semantics::{TextureBinding, UboReflection};
|
|||
use librashader_reflect::reflect::ShaderReflection;
|
||||
use librashader_runtime::render_target::RenderTarget;
|
||||
use std::ffi::CStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
const ENTRY_POINT: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"main\0") };
|
||||
|
||||
|
@ -177,19 +178,21 @@ pub struct VulkanGraphicsPipeline {
|
|||
pub layout: PipelineLayoutObjects,
|
||||
pub pipeline: vk::Pipeline,
|
||||
pub render_pass: Option<VulkanRenderPass>,
|
||||
device: Arc<ash::Device>,
|
||||
vertex: VulkanShaderModule,
|
||||
fragment: VulkanShaderModule,
|
||||
cache: vk::PipelineCache,
|
||||
}
|
||||
|
||||
impl VulkanGraphicsPipeline {
|
||||
pub fn new(
|
||||
fn create_pipeline(
|
||||
device: &ash::Device,
|
||||
cache: &vk::PipelineCache,
|
||||
shader_assembly: &ShaderCompilerOutput<Vec<u32>>,
|
||||
reflection: &ShaderReflection,
|
||||
replicas: u32,
|
||||
render_pass_format: vk::Format,
|
||||
) -> error::Result<VulkanGraphicsPipeline> {
|
||||
let pipeline_layout = PipelineLayoutObjects::new(reflection, replicas, device)?;
|
||||
|
||||
pipeline_layout: &PipelineLayoutObjects,
|
||||
vertex_module: &VulkanShaderModule,
|
||||
fragment_module: &VulkanShaderModule,
|
||||
render_pass: Option<&VulkanRenderPass>,
|
||||
) -> error::Result<vk::Pipeline> {
|
||||
let input_assembly = vk::PipelineInputAssemblyStateCreateInfo::builder()
|
||||
.topology(vk::PrimitiveTopology::TRIANGLE_STRIP)
|
||||
.build();
|
||||
|
@ -262,16 +265,6 @@ impl VulkanGraphicsPipeline {
|
|||
.dynamic_states(&states)
|
||||
.build();
|
||||
|
||||
let vertex_info = vk::ShaderModuleCreateInfo::builder()
|
||||
.code(shader_assembly.vertex.as_ref())
|
||||
.build();
|
||||
let fragment_info = vk::ShaderModuleCreateInfo::builder()
|
||||
.code(shader_assembly.fragment.as_ref())
|
||||
.build();
|
||||
|
||||
let vertex_module = VulkanShaderModule::new(device, &vertex_info)?;
|
||||
let fragment_module = VulkanShaderModule::new(device, &fragment_info)?;
|
||||
|
||||
let shader_stages = [
|
||||
vk::PipelineShaderStageCreateInfo::builder()
|
||||
.stage(vk::ShaderStageFlags::VERTEX)
|
||||
|
@ -297,32 +290,93 @@ impl VulkanGraphicsPipeline {
|
|||
.dynamic_state(&dynamic_state)
|
||||
.layout(pipeline_layout.layout);
|
||||
|
||||
if let Some(render_pass) = render_pass {
|
||||
pipeline_info = pipeline_info.render_pass(render_pass.handle)
|
||||
}
|
||||
|
||||
let pipeline_info = [pipeline_info.build()];
|
||||
|
||||
let pipeline = unsafe {
|
||||
// panic_safety: if this is successful this should return 1 pipelines.
|
||||
device
|
||||
.create_graphics_pipelines(*cache, &pipeline_info, None)
|
||||
.map_err(|e| e.1)
|
||||
.unwrap()[0]
|
||||
};
|
||||
|
||||
Ok(pipeline)
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
device: &Arc<ash::Device>,
|
||||
cache: &vk::PipelineCache,
|
||||
shader_assembly: &ShaderCompilerOutput<Vec<u32>>,
|
||||
reflection: &ShaderReflection,
|
||||
replicas: u32,
|
||||
render_pass_format: vk::Format,
|
||||
) -> error::Result<VulkanGraphicsPipeline> {
|
||||
let pipeline_layout = PipelineLayoutObjects::new(reflection, replicas, device)?;
|
||||
|
||||
let vertex_info = vk::ShaderModuleCreateInfo::builder()
|
||||
.code(shader_assembly.vertex.as_ref())
|
||||
.build();
|
||||
let fragment_info = vk::ShaderModuleCreateInfo::builder()
|
||||
.code(shader_assembly.fragment.as_ref())
|
||||
.build();
|
||||
|
||||
let vertex_module = VulkanShaderModule::new(device, &vertex_info)?;
|
||||
let fragment_module = VulkanShaderModule::new(device, &fragment_info)?;
|
||||
|
||||
let mut render_pass = None;
|
||||
if render_pass_format != vk::Format::UNDEFINED {
|
||||
render_pass = Some(VulkanRenderPass::create_render_pass(
|
||||
device,
|
||||
render_pass_format,
|
||||
)?);
|
||||
pipeline_info = pipeline_info.render_pass(render_pass.as_ref().unwrap().handle)
|
||||
}
|
||||
|
||||
let pipeline_info = pipeline_info.build();
|
||||
|
||||
let pipeline = unsafe {
|
||||
// panic_safety: if this is successful this should return 1 pipelines.
|
||||
device
|
||||
.create_graphics_pipelines(*cache, &[pipeline_info], None)
|
||||
.map_err(|e| e.1)
|
||||
.unwrap()[0]
|
||||
};
|
||||
let pipeline = Self::create_pipeline(
|
||||
&device,
|
||||
&cache,
|
||||
&pipeline_layout,
|
||||
&vertex_module,
|
||||
&fragment_module,
|
||||
render_pass.as_ref(),
|
||||
)?;
|
||||
|
||||
Ok(VulkanGraphicsPipeline {
|
||||
device: Arc::clone(device),
|
||||
layout: pipeline_layout,
|
||||
pipeline,
|
||||
render_pass,
|
||||
vertex: vertex_module,
|
||||
fragment: fragment_module,
|
||||
cache: *cache,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn recompile(&mut self, format: vk::Format) -> error::Result<()> {
|
||||
let mut new_renderpass = if self.render_pass.is_some() {
|
||||
Some(VulkanRenderPass::create_render_pass(&self.device, format)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let mut new_pipeline = Self::create_pipeline(
|
||||
&self.device,
|
||||
&self.cache,
|
||||
&self.layout,
|
||||
&self.vertex,
|
||||
&self.fragment,
|
||||
new_renderpass.as_ref(),
|
||||
)?;
|
||||
|
||||
std::mem::swap(&mut self.render_pass, &mut new_renderpass);
|
||||
std::mem::swap(&mut self.pipeline, &mut new_pipeline);
|
||||
|
||||
unsafe { self.device.destroy_pipeline(new_pipeline, None) }
|
||||
Ok(())
|
||||
}
|
||||
#[inline(always)]
|
||||
pub(crate) fn begin_rendering(
|
||||
&self,
|
|
@ -11,6 +11,7 @@ mod draw_quad;
|
|||
mod filter_chain;
|
||||
mod filter_pass;
|
||||
mod framebuffer;
|
||||
mod graphics_pipeline;
|
||||
#[cfg(test)]
|
||||
mod hello_triangle;
|
||||
mod luts;
|
||||
|
@ -20,7 +21,6 @@ mod samplers;
|
|||
mod texture;
|
||||
mod util;
|
||||
mod vulkan_primitives;
|
||||
mod vulkan_state;
|
||||
|
||||
pub use filter_chain::FilterChainVulkan;
|
||||
pub use filter_chain::VulkanInstance;
|
||||
|
@ -41,7 +41,6 @@ mod tests {
|
|||
fn triangle_vk() {
|
||||
let entry = unsafe { ash::Entry::load().unwrap() };
|
||||
let base = VulkanBase::new(entry).unwrap();
|
||||
dbg!("finished");
|
||||
let filter = FilterChainVulkan::load_from_path(
|
||||
&base,
|
||||
// "../test/slang-shaders/crt/crt-royale.slangp",
|
||||
|
@ -50,7 +49,7 @@ mod tests {
|
|||
Some(&FilterChainOptionsVulkan {
|
||||
frames_in_flight: 3,
|
||||
force_no_mipmaps: false,
|
||||
use_render_pass: false,
|
||||
use_render_pass: true,
|
||||
}),
|
||||
)
|
||||
.unwrap();
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
|
||||
#include <iostream>
|
||||
#include <filesystem>
|
||||
#define LIBRA_RUNTIME_VULKAN
|
||||
#define LIBRA_RUNTIME_OPENGL
|
||||
#define LIBRA_RUNTIME_D3D11
|
||||
#define LIBRA_RUNTIME_D3D12
|
||||
|
||||
|
||||
#include "../../../../include/librashader_ld.h"
|
||||
int main()
|
||||
|
@ -16,11 +21,11 @@ int main()
|
|||
"gameboy-player-crt-royale.slangp",
|
||||
&preset);
|
||||
|
||||
libra_shader_preset_t preset2;
|
||||
/* libra_shader_preset_t preset2;
|
||||
libra_preset_create(
|
||||
"../../../slang-shaders/border/gameboy-player/"
|
||||
"gameboy-player-crt-royale.slangp",
|
||||
&preset2);
|
||||
&preset2);*/
|
||||
|
||||
instance.preset_print(&preset);
|
||||
std::cout << "printed\n";
|
||||
|
|
|
@ -108,7 +108,7 @@
|
|||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<TreatAngleIncludeAsExternal>false</TreatAngleIncludeAsExternal>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
||||
<AdditionalIncludeDirectories>D:\Runtime\Vulkan\1.3.224.1\Include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
|
@ -128,6 +128,7 @@
|
|||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>D:\Runtime\Vulkan\1.3.224.1\Include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -145,9 +146,6 @@
|
|||
<ClInclude Include="..\..\..\..\include\librashader.h" />
|
||||
<ClInclude Include="..\..\..\..\include\librashader_ld.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Library Include="..\..\..\..\target\debug\librashader.lib" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
|
|
@ -27,7 +27,4 @@
|
|||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Library Include="..\..\..\..\target\debug\librashader.lib" />
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Add table
Reference in a new issue