Pass [u8] instead of [u32] for push constants (#918)

* Pass [u8] instead of [u32] for push constants

Use 2-instruction aligner

Fixed alignment

Fixed offsets

Added alignment checks and fixed size

Use semantic constants

* Replaced all magic number with constant

* Fixed type cast
This commit is contained in:
PENGUINLIONG 2020-10-09 11:13:18 +08:00 committed by GitHub
parent 7377552828
commit 6f4508523a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 66 additions and 15 deletions

View File

@ -232,7 +232,8 @@ impl RenderBundle {
let pipeline_layout = &pipeline_layout_guard[pipeline_layout_id];
if let Some(values_offset) = values_offset {
let values_end_offset = (values_offset + size_bytes / 4) as usize;
let values_end_offset =
(values_offset + size_bytes / wgt::PUSH_CONSTANT_ALIGNMENT) as usize;
let data_slice = &self.base.push_constant_data
[(values_offset as usize)..values_end_offset];
@ -1035,14 +1036,30 @@ pub mod bundle_ffi {
stages: wgt::ShaderStage,
offset: u32,
size_bytes: u32,
data: *const u32,
data: *const u8,
) {
span!(_guard, DEBUG, "RenderBundle::set_push_constants");
let data_slice = slice::from_raw_parts(data, (size_bytes / 4) as usize);
assert_eq!(
offset & (wgt::PUSH_CONSTANT_ALIGNMENT - 1),
0,
"Push constant offset must be aligned to 4 bytes."
);
assert_eq!(
size_bytes & (wgt::PUSH_CONSTANT_ALIGNMENT - 1),
0,
"Push constant size must be aligned to 4 bytes."
);
let data_slice = slice::from_raw_parts(data, size_bytes as usize);
let value_offset = pass.base.push_constant_data.len().try_into().expect(
"Ran out of push constant space. Don't set 4gb of push constants per RenderBundle.",
);
pass.base.push_constant_data.extend_from_slice(data_slice);
pass.base.push_constant_data.extend(
data_slice
.chunks_exact(wgt::PUSH_CONSTANT_ALIGNMENT as usize)
.map(|arr| u32::from_ne_bytes([arr[0], arr[1], arr[2], arr[3]])),
);
pass.base.commands.push(RenderCommand::SetPushConstant {
stages,
offset,

View File

@ -368,7 +368,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
values_offset,
} => {
let end_offset_bytes = offset + size_bytes;
let values_end_offset = (values_offset + size_bytes / 4) as usize;
let values_end_offset =
(values_offset + size_bytes / wgt::PUSH_CONSTANT_ALIGNMENT) as usize;
let data_slice =
&base.push_constant_data[(values_offset as usize)..values_end_offset];
@ -500,14 +501,30 @@ pub mod compute_ffi {
pass: &mut ComputePass,
offset: u32,
size_bytes: u32,
data: *const u32,
data: *const u8,
) {
span!(_guard, DEBUG, "RenderPass::set_push_constant");
let data_slice = slice::from_raw_parts(data, (size_bytes / 4) as usize);
span!(_guard, DEBUG, "ComputePass::set_push_constant");
assert_eq!(
offset & (wgt::PUSH_CONSTANT_ALIGNMENT - 1),
0,
"Push constant offset must be aligned to 4 bytes."
);
assert_eq!(
size_bytes & (wgt::PUSH_CONSTANT_ALIGNMENT - 1),
0,
"Push constant size must be aligned to 4 bytes."
);
let data_slice = slice::from_raw_parts(data, size_bytes as usize);
let value_offset = pass.base.push_constant_data.len().try_into().expect(
"Ran out of push constant space. Don't set 4gb of push constants per ComputePass.",
);
pass.base.push_constant_data.extend_from_slice(data_slice);
pass.base.push_constant_data.extend(
data_slice
.chunks_exact(wgt::PUSH_CONSTANT_ALIGNMENT as usize)
.map(|arr| u32::from_ne_bytes([arr[0], arr[1], arr[2], arr[3]])),
);
pass.base.commands.push(ComputeCommand::SetPushConstant {
offset,
size_bytes,

View File

@ -256,9 +256,9 @@ where
PushFn: FnMut(u32, &[u32]),
{
let mut count_words = 0_u32;
let size_words = size_bytes / 4;
let size_words = size_bytes / wgt::PUSH_CONSTANT_ALIGNMENT;
while count_words < size_words {
let count_bytes = count_words * 4;
let count_bytes = count_words * wgt::PUSH_CONSTANT_ALIGNMENT;
let size_to_write_words =
(size_words - count_words).min(PUSH_CONSTANT_CLEAR_ARRAY.len() as u32);

View File

@ -1248,7 +1248,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
values_offset.ok_or(RenderPassError::InvalidValuesOffset)?;
let end_offset_bytes = offset + size_bytes;
let values_end_offset = (values_offset + size_bytes / 4) as usize;
let values_end_offset =
(values_offset + size_bytes / wgt::PUSH_CONSTANT_ALIGNMENT) as usize;
let data_slice =
&base.push_constant_data[(values_offset as usize)..values_end_offset];
@ -1715,14 +1716,30 @@ pub mod render_ffi {
stages: wgt::ShaderStage,
offset: u32,
size_bytes: u32,
data: *const u32,
data: *const u8,
) {
span!(_guard, DEBUG, "RenderPass::set_push_constants");
let data_slice = slice::from_raw_parts(data, (size_bytes / 4) as usize);
assert_eq!(
offset & (wgt::PUSH_CONSTANT_ALIGNMENT - 1),
0,
"Push constant offset must be aligned to 4 bytes."
);
assert_eq!(
size_bytes & (wgt::PUSH_CONSTANT_ALIGNMENT - 1),
0,
"Push constant size must be aligned to 4 bytes."
);
let data_slice = slice::from_raw_parts(data, size_bytes as usize);
let value_offset = pass.base.push_constant_data.len().try_into().expect(
"Ran out of push constant space. Don't set 4gb of push constants per RenderPass.",
);
pass.base.push_constant_data.extend_from_slice(data_slice);
pass.base.push_constant_data.extend(
data_slice
.chunks_exact(wgt::PUSH_CONSTANT_ALIGNMENT as usize)
.map(|arr| u32::from_ne_bytes([arr[0], arr[1], arr[2], arr[3]])),
);
pass.base.commands.push(RenderCommand::SetPushConstant {
stages,
offset,