2022-11-26 18:38:15 +11:00
|
|
|
use librashader_common::Size;
|
|
|
|
use windows::Win32::Graphics::Direct3D11::{ID3D11Device, ID3D11SamplerState, ID3D11ShaderResourceView, ID3D11Texture2D, D3D11_BIND_RENDER_TARGET, D3D11_BIND_SHADER_RESOURCE, D3D11_CPU_ACCESS_FLAG, D3D11_CPU_ACCESS_WRITE, D3D11_FORMAT_SUPPORT_RENDER_TARGET, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE, D3D11_FORMAT_SUPPORT_TEXTURE2D, D3D11_RESOURCE_MISC_GENERATE_MIPS, D3D11_TEXTURE2D_DESC, D3D11_USAGE_DYNAMIC, D3D11_SHADER_RESOURCE_VIEW_DESC, D3D11_SHADER_RESOURCE_VIEW_DESC_0, D3D11_TEX2D_SRV, D3D11_BIND_FLAG, D3D11_RESOURCE_MISC_FLAG, D3D11_USAGE_STAGING, ID3D11DeviceContext, D3D11_SUBRESOURCE_DATA, D3D11_MAP_WRITE, D3D11_BOX};
|
|
|
|
use windows::Win32::Graphics::Direct3D::D3D_SRV_DIMENSION_TEXTURE2D;
|
|
|
|
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
|
|
|
|
use librashader_common::image::Image;
|
|
|
|
use crate::util::d3d11_get_closest_format;
|
|
|
|
use crate::util::Result;
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct ExternalTexture {
|
|
|
|
pub srv: ID3D11ShaderResourceView,
|
|
|
|
pub size: Size<u32>, // pub image: GlImage,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct OwnedTexture {
|
|
|
|
pub handle: ID3D11Texture2D,
|
|
|
|
// pub staging: ID3D11Texture2D,
|
|
|
|
pub srv: ID3D11ShaderResourceView,
|
|
|
|
pub desc: D3D11_TEXTURE2D_DESC,
|
|
|
|
pub size: Size<u32>, // pub image: GlImage,
|
|
|
|
// pub filter: FilterMode,
|
|
|
|
// pub mip_filter: FilterMode,
|
|
|
|
// pub wrap_mode: WrapMode,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl OwnedTexture {
|
|
|
|
pub fn new(device: &ID3D11Device, source: &Image, desc: D3D11_TEXTURE2D_DESC) -> Result<OwnedTexture> {
|
|
|
|
let mut desc = D3D11_TEXTURE2D_DESC {
|
|
|
|
Width: source.size.width,
|
|
|
|
Height: source.size.height,
|
|
|
|
// todo: set this to 0
|
|
|
|
MipLevels: if (desc.MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS).0 != 0 {
|
|
|
|
0
|
|
|
|
} else {
|
|
|
|
1
|
|
|
|
},
|
|
|
|
ArraySize: 1,
|
|
|
|
SampleDesc: DXGI_SAMPLE_DESC {
|
|
|
|
Count: 1,
|
|
|
|
Quality: 0,
|
|
|
|
},
|
|
|
|
CPUAccessFlags: if desc.Usage == D3D11_USAGE_DYNAMIC {
|
|
|
|
D3D11_CPU_ACCESS_WRITE
|
|
|
|
} else {
|
|
|
|
D3D11_CPU_ACCESS_FLAG(0)
|
|
|
|
},
|
|
|
|
..desc
|
|
|
|
};
|
|
|
|
desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE;
|
|
|
|
|
|
|
|
// determine number of mipmaps required
|
|
|
|
if (desc.MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS).0 != 0 {
|
|
|
|
let mut width = desc.Width >> 5;
|
|
|
|
let mut height = desc.Height >> 5;
|
|
|
|
desc.BindFlags |= D3D11_BIND_RENDER_TARGET;
|
|
|
|
|
|
|
|
while width != 0 && height != 0 {
|
|
|
|
width >>= 1;
|
|
|
|
height >>= 1;
|
|
|
|
desc.MipLevels += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// determine if format is supported.
|
|
|
|
// bruh why does D3D11_FORMAT_SUPPORT not implement bitor???
|
|
|
|
let mut format_support =
|
|
|
|
D3D11_FORMAT_SUPPORT_TEXTURE2D.0 | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE.0;
|
|
|
|
if (desc.BindFlags & D3D11_BIND_RENDER_TARGET).0 != 0 {
|
|
|
|
format_support |= D3D11_FORMAT_SUPPORT_RENDER_TARGET.0;
|
|
|
|
}
|
|
|
|
|
2022-11-27 15:57:22 +11:00
|
|
|
// eprintln!("s {:?}, p {:?}, l {:?}", source.size, source.pitch, source.bytes.len());
|
|
|
|
// eprintln!("{:#?}", desc);
|
2022-11-26 18:38:15 +11:00
|
|
|
|
|
|
|
unsafe {
|
|
|
|
let handle = device.CreateTexture2D(&desc, None).unwrap();
|
|
|
|
|
|
|
|
let srv = device.CreateShaderResourceView(&handle, Some(&D3D11_SHADER_RESOURCE_VIEW_DESC {
|
|
|
|
Format: desc.Format,
|
|
|
|
ViewDimension: D3D_SRV_DIMENSION_TEXTURE2D,
|
|
|
|
Anonymous: D3D11_SHADER_RESOURCE_VIEW_DESC_0 {
|
|
|
|
Texture2D: D3D11_TEX2D_SRV {
|
|
|
|
MostDetailedMip: 0,
|
|
|
|
MipLevels: u32::MAX
|
|
|
|
}
|
|
|
|
},
|
|
|
|
}))?;
|
|
|
|
|
|
|
|
|
|
|
|
let mut context = None;
|
|
|
|
device.GetImmediateContext(&mut context);
|
|
|
|
|
|
|
|
// todo: make this fallible
|
|
|
|
let context = context.unwrap();
|
|
|
|
|
|
|
|
// need a staging texture to defer mipmap generation
|
|
|
|
let staging = device.CreateTexture2D(&D3D11_TEXTURE2D_DESC {
|
|
|
|
MipLevels: 1,
|
|
|
|
BindFlags: D3D11_BIND_FLAG(0),
|
|
|
|
MiscFlags: D3D11_RESOURCE_MISC_FLAG(0),
|
|
|
|
Usage: D3D11_USAGE_STAGING,
|
|
|
|
CPUAccessFlags: D3D11_CPU_ACCESS_WRITE,
|
|
|
|
..desc
|
|
|
|
}, Some(&D3D11_SUBRESOURCE_DATA {
|
|
|
|
pSysMem: source.bytes.as_ptr().cast(),
|
|
|
|
SysMemPitch: source.pitch as u32,
|
|
|
|
SysMemSlicePitch: 0
|
|
|
|
}))?;
|
|
|
|
|
2022-11-27 07:55:14 +11:00
|
|
|
// todo: do format conversion (leverage image crate..?
|
|
|
|
// is this necessary with CopySubresourceRegion)...
|
2022-11-26 18:38:15 +11:00
|
|
|
|
|
|
|
context.CopySubresourceRegion(&handle, 0, 0, 0, 0,
|
|
|
|
&staging, 0, Some(&D3D11_BOX {
|
|
|
|
left: 0,
|
|
|
|
top: 0,
|
|
|
|
front: 0,
|
|
|
|
right: source.size.width,
|
|
|
|
bottom: source.size.height,
|
|
|
|
back: 1,
|
|
|
|
}));
|
|
|
|
|
|
|
|
if (desc.MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS).0 != 0 {
|
|
|
|
context.GenerateMips(&srv)
|
|
|
|
}
|
|
|
|
|
|
|
|
// let mut subresource = context.Map(staging, 0, D3D11_MAP_WRITE, 0)?;
|
|
|
|
// staging.Upd
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ok(OwnedTexture {
|
|
|
|
handle,
|
|
|
|
// staging,
|
|
|
|
srv,
|
|
|
|
desc,
|
|
|
|
size: source.size,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|