mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-10-30 05:51:42 +00:00
Texture format MSAA capabilities
This commit is contained in:
parent
01f62baad2
commit
dbec075cdc
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -995,8 +995,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "metal"
|
||||
version = "0.23.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0514f491f4cc03632ab399ee01e2c1c1b12d3e1cf2d667c1ff5f87d6dcd2084"
|
||||
source = "git+https://github.com/gfx-rs/metal-rs?rev=140c8f4#140c8f4e39001ae154f153ffc767da6c0c9d7f06"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"block",
|
||||
|
@ -94,6 +94,8 @@ impl RenderBundleEncoder {
|
||||
parent_id: id::DeviceId,
|
||||
base: Option<BasePass<RenderCommand>>,
|
||||
) -> Result<Self, CreateRenderBundleError> {
|
||||
//TODO: validate that attachment formats are renderable,
|
||||
// have expected aspects, support multisampling.
|
||||
Ok(Self {
|
||||
base: base.unwrap_or_else(|| BasePass::new(&desc.label)),
|
||||
parent_id,
|
||||
|
@ -409,6 +409,8 @@ pub enum RenderPassErrorInner {
|
||||
InvalidColorAttachmentFormat(wgt::TextureFormat),
|
||||
#[error("attachment format {0:?} is not a depth-stencil format")]
|
||||
InvalidDepthStencilAttachmentFormat(wgt::TextureFormat),
|
||||
#[error("attachment format {0:?} can not be resolved")]
|
||||
UnsupportedResolveTargetFormat(wgt::TextureFormat),
|
||||
#[error("necessary attachments are missing")]
|
||||
MissingAttachments,
|
||||
#[error("attachments have differing sizes: {previous:?} is followed by {mismatch:?}")]
|
||||
@ -418,10 +420,15 @@ pub enum RenderPassErrorInner {
|
||||
},
|
||||
#[error("attachment's sample count {0} is invalid")]
|
||||
InvalidSampleCount(u32),
|
||||
#[error("attachment with resolve target must be multi-sampled")]
|
||||
InvalidResolveSourceSampleCount,
|
||||
#[error("resolve target must have a sample count of 1")]
|
||||
InvalidResolveTargetSampleCount,
|
||||
#[error("resolve source must be multi-sampled (has {src} samples) while the resolve destination must not be multisampled (has {dst} samples)")]
|
||||
InvalidResolveSampleCounts { src: u32, dst: u32 },
|
||||
#[error(
|
||||
"resource source format ({src:?}) must match the resolve destination format ({dst:?})"
|
||||
)]
|
||||
MismatchedResolveTextureFormat {
|
||||
src: wgt::TextureFormat,
|
||||
dst: wgt::TextureFormat,
|
||||
},
|
||||
#[error("surface texture is dropped before the render pass is finished")]
|
||||
SurfaceTextureDropped,
|
||||
#[error("not enough memory left")]
|
||||
@ -438,7 +445,8 @@ pub enum RenderPassErrorInner {
|
||||
MissingFeatures(#[from] MissingFeatures),
|
||||
#[error(transparent)]
|
||||
MissingDownlevelFlags(#[from] MissingDownlevelFlags),
|
||||
#[error("indirect draw uses bytes {offset}..{end_offset} {} which overruns indirect buffer of size {buffer_size}", count.map_or_else(String::new, |v| format!("(using count {})", v)))]
|
||||
#[error("indirect draw uses bytes {offset}..{end_offset} {} which overruns indirect buffer of size {buffer_size}",
|
||||
count.map_or_else(String::new, |v| format!("(using count {})", v)))]
|
||||
IndirectBufferOverrun {
|
||||
count: Option<NonZeroU32>,
|
||||
offset: u64,
|
||||
@ -823,6 +831,7 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
.views
|
||||
.use_extend(&*view_guard, resolve_target, (), ())
|
||||
.map_err(|_| RenderPassErrorInner::InvalidAttachment(resolve_target))?;
|
||||
|
||||
check_multiview(resolve_view)?;
|
||||
if color_view.extent != resolve_view.extent {
|
||||
return Err(RenderPassErrorInner::AttachmentsDimensionMismatch {
|
||||
@ -830,11 +839,26 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
mismatch: ("resolve", resolve_view.extent),
|
||||
});
|
||||
}
|
||||
if color_view.samples == 1 {
|
||||
return Err(RenderPassErrorInner::InvalidResolveSourceSampleCount);
|
||||
if color_view.samples == 1 || resolve_view.samples != 1 {
|
||||
return Err(RenderPassErrorInner::InvalidResolveSampleCounts {
|
||||
src: color_view.samples,
|
||||
dst: resolve_view.samples,
|
||||
});
|
||||
}
|
||||
if resolve_view.samples != 1 {
|
||||
return Err(RenderPassErrorInner::InvalidResolveTargetSampleCount);
|
||||
if color_view.desc.format != resolve_view.desc.format {
|
||||
return Err(RenderPassErrorInner::MismatchedResolveTextureFormat {
|
||||
src: color_view.desc.format,
|
||||
dst: resolve_view.desc.format,
|
||||
});
|
||||
}
|
||||
if !resolve_view
|
||||
.format_features
|
||||
.flags
|
||||
.contains(wgt::TextureFormatFeatureFlags::MULTISAMPLE_RESOLVE)
|
||||
{
|
||||
return Err(RenderPassErrorInner::UnsupportedResolveTargetFormat(
|
||||
resolve_view.desc.format,
|
||||
));
|
||||
}
|
||||
|
||||
cmd_buf.texture_memory_actions.register_implicit_init(
|
||||
|
@ -1890,19 +1890,19 @@ impl<A: HalApi> Device<A> {
|
||||
view_samples: view.samples,
|
||||
});
|
||||
}
|
||||
match (sample_type, format_info.sample_type, view.format_features.filterable) {
|
||||
(Tst::Uint, Tst::Uint, ..) |
|
||||
(Tst::Sint, Tst::Sint, ..) |
|
||||
(Tst::Depth, Tst::Depth, ..) |
|
||||
match (sample_type, format_info.sample_type) {
|
||||
(Tst::Uint, Tst::Uint) |
|
||||
(Tst::Sint, Tst::Sint) |
|
||||
(Tst::Depth, Tst::Depth) |
|
||||
// if we expect non-filterable, accept anything float
|
||||
(Tst::Float { filterable: false }, Tst::Float { .. }, ..) |
|
||||
(Tst::Float { filterable: false }, Tst::Float { .. }) |
|
||||
// if we expect filterable, require it
|
||||
(Tst::Float { filterable: true }, Tst::Float { filterable: true }, ..) |
|
||||
// if we expect filterable, also accept Float that is defined as unfilterable if filterable feature is explicitly enabled
|
||||
// (only hit if wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES is enabled)
|
||||
(Tst::Float { filterable: true }, Tst::Float { .. }, true) |
|
||||
(Tst::Float { filterable: true }, Tst::Float { filterable: true }) |
|
||||
// if we expect float, also accept depth
|
||||
(Tst::Float { .. }, Tst::Depth, ..) => {}
|
||||
// if we expect filterable, also accept Float that is defined as unfilterable if filterable feature is explicitly enabled
|
||||
// (only hit if wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES is enabled)
|
||||
(Tst::Float { filterable: true }, Tst::Float { .. }) if view.format_features.flags.contains(wgt::TextureFormatFeatureFlags::FILTERABLE) => {}
|
||||
_ => {
|
||||
return Err(Error::InvalidTextureSampleType {
|
||||
binding,
|
||||
@ -2268,6 +2268,8 @@ impl<A: HalApi> Device<A> {
|
||||
hub: &Hub<A, G>,
|
||||
token: &mut Token<Self>,
|
||||
) -> Result<pipeline::RenderPipeline<A>, pipeline::CreateRenderPipelineError> {
|
||||
use wgt::TextureFormatFeatureFlags as Tfff;
|
||||
|
||||
//TODO: only lock mutable if the layout is derived
|
||||
let (mut pipeline_layout_guard, mut token) = hub.pipeline_layouts.write(token);
|
||||
let (mut bgl_guard, mut token) = hub.bind_group_layouts.write(&mut token);
|
||||
@ -2413,12 +2415,16 @@ impl<A: HalApi> Device<A> {
|
||||
{
|
||||
break Some(pipeline::ColorStateError::FormatNotRenderable(cs.format));
|
||||
}
|
||||
if cs.blend.is_some() && !format_features.filterable {
|
||||
if cs.blend.is_some() && !format_features.flags.contains(Tfff::FILTERABLE) {
|
||||
break Some(pipeline::ColorStateError::FormatNotBlendable(cs.format));
|
||||
}
|
||||
if !hal::FormatAspects::from(cs.format).contains(hal::FormatAspects::COLOR) {
|
||||
break Some(pipeline::ColorStateError::FormatNotColor(cs.format));
|
||||
}
|
||||
if desc.multisample.count > 1 && !format_features.flags.contains(Tfff::MULTISAMPLE)
|
||||
{
|
||||
break Some(pipeline::ColorStateError::FormatNotMultisampled(cs.format));
|
||||
}
|
||||
|
||||
break None;
|
||||
};
|
||||
@ -2429,8 +2435,8 @@ impl<A: HalApi> Device<A> {
|
||||
|
||||
if let Some(ds) = depth_stencil_state {
|
||||
let error = loop {
|
||||
if !self
|
||||
.describe_format_features(adapter, ds.format)?
|
||||
let format_features = self.describe_format_features(adapter, ds.format)?;
|
||||
if !format_features
|
||||
.allowed_usages
|
||||
.contains(wgt::TextureUsages::RENDER_ATTACHMENT)
|
||||
{
|
||||
@ -2438,6 +2444,7 @@ impl<A: HalApi> Device<A> {
|
||||
ds.format,
|
||||
));
|
||||
}
|
||||
|
||||
let aspect = hal::FormatAspects::from(ds.format);
|
||||
if ds.is_depth_enabled() && !aspect.contains(hal::FormatAspects::DEPTH) {
|
||||
break Some(pipeline::DepthStencilStateError::FormatNotDepth(ds.format));
|
||||
@ -2447,6 +2454,13 @@ impl<A: HalApi> Device<A> {
|
||||
ds.format,
|
||||
));
|
||||
}
|
||||
if desc.multisample.count > 1 && !format_features.flags.contains(Tfff::MULTISAMPLE)
|
||||
{
|
||||
break Some(pipeline::DepthStencilStateError::FormatNotMultisampled(
|
||||
ds.format,
|
||||
));
|
||||
}
|
||||
|
||||
break None;
|
||||
};
|
||||
if let Some(e) = error {
|
||||
|
@ -270,14 +270,25 @@ impl<A: HalApi> Adapter<A> {
|
||||
// We are currently taking the filtering and blending together,
|
||||
// but we may reconsider this in the future if there are formats
|
||||
// in the wild for which these two capabilities do not match.
|
||||
let filterable = caps.contains(Tfc::SAMPLED_LINEAR)
|
||||
&& (!caps.contains(Tfc::COLOR_ATTACHMENT)
|
||||
|| caps.contains(Tfc::COLOR_ATTACHMENT_BLEND));
|
||||
flags.set(
|
||||
wgt::TextureFormatFeatureFlags::FILTERABLE,
|
||||
caps.contains(Tfc::SAMPLED_LINEAR)
|
||||
&& (!caps.contains(Tfc::COLOR_ATTACHMENT)
|
||||
|| caps.contains(Tfc::COLOR_ATTACHMENT_BLEND)),
|
||||
);
|
||||
|
||||
flags.set(
|
||||
wgt::TextureFormatFeatureFlags::MULTISAMPLE,
|
||||
caps.contains(Tfc::MULTISAMPLE),
|
||||
);
|
||||
flags.set(
|
||||
wgt::TextureFormatFeatureFlags::MULTISAMPLE_RESOLVE,
|
||||
caps.contains(Tfc::MULTISAMPLE_RESOLVE),
|
||||
);
|
||||
|
||||
wgt::TextureFormatFeatures {
|
||||
allowed_usages,
|
||||
flags,
|
||||
filterable,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -270,6 +270,8 @@ pub enum ColorStateError {
|
||||
FormatNotBlendable(wgt::TextureFormat),
|
||||
#[error("format {0:?} does not have a color aspect")]
|
||||
FormatNotColor(wgt::TextureFormat),
|
||||
#[error("format {0:?} can't be multisampled")]
|
||||
FormatNotMultisampled(wgt::TextureFormat),
|
||||
#[error("output format {pipeline} is incompatible with the shader {shader}")]
|
||||
IncompatibleFormat {
|
||||
pipeline: validation::NumericType,
|
||||
@ -287,6 +289,8 @@ pub enum DepthStencilStateError {
|
||||
FormatNotDepth(wgt::TextureFormat),
|
||||
#[error("format {0:?} does not have a stencil aspect, but stencil test/write is enabled")]
|
||||
FormatNotStencil(wgt::TextureFormat),
|
||||
#[error("format {0:?} can't be multisampled")]
|
||||
FormatNotMultisampled(wgt::TextureFormat),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
|
@ -170,8 +170,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
hal_usage: conv::map_texture_usage(config.usage, config.format.into()),
|
||||
format_features: wgt::TextureFormatFeatures {
|
||||
allowed_usages: wgt::TextureUsages::RENDER_ATTACHMENT,
|
||||
flags: wgt::TextureFormatFeatureFlags::empty(),
|
||||
filterable: false,
|
||||
flags: wgt::TextureFormatFeatureFlags::MULTISAMPLE
|
||||
| wgt::TextureFormatFeatureFlags::MULTISAMPLE_RESOLVE,
|
||||
},
|
||||
initialization_status: TextureInitTracker::new(1, 1),
|
||||
full_range: TextureSelector {
|
||||
|
@ -71,7 +71,7 @@ winapi = { version = "0.3", features = ["libloaderapi", "windef", "winuser"] }
|
||||
native = { package = "d3d12", version = "0.4.1", features = ["libloading"], optional = true }
|
||||
|
||||
[target.'cfg(any(target_os="macos", target_os="ios"))'.dependencies]
|
||||
mtl = { package = "metal", version = "0.23.1" }
|
||||
mtl = { package = "metal", git = "https://github.com/gfx-rs/metal-rs", rev = "140c8f4" }
|
||||
objc = "0.2.5"
|
||||
core-graphics-types = "0.1"
|
||||
|
||||
|
@ -332,13 +332,16 @@ impl crate::Adapter<super::Api> for super::Adapter {
|
||||
);
|
||||
|
||||
let mut caps = Tfc::COPY_SRC | Tfc::COPY_DST;
|
||||
let can_image = 0
|
||||
!= data.Support1
|
||||
& (d3d12::D3D12_FORMAT_SUPPORT1_TEXTURE1D
|
||||
| d3d12::D3D12_FORMAT_SUPPORT1_TEXTURE2D
|
||||
| d3d12::D3D12_FORMAT_SUPPORT1_TEXTURE3D
|
||||
| d3d12::D3D12_FORMAT_SUPPORT1_TEXTURECUBE);
|
||||
caps.set(Tfc::SAMPLED, can_image);
|
||||
let is_texture = data.Support1
|
||||
& (d3d12::D3D12_FORMAT_SUPPORT1_TEXTURE1D
|
||||
| d3d12::D3D12_FORMAT_SUPPORT1_TEXTURE2D
|
||||
| d3d12::D3D12_FORMAT_SUPPORT1_TEXTURE3D
|
||||
| d3d12::D3D12_FORMAT_SUPPORT1_TEXTURECUBE)
|
||||
!= 0;
|
||||
caps.set(
|
||||
Tfc::SAMPLED,
|
||||
is_texture && data.Support1 & d3d12::D3D12_FORMAT_SUPPORT1_SHADER_LOAD != 0,
|
||||
);
|
||||
caps.set(
|
||||
Tfc::SAMPLED_LINEAR,
|
||||
data.Support1 & d3d12::D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE != 0,
|
||||
@ -364,6 +367,19 @@ impl crate::Adapter<super::Api> for super::Adapter {
|
||||
data.Support2 & d3d12::D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD != 0,
|
||||
);
|
||||
|
||||
let no_msaa_load = caps.contains(Tfc::SAMPLED)
|
||||
&& data.Support1 & d3d12::D3D12_FORMAT_SUPPORT1_MULTISAMPLE_LOAD == 0;
|
||||
let no_msaa_target = data.Support1
|
||||
& (d3d12::D3D12_FORMAT_SUPPORT1_RENDER_TARGET
|
||||
| d3d12::D3D12_FORMAT_SUPPORT1_DEPTH_STENCIL)
|
||||
!= 0
|
||||
&& data.Support1 & d3d12::D3D12_FORMAT_SUPPORT1_MULTISAMPLE_RENDERTARGET == 0;
|
||||
caps.set(Tfc::MULTISAMPLE, !no_msaa_load && !no_msaa_target);
|
||||
caps.set(
|
||||
Tfc::MULTISAMPLE_RESOLVE,
|
||||
data.Support1 & d3d12::D3D12_FORMAT_SUPPORT1_MULTISAMPLE_RESOLVE != 0,
|
||||
);
|
||||
|
||||
caps
|
||||
}
|
||||
|
||||
|
@ -576,9 +576,11 @@ impl crate::Adapter<super::Api> for super::Adapter {
|
||||
) -> crate::TextureFormatCapabilities {
|
||||
use crate::TextureFormatCapabilities as Tfc;
|
||||
use wgt::TextureFormat as Tf;
|
||||
|
||||
// The storage types are sprinkled based on section
|
||||
// "TEXTURE IMAGE LOADS AND STORES" of GLES-3.2 spec.
|
||||
let unfiltered_color = Tfc::SAMPLED | Tfc::COLOR_ATTACHMENT;
|
||||
let unfiltered_color =
|
||||
Tfc::SAMPLED | Tfc::COLOR_ATTACHMENT | Tfc::MULTISAMPLE | Tfc::MULTISAMPLE_RESOLVE;
|
||||
let filtered_color = unfiltered_color | Tfc::SAMPLED_LINEAR | Tfc::COLOR_ATTACHMENT_BLEND;
|
||||
match format {
|
||||
Tf::R8Unorm | Tf::R8Snorm => filtered_color,
|
||||
|
@ -373,7 +373,7 @@ impl super::Queue {
|
||||
gl.pixel_store_i32(glow::UNPACK_ROW_LENGTH, row_texels as i32);
|
||||
gl.pixel_store_i32(glow::UNPACK_IMAGE_HEIGHT, column_texels as i32);
|
||||
let mut unbind_unpack_buffer = false;
|
||||
if format_info.block_dimensions == (1, 1) {
|
||||
if !format_info.is_compressed() {
|
||||
let buffer_data;
|
||||
let unpack_data = match src.raw {
|
||||
Some(buffer) => {
|
||||
@ -540,7 +540,7 @@ impl super::Queue {
|
||||
ref copy,
|
||||
} => {
|
||||
let format_info = src_format.describe();
|
||||
if format_info.block_dimensions != (1, 1) {
|
||||
if format_info.is_compressed() {
|
||||
log::error!("Not implemented yet: compressed texture copy to buffer");
|
||||
return;
|
||||
}
|
||||
|
@ -562,10 +562,15 @@ bitflags!(
|
||||
/// Format can be used as depth-stencil and input attachment.
|
||||
const DEPTH_STENCIL_ATTACHMENT = 1 << 8;
|
||||
|
||||
/// Format can be multisampled.
|
||||
const MULTISAMPLE = 1 << 9;
|
||||
/// Format can be used for render pass resolve targets.
|
||||
const MULTISAMPLE_RESOLVE = 1 << 10;
|
||||
|
||||
/// Format can be copied from.
|
||||
const COPY_SRC = 1 << 9;
|
||||
const COPY_SRC = 1 << 11;
|
||||
/// Format can be copied to.
|
||||
const COPY_DST = 1 << 10;
|
||||
const COPY_DST = 1 << 12;
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -55,6 +55,26 @@ impl crate::Adapter<super::Api> for super::Adapter {
|
||||
(Tfc::STORAGE_READ_WRITE, Tfc::STORAGE_READ_WRITE)
|
||||
}
|
||||
};
|
||||
let msaa_desktop_if = if pc.msaa_desktop {
|
||||
Tfc::MULTISAMPLE
|
||||
} else {
|
||||
Tfc::empty()
|
||||
};
|
||||
let msaa_apple7x_if = if pc.msaa_desktop | pc.msaa_apple7 {
|
||||
Tfc::MULTISAMPLE
|
||||
} else {
|
||||
Tfc::empty()
|
||||
};
|
||||
let msaa_resolve_desktop_if = if pc.msaa_desktop {
|
||||
Tfc::MULTISAMPLE_RESOLVE
|
||||
} else {
|
||||
Tfc::empty()
|
||||
};
|
||||
let msaa_resolve_apple3x_if = if pc.msaa_desktop | pc.msaa_apple3 {
|
||||
Tfc::MULTISAMPLE_RESOLVE
|
||||
} else {
|
||||
Tfc::empty()
|
||||
};
|
||||
|
||||
let extra = match format {
|
||||
Tf::R8Unorm => {
|
||||
@ -63,59 +83,77 @@ impl crate::Adapter<super::Api> for super::Adapter {
|
||||
| Tfc::STORAGE
|
||||
| Tfc::COLOR_ATTACHMENT
|
||||
| Tfc::COLOR_ATTACHMENT_BLEND
|
||||
| Tfc::MULTISAMPLE
|
||||
| Tfc::MULTISAMPLE_RESOLVE
|
||||
}
|
||||
Tf::R8Snorm => {
|
||||
Tfc::SAMPLED_LINEAR
|
||||
| Tfc::STORAGE
|
||||
| Tfc::COLOR_ATTACHMENT
|
||||
| Tfc::COLOR_ATTACHMENT_BLEND
|
||||
| Tfc::MULTISAMPLE
|
||||
| Tfc::MULTISAMPLE_RESOLVE
|
||||
}
|
||||
Tf::R8Uint | Tf::R8Sint | Tf::R16Uint | Tf::R16Sint => {
|
||||
read_write_tier2_if | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT
|
||||
read_write_tier2_if | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::MULTISAMPLE
|
||||
}
|
||||
Tf::R16Float => {
|
||||
read_write_tier2_if
|
||||
| Tfc::STORAGE
|
||||
| Tfc::COLOR_ATTACHMENT
|
||||
| Tfc::COLOR_ATTACHMENT_BLEND
|
||||
| Tfc::MULTISAMPLE
|
||||
| Tfc::MULTISAMPLE_RESOLVE
|
||||
}
|
||||
Tf::R16Unorm | Tf::R16Snorm => {
|
||||
Tfc::SAMPLED_LINEAR
|
||||
| Tfc::STORAGE
|
||||
| Tfc::COLOR_ATTACHMENT
|
||||
| Tfc::COLOR_ATTACHMENT_BLEND
|
||||
| Tfc::MULTISAMPLE
|
||||
| msaa_resolve_desktop_if
|
||||
}
|
||||
Tf::Rg8Unorm | Tf::Rg8Snorm => {
|
||||
Tfc::SAMPLED_LINEAR
|
||||
| Tfc::STORAGE
|
||||
| Tfc::COLOR_ATTACHMENT
|
||||
| Tfc::COLOR_ATTACHMENT_BLEND
|
||||
| Tfc::MULTISAMPLE
|
||||
| Tfc::MULTISAMPLE_RESOLVE
|
||||
}
|
||||
Tf::Rg8Uint | Tf::Rg8Sint => Tfc::COLOR_ATTACHMENT,
|
||||
Tf::Rg8Uint | Tf::Rg8Sint => Tfc::COLOR_ATTACHMENT | Tfc::MULTISAMPLE,
|
||||
Tf::R32Uint | Tf::R32Sint => {
|
||||
if pc.format_r32_all {
|
||||
read_write_tier1_if | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT
|
||||
let storage = if pc.format_r32_all {
|
||||
read_write_tier1_if | Tfc::STORAGE
|
||||
} else {
|
||||
Tfc::COLOR_ATTACHMENT
|
||||
}
|
||||
Tfc::empty()
|
||||
};
|
||||
Tfc::COLOR_ATTACHMENT | storage | msaa_desktop_if
|
||||
}
|
||||
Tf::R32Float => {
|
||||
let mut flags = Tfc::COLOR_ATTACHMENT | Tfc::COLOR_ATTACHMENT_BLEND;
|
||||
if pc.format_r32float_all {
|
||||
flags |= read_write_tier1_if | Tfc::STORAGE | Tfc::SAMPLED_LINEAR;
|
||||
let flags = Tfc::COLOR_ATTACHMENT
|
||||
| Tfc::COLOR_ATTACHMENT_BLEND
|
||||
| Tfc::MULTISAMPLE
|
||||
| msaa_resolve_desktop_if;
|
||||
let extra = if pc.format_r32float_all {
|
||||
read_write_tier1_if | Tfc::STORAGE | Tfc::SAMPLED_LINEAR
|
||||
} else if pc.format_r32float_no_filter {
|
||||
flags |= Tfc::SAMPLED_LINEAR;
|
||||
}
|
||||
flags
|
||||
Tfc::SAMPLED_LINEAR
|
||||
} else {
|
||||
Tfc::empty()
|
||||
};
|
||||
flags | extra
|
||||
}
|
||||
Tf::Rg16Uint | Tf::Rg16Sint => {
|
||||
read_write_tier2_if | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT
|
||||
read_write_tier2_if | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::MULTISAMPLE
|
||||
}
|
||||
Tf::Rg16Unorm | Tf::Rg16Snorm => {
|
||||
Tfc::SAMPLED_LINEAR
|
||||
| Tfc::STORAGE
|
||||
| Tfc::COLOR_ATTACHMENT
|
||||
| Tfc::COLOR_ATTACHMENT_BLEND
|
||||
| Tfc::MULTISAMPLE
|
||||
| msaa_resolve_desktop_if
|
||||
}
|
||||
Tf::Rg16Float => {
|
||||
read_write_tier2_if
|
||||
@ -123,6 +161,8 @@ impl crate::Adapter<super::Api> for super::Adapter {
|
||||
| Tfc::STORAGE
|
||||
| Tfc::COLOR_ATTACHMENT
|
||||
| Tfc::COLOR_ATTACHMENT_BLEND
|
||||
| Tfc::MULTISAMPLE
|
||||
| Tfc::MULTISAMPLE_RESOLVE
|
||||
}
|
||||
Tf::Rgba8Unorm => {
|
||||
read_write_tier2_if
|
||||
@ -130,10 +170,15 @@ impl crate::Adapter<super::Api> for super::Adapter {
|
||||
| Tfc::STORAGE
|
||||
| Tfc::COLOR_ATTACHMENT
|
||||
| Tfc::COLOR_ATTACHMENT_BLEND
|
||||
| Tfc::MULTISAMPLE
|
||||
| Tfc::MULTISAMPLE_RESOLVE
|
||||
}
|
||||
Tf::Rgba8UnormSrgb | Tf::Bgra8UnormSrgb => {
|
||||
let mut flags =
|
||||
Tfc::SAMPLED_LINEAR | Tfc::COLOR_ATTACHMENT | Tfc::COLOR_ATTACHMENT_BLEND;
|
||||
let mut flags = Tfc::SAMPLED_LINEAR
|
||||
| Tfc::COLOR_ATTACHMENT
|
||||
| Tfc::COLOR_ATTACHMENT_BLEND
|
||||
| Tfc::MULTISAMPLE
|
||||
| Tfc::MULTISAMPLE_RESOLVE;
|
||||
flags.set(Tfc::STORAGE, pc.format_rgba8_srgb_all);
|
||||
flags
|
||||
}
|
||||
@ -142,25 +187,34 @@ impl crate::Adapter<super::Api> for super::Adapter {
|
||||
| Tfc::STORAGE
|
||||
| Tfc::COLOR_ATTACHMENT
|
||||
| Tfc::COLOR_ATTACHMENT_BLEND
|
||||
| Tfc::MULTISAMPLE
|
||||
| Tfc::MULTISAMPLE_RESOLVE
|
||||
}
|
||||
Tf::Rgba8Uint | Tf::Rgba8Sint => {
|
||||
read_write_tier2_if | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT
|
||||
read_write_tier2_if | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::MULTISAMPLE
|
||||
}
|
||||
Tf::Rgb10a2Unorm => {
|
||||
let mut flags =
|
||||
Tfc::SAMPLED_LINEAR | Tfc::COLOR_ATTACHMENT | Tfc::COLOR_ATTACHMENT_BLEND;
|
||||
let mut flags = Tfc::SAMPLED_LINEAR
|
||||
| Tfc::COLOR_ATTACHMENT
|
||||
| Tfc::COLOR_ATTACHMENT_BLEND
|
||||
| Tfc::MULTISAMPLE
|
||||
| Tfc::MULTISAMPLE_RESOLVE;
|
||||
flags.set(Tfc::STORAGE, pc.format_rgb10a2_unorm_all);
|
||||
flags
|
||||
}
|
||||
Tf::Rg11b10Float => {
|
||||
let mut flags =
|
||||
Tfc::SAMPLED_LINEAR | Tfc::COLOR_ATTACHMENT | Tfc::COLOR_ATTACHMENT_BLEND;
|
||||
let mut flags = Tfc::SAMPLED_LINEAR
|
||||
| Tfc::COLOR_ATTACHMENT
|
||||
| Tfc::COLOR_ATTACHMENT_BLEND
|
||||
| Tfc::MULTISAMPLE
|
||||
| Tfc::MULTISAMPLE_RESOLVE;
|
||||
flags.set(Tfc::STORAGE, pc.format_rg11b10_all);
|
||||
flags
|
||||
}
|
||||
Tf::Rg32Uint | Tf::Rg32Sint => Tfc::COLOR_ATTACHMENT | Tfc::STORAGE,
|
||||
Tf::Rg32Uint | Tf::Rg32Sint => Tfc::COLOR_ATTACHMENT | Tfc::STORAGE | msaa_apple7x_if,
|
||||
Tf::Rg32Float => {
|
||||
let mut flags = Tfc::COLOR_ATTACHMENT | Tfc::COLOR_ATTACHMENT_BLEND;
|
||||
let mut flags =
|
||||
Tfc::COLOR_ATTACHMENT | Tfc::COLOR_ATTACHMENT_BLEND | msaa_apple7x_if;
|
||||
if pc.format_rg32float_all {
|
||||
flags |= Tfc::STORAGE | Tfc::SAMPLED_LINEAR;
|
||||
} else if pc.format_rg32float_color_blend {
|
||||
@ -169,13 +223,15 @@ impl crate::Adapter<super::Api> for super::Adapter {
|
||||
flags
|
||||
}
|
||||
Tf::Rgba16Uint | Tf::Rgba16Sint => {
|
||||
read_write_tier2_if | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT
|
||||
read_write_tier2_if | Tfc::STORAGE | Tfc::COLOR_ATTACHMENT | Tfc::MULTISAMPLE
|
||||
}
|
||||
Tf::Rgba16Unorm | Tf::Rgba16Snorm => {
|
||||
Tfc::SAMPLED_LINEAR
|
||||
| Tfc::STORAGE
|
||||
| Tfc::COLOR_ATTACHMENT
|
||||
| Tfc::COLOR_ATTACHMENT_BLEND
|
||||
| Tfc::MULTISAMPLE
|
||||
| msaa_resolve_desktop_if
|
||||
}
|
||||
Tf::Rgba16Float => {
|
||||
read_write_tier2_if
|
||||
@ -183,38 +239,52 @@ impl crate::Adapter<super::Api> for super::Adapter {
|
||||
| Tfc::STORAGE
|
||||
| Tfc::COLOR_ATTACHMENT
|
||||
| Tfc::COLOR_ATTACHMENT_BLEND
|
||||
| Tfc::MULTISAMPLE
|
||||
| Tfc::MULTISAMPLE_RESOLVE
|
||||
}
|
||||
Tf::Rgba32Uint | Tf::Rgba32Sint => {
|
||||
if pc.format_rgba32int_color_write {
|
||||
read_write_tier2_if | Tfc::COLOR_ATTACHMENT | Tfc::STORAGE
|
||||
let storage = if pc.format_rgba32int_color_write {
|
||||
read_write_tier2_if | Tfc::STORAGE
|
||||
} else {
|
||||
Tfc::COLOR_ATTACHMENT
|
||||
}
|
||||
Tfc::empty()
|
||||
};
|
||||
storage | Tfc::COLOR_ATTACHMENT | msaa_desktop_if
|
||||
}
|
||||
Tf::Rgba32Float => {
|
||||
if pc.format_rgba32float_all {
|
||||
let extra = if pc.format_rgba32float_all {
|
||||
read_write_tier2_if
|
||||
| Tfc::SAMPLED_LINEAR
|
||||
| Tfc::STORAGE
|
||||
| Tfc::COLOR_ATTACHMENT
|
||||
| Tfc::COLOR_ATTACHMENT_BLEND
|
||||
} else if pc.format_rgba32float_color_write {
|
||||
read_write_tier2_if | Tfc::COLOR_ATTACHMENT | Tfc::STORAGE
|
||||
read_write_tier2_if | Tfc::STORAGE
|
||||
} else {
|
||||
Tfc::COLOR_ATTACHMENT
|
||||
}
|
||||
Tfc::empty()
|
||||
};
|
||||
extra | Tfc::COLOR_ATTACHMENT | msaa_apple7x_if | msaa_resolve_desktop_if
|
||||
}
|
||||
Tf::Depth32Float => {
|
||||
if pc.format_depth32float_filter {
|
||||
Tfc::DEPTH_STENCIL_ATTACHMENT | Tfc::SAMPLED_LINEAR
|
||||
let linear = if pc.format_depth32float_filter {
|
||||
Tfc::SAMPLED_LINEAR
|
||||
} else {
|
||||
Tfc::DEPTH_STENCIL_ATTACHMENT
|
||||
}
|
||||
Tfc::empty()
|
||||
};
|
||||
linear | Tfc::DEPTH_STENCIL_ATTACHMENT | Tfc::MULTISAMPLE | msaa_resolve_apple3x_if
|
||||
}
|
||||
Tf::Depth24Plus | Tf::Depth24PlusStencil8 => {
|
||||
Tfc::DEPTH_STENCIL_ATTACHMENT | Tfc::SAMPLED_LINEAR
|
||||
Tfc::DEPTH_STENCIL_ATTACHMENT
|
||||
| Tfc::SAMPLED_LINEAR
|
||||
| Tfc::MULTISAMPLE
|
||||
| msaa_resolve_apple3x_if
|
||||
}
|
||||
Tf::Rgb9e5Ufloat => {
|
||||
let msaa = if msaa_desktop_if.is_empty() {
|
||||
Tfc::MULTISAMPLE | Tfc::MULTISAMPLE_RESOLVE
|
||||
} else {
|
||||
Tfc::empty()
|
||||
};
|
||||
Tfc::SAMPLED_LINEAR | msaa
|
||||
}
|
||||
Tf::Rgb9e5Ufloat => Tfc::SAMPLED_LINEAR,
|
||||
Tf::Bc1RgbaUnorm
|
||||
| Tf::Bc1RgbaUnormSrgb
|
||||
| Tf::Bc2RgbaUnorm
|
||||
@ -613,6 +683,9 @@ impl super::PrivateCapabilities {
|
||||
} else {
|
||||
mtl::MTLReadWriteTextureTier::TierNone
|
||||
},
|
||||
msaa_desktop: os_is_mac,
|
||||
msaa_apple3: family_check && device.supports_family(MTLGPUFamily::Apple3),
|
||||
msaa_apple7: family_check && device.supports_family(MTLGPUFamily::Apple7),
|
||||
resource_heaps: Self::supports_any(device, RESOURCE_HEAP_SUPPORT),
|
||||
argument_buffers: Self::supports_any(device, ARGUMENT_BUFFER_SUPPORT),
|
||||
shared_textures: !os_is_mac,
|
||||
|
@ -144,6 +144,9 @@ struct PrivateCapabilities {
|
||||
msl_version: mtl::MTLLanguageVersion,
|
||||
fragment_rw_storage: bool,
|
||||
read_write_texture_tier: mtl::MTLReadWriteTextureTier,
|
||||
msaa_desktop: bool,
|
||||
msaa_apple3: bool,
|
||||
msaa_apple7: bool,
|
||||
resource_heaps: bool,
|
||||
argument_buffers: bool,
|
||||
shared_textures: bool,
|
||||
|
@ -1332,6 +1332,7 @@ impl crate::Adapter<super::Api> for super::Adapter {
|
||||
format: wgt::TextureFormat,
|
||||
) -> crate::TextureFormatCapabilities {
|
||||
use crate::TextureFormatCapabilities as Tfc;
|
||||
|
||||
let vk_format = self.private_caps.map_texture_format(format);
|
||||
let properties = self
|
||||
.phd_capabilities
|
||||
@ -1385,6 +1386,11 @@ impl crate::Adapter<super::Api> for super::Adapter {
|
||||
vk::FormatFeatureFlags::TRANSFER_DST | vk::FormatFeatureFlags::BLIT_DST,
|
||||
),
|
||||
);
|
||||
// Vulkan is very permissive about MSAA
|
||||
flags.set(
|
||||
Tfc::MULTISAMPLE | Tfc::MULTISAMPLE_RESOLVE,
|
||||
!format.describe().is_compressed(),
|
||||
);
|
||||
flags
|
||||
}
|
||||
|
||||
|
@ -1410,12 +1410,20 @@ bitflags::bitflags! {
|
||||
/// Feature flags for a texture format.
|
||||
#[repr(transparent)]
|
||||
pub struct TextureFormatFeatureFlags: u32 {
|
||||
/// If not present, the texture can't be sampled with a filtering sampler.
|
||||
/// This may overwrite TextureSampleType::Float.filterable
|
||||
const FILTERABLE = 1 << 0;
|
||||
/// Allows [`TextureDescriptor::sample_count`] greater than `1`.
|
||||
const MULTISAMPLE = 1 << 1;
|
||||
/// Allows a texture of this format to back a view passed as `resolve_target`
|
||||
/// to a render pass for an automatic driver-implemented resolve.
|
||||
const MULTISAMPLE_RESOLVE = 1 << 2;
|
||||
/// When used as a STORAGE texture, then a texture with this format can be bound with
|
||||
/// [`StorageTextureAccess::ReadOnly`] or [`StorageTextureAccess::ReadWrite`].
|
||||
const STORAGE_READ_WRITE = 1 << 0;
|
||||
const STORAGE_READ_WRITE = 1 << 3;
|
||||
/// When used as a STORAGE texture, then a texture with this format can be written to with atomics.
|
||||
// TODO: No access flag exposed as of writing
|
||||
const STORAGE_ATOMICS = 1 << 1;
|
||||
const STORAGE_ATOMICS = 1 << 4;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1431,9 +1439,6 @@ pub struct TextureFormatFeatures {
|
||||
pub allowed_usages: TextureUsages,
|
||||
/// Additional property flags for the format.
|
||||
pub flags: TextureFormatFeatureFlags,
|
||||
/// If `filterable` is false, the texture can't be sampled with a filtering sampler.
|
||||
/// This may overwrite TextureSampleType::Float.filterable
|
||||
pub filterable: bool,
|
||||
}
|
||||
|
||||
/// Information about a texture format.
|
||||
@ -1455,6 +1460,13 @@ pub struct TextureFormatInfo {
|
||||
pub guaranteed_format_features: TextureFormatFeatures,
|
||||
}
|
||||
|
||||
impl TextureFormatInfo {
|
||||
/// Return `true` for compressed formats.
|
||||
pub fn is_compressed(&self) -> bool {
|
||||
self.block_dimensions != (1, 1)
|
||||
}
|
||||
}
|
||||
|
||||
/// Underlying texture data format.
|
||||
///
|
||||
/// If there is a conversion in the format (such as srgb -> linear), The conversion listed is for
|
||||
@ -1984,9 +1996,18 @@ impl TextureFormat {
|
||||
let float = TextureSampleType::Float { filterable: true };
|
||||
let depth = TextureSampleType::Depth;
|
||||
|
||||
// Color spaces
|
||||
let linear = false;
|
||||
let srgb = true;
|
||||
enum ColorSpace {
|
||||
Linear,
|
||||
Corrected,
|
||||
}
|
||||
let linear = ColorSpace::Linear;
|
||||
let corrected = ColorSpace::Corrected;
|
||||
|
||||
// Multisampling
|
||||
let noaa = TextureFormatFeatureFlags::empty();
|
||||
let msaa = TextureFormatFeatureFlags::MULTISAMPLE;
|
||||
let msaa_resolve =
|
||||
TextureFormatFeatureFlags::MULTISAMPLE | TextureFormatFeatureFlags::MULTISAMPLE_RESOLVE;
|
||||
|
||||
// Flags
|
||||
let basic =
|
||||
@ -1999,145 +2020,238 @@ impl TextureFormat {
|
||||
let (
|
||||
required_features,
|
||||
sample_type,
|
||||
srgb,
|
||||
color_space,
|
||||
msaa_flags,
|
||||
block_dimensions,
|
||||
block_size,
|
||||
allowed_usages,
|
||||
components,
|
||||
) = match self {
|
||||
// Normal 8 bit textures
|
||||
Self::R8Unorm => (native, float, linear, (1, 1), 1, attachment, 1),
|
||||
Self::R8Snorm => (native, float, linear, (1, 1), 1, basic, 1),
|
||||
Self::R8Uint => (native, uint, linear, (1, 1), 1, attachment, 1),
|
||||
Self::R8Sint => (native, sint, linear, (1, 1), 1, attachment, 1),
|
||||
Self::R8Unorm => (
|
||||
native,
|
||||
float,
|
||||
linear,
|
||||
msaa_resolve,
|
||||
(1, 1),
|
||||
1,
|
||||
attachment,
|
||||
1,
|
||||
),
|
||||
Self::R8Snorm => (native, float, linear, msaa, (1, 1), 1, basic, 1),
|
||||
Self::R8Uint => (native, uint, linear, msaa, (1, 1), 1, attachment, 1),
|
||||
Self::R8Sint => (native, sint, linear, msaa, (1, 1), 1, attachment, 1),
|
||||
|
||||
// Normal 16 bit textures
|
||||
Self::R16Uint => (native, uint, linear, (1, 1), 2, attachment, 1),
|
||||
Self::R16Sint => (native, sint, linear, (1, 1), 2, attachment, 1),
|
||||
Self::R16Float => (native, float, linear, (1, 1), 2, attachment, 1),
|
||||
Self::Rg8Unorm => (native, float, linear, (1, 1), 2, attachment, 2),
|
||||
Self::Rg8Snorm => (native, float, linear, (1, 1), 2, attachment, 2),
|
||||
Self::Rg8Uint => (native, uint, linear, (1, 1), 2, attachment, 2),
|
||||
Self::Rg8Sint => (native, sint, linear, (1, 1), 2, basic, 2),
|
||||
Self::R16Uint => (native, uint, linear, msaa, (1, 1), 2, attachment, 1),
|
||||
Self::R16Sint => (native, sint, linear, msaa, (1, 1), 2, attachment, 1),
|
||||
Self::R16Float => (
|
||||
native,
|
||||
float,
|
||||
linear,
|
||||
msaa_resolve,
|
||||
(1, 1),
|
||||
2,
|
||||
attachment,
|
||||
1,
|
||||
),
|
||||
Self::Rg8Unorm => (
|
||||
native,
|
||||
float,
|
||||
linear,
|
||||
msaa_resolve,
|
||||
(1, 1),
|
||||
2,
|
||||
attachment,
|
||||
2,
|
||||
),
|
||||
Self::Rg8Snorm => (native, float, linear, msaa, (1, 1), 2, attachment, 2),
|
||||
Self::Rg8Uint => (native, uint, linear, msaa, (1, 1), 2, attachment, 2),
|
||||
Self::Rg8Sint => (native, sint, linear, msaa, (1, 1), 2, basic, 2),
|
||||
|
||||
// Normal 32 bit textures
|
||||
Self::R32Uint => (native, uint, linear, (1, 1), 4, all_flags, 1),
|
||||
Self::R32Sint => (native, sint, linear, (1, 1), 4, all_flags, 1),
|
||||
Self::R32Float => (native, nearest, linear, (1, 1), 4, all_flags, 1),
|
||||
Self::Rg16Uint => (native, uint, linear, (1, 1), 4, attachment, 2),
|
||||
Self::Rg16Sint => (native, sint, linear, (1, 1), 4, attachment, 2),
|
||||
Self::Rg16Float => (native, float, linear, (1, 1), 4, attachment, 2),
|
||||
Self::Rgba8Unorm => (native, float, linear, (1, 1), 4, all_flags, 4),
|
||||
Self::Rgba8UnormSrgb => (native, float, srgb, (1, 1), 4, attachment, 4),
|
||||
Self::Rgba8Snorm => (native, float, linear, (1, 1), 4, storage, 4),
|
||||
Self::Rgba8Uint => (native, uint, linear, (1, 1), 4, all_flags, 4),
|
||||
Self::Rgba8Sint => (native, sint, linear, (1, 1), 4, all_flags, 4),
|
||||
Self::Bgra8Unorm => (native, float, linear, (1, 1), 4, attachment, 4),
|
||||
Self::Bgra8UnormSrgb => (native, float, srgb, (1, 1), 4, attachment, 4),
|
||||
Self::R32Uint => (native, uint, linear, noaa, (1, 1), 4, all_flags, 1),
|
||||
Self::R32Sint => (native, sint, linear, noaa, (1, 1), 4, all_flags, 1),
|
||||
Self::R32Float => (native, nearest, linear, msaa, (1, 1), 4, all_flags, 1),
|
||||
Self::Rg16Uint => (native, uint, linear, msaa, (1, 1), 4, attachment, 2),
|
||||
Self::Rg16Sint => (native, sint, linear, msaa, (1, 1), 4, attachment, 2),
|
||||
Self::Rg16Float => (
|
||||
native,
|
||||
float,
|
||||
linear,
|
||||
msaa_resolve,
|
||||
(1, 1),
|
||||
4,
|
||||
attachment,
|
||||
2,
|
||||
),
|
||||
Self::Rgba8Unorm => (native, float, linear, msaa_resolve, (1, 1), 4, all_flags, 4),
|
||||
Self::Rgba8UnormSrgb => (
|
||||
native,
|
||||
float,
|
||||
corrected,
|
||||
msaa_resolve,
|
||||
(1, 1),
|
||||
4,
|
||||
attachment,
|
||||
4,
|
||||
),
|
||||
Self::Rgba8Snorm => (native, float, linear, msaa, (1, 1), 4, storage, 4),
|
||||
Self::Rgba8Uint => (native, uint, linear, msaa, (1, 1), 4, all_flags, 4),
|
||||
Self::Rgba8Sint => (native, sint, linear, msaa, (1, 1), 4, all_flags, 4),
|
||||
Self::Bgra8Unorm => (
|
||||
native,
|
||||
float,
|
||||
linear,
|
||||
msaa_resolve,
|
||||
(1, 1),
|
||||
4,
|
||||
attachment,
|
||||
4,
|
||||
),
|
||||
Self::Bgra8UnormSrgb => (
|
||||
native,
|
||||
float,
|
||||
corrected,
|
||||
msaa_resolve,
|
||||
(1, 1),
|
||||
4,
|
||||
attachment,
|
||||
4,
|
||||
),
|
||||
|
||||
// Packed 32 bit textures
|
||||
Self::Rgb10a2Unorm => (native, float, linear, (1, 1), 4, attachment, 4),
|
||||
Self::Rg11b10Float => (native, float, linear, (1, 1), 4, basic, 3),
|
||||
Self::Rgb10a2Unorm => (
|
||||
native,
|
||||
float,
|
||||
linear,
|
||||
msaa_resolve,
|
||||
(1, 1),
|
||||
4,
|
||||
attachment,
|
||||
4,
|
||||
),
|
||||
Self::Rg11b10Float => (native, float, linear, msaa, (1, 1), 4, basic, 3),
|
||||
|
||||
// Packed 32 bit textures
|
||||
Self::Rg32Uint => (native, uint, linear, (1, 1), 8, all_flags, 2),
|
||||
Self::Rg32Sint => (native, sint, linear, (1, 1), 8, all_flags, 2),
|
||||
Self::Rg32Float => (native, nearest, linear, (1, 1), 8, all_flags, 2),
|
||||
Self::Rgba16Uint => (native, uint, linear, (1, 1), 8, all_flags, 4),
|
||||
Self::Rgba16Sint => (native, sint, linear, (1, 1), 8, all_flags, 4),
|
||||
Self::Rgba16Float => (native, float, linear, (1, 1), 8, all_flags, 4),
|
||||
Self::Rg32Uint => (native, uint, linear, noaa, (1, 1), 8, all_flags, 2),
|
||||
Self::Rg32Sint => (native, sint, linear, noaa, (1, 1), 8, all_flags, 2),
|
||||
Self::Rg32Float => (native, nearest, linear, noaa, (1, 1), 8, all_flags, 2),
|
||||
Self::Rgba16Uint => (native, uint, linear, msaa, (1, 1), 8, all_flags, 4),
|
||||
Self::Rgba16Sint => (native, sint, linear, msaa, (1, 1), 8, all_flags, 4),
|
||||
Self::Rgba16Float => (native, float, linear, msaa_resolve, (1, 1), 8, all_flags, 4),
|
||||
|
||||
// Packed 32 bit textures
|
||||
Self::Rgba32Uint => (native, uint, linear, (1, 1), 16, all_flags, 4),
|
||||
Self::Rgba32Sint => (native, sint, linear, (1, 1), 16, all_flags, 4),
|
||||
Self::Rgba32Float => (native, nearest, linear, (1, 1), 16, all_flags, 4),
|
||||
Self::Rgba32Uint => (native, uint, linear, noaa, (1, 1), 16, all_flags, 4),
|
||||
Self::Rgba32Sint => (native, sint, linear, noaa, (1, 1), 16, all_flags, 4),
|
||||
Self::Rgba32Float => (native, nearest, linear, noaa, (1, 1), 16, all_flags, 4),
|
||||
|
||||
// Depth-stencil textures
|
||||
Self::Depth32Float => (native, depth, linear, (1, 1), 4, attachment, 1),
|
||||
Self::Depth24Plus => (native, depth, linear, (1, 1), 4, attachment, 1),
|
||||
Self::Depth24PlusStencil8 => (native, depth, linear, (1, 1), 4, attachment, 2),
|
||||
Self::Depth32Float => (native, depth, linear, msaa, (1, 1), 4, attachment, 1),
|
||||
Self::Depth24Plus => (native, depth, linear, msaa, (1, 1), 4, attachment, 1),
|
||||
Self::Depth24PlusStencil8 => (native, depth, linear, msaa, (1, 1), 4, attachment, 2),
|
||||
|
||||
// Packed uncompressed
|
||||
Self::Rgb9e5Ufloat => (native, float, linear, (1, 1), 4, basic, 3),
|
||||
Self::Rgb9e5Ufloat => (native, float, linear, noaa, (1, 1), 4, basic, 3),
|
||||
|
||||
// BCn compressed textures
|
||||
Self::Bc1RgbaUnorm => (bc, float, linear, (4, 4), 8, basic, 4),
|
||||
Self::Bc1RgbaUnormSrgb => (bc, float, srgb, (4, 4), 8, basic, 4),
|
||||
Self::Bc2RgbaUnorm => (bc, float, linear, (4, 4), 16, basic, 4),
|
||||
Self::Bc2RgbaUnormSrgb => (bc, float, srgb, (4, 4), 16, basic, 4),
|
||||
Self::Bc3RgbaUnorm => (bc, float, linear, (4, 4), 16, basic, 4),
|
||||
Self::Bc3RgbaUnormSrgb => (bc, float, srgb, (4, 4), 16, basic, 4),
|
||||
Self::Bc4RUnorm => (bc, float, linear, (4, 4), 8, basic, 1),
|
||||
Self::Bc4RSnorm => (bc, float, linear, (4, 4), 8, basic, 1),
|
||||
Self::Bc5RgUnorm => (bc, float, linear, (4, 4), 16, basic, 2),
|
||||
Self::Bc5RgSnorm => (bc, float, linear, (4, 4), 16, basic, 2),
|
||||
Self::Bc6hRgbUfloat => (bc, float, linear, (4, 4), 16, basic, 3),
|
||||
Self::Bc6hRgbSfloat => (bc, float, linear, (4, 4), 16, basic, 3),
|
||||
Self::Bc7RgbaUnorm => (bc, float, linear, (4, 4), 16, basic, 4),
|
||||
Self::Bc7RgbaUnormSrgb => (bc, float, srgb, (4, 4), 16, basic, 4),
|
||||
Self::Bc1RgbaUnorm => (bc, float, linear, noaa, (4, 4), 8, basic, 4),
|
||||
Self::Bc1RgbaUnormSrgb => (bc, float, corrected, noaa, (4, 4), 8, basic, 4),
|
||||
Self::Bc2RgbaUnorm => (bc, float, linear, noaa, (4, 4), 16, basic, 4),
|
||||
Self::Bc2RgbaUnormSrgb => (bc, float, corrected, noaa, (4, 4), 16, basic, 4),
|
||||
Self::Bc3RgbaUnorm => (bc, float, linear, noaa, (4, 4), 16, basic, 4),
|
||||
Self::Bc3RgbaUnormSrgb => (bc, float, corrected, noaa, (4, 4), 16, basic, 4),
|
||||
Self::Bc4RUnorm => (bc, float, linear, noaa, (4, 4), 8, basic, 1),
|
||||
Self::Bc4RSnorm => (bc, float, linear, noaa, (4, 4), 8, basic, 1),
|
||||
Self::Bc5RgUnorm => (bc, float, linear, noaa, (4, 4), 16, basic, 2),
|
||||
Self::Bc5RgSnorm => (bc, float, linear, noaa, (4, 4), 16, basic, 2),
|
||||
Self::Bc6hRgbUfloat => (bc, float, linear, noaa, (4, 4), 16, basic, 3),
|
||||
Self::Bc6hRgbSfloat => (bc, float, linear, noaa, (4, 4), 16, basic, 3),
|
||||
Self::Bc7RgbaUnorm => (bc, float, linear, noaa, (4, 4), 16, basic, 4),
|
||||
Self::Bc7RgbaUnormSrgb => (bc, float, corrected, noaa, (4, 4), 16, basic, 4),
|
||||
|
||||
// ETC compressed textures
|
||||
Self::Etc2Rgb8Unorm => (etc2, float, linear, (4, 4), 8, basic, 3),
|
||||
Self::Etc2Rgb8UnormSrgb => (etc2, float, srgb, (4, 4), 8, basic, 3),
|
||||
Self::Etc2Rgb8A1Unorm => (etc2, float, linear, (4, 4), 8, basic, 4),
|
||||
Self::Etc2Rgb8A1UnormSrgb => (etc2, float, srgb, (4, 4), 8, basic, 4),
|
||||
Self::Etc2Rgba8Unorm => (etc2, float, linear, (4, 4), 16, basic, 4),
|
||||
Self::Etc2Rgba8UnormSrgb => (etc2, float, srgb, (4, 4), 16, basic, 4),
|
||||
Self::EacR11Unorm => (etc2, float, linear, (4, 4), 8, basic, 1),
|
||||
Self::EacR11Snorm => (etc2, float, linear, (4, 4), 8, basic, 1),
|
||||
Self::EacRg11Unorm => (etc2, float, linear, (4, 4), 16, basic, 2),
|
||||
Self::EacRg11Snorm => (etc2, float, linear, (4, 4), 16, basic, 2),
|
||||
Self::Etc2Rgb8Unorm => (etc2, float, linear, noaa, (4, 4), 8, basic, 3),
|
||||
Self::Etc2Rgb8UnormSrgb => (etc2, float, corrected, noaa, (4, 4), 8, basic, 3),
|
||||
Self::Etc2Rgb8A1Unorm => (etc2, float, linear, noaa, (4, 4), 8, basic, 4),
|
||||
Self::Etc2Rgb8A1UnormSrgb => (etc2, float, corrected, noaa, (4, 4), 8, basic, 4),
|
||||
Self::Etc2Rgba8Unorm => (etc2, float, linear, noaa, (4, 4), 16, basic, 4),
|
||||
Self::Etc2Rgba8UnormSrgb => (etc2, float, corrected, noaa, (4, 4), 16, basic, 4),
|
||||
Self::EacR11Unorm => (etc2, float, linear, noaa, (4, 4), 8, basic, 1),
|
||||
Self::EacR11Snorm => (etc2, float, linear, noaa, (4, 4), 8, basic, 1),
|
||||
Self::EacRg11Unorm => (etc2, float, linear, noaa, (4, 4), 16, basic, 2),
|
||||
Self::EacRg11Snorm => (etc2, float, linear, noaa, (4, 4), 16, basic, 2),
|
||||
|
||||
// ASTC compressed textures
|
||||
Self::Astc4x4RgbaUnorm => (astc_ldr, float, linear, (4, 4), 16, basic, 4),
|
||||
Self::Astc4x4RgbaUnormSrgb => (astc_ldr, float, srgb, (4, 4), 16, basic, 4),
|
||||
Self::Astc5x4RgbaUnorm => (astc_ldr, float, linear, (5, 4), 16, basic, 4),
|
||||
Self::Astc5x4RgbaUnormSrgb => (astc_ldr, float, srgb, (5, 4), 16, basic, 4),
|
||||
Self::Astc5x5RgbaUnorm => (astc_ldr, float, linear, (5, 5), 16, basic, 4),
|
||||
Self::Astc5x5RgbaUnormSrgb => (astc_ldr, float, srgb, (5, 5), 16, basic, 4),
|
||||
Self::Astc6x5RgbaUnorm => (astc_ldr, float, linear, (6, 5), 16, basic, 4),
|
||||
Self::Astc6x5RgbaUnormSrgb => (astc_ldr, float, srgb, (6, 5), 16, basic, 4),
|
||||
Self::Astc6x6RgbaUnorm => (astc_ldr, float, linear, (6, 6), 16, basic, 4),
|
||||
Self::Astc6x6RgbaUnormSrgb => (astc_ldr, float, srgb, (6, 6), 16, basic, 4),
|
||||
Self::Astc8x5RgbaUnorm => (astc_ldr, float, linear, (8, 5), 16, basic, 4),
|
||||
Self::Astc8x5RgbaUnormSrgb => (astc_ldr, float, srgb, (8, 5), 16, basic, 4),
|
||||
Self::Astc8x6RgbaUnorm => (astc_ldr, float, linear, (8, 6), 16, basic, 4),
|
||||
Self::Astc8x6RgbaUnormSrgb => (astc_ldr, float, srgb, (8, 6), 16, basic, 4),
|
||||
Self::Astc10x5RgbaUnorm => (astc_ldr, float, linear, (10, 5), 16, basic, 4),
|
||||
Self::Astc10x5RgbaUnormSrgb => (astc_ldr, float, srgb, (10, 5), 16, basic, 4),
|
||||
Self::Astc10x6RgbaUnorm => (astc_ldr, float, linear, (10, 6), 16, basic, 4),
|
||||
Self::Astc10x6RgbaUnormSrgb => (astc_ldr, float, srgb, (10, 6), 16, basic, 4),
|
||||
Self::Astc8x8RgbaUnorm => (astc_ldr, float, linear, (8, 8), 16, basic, 4),
|
||||
Self::Astc8x8RgbaUnormSrgb => (astc_ldr, float, srgb, (8, 8), 16, basic, 4),
|
||||
Self::Astc10x8RgbaUnorm => (astc_ldr, float, linear, (10, 8), 16, basic, 4),
|
||||
Self::Astc10x8RgbaUnormSrgb => (astc_ldr, float, srgb, (10, 8), 16, basic, 4),
|
||||
Self::Astc10x10RgbaUnorm => (astc_ldr, float, linear, (10, 10), 16, basic, 4),
|
||||
Self::Astc10x10RgbaUnormSrgb => (astc_ldr, float, srgb, (10, 10), 16, basic, 4),
|
||||
Self::Astc12x10RgbaUnorm => (astc_ldr, float, linear, (12, 10), 16, basic, 4),
|
||||
Self::Astc12x10RgbaUnormSrgb => (astc_ldr, float, srgb, (12, 10), 16, basic, 4),
|
||||
Self::Astc12x12RgbaUnorm => (astc_ldr, float, linear, (12, 12), 16, basic, 4),
|
||||
Self::Astc12x12RgbaUnormSrgb => (astc_ldr, float, srgb, (12, 12), 16, basic, 4),
|
||||
Self::Astc4x4RgbaUnorm => (astc_ldr, float, linear, noaa, (4, 4), 16, basic, 4),
|
||||
Self::Astc4x4RgbaUnormSrgb => (astc_ldr, float, corrected, noaa, (4, 4), 16, basic, 4),
|
||||
Self::Astc5x4RgbaUnorm => (astc_ldr, float, linear, noaa, (5, 4), 16, basic, 4),
|
||||
Self::Astc5x4RgbaUnormSrgb => (astc_ldr, float, corrected, noaa, (5, 4), 16, basic, 4),
|
||||
Self::Astc5x5RgbaUnorm => (astc_ldr, float, linear, noaa, (5, 5), 16, basic, 4),
|
||||
Self::Astc5x5RgbaUnormSrgb => (astc_ldr, float, corrected, noaa, (5, 5), 16, basic, 4),
|
||||
Self::Astc6x5RgbaUnorm => (astc_ldr, float, linear, noaa, (6, 5), 16, basic, 4),
|
||||
Self::Astc6x5RgbaUnormSrgb => (astc_ldr, float, corrected, noaa, (6, 5), 16, basic, 4),
|
||||
Self::Astc6x6RgbaUnorm => (astc_ldr, float, linear, noaa, (6, 6), 16, basic, 4),
|
||||
Self::Astc6x6RgbaUnormSrgb => (astc_ldr, float, corrected, noaa, (6, 6), 16, basic, 4),
|
||||
Self::Astc8x5RgbaUnorm => (astc_ldr, float, linear, noaa, (8, 5), 16, basic, 4),
|
||||
Self::Astc8x5RgbaUnormSrgb => (astc_ldr, float, corrected, noaa, (8, 5), 16, basic, 4),
|
||||
Self::Astc8x6RgbaUnorm => (astc_ldr, float, linear, noaa, (8, 6), 16, basic, 4),
|
||||
Self::Astc8x6RgbaUnormSrgb => (astc_ldr, float, corrected, noaa, (8, 6), 16, basic, 4),
|
||||
Self::Astc10x5RgbaUnorm => (astc_ldr, float, linear, noaa, (10, 5), 16, basic, 4),
|
||||
Self::Astc10x5RgbaUnormSrgb => {
|
||||
(astc_ldr, float, corrected, noaa, (10, 5), 16, basic, 4)
|
||||
}
|
||||
Self::Astc10x6RgbaUnorm => (astc_ldr, float, linear, noaa, (10, 6), 16, basic, 4),
|
||||
Self::Astc10x6RgbaUnormSrgb => {
|
||||
(astc_ldr, float, corrected, noaa, (10, 6), 16, basic, 4)
|
||||
}
|
||||
Self::Astc8x8RgbaUnorm => (astc_ldr, float, linear, noaa, (8, 8), 16, basic, 4),
|
||||
Self::Astc8x8RgbaUnormSrgb => (astc_ldr, float, corrected, noaa, (8, 8), 16, basic, 4),
|
||||
Self::Astc10x8RgbaUnorm => (astc_ldr, float, linear, noaa, (10, 8), 16, basic, 4),
|
||||
Self::Astc10x8RgbaUnormSrgb => {
|
||||
(astc_ldr, float, corrected, noaa, (10, 8), 16, basic, 4)
|
||||
}
|
||||
Self::Astc10x10RgbaUnorm => (astc_ldr, float, linear, noaa, (10, 10), 16, basic, 4),
|
||||
Self::Astc10x10RgbaUnormSrgb => {
|
||||
(astc_ldr, float, corrected, noaa, (10, 10), 16, basic, 4)
|
||||
}
|
||||
Self::Astc12x10RgbaUnorm => (astc_ldr, float, linear, noaa, (12, 10), 16, basic, 4),
|
||||
Self::Astc12x10RgbaUnormSrgb => {
|
||||
(astc_ldr, float, corrected, noaa, (12, 10), 16, basic, 4)
|
||||
}
|
||||
Self::Astc12x12RgbaUnorm => (astc_ldr, float, linear, noaa, (12, 12), 16, basic, 4),
|
||||
Self::Astc12x12RgbaUnormSrgb => {
|
||||
(astc_ldr, float, corrected, noaa, (12, 12), 16, basic, 4)
|
||||
}
|
||||
|
||||
// Optional normalized 16-bit-per-channel formats
|
||||
Self::R16Unorm => (norm16bit, float, linear, (1, 1), 2, storage, 1),
|
||||
Self::R16Snorm => (norm16bit, float, linear, (1, 1), 2, storage, 1),
|
||||
Self::Rg16Unorm => (norm16bit, float, linear, (1, 1), 4, storage, 2),
|
||||
Self::Rg16Snorm => (norm16bit, float, linear, (1, 1), 4, storage, 2),
|
||||
Self::Rgba16Unorm => (norm16bit, float, linear, (1, 1), 8, storage, 4),
|
||||
Self::Rgba16Snorm => (norm16bit, float, linear, (1, 1), 8, storage, 4),
|
||||
Self::R16Unorm => (norm16bit, float, linear, msaa, (1, 1), 2, storage, 1),
|
||||
Self::R16Snorm => (norm16bit, float, linear, msaa, (1, 1), 2, storage, 1),
|
||||
Self::Rg16Unorm => (norm16bit, float, linear, msaa, (1, 1), 4, storage, 2),
|
||||
Self::Rg16Snorm => (norm16bit, float, linear, msaa, (1, 1), 4, storage, 2),
|
||||
Self::Rgba16Unorm => (norm16bit, float, linear, msaa, (1, 1), 8, storage, 4),
|
||||
Self::Rgba16Snorm => (norm16bit, float, linear, msaa, (1, 1), 8, storage, 4),
|
||||
};
|
||||
|
||||
let mut flags = msaa_flags;
|
||||
flags.set(
|
||||
TextureFormatFeatureFlags::FILTERABLE,
|
||||
sample_type == TextureSampleType::Float { filterable: true },
|
||||
);
|
||||
|
||||
TextureFormatInfo {
|
||||
required_features,
|
||||
sample_type,
|
||||
block_dimensions,
|
||||
block_size,
|
||||
components,
|
||||
srgb,
|
||||
srgb: match color_space {
|
||||
ColorSpace::Linear => false,
|
||||
ColorSpace::Corrected => true,
|
||||
},
|
||||
guaranteed_format_features: TextureFormatFeatures {
|
||||
allowed_usages,
|
||||
flags: TextureFormatFeatureFlags::empty(),
|
||||
filterable: sample_type == TextureSampleType::Float { filterable: true },
|
||||
flags,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user