Respect external clear status for Textures
Use ExternalImageDescriptor->isCleared to set the clear status of subresources so it can be correctly lazy cleared when used. Also remove old Wrap path that uses regular texture descriptors since we have moved to use ExternalImageDescriptor. Bug: chromium:1036080 Change-Id: Icb605dbf3cf3f0dc8a30287e8b9b8d9134805112 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/16320 Commit-Queue: Natasha Lee <natlee@microsoft.com> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
2538aaf304
commit
7d20b44501
|
@ -58,15 +58,4 @@ namespace dawn_native { namespace d3d12 {
|
||||||
return reinterpret_cast<WGPUTexture>(texture);
|
return reinterpret_cast<WGPUTexture>(texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
WGPUTexture WrapSharedHandle(WGPUDevice device,
|
|
||||||
const WGPUTextureDescriptor* descriptor,
|
|
||||||
HANDLE sharedHandle,
|
|
||||||
uint64_t acquireMutexKey) {
|
|
||||||
Device* backendDevice = reinterpret_cast<Device*>(device);
|
|
||||||
ExternalImageDescriptorDXGISharedHandle externalDescriptor = {};
|
|
||||||
externalDescriptor.cTextureDescriptor = descriptor;
|
|
||||||
TextureBase* texture =
|
|
||||||
backendDevice->WrapSharedHandle(&externalDescriptor, sharedHandle, acquireMutexKey);
|
|
||||||
return reinterpret_cast<WGPUTexture>(texture);
|
|
||||||
}
|
|
||||||
}} // namespace dawn_native::d3d12
|
}} // namespace dawn_native::d3d12
|
||||||
|
|
|
@ -290,6 +290,10 @@ namespace dawn_native { namespace d3d12 {
|
||||||
AcquireRef(new Texture(device, textureDescriptor, TextureState::OwnedExternal));
|
AcquireRef(new Texture(device, textureDescriptor, TextureState::OwnedExternal));
|
||||||
DAWN_TRY(dawnTexture->InitializeAsExternalTexture(textureDescriptor, sharedHandle,
|
DAWN_TRY(dawnTexture->InitializeAsExternalTexture(textureDescriptor, sharedHandle,
|
||||||
acquireMutexKey));
|
acquireMutexKey));
|
||||||
|
|
||||||
|
dawnTexture->SetIsSubresourceContentInitialized(descriptor->isCleared, 0,
|
||||||
|
textureDescriptor->mipLevelCount, 0,
|
||||||
|
textureDescriptor->arrayLayerCount);
|
||||||
return dawnTexture.Detach();
|
return dawnTexture.Detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,9 +325,6 @@ namespace dawn_native { namespace d3d12 {
|
||||||
info.mMethod = AllocationMethod::kDirect;
|
info.mMethod = AllocationMethod::kDirect;
|
||||||
mResourceAllocation = {info, 0, std::move(d3d12Resource)};
|
mResourceAllocation = {info, 0, std::move(d3d12Resource)};
|
||||||
|
|
||||||
SetIsSubresourceContentInitialized(true, 0, descriptor->mipLevelCount, 0,
|
|
||||||
descriptor->arrayLayerCount);
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,18 +39,6 @@ namespace dawn_native { namespace metal {
|
||||||
return reinterpret_cast<WGPUTexture>(texture);
|
return reinterpret_cast<WGPUTexture>(texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
WGPUTexture WrapIOSurface(WGPUDevice cDevice,
|
|
||||||
const WGPUTextureDescriptor* cDescriptor,
|
|
||||||
IOSurfaceRef ioSurface,
|
|
||||||
uint32_t plane) {
|
|
||||||
Device* device = reinterpret_cast<Device*>(cDevice);
|
|
||||||
ExternalImageDescriptorIOSurface descriptor = {};
|
|
||||||
descriptor.cTextureDescriptor = cDescriptor;
|
|
||||||
TextureBase* texture =
|
|
||||||
device->CreateTextureWrappingIOSurface(&descriptor, ioSurface, plane);
|
|
||||||
return reinterpret_cast<WGPUTexture>(texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WaitForCommandsToBeScheduled(WGPUDevice cDevice) {
|
void WaitForCommandsToBeScheduled(WGPUDevice cDevice) {
|
||||||
Device* device = reinterpret_cast<Device*>(cDevice);
|
Device* device = reinterpret_cast<Device*>(cDevice);
|
||||||
device->WaitForCommandsToBeScheduled();
|
device->WaitForCommandsToBeScheduled();
|
||||||
|
|
|
@ -349,8 +349,7 @@ namespace dawn_native { namespace metal {
|
||||||
plane:plane];
|
plane:plane];
|
||||||
[mtlDesc release];
|
[mtlDesc release];
|
||||||
|
|
||||||
// TODO(enga): Set as uninitialized if IOSurface isn't initialized.
|
SetIsSubresourceContentInitialized(descriptor->isCleared, 0, 1, 0, 1);
|
||||||
SetIsSubresourceContentInitialized(true, 0, 1, 0, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::~Texture() {
|
Texture::~Texture() {
|
||||||
|
|
|
@ -42,11 +42,6 @@ namespace dawn_native { namespace d3d12 {
|
||||||
DAWN_NATIVE_EXPORT WGPUTexture
|
DAWN_NATIVE_EXPORT WGPUTexture
|
||||||
WrapSharedHandle(WGPUDevice device, const ExternalImageDescriptorDXGISharedHandle* descriptor);
|
WrapSharedHandle(WGPUDevice device, const ExternalImageDescriptorDXGISharedHandle* descriptor);
|
||||||
|
|
||||||
// Note: SharedHandle must be a handle to a texture object.
|
|
||||||
DAWN_NATIVE_EXPORT WGPUTexture WrapSharedHandle(WGPUDevice device,
|
|
||||||
const WGPUTextureDescriptor* descriptor,
|
|
||||||
HANDLE sharedHandle,
|
|
||||||
uint64_t acquireMutexKey);
|
|
||||||
}} // namespace dawn_native::d3d12
|
}} // namespace dawn_native::d3d12
|
||||||
|
|
||||||
#endif // DAWNNATIVE_D3D12BACKEND_H_
|
#endif // DAWNNATIVE_D3D12BACKEND_H_
|
||||||
|
|
|
@ -44,11 +44,6 @@ namespace dawn_native { namespace metal {
|
||||||
DAWN_NATIVE_EXPORT WGPUTexture
|
DAWN_NATIVE_EXPORT WGPUTexture
|
||||||
WrapIOSurface(WGPUDevice device, const ExternalImageDescriptorIOSurface* descriptor);
|
WrapIOSurface(WGPUDevice device, const ExternalImageDescriptorIOSurface* descriptor);
|
||||||
|
|
||||||
DAWN_NATIVE_EXPORT WGPUTexture WrapIOSurface(WGPUDevice device,
|
|
||||||
const WGPUTextureDescriptor* descriptor,
|
|
||||||
IOSurfaceRef ioSurface,
|
|
||||||
uint32_t plane);
|
|
||||||
|
|
||||||
// When making Metal interop with other APIs, we need to be careful that QueueSubmit doesn't
|
// When making Metal interop with other APIs, we need to be careful that QueueSubmit doesn't
|
||||||
// mean that the operations will be visible to other APIs/Metal devices right away. macOS
|
// mean that the operations will be visible to other APIs/Metal devices right away. macOS
|
||||||
// does have a global queue of graphics operations, but the command buffers are inserted there
|
// does have a global queue of graphics operations, but the command buffers are inserted there
|
||||||
|
|
|
@ -301,7 +301,8 @@ class D3D12SharedHandleUsageTests : public D3D12ResourceTestBase {
|
||||||
wgpu::Texture* dawnTextureOut,
|
wgpu::Texture* dawnTextureOut,
|
||||||
const wgpu::Color& clearColor,
|
const wgpu::Color& clearColor,
|
||||||
ID3D11Texture2D** d3d11TextureOut,
|
ID3D11Texture2D** d3d11TextureOut,
|
||||||
IDXGIKeyedMutex** dxgiKeyedMutexOut) const {
|
IDXGIKeyedMutex** dxgiKeyedMutexOut,
|
||||||
|
bool isCleared = true) const {
|
||||||
ComPtr<ID3D11Texture2D> d3d11Texture;
|
ComPtr<ID3D11Texture2D> d3d11Texture;
|
||||||
HRESULT hr = mD3d11Device->CreateTexture2D(d3dDescriptor, nullptr, &d3d11Texture);
|
HRESULT hr = mD3d11Device->CreateTexture2D(d3dDescriptor, nullptr, &d3d11Texture);
|
||||||
ASSERT_EQ(hr, S_OK);
|
ASSERT_EQ(hr, S_OK);
|
||||||
|
@ -338,6 +339,7 @@ class D3D12SharedHandleUsageTests : public D3D12ResourceTestBase {
|
||||||
reinterpret_cast<const WGPUTextureDescriptor*>(dawnDescriptor);
|
reinterpret_cast<const WGPUTextureDescriptor*>(dawnDescriptor);
|
||||||
externDesc.sharedHandle = sharedHandle;
|
externDesc.sharedHandle = sharedHandle;
|
||||||
externDesc.acquireMutexKey = 1;
|
externDesc.acquireMutexKey = 1;
|
||||||
|
externDesc.isCleared = isCleared;
|
||||||
WGPUTexture dawnTexture = dawn_native::d3d12::WrapSharedHandle(device.Get(), &externDesc);
|
WGPUTexture dawnTexture = dawn_native::d3d12::WrapSharedHandle(device.Get(), &externDesc);
|
||||||
|
|
||||||
*dawnTextureOut = wgpu::Texture::Acquire(dawnTexture);
|
*dawnTextureOut = wgpu::Texture::Acquire(dawnTexture);
|
||||||
|
@ -499,5 +501,23 @@ TEST_P(D3D12SharedHandleUsageTests, ClearTwiceInD3D12ReadbackInD3D11) {
|
||||||
ExpectPixelRGBA8EQ(2, d3d11Texture.Get(), dxgiKeyedMutex.Get(), d3d12ClearColor2);
|
ExpectPixelRGBA8EQ(2, d3d11Texture.Get(), dxgiKeyedMutex.Get(), d3d12ClearColor2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1. Create and clear a D3D11 texture with clearColor
|
||||||
|
// 2. Import the texture with isCleared = false
|
||||||
|
// 3. Verify clearColor is not visible in wrapped texture
|
||||||
|
TEST_P(D3D12SharedHandleUsageTests, UnclearedTextureIsCleared) {
|
||||||
|
DAWN_SKIP_TEST_IF(UsesWire());
|
||||||
|
|
||||||
|
const wgpu::Color clearColor{1.0f, 0.0f, 0.0f, 1.0f};
|
||||||
|
wgpu::Texture dawnTexture;
|
||||||
|
ComPtr<ID3D11Texture2D> d3d11Texture;
|
||||||
|
ComPtr<IDXGIKeyedMutex> dxgiKeyedMutex;
|
||||||
|
WrapAndClearD3D11Texture(&dawnDescriptor, &d3dDescriptor, &dawnTexture, clearColor,
|
||||||
|
&d3d11Texture, &dxgiKeyedMutex, false);
|
||||||
|
|
||||||
|
// Readback the destination texture and ensure it contains the colors we used
|
||||||
|
// to clear the source texture on the D3D device.
|
||||||
|
EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 0, 0, 0), dawnTexture, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
DAWN_INSTANTIATE_TEST(D3D12SharedHandleValidation, D3D12Backend());
|
DAWN_INSTANTIATE_TEST(D3D12SharedHandleValidation, D3D12Backend());
|
||||||
DAWN_INSTANTIATE_TEST(D3D12SharedHandleUsageTests, D3D12Backend());
|
DAWN_INSTANTIATE_TEST(D3D12SharedHandleUsageTests, D3D12Backend());
|
||||||
|
|
|
@ -95,12 +95,14 @@ namespace {
|
||||||
public:
|
public:
|
||||||
wgpu::Texture WrapIOSurface(const wgpu::TextureDescriptor* descriptor,
|
wgpu::Texture WrapIOSurface(const wgpu::TextureDescriptor* descriptor,
|
||||||
IOSurfaceRef ioSurface,
|
IOSurfaceRef ioSurface,
|
||||||
uint32_t plane) {
|
uint32_t plane,
|
||||||
|
bool isCleared = true) {
|
||||||
dawn_native::metal::ExternalImageDescriptorIOSurface externDesc;
|
dawn_native::metal::ExternalImageDescriptorIOSurface externDesc;
|
||||||
externDesc.cTextureDescriptor =
|
externDesc.cTextureDescriptor =
|
||||||
reinterpret_cast<const WGPUTextureDescriptor*>(descriptor);
|
reinterpret_cast<const WGPUTextureDescriptor*>(descriptor);
|
||||||
externDesc.ioSurface = ioSurface;
|
externDesc.ioSurface = ioSurface;
|
||||||
externDesc.plane = plane;
|
externDesc.plane = plane;
|
||||||
|
externDesc.isCleared = isCleared;
|
||||||
WGPUTexture texture = dawn_native::metal::WrapIOSurface(device.Get(), &externDesc);
|
WGPUTexture texture = dawn_native::metal::WrapIOSurface(device.Get(), &externDesc);
|
||||||
return wgpu::Texture::Acquire(texture);
|
return wgpu::Texture::Acquire(texture);
|
||||||
}
|
}
|
||||||
|
@ -442,5 +444,30 @@ TEST_P(IOSurfaceUsageTests, ClearRGBA8IOSurface) {
|
||||||
DoClearTest(ioSurface.get(), wgpu::TextureFormat::RGBA8Unorm, &data, sizeof(data));
|
DoClearTest(ioSurface.get(), wgpu::TextureFormat::RGBA8Unorm, &data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that texture with color is cleared when isCleared = false
|
||||||
|
TEST_P(IOSurfaceUsageTests, UnclearedTextureIsCleared) {
|
||||||
|
DAWN_SKIP_TEST_IF(UsesWire());
|
||||||
|
|
||||||
|
ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(1, 1, 'RGBA', 4);
|
||||||
|
uint32_t data = 0x04030201;
|
||||||
|
|
||||||
|
IOSurfaceLock(ioSurface.get(), 0, nullptr);
|
||||||
|
memcpy(IOSurfaceGetBaseAddress(ioSurface.get()), &data, sizeof(data));
|
||||||
|
IOSurfaceUnlock(ioSurface.get(), 0, nullptr);
|
||||||
|
|
||||||
|
wgpu::TextureDescriptor textureDescriptor;
|
||||||
|
textureDescriptor.dimension = wgpu::TextureDimension::e2D;
|
||||||
|
textureDescriptor.format = wgpu::TextureFormat::RGBA8Unorm;
|
||||||
|
textureDescriptor.size = {1, 1, 1};
|
||||||
|
textureDescriptor.sampleCount = 1;
|
||||||
|
textureDescriptor.arrayLayerCount = 1;
|
||||||
|
textureDescriptor.mipLevelCount = 1;
|
||||||
|
textureDescriptor.usage = wgpu::TextureUsage::OutputAttachment | wgpu::TextureUsage::CopySrc;
|
||||||
|
|
||||||
|
// wrap ioSurface and ensure color is not visible when isCleared set to false
|
||||||
|
wgpu::Texture ioSurfaceTexture = WrapIOSurface(&textureDescriptor, ioSurface.get(), 0, false);
|
||||||
|
EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 0, 0, 0), ioSurfaceTexture, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
DAWN_INSTANTIATE_TEST(IOSurfaceValidationTests, MetalBackend());
|
DAWN_INSTANTIATE_TEST(IOSurfaceValidationTests, MetalBackend());
|
||||||
DAWN_INSTANTIATE_TEST(IOSurfaceUsageTests, MetalBackend());
|
DAWN_INSTANTIATE_TEST(IOSurfaceUsageTests, MetalBackend());
|
||||||
|
|
Loading…
Reference in New Issue