test: make RenderTest trait object safe
This commit is contained in:
parent
f7a938a00d
commit
eeda0d02d0
|
@ -6,14 +6,14 @@ use librashader::runtime::{Size, Viewport};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
impl RenderTest for Direct3D11 {
|
impl RenderTest for Direct3D11 {
|
||||||
fn new(path: impl AsRef<Path>) -> anyhow::Result<Self>
|
fn new(path: &Path) -> anyhow::Result<Self>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
Direct3D11::new(path)
|
Direct3D11::new(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&mut self, path: impl AsRef<Path>, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
fn render(&mut self, path: &Path, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
||||||
let (renderbuffer, rtv) = self.create_renderbuffer(self.image_bytes.size)?;
|
let (renderbuffer, rtv) = self.create_renderbuffer(self.image_bytes.size)?;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -87,7 +87,7 @@ use windows::{
|
||||||
pub struct Direct3D11 {
|
pub struct Direct3D11 {
|
||||||
device: ID3D11Device,
|
device: ID3D11Device,
|
||||||
immediate_context: ID3D11DeviceContext,
|
immediate_context: ID3D11DeviceContext,
|
||||||
image_tex: ID3D11Texture2D,
|
_image_tex: ID3D11Texture2D,
|
||||||
image_srv: ID3D11ShaderResourceView,
|
image_srv: ID3D11ShaderResourceView,
|
||||||
image_bytes: Image,
|
image_bytes: Image,
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ impl Direct3D11 {
|
||||||
Ok((dxgi_factory, out_device.unwrap(), out_context.unwrap()))
|
Ok((dxgi_factory, out_device.unwrap(), out_context.unwrap()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(image_path: impl AsRef<Path>) -> anyhow::Result<Self> {
|
pub fn new(image_path: &Path) -> anyhow::Result<Self> {
|
||||||
let (_factory, device, imm_context) = Self::create_device()?;
|
let (_factory, device, imm_context) = Self::create_device()?;
|
||||||
|
|
||||||
let (image, image_tex, srv) = Self::load_image(&device, image_path)?;
|
let (image, image_tex, srv) = Self::load_image(&device, image_path)?;
|
||||||
|
@ -125,17 +125,17 @@ impl Direct3D11 {
|
||||||
device,
|
device,
|
||||||
immediate_context: imm_context,
|
immediate_context: imm_context,
|
||||||
image_bytes: image,
|
image_bytes: image,
|
||||||
image_tex,
|
_image_tex: image_tex,
|
||||||
image_srv: srv,
|
image_srv: srv,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_image(
|
fn load_image(
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
image_path: impl AsRef<Path>,
|
image_path: &Path,
|
||||||
) -> anyhow::Result<(Image, ID3D11Texture2D, ID3D11ShaderResourceView)> {
|
) -> anyhow::Result<(Image, ID3D11Texture2D, ID3D11ShaderResourceView)> {
|
||||||
let image = Image::load(image_path, UVDirection::TopLeft)?;
|
let image = Image::load(image_path, UVDirection::TopLeft)?;
|
||||||
let mut desc = D3D11_TEXTURE2D_DESC {
|
let desc = D3D11_TEXTURE2D_DESC {
|
||||||
Width: image.size.width,
|
Width: image.size.width,
|
||||||
Height: image.size.height,
|
Height: image.size.height,
|
||||||
// todo: set this to 0
|
// todo: set this to 0
|
||||||
|
|
|
@ -11,57 +11,54 @@ use librashader::runtime::d3d12::{
|
||||||
};
|
};
|
||||||
use librashader::runtime::Viewport;
|
use librashader::runtime::Viewport;
|
||||||
use librashader_runtime::image::{Image, PixelFormat, UVDirection, BGRA8};
|
use librashader_runtime::image::{Image, PixelFormat, UVDirection, BGRA8};
|
||||||
use std::ffi::CStr;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use windows::core::Interface;
|
use windows::core::Interface;
|
||||||
use windows::Win32::Foundation::CloseHandle;
|
use windows::Win32::Foundation::CloseHandle;
|
||||||
use windows::Win32::Graphics::Direct3D::{D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_12_1};
|
use windows::Win32::Graphics::Direct3D::{D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_12_1};
|
||||||
use windows::Win32::Graphics::Direct3D12::{
|
use windows::Win32::Graphics::Direct3D12::{
|
||||||
D3D12CreateDevice, ID3D12CommandAllocator, ID3D12CommandQueue, ID3D12Device, ID3D12Fence,
|
D3D12CreateDevice, ID3D12CommandAllocator, ID3D12CommandQueue, ID3D12Device, ID3D12Fence,
|
||||||
ID3D12GraphicsCommandList, ID3D12InfoQueue1, ID3D12Resource, D3D12_COMMAND_LIST_TYPE_DIRECT,
|
ID3D12GraphicsCommandList, ID3D12Resource, D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||||
D3D12_COMMAND_QUEUE_DESC, D3D12_COMMAND_QUEUE_FLAG_NONE, D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
|
D3D12_COMMAND_QUEUE_DESC, D3D12_COMMAND_QUEUE_FLAG_NONE, D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
|
||||||
D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING,
|
D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING,
|
||||||
D3D12_FENCE_FLAG_NONE, D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES, D3D12_HEAP_TYPE_CUSTOM,
|
D3D12_FENCE_FLAG_NONE, D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES, D3D12_HEAP_TYPE_CUSTOM,
|
||||||
D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_TYPE_UPLOAD, D3D12_MEMORY_POOL_L0,
|
D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_TYPE_UPLOAD, D3D12_MEMORY_POOL_L0,
|
||||||
D3D12_MEMORY_POOL_UNKNOWN, D3D12_MESSAGE_CALLBACK_FLAG_NONE, D3D12_MESSAGE_CATEGORY,
|
D3D12_MEMORY_POOL_UNKNOWN, D3D12_PLACED_SUBRESOURCE_FOOTPRINT, D3D12_RESOURCE_DESC,
|
||||||
D3D12_MESSAGE_ID, D3D12_MESSAGE_SEVERITY, D3D12_PLACED_SUBRESOURCE_FOOTPRINT,
|
|
||||||
D3D12_RENDER_TARGET_VIEW_DESC, D3D12_RENDER_TARGET_VIEW_DESC_0, D3D12_RESOURCE_DESC,
|
|
||||||
D3D12_RESOURCE_DIMENSION_BUFFER, D3D12_RESOURCE_DIMENSION_TEXTURE2D,
|
D3D12_RESOURCE_DIMENSION_BUFFER, D3D12_RESOURCE_DIMENSION_TEXTURE2D,
|
||||||
D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE,
|
D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, D3D12_RESOURCE_STATE_COMMON,
|
||||||
D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_GENERIC_READ,
|
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET,
|
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||||
D3D12_RTV_DIMENSION_TEXTURE2D, D3D12_SHADER_RESOURCE_VIEW_DESC,
|
D3D12_SHADER_RESOURCE_VIEW_DESC, D3D12_SHADER_RESOURCE_VIEW_DESC_0,
|
||||||
D3D12_SHADER_RESOURCE_VIEW_DESC_0, D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_SUBRESOURCE_DATA,
|
D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_SUBRESOURCE_DATA, D3D12_TEX2D_SRV,
|
||||||
D3D12_TEX2D_RTV, D3D12_TEX2D_SRV, D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
|
D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
|
||||||
};
|
};
|
||||||
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_SAMPLE_DESC};
|
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_SAMPLE_DESC};
|
||||||
use windows::Win32::Graphics::Dxgi::{
|
use windows::Win32::Graphics::Dxgi::{
|
||||||
CreateDXGIFactory2, IDXGIAdapter1, IDXGIFactory4, DXGI_ADAPTER_FLAG_NONE,
|
CreateDXGIFactory2, IDXGIAdapter1, IDXGIFactory4, DXGI_ADAPTER_FLAG_NONE,
|
||||||
DXGI_ADAPTER_FLAG_SOFTWARE, DXGI_CREATE_FACTORY_DEBUG, DXGI_CREATE_FACTORY_FLAGS,
|
DXGI_ADAPTER_FLAG_SOFTWARE, DXGI_CREATE_FACTORY_DEBUG,
|
||||||
};
|
};
|
||||||
use windows::Win32::System::Threading::{CreateEventA, WaitForSingleObject, INFINITE};
|
use windows::Win32::System::Threading::{CreateEventA, WaitForSingleObject, INFINITE};
|
||||||
|
|
||||||
pub struct Direct3D12 {
|
pub struct Direct3D12 {
|
||||||
device: ID3D12Device,
|
device: ID3D12Device,
|
||||||
cpu_heap: D3D12DescriptorHeap<CpuStagingHeap>,
|
_cpu_heap: D3D12DescriptorHeap<CpuStagingHeap>,
|
||||||
rtv_heap: D3D12DescriptorHeap<RenderTargetHeap>,
|
rtv_heap: D3D12DescriptorHeap<RenderTargetHeap>,
|
||||||
|
|
||||||
texture: D3D12InputImage,
|
texture: D3D12InputImage,
|
||||||
heap_slot: D3D12DescriptorHeapSlot<CpuStagingHeap>,
|
_heap_slot: D3D12DescriptorHeapSlot<CpuStagingHeap>,
|
||||||
command_pool: ID3D12CommandAllocator,
|
command_pool: ID3D12CommandAllocator,
|
||||||
queue: ID3D12CommandQueue,
|
queue: ID3D12CommandQueue,
|
||||||
image: Image<BGRA8>,
|
image: Image<BGRA8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderTest for Direct3D12 {
|
impl RenderTest for Direct3D12 {
|
||||||
fn new(path: impl AsRef<Path>) -> anyhow::Result<Self>
|
fn new(path: &Path) -> anyhow::Result<Self>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
Direct3D12::new(path)
|
Direct3D12::new(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&mut self, path: impl AsRef<Path>, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
fn render(&mut self, path: &Path, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let descriptor = self.rtv_heap.allocate_descriptor()?;
|
let descriptor = self.rtv_heap.allocate_descriptor()?;
|
||||||
|
|
||||||
|
@ -175,10 +172,10 @@ impl RenderTest for Direct3D12 {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Direct3D12 {
|
impl Direct3D12 {
|
||||||
pub fn new(image_path: impl AsRef<Path>) -> anyhow::Result<Self> {
|
pub fn new(image_path: &Path) -> anyhow::Result<Self> {
|
||||||
let device = Self::create_device()?;
|
let device = Self::create_device()?;
|
||||||
let mut heap = unsafe { D3D12DescriptorHeap::new(&device, 8)? };
|
let mut heap = unsafe { D3D12DescriptorHeap::new(&device, 8)? };
|
||||||
let mut rtv_heap = unsafe { D3D12DescriptorHeap::new(&device, 16)? };
|
let rtv_heap = unsafe { D3D12DescriptorHeap::new(&device, 16)? };
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let command_pool: ID3D12CommandAllocator =
|
let command_pool: ID3D12CommandAllocator =
|
||||||
|
@ -196,10 +193,10 @@ impl Direct3D12 {
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
device,
|
device,
|
||||||
cpu_heap: heap,
|
_cpu_heap: heap,
|
||||||
rtv_heap,
|
rtv_heap,
|
||||||
texture,
|
texture,
|
||||||
heap_slot,
|
_heap_slot: heap_slot,
|
||||||
command_pool,
|
command_pool,
|
||||||
image,
|
image,
|
||||||
queue,
|
queue,
|
||||||
|
@ -225,7 +222,7 @@ impl Direct3D12 {
|
||||||
command_pool: &ID3D12CommandAllocator,
|
command_pool: &ID3D12CommandAllocator,
|
||||||
queue: &ID3D12CommandQueue,
|
queue: &ID3D12CommandQueue,
|
||||||
heap: &mut D3D12DescriptorHeap<CpuStagingHeap>,
|
heap: &mut D3D12DescriptorHeap<CpuStagingHeap>,
|
||||||
path: impl AsRef<Path>,
|
path: &Path,
|
||||||
) -> anyhow::Result<(
|
) -> anyhow::Result<(
|
||||||
Image<BGRA8>,
|
Image<BGRA8>,
|
||||||
D3D12InputImage,
|
D3D12InputImage,
|
||||||
|
@ -386,7 +383,7 @@ impl Direct3D12 {
|
||||||
for i in 0.. {
|
for i in 0.. {
|
||||||
let adapter = unsafe { factory.EnumAdapters1(i)? };
|
let adapter = unsafe { factory.EnumAdapters1(i)? };
|
||||||
|
|
||||||
let mut desc = unsafe { adapter.GetDesc1()? };
|
let desc = unsafe { adapter.GetDesc1()? };
|
||||||
|
|
||||||
if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE.0 as u32) != DXGI_ADAPTER_FLAG_NONE.0 as u32
|
if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE.0 as u32) != DXGI_ADAPTER_FLAG_NONE.0 as u32
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use std::mem::ManuallyDrop;
|
use std::mem::ManuallyDrop;
|
||||||
use windows::Win32::Graphics::Direct3D12::{
|
use windows::Win32::Graphics::Direct3D12::{
|
||||||
ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_FEATURE_FORMAT_SUPPORT,
|
ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_MEMCPY_DEST,
|
||||||
D3D12_MEMCPY_DEST, D3D12_PLACED_SUBRESOURCE_FOOTPRINT, D3D12_RESOURCE_BARRIER,
|
D3D12_PLACED_SUBRESOURCE_FOOTPRINT, D3D12_RESOURCE_BARRIER, D3D12_RESOURCE_BARRIER_0,
|
||||||
D3D12_RESOURCE_BARRIER_0, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
|
D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, D3D12_RESOURCE_BARRIER_FLAG_NONE,
|
||||||
D3D12_RESOURCE_BARRIER_FLAG_NONE, D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
|
D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, D3D12_RESOURCE_DIMENSION_BUFFER, D3D12_RESOURCE_STATES,
|
||||||
D3D12_RESOURCE_DIMENSION_BUFFER, D3D12_RESOURCE_STATES, D3D12_RESOURCE_TRANSITION_BARRIER,
|
D3D12_RESOURCE_TRANSITION_BARRIER, D3D12_SUBRESOURCE_DATA, D3D12_TEXTURE_COPY_LOCATION,
|
||||||
D3D12_SUBRESOURCE_DATA, D3D12_TEXTURE_COPY_LOCATION, D3D12_TEXTURE_COPY_LOCATION_0,
|
D3D12_TEXTURE_COPY_LOCATION_0, D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
|
||||||
D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
|
@ -22,14 +22,14 @@ pub struct Direct3D9 {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderTest for Direct3D9 {
|
impl RenderTest for Direct3D9 {
|
||||||
fn new(path: impl AsRef<Path>) -> anyhow::Result<Self>
|
fn new(path: &Path) -> anyhow::Result<Self>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
Direct3D9::new(path)
|
Direct3D9::new(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&mut self, path: impl AsRef<Path>, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
fn render(&mut self, path: &Path, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut filter_chain = FilterChain::load_from_path(
|
let mut filter_chain = FilterChain::load_from_path(
|
||||||
path,
|
path,
|
||||||
|
|
|
@ -20,19 +20,14 @@
|
||||||
|
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use glfw::{fail_on_errors, Context, Glfw, OpenGlProfileHint, PWindow, WindowHint, WindowMode};
|
use glfw::{fail_on_errors, Context, Glfw, OpenGlProfileHint, PWindow, WindowHint, WindowMode};
|
||||||
use glow::HasContext;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub struct GlfwContext {
|
pub struct GlfwContext {
|
||||||
wnd: PWindow,
|
_wnd: PWindow,
|
||||||
glfw: Glfw,
|
_glfw: Glfw,
|
||||||
pub gl: Arc<glow::Context>,
|
pub gl: Arc<glow::Context>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug_callback(_source: u32, _err_type: u32, _id: u32, _severity: u32, message: &str) {
|
|
||||||
println!("[gl] {message:?}");
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GlfwContext {
|
impl GlfwContext {
|
||||||
pub fn new(version: GLVersion, width: u32, height: u32) -> Result<Self, anyhow::Error> {
|
pub fn new(version: GLVersion, width: u32, height: u32) -> Result<Self, anyhow::Error> {
|
||||||
let mut glfw = glfw::init(fail_on_errors!())?;
|
let mut glfw = glfw::init(fail_on_errors!())?;
|
||||||
|
@ -50,19 +45,19 @@ impl GlfwContext {
|
||||||
|
|
||||||
wnd.make_current();
|
wnd.make_current();
|
||||||
|
|
||||||
let mut gl =
|
let gl =
|
||||||
unsafe { glow::Context::from_loader_function(|proc| wnd.get_proc_address(proc) as _) };
|
unsafe { glow::Context::from_loader_function(|proc| wnd.get_proc_address(proc) as _) };
|
||||||
|
|
||||||
unsafe {
|
// unsafe {
|
||||||
gl.enable(glow::DEBUG_OUTPUT);
|
// gl.enable(glow::DEBUG_OUTPUT);
|
||||||
gl.enable(glow::DEBUG_OUTPUT_SYNCHRONOUS);
|
// gl.enable(glow::DEBUG_OUTPUT_SYNCHRONOUS);
|
||||||
gl.debug_message_callback(debug_callback);
|
// gl.debug_message_callback(debug_callback);
|
||||||
gl.debug_message_control(glow::DONT_CARE, glow::DONT_CARE, glow::DONT_CARE, &[], true);
|
// gl.debug_message_control(glow::DONT_CARE, glow::DONT_CARE, glow::DONT_CARE, &[], true);
|
||||||
}
|
// }
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
wnd,
|
_wnd: wnd,
|
||||||
glfw,
|
_glfw: glfw,
|
||||||
gl: Arc::new(gl),
|
gl: Arc::new(gl),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ use std::sync::Arc;
|
||||||
|
|
||||||
struct OpenGl {
|
struct OpenGl {
|
||||||
context: GlfwContext,
|
context: GlfwContext,
|
||||||
use_dsa: bool,
|
|
||||||
texture: GLImage,
|
texture: GLImage,
|
||||||
image_bytes: Image<RGBA8>,
|
image_bytes: Image<RGBA8>,
|
||||||
}
|
}
|
||||||
|
@ -22,14 +21,14 @@ pub struct OpenGl3(OpenGl);
|
||||||
pub struct OpenGl4(OpenGl);
|
pub struct OpenGl4(OpenGl);
|
||||||
|
|
||||||
impl RenderTest for OpenGl3 {
|
impl RenderTest for OpenGl3 {
|
||||||
fn new(path: impl AsRef<Path>) -> anyhow::Result<Self>
|
fn new(path: &Path) -> anyhow::Result<Self>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
OpenGl3::new(path)
|
OpenGl3::new(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&mut self, path: impl AsRef<Path>, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
fn render(&mut self, path: &Path, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
||||||
let mut filter_chain = unsafe {
|
let mut filter_chain = unsafe {
|
||||||
FilterChain::load_from_path(
|
FilterChain::load_from_path(
|
||||||
path,
|
path,
|
||||||
|
@ -48,14 +47,14 @@ impl RenderTest for OpenGl3 {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderTest for OpenGl4 {
|
impl RenderTest for OpenGl4 {
|
||||||
fn new(path: impl AsRef<Path>) -> anyhow::Result<Self>
|
fn new(path: &Path) -> anyhow::Result<Self>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
OpenGl4::new(path)
|
OpenGl4::new(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&mut self, path: impl AsRef<Path>, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
fn render(&mut self, path: &Path, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
||||||
let mut filter_chain = unsafe {
|
let mut filter_chain = unsafe {
|
||||||
FilterChain::load_from_path(
|
FilterChain::load_from_path(
|
||||||
path,
|
path,
|
||||||
|
@ -74,20 +73,20 @@ impl RenderTest for OpenGl4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OpenGl3 {
|
impl OpenGl3 {
|
||||||
pub fn new(image_path: impl AsRef<Path>) -> anyhow::Result<Self> {
|
pub fn new(image_path: &Path) -> anyhow::Result<Self> {
|
||||||
Ok(Self(OpenGl::new(image_path, false)?))
|
Ok(Self(OpenGl::new(image_path, false)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OpenGl4 {
|
impl OpenGl4 {
|
||||||
pub fn new(image_path: impl AsRef<Path>) -> anyhow::Result<Self> {
|
pub fn new(image_path: &Path) -> anyhow::Result<Self> {
|
||||||
Ok(Self(OpenGl::new(image_path, true)?))
|
Ok(Self(OpenGl::new(image_path, true)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OpenGl {
|
impl OpenGl {
|
||||||
pub fn new(image_path: impl AsRef<Path>, use_dsa: bool) -> anyhow::Result<Self> {
|
pub fn new(image_path: &Path, use_dsa: bool) -> anyhow::Result<Self> {
|
||||||
let image: Image<RGBA8> = Image::load(image_path.as_ref(), UVDirection::TopLeft)?;
|
let image: Image<RGBA8> = Image::load(image_path, UVDirection::TopLeft)?;
|
||||||
let height = image.size.height;
|
let height = image.size.height;
|
||||||
let width = image.size.width;
|
let width = image.size.width;
|
||||||
let version = if use_dsa {
|
let version = if use_dsa {
|
||||||
|
@ -131,7 +130,6 @@ impl OpenGl {
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
context,
|
context,
|
||||||
use_dsa,
|
|
||||||
texture: GLImage {
|
texture: GLImage {
|
||||||
handle: Some(texture),
|
handle: Some(texture),
|
||||||
format: glow::RGBA8,
|
format: glow::RGBA8,
|
||||||
|
|
|
@ -24,7 +24,7 @@ use std::path::Path;
|
||||||
/// Test harness to set up a device, render a triangle, and apply a shader
|
/// Test harness to set up a device, render a triangle, and apply a shader
|
||||||
pub trait RenderTest {
|
pub trait RenderTest {
|
||||||
/// Create a new instance of the test harness.
|
/// Create a new instance of the test harness.
|
||||||
fn new(path: impl AsRef<Path>) -> anyhow::Result<Self>
|
fn new(path: &Path) -> anyhow::Result<Self>
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
|
|
||||||
|
@ -36,11 +36,7 @@ pub trait RenderTest {
|
||||||
/// For testing purposes, it is often that a single image will be reused with multiple
|
/// For testing purposes, it is often that a single image will be reused with multiple
|
||||||
/// shader presets, so the actual image that a shader will be applied to
|
/// shader presets, so the actual image that a shader will be applied to
|
||||||
/// will often be part of the test harness object.
|
/// will often be part of the test harness object.
|
||||||
fn render(
|
fn render(&mut self, path: &Path, frame_count: usize) -> anyhow::Result<image::RgbaImage>;
|
||||||
&mut self,
|
|
||||||
path: impl AsRef<Path>,
|
|
||||||
frame_count: usize,
|
|
||||||
) -> anyhow::Result<image::RgbaImage>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -57,8 +53,8 @@ mod test {
|
||||||
// "../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp";
|
// "../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp";
|
||||||
|
|
||||||
fn do_test<T: RenderTest>() -> anyhow::Result<()> {
|
fn do_test<T: RenderTest>() -> anyhow::Result<()> {
|
||||||
let mut test = T::new(IMAGE_PATH)?;
|
let mut test = T::new(IMAGE_PATH.as_ref())?;
|
||||||
let image = test.render(FILTER_PATH, 100)?;
|
let image = test.render(FILTER_PATH.as_ref(), 100)?;
|
||||||
|
|
||||||
let out = File::create("out.png")?;
|
let out = File::create("out.png")?;
|
||||||
image.write_with_encoder(PngEncoder::new(out))?;
|
image.write_with_encoder(PngEncoder::new(out))?;
|
||||||
|
@ -114,11 +110,11 @@ mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compare<A: RenderTest, B: RenderTest>() -> anyhow::Result<()> {
|
pub fn compare<A: RenderTest, B: RenderTest>() -> anyhow::Result<()> {
|
||||||
let mut a = A::new(IMAGE_PATH)?;
|
let mut a = A::new(IMAGE_PATH.as_ref())?;
|
||||||
let mut b = B::new(IMAGE_PATH)?;
|
let mut b = B::new(IMAGE_PATH.as_ref())?;
|
||||||
|
|
||||||
let a_image = a.render(FILTER_PATH, 100)?;
|
let a_image = a.render(FILTER_PATH.as_ref(), 100)?;
|
||||||
let b_image = b.render(FILTER_PATH, 100)?;
|
let b_image = b.render(FILTER_PATH.as_ref(), 100)?;
|
||||||
|
|
||||||
let similarity = image_compare::rgba_hybrid_compare(&a_image, &b_image)?;
|
let similarity = image_compare::rgba_hybrid_compare(&a_image, &b_image)?;
|
||||||
assert!(similarity.score > 0.95);
|
assert!(similarity.score > 0.95);
|
||||||
|
|
|
@ -22,14 +22,14 @@ pub struct Metal {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderTest for Metal {
|
impl RenderTest for Metal {
|
||||||
fn new(path: impl AsRef<Path>) -> anyhow::Result<Self>
|
fn new(path: &Path) -> anyhow::Result<Self>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
Metal::new(path)
|
Metal::new(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&mut self, path: impl AsRef<Path>, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
fn render(&mut self, path: &Path, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
||||||
let queue = self
|
let queue = self
|
||||||
.device
|
.device
|
||||||
.newCommandQueue()
|
.newCommandQueue()
|
||||||
|
|
|
@ -6,16 +6,11 @@ use std::ffi::CStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub struct VulkanBase {
|
pub struct VulkanBase {
|
||||||
entry: ash::Entry,
|
|
||||||
instance: ash::Instance,
|
|
||||||
device: Arc<ash::Device>,
|
device: Arc<ash::Device>,
|
||||||
graphics_queue: vk::Queue,
|
graphics_queue: vk::Queue,
|
||||||
// pub debug: VulkanDebug,
|
|
||||||
physical_device: vk::PhysicalDevice,
|
|
||||||
mem_props: vk::PhysicalDeviceMemoryProperties,
|
|
||||||
allocator: Arc<Mutex<Allocator>>,
|
allocator: Arc<Mutex<Allocator>>,
|
||||||
_pool: vk::CommandPool,
|
|
||||||
cmd_buffer: vk::CommandBuffer,
|
cmd_buffer: vk::CommandBuffer,
|
||||||
|
pool: vk::CommandPool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&VulkanBase> for VulkanObjects {
|
impl From<&VulkanBase> for VulkanObjects {
|
||||||
|
@ -52,7 +47,6 @@ impl VulkanBase {
|
||||||
let physical_device = super::physical_device::pick_physical_device(&instance)?;
|
let physical_device = super::physical_device::pick_physical_device(&instance)?;
|
||||||
|
|
||||||
let (device, queue, cmd_pool) = Self::create_device(&instance, &physical_device)?;
|
let (device, queue, cmd_pool) = Self::create_device(&instance, &physical_device)?;
|
||||||
let mem_props = unsafe { instance.get_physical_device_memory_properties(physical_device) };
|
|
||||||
|
|
||||||
let alloc = super::memory::create_allocator(
|
let alloc = super::memory::create_allocator(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
|
@ -71,15 +65,11 @@ impl VulkanBase {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
entry,
|
|
||||||
instance,
|
|
||||||
device: Arc::new(device),
|
device: Arc::new(device),
|
||||||
graphics_queue: queue,
|
graphics_queue: queue,
|
||||||
physical_device,
|
|
||||||
mem_props,
|
|
||||||
// debug,
|
// debug,
|
||||||
allocator: alloc,
|
allocator: alloc,
|
||||||
_pool: cmd_pool,
|
pool: cmd_pool,
|
||||||
cmd_buffer: buffers,
|
cmd_buffer: buffers,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -157,7 +147,7 @@ impl VulkanBase {
|
||||||
impl Drop for VulkanBase {
|
impl Drop for VulkanBase {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device.destroy_command_pool(self._pool, None);
|
self.device.destroy_command_pool(self.pool, None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,6 @@ pub struct VulkanBuffer {
|
||||||
device: Arc<ash::Device>,
|
device: Arc<ash::Device>,
|
||||||
allocation: ManuallyDrop<Allocation>,
|
allocation: ManuallyDrop<Allocation>,
|
||||||
allocator: Arc<Mutex<Allocator>>,
|
allocator: Arc<Mutex<Allocator>>,
|
||||||
size: vk::DeviceSize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VulkanBuffer {
|
impl VulkanBuffer {
|
||||||
|
@ -88,7 +87,6 @@ impl VulkanBuffer {
|
||||||
handle: buffer,
|
handle: buffer,
|
||||||
allocation: ManuallyDrop::new(alloc),
|
allocation: ManuallyDrop::new(alloc),
|
||||||
allocator: Arc::clone(allocator),
|
allocator: Arc::clone(allocator),
|
||||||
size: size as vk::DeviceSize,
|
|
||||||
device: device.clone(),
|
device: device.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ use image::RgbaImage;
|
||||||
use librashader::runtime::vk::{FilterChain, FilterChainOptions, VulkanImage};
|
use librashader::runtime::vk::{FilterChain, FilterChainOptions, VulkanImage};
|
||||||
use librashader::runtime::Viewport;
|
use librashader::runtime::Viewport;
|
||||||
use librashader_runtime::image::{Image, UVDirection, BGRA8};
|
use librashader_runtime::image::{Image, UVDirection, BGRA8};
|
||||||
use std::io::Write;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
mod base;
|
mod base;
|
||||||
|
@ -20,19 +19,18 @@ pub struct Vulkan {
|
||||||
vk: VulkanBase,
|
vk: VulkanBase,
|
||||||
image_bytes: Image<BGRA8>,
|
image_bytes: Image<BGRA8>,
|
||||||
image: vk::Image,
|
image: vk::Image,
|
||||||
view: vk::ImageView,
|
_image_alloc: VulkanImageMemory,
|
||||||
image_alloc: VulkanImageMemory,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderTest for Vulkan {
|
impl RenderTest for Vulkan {
|
||||||
fn new(path: impl AsRef<Path>) -> anyhow::Result<Self>
|
fn new(path: &Path) -> anyhow::Result<Self>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
Vulkan::new(path)
|
Vulkan::new(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&mut self, path: impl AsRef<Path>, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
fn render(&mut self, path: &Path, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut filter_chain = FilterChain::load_from_path(
|
let mut filter_chain = FilterChain::load_from_path(
|
||||||
path,
|
path,
|
||||||
|
@ -56,10 +54,10 @@ impl RenderTest for Vulkan {
|
||||||
.usage(vk::ImageUsageFlags::COLOR_ATTACHMENT | vk::ImageUsageFlags::TRANSFER_SRC)
|
.usage(vk::ImageUsageFlags::COLOR_ATTACHMENT | vk::ImageUsageFlags::TRANSFER_SRC)
|
||||||
.initial_layout(vk::ImageLayout::UNDEFINED);
|
.initial_layout(vk::ImageLayout::UNDEFINED);
|
||||||
|
|
||||||
let render_texture = unsafe { self.vk.device().create_image(&image_info, None)? };
|
let render_texture = { self.vk.device().create_image(&image_info, None)? };
|
||||||
|
|
||||||
// This just needs to stay alive until the read.
|
// This just needs to stay alive until the read.
|
||||||
let _memory = unsafe {
|
let _memory = {
|
||||||
let mem_reqs = self
|
let mem_reqs = self
|
||||||
.vk
|
.vk
|
||||||
.device()
|
.device()
|
||||||
|
@ -87,7 +85,7 @@ impl RenderTest for Vulkan {
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut transfer_memory = unsafe {
|
let mut transfer_memory = {
|
||||||
let mem_reqs = self
|
let mem_reqs = self
|
||||||
.vk
|
.vk
|
||||||
.device()
|
.device()
|
||||||
|
@ -101,8 +99,7 @@ impl RenderTest for Vulkan {
|
||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
|
|
||||||
self.vk.queue_work(|cmd| unsafe {
|
self.vk.queue_work(|cmd| {
|
||||||
unsafe {
|
|
||||||
util::vulkan_image_layout_transition_levels(
|
util::vulkan_image_layout_transition_levels(
|
||||||
&self.vk.device(),
|
&self.vk.device(),
|
||||||
cmd,
|
cmd,
|
||||||
|
@ -131,8 +128,7 @@ impl RenderTest for Vulkan {
|
||||||
vk::PipelineStageFlags::TRANSFER,
|
vk::PipelineStageFlags::TRANSFER,
|
||||||
vk::QUEUE_FAMILY_IGNORED,
|
vk::QUEUE_FAMILY_IGNORED,
|
||||||
vk::QUEUE_FAMILY_IGNORED,
|
vk::QUEUE_FAMILY_IGNORED,
|
||||||
)
|
);
|
||||||
}
|
|
||||||
|
|
||||||
filter_chain.frame(
|
filter_chain.frame(
|
||||||
&VulkanImage {
|
&VulkanImage {
|
||||||
|
@ -153,7 +149,7 @@ impl RenderTest for Vulkan {
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
unsafe {
|
{
|
||||||
util::vulkan_image_layout_transition_levels(
|
util::vulkan_image_layout_transition_levels(
|
||||||
&self.vk.device(),
|
&self.vk.device(),
|
||||||
cmd,
|
cmd,
|
||||||
|
@ -235,23 +231,22 @@ impl RenderTest for Vulkan {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vulkan {
|
impl Vulkan {
|
||||||
pub fn new(image_path: impl AsRef<Path>) -> anyhow::Result<Self> {
|
pub fn new(image_path: &Path) -> anyhow::Result<Self> {
|
||||||
let vk = VulkanBase::new()?;
|
let vk = VulkanBase::new()?;
|
||||||
|
|
||||||
let (image_bytes, image_alloc, image, view) = Self::load_image(&vk, image_path)?;
|
let (image_bytes, image_alloc, image, _view) = Self::load_image(&vk, image_path)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
vk,
|
vk,
|
||||||
image,
|
image,
|
||||||
image_bytes,
|
image_bytes,
|
||||||
view,
|
_image_alloc: image_alloc,
|
||||||
image_alloc,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_image(
|
pub fn load_image(
|
||||||
vk: &VulkanBase,
|
vk: &VulkanBase,
|
||||||
image_path: impl AsRef<Path>,
|
image_path: &Path,
|
||||||
) -> anyhow::Result<(Image<BGRA8>, VulkanImageMemory, vk::Image, vk::ImageView)> {
|
) -> anyhow::Result<(Image<BGRA8>, VulkanImageMemory, vk::Image, vk::ImageView)> {
|
||||||
let image: Image<BGRA8> = Image::load(image_path, UVDirection::TopLeft)?;
|
let image: Image<BGRA8> = Image::load(image_path, UVDirection::TopLeft)?;
|
||||||
|
|
||||||
|
|
|
@ -17,16 +17,15 @@ use wgpu_types::{
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
|
||||||
pub struct Wgpu {
|
pub struct Wgpu {
|
||||||
instance: Instance,
|
_instance: Instance,
|
||||||
adapter: Adapter,
|
_adapter: Adapter,
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
queue: Arc<Queue>,
|
queue: Arc<Queue>,
|
||||||
image: Image,
|
_image: Image,
|
||||||
texture: Arc<Texture>,
|
texture: Arc<Texture>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BufferDimensions {
|
struct BufferDimensions {
|
||||||
width: usize,
|
|
||||||
height: usize,
|
height: usize,
|
||||||
unpadded_bytes_per_row: usize,
|
unpadded_bytes_per_row: usize,
|
||||||
padded_bytes_per_row: usize,
|
padded_bytes_per_row: usize,
|
||||||
|
@ -40,7 +39,6 @@ impl BufferDimensions {
|
||||||
let padded_bytes_per_row_padding = (align - unpadded_bytes_per_row % align) % align;
|
let padded_bytes_per_row_padding = (align - unpadded_bytes_per_row % align) % align;
|
||||||
let padded_bytes_per_row = unpadded_bytes_per_row + padded_bytes_per_row_padding;
|
let padded_bytes_per_row = unpadded_bytes_per_row + padded_bytes_per_row_padding;
|
||||||
Self {
|
Self {
|
||||||
width,
|
|
||||||
height,
|
height,
|
||||||
unpadded_bytes_per_row,
|
unpadded_bytes_per_row,
|
||||||
padded_bytes_per_row,
|
padded_bytes_per_row,
|
||||||
|
@ -49,14 +47,14 @@ impl BufferDimensions {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderTest for Wgpu {
|
impl RenderTest for Wgpu {
|
||||||
fn new(path: impl AsRef<Path>) -> anyhow::Result<Self>
|
fn new(path: &Path) -> anyhow::Result<Self>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
Wgpu::new(path)
|
Wgpu::new(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&mut self, path: impl AsRef<Path>, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
fn render(&mut self, path: &Path, frame_count: usize) -> anyhow::Result<RgbaImage> {
|
||||||
let mut chain = FilterChain::load_from_path(
|
let mut chain = FilterChain::load_from_path(
|
||||||
path,
|
path,
|
||||||
Arc::clone(&self.device),
|
Arc::clone(&self.device),
|
||||||
|
@ -126,7 +124,7 @@ impl RenderTest for Wgpu {
|
||||||
|
|
||||||
let capturable = Arc::clone(&output_buf);
|
let capturable = Arc::clone(&output_buf);
|
||||||
|
|
||||||
let mut pixels = Arc::new(Mutex::new(Vec::new()));
|
let pixels = Arc::new(Mutex::new(Vec::new()));
|
||||||
|
|
||||||
let pixels_async = Arc::clone(&pixels);
|
let pixels_async = Arc::clone(&pixels);
|
||||||
output_buf
|
output_buf
|
||||||
|
@ -167,7 +165,7 @@ impl RenderTest for Wgpu {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Wgpu {
|
impl Wgpu {
|
||||||
pub fn new(image: impl AsRef<Path>) -> anyhow::Result<Self> {
|
pub fn new(image: &Path) -> anyhow::Result<Self> {
|
||||||
pollster::block_on(async {
|
pollster::block_on(async {
|
||||||
let instance = wgpu::Instance::default();
|
let instance = wgpu::Instance::default();
|
||||||
let adapter = instance
|
let adapter = instance
|
||||||
|
@ -196,21 +194,17 @@ impl Wgpu {
|
||||||
let (image, texture) = Self::load_image(&device, &queue, image)?;
|
let (image, texture) = Self::load_image(&device, &queue, image)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
instance,
|
_instance: instance,
|
||||||
adapter,
|
_adapter: adapter,
|
||||||
device: Arc::new(device),
|
device: Arc::new(device),
|
||||||
queue: Arc::new(queue),
|
queue: Arc::new(queue),
|
||||||
image,
|
_image: image,
|
||||||
texture: Arc::new(texture),
|
texture: Arc::new(texture),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_image(
|
fn load_image(device: &Device, queue: &Queue, path: &Path) -> anyhow::Result<(Image, Texture)> {
|
||||||
device: &Device,
|
|
||||||
queue: &Queue,
|
|
||||||
path: impl AsRef<Path>,
|
|
||||||
) -> anyhow::Result<(Image, Texture)> {
|
|
||||||
let image = Image::load(path, UVDirection::TopLeft)?;
|
let image = Image::load(path, UVDirection::TopLeft)?;
|
||||||
let texture = device.create_texture(&TextureDescriptor {
|
let texture = device.create_texture(&TextureDescriptor {
|
||||||
size: image.size.into(),
|
size: image.size.into(),
|
||||||
|
|
Loading…
Reference in a new issue