mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-22 14:55:05 +00:00
hal:: Fill the command buffer calls
This commit is contained in:
parent
738ae2b227
commit
6d51fab864
@ -47,10 +47,10 @@ use crate::{
|
||||
AttachmentData, Device, DeviceError, RenderPassContext, MAX_VERTEX_BUFFERS,
|
||||
SHADER_STAGE_COUNT,
|
||||
},
|
||||
hal::BufferUse,
|
||||
hub::{GlobalIdentityHandlerFactory, HalApi, Hub, Resource, Storage, Token},
|
||||
id,
|
||||
memory_init_tracker::{MemoryInitKind, MemoryInitTrackerAction},
|
||||
resource::BufferUse,
|
||||
track::{TrackerSet, UsageConflict},
|
||||
validation::check_buffer_usage,
|
||||
Label, LabelHelpers, LifeGuard, Stored, MAX_BIND_GROUPS,
|
||||
|
@ -18,7 +18,7 @@ use crate::{
|
||||
Label, DOWNLEVEL_ERROR_WARNING_MESSAGE,
|
||||
};
|
||||
|
||||
use hal::command::CommandBuffer as _;
|
||||
use hal::CommandBuffer as _;
|
||||
use thiserror::Error;
|
||||
use wgt::{BufferAddress, BufferUsage, ShaderStage};
|
||||
|
||||
@ -216,7 +216,7 @@ impl State {
|
||||
|
||||
fn flush_states<A: HalApi>(
|
||||
&mut self,
|
||||
raw_cmd_buf: &mut B::CommandBuffer,
|
||||
raw_cmd_buf: &mut A::CommandBuffer,
|
||||
base_trackers: &mut TrackerSet,
|
||||
bind_group_guard: &Storage<BindGroup<A>, id::BindGroupId>,
|
||||
buffer_guard: &Storage<Buffer<A>, id::BufferId>,
|
||||
|
@ -7,8 +7,8 @@
|
||||
|
||||
use crate::{
|
||||
binding_model::PushConstantUploadError,
|
||||
hal::BufferUse,
|
||||
id,
|
||||
resource::BufferUse,
|
||||
track::UseExtendError,
|
||||
validation::{MissingBufferUsageError, MissingTextureUsageError},
|
||||
};
|
||||
|
@ -114,15 +114,13 @@ impl<A: HalApi> CommandBuffer<A> {
|
||||
}
|
||||
|
||||
pub(crate) fn insert_barriers(
|
||||
raw: &mut B::CommandBuffer,
|
||||
raw: &mut A::CommandBuffer,
|
||||
base: &mut TrackerSet,
|
||||
head_buffers: &ResourceTracker<BufferState>,
|
||||
head_textures: &ResourceTracker<TextureState>,
|
||||
buffer_guard: &Storage<Buffer<A>, id::BufferId>,
|
||||
texture_guard: &Storage<Texture<A>, id::TextureId>,
|
||||
) {
|
||||
use hal::command::CommandBuffer as _;
|
||||
|
||||
profiling::scope!("insert_barriers");
|
||||
debug_assert_eq!(A::VARIANT, base.backend());
|
||||
|
||||
@ -135,14 +133,9 @@ impl<A: HalApi> CommandBuffer<A> {
|
||||
pending.into_hal(tex)
|
||||
});
|
||||
|
||||
//TODO: be more deliberate about the stages
|
||||
let stages = all_buffer_stages() | all_image_stages();
|
||||
unsafe {
|
||||
raw.pipeline_barrier(
|
||||
stages..stages,
|
||||
hal::memory::Dependencies::empty(),
|
||||
buffer_barriers.chain(texture_barriers),
|
||||
);
|
||||
raw.transition_buffers(buffer_barriers);
|
||||
raw.transition_textures(texture_barriers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ use hal::command::CommandBuffer as _;
|
||||
use crate::device::trace::Command as TraceCommand;
|
||||
use crate::{
|
||||
command::{CommandBuffer, CommandEncoderError},
|
||||
device::all_buffer_stages,
|
||||
hub::{Global, GlobalIdentityHandlerFactory, HalApi, Storage, Token},
|
||||
id::{self, Id, TypedId},
|
||||
resource::{BufferUse, QuerySet},
|
||||
|
@ -24,6 +24,77 @@ pub fn is_valid_copy_dst_texture_format(format: wgt::TextureFormat) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_buffer_usage(usage: wgt::BufferUsage) -> hal::BufferUse {
|
||||
let mut u = hal::BufferUse::empty();
|
||||
u.set(
|
||||
hal::BufferUse::MAP_READ,
|
||||
usage.contains(wgt::BufferUsage::MAP_READ),
|
||||
);
|
||||
u.set(
|
||||
hal::BufferUse::MAP_WRITE,
|
||||
usage.contains(wgt::BufferUsage::MAP_WRITE),
|
||||
);
|
||||
u.set(
|
||||
hal::BufferUse::COPY_SRC,
|
||||
usage.contains(wgt::BufferUsage::COPY_SRC),
|
||||
);
|
||||
u.set(
|
||||
hal::BufferUse::COPY_DST,
|
||||
usage.contains(wgt::BufferUsage::COPY_DST),
|
||||
);
|
||||
u.set(
|
||||
hal::BufferUse::INDEX,
|
||||
usage.contains(wgt::BufferUsage::INDEX),
|
||||
);
|
||||
u.set(
|
||||
hal::BufferUse::VERTEX,
|
||||
usage.contains(wgt::BufferUsage::VERTEX),
|
||||
);
|
||||
u.set(
|
||||
hal::BufferUse::UNIFORM,
|
||||
usage.contains(wgt::BufferUsage::UNIFORM),
|
||||
);
|
||||
u.set(
|
||||
hal::BufferUse::STORAGE,
|
||||
usage.contains(wgt::BufferUsage::STORAGE),
|
||||
);
|
||||
u.set(
|
||||
hal::BufferUse::INDIRECT,
|
||||
usage.contains(wgt::BufferUsage::INDIRECT),
|
||||
);
|
||||
u
|
||||
}
|
||||
|
||||
pub fn map_texture_usage(usage: wgt::TextureUsage, aspect: hal::FormatAspect) -> hal::TextureUse {
|
||||
let mut u = hal::TextureUse::empty();
|
||||
u.set(
|
||||
hal::TextureUse::COPY_SRC,
|
||||
usage.contains(wgt::TextureUsage::COPY_SRC),
|
||||
);
|
||||
u.set(
|
||||
hal::TextureUse::COPY_DST,
|
||||
usage.contains(wgt::TextureUsage::COPY_DST),
|
||||
);
|
||||
u.set(
|
||||
hal::TextureUse::SAMPLED,
|
||||
usage.contains(wgt::TextureUsage::SAMPLED),
|
||||
);
|
||||
u.set(
|
||||
hal::TextureUse::STORAGE_LOAD | hal::TextureUse::STORAGE_STORE,
|
||||
usage.contains(wgt::TextureUsage::STORAGE),
|
||||
);
|
||||
let is_color = aspect.contains(hal::FormatAspect::COLOR);
|
||||
u.set(
|
||||
hal::TextureUse::COLOR_TARGET,
|
||||
usage.contains(wgt::TextureUsage::RENDER_ATTACHMENT) && is_color,
|
||||
);
|
||||
u.set(
|
||||
hal::TextureUse::DEPTH_STENCIL_READ | hal::TextureUse::DEPTH_STENCIL_WRITE,
|
||||
usage.contains(wgt::TextureUsage::RENDER_ATTACHMENT) && !is_color,
|
||||
);
|
||||
u
|
||||
}
|
||||
|
||||
pub fn check_texture_dimension_size(
|
||||
dimension: wgt::TextureDimension,
|
||||
wgt::Extent3d {
|
||||
|
@ -448,13 +448,13 @@ impl<A: HalApi> Device<A> {
|
||||
return Err(resource::CreateBufferError::EmptyUsage);
|
||||
}
|
||||
|
||||
let buffer = unsafe {
|
||||
self.raw.create_buffer(&resource::BufferDescriptor {
|
||||
usage,
|
||||
..desc.clone()
|
||||
})
|
||||
}
|
||||
.map_err(DeviceError::from)?;
|
||||
let hal_desc = hal::BufferDescriptor {
|
||||
label: desc.label,
|
||||
size: desc.size,
|
||||
usage: conv::map_buffer_usage(usage),
|
||||
memory_flags: hal::MemoryFlag::empty(),
|
||||
};
|
||||
let buffer = unsafe { self.raw.create_buffer(&hal_desc) }.map_err(DeviceError::from)?;
|
||||
|
||||
Ok(resource::Buffer {
|
||||
raw: Some(buffer),
|
||||
@ -529,10 +529,24 @@ impl<A: HalApi> Device<A> {
|
||||
return Err(resource::CreateTextureError::InvalidMipLevelCount(mips));
|
||||
}
|
||||
|
||||
let mut image = unsafe { self.raw.create_image(desc).map_err(DeviceError::from)? };
|
||||
let hal_desc = hal::TextureDescriptor {
|
||||
label: desc.label,
|
||||
size: desc.size,
|
||||
mip_level_count: desc.mip_level_count,
|
||||
sample_count: desc.sample_count,
|
||||
dimension: desc.dimension,
|
||||
format: desc.format,
|
||||
usage: conv::map_texture_usage(desc.usage, desc.format.into()),
|
||||
memory_flags: hal::MemoryFlag::empty(),
|
||||
};
|
||||
let mut raw = unsafe {
|
||||
self.raw
|
||||
.create_texture(&hal_desc)
|
||||
.map_err(DeviceError::from)?
|
||||
};
|
||||
|
||||
Ok(resource::Texture {
|
||||
raw: Some(image),
|
||||
raw: Some(raw),
|
||||
device_id: Stored {
|
||||
value: id::Valid(self_id),
|
||||
ref_count: self.life_guard.add_ref(),
|
||||
@ -698,9 +712,9 @@ impl<A: HalApi> Device<A> {
|
||||
samples: texture.kind.num_samples(),
|
||||
// once a storage - forever a storage
|
||||
sampled_internal_use: if texture.usage.contains(wgt::TextureUsage::STORAGE) {
|
||||
resource::TextureUse::SAMPLED | resource::TextureUse::STORAGE_LOAD
|
||||
hal::TextureUse::SAMPLED | hal::TextureUse::STORAGE_LOAD
|
||||
} else {
|
||||
resource::TextureUse::SAMPLED
|
||||
hal::TextureUse::SAMPLED
|
||||
},
|
||||
selector,
|
||||
life_guard: LifeGuard::new(desc.label.borrow_or_default()),
|
||||
@ -1083,15 +1097,15 @@ impl<A: HalApi> Device<A> {
|
||||
let (pub_usage, internal_use, range_limit) = match binding_ty {
|
||||
wgt::BufferBindingType::Uniform => (
|
||||
wgt::BufferUsage::UNIFORM,
|
||||
resource::BufferUse::UNIFORM,
|
||||
hal::BufferUse::UNIFORM,
|
||||
limits.max_uniform_buffer_binding_size,
|
||||
),
|
||||
wgt::BufferBindingType::Storage { read_only } => (
|
||||
wgt::BufferUsage::STORAGE,
|
||||
if read_only {
|
||||
resource::BufferUse::STORAGE_LOAD
|
||||
hal::BufferUse::STORAGE_LOAD
|
||||
} else {
|
||||
resource::BufferUse::STORAGE_STORE
|
||||
hal::BufferUse::STORAGE_STORE
|
||||
},
|
||||
limits.max_storage_buffer_binding_size,
|
||||
),
|
||||
@ -1360,10 +1374,10 @@ impl<A: HalApi> Device<A> {
|
||||
}
|
||||
let internal_use = match access {
|
||||
wgt::StorageTextureAccess::ReadOnly => {
|
||||
resource::TextureUse::STORAGE_LOAD
|
||||
hal::TextureUse::STORAGE_LOAD
|
||||
}
|
||||
wgt::StorageTextureAccess::WriteOnly => {
|
||||
resource::TextureUse::STORAGE_STORE
|
||||
hal::TextureUse::STORAGE_STORE
|
||||
}
|
||||
wgt::StorageTextureAccess::ReadWrite => {
|
||||
if !view.format_features.flags.contains(
|
||||
@ -1374,8 +1388,7 @@ impl<A: HalApi> Device<A> {
|
||||
));
|
||||
}
|
||||
|
||||
resource::TextureUse::STORAGE_STORE
|
||||
| resource::TextureUse::STORAGE_LOAD
|
||||
hal::TextureUse::STORAGE_STORE | hal::TextureUse::STORAGE_LOAD
|
||||
}
|
||||
};
|
||||
(wgt::TextureUsage::STORAGE, internal_use)
|
||||
@ -2459,7 +2472,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
let ref_count = buffer.life_guard.add_ref();
|
||||
|
||||
let buffer_use = if !desc.mapped_at_creation {
|
||||
resource::BufferUse::EMPTY
|
||||
hal::BufferUse::EMPTY
|
||||
} else if desc.usage.contains(wgt::BufferUsage::MAP_WRITE) {
|
||||
// buffer is mappable, so we are just doing that at start
|
||||
let map_size = buffer.size;
|
||||
@ -2480,7 +2493,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
range: 0..map_size,
|
||||
host: HostMap::Write,
|
||||
};
|
||||
resource::BufferUse::MAP_WRITE
|
||||
hal::BufferUse::MAP_WRITE
|
||||
} else {
|
||||
// buffer needs staging area for initialization only
|
||||
let stage_desc = wgt::BufferDescriptor {
|
||||
@ -2533,7 +2546,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
stage_buffer,
|
||||
stage_memory,
|
||||
};
|
||||
resource::BufferUse::COPY_DST
|
||||
hal::BufferUse::COPY_DST
|
||||
};
|
||||
|
||||
let id = fid.assign(buffer, &mut token);
|
||||
@ -4236,8 +4249,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
let mut token = Token::root();
|
||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||
let (pub_usage, internal_use) = match op.host {
|
||||
HostMap::Read => (wgt::BufferUsage::MAP_READ, resource::BufferUse::MAP_READ),
|
||||
HostMap::Write => (wgt::BufferUsage::MAP_WRITE, resource::BufferUse::MAP_WRITE),
|
||||
HostMap::Read => (wgt::BufferUsage::MAP_READ, hal::BufferUse::MAP_READ),
|
||||
HostMap::Write => (wgt::BufferUsage::MAP_WRITE, hal::BufferUse::MAP_WRITE),
|
||||
};
|
||||
|
||||
if range.start % wgt::MAP_ALIGNMENT != 0 || range.end % wgt::COPY_BUFFER_ALIGNMENT != 0 {
|
||||
@ -4404,32 +4417,26 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
.ok_or(resource::BufferAccessError::Destroyed)?;
|
||||
|
||||
buffer.life_guard.use_at(device.active_submission_index + 1);
|
||||
let region = hal::command::BufferCopy {
|
||||
let region = hal::BufferCopy {
|
||||
src: 0,
|
||||
dst: 0,
|
||||
size: buffer.size,
|
||||
};
|
||||
let transition_src = hal::memory::Barrier::Buffer {
|
||||
states: hal::buffer::Access::HOST_WRITE..hal::buffer::Access::TRANSFER_READ,
|
||||
target: &stage_buffer,
|
||||
range: hal::buffer::SubRange::WHOLE,
|
||||
families: None,
|
||||
let transition_src = hal::BufferBarrier {
|
||||
buffer: &stage_buffer,
|
||||
usage: hal::BufferUse::MAP_WRITE..hal::BufferUse::COPY_SRC,
|
||||
};
|
||||
let transition_dst = hal::memory::Barrier::Buffer {
|
||||
states: hal::buffer::Access::empty()..hal::buffer::Access::TRANSFER_WRITE,
|
||||
target: buf_raw,
|
||||
range: hal::buffer::SubRange::WHOLE,
|
||||
families: None,
|
||||
let transition_dst = hal::BufferBarrier {
|
||||
buffer: buf_raw,
|
||||
usage: hal::BufferUse::empty()..hal::BufferUse::COPY_DST,
|
||||
};
|
||||
unsafe {
|
||||
let cmdbuf = device.borrow_pending_writes();
|
||||
cmdbuf.pipeline_barrier(
|
||||
hal::pso::PipelineStage::HOST..hal::pso::PipelineStage::TRANSFER,
|
||||
hal::memory::Dependencies::empty(),
|
||||
let cmd_buf = device.borrow_pending_writes();
|
||||
cmd_buf.transition_buffers(
|
||||
iter::once(transition_src).chain(iter::once(transition_dst)),
|
||||
);
|
||||
if buffer.size > 0 {
|
||||
cmdbuf.copy_buffer(&stage_buffer, buf_raw, iter::once(region));
|
||||
cmd_buf.copy_buffer_to_buffer(&stage_buffer, buf_raw, iter::once(region));
|
||||
}
|
||||
}
|
||||
device
|
||||
|
@ -7,38 +7,37 @@ use crate::device::trace::Action;
|
||||
use crate::{
|
||||
command::{
|
||||
texture_copy_view_to_hal, validate_linear_texture_data, validate_texture_copy_range,
|
||||
CommandAllocator, CommandBuffer, CopySide, ImageCopyTexture, TransferError, BITS_PER_BYTE,
|
||||
CommandBuffer, CopySide, ImageCopyTexture, TransferError, BITS_PER_BYTE,
|
||||
},
|
||||
conv,
|
||||
device::{alloc, DeviceError, WaitIdleError},
|
||||
device::{DeviceError, WaitIdleError},
|
||||
hub::{Global, GlobalIdentityHandlerFactory, HalApi, Storage, Token},
|
||||
id,
|
||||
memory_init_tracker::{MemoryInitKind, MemoryInitTrackerAction},
|
||||
resource::{Buffer, BufferAccessError, BufferMapState, BufferUse, TextureUse},
|
||||
resource::{Buffer, BufferAccessError, BufferMapState},
|
||||
FastHashMap, FastHashSet,
|
||||
};
|
||||
|
||||
use hal::{command::CommandBuffer as _, device::Device as _, queue::Queue as _};
|
||||
use hal::{CommandBuffer as _, Device as _, Queue as _};
|
||||
use smallvec::SmallVec;
|
||||
use std::{iter, ops::Range, ptr};
|
||||
use thiserror::Error;
|
||||
|
||||
struct StagingData<A: hal::Api> {
|
||||
buffer: B::Buffer,
|
||||
memory: alloc::MemoryBlock<A>,
|
||||
cmdbuf: B::CommandBuffer,
|
||||
buffer: A::Buffer,
|
||||
cmdbuf: A::CommandBuffer,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TempResource<A: hal::Api> {
|
||||
Buffer(B::Buffer),
|
||||
Image(B::Image),
|
||||
Buffer(A::Buffer),
|
||||
Texture(A::Texture),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct PendingWrites<A: hal::Api> {
|
||||
pub command_buffer: Option<B::CommandBuffer>,
|
||||
pub temp_resources: Vec<(TempResource<A>, alloc::MemoryBlock<A>)>,
|
||||
pub command_buffer: Option<A::CommandBuffer>,
|
||||
pub temp_resources: Vec<TempResource<A>>,
|
||||
pub dst_buffers: FastHashSet<id::BufferId>,
|
||||
pub dst_textures: FastHashSet<id::TextureId>,
|
||||
}
|
||||
@ -53,40 +52,35 @@ impl<A: hal::Api> PendingWrites<A> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dispose(
|
||||
self,
|
||||
device: &B::Device,
|
||||
cmd_allocator: &CommandAllocator<A>,
|
||||
mem_allocator: &mut alloc::MemoryAllocator<A>,
|
||||
) {
|
||||
pub fn dispose(self, device: &A::Device) {
|
||||
if let Some(raw) = self.command_buffer {
|
||||
cmd_allocator.discard_internal(raw);
|
||||
unsafe {
|
||||
device.destroy_command_buffer(raw);
|
||||
}
|
||||
}
|
||||
for (resource, memory) in self.temp_resources {
|
||||
mem_allocator.free(device, memory);
|
||||
for resource in self.temp_resources {
|
||||
match resource {
|
||||
TempResource::Buffer(buffer) => unsafe {
|
||||
device.destroy_buffer(buffer);
|
||||
},
|
||||
TempResource::Image(image) => unsafe {
|
||||
device.destroy_image(image);
|
||||
TempResource::Texture(texture) => unsafe {
|
||||
device.destroy_image(texture);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn consume_temp(&mut self, resource: TempResource<A>, memory: alloc::MemoryBlock<A>) {
|
||||
self.temp_resources.push((resource, memory));
|
||||
pub fn consume_temp(&mut self, resource: TempResource<A>) {
|
||||
self.temp_resources.push(resource);
|
||||
}
|
||||
|
||||
fn consume(&mut self, stage: StagingData<A>) {
|
||||
self.temp_resources
|
||||
.push((TempResource::Buffer(stage.buffer), stage.memory));
|
||||
self.temp_resources.push(TempResource::Buffer(stage.buffer));
|
||||
self.command_buffer = Some(stage.cmdbuf);
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
fn finish(&mut self) -> Option<B::CommandBuffer> {
|
||||
fn finish(&mut self) -> Option<A::CommandBuffer> {
|
||||
self.dst_buffers.clear();
|
||||
self.dst_textures.clear();
|
||||
self.command_buffer.take().map(|mut cmd_buf| unsafe {
|
||||
@ -95,13 +89,19 @@ impl<A: hal::Api> PendingWrites<A> {
|
||||
})
|
||||
}
|
||||
|
||||
fn borrow_cmd_buf(&mut self, cmd_allocator: &CommandAllocator<A>) -> &mut B::CommandBuffer {
|
||||
fn create_cmd_buf(device: &A::Device) -> A::CommandBuffer {
|
||||
unsafe {
|
||||
let mut cmd_buf = device.create_command_buffer(&hal::CommandBufferDescriptor {
|
||||
label: Some("_PendingWrites"),
|
||||
});
|
||||
cmd_buf.begin();
|
||||
cmd_buf
|
||||
}
|
||||
}
|
||||
|
||||
fn borrow_cmd_buf(&mut self, device: &A::Device) -> &mut A::CommandBuffer {
|
||||
if self.command_buffer.is_none() {
|
||||
let mut cmdbuf = cmd_allocator.allocate_internal();
|
||||
unsafe {
|
||||
cmdbuf.begin_primary(hal::command::CommandBufferFlags::ONE_TIME_SUBMIT);
|
||||
}
|
||||
self.command_buffer = Some(cmdbuf);
|
||||
self.command_buffer = Some(Self::create_cmd_buf(device));
|
||||
}
|
||||
self.command_buffer.as_mut().unwrap()
|
||||
}
|
||||
@ -141,52 +141,25 @@ impl RequiredBufferInits {
|
||||
}
|
||||
|
||||
impl<A: hal::Api> super::Device<A> {
|
||||
pub fn borrow_pending_writes(&mut self) -> &mut B::CommandBuffer {
|
||||
self.pending_writes.borrow_cmd_buf(&self.cmd_allocator)
|
||||
pub fn borrow_pending_writes(&mut self) -> &mut A::CommandBuffer {
|
||||
self.pending_writes.borrow_cmd_buf(&self.raw)
|
||||
}
|
||||
|
||||
fn prepare_stage(&mut self, size: wgt::BufferAddress) -> Result<StagingData<A>, DeviceError> {
|
||||
profiling::scope!("prepare_stage");
|
||||
let mut buffer = unsafe {
|
||||
self.raw
|
||||
.create_buffer(
|
||||
size,
|
||||
hal::buffer::Usage::TRANSFER_SRC,
|
||||
hal::memory::SparseFlags::empty(),
|
||||
)
|
||||
.map_err(|err| match err {
|
||||
hal::buffer::CreationError::OutOfMemory(_) => DeviceError::OutOfMemory,
|
||||
_ => panic!("failed to create staging buffer: {}", err),
|
||||
})?
|
||||
let stage_desc = hal::BufferDescriptor {
|
||||
label: Some("_Staging"),
|
||||
size,
|
||||
usage: hal::BufferUse::MAP_WRITE | hal::BufferUse::COPY_SRC,
|
||||
memory_flags: hal::MemoryFlag::TRANSIENT,
|
||||
};
|
||||
//TODO: do we need to transition into HOST_WRITE access first?
|
||||
let requirements = unsafe {
|
||||
self.raw.set_buffer_name(&mut buffer, "<write_buffer_temp>");
|
||||
self.raw.get_buffer_requirements(&buffer)
|
||||
};
|
||||
|
||||
let block = self.mem_allocator.lock().allocate(
|
||||
&self.raw,
|
||||
requirements,
|
||||
gpu_alloc::UsageFlags::UPLOAD | gpu_alloc::UsageFlags::TRANSIENT,
|
||||
)?;
|
||||
block.bind_buffer(&self.raw, &mut buffer)?;
|
||||
let mut buffer = unsafe { self.raw.create_buffer(&stage_desc)? };
|
||||
|
||||
let cmdbuf = match self.pending_writes.command_buffer.take() {
|
||||
Some(cmdbuf) => cmdbuf,
|
||||
None => {
|
||||
let mut cmdbuf = self.cmd_allocator.allocate_internal();
|
||||
unsafe {
|
||||
cmdbuf.begin_primary(hal::command::CommandBufferFlags::ONE_TIME_SUBMIT);
|
||||
}
|
||||
cmdbuf
|
||||
}
|
||||
None => PendingWrites::create_cmd_buf(&self.raw),
|
||||
};
|
||||
Ok(StagingData {
|
||||
buffer,
|
||||
memory: block,
|
||||
cmdbuf,
|
||||
})
|
||||
Ok(StagingData { buffer, cmdbuf })
|
||||
}
|
||||
|
||||
fn initialize_buffer_memory(
|
||||
@ -217,7 +190,7 @@ impl<A: hal::Api> super::Device<A> {
|
||||
let transition = trackers.buffers.change_replace_tracked(
|
||||
id::Valid(buffer_id),
|
||||
(),
|
||||
BufferUse::COPY_DST,
|
||||
hal::BufferUse::COPY_DST,
|
||||
);
|
||||
let buffer = buffer_guard.get(buffer_id).unwrap();
|
||||
let &(ref buffer_raw, _) = buffer
|
||||
@ -225,27 +198,15 @@ impl<A: hal::Api> super::Device<A> {
|
||||
.as_ref()
|
||||
.ok_or(QueueSubmitError::DestroyedBuffer(buffer_id))?;
|
||||
unsafe {
|
||||
cmd_buf.pipeline_barrier(
|
||||
super::all_buffer_stages()..hal::pso::PipelineStage::TRANSFER,
|
||||
hal::memory::Dependencies::empty(),
|
||||
transition.map(|pending| pending.into_hal(buffer)),
|
||||
);
|
||||
cmd_buf.transition_buffers(transition.map(|pending| pending.into_hal(buffer)));
|
||||
}
|
||||
for range in ranges {
|
||||
let size = range.end - range.start;
|
||||
|
||||
for range in ranges {
|
||||
assert!(range.start % 4 == 0, "Buffer {:?} has an uninitialized range with a start not aligned to 4 (start was {})", buffer, range.start);
|
||||
assert!(size % 4 == 0, "Buffer {:?} has an uninitialized range with a size not aligned to 4 (size was {})", buffer, size);
|
||||
assert!(range.end % 4 == 0, "Buffer {:?} has an uninitialized range with an end not aligned to 4 (end was {})", buffer, range.end);
|
||||
|
||||
unsafe {
|
||||
cmd_buf.fill_buffer(
|
||||
buffer_raw,
|
||||
hal::buffer::SubRange {
|
||||
offset: range.start,
|
||||
size: Some(size),
|
||||
},
|
||||
0,
|
||||
);
|
||||
cmd_buf.fill_buffer(buffer_raw, range, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -326,7 +287,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
let mut trackers = device.trackers.lock();
|
||||
let (dst, transition) = trackers
|
||||
.buffers
|
||||
.use_replace(&*buffer_guard, buffer_id, (), BufferUse::COPY_DST)
|
||||
.use_replace(&*buffer_guard, buffer_id, (), hal::BufferUse::COPY_DST)
|
||||
.map_err(TransferError::InvalidBuffer)?;
|
||||
let &(ref dst_raw, _) = dst
|
||||
.raw
|
||||
|
@ -16,9 +16,6 @@ use thiserror::Error;
|
||||
|
||||
use std::{borrow::Borrow, num::NonZeroU8, ops::Range, ptr::NonNull};
|
||||
|
||||
//TODO: remove the alias, just use it from `hal`
|
||||
pub(crate) use hal::{BufferUse, TextureUse};
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub enum BufferMapAsyncStatus {
|
||||
@ -166,7 +163,7 @@ pub type TextureDescriptor<'a> = wgt::TextureDescriptor<Label<'a>>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Texture<A: hal::Api> {
|
||||
pub(crate) raw: Option<A::Image>,
|
||||
pub(crate) raw: Option<A::Texture>,
|
||||
pub(crate) device_id: Stored<DeviceId>,
|
||||
pub(crate) desc: wgt::TextureDescriptor<()>,
|
||||
pub(crate) format_features: wgt::TextureFormatFeatures,
|
||||
@ -272,7 +269,7 @@ pub struct TextureView<A: hal::Api> {
|
||||
pub(crate) extent: wgt::Extent3d,
|
||||
pub(crate) samples: u32,
|
||||
/// Internal use of this texture view when used as `BindingType::Texture`.
|
||||
pub(crate) sampled_internal_use: TextureUse,
|
||||
pub(crate) sampled_internal_use: hal::TextureUse,
|
||||
pub(crate) selector: TextureSelector,
|
||||
pub(crate) life_guard: LifeGuard,
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
},
|
||||
samples: 1,
|
||||
framebuffer_attachment: sc.framebuffer_attachment.clone(),
|
||||
sampled_internal_use: resource::TextureUse::empty(),
|
||||
sampled_internal_use: hal::TextureUse::empty(),
|
||||
selector: TextureSelector {
|
||||
layers: 0..1,
|
||||
levels: 0..1,
|
||||
|
@ -3,12 +3,9 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use super::{PendingTransition, ResourceState, Unit};
|
||||
use crate::{
|
||||
id::{BufferId, Valid},
|
||||
resource::BufferUse,
|
||||
};
|
||||
use crate::id::{BufferId, Valid};
|
||||
use hal::BufferUse;
|
||||
|
||||
//TODO: store `hal::buffer::State` here to avoid extra conversions
|
||||
pub(crate) type BufferState = Unit<BufferUse>;
|
||||
|
||||
impl PendingTransition<BufferState> {
|
||||
|
@ -124,6 +124,21 @@ pub(crate) struct PendingTransition<S: ResourceState> {
|
||||
pub usage: ops::Range<S::Usage>,
|
||||
}
|
||||
|
||||
impl PendingTransition<BufferState> {
|
||||
/// Produce the hal barrier corresponding to the transition.
|
||||
pub fn into_hal<'a, A: hal::Api>(
|
||||
self,
|
||||
buf: &'a resource::Buffer<A>,
|
||||
) -> hal::BufferBarrier<'a, A> {
|
||||
log::trace!("\tbuffer -> {:?}", self);
|
||||
let &(ref buffer, _) = buf.raw.as_ref().expect("Buffer is destroyed");
|
||||
hal::BufferBarrier {
|
||||
buffer,
|
||||
usage: self.usage,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PendingTransition<BufferState>> for UsageConflict {
|
||||
fn from(e: PendingTransition<BufferState>) -> Self {
|
||||
Self::Buffer {
|
||||
@ -133,6 +148,22 @@ impl From<PendingTransition<BufferState>> for UsageConflict {
|
||||
}
|
||||
}
|
||||
|
||||
impl PendingTransition<TextureState> {
|
||||
/// Produce the hal barrier corresponding to the transition.
|
||||
pub fn into_hal<'a, A: hal::Api>(
|
||||
self,
|
||||
tex: &'a resource::Texture<A>,
|
||||
) -> hal::TextureBarrier<'a, A> {
|
||||
log::trace!("\ttexture -> {:?}", self);
|
||||
let &(ref texture, _) = tex.raw.as_ref().expect("Texture is destroyed");
|
||||
hal::TextureBarrier {
|
||||
texture,
|
||||
subresource: self.selector,
|
||||
usage: self.usage,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PendingTransition<TextureState>> for UsageConflict {
|
||||
fn from(e: PendingTransition<TextureState>) -> Self {
|
||||
Self::Texture {
|
||||
@ -514,14 +545,14 @@ pub enum UsageConflict {
|
||||
)]
|
||||
Buffer {
|
||||
id: id::BufferId,
|
||||
combined_use: resource::BufferUse,
|
||||
combined_use: hal::BufferUse,
|
||||
},
|
||||
#[error("Attempted to use texture {id:?} mips {mip_levels:?} layers {array_layers:?} as a combination of {combined_use:?} within a usage scope.")]
|
||||
Texture {
|
||||
id: id::TextureId,
|
||||
mip_levels: ops::Range<u32>,
|
||||
array_layers: ops::Range<u32>,
|
||||
combined_use: resource::TextureUse,
|
||||
combined_use: hal::TextureUse,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,8 @@ use super::{range::RangedStates, PendingTransition, ResourceState, Unit};
|
||||
use crate::{
|
||||
device::MAX_MIP_LEVELS,
|
||||
id::{TextureId, Valid},
|
||||
resource::TextureUse,
|
||||
};
|
||||
use hal::TextureUse;
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
#![allow(unused_variables)]
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Api;
|
||||
pub struct Context;
|
||||
@ -42,161 +44,241 @@ impl crate::Instance<Api> for Context {
|
||||
impl crate::Surface<Api> for Context {
|
||||
unsafe fn configure(
|
||||
&mut self,
|
||||
_device: &Context,
|
||||
_config: &crate::SurfaceConfiguration,
|
||||
device: &Context,
|
||||
config: &crate::SurfaceConfiguration,
|
||||
) -> Result<(), crate::SurfaceError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
unsafe fn unconfigure(&mut self, _device: &Context) {}
|
||||
unsafe fn unconfigure(&mut self, device: &Context) {}
|
||||
|
||||
unsafe fn acquire_texture(
|
||||
&mut self,
|
||||
_timeout_ms: u32,
|
||||
timeout_ms: u32,
|
||||
) -> Result<(Resource, Option<crate::Suboptimal>), crate::SurfaceError> {
|
||||
Ok((Resource, None))
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Adapter<Api> for Context {
|
||||
unsafe fn open(&self, _features: wgt::Features) -> DeviceResult<crate::OpenDevice<Api>> {
|
||||
unsafe fn open(&self, features: wgt::Features) -> DeviceResult<crate::OpenDevice<Api>> {
|
||||
Err(crate::DeviceError::Lost)
|
||||
}
|
||||
unsafe fn close(&self, _device: Context) {}
|
||||
unsafe fn close(&self, device: Context) {}
|
||||
unsafe fn texture_format_capabilities(
|
||||
&self,
|
||||
_format: wgt::TextureFormat,
|
||||
format: wgt::TextureFormat,
|
||||
) -> crate::TextureFormatCapability {
|
||||
crate::TextureFormatCapability::empty()
|
||||
}
|
||||
unsafe fn surface_capabilities(
|
||||
&self,
|
||||
_surface: &Context,
|
||||
) -> Option<crate::SurfaceCapabilities> {
|
||||
unsafe fn surface_capabilities(&self, surface: &Context) -> Option<crate::SurfaceCapabilities> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Queue<Api> for Context {
|
||||
unsafe fn submit<I: Iterator<Item = Encoder>>(&mut self, _command_buffers: I) {}
|
||||
unsafe fn submit<I>(&mut self, command_buffers: I) {}
|
||||
}
|
||||
|
||||
impl crate::Device<Api> for Context {
|
||||
unsafe fn create_buffer(
|
||||
&self,
|
||||
_desc: &wgt::BufferDescriptor<crate::Label>,
|
||||
) -> DeviceResult<Resource> {
|
||||
unsafe fn create_buffer(&self, desc: &crate::BufferDescriptor) -> DeviceResult<Resource> {
|
||||
Ok(Resource)
|
||||
}
|
||||
unsafe fn destroy_buffer(&self, _buffer: Resource) {}
|
||||
unsafe fn destroy_buffer(&self, buffer: Resource) {}
|
||||
unsafe fn map_buffer(
|
||||
&self,
|
||||
_buffer: &Resource,
|
||||
_range: crate::MemoryRange,
|
||||
buffer: &Resource,
|
||||
range: crate::MemoryRange,
|
||||
) -> DeviceResult<std::ptr::NonNull<u8>> {
|
||||
Err(crate::DeviceError::Lost)
|
||||
}
|
||||
unsafe fn unmap_buffer(&self, _buffer: &Resource) {}
|
||||
unsafe fn flush_mapped_ranges<I: Iterator<Item = crate::MemoryRange>>(
|
||||
&self,
|
||||
_buffer: &Resource,
|
||||
_ranges: I,
|
||||
) {
|
||||
}
|
||||
unsafe fn invalidate_mapped_ranges<I: Iterator<Item = crate::MemoryRange>>(
|
||||
&self,
|
||||
_buffer: &Resource,
|
||||
_ranges: I,
|
||||
) {
|
||||
}
|
||||
unsafe fn unmap_buffer(&self, buffer: &Resource) {}
|
||||
unsafe fn flush_mapped_ranges<I>(&self, buffer: &Resource, ranges: I) {}
|
||||
unsafe fn invalidate_mapped_ranges<I>(&self, buffer: &Resource, ranges: I) {}
|
||||
|
||||
unsafe fn create_texture(
|
||||
&self,
|
||||
_desc: &wgt::TextureDescriptor<crate::Label>,
|
||||
) -> DeviceResult<Resource> {
|
||||
unsafe fn create_texture(&self, desc: &crate::TextureDescriptor) -> DeviceResult<Resource> {
|
||||
Ok(Resource)
|
||||
}
|
||||
unsafe fn destroy_texture(&self, _texture: Resource) {}
|
||||
unsafe fn destroy_texture(&self, texture: Resource) {}
|
||||
unsafe fn create_texture_view(
|
||||
&self,
|
||||
_texture: &Resource,
|
||||
_desc: &crate::TextureViewDescriptor,
|
||||
texture: &Resource,
|
||||
desc: &crate::TextureViewDescriptor,
|
||||
) -> DeviceResult<Resource> {
|
||||
Ok(Resource)
|
||||
}
|
||||
unsafe fn destroy_texture_view(&self, _view: Resource) {}
|
||||
unsafe fn create_sampler(&self, _desc: &crate::SamplerDescriptor) -> DeviceResult<Resource> {
|
||||
unsafe fn destroy_texture_view(&self, view: Resource) {}
|
||||
unsafe fn create_sampler(&self, desc: &crate::SamplerDescriptor) -> DeviceResult<Resource> {
|
||||
Ok(Resource)
|
||||
}
|
||||
unsafe fn destroy_sampler(&self, _sampler: Resource) {}
|
||||
unsafe fn destroy_sampler(&self, sampler: Resource) {}
|
||||
|
||||
unsafe fn create_command_buffer(
|
||||
&self,
|
||||
_desc: &crate::CommandBufferDescriptor,
|
||||
desc: &crate::CommandBufferDescriptor,
|
||||
) -> DeviceResult<Encoder> {
|
||||
Ok(Encoder)
|
||||
}
|
||||
unsafe fn destroy_command_buffer(&self, _cmd_buf: Encoder) {}
|
||||
unsafe fn destroy_command_buffer(&self, cmd_buf: Encoder) {}
|
||||
|
||||
unsafe fn create_bind_group_layout(
|
||||
&self,
|
||||
_desc: &crate::BindGroupLayoutDescriptor,
|
||||
desc: &crate::BindGroupLayoutDescriptor,
|
||||
) -> DeviceResult<Resource> {
|
||||
Ok(Resource)
|
||||
}
|
||||
unsafe fn destroy_bind_group_layout(&self, _bg_layout: Resource) {}
|
||||
unsafe fn destroy_bind_group_layout(&self, bg_layout: Resource) {}
|
||||
unsafe fn create_pipeline_layout(
|
||||
&self,
|
||||
_desc: &crate::PipelineLayoutDescriptor<Api>,
|
||||
desc: &crate::PipelineLayoutDescriptor<Api>,
|
||||
) -> DeviceResult<Resource> {
|
||||
Ok(Resource)
|
||||
}
|
||||
unsafe fn destroy_pipeline_layout(&self, _pipeline_layout: Resource) {}
|
||||
unsafe fn destroy_pipeline_layout(&self, pipeline_layout: Resource) {}
|
||||
unsafe fn create_bind_group(
|
||||
&self,
|
||||
_desc: &crate::BindGroupDescriptor<Api>,
|
||||
desc: &crate::BindGroupDescriptor<Api>,
|
||||
) -> DeviceResult<Resource> {
|
||||
Ok(Resource)
|
||||
}
|
||||
unsafe fn destroy_bind_group(&self, _group: Resource) {}
|
||||
unsafe fn destroy_bind_group(&self, group: Resource) {}
|
||||
|
||||
unsafe fn create_shader_module(
|
||||
&self,
|
||||
_desc: &crate::ShaderModuleDescriptor,
|
||||
_shader: crate::NagaShader,
|
||||
desc: &crate::ShaderModuleDescriptor,
|
||||
shader: crate::NagaShader,
|
||||
) -> Result<Resource, (crate::ShaderError, crate::NagaShader)> {
|
||||
Ok(Resource)
|
||||
}
|
||||
unsafe fn destroy_shader_module(&self, _module: Resource) {}
|
||||
unsafe fn destroy_shader_module(&self, module: Resource) {}
|
||||
unsafe fn create_render_pipeline(
|
||||
&self,
|
||||
_desc: &crate::RenderPipelineDescriptor<Api>,
|
||||
desc: &crate::RenderPipelineDescriptor<Api>,
|
||||
) -> Result<Resource, crate::PipelineError> {
|
||||
Ok(Resource)
|
||||
}
|
||||
unsafe fn destroy_render_pipeline(&self, _pipeline: Resource) {}
|
||||
unsafe fn destroy_render_pipeline(&self, pipeline: Resource) {}
|
||||
unsafe fn create_compute_pipeline(
|
||||
&self,
|
||||
_desc: &crate::ComputePipelineDescriptor<Api>,
|
||||
desc: &crate::ComputePipelineDescriptor<Api>,
|
||||
) -> Result<Resource, crate::PipelineError> {
|
||||
Ok(Resource)
|
||||
}
|
||||
unsafe fn destroy_compute_pipeline(&self, _pipeline: Resource) {}
|
||||
unsafe fn destroy_compute_pipeline(&self, pipeline: Resource) {}
|
||||
}
|
||||
|
||||
impl crate::CommandBuffer<Api> for Encoder {
|
||||
unsafe fn begin(&mut self) {}
|
||||
unsafe fn end(&mut self) {}
|
||||
|
||||
unsafe fn transition_buffers<'a, T>(&mut self, barriers: T)
|
||||
where
|
||||
T: Iterator<Item = crate::BufferBarrier<'a, Api>>,
|
||||
{
|
||||
}
|
||||
|
||||
unsafe fn transition_textures<'a, T>(&mut self, barriers: T)
|
||||
where
|
||||
T: Iterator<Item = crate::TextureBarrier<'a, Api>>,
|
||||
{
|
||||
}
|
||||
|
||||
unsafe fn fill_buffer(&mut self, buffer: &Resource, range: crate::MemoryRange, value: u8) {}
|
||||
|
||||
unsafe fn copy_buffer_to_buffer<T>(&mut self, src: &Resource, dst: &Resource, regions: T)
|
||||
where
|
||||
T: Iterator<Item = crate::BufferCopy>,
|
||||
{
|
||||
}
|
||||
|
||||
/// Note: `dst` current usage has to be `TextureUse::COPY_DST`.
|
||||
unsafe fn copy_texture_to_texture<T>(
|
||||
&mut self,
|
||||
src: &Resource,
|
||||
src_usage: crate::TextureUse,
|
||||
dst: &Resource,
|
||||
regions: T,
|
||||
) {
|
||||
}
|
||||
|
||||
/// Note: `dst` current usage has to be `TextureUse::COPY_DST`.
|
||||
unsafe fn copy_buffer_to_texture<T>(&mut self, src: &Resource, dst: &Resource, regions: T) {}
|
||||
|
||||
unsafe fn copy_texture_to_buffer<T>(
|
||||
&mut self,
|
||||
src: &Resource,
|
||||
src_usage: crate::TextureUse,
|
||||
dst: &Resource,
|
||||
regions: T,
|
||||
) {
|
||||
}
|
||||
|
||||
unsafe fn begin_render_pass(&mut self) -> Encoder {
|
||||
Encoder
|
||||
}
|
||||
unsafe fn end_render_pass(&mut self, _pass: Encoder) {}
|
||||
unsafe fn end_render_pass(&mut self, pass: Encoder) {}
|
||||
unsafe fn begin_compute_pass(&mut self) -> Encoder {
|
||||
Encoder
|
||||
}
|
||||
unsafe fn end_compute_pass(&mut self, _pass: Encoder) {}
|
||||
unsafe fn end_compute_pass(&mut self, pass: Encoder) {}
|
||||
}
|
||||
|
||||
impl crate::RenderPass<Api> for Encoder {}
|
||||
impl crate::ComputePass<Api> for Encoder {}
|
||||
impl crate::RenderPass<Api> for Encoder {
|
||||
unsafe fn set_pipeline(&mut self, pipeline: &Resource) {}
|
||||
|
||||
unsafe fn set_bind_group(&mut self, layout: &Resource, index: u32, group: &Resource) {}
|
||||
|
||||
unsafe fn set_index_buffer<'a>(
|
||||
&mut self,
|
||||
binding: crate::BufferBinding<'a, Api>,
|
||||
format: wgt::IndexFormat,
|
||||
) {
|
||||
}
|
||||
unsafe fn set_vertex_buffer<'a>(&mut self, index: u32, binding: crate::BufferBinding<'a, Api>) {
|
||||
}
|
||||
unsafe fn set_viewport(&mut self, rect: &crate::Rect, depth_range: std::ops::Range<f32>) {}
|
||||
unsafe fn set_scissor_rect(&mut self, rect: &crate::Rect) {}
|
||||
unsafe fn set_stencil_reference(&mut self, value: u32) {}
|
||||
unsafe fn set_blend_constants(&mut self, color: wgt::Color) {}
|
||||
|
||||
unsafe fn draw(
|
||||
&mut self,
|
||||
start_vertex: u32,
|
||||
vertex_count: u32,
|
||||
start_instance: u32,
|
||||
instance_count: u32,
|
||||
) {
|
||||
}
|
||||
unsafe fn draw_indexed(
|
||||
&mut self,
|
||||
start_index: u32,
|
||||
index_count: u32,
|
||||
base_vertex: i32,
|
||||
start_instance: u32,
|
||||
instance_count: u32,
|
||||
) {
|
||||
}
|
||||
unsafe fn draw_indirect(
|
||||
&mut self,
|
||||
buffer: &Resource,
|
||||
offset: wgt::BufferAddress,
|
||||
draw_count: u32,
|
||||
) {
|
||||
}
|
||||
unsafe fn draw_indexed_indirect(
|
||||
&mut self,
|
||||
buffer: &Resource,
|
||||
offset: wgt::BufferAddress,
|
||||
draw_count: u32,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::ComputePass<Api> for Encoder {
|
||||
unsafe fn set_pipeline(&mut self, pipeline: &Resource) {}
|
||||
|
||||
unsafe fn set_bind_group(&mut self, layout: &Resource, index: u32, group: &Resource) {}
|
||||
|
||||
unsafe fn dispatch(&mut self, count: [u32; 3]) {}
|
||||
unsafe fn dispatch_indirect(&mut self, buffer: &Resource, offset: wgt::BufferAddress) {}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* - Objects are passed by references and returned by value. No IDs.
|
||||
* - Mapping is persistent, with explicit synchronization.
|
||||
* - Resource transitions are explicit.
|
||||
* - All layouts are explicit.
|
||||
* - All layouts are explicit. Binding model has compatibility.
|
||||
*/
|
||||
|
||||
#![allow(
|
||||
@ -107,9 +107,9 @@ pub trait Api: Clone + Sized {
|
||||
type RenderPass: RenderPass<Self>;
|
||||
type ComputePass: ComputePass<Self>;
|
||||
|
||||
type Buffer: fmt::Debug + Send + Sync;
|
||||
type Buffer: fmt::Debug + Send + Sync + 'static;
|
||||
type QuerySet: fmt::Debug + Send + Sync;
|
||||
type Texture: fmt::Debug + Send + Sync;
|
||||
type Texture: fmt::Debug + Send + Sync + 'static;
|
||||
type SurfaceTexture: fmt::Debug + Send + Sync + Borrow<Self::Texture>;
|
||||
type TextureView: fmt::Debug + Send + Sync;
|
||||
type Sampler: fmt::Debug + Send + Sync;
|
||||
@ -158,10 +158,8 @@ pub trait Adapter<A: Api> {
|
||||
}
|
||||
|
||||
pub trait Device<A: Api> {
|
||||
unsafe fn create_buffer(
|
||||
&self,
|
||||
desc: &wgt::BufferDescriptor<Label>,
|
||||
) -> Result<A::Buffer, DeviceError>;
|
||||
///Note: `desc.mapped_at_creation` flag is ignored.
|
||||
unsafe fn create_buffer(&self, desc: &BufferDescriptor) -> Result<A::Buffer, DeviceError>;
|
||||
unsafe fn destroy_buffer(&self, buffer: A::Buffer);
|
||||
unsafe fn map_buffer(
|
||||
&self,
|
||||
@ -180,10 +178,7 @@ pub trait Device<A: Api> {
|
||||
ranges: I,
|
||||
);
|
||||
|
||||
unsafe fn create_texture(
|
||||
&self,
|
||||
desc: &wgt::TextureDescriptor<Label>,
|
||||
) -> Result<A::Texture, DeviceError>;
|
||||
unsafe fn create_texture(&self, desc: &TextureDescriptor) -> Result<A::Texture, DeviceError>;
|
||||
unsafe fn destroy_texture(&self, texture: A::Texture);
|
||||
unsafe fn create_texture_view(
|
||||
&self,
|
||||
@ -244,14 +239,117 @@ pub trait CommandBuffer<A: Api> {
|
||||
unsafe fn begin(&mut self);
|
||||
unsafe fn end(&mut self);
|
||||
|
||||
unsafe fn transition_buffers<'a, T>(&mut self, barriers: T)
|
||||
where
|
||||
T: Iterator<Item = BufferBarrier<'a, A>>;
|
||||
|
||||
unsafe fn transition_textures<'a, T>(&mut self, barriers: T)
|
||||
where
|
||||
T: Iterator<Item = TextureBarrier<'a, A>>;
|
||||
|
||||
unsafe fn fill_buffer(&mut self, buffer: &A::Buffer, range: MemoryRange, value: u8);
|
||||
|
||||
unsafe fn copy_buffer_to_buffer<T>(&mut self, src: &A::Buffer, dst: &A::Buffer, regions: T)
|
||||
where
|
||||
T: Iterator<Item = BufferCopy>;
|
||||
|
||||
/// Note: `dst` current usage has to be `TextureUse::COPY_DST`.
|
||||
unsafe fn copy_texture_to_texture<T>(
|
||||
&mut self,
|
||||
src: &A::Texture,
|
||||
src_usage: TextureUse,
|
||||
dst: &A::Texture,
|
||||
regions: T,
|
||||
) where
|
||||
T: Iterator<Item = TextureCopy>;
|
||||
|
||||
/// Note: `dst` current usage has to be `TextureUse::COPY_DST`.
|
||||
unsafe fn copy_buffer_to_texture<T>(&mut self, src: &A::Buffer, dst: &A::Texture, regions: T)
|
||||
where
|
||||
T: Iterator<Item = BufferTextureCopy>;
|
||||
|
||||
unsafe fn copy_texture_to_buffer<T>(
|
||||
&mut self,
|
||||
src: &A::Texture,
|
||||
src_usage: TextureUse,
|
||||
dst: &A::Buffer,
|
||||
regions: T,
|
||||
) where
|
||||
T: Iterator<Item = BufferTextureCopy>;
|
||||
|
||||
unsafe fn begin_render_pass(&mut self) -> A::RenderPass;
|
||||
unsafe fn end_render_pass(&mut self, pass: A::RenderPass);
|
||||
unsafe fn begin_compute_pass(&mut self) -> A::ComputePass;
|
||||
unsafe fn end_compute_pass(&mut self, pass: A::ComputePass);
|
||||
}
|
||||
|
||||
pub trait RenderPass<A: Api> {}
|
||||
pub trait ComputePass<A: Api> {}
|
||||
pub trait RenderPass<A: Api> {
|
||||
unsafe fn set_pipeline(&mut self, pipeline: &A::RenderPipeline);
|
||||
|
||||
/// Sets the bind group at `index` to `group`, assuming the layout
|
||||
/// of all the preceeding groups to be taken from `layout`.
|
||||
unsafe fn set_bind_group(
|
||||
&mut self,
|
||||
layout: &A::PipelineLayout,
|
||||
index: u32,
|
||||
group: &A::BindGroup,
|
||||
);
|
||||
|
||||
unsafe fn set_index_buffer<'a>(
|
||||
&mut self,
|
||||
binding: BufferBinding<'a, A>,
|
||||
format: wgt::IndexFormat,
|
||||
);
|
||||
unsafe fn set_vertex_buffer<'a>(&mut self, index: u32, binding: BufferBinding<'a, A>);
|
||||
unsafe fn set_viewport(&mut self, rect: &Rect, depth_range: Range<f32>);
|
||||
unsafe fn set_scissor_rect(&mut self, rect: &Rect);
|
||||
unsafe fn set_stencil_reference(&mut self, value: u32);
|
||||
unsafe fn set_blend_constants(&mut self, color: wgt::Color);
|
||||
|
||||
unsafe fn draw(
|
||||
&mut self,
|
||||
start_vertex: u32,
|
||||
vertex_count: u32,
|
||||
start_instance: u32,
|
||||
instance_count: u32,
|
||||
);
|
||||
unsafe fn draw_indexed(
|
||||
&mut self,
|
||||
start_index: u32,
|
||||
index_count: u32,
|
||||
base_vertex: i32,
|
||||
start_instance: u32,
|
||||
instance_count: u32,
|
||||
);
|
||||
unsafe fn draw_indirect(
|
||||
&mut self,
|
||||
buffer: &A::Buffer,
|
||||
offset: wgt::BufferAddress,
|
||||
draw_count: u32,
|
||||
);
|
||||
unsafe fn draw_indexed_indirect(
|
||||
&mut self,
|
||||
buffer: &A::Buffer,
|
||||
offset: wgt::BufferAddress,
|
||||
draw_count: u32,
|
||||
);
|
||||
}
|
||||
|
||||
pub trait ComputePass<A: Api> {
|
||||
unsafe fn set_pipeline(&mut self, pipeline: &A::ComputePipeline);
|
||||
|
||||
/// Sets the bind group at `index` to `group`, assuming the layout
|
||||
/// of all the preceeding groups to be taken from `layout`.
|
||||
unsafe fn set_bind_group(
|
||||
&mut self,
|
||||
layout: &A::PipelineLayout,
|
||||
index: u32,
|
||||
group: &A::BindGroup,
|
||||
);
|
||||
|
||||
unsafe fn dispatch(&mut self, count: [u32; 3]);
|
||||
unsafe fn dispatch_indirect(&mut self, buffer: &A::Buffer, offset: wgt::BufferAddress);
|
||||
}
|
||||
|
||||
bitflags!(
|
||||
/// Texture format capability flags.
|
||||
@ -303,6 +401,12 @@ impl From<wgt::TextureFormat> for FormatAspect {
|
||||
}
|
||||
}
|
||||
|
||||
bitflags!(
|
||||
pub struct MemoryFlag: u32 {
|
||||
const TRANSIENT = 1;
|
||||
}
|
||||
);
|
||||
|
||||
bitflags::bitflags! {
|
||||
/// Similar to `wgt::BufferUsage` but for internal use.
|
||||
pub struct BufferUse: u32 {
|
||||
@ -423,6 +527,26 @@ pub struct OpenDevice<A: Api> {
|
||||
pub queue: A::Queue,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BufferDescriptor<'a> {
|
||||
pub label: Label<'a>,
|
||||
pub size: wgt::BufferAddress,
|
||||
pub usage: BufferUse,
|
||||
pub memory_flags: MemoryFlag,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TextureDescriptor<'a> {
|
||||
pub label: Label<'a>,
|
||||
pub size: wgt::Extent3d,
|
||||
pub mip_level_count: u32,
|
||||
pub sample_count: u32,
|
||||
pub dimension: wgt::TextureDimension,
|
||||
pub format: wgt::TextureFormat,
|
||||
pub usage: TextureUse,
|
||||
pub memory_flags: MemoryFlag,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TextureViewDescriptor<'a> {
|
||||
pub label: Label<'a>,
|
||||
@ -638,6 +762,51 @@ pub struct SurfaceConfiguration {
|
||||
pub usage: TextureUse,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Rect {
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
pub w: f32,
|
||||
pub h: f32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BufferBarrier<'a, A: Api> {
|
||||
pub buffer: &'a A::Buffer,
|
||||
pub usage: Range<BufferUse>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TextureBarrier<'a, A: Api> {
|
||||
pub texture: &'a A::Texture,
|
||||
pub subresource: wgt::ImageSubresourceRange,
|
||||
pub usage: Range<TextureUse>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct BufferCopy {
|
||||
pub src: wgt::BufferAddress,
|
||||
pub dst: wgt::BufferAddress,
|
||||
pub size: wgt::BufferSize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TextureCopy {
|
||||
pub src_subresource: wgt::ImageSubresourceRange,
|
||||
pub src_origin: wgt::Origin3d,
|
||||
pub dst_subresource: wgt::ImageSubresourceRange,
|
||||
pub dst_origin: wgt::Origin3d,
|
||||
pub size: wgt::Extent3d,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BufferTextureCopy {
|
||||
pub buffer_layout: wgt::ImageDataLayout,
|
||||
pub texture_mip_level: u32,
|
||||
pub texture_origin: wgt::Origin3d,
|
||||
pub size: wgt::Extent3d,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_limits() {
|
||||
let limits = wgt::Limits::default();
|
||||
|
Loading…
Reference in New Issue
Block a user