From bdfa46807f014dfd9073b0d122a6e780d1274b00 Mon Sep 17 00:00:00 2001 From: dtzxporter Date: Thu, 4 Jan 2024 17:23:49 -0500 Subject: [PATCH 1/2] Fix row calculation in `Queue::write_texture`. Fix row calculation in `Queue::write_texture`. The D3D12_SUBRESOURCE_FOOTPRINT was calculated incorrectly by multiplying the height by the block count. DirectX automatically takes format into account because it's passed into the footprint. Only the block width is necessary to compute the pitch or linear size. This prevents a crash when using `Queue::write_texture` with a block compressed texture. --- CHANGELOG.md | 4 ++++ wgpu-core/src/device/queue.rs | 2 +- wgpu-hal/src/dx12/command.rs | 7 ++----- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e4cae9ca0..3bd13e24ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -182,6 +182,10 @@ Passing an owned value `window` to `Surface` will return a `Surface<'static>`. S - Align `wgpu_types::CompositeAlphaMode` serde serialization to spec. By @littledivy in [#4940](https://github.com/gfx-rs/wgpu/pull/4940) - Fix error message of `ConfigureSurfaceError::TooLarge`. By @Dinnerbone in [#4960](https://github.com/gfx-rs/wgpu/pull/4960) +#### DX12 + +- Fixed D3D12_SUBRESOURCE_FOOTPRINT calculation for block compressed textures which caused a crash with `Queue::write_texture` on DX12. By @DTZxPorter in [#4990](https://github.com/gfx-rs/wgpu/pull/4990) + #### Vulkan - Use `VK_EXT_robustness2` only when not using an outdated intel iGPU driver. By @TheoDulka in [#4602](https://github.com/gfx-rs/wgpu/pull/4602). diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 1b895a2183..c9bc190942 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -740,7 +740,7 @@ impl Global { // doesn't really matter because we need this only if we copy // more than one layer, and then we validate for this being not // None - size.height, + height_blocks, ); let block_size = dst diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index c5d0d16b2c..3d05813ed7 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -20,7 +20,7 @@ impl crate::BufferTextureCopy { &self, format: wgt::TextureFormat, ) -> d3d12_ty::D3D12_PLACED_SUBRESOURCE_FOOTPRINT { - let (block_width, block_height) = format.block_dimensions(); + let (block_width, _) = format.block_dimensions(); d3d12_ty::D3D12_PLACED_SUBRESOURCE_FOOTPRINT { Offset: self.buffer_layout.offset, Footprint: d3d12_ty::D3D12_SUBRESOURCE_FOOTPRINT { @@ -30,10 +30,7 @@ impl crate::BufferTextureCopy { ) .unwrap(), Width: self.size.width, - Height: self - .buffer_layout - .rows_per_image - .map_or(self.size.height, |count| count * block_height), + Height: self.size.height, Depth: self.size.depth, RowPitch: { let actual = self.buffer_layout.bytes_per_row.unwrap_or_else(|| { From 4e75e5f95b1d2dc653cc862dccaf151e4b2a6614 Mon Sep 17 00:00:00 2001 From: dtzxporter Date: Thu, 4 Jan 2024 18:22:51 -0500 Subject: [PATCH 2/2] Enable `write_texture_subset_2d` test for DX12 now that it passes. --- tests/tests/write_texture.rs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/tests/tests/write_texture.rs b/tests/tests/write_texture.rs index 967d76be8c..c6f431737c 100644 --- a/tests/tests/write_texture.rs +++ b/tests/tests/write_texture.rs @@ -1,17 +1,10 @@ //! Tests for texture copy -use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters}; +use wgpu_test::{gpu_test, GpuTestConfiguration}; #[gpu_test] -static WRITE_TEXTURE_SUBSET_2D: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters( - TestParameters::default() - // This just totally removes the device due to invalid api call. - // - // https://github.com/gfx-rs/wgpu/issues/3072 - .expect_fail(FailureCase::backend(wgpu::Backends::DX12)), - ) - .run_sync(|ctx| { +static WRITE_TEXTURE_SUBSET_2D: GpuTestConfiguration = + GpuTestConfiguration::new().run_sync(|ctx| { let size = 256; let tex = ctx.device.create_texture(&wgpu::TextureDescriptor {