mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Rename SwapChain::get_next_texture to SwapChain::get_next_frame, and have it return errors to the user.
This commit is contained in:
@@ -28,14 +28,14 @@ vulkan = ["wgc/gfx-backend-vulkan"]
|
||||
package = "wgpu-core"
|
||||
version = "0.5"
|
||||
git = "https://github.com/gfx-rs/wgpu"
|
||||
rev = "4e1d76013c0b272383400beba48dc306e1a350f6"
|
||||
rev = "a6d468086dc48683d0c97b9e3b63264ad67660da"
|
||||
features = ["raw-window-handle"]
|
||||
|
||||
[dependencies.wgt]
|
||||
package = "wgpu-types"
|
||||
version = "0.5"
|
||||
git = "https://github.com/gfx-rs/wgpu"
|
||||
rev = "4e1d76013c0b272383400beba48dc306e1a350f6"
|
||||
rev = "a6d468086dc48683d0c97b9e3b63264ad67660da"
|
||||
|
||||
[dependencies]
|
||||
arrayvec = "0.5"
|
||||
|
||||
@@ -259,7 +259,7 @@ impl framework::Example for Example {
|
||||
/// a TriangleList draw call for all NUM_PARTICLES at 3 vertices each
|
||||
fn render(
|
||||
&mut self,
|
||||
frame: &wgpu::SwapChainOutput,
|
||||
frame: &wgpu::SwapChainTexture,
|
||||
device: &wgpu::Device,
|
||||
_queue: &wgpu::Queue,
|
||||
) -> wgpu::CommandBuffer {
|
||||
|
||||
@@ -95,7 +95,7 @@ async fn run() {
|
||||
queue.submit(Some(command_buffer));
|
||||
|
||||
// Note that we're not calling `.await` here.
|
||||
let buffer_future = output_buffer.map_read(0, (size * size) as u64 * size_of::<u32>() as u64);
|
||||
let buffer_future = output_buffer.map_read(0, wgt::BufferSize::WHOLE);
|
||||
|
||||
// Poll the device in a blocking manner so that our future resolves.
|
||||
// In an actual application, `device.poll(...)` should
|
||||
|
||||
@@ -319,7 +319,7 @@ impl framework::Example for Example {
|
||||
|
||||
fn render(
|
||||
&mut self,
|
||||
frame: &wgpu::SwapChainOutput,
|
||||
frame: &wgpu::SwapChainTexture,
|
||||
device: &wgpu::Device,
|
||||
_queue: &wgpu::Queue,
|
||||
) -> wgpu::CommandBuffer {
|
||||
|
||||
@@ -44,7 +44,7 @@ pub trait Example: 'static + Sized {
|
||||
fn update(&mut self, event: WindowEvent);
|
||||
fn render(
|
||||
&mut self,
|
||||
frame: &wgpu::SwapChainOutput,
|
||||
frame: &wgpu::SwapChainTexture,
|
||||
device: &wgpu::Device,
|
||||
queue: &wgpu::Queue,
|
||||
) -> wgpu::CommandBuffer;
|
||||
@@ -143,7 +143,6 @@ async fn run_async<E: Example>(event_loop: EventLoop<()>, window: Window) {
|
||||
log::info!("Resizing to {:?}", size);
|
||||
sc_desc.width = size.width;
|
||||
sc_desc.height = size.height;
|
||||
swap_chain = device.create_swap_chain(&surface, &sc_desc);
|
||||
example.resize(&sc_desc, &device, &queue);
|
||||
}
|
||||
event::Event::WindowEvent { event, .. } => match event {
|
||||
@@ -164,10 +163,17 @@ async fn run_async<E: Example>(event_loop: EventLoop<()>, window: Window) {
|
||||
}
|
||||
},
|
||||
event::Event::RedrawRequested(_) => {
|
||||
let frame = swap_chain
|
||||
.get_next_texture()
|
||||
.expect("Timeout when acquiring next swap chain texture");
|
||||
let command_buf = example.render(&frame, &device, &queue);
|
||||
let frame = match swap_chain.get_next_frame() {
|
||||
Ok(frame) => frame,
|
||||
Err(_) => {
|
||||
swap_chain = device.create_swap_chain(&surface, &sc_desc);
|
||||
swap_chain
|
||||
.get_next_frame()
|
||||
.expect("Failed to acquire next swap chain texture!")
|
||||
}
|
||||
};
|
||||
|
||||
let command_buf = example.render(&frame.output, &device, &queue);
|
||||
queue.submit(Some(command_buf));
|
||||
}
|
||||
_ => {}
|
||||
|
||||
@@ -111,7 +111,7 @@ async fn execute_gpu(numbers: Vec<u32>) -> Vec<u32> {
|
||||
queue.submit(Some(encoder.finish()));
|
||||
|
||||
// Note that we're not calling `.await` here.
|
||||
let buffer_future = staging_buffer.map_read(0, size);
|
||||
let buffer_future = staging_buffer.map_read(0, wgt::BufferSize::WHOLE);
|
||||
|
||||
// Poll the device in a blocking manner so that our future resolves.
|
||||
// In an actual application, `device.poll(...)` should
|
||||
|
||||
@@ -110,8 +110,9 @@ async fn run(event_loop: EventLoop<()>, window: Window, swapchain_format: wgpu::
|
||||
}
|
||||
Event::RedrawRequested(_) => {
|
||||
let frame = swap_chain
|
||||
.get_next_texture()
|
||||
.expect("Timeout when acquiring next swap chain texture");
|
||||
.get_next_frame()
|
||||
.expect("Failed to acquire next swap chain texture")
|
||||
.output;
|
||||
let mut encoder =
|
||||
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
||||
{
|
||||
|
||||
@@ -412,7 +412,7 @@ impl framework::Example for Example {
|
||||
|
||||
fn render(
|
||||
&mut self,
|
||||
frame: &wgpu::SwapChainOutput,
|
||||
frame: &wgpu::SwapChainTexture,
|
||||
device: &wgpu::Device,
|
||||
_queue: &wgpu::Queue,
|
||||
) -> wgpu::CommandBuffer {
|
||||
|
||||
@@ -218,7 +218,7 @@ impl framework::Example for Example {
|
||||
|
||||
fn render(
|
||||
&mut self,
|
||||
frame: &wgpu::SwapChainOutput,
|
||||
frame: &wgpu::SwapChainTexture,
|
||||
device: &wgpu::Device,
|
||||
_queue: &wgpu::Queue,
|
||||
) -> wgpu::CommandBuffer {
|
||||
|
||||
@@ -698,7 +698,7 @@ impl framework::Example for Example {
|
||||
|
||||
fn render(
|
||||
&mut self,
|
||||
frame: &wgpu::SwapChainOutput,
|
||||
frame: &wgpu::SwapChainTexture,
|
||||
device: &wgpu::Device,
|
||||
queue: &wgpu::Queue,
|
||||
) -> wgpu::CommandBuffer {
|
||||
|
||||
@@ -261,7 +261,7 @@ impl framework::Example for Skybox {
|
||||
|
||||
fn render(
|
||||
&mut self,
|
||||
frame: &wgpu::SwapChainOutput,
|
||||
frame: &wgpu::SwapChainTexture,
|
||||
device: &wgpu::Device,
|
||||
queue: &wgpu::Queue,
|
||||
) -> wgpu::CommandBuffer {
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
use crate::{
|
||||
backend::native_gpu_future, BindGroupDescriptor, BindGroupLayoutDescriptor, BindingResource,
|
||||
BindingType, BufferDescriptor, CommandEncoderDescriptor, ComputePipelineDescriptor,
|
||||
PipelineLayoutDescriptor, RenderPipelineDescriptor, SamplerDescriptor, TextureDescriptor,
|
||||
TextureViewDescriptor, TextureViewDimension,
|
||||
PipelineLayoutDescriptor, RenderPipelineDescriptor, SamplerDescriptor, SwapChainStatus,
|
||||
TextureDescriptor, TextureViewDescriptor, TextureViewDimension,
|
||||
};
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
use futures::future::{ready, Ready};
|
||||
use smallvec::SmallVec;
|
||||
use std::{ffi::CString, marker::PhantomData, ptr, slice};
|
||||
use std::{ffi::CString, marker::PhantomData, ops::Range, ptr, slice};
|
||||
|
||||
macro_rules! gfx_select {
|
||||
($id:expr => $global:ident.$method:ident( $($param:expr),+ )) => {
|
||||
@@ -89,7 +89,7 @@ mod pass_impl {
|
||||
&mut self,
|
||||
buffer: &wgc::id::BufferId,
|
||||
offset: wgt::BufferAddress,
|
||||
size: wgt::BufferAddress,
|
||||
size: wgt::BufferSize,
|
||||
) {
|
||||
unsafe { wgpu_render_pass_set_index_buffer(self, *buffer, offset, size) }
|
||||
}
|
||||
@@ -98,7 +98,7 @@ mod pass_impl {
|
||||
slot: u32,
|
||||
buffer: &wgc::id::BufferId,
|
||||
offset: wgt::BufferAddress,
|
||||
size: wgt::BufferAddress,
|
||||
size: wgt::BufferSize,
|
||||
) {
|
||||
unsafe { wgpu_render_pass_set_vertex_buffer(self, slot, *buffer, offset, size) }
|
||||
}
|
||||
@@ -358,7 +358,7 @@ impl crate::Context for Context {
|
||||
bm::BindingResource::Buffer(bm::BufferBinding {
|
||||
buffer: buffer_slice.buffer.id,
|
||||
offset: buffer_slice.offset,
|
||||
size: buffer_slice.size_or_0(),
|
||||
size: buffer_slice.size,
|
||||
})
|
||||
}
|
||||
BindingResource::Sampler(ref sampler) => {
|
||||
@@ -590,10 +590,10 @@ impl crate::Context for Context {
|
||||
fn buffer_map_read(
|
||||
&self,
|
||||
buffer: &Self::BufferId,
|
||||
start: wgt::BufferAddress,
|
||||
size: wgt::BufferAddress,
|
||||
range: Range<wgt::BufferAddress>,
|
||||
) -> Self::MapReadFuture {
|
||||
let (future, completion) = native_gpu_future::new_gpu_future(*buffer, size);
|
||||
let (future, completion) =
|
||||
native_gpu_future::new_gpu_future(*buffer, range.end - range.start);
|
||||
|
||||
extern "C" fn buffer_map_read_future_wrapper(
|
||||
status: wgc::resource::BufferMapAsyncStatus,
|
||||
@@ -619,7 +619,7 @@ impl crate::Context for Context {
|
||||
callback: buffer_map_read_future_wrapper,
|
||||
userdata: completion.to_raw() as _,
|
||||
};
|
||||
gfx_select!(*buffer => self.buffer_map_async(*buffer, start .. start + size, operation));
|
||||
gfx_select!(*buffer => self.buffer_map_async(*buffer, range, operation));
|
||||
|
||||
future
|
||||
}
|
||||
@@ -627,10 +627,10 @@ impl crate::Context for Context {
|
||||
fn buffer_map_write(
|
||||
&self,
|
||||
buffer: &Self::BufferId,
|
||||
start: wgt::BufferAddress,
|
||||
size: wgt::BufferAddress,
|
||||
range: Range<wgt::BufferAddress>,
|
||||
) -> Self::MapWriteFuture {
|
||||
let (future, completion) = native_gpu_future::new_gpu_future(*buffer, size);
|
||||
let (future, completion) =
|
||||
native_gpu_future::new_gpu_future(*buffer, range.end - range.start);
|
||||
|
||||
extern "C" fn buffer_map_write_future_wrapper(
|
||||
status: wgc::resource::BufferMapAsyncStatus,
|
||||
@@ -656,7 +656,7 @@ impl crate::Context for Context {
|
||||
callback: buffer_map_write_future_wrapper,
|
||||
userdata: completion.to_raw() as _,
|
||||
};
|
||||
gfx_select!(*buffer => self.buffer_map_async(*buffer, start .. start + size, operation));
|
||||
gfx_select!(*buffer => self.buffer_map_async(*buffer, range, operation));
|
||||
|
||||
future
|
||||
}
|
||||
@@ -668,17 +668,11 @@ impl crate::Context for Context {
|
||||
fn swap_chain_get_next_texture(
|
||||
&self,
|
||||
swap_chain: &Self::SwapChainId,
|
||||
) -> Result<(Self::TextureViewId, Self::SwapChainOutputDetail), crate::TimeOut> {
|
||||
gfx_select!(*swap_chain => self.swap_chain_get_next_texture(*swap_chain, PhantomData))
|
||||
.map(|output| {
|
||||
(
|
||||
output.view_id.unwrap(),
|
||||
SwapChainOutputDetail {
|
||||
swap_chain_id: *swap_chain,
|
||||
},
|
||||
)
|
||||
})
|
||||
.map_err(|_| crate::TimeOut)
|
||||
) -> (Option<Self::TextureViewId>, SwapChainStatus, Self::SwapChainOutputDetail) {
|
||||
let wgc::swap_chain::SwapChainOutput { status, view_id } =
|
||||
gfx_select!(*swap_chain => self.swap_chain_get_next_texture(*swap_chain, PhantomData));
|
||||
|
||||
(view_id, status, SwapChainOutputDetail { swap_chain_id: *swap_chain })
|
||||
}
|
||||
|
||||
fn swap_chain_present(&self, view: &Self::TextureViewId, detail: &Self::SwapChainOutputDetail) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::{
|
||||
BindGroupDescriptor, BindGroupLayoutDescriptor, BindingResource, BindingType, BufferDescriptor,
|
||||
CommandEncoderDescriptor, ComputePipelineDescriptor, PipelineLayoutDescriptor,
|
||||
ProgrammableStageDescriptor, RenderPipelineDescriptor, SamplerDescriptor, TextureDescriptor,
|
||||
TextureViewDescriptor, TextureViewDimension,
|
||||
ProgrammableStageDescriptor, RenderPipelineDescriptor, SamplerDescriptor, SwapChainStatus,
|
||||
TextureDescriptor, TextureViewDescriptor, TextureViewDimension,
|
||||
};
|
||||
|
||||
use futures::FutureExt;
|
||||
@@ -107,20 +107,22 @@ impl crate::RenderPassInner<Context> for RenderPass {
|
||||
&mut self,
|
||||
buffer: &Sendable<web_sys::GpuBuffer>,
|
||||
offset: wgt::BufferAddress,
|
||||
size: wgt::BufferAddress,
|
||||
size: wgt::BufferSize,
|
||||
) {
|
||||
assert_ne!(size, wgt::BufferSize::WHOLE); //TODO
|
||||
self.0
|
||||
.set_index_buffer_with_f64_and_f64(&buffer.0, offset as f64, size as f64);
|
||||
.set_index_buffer_with_f64_and_f64(&buffer.0, offset as f64, size.0 as f64);
|
||||
}
|
||||
fn set_vertex_buffer(
|
||||
&mut self,
|
||||
slot: u32,
|
||||
buffer: &Sendable<web_sys::GpuBuffer>,
|
||||
offset: wgt::BufferAddress,
|
||||
size: wgt::BufferAddress,
|
||||
size: wgt::BufferSize,
|
||||
) {
|
||||
assert_ne!(size, wgt::BufferSize::WHOLE); //TODO
|
||||
self.0
|
||||
.set_vertex_buffer_with_f64_and_f64(slot, &buffer.0, offset as f64, size as f64);
|
||||
.set_vertex_buffer_with_f64_and_f64(slot, &buffer.0, offset as f64, size.0 as f64);
|
||||
}
|
||||
fn set_blend_color(&mut self, color: wgt::Color) {
|
||||
self.0
|
||||
@@ -830,7 +832,9 @@ impl crate::Context for Context {
|
||||
let mut mapped_buffer_binding =
|
||||
web_sys::GpuBufferBinding::new(&buffer_slice.buffer.id.0);
|
||||
mapped_buffer_binding.offset(buffer_slice.offset as f64);
|
||||
mapped_buffer_binding.size(buffer_slice.size_or_0() as f64);
|
||||
if buffer_slice.size != wgt::BufferSize::WHOLE {
|
||||
mapped_buffer_binding.size(buffer_slice.size.0 as f64);
|
||||
}
|
||||
JsValue::from(mapped_buffer_binding.clone())
|
||||
}
|
||||
BindingResource::Sampler(ref sampler) => JsValue::from(sampler.id.0.clone()),
|
||||
@@ -1046,8 +1050,7 @@ impl crate::Context for Context {
|
||||
fn buffer_map_read(
|
||||
&self,
|
||||
buffer: &Self::BufferId,
|
||||
_start: wgt::BufferAddress,
|
||||
_size: wgt::BufferAddress,
|
||||
_range: Range<wgt::BufferAddress>,
|
||||
) -> Self::MapReadFuture {
|
||||
MakeSendFuture(MapFuture {
|
||||
child: wasm_bindgen_futures::JsFuture::from(buffer.0.map_read_async()),
|
||||
@@ -1059,8 +1062,7 @@ impl crate::Context for Context {
|
||||
fn buffer_map_write(
|
||||
&self,
|
||||
buffer: &Self::BufferId,
|
||||
_start: wgt::BufferAddress,
|
||||
_size: wgt::BufferAddress,
|
||||
_range: Range<wgt::BufferAddress>,
|
||||
) -> Self::MapWriteFuture {
|
||||
MakeSendFuture(MapFuture {
|
||||
child: wasm_bindgen_futures::JsFuture::from(buffer.0.map_write_async()),
|
||||
@@ -1076,13 +1078,10 @@ impl crate::Context for Context {
|
||||
fn swap_chain_get_next_texture(
|
||||
&self,
|
||||
swap_chain: &Self::SwapChainId,
|
||||
) -> Result<(Self::TextureViewId, Self::SwapChainOutputDetail), crate::TimeOut> {
|
||||
) -> (Option<Self::TextureViewId>, SwapChainStatus, Self::SwapChainOutputDetail) {
|
||||
// TODO: Should we pass a descriptor here?
|
||||
// Or is the default view always correct?
|
||||
Ok((
|
||||
Sendable(swap_chain.0.get_current_texture().create_view()),
|
||||
(),
|
||||
))
|
||||
(Some(Sendable(swap_chain.0.get_current_texture().create_view())), SwapChainStatus::Good, ())
|
||||
}
|
||||
|
||||
fn swap_chain_present(
|
||||
|
||||
137
src/lib.rs
137
src/lib.rs
@@ -18,14 +18,14 @@ use std::{
|
||||
pub use wgc::instance::{AdapterInfo, DeviceType};
|
||||
pub use wgt::{
|
||||
read_spirv, AddressMode, Backend, BackendBit, BlendDescriptor, BlendFactor, BlendOperation,
|
||||
BufferAddress, BufferUsage, Color, ColorStateDescriptor, ColorWrite, CommandBufferDescriptor,
|
||||
CompareFunction, CullMode, DepthStencilStateDescriptor, DeviceDescriptor, DynamicOffset,
|
||||
Extensions, Extent3d, FilterMode, FrontFace, IndexFormat, InputStepMode, Limits, LoadOp,
|
||||
Origin3d, PowerPreference, PresentMode, PrimitiveTopology, RasterizationStateDescriptor,
|
||||
ShaderLocation, ShaderStage, StencilOperation, StencilStateFaceDescriptor, StoreOp,
|
||||
SwapChainDescriptor, TextureAspect, TextureComponentType, TextureDataLayout, TextureDimension,
|
||||
TextureFormat, TextureUsage, TextureViewDimension, VertexAttributeDescriptor, VertexFormat,
|
||||
BIND_BUFFER_ALIGNMENT, MAX_BIND_GROUPS,
|
||||
BufferAddress, BufferSize, BufferUsage, Color, ColorStateDescriptor, ColorWrite,
|
||||
CommandBufferDescriptor, CompareFunction, CullMode, DepthStencilStateDescriptor,
|
||||
DeviceDescriptor, DynamicOffset, Extensions, Extent3d, FilterMode, FrontFace, IndexFormat,
|
||||
InputStepMode, Limits, LoadOp, Origin3d, PowerPreference, PresentMode, PrimitiveTopology,
|
||||
RasterizationStateDescriptor, ShaderLocation, ShaderStage, StencilOperation,
|
||||
StencilStateFaceDescriptor, StoreOp, SwapChainDescriptor, SwapChainStatus, TextureAspect,
|
||||
TextureComponentType, TextureDataLayout, TextureDimension, TextureFormat, TextureUsage,
|
||||
TextureViewDimension, VertexAttributeDescriptor, VertexFormat, BIND_BUFFER_ALIGNMENT,
|
||||
};
|
||||
|
||||
use backend::Context as C;
|
||||
@@ -54,18 +54,13 @@ trait RenderPassInner<Ctx: Context> {
|
||||
bind_group: &Ctx::BindGroupId,
|
||||
offsets: &[DynamicOffset],
|
||||
);
|
||||
fn set_index_buffer(
|
||||
&mut self,
|
||||
buffer: &Ctx::BufferId,
|
||||
offset: BufferAddress,
|
||||
size: BufferAddress,
|
||||
);
|
||||
fn set_index_buffer(&mut self, buffer: &Ctx::BufferId, offset: BufferAddress, size: BufferSize);
|
||||
fn set_vertex_buffer(
|
||||
&mut self,
|
||||
slot: u32,
|
||||
buffer: &Ctx::BufferId,
|
||||
offset: BufferAddress,
|
||||
size: BufferAddress,
|
||||
size: BufferSize,
|
||||
);
|
||||
fn set_blend_color(&mut self, color: wgt::Color);
|
||||
fn set_scissor_rect(&mut self, x: u32, y: u32, width: u32, height: u32);
|
||||
@@ -207,20 +202,18 @@ trait Context: Sized {
|
||||
fn buffer_map_read(
|
||||
&self,
|
||||
buffer: &Self::BufferId,
|
||||
start: BufferAddress,
|
||||
size: BufferAddress,
|
||||
range: Range<BufferAddress>,
|
||||
) -> Self::MapReadFuture;
|
||||
fn buffer_map_write(
|
||||
&self,
|
||||
buffer: &Self::BufferId,
|
||||
start: BufferAddress,
|
||||
size: BufferAddress,
|
||||
range: Range<BufferAddress>,
|
||||
) -> Self::MapWriteFuture;
|
||||
fn buffer_unmap(&self, buffer: &Self::BufferId);
|
||||
fn swap_chain_get_next_texture(
|
||||
&self,
|
||||
swap_chain: &Self::SwapChainId,
|
||||
) -> Result<(Self::TextureViewId, Self::SwapChainOutputDetail), TimeOut>;
|
||||
) -> (Option<Self::TextureViewId>, SwapChainStatus, Self::SwapChainOutputDetail);
|
||||
fn swap_chain_present(&self, view: &Self::TextureViewId, detail: &Self::SwapChainOutputDetail);
|
||||
fn texture_create_view(
|
||||
&self,
|
||||
@@ -357,22 +350,14 @@ pub enum Maintain {
|
||||
pub struct Buffer {
|
||||
context: Arc<C>,
|
||||
id: <C as Context>::BufferId,
|
||||
//detail: <C as Context>::BufferDetail,
|
||||
size: BufferAddress,
|
||||
}
|
||||
|
||||
/// A description of what portion of a buffer to use
|
||||
pub struct BufferSlice<'a> {
|
||||
buffer: &'a Buffer,
|
||||
offset: BufferAddress,
|
||||
size: Option<BufferAddress>,
|
||||
}
|
||||
|
||||
impl<'a> BufferSlice<'a> {
|
||||
/// This fn can be used for calling lower-level APIs where `0` denotes that the slice should
|
||||
/// extend to the end of the buffer.
|
||||
fn size_or_0(&self) -> BufferAddress {
|
||||
self.size.unwrap_or(0)
|
||||
}
|
||||
size: BufferSize,
|
||||
}
|
||||
|
||||
/// A handle to a texture on the GPU.
|
||||
@@ -835,11 +820,26 @@ pub type TextureViewDescriptor<'a> = wgt::TextureViewDescriptor<Option<&'a str>>
|
||||
pub type SamplerDescriptor<'a> = wgt::SamplerDescriptor<Option<&'a str>>;
|
||||
|
||||
/// A swap chain image that can be rendered to.
|
||||
pub struct SwapChainOutput {
|
||||
pub struct SwapChainTexture {
|
||||
pub view: TextureView,
|
||||
detail: <C as Context>::SwapChainOutputDetail,
|
||||
}
|
||||
|
||||
/// The result of a successful call to `SwapChain::get_next_frame`.
|
||||
pub struct SwapChainFrame {
|
||||
pub output: SwapChainTexture,
|
||||
pub suboptimal: bool,
|
||||
}
|
||||
|
||||
/// The result of an unsuccessful call to `SwapChain::get_next_frame`.
|
||||
#[derive(Debug)]
|
||||
pub enum SwapChainError {
|
||||
Timeout,
|
||||
Outdated,
|
||||
Lost,
|
||||
OutOfMemory,
|
||||
}
|
||||
|
||||
/// A view of a buffer which can be used to copy to or from a texture.
|
||||
#[derive(Clone)]
|
||||
pub struct BufferCopyView<'a> {
|
||||
@@ -887,7 +887,7 @@ impl CreateBufferMapped<'_> {
|
||||
Buffer {
|
||||
context: self.context,
|
||||
id: self.id,
|
||||
//detail: self.detail,
|
||||
size: self.mapped_data.len() as BufferAddress,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1074,6 +1074,7 @@ impl Device {
|
||||
Buffer {
|
||||
context: Arc::clone(&self.context),
|
||||
id: Context::device_create_buffer(&*self.context, &self.id, desc),
|
||||
size: desc.size,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1197,9 +1198,9 @@ impl Buffer {
|
||||
Bound::Unbounded => 0,
|
||||
};
|
||||
let size = match bounds.end_bound() {
|
||||
Bound::Included(&bound) => Some(bound + 1 - offset),
|
||||
Bound::Excluded(&bound) => Some(bound - offset),
|
||||
Bound::Unbounded => None,
|
||||
Bound::Included(&bound) => BufferSize(bound + 1 - offset),
|
||||
Bound::Excluded(&bound) => BufferSize(bound - offset),
|
||||
Bound::Unbounded => BufferSize::WHOLE,
|
||||
};
|
||||
BufferSlice {
|
||||
buffer: self,
|
||||
@@ -1219,11 +1220,16 @@ impl Buffer {
|
||||
pub fn map_read(
|
||||
&self,
|
||||
start: BufferAddress,
|
||||
size: BufferAddress,
|
||||
size: BufferSize,
|
||||
) -> impl Future<Output = Result<BufferReadMapping, BufferAsyncError>> + Send {
|
||||
let context = Arc::clone(&self.context);
|
||||
let end = if size == BufferSize::WHOLE {
|
||||
self.size
|
||||
} else {
|
||||
start + size.0
|
||||
};
|
||||
self.context
|
||||
.buffer_map_read(&self.id, start, size)
|
||||
.buffer_map_read(&self.id, start..end)
|
||||
.map(|result| result.map(|detail| BufferReadMapping { context, detail }))
|
||||
}
|
||||
|
||||
@@ -1234,11 +1240,16 @@ impl Buffer {
|
||||
pub fn map_write(
|
||||
&self,
|
||||
start: BufferAddress,
|
||||
size: BufferAddress,
|
||||
size: BufferSize,
|
||||
) -> impl Future<Output = Result<BufferWriteMapping, BufferAsyncError>> + Send {
|
||||
let context = Arc::clone(&self.context);
|
||||
let end = if size == BufferSize::WHOLE {
|
||||
self.size
|
||||
} else {
|
||||
start + size.0
|
||||
};
|
||||
self.context
|
||||
.buffer_map_write(&self.id, start, size)
|
||||
.buffer_map_write(&self.id, start..end)
|
||||
.map(|result| result.map(|detail| BufferWriteMapping { context, detail }))
|
||||
}
|
||||
|
||||
@@ -1422,7 +1433,7 @@ impl<'a> RenderPass<'a> {
|
||||
&mut self.id,
|
||||
&buffer_slice.buffer.id,
|
||||
buffer_slice.offset,
|
||||
buffer_slice.size_or_0(),
|
||||
buffer_slice.size,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1444,7 +1455,7 @@ impl<'a> RenderPass<'a> {
|
||||
slot,
|
||||
&buffer_slice.buffer.id,
|
||||
buffer_slice.offset,
|
||||
buffer_slice.size_or_0(),
|
||||
buffer_slice.size,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1613,7 +1624,7 @@ impl Queue {
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for SwapChainOutput {
|
||||
impl Drop for SwapChainTexture {
|
||||
fn drop(&mut self) {
|
||||
if !thread::panicking() {
|
||||
Context::swap_chain_present(&*self.view.context, &self.view.id, &self.detail);
|
||||
@@ -1621,26 +1632,36 @@ impl Drop for SwapChainOutput {
|
||||
}
|
||||
}
|
||||
|
||||
/// The GPU timed out when attempting to acquire the next texture or if a
|
||||
/// previous output is still alive.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TimeOut;
|
||||
|
||||
impl SwapChain {
|
||||
/// Returns the next texture to be presented by the swapchain for drawing.
|
||||
///
|
||||
/// When the [`SwapChainOutput`] returned by this method is dropped, the swapchain will present
|
||||
/// the texture to the associated [`Surface`].
|
||||
pub fn get_next_texture(&mut self) -> Result<SwapChainOutput, TimeOut> {
|
||||
Context::swap_chain_get_next_texture(&*self.context, &self.id).map(|(id, detail)| {
|
||||
SwapChainOutput {
|
||||
view: TextureView {
|
||||
context: Arc::clone(&self.context),
|
||||
id,
|
||||
owned: false,
|
||||
},
|
||||
detail,
|
||||
}
|
||||
})
|
||||
pub fn get_next_frame(&mut self) -> Result<SwapChainFrame, SwapChainError> {
|
||||
let (view_id, status, detail) =
|
||||
Context::swap_chain_get_next_texture(&*self.context, &self.id);
|
||||
let output = view_id.map(|id| SwapChainTexture {
|
||||
view: TextureView {
|
||||
context: Arc::clone(&self.context),
|
||||
id: id,
|
||||
owned: false,
|
||||
},
|
||||
detail,
|
||||
});
|
||||
|
||||
match status {
|
||||
SwapChainStatus::Good => Ok(SwapChainFrame {
|
||||
output: output.unwrap(),
|
||||
suboptimal: false,
|
||||
}),
|
||||
SwapChainStatus::Suboptimal => Ok(SwapChainFrame {
|
||||
output: output.unwrap(),
|
||||
suboptimal: true,
|
||||
}),
|
||||
SwapChainStatus::Timeout => Err(SwapChainError::Timeout),
|
||||
SwapChainStatus::Outdated => Err(SwapChainError::Outdated),
|
||||
SwapChainStatus::Lost => Err(SwapChainError::Lost),
|
||||
SwapChainStatus::OutOfMemory => Err(SwapChainError::OutOfMemory),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user