rafx_framework/upload/
buffer_upload.rs1use rafx_api::extra::upload::{RafxTransferUpload, RafxUploadError};
2use rafx_api::{
3 RafxBarrierQueueTransition, RafxBuffer, RafxBufferBarrier, RafxBufferDef,
4 RafxCmdCopyBufferToBufferParams, RafxDeviceContext, RafxMemoryUsage, RafxOffsetSize,
5 RafxResourceState, RafxResourceType,
6};
7
8pub fn enqueue_load_buffer(
9 device_context: &RafxDeviceContext,
10 upload: &mut RafxTransferUpload,
11 resource_type: RafxResourceType,
14 data: &[u8],
15 dst_buffer: Option<&RafxBuffer>,
16 dst_byte_offset: u64,
17 ) -> Result<Option<RafxBuffer>, RafxUploadError> {
19 const REQUIRED_ALIGNMENT: usize = 16;
21
22 let src_byte_offset = upload.push(data, REQUIRED_ALIGNMENT)?;
24 let size = data.len() as u64;
25
26 let mut new_buffer = None;
28 let (dst_buffer, barrier_offset_size) = if let Some(dst_buffer) = dst_buffer {
29 if device_context.is_dx12() {
30 (dst_buffer, None)
32 } else {
33 let barrier_offset_size = RafxOffsetSize {
34 size: data.len() as u64,
35 byte_offset: dst_byte_offset,
36 };
37 (dst_buffer, Some(barrier_offset_size))
38 }
39 } else {
40 new_buffer = Some(device_context.create_buffer(&RafxBufferDef {
41 size,
42 memory_usage: RafxMemoryUsage::GpuOnly,
43 queue_type: upload.transfer_queue().queue_type(),
44 resource_type,
45 ..Default::default()
46 })?);
47 (new_buffer.as_ref().unwrap(), None)
48 };
49
50 let use_transfer_queue = new_buffer.is_some();
55
56 let copy_params = RafxCmdCopyBufferToBufferParams {
59 src_byte_offset,
60 dst_byte_offset,
61 size: data.len() as u64,
62 };
63
64 if use_transfer_queue {
65 upload.transfer_command_buffer().cmd_copy_buffer_to_buffer(
66 &upload.staging_buffer(),
67 &dst_buffer,
68 ©_params,
69 )?;
70
71 upload.transfer_command_buffer().cmd_resource_barrier(
72 &[RafxBufferBarrier {
73 buffer: &dst_buffer,
74 src_state: RafxResourceState::COPY_DST,
75 dst_state: RafxResourceState::VERTEX_AND_CONSTANT_BUFFER
76 | RafxResourceState::INDEX_BUFFER,
77 queue_transition: RafxBarrierQueueTransition::ReleaseTo(
78 upload.dst_queue().queue_type(),
79 ),
80 offset_size: barrier_offset_size,
81 }],
82 &[],
83 )?;
84
85 upload.dst_command_buffer().cmd_resource_barrier(
86 &[RafxBufferBarrier {
87 buffer: &dst_buffer,
88 src_state: RafxResourceState::COPY_DST,
89 dst_state: RafxResourceState::VERTEX_AND_CONSTANT_BUFFER
90 | RafxResourceState::INDEX_BUFFER,
91 queue_transition: RafxBarrierQueueTransition::AcquireFrom(
92 upload.transfer_queue().queue_type(),
93 ),
94 offset_size: barrier_offset_size,
95 }],
96 &[],
97 )?;
98 } else {
99 if new_buffer.is_none() {
102 upload.dst_command_buffer().cmd_resource_barrier(
103 &[RafxBufferBarrier {
104 buffer: &dst_buffer,
105 src_state: RafxResourceState::VERTEX_AND_CONSTANT_BUFFER
106 | RafxResourceState::INDEX_BUFFER,
107 dst_state: RafxResourceState::COPY_DST,
108 queue_transition: RafxBarrierQueueTransition::None,
109 offset_size: barrier_offset_size,
110 }],
111 &[],
112 )?;
113 }
114
115 upload.dst_command_buffer().cmd_copy_buffer_to_buffer(
116 &upload.staging_buffer(),
117 &dst_buffer,
118 ©_params,
119 )?;
120
121 upload.dst_command_buffer().cmd_resource_barrier(
122 &[RafxBufferBarrier {
123 buffer: &dst_buffer,
124 src_state: RafxResourceState::COPY_DST,
125 dst_state: RafxResourceState::VERTEX_AND_CONSTANT_BUFFER
126 | RafxResourceState::INDEX_BUFFER,
127 queue_transition: RafxBarrierQueueTransition::None,
128 offset_size: barrier_offset_size,
129 }],
130 &[],
131 )?;
132 }
133
134 log::trace!("upload buffer bytes: {}", data.len());
135
136 Ok(new_buffer)
137}