Pipe viewFormats from ExternalImageDXGI to the texture descriptor
Bug: dawn:1470
Change-Id: I14d93d92a56e1b5c124330a992966feb1ddc0944
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/112241
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Loko Kung <lokokung@google.com>
Commit-Queue: Austin Eng <enga@chromium.org>
diff --git a/src/dawn/native/d3d12/ExternalImageDXGIImpl.cpp b/src/dawn/native/d3d12/ExternalImageDXGIImpl.cpp
index 5ffd1c7..b66a37a 100644
--- a/src/dawn/native/d3d12/ExternalImageDXGIImpl.cpp
+++ b/src/dawn/native/d3d12/ExternalImageDXGIImpl.cpp
@@ -38,7 +38,9 @@
mSize(textureDescriptor->size),
mFormat(textureDescriptor->format),
mMipLevelCount(textureDescriptor->mipLevelCount),
- mSampleCount(textureDescriptor->sampleCount) {
+ mSampleCount(textureDescriptor->sampleCount),
+ mViewFormats(textureDescriptor->viewFormats,
+ textureDescriptor->viewFormats + textureDescriptor->viewFormatCount) {
ASSERT(mBackendDevice != nullptr);
ASSERT(mD3D12Resource != nullptr);
ASSERT(!textureDescriptor->nextInChain || textureDescriptor->nextInChain->sType ==
@@ -84,6 +86,8 @@
textureDescriptor.format = mFormat;
textureDescriptor.mipLevelCount = mMipLevelCount;
textureDescriptor.sampleCount = mSampleCount;
+ textureDescriptor.viewFormats = mViewFormats.data();
+ textureDescriptor.viewFormatCount = static_cast<uint32_t>(mViewFormats.size());
DawnTextureInternalUsageDescriptor internalDesc = {};
if (mUsageInternal != wgpu::TextureUsage::None) {
diff --git a/src/dawn/native/d3d12/ExternalImageDXGIImpl.h b/src/dawn/native/d3d12/ExternalImageDXGIImpl.h
index b3b914c..b989564 100644
--- a/src/dawn/native/d3d12/ExternalImageDXGIImpl.h
+++ b/src/dawn/native/d3d12/ExternalImageDXGIImpl.h
@@ -18,6 +18,7 @@
#include <wrl/client.h>
#include <memory>
+#include <vector>
#include "dawn/common/LinkedList.h"
#include "dawn/dawn_wsi.h"
@@ -71,6 +72,7 @@
wgpu::TextureFormat mFormat;
uint32_t mMipLevelCount;
uint32_t mSampleCount;
+ std::vector<wgpu::TextureFormat> mViewFormats;
};
} // namespace dawn::native::d3d12
diff --git a/src/dawn/tests/end2end/D3D12ResourceWrappingTests.cpp b/src/dawn/tests/end2end/D3D12ResourceWrappingTests.cpp
index 52de5d3..a60e33a 100644
--- a/src/dawn/tests/end2end/D3D12ResourceWrappingTests.cpp
+++ b/src/dawn/tests/end2end/D3D12ResourceWrappingTests.cpp
@@ -1017,6 +1017,47 @@
EXPECT_BUFFER_U32_EQ(kExpected, buffer, 0);
}
+// Test that texture descriptor view formats are passed to the backend for wrapped external
+// textures, and that contents may be reinterpreted as sRGB.
+TEST_P(D3D12SharedHandleUsageTests, SRGBReinterpretation) {
+ DAWN_TEST_UNSUPPORTED_IF(UsesWire());
+
+ wgpu::Texture texture;
+ ComPtr<ID3D11Texture2D> d3d11Texture;
+ std::unique_ptr<dawn::native::d3d12::ExternalImageDXGI> externalImage;
+
+ // The texture will be reinterpreted as sRGB.
+ wgpu::TextureViewDescriptor viewDesc = {};
+ viewDesc.format = wgpu::TextureFormat::RGBA8UnormSrgb;
+
+ wgpu::TextureDescriptor textureDesc = baseDawnDescriptor;
+ textureDesc.viewFormatCount = 1;
+ textureDesc.viewFormats = &viewDesc.format;
+ // Check that the base format is not sRGB.
+ ASSERT_EQ(textureDesc.format, wgpu::TextureFormat::RGBA8Unorm);
+
+ // Wrap a shared handle as a Dawn texture.
+ WrapSharedHandle(&textureDesc, &baseD3dDescriptor, &texture, &d3d11Texture, &externalImage);
+ ASSERT_NE(texture.Get(), nullptr);
+
+ // Submit a clear operation to sRGB value rgb(234, 51, 35).
+ {
+ utils::ComboRenderPassDescriptor renderPassDescriptor({texture.CreateView(&viewDesc)}, {});
+ renderPassDescriptor.cColorAttachments[0].clearValue = {234.0 / 255.0, 51.0 / 255.0,
+ 35.0 / 255.0, 1.0};
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ encoder.BeginRenderPass(&renderPassDescriptor).End();
+
+ wgpu::CommandBuffer commands = encoder.Finish();
+ queue.Submit(1, &commands);
+ }
+
+ // Expect the contents to be approximately rgb(246 124 104)
+ EXPECT_PIXEL_RGBA8_BETWEEN( //
+ utils::RGBA8(245, 123, 103, 255), //
+ utils::RGBA8(247, 125, 105, 255), texture, 0, 0);
+}
+
DAWN_INSTANTIATE_TEST_P(D3D12SharedHandleValidation,
{D3D12Backend()},
{SyncMode::kKeyedMutex, SyncMode::kFence});