use std::marker;
use crate::image::format::{InternalFormat, Multisamplable};
use crate::rendering::attachment::{AsMultisampleAttachment, AttachmentData};
use crate::rendering::load_op::LoadAction;
use crate::rendering::AsAttachment;
use crate::rendering::{
FloatBuffer, IntegerBuffer, LoadOp, RenderingOutputBuffer, StoreOp, UnsignedIntegerBuffer,
};
pub trait EncodeColorBuffer {
type Buffer: RenderingOutputBuffer;
fn encode_color_buffer<'a, 'b>(
&'a mut self,
context: &'b mut ColorBufferEncodingContext,
) -> ColorBufferEncoding<'b, 'a, Self::Buffer>;
}
pub trait EncodeMultisampleColorBuffer {
type Buffer: RenderingOutputBuffer;
fn encode_multisample_color_buffer<'a, 'b>(
&'a mut self,
context: &'b mut ColorBufferEncodingContext,
) -> ColorBufferEncoding<'b, 'a, Self::Buffer>;
}
pub struct ColorBufferEncodingContext {
pub(crate) render_pass_id: u64,
pub(crate) buffer_index: i32,
}
pub struct ColorBufferEncoding<'a, 'b, B> {
pub(crate) buffer: B,
pub(crate) load_action: LoadAction,
pub(crate) store_op: StoreOp,
pub(crate) image: AttachmentData,
pub(crate) _context: &'a mut ColorBufferEncodingContext,
pub(crate) _image_ref: marker::PhantomData<&'b ()>,
}
impl<'a, 'b, F> ColorBufferEncoding<'a, 'b, FloatBuffer<F>>
where
F: InternalFormat,
{
pub fn float_attachment<I>(
context: &'a mut ColorBufferEncodingContext,
image: &'b mut I,
load_op: LoadOp<[f32; 4]>,
store_op: StoreOp,
) -> Self
where
I: AsAttachment<Format = F>,
{
let image = image.as_attachment().into_data();
ColorBufferEncoding {
buffer: FloatBuffer::new(
context.render_pass_id,
context.buffer_index,
image.width,
image.height,
),
load_action: load_op.as_load_float_action(context.buffer_index),
store_op,
image,
_context: context,
_image_ref: marker::PhantomData,
}
}
pub fn multisample_float_attachment<I>(
context: &'a mut ColorBufferEncodingContext,
image: &'b mut I,
load_op: LoadOp<[f32; 4]>,
store_op: StoreOp,
) -> Self
where
I: AsMultisampleAttachment<SampleFormat = F>,
F: Multisamplable,
{
let image = image.as_multisample_attachment().into_data();
ColorBufferEncoding {
buffer: FloatBuffer::new(
context.render_pass_id,
context.buffer_index,
image.width,
image.height,
),
load_action: load_op.as_load_float_action(context.buffer_index),
store_op,
image,
_context: context,
_image_ref: marker::PhantomData,
}
}
}
impl<'a, 'b, F> ColorBufferEncoding<'a, 'b, IntegerBuffer<F>>
where
F: InternalFormat,
{
pub fn integer_attachment<I>(
context: &'a mut ColorBufferEncodingContext,
image: &'b mut I,
load_op: LoadOp<[i32; 4]>,
store_op: StoreOp,
) -> Self
where
I: AsAttachment<Format = F>,
{
let image = image.as_attachment().into_data();
ColorBufferEncoding {
buffer: IntegerBuffer::new(
context.render_pass_id,
context.buffer_index,
image.width,
image.height,
),
load_action: load_op.as_load_integer_action(context.buffer_index),
store_op,
image,
_context: context,
_image_ref: marker::PhantomData,
}
}
}
impl<'a, 'b, F> ColorBufferEncoding<'a, 'b, UnsignedIntegerBuffer<F>>
where
F: InternalFormat,
{
pub fn unsigned_integer_attachment<I>(
context: &'a mut ColorBufferEncodingContext,
image: &'b mut I,
load_op: LoadOp<[u32; 4]>,
store_op: StoreOp,
) -> Self
where
I: AsAttachment<Format = F>,
{
let image = image.as_attachment().into_data();
ColorBufferEncoding {
buffer: UnsignedIntegerBuffer::new(
context.render_pass_id,
context.buffer_index,
image.width,
image.height,
),
load_action: load_op.as_load_unsigned_integer_action(context.buffer_index),
store_op,
image,
_context: context,
_image_ref: marker::PhantomData,
}
}
}
pub struct FloatAttachment<I> {
pub(crate) image: I,
pub(crate) load_op: LoadOp<[f32; 4]>,
pub(crate) store_op: StoreOp,
}
impl<I> EncodeColorBuffer for FloatAttachment<I>
where
I: AsAttachment,
{
type Buffer = FloatBuffer<I::Format>;
fn encode_color_buffer<'a, 'b>(
&'a mut self,
context: &'b mut ColorBufferEncodingContext,
) -> ColorBufferEncoding<'b, 'a, Self::Buffer> {
ColorBufferEncoding::float_attachment(context, &mut self.image, self.load_op, self.store_op)
}
}
impl<I> EncodeMultisampleColorBuffer for FloatAttachment<I>
where
I: AsMultisampleAttachment,
{
type Buffer = FloatBuffer<I::SampleFormat>;
fn encode_multisample_color_buffer<'a, 'b>(
&'a mut self,
context: &'b mut ColorBufferEncodingContext,
) -> ColorBufferEncoding<'b, 'a, Self::Buffer> {
ColorBufferEncoding::multisample_float_attachment(
context,
&mut self.image,
self.load_op,
self.store_op,
)
}
}
pub struct IntegerAttachment<I> {
pub(crate) image: I,
pub(crate) load_op: LoadOp<[i32; 4]>,
pub(crate) store_op: StoreOp,
}
impl<I> EncodeColorBuffer for IntegerAttachment<I>
where
I: AsAttachment,
{
type Buffer = IntegerBuffer<I::Format>;
fn encode_color_buffer<'a, 'b>(
&'a mut self,
context: &'b mut ColorBufferEncodingContext,
) -> ColorBufferEncoding<'b, 'a, Self::Buffer> {
ColorBufferEncoding::integer_attachment(
context,
&mut self.image,
self.load_op,
self.store_op,
)
}
}
pub struct UnsignedIntegerAttachment<I> {
pub(crate) image: I,
pub(crate) load_op: LoadOp<[u32; 4]>,
pub(crate) store_op: StoreOp,
}
impl<I> EncodeColorBuffer for UnsignedIntegerAttachment<I>
where
I: AsAttachment,
{
type Buffer = UnsignedIntegerBuffer<I::Format>;
fn encode_color_buffer<'a, 'b>(
&'a mut self,
context: &'b mut ColorBufferEncodingContext,
) -> ColorBufferEncoding<'b, 'a, Self::Buffer> {
ColorBufferEncoding::unsigned_integer_attachment(
context,
&mut self.image,
self.load_op,
self.store_op,
)
}
}