use super::*;
#[derive(Clone, Debug)]
pub struct Dx11WideSdrOutput {
bundle: TextureBundle,
owner: ID3D11DeviceContext,
recording: Arc<Recording>,
}
impl Dx11CustomContext {
pub fn create_wide_sdr_output(&self, extent: Size<DevicePixels>) -> Result<Dx11WideSdrOutput> {
ensure!(
self.recording.state.load(Ordering::Acquire) == PENDING,
"DirectX preparation is no longer writable"
);
Ok(Dx11WideSdrOutput {
bundle: allocate_texture_format(
&self.device,
extent,
DXGI_FORMAT_R16G16B16A16_FLOAT,
8,
)?,
owner: self.owner.clone(),
recording: self.recording.clone(),
})
}
pub fn can_reuse_wide_sdr(&self, output: &Dx11WideSdrOutput) -> bool {
self.owner.as_raw() == output.owner.as_raw() && self.recording.can_reuse(&output.recording)
}
pub fn record_wide_sdr<T>(
&self,
output: &Dx11WideSdrOutput,
encode: impl FnOnce(&ID3D11DeviceContext, &ID3D11RenderTargetView) -> Result<T>,
) -> Result<T> {
ensure!(
self.owner.as_raw() == output.owner.as_raw()
&& Arc::ptr_eq(&self.recording, &output.recording)
&& self.recording.state.load(Ordering::Acquire) == PENDING,
"cannot mutate submitted or foreign DirectX wide output"
);
self.record(|deferred| encode(deferred, &output.bundle.rtv))
}
}
impl Dx11WideSdrOutput {
pub fn texture(&self) -> &ID3D11Texture2D {
&self.bundle.texture
}
pub(crate) fn validate(
self,
context: &Dx11CustomContext,
extent: Size<DevicePixels>,
) -> Result<TextureBundle> {
ensure!(
context.can_reuse_wide_sdr(&self),
"foreign or abandoned DirectX wide output"
);
ensure!(
self.bundle.extent == extent,
"invalid DirectX wide output extent"
);
ensure!(
unsafe { self.bundle.texture.GetDevice()? }.as_raw() == context.device.as_raw(),
"DirectX wide output belongs to another device"
);
let mut desc = D3D11_TEXTURE2D_DESC::default();
unsafe {
self.bundle.texture.GetDesc(&mut desc);
}
ensure!(
desc.Format == DXGI_FORMAT_R16G16B16A16_FLOAT
&& desc.Width == extent.width.0 as u32
&& desc.Height == extent.height.0 as u32
&& desc.MipLevels == 1
&& desc.ArraySize == 1
&& desc.SampleDesc.Count == 1
&& desc.SampleDesc.Quality == 0
&& desc.BindFlags & D3D11_BIND_SHADER_RESOURCE.0 as u32 != 0,
"invalid DirectX wide texture structure"
);
Ok(self.bundle)
}
}
#[cfg(test)]
mod tests;