122: Wholesome update for the git master of wgpu-native r=grovesNL a=kvark

Depends on https://github.com/gfx-rs/wgpu/pull/382

Co-authored-by: Dzmitry Malyshau <dmalyshau@mozilla.com>
This commit is contained in:
bors[bot] 2019-11-20 01:59:27 +00:00 committed by GitHub
commit fcc162a7aa
7 changed files with 181 additions and 142 deletions

View File

@ -20,12 +20,19 @@ license = "MPL-2.0"
[features]
default = []
# Make Vulkan backend available on platforms where it is by default not, e.g. macOS
vulkan = ["wgn/gfx-backend-vulkan"]
vulkan = ["wgn/vulkan-portability"]
[dependencies.wgn]
package = "wgpu-native"
version = "0.4"
features = ["local"]
git = "https://github.com/gfx-rs/wgpu"
rev = "73b33ea76e2f91b3114aa7640b1d60518d39f915"
[dependencies.core]
package = "wgpu-core"
version = "0.1"
git = "https://github.com/gfx-rs/wgpu"
rev = "73b33ea76e2f91b3114aa7640b1d60518d39f915"
[dependencies]
arrayvec = "0.5"

View File

@ -7,10 +7,12 @@ use std::mem::size_of;
fn main() {
env_logger::init();
let adapter = wgpu::Adapter::request(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
backends: wgpu::BackendBit::PRIMARY,
}).unwrap();
let adapter = wgpu::Adapter::request(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
},
wgpu::BackendBit::PRIMARY,
).unwrap();
let (device, mut queue) = adapter.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {

View File

@ -2,10 +2,12 @@
fn main() {
env_logger::init();
let adapter = wgpu::Adapter::request(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
backends: wgpu::BackendBit::PRIMARY,
}).unwrap();
let adapter = wgpu::Adapter::request(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
},
wgpu::BackendBit::PRIMARY,
).unwrap();
println!("{:?}", adapter.get_info())
}

View File

@ -94,11 +94,12 @@ pub fn run<E: Example>(title: &str) {
(window, instance, hidpi_factor, size, surface)
};
let adapter = wgpu::Adapter::request(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
backends: wgpu::BackendBit::PRIMARY,
})
.unwrap();
let adapter = wgpu::Adapter::request(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
},
wgpu::BackendBit::PRIMARY,
).unwrap();
let (device, mut queue) = adapter.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {

View File

@ -14,10 +14,12 @@ fn main() {
let size = (numbers.len() * std::mem::size_of::<u32>()) as wgpu::BufferAddress;
let adapter = wgpu::Adapter::request(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
backends: wgpu::BackendBit::PRIMARY,
}).unwrap();
let adapter = wgpu::Adapter::request(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
},
wgpu::BackendBit::PRIMARY,
).unwrap();
let (device, mut queue) = adapter.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {

View File

@ -38,10 +38,12 @@ fn main() {
(window, instance, size, surface)
};
let adapter = wgpu::Adapter::request(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
backends: wgpu::BackendBit::PRIMARY,
}).unwrap();
let adapter = wgpu::Adapter::request(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
},
wgpu::BackendBit::PRIMARY,
).unwrap();
let (device, mut queue) = adapter.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {

View File

@ -10,63 +10,73 @@ use std::ptr;
use std::slice;
use std::thread;
pub use wgn::{
AdapterInfo,
AddressMode,
BackendBit,
BlendDescriptor,
BlendFactor,
BlendOperation,
pub use core::{
binding_model::{
ShaderStage,
},
command::{
CommandEncoderDescriptor,
CommandBufferDescriptor,
LoadOp,
RenderPassDepthStencilAttachmentDescriptor,
StoreOp,
},
instance::{
AdapterInfo,
BackendBit,
DeviceDescriptor,
Extensions,
Limits,
PowerPreference,
RequestAdapterOptions,
},
pipeline::{
BlendDescriptor,
BlendFactor,
BlendOperation,
ColorStateDescriptor,
ColorWrite,
CullMode,
DepthStencilStateDescriptor,
FrontFace,
IndexFormat,
InputStepMode,
PrimitiveTopology,
RasterizationStateDescriptor,
ShaderLocation,
ShaderModuleDescriptor,
StencilOperation,
StencilStateFaceDescriptor,
VertexAttributeDescriptor,
VertexFormat,
},
resource::{
AddressMode,
BufferDescriptor,
BufferMapAsyncStatus,
BufferUsage,
CompareFunction,
FilterMode,
SamplerDescriptor,
TextureAspect,
TextureDescriptor,
TextureDimension,
TextureFormat,
TextureUsage,
TextureViewDescriptor,
TextureViewDimension,
},
swap_chain::{
PresentMode,
SwapChainDescriptor,
},
BufferAddress,
BufferDescriptor,
BufferMapAsyncStatus,
BufferUsage,
Color,
ColorStateDescriptor,
ColorWrite,
CommandEncoderDescriptor,
CommandBufferDescriptor,
CompareFunction,
CullMode,
DepthStencilStateDescriptor,
DeviceDescriptor,
Extensions,
Extent3d,
FilterMode,
FrontFace,
IndexFormat,
InputStepMode,
Limits,
LoadOp,
Origin3d,
PowerPreference,
PresentMode,
PrimitiveTopology,
RasterizationStateDescriptor,
RenderPassDepthStencilAttachmentDescriptor,
RequestAdapterOptions,
SamplerDescriptor,
ShaderLocation,
ShaderModuleDescriptor,
ShaderStage,
StencilOperation,
StencilStateFaceDescriptor,
StoreOp,
SwapChainDescriptor,
TextureAspect,
TextureDescriptor,
TextureDimension,
TextureFormat,
TextureUsage,
TextureViewDescriptor,
TextureViewDimension,
VertexAttributeDescriptor,
VertexFormat,
read_spirv,
};
#[cfg(feature = "gl")]
pub use wgn::glutin;
//TODO: avoid heap allocating vectors during resource creation.
#[derive(Default)]
@ -82,7 +92,7 @@ struct Temp {
/// yielding a [`Device`] object.
#[derive(Debug)]
pub struct Adapter {
id: wgn::AdapterId,
id: core::id::AdapterId,
}
/// An open connection to a graphics and/or compute device.
@ -91,20 +101,20 @@ pub struct Adapter {
/// well as exposing [`Queue`] objects.
#[derive(Debug)]
pub struct Device {
id: wgn::DeviceId,
id: core::id::DeviceId,
temp: Temp,
}
/// A handle to a GPU-accessible buffer.
#[derive(Debug)]
pub struct Buffer {
id: wgn::BufferId,
id: core::id::BufferId,
}
/// A handle to a texture on the GPU.
#[derive(Debug)]
pub struct Texture {
id: wgn::TextureId,
id: core::id::TextureId,
owned: bool,
}
@ -114,7 +124,7 @@ pub struct Texture {
/// [`RenderPipeline`] or [`BindGroup`].
#[derive(Debug)]
pub struct TextureView {
id: wgn::TextureViewId,
id: core::id::TextureViewId,
owned: bool,
}
@ -125,7 +135,7 @@ pub struct TextureView {
/// the documentation for [`SamplerDescriptor`] for more information.
#[derive(Debug)]
pub struct Sampler {
id: wgn::SamplerId,
id: core::id::SamplerId,
}
/// A handle to a presentable surface.
@ -134,7 +144,7 @@ pub struct Sampler {
/// be presented. A `Surface` may be created with [`Surface::create`].
#[derive(Debug)]
pub struct Surface {
id: wgn::SurfaceId,
id: core::id::SurfaceId,
}
/// A handle to a swap chain.
@ -143,7 +153,7 @@ pub struct Surface {
/// A `SwapChain` may be created with [`Device::create_swap_chain`].
#[derive(Debug)]
pub struct SwapChain {
id: wgn::SwapChainId,
id: core::id::SwapChainId,
}
/// An opaque handle to a binding group layout.
@ -154,7 +164,7 @@ pub struct SwapChain {
/// create a [`PipelineLayoutDescriptor`], which can be used to create a [`PipelineLayout`].
#[derive(Debug)]
pub struct BindGroupLayout {
id: wgn::BindGroupLayoutId,
id: core::id::BindGroupLayoutId,
}
/// An opaque handle to a binding group.
@ -165,7 +175,7 @@ pub struct BindGroupLayout {
/// [`ComputePass`] with [`ComputePass::set_bind_group`].
#[derive(Debug)]
pub struct BindGroup {
id: wgn::BindGroupId,
id: core::id::BindGroupId,
}
impl Drop for BindGroup {
@ -181,7 +191,7 @@ impl Drop for BindGroup {
/// programmable stages of a pipeline.
#[derive(Debug)]
pub struct ShaderModule {
id: wgn::ShaderModuleId,
id: core::id::ShaderModuleId,
}
/// An opaque handle to a pipeline layout.
@ -189,7 +199,7 @@ pub struct ShaderModule {
/// A `PipelineLayout` object describes the available binding groups of a pipeline.
#[derive(Debug)]
pub struct PipelineLayout {
id: wgn::PipelineLayoutId,
id: core::id::PipelineLayoutId,
}
/// A handle to a rendering (graphics) pipeline.
@ -198,13 +208,13 @@ pub struct PipelineLayout {
/// buffers and targets. A `RenderPipeline` may be created with [`Device::create_render_pipeline`].
#[derive(Debug)]
pub struct RenderPipeline {
id: wgn::RenderPipelineId,
id: core::id::RenderPipelineId,
}
/// A handle to a compute pipeline.
#[derive(Debug)]
pub struct ComputePipeline {
id: wgn::ComputePipelineId,
id: core::id::ComputePipelineId,
}
/// An opaque handle to a command buffer on the GPU.
@ -214,7 +224,7 @@ pub struct ComputePipeline {
/// a [`CommandEncoder`] and then calling [`CommandEncoder::finish`].
#[derive(Debug)]
pub struct CommandBuffer {
id: wgn::CommandBufferId,
id: core::id::CommandBufferId,
}
/// An object that encodes GPU operations.
@ -226,20 +236,20 @@ pub struct CommandBuffer {
/// be submitted for execution.
#[derive(Debug)]
pub struct CommandEncoder {
id: wgn::CommandEncoderId,
id: core::id::CommandEncoderId,
}
/// An in-progress recording of a render pass.
#[derive(Debug)]
pub struct RenderPass<'a> {
id: wgn::RenderPassId,
id: core::id::RenderPassId,
_parent: &'a mut CommandEncoder,
}
/// An in-progress recording of a compute pass.
#[derive(Debug)]
pub struct ComputePass<'a> {
id: wgn::ComputePassId,
id: core::id::ComputePassId,
_parent: &'a mut CommandEncoder,
}
@ -248,8 +258,8 @@ pub struct ComputePass<'a> {
/// A `Queue` executes recorded [`CommandBuffer`] objects.
#[derive(Debug)]
pub struct Queue {
id: wgn::QueueId,
temp_command_buffers: Vec<wgn::CommandBufferId>,
id: core::id::QueueId,
temp_command_buffers: Vec<core::id::CommandBufferId>,
}
/// A resource that can be bound to a pipeline.
@ -432,7 +442,7 @@ pub struct RenderPassColorAttachmentDescriptor<'a> {
#[derive(Debug)]
pub struct SwapChainOutput<'a> {
pub view: TextureView,
swap_chain_id: &'a wgn::SwapChainId,
swap_chain_id: &'a core::id::SwapChainId,
}
/// A view of a buffer which can be used to copy to or from a texture.
@ -452,8 +462,8 @@ pub struct BufferCopyView<'a> {
}
impl<'a> BufferCopyView<'a> {
fn into_native(self) -> wgn::BufferCopyView {
wgn::BufferCopyView {
fn into_native(self) -> core::command::BufferCopyView {
core::command::BufferCopyView {
buffer: self.buffer.id,
offset: self.offset,
row_pitch: self.row_pitch,
@ -479,8 +489,8 @@ pub struct TextureCopyView<'a> {
}
impl<'a> TextureCopyView<'a> {
fn into_native(self) -> wgn::TextureCopyView {
wgn::TextureCopyView {
fn into_native(self) -> core::command::TextureCopyView {
core::command::TextureCopyView {
texture: self.texture.id,
mip_level: self.mip_level,
array_layer: self.array_layer,
@ -491,7 +501,7 @@ impl<'a> TextureCopyView<'a> {
/// A buffer being created, mapped in host memory.
pub struct CreateBufferMapped<'a, T> {
id: wgn::BufferId,
id: core::id::BufferId,
pub data: &'a mut [T],
}
@ -540,9 +550,15 @@ impl Adapter {
/// Some options are "soft", so treated as non-mandatory. Others are "hard".
///
/// If no adapters are found that suffice all the "hard" options, `None` is returned.
pub fn request(options: &wgn::RequestAdapterOptions) -> Option<Self> {
pub fn request(options: &RequestAdapterOptions, backends: BackendBit) -> Option<Self> {
unsafe extern "C" fn adapter_callback(id: core::id::AdapterId, user_data: *mut std::ffi::c_void) {
*(user_data as *mut core::id::AdapterId) = id;
}
let mut id = core::id::AdapterId::ERROR;
wgn::wgpu_request_adapter_async(Some(options), backends, adapter_callback, &mut id as *mut _ as *mut std::ffi::c_void);
Some(Adapter {
id: wgn::wgpu_request_adapter(Some(options)),
id,
})
}
@ -577,8 +593,8 @@ impl Device {
/// Creates a shader module from SPIR-V source code.
pub fn create_shader_module(&self, spv: &[u32]) -> ShaderModule {
let desc = wgn::ShaderModuleDescriptor {
code: wgn::U32Array {
let desc = core::pipeline::ShaderModuleDescriptor {
code: core::U32Array {
bytes: spv.as_ptr(),
length: spv.len(),
},
@ -597,33 +613,36 @@ impl Device {
/// Creates a new bind group.
pub fn create_bind_group(&self, desc: &BindGroupDescriptor) -> BindGroup {
use core::binding_model as bm;
let bindings = desc
.bindings
.into_iter()
.map(|binding| wgn::BindGroupBinding {
.map(|binding| bm::BindGroupBinding {
binding: binding.binding,
resource: match binding.resource {
BindingResource::Buffer {
ref buffer,
ref range,
} => wgn::BindingResource::Buffer(wgn::BufferBinding {
} => bm::BindingResource::Buffer(bm::BufferBinding {
buffer: buffer.id,
offset: range.start,
size: range.end - range.start,
}),
BindingResource::Sampler(ref sampler) => {
wgn::BindingResource::Sampler(sampler.id)
bm::BindingResource::Sampler(sampler.id)
}
BindingResource::TextureView(ref texture_view) => {
wgn::BindingResource::TextureView(texture_view.id)
bm::BindingResource::TextureView(texture_view.id)
}
},
})
.collect::<Vec<_>>();
BindGroup {
id: wgn::wgpu_device_create_bind_group(
self.id,
&wgn::BindGroupDescriptor {
&bm::BindGroupDescriptor {
layout: desc.layout.id,
bindings: bindings.as_ptr(),
bindings_length: bindings.len(),
@ -634,18 +653,20 @@ impl Device {
/// Creates a bind group layout.
pub fn create_bind_group_layout(&self, desc: &BindGroupLayoutDescriptor) -> BindGroupLayout {
use core::binding_model as bm;
let temp_layouts = desc.bindings
.iter()
.map(|bind| wgn::BindGroupLayoutBinding {
.map(|bind| bm::BindGroupLayoutBinding {
binding: bind.binding,
visibility: bind.visibility,
ty: match bind.ty {
BindingType::UniformBuffer { .. } => wgn::BindingType::UniformBuffer,
BindingType::StorageBuffer { readonly: false, .. } => wgn::BindingType::StorageBuffer,
BindingType::StorageBuffer { readonly: true, .. } => wgn::BindingType::ReadonlyStorageBuffer,
BindingType::Sampler => wgn::BindingType::Sampler,
BindingType::SampledTexture { .. } => wgn::BindingType::SampledTexture,
BindingType::StorageTexture { .. } => wgn::BindingType::StorageTexture,
BindingType::UniformBuffer { .. } => bm::BindingType::UniformBuffer,
BindingType::StorageBuffer { readonly: false, .. } => bm::BindingType::StorageBuffer,
BindingType::StorageBuffer { readonly: true, .. } => bm::BindingType::ReadonlyStorageBuffer,
BindingType::Sampler => bm::BindingType::Sampler,
BindingType::SampledTexture { .. } => bm::BindingType::SampledTexture,
BindingType::StorageTexture { .. } => bm::BindingType::StorageTexture,
},
dynamic: match bind.ty {
BindingType::UniformBuffer { dynamic } |
@ -666,7 +687,7 @@ impl Device {
BindGroupLayout {
id: wgn::wgpu_device_create_bind_group_layout(
self.id,
&wgn::BindGroupLayoutDescriptor {
&bm::BindGroupLayoutDescriptor {
bindings: temp_layouts.as_ptr(),
bindings_length: temp_layouts.len(),
},
@ -685,7 +706,7 @@ impl Device {
PipelineLayout {
id: wgn::wgpu_device_create_pipeline_layout(
self.id,
&wgn::PipelineLayoutDescriptor {
&core::binding_model::PipelineLayoutDescriptor {
bind_group_layouts: temp_layouts.as_ptr(),
bind_group_layouts_length: temp_layouts.len(),
},
@ -695,15 +716,17 @@ impl Device {
/// Creates a render pipeline.
pub fn create_render_pipeline(&self, desc: &RenderPipelineDescriptor) -> RenderPipeline {
use core::pipeline as pipe;
let vertex_entry_point = CString::new(desc.vertex_stage.entry_point).unwrap();
let vertex_stage = wgn::ProgrammableStageDescriptor {
let vertex_stage = pipe::ProgrammableStageDescriptor {
module: desc.vertex_stage.module.id,
entry_point: vertex_entry_point.as_ptr(),
};
let (_fragment_entry_point, fragment_stage) =
if let Some(fragment_stage) = &desc.fragment_stage {
let fragment_entry_point = CString::new(fragment_stage.entry_point).unwrap();
let fragment_stage = wgn::ProgrammableStageDescriptor {
let fragment_stage = pipe::ProgrammableStageDescriptor {
module: fragment_stage.module.id,
entry_point: fragment_entry_point.as_ptr(),
};
@ -716,7 +739,7 @@ impl Device {
let temp_vertex_buffers = desc
.vertex_buffers
.iter()
.map(|vbuf| wgn::VertexBufferDescriptor {
.map(|vbuf| pipe::VertexBufferDescriptor {
stride: vbuf.stride,
step_mode: vbuf.step_mode,
attributes: vbuf.attributes.as_ptr(),
@ -727,7 +750,7 @@ impl Device {
RenderPipeline {
id: wgn::wgpu_device_create_render_pipeline(
self.id,
&wgn::RenderPipelineDescriptor {
&pipe::RenderPipelineDescriptor {
layout: desc.layout.id,
vertex_stage,
fragment_stage: fragment_stage
@ -743,7 +766,7 @@ impl Device {
.depth_stencil_state
.as_ref()
.map_or(ptr::null(), |p| p as *const _),
vertex_input: wgn::VertexInputDescriptor {
vertex_input: pipe::VertexInputDescriptor {
index_format: desc.index_format,
vertex_buffers: temp_vertex_buffers.as_ptr(),
vertex_buffers_length: temp_vertex_buffers.len(),
@ -758,14 +781,16 @@ impl Device {
/// Creates a compute pipeline.
pub fn create_compute_pipeline(&self, desc: &ComputePipelineDescriptor) -> ComputePipeline {
use core::pipeline as pipe;
let entry_point = CString::new(desc.compute_stage.entry_point).unwrap();
ComputePipeline {
id: wgn::wgpu_device_create_compute_pipeline(
self.id,
&wgn::ComputePipelineDescriptor {
&pipe::ComputePipelineDescriptor {
layout: desc.layout.id,
compute_stage: wgn::ProgrammableStageDescriptor {
compute_stage: pipe::ProgrammableStageDescriptor {
module: desc.compute_stage.module.id,
entry_point: entry_point.as_ptr(),
},
@ -847,7 +872,7 @@ impl Drop for Device {
pub struct BufferAsyncMapping<T> {
pub data: T,
buffer_id: wgn::BufferId,
buffer_id: core::id::BufferId,
}
//TODO: proper error type
pub type BufferMapAsyncResult<T> = Result<BufferAsyncMapping<T>, ()>;
@ -865,7 +890,7 @@ where
{
size: BufferAddress,
callback: F,
buffer_id: wgn::BufferId,
buffer_id: core::id::BufferId,
phantom: std::marker::PhantomData<T>,
}
@ -876,7 +901,7 @@ where
{
size: BufferAddress,
callback: F,
buffer_id: wgn::BufferId,
buffer_id: core::id::BufferId,
phantom: std::marker::PhantomData<T>,
}
@ -887,7 +912,7 @@ impl Buffer {
F: FnOnce(BufferMapAsyncResult<&[T]>) + 'static,
{
extern "C" fn buffer_map_read_callback_wrapper<T, F>(
status: wgn::BufferMapAsyncStatus,
status: BufferMapAsyncStatus,
data: *const u8,
user_data: *mut u8,
) where
@ -902,13 +927,12 @@ impl Buffer {
let data = LayoutVerified::new_slice(data)
.expect("could not interpret bytes as &[T]")
.into_slice();
if let wgn::BufferMapAsyncStatus::Success = status {
(user_data.callback)(Ok(BufferAsyncMapping {
match status {
BufferMapAsyncStatus::Success => (user_data.callback)(Ok(BufferAsyncMapping {
data,
buffer_id: user_data.buffer_id,
}));
} else {
(user_data.callback)(Err(()))
})),
_ => (user_data.callback)(Err(())),
}
}
@ -933,7 +957,7 @@ impl Buffer {
F: FnOnce(BufferMapAsyncResult<&mut [T]>) + 'static,
{
extern "C" fn buffer_map_write_callback_wrapper<T, F>(
status: wgn::BufferMapAsyncStatus,
status: BufferMapAsyncStatus,
data: *mut u8,
user_data: *mut u8,
) where
@ -948,13 +972,12 @@ impl Buffer {
let data = LayoutVerified::new_slice(data)
.expect("could not interpret bytes as &mut [T]")
.into_mut_slice();
if let wgn::BufferMapAsyncStatus::Success = status {
(user_data.callback)(Ok(BufferAsyncMapping {
match status {
BufferMapAsyncStatus::Success => (user_data.callback)(Ok(BufferAsyncMapping {
data,
buffer_id: user_data.buffer_id,
}));
} else {
(user_data.callback)(Err(()))
})),
_ => (user_data.callback)(Err(())),
}
}
@ -1034,7 +1057,7 @@ impl CommandEncoder {
let colors = desc
.color_attachments
.iter()
.map(|ca| wgn::RenderPassColorAttachmentDescriptor {
.map(|ca| core::command::RenderPassColorAttachmentDescriptor {
attachment: ca.attachment.id,
resolve_target: ca.resolve_target.map_or(ptr::null(), |v| &v.id as *const _),
load_op: ca.load_op,
@ -1058,7 +1081,7 @@ impl CommandEncoder {
RenderPass {
id: wgn::wgpu_command_encoder_begin_render_pass(
self.id,
&wgn::RenderPassDescriptor {
&core::command::RenderPassDescriptor {
color_attachments: colors.as_ptr(),
color_attachments_length: colors.len(),
depth_stencil_attachment: depth_stencil
@ -1355,7 +1378,7 @@ impl SwapChain {
/// Returns an `Err` if the GPU timed out when attempting to acquire the next texture.
pub fn get_next_texture(&mut self) -> Result<SwapChainOutput, ()> {
let output = wgn::wgpu_swap_chain_get_next_texture(self.id);
if output.view_id == wgn::Id::ERROR {
if output.view_id == core::id::Id::ERROR {
Err(())
} else {
Ok(SwapChainOutput {