mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 08:45:46 +00:00
Bug 1572843 - WR swizzling part-2 r=gw
This is a medium-size follow-up to D21965. Refactors the use of swizzling by the texture cache. Adds a device capability flag that is checked at run-time. Also makes the texture cache to communicate with the texture uploader if there is a format conversion needed, which fixes the case on platforms that don't support swizzling. Differential Revision: https://phabricator.services.mozilla.com/D41446 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
dc10950243
commit
0aa1247a1e
@ -8,7 +8,7 @@ use api::{MixBlendMode, TextureTarget, VoidPtrToSizeFn};
|
||||
use api::units::*;
|
||||
use euclid::default::Transform3D;
|
||||
use gleam::gl;
|
||||
use crate::internal_types::{FastHashMap, LayerIndex, RenderTargetInfo, Swizzle};
|
||||
use crate::internal_types::{FastHashMap, LayerIndex, RenderTargetInfo, Swizzle, SwizzleSettings};
|
||||
use crate::util::round_up_to_multiple;
|
||||
use crate::profiler;
|
||||
use log::Level;
|
||||
@ -940,6 +940,8 @@ pub struct Capabilities {
|
||||
/// Whether KHR_debug is supported for getting debug messages from
|
||||
/// the driver.
|
||||
pub supports_khr_debug: bool,
|
||||
/// Whether we can configure texture units to do swizzling on sampling.
|
||||
pub supports_texture_swizzle: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -973,6 +975,7 @@ enum TexStorageUsage {
|
||||
Always,
|
||||
}
|
||||
|
||||
|
||||
pub struct Device {
|
||||
gl: Rc<dyn gl::Gl>,
|
||||
|
||||
@ -1001,8 +1004,7 @@ pub struct Device {
|
||||
|
||||
color_formats: TextureFormatPair<ImageFormat>,
|
||||
bgra_formats: TextureFormatPair<gl::GLuint>,
|
||||
// the swizzle required on sampling a texture with `TextureFormat::BGRA` format
|
||||
bgra_swizzle: Swizzle,
|
||||
swizzle_settings: SwizzleSettings,
|
||||
|
||||
/// Map from texture dimensions to shared depth buffers for render targets.
|
||||
///
|
||||
@ -1300,7 +1302,7 @@ impl Device {
|
||||
// GL_EXT_texture_storage and GL_EXT_texture_format_BGRA8888.
|
||||
let supports_gles_bgra = supports_extension(&extensions, "GL_EXT_texture_format_BGRA8888");
|
||||
|
||||
let (color_formats, bgra_formats, bgra_swizzle, texture_storage_usage) = match gl.get_type() {
|
||||
let (color_formats, bgra_formats, bgra8_sampling_swizzle, texture_storage_usage) = match gl.get_type() {
|
||||
// There is `glTexStorage`, use it and expect RGBA on the input.
|
||||
gl::GlType::Gl if
|
||||
allow_texture_storage_support &&
|
||||
@ -1354,7 +1356,7 @@ impl Device {
|
||||
};
|
||||
|
||||
info!("GL texture cache {:?}, bgra {:?} swizzle {:?}, texture storage {:?}",
|
||||
color_formats, bgra_formats, bgra_swizzle, texture_storage_usage);
|
||||
color_formats, bgra_formats, bgra8_sampling_swizzle, texture_storage_usage);
|
||||
let supports_copy_image_sub_data = supports_extension(&extensions, "GL_EXT_copy_image") ||
|
||||
supports_extension(&extensions, "GL_ARB_copy_image");
|
||||
|
||||
@ -1380,6 +1382,9 @@ impl Device {
|
||||
supports_extension(&extensions, "GL_KHR_blend_equation_advanced") &&
|
||||
!renderer_name.starts_with("Adreno");
|
||||
|
||||
let supports_texture_swizzle = allow_texture_swizzling &&
|
||||
(gl.get_type() == gl::GlType::Gles || supports_extension(&extensions, "GL_ARB_texture_storage"));
|
||||
|
||||
// On Adreno GPUs PBO texture upload is only performed asynchronously
|
||||
// if the stride of the data in the PBO is a multiple of 256 bytes.
|
||||
// Other platforms may have similar requirements and should be added
|
||||
@ -1405,11 +1410,14 @@ impl Device {
|
||||
supports_pixel_local_storage,
|
||||
supports_advanced_blend_equation,
|
||||
supports_khr_debug,
|
||||
supports_texture_swizzle,
|
||||
},
|
||||
|
||||
color_formats,
|
||||
bgra_formats,
|
||||
bgra_swizzle,
|
||||
swizzle_settings: SwizzleSettings {
|
||||
bgra8_sampling_swizzle,
|
||||
},
|
||||
|
||||
depth_targets: FastHashMap::default(),
|
||||
|
||||
@ -1473,8 +1481,12 @@ impl Device {
|
||||
self.color_formats.clone()
|
||||
}
|
||||
|
||||
pub fn bgra_swizzle(&self) -> Swizzle {
|
||||
self.bgra_swizzle
|
||||
pub fn swizzle_settings(&self) -> Option<SwizzleSettings> {
|
||||
if self.capabilities.supports_texture_swizzle {
|
||||
Some(self.swizzle_settings)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_optimal_pbo_stride(&self) -> NonZeroUsize {
|
||||
@ -1606,14 +1618,18 @@ impl Device {
|
||||
self.gl.active_texture(gl::TEXTURE0 + slot.0 as gl::GLuint);
|
||||
self.gl.bind_texture(target, id);
|
||||
if let Some(swizzle) = set_swizzle {
|
||||
let components = match swizzle {
|
||||
Swizzle::Rgba => [gl::RED, gl::GREEN, gl::BLUE, gl::ALPHA],
|
||||
Swizzle::Bgra => [gl::BLUE, gl::GREEN, gl::RED, gl::ALPHA],
|
||||
};
|
||||
self.gl.tex_parameter_i(target, gl::TEXTURE_SWIZZLE_R, components[0] as i32);
|
||||
self.gl.tex_parameter_i(target, gl::TEXTURE_SWIZZLE_G, components[1] as i32);
|
||||
self.gl.tex_parameter_i(target, gl::TEXTURE_SWIZZLE_B, components[2] as i32);
|
||||
self.gl.tex_parameter_i(target, gl::TEXTURE_SWIZZLE_A, components[3] as i32);
|
||||
if self.capabilities.supports_texture_swizzle {
|
||||
let components = match swizzle {
|
||||
Swizzle::Rgba => [gl::RED, gl::GREEN, gl::BLUE, gl::ALPHA],
|
||||
Swizzle::Bgra => [gl::BLUE, gl::GREEN, gl::RED, gl::ALPHA],
|
||||
};
|
||||
self.gl.tex_parameter_i(target, gl::TEXTURE_SWIZZLE_R, components[0] as i32);
|
||||
self.gl.tex_parameter_i(target, gl::TEXTURE_SWIZZLE_G, components[1] as i32);
|
||||
self.gl.tex_parameter_i(target, gl::TEXTURE_SWIZZLE_B, components[2] as i32);
|
||||
self.gl.tex_parameter_i(target, gl::TEXTURE_SWIZZLE_A, components[3] as i32);
|
||||
} else {
|
||||
debug_assert_eq!(swizzle, Swizzle::default());
|
||||
}
|
||||
}
|
||||
self.gl.active_texture(gl::TEXTURE0);
|
||||
self.bound_textures[slot.0] = id;
|
||||
@ -3393,6 +3409,7 @@ struct UploadChunk {
|
||||
layer_index: i32,
|
||||
stride: Option<i32>,
|
||||
offset: usize,
|
||||
format_override: Option<ImageFormat>,
|
||||
}
|
||||
|
||||
struct PixelBuffer {
|
||||
@ -3447,6 +3464,7 @@ impl<'a, T> TextureUploader<'a, T> {
|
||||
mut rect: DeviceIntRect,
|
||||
layer_index: i32,
|
||||
stride: Option<i32>,
|
||||
format_override: Option<ImageFormat>,
|
||||
data: &[T],
|
||||
) -> usize {
|
||||
// Textures dimensions may have been clamped by the hardware. Crop the
|
||||
@ -3538,15 +3556,21 @@ impl<'a, T> TextureUploader<'a, T> {
|
||||
}
|
||||
|
||||
buffer.chunks.push(UploadChunk {
|
||||
rect, layer_index, stride: Some(dst_stride as i32),
|
||||
rect,
|
||||
layer_index,
|
||||
stride: Some(dst_stride as i32),
|
||||
offset: buffer.size_used,
|
||||
format_override,
|
||||
});
|
||||
buffer.size_used += dst_size;
|
||||
}
|
||||
None => {
|
||||
self.target.update_impl(UploadChunk {
|
||||
rect, layer_index, stride,
|
||||
rect,
|
||||
layer_index,
|
||||
stride,
|
||||
offset: data.as_ptr() as _,
|
||||
format_override,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -3557,7 +3581,8 @@ impl<'a, T> TextureUploader<'a, T> {
|
||||
|
||||
impl<'a> UploadTarget<'a> {
|
||||
fn update_impl(&mut self, chunk: UploadChunk) {
|
||||
let (gl_format, bpp, data_type) = match self.texture.format {
|
||||
let format = chunk.format_override.unwrap_or(self.texture.format);
|
||||
let (gl_format, bpp, data_type) = match format {
|
||||
ImageFormat::R8 => (gl::RED, 1, gl::UNSIGNED_BYTE),
|
||||
ImageFormat::R16 => (gl::RED, 2, gl::UNSIGNED_SHORT),
|
||||
ImageFormat::BGRA8 => (self.bgra_format, 4, gl::UNSIGNED_BYTE),
|
||||
|
@ -175,6 +175,15 @@ impl Default for Swizzle {
|
||||
}
|
||||
}
|
||||
|
||||
/// Swizzle settings of the texture cache.
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq)]
|
||||
pub struct SwizzleSettings {
|
||||
/// Swizzle required on sampling a texture with BGRA8 format.
|
||||
pub bgra8_sampling_swizzle: Swizzle,
|
||||
}
|
||||
|
||||
/// An ID for a texture that is owned by the `texture_cache` module.
|
||||
///
|
||||
/// This can include atlases or standalone textures allocated via the texture
|
||||
@ -307,6 +316,7 @@ pub struct TextureCacheUpdate {
|
||||
pub stride: Option<i32>,
|
||||
pub offset: i32,
|
||||
pub layer_index: i32,
|
||||
pub format_override: Option<ImageFormat>,
|
||||
pub source: TextureUpdateSource,
|
||||
}
|
||||
|
||||
@ -364,10 +374,11 @@ impl TextureUpdateList {
|
||||
self.push_update(TextureCacheUpdate {
|
||||
id,
|
||||
rect,
|
||||
source: TextureUpdateSource::DebugClear,
|
||||
stride: None,
|
||||
offset: 0,
|
||||
layer_index: layer_index as i32,
|
||||
format_override: None,
|
||||
source: TextureUpdateSource::DebugClear,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1468,7 +1468,7 @@ impl GpuCacheTexture {
|
||||
DeviceIntSize::new(MAX_VERTEX_TEXTURE_WIDTH as i32, 1),
|
||||
);
|
||||
|
||||
uploader.upload(rect, 0, None, &*row.cpu_blocks);
|
||||
uploader.upload(rect, 0, None, None, &*row.cpu_blocks);
|
||||
|
||||
row.is_dirty = false;
|
||||
}
|
||||
@ -1592,7 +1592,7 @@ impl<T> VertexDataTexture<T> {
|
||||
);
|
||||
device
|
||||
.upload_texture(self.texture(), &self.pbo, 0)
|
||||
.upload(rect, 0, None, data);
|
||||
.upload(rect, 0, None, None, data);
|
||||
}
|
||||
|
||||
fn deinit(mut self, device: &mut Device) {
|
||||
@ -1858,7 +1858,7 @@ impl Renderer {
|
||||
);
|
||||
|
||||
let color_cache_formats = device.preferred_color_formats();
|
||||
let bgra_swizzle = device.bgra_swizzle();
|
||||
let swizzle_settings = device.swizzle_settings();
|
||||
let supports_dual_source_blending = match gl_type {
|
||||
gl::GlType::Gl => device.supports_extension("GL_ARB_blend_func_extended") &&
|
||||
device.supports_extension("GL_ARB_explicit_attrib_location"),
|
||||
@ -2166,7 +2166,7 @@ impl Renderer {
|
||||
},
|
||||
start_size,
|
||||
color_cache_formats,
|
||||
bgra_swizzle,
|
||||
swizzle_settings,
|
||||
);
|
||||
|
||||
let glyph_cache = GlyphCache::new(max_glyph_cache_size);
|
||||
@ -3168,7 +3168,7 @@ impl Renderer {
|
||||
}
|
||||
|
||||
for update in update_list.updates {
|
||||
let TextureCacheUpdate { id, rect, stride, offset, layer_index, source } = update;
|
||||
let TextureCacheUpdate { id, rect, stride, offset, layer_index, format_override, source } = update;
|
||||
let texture = &self.texture_resolver.texture_cache_map[&id];
|
||||
|
||||
let bytes_uploaded = match source {
|
||||
@ -3179,7 +3179,10 @@ impl Renderer {
|
||||
0,
|
||||
);
|
||||
uploader.upload(
|
||||
rect, layer_index, stride,
|
||||
rect,
|
||||
layer_index,
|
||||
stride,
|
||||
format_override,
|
||||
&data[offset as usize ..],
|
||||
)
|
||||
}
|
||||
@ -3193,12 +3196,10 @@ impl Renderer {
|
||||
.as_mut()
|
||||
.expect("Found external image, but no handler set!");
|
||||
// The filter is only relevant for NativeTexture external images.
|
||||
let size = match handler.lock(id, channel_index, ImageRendering::Auto).source {
|
||||
let dummy_data;
|
||||
let data = match handler.lock(id, channel_index, ImageRendering::Auto).source {
|
||||
ExternalImageSource::RawData(data) => {
|
||||
uploader.upload(
|
||||
rect, layer_index, stride,
|
||||
&data[offset as usize ..],
|
||||
)
|
||||
&data[offset as usize ..]
|
||||
}
|
||||
ExternalImageSource::Invalid => {
|
||||
// Create a local buffer to fill the pbo.
|
||||
@ -3207,13 +3208,20 @@ impl Renderer {
|
||||
let total_size = width * rect.size.height;
|
||||
// WR haven't support RGBAF32 format in texture_cache, so
|
||||
// we use u8 type here.
|
||||
let dummy_data: Vec<u8> = vec![255; total_size as usize];
|
||||
uploader.upload(rect, layer_index, stride, &dummy_data)
|
||||
dummy_data = vec![0xFFu8; total_size as usize];
|
||||
&dummy_data
|
||||
}
|
||||
ExternalImageSource::NativeTexture(eid) => {
|
||||
panic!("Unexpected external texture {:?} for the texture cache update of {:?}", eid, id);
|
||||
}
|
||||
};
|
||||
let size = uploader.upload(
|
||||
rect,
|
||||
layer_index,
|
||||
stride,
|
||||
format_override,
|
||||
data,
|
||||
);
|
||||
handler.unlock(id, channel_index);
|
||||
size
|
||||
}
|
||||
|
@ -2204,7 +2204,7 @@ impl ResourceCache {
|
||||
&self.texture_cache.picture_tile_sizes(),
|
||||
DeviceIntSize::zero(),
|
||||
self.texture_cache.color_formats(),
|
||||
self.texture_cache.bgra_swizzle(),
|
||||
self.texture_cache.swizzle_settings(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ use crate::freelist::{FreeList, FreeListHandle, UpsertResult, WeakFreeListHandle
|
||||
use crate::gpu_cache::{GpuCache, GpuCacheHandle};
|
||||
use crate::gpu_types::{ImageSource, UvRectKind};
|
||||
use crate::internal_types::{
|
||||
CacheTextureId, FastHashMap, LayerIndex, Swizzle,
|
||||
CacheTextureId, FastHashMap, LayerIndex, Swizzle, SwizzleSettings,
|
||||
TextureUpdateList, TextureUpdateSource, TextureSource,
|
||||
TextureCacheAllocInfo, TextureCacheUpdate,
|
||||
};
|
||||
@ -173,6 +173,14 @@ impl CacheEntry {
|
||||
eviction_notice.notify();
|
||||
}
|
||||
}
|
||||
|
||||
fn alternative_input_format(&self) -> ImageFormat {
|
||||
match self.input_format {
|
||||
ImageFormat::RGBA8 => ImageFormat::BGRA8,
|
||||
ImageFormat::BGRA8 => ImageFormat::RGBA8,
|
||||
other => other,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -299,31 +307,23 @@ impl SharedTextures {
|
||||
/// Returns a mutable borrow for the shared texture array matching the parameters.
|
||||
fn select(
|
||||
&mut self, external_format: ImageFormat, filter: TextureFilter
|
||||
) -> (&mut TextureArray, Swizzle) {
|
||||
) -> &mut TextureArray {
|
||||
match external_format {
|
||||
ImageFormat::R8 => {
|
||||
assert_eq!(filter, TextureFilter::Linear);
|
||||
(&mut self.array_alpha8_linear, Swizzle::default())
|
||||
&mut self.array_alpha8_linear
|
||||
}
|
||||
ImageFormat::R16 => {
|
||||
assert_eq!(filter, TextureFilter::Linear);
|
||||
(&mut self.array_alpha16_linear, Swizzle::default())
|
||||
&mut self.array_alpha16_linear
|
||||
}
|
||||
ImageFormat::RGBA8 |
|
||||
ImageFormat::BGRA8 => {
|
||||
let array = match filter {
|
||||
match filter {
|
||||
TextureFilter::Linear => &mut self.array_color8_linear,
|
||||
TextureFilter::Nearest => &mut self.array_color8_nearest,
|
||||
_ => panic!("Unexpexcted filter {:?}", filter),
|
||||
};
|
||||
let swizzle = if array.formats.external == external_format {
|
||||
Swizzle::default()
|
||||
} else {
|
||||
// TODO: figure out how to check this properly
|
||||
//assert_eq!(array.formats.internal, external_format);
|
||||
Swizzle::Bgra
|
||||
};
|
||||
(array, swizzle)
|
||||
}
|
||||
}
|
||||
_ => panic!("Unexpected format {:?}", external_format),
|
||||
}
|
||||
@ -517,8 +517,8 @@ pub struct TextureCache {
|
||||
/// Maximum number of texture layers supported by hardware.
|
||||
max_texture_layers: usize,
|
||||
|
||||
/// Swizzle required on sampling a texture with BGRA8 format.
|
||||
bgra_swizzle: Swizzle,
|
||||
/// Settings on using texture unit swizzling.
|
||||
swizzle: Option<SwizzleSettings>,
|
||||
|
||||
/// The current set of debug flags.
|
||||
debug_flags: DebugFlags,
|
||||
@ -564,7 +564,7 @@ impl TextureCache {
|
||||
picture_tile_sizes: &[DeviceIntSize],
|
||||
initial_size: DeviceIntSize,
|
||||
color_formats: TextureFormatPair<ImageFormat>,
|
||||
bgra_swizzle: Swizzle,
|
||||
swizzle: Option<SwizzleSettings>,
|
||||
) -> Self {
|
||||
if cfg!(target_os = "macos") {
|
||||
// On MBP integrated Intel GPUs, texture arrays appear to be
|
||||
@ -622,7 +622,9 @@ impl TextureCache {
|
||||
// Shared texture cache controls swizzling on a per-entry basis, assuming that
|
||||
// the texture as a whole doesn't need to be swizzled (but only some entries do).
|
||||
// It would be possible to support this, but not needed at the moment.
|
||||
assert!(color_formats.internal != ImageFormat::BGRA8 || bgra_swizzle == Swizzle::default());
|
||||
assert!(color_formats.internal != ImageFormat::BGRA8 ||
|
||||
swizzle.map_or(true, |s| s.bgra8_sampling_swizzle == Swizzle::default())
|
||||
);
|
||||
|
||||
TextureCache {
|
||||
shared_textures: SharedTextures::new(color_formats),
|
||||
@ -631,7 +633,7 @@ impl TextureCache {
|
||||
entries: FreeList::new(),
|
||||
max_texture_size,
|
||||
max_texture_layers,
|
||||
bgra_swizzle,
|
||||
swizzle,
|
||||
debug_flags: DebugFlags::empty(),
|
||||
next_id: CacheTextureId(next_texture_id),
|
||||
pending_updates,
|
||||
@ -657,7 +659,7 @@ impl TextureCache {
|
||||
&[],
|
||||
DeviceIntSize::zero(),
|
||||
TextureFormatPair::from(image_format),
|
||||
Swizzle::default(),
|
||||
None,
|
||||
);
|
||||
let mut now = FrameStamp::first(DocumentId::new(IdNamespace(1), 1));
|
||||
now.advance();
|
||||
@ -887,8 +889,8 @@ impl TextureCache {
|
||||
}
|
||||
|
||||
#[cfg(feature = "replay")]
|
||||
pub fn bgra_swizzle(&self) -> Swizzle {
|
||||
self.bgra_swizzle
|
||||
pub fn swizzle_settings(&self) -> Option<SwizzleSettings> {
|
||||
self.swizzle
|
||||
}
|
||||
|
||||
pub fn pending_updates(&mut self) -> TextureUpdateList {
|
||||
@ -919,7 +921,8 @@ impl TextureCache {
|
||||
// - Exists in the cache but dimensions / format have changed.
|
||||
let realloc = match self.entries.get_opt(handle) {
|
||||
Some(entry) => {
|
||||
entry.size != descriptor.size || entry.input_format != descriptor.format
|
||||
entry.size != descriptor.size || (entry.input_format != descriptor.format &&
|
||||
entry.alternative_input_format() != descriptor.format)
|
||||
}
|
||||
None => {
|
||||
// Not allocated, or was previously allocated but has been evicted.
|
||||
@ -957,6 +960,10 @@ impl TextureCache {
|
||||
// to upload the new image data into the correct location
|
||||
// in GPU memory.
|
||||
if let Some(data) = data {
|
||||
// If the swizzling is supported, we always upload in the internal
|
||||
// texture format (thus avoiding the conversion by the driver).
|
||||
// Otherwise, pass the external format to the driver.
|
||||
let use_upload_format = !self.swizzle.is_some();
|
||||
let (layer_index, origin) = entry.details.describe();
|
||||
let op = TextureCacheUpdate::new_update(
|
||||
data,
|
||||
@ -965,6 +972,7 @@ impl TextureCache {
|
||||
entry.size,
|
||||
entry.texture_id,
|
||||
layer_index as i32,
|
||||
use_upload_format,
|
||||
&dirty_rect,
|
||||
);
|
||||
self.pending_updates.push_update(op);
|
||||
@ -1130,7 +1138,7 @@ impl TextureCache {
|
||||
}
|
||||
EntryDetails::Cache { origin, layer_index } => {
|
||||
// Free the block in the given region.
|
||||
let (texture_array, _swizzle) = self.shared_textures.select(entry.input_format, entry.filter);
|
||||
let texture_array = self.shared_textures.select(entry.input_format, entry.filter);
|
||||
let unit = texture_array.units
|
||||
.iter_mut()
|
||||
.find(|unit| unit.texture_id == entry.texture_id)
|
||||
@ -1159,7 +1167,7 @@ impl TextureCache {
|
||||
&mut self,
|
||||
params: &CacheAllocParams,
|
||||
) -> bool {
|
||||
let (texture_array, _swizzle) = self.shared_textures.select(
|
||||
let texture_array = self.shared_textures.select(
|
||||
params.descriptor.format,
|
||||
params.filter,
|
||||
);
|
||||
@ -1175,10 +1183,18 @@ impl TextureCache {
|
||||
params: &CacheAllocParams,
|
||||
) -> CacheEntry {
|
||||
// Mutably borrow the correct texture.
|
||||
let (texture_array, swizzle) = self.shared_textures.select(
|
||||
let texture_array = self.shared_textures.select(
|
||||
params.descriptor.format,
|
||||
params.filter,
|
||||
);
|
||||
let swizzle = if texture_array.formats.external == params.descriptor.format {
|
||||
Swizzle::default()
|
||||
} else {
|
||||
match self.swizzle {
|
||||
Some(_) => Swizzle::Bgra,
|
||||
None => Swizzle::default(),
|
||||
}
|
||||
};
|
||||
|
||||
let max_texture_layers = self.max_texture_layers;
|
||||
let slab_size = SlabSize::new(params.descriptor.size);
|
||||
@ -1277,16 +1293,16 @@ impl TextureCache {
|
||||
|
||||
// Special handing for BGRA8 textures that may need to be swizzled.
|
||||
let swizzle = if params.descriptor.format == ImageFormat::BGRA8 {
|
||||
self.bgra_swizzle
|
||||
self.swizzle.map(|s| s.bgra8_sampling_swizzle)
|
||||
} else {
|
||||
Swizzle::default()
|
||||
None
|
||||
};
|
||||
|
||||
CacheEntry::new_standalone(
|
||||
texture_id,
|
||||
self.now,
|
||||
params,
|
||||
swizzle,
|
||||
swizzle.unwrap_or_default(),
|
||||
)
|
||||
}
|
||||
|
||||
@ -1823,6 +1839,7 @@ impl TextureCacheUpdate {
|
||||
size: DeviceIntSize,
|
||||
texture_id: CacheTextureId,
|
||||
layer_index: i32,
|
||||
use_upload_format: bool,
|
||||
dirty_rect: &ImageDirtyRect,
|
||||
) -> TextureCacheUpdate {
|
||||
let source = match data {
|
||||
@ -1847,8 +1864,13 @@ impl TextureCacheUpdate {
|
||||
TextureUpdateSource::Bytes { data: bytes }
|
||||
}
|
||||
};
|
||||
let format_override = if use_upload_format {
|
||||
Some(descriptor.format)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let update_op = match *dirty_rect {
|
||||
match *dirty_rect {
|
||||
DirtyRect::Partial(dirty) => {
|
||||
// the dirty rectangle doesn't have to be within the area but has to intersect it, at least
|
||||
let stride = descriptor.compute_stride();
|
||||
@ -1866,6 +1888,7 @@ impl TextureCacheUpdate {
|
||||
source,
|
||||
stride: Some(stride),
|
||||
offset,
|
||||
format_override,
|
||||
layer_index,
|
||||
}
|
||||
}
|
||||
@ -1876,12 +1899,11 @@ impl TextureCacheUpdate {
|
||||
source,
|
||||
stride: descriptor.stride,
|
||||
offset: descriptor.offset,
|
||||
format_override,
|
||||
layer_index,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
update_op
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -948,7 +948,7 @@ impl RenderPass {
|
||||
kind: RenderPassKind::OffScreen {
|
||||
color: RenderTargetList::new(
|
||||
screen_size,
|
||||
ImageFormat::BGRA8,
|
||||
ImageFormat::RGBA8,
|
||||
gpu_supports_fast_clears,
|
||||
),
|
||||
alpha: RenderTargetList::new(
|
||||
|
@ -807,9 +807,10 @@ impl YamlFrameWriter {
|
||||
);
|
||||
|
||||
assert!(data.stride > 0);
|
||||
let (color_type, bpp) = match data.format {
|
||||
ImageFormat::BGRA8 => (ColorType::RGBA(8), 4),
|
||||
ImageFormat::R8 => (ColorType::Gray(8), 1),
|
||||
let (color_type, bpp, do_unpremultiply) = match data.format {
|
||||
ImageFormat::RGBA8 |
|
||||
ImageFormat::BGRA8 => (ColorType::RGBA(8), 4, true),
|
||||
ImageFormat::R8 => (ColorType::Gray(8), 1, false),
|
||||
_ => {
|
||||
println!(
|
||||
"Failed to write image with format {:?}, dimensions {}x{}, stride {}",
|
||||
@ -823,7 +824,7 @@ impl YamlFrameWriter {
|
||||
};
|
||||
|
||||
if data.stride == data.width * bpp {
|
||||
if data.format == ImageFormat::BGRA8 {
|
||||
if do_unpremultiply {
|
||||
unpremultiply(bytes.as_mut_slice());
|
||||
}
|
||||
save_buffer(
|
||||
@ -842,7 +843,7 @@ impl YamlFrameWriter {
|
||||
chunk[.. (data.width * bpp) as usize].iter().cloned()
|
||||
})
|
||||
.collect();
|
||||
if data.format == ImageFormat::BGRA8 {
|
||||
if do_unpremultiply {
|
||||
unpremultiply(tmp.as_mut_slice());
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user