mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-08 21:17:45 +00:00
d3d12: External image import using multiple wait fences and signal fence
To support concurrent readers on multiple command queues/devices, Dawn must support importing via wait multiple fences and also export a signal fence. The previous implementation of using a single fence for waiting and signaling doesn't work for concurrent reads across queues. This CL adds support for specifying multiple wait fences for ExternalImageDXGI via a BeginAccess method that's meant to replace ProduceTexture. There's also an EndAccess method that returns a signal fence for the client. For performance reasons, we use the same fence as the signal fence that the Device uses internally, and record its value on the texture after ExecuteCommandLists. Therefore, the CL also makes the Device's internal fence a shared fence so that we can export it to the client. This CL also expands the ConcurrentExternalImageReadAccess test so that it tests fence synchronization across multiple devices. A number of test helpers also now take an optional device parameter so that we can use pixel value expectations with secondary devices. Bug: dawn:576 Change-Id: I6bc86808ede9b5aacf87667106cbd16731a12516 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/99746 Commit-Queue: Sunny Sachanandani <sunnyps@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
committed by
Dawn LUCI CQ
parent
29aa613dcf
commit
5881e735f9
@@ -21,6 +21,7 @@
|
||||
#include <wrl/client.h>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "dawn/dawn_wsi.h"
|
||||
#include "dawn/native/DawnNative.h"
|
||||
@@ -54,30 +55,30 @@ struct DAWN_NATIVE_EXPORT ExternalImageDescriptorDXGISharedHandle : ExternalImag
|
||||
ExternalImageDescriptorDXGISharedHandle();
|
||||
|
||||
// Note: SharedHandle must be a handle to a texture object.
|
||||
// TODO(dawn:576): Remove after changing Chromium code to set textureSharedHandle.
|
||||
HANDLE sharedHandle = nullptr;
|
||||
HANDLE textureSharedHandle = nullptr;
|
||||
|
||||
// Optional shared handle to a D3D11/12 fence which can be used to synchronize using wait/signal
|
||||
// values specified in the access descriptor below. If null, the texture will be assumed to have
|
||||
// an associated DXGI keyed mutex which will be used with a fixed key of 0 for synchronization.
|
||||
HANDLE fenceSharedHandle = nullptr;
|
||||
// Whether fence synchronization should be used instead of texture's keyed mutex.
|
||||
bool useFenceSynchronization = false;
|
||||
};
|
||||
|
||||
// Keyed mutex acquire/release uses a fixed key of 0 to match Chromium behavior.
|
||||
constexpr UINT64 kDXGIKeyedMutexAcquireReleaseKey = 0;
|
||||
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageAccessDescriptorDXGISharedHandle
|
||||
: ExternalImageAccessDescriptor {
|
||||
public:
|
||||
// Value used for fence wait. A value of 0 is valid, but essentially a no-op since the fence
|
||||
// lifetime starts with the 0 value signaled. A value of UINT64_MAX is ignored since it's also
|
||||
// used by the D3D runtime to indicate that the device was removed.
|
||||
uint64_t fenceWaitValue = 0;
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageDXGIFenceDescriptor {
|
||||
// Shared handle for the fence. This never passes ownership to the callee (when used as an input
|
||||
// parameter) or to the caller (when used as a return value or output parameter).
|
||||
HANDLE fenceHandle = nullptr;
|
||||
|
||||
// Value to signal the fence with after the texture is destroyed. A value of 0 means the fence
|
||||
// will not be signaled.
|
||||
uint64_t fenceSignalValue = 0;
|
||||
// The value that was previously signaled on this fence and should be waited on.
|
||||
uint64_t fenceValue = 0;
|
||||
};
|
||||
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageDXGIBeginAccessDescriptor {
|
||||
bool isInitialized = false; // Whether the texture is initialized on import
|
||||
WGPUTextureUsageFlags usage = WGPUTextureUsage_None;
|
||||
|
||||
// A list of fences to wait on before accessing the texture.
|
||||
std::vector<ExternalImageDXGIFenceDescriptor> waitFences;
|
||||
|
||||
// Whether the texture is for a WebGPU swap chain.
|
||||
bool isSwapChainTexture = false;
|
||||
@@ -85,7 +86,7 @@ struct DAWN_NATIVE_EXPORT ExternalImageAccessDescriptorDXGISharedHandle
|
||||
|
||||
// TODO(dawn:576): Remove after changing Chromium code to use the new struct name.
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageAccessDescriptorDXGIKeyedMutex
|
||||
: ExternalImageAccessDescriptorDXGISharedHandle {
|
||||
: ExternalImageDXGIBeginAccessDescriptor {
|
||||
public:
|
||||
// TODO(chromium:1241533): Remove deprecated keyed mutex params after removing associated
|
||||
// code from Chromium - we use a fixed key of 0 for acquire and release everywhere now.
|
||||
@@ -105,11 +106,19 @@ class DAWN_NATIVE_EXPORT ExternalImageDXGI {
|
||||
// guaranteed to fail e.g. after device destruction.
|
||||
bool IsValid() const;
|
||||
|
||||
// TODO(sunnyps): |device| is ignored - remove after Chromium migrates to single parameter call.
|
||||
// TODO(sunnyps): |device| is ignored - remove after Chromium migrates to BeginAccess().
|
||||
WGPUTexture ProduceTexture(WGPUDevice device,
|
||||
const ExternalImageAccessDescriptorDXGISharedHandle* descriptor);
|
||||
const ExternalImageDXGIBeginAccessDescriptor* descriptor);
|
||||
|
||||
WGPUTexture ProduceTexture(const ExternalImageAccessDescriptorDXGISharedHandle* descriptor);
|
||||
// Creates WGPUTexture wrapping the DXGI shared handle. The provided wait fences or the
|
||||
// texture's keyed mutex will be synchronized before using the texture in any command lists.
|
||||
// Empty fences (nullptr handle) are ignored for convenience (EndAccess can return such fences).
|
||||
WGPUTexture BeginAccess(const ExternalImageDXGIBeginAccessDescriptor* descriptor);
|
||||
|
||||
// Returns the signalFence that the client must wait on for correct synchronization. Can return
|
||||
// an empty fence (nullptr handle) if the texture wasn't accessed by Dawn.
|
||||
// Note that merely calling Destroy() on the WGPUTexture does not ensure synchronization.
|
||||
void EndAccess(WGPUTexture texture, ExternalImageDXGIFenceDescriptor* signalFence);
|
||||
|
||||
private:
|
||||
explicit ExternalImageDXGI(std::unique_ptr<ExternalImageDXGIImpl> impl);
|
||||
|
||||
@@ -237,12 +237,6 @@ struct DAWN_NATIVE_EXPORT ExternalImageDescriptor {
|
||||
ExternalImageType mType;
|
||||
};
|
||||
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageAccessDescriptor {
|
||||
public:
|
||||
bool isInitialized = false; // Whether the texture is initialized on import
|
||||
WGPUTextureUsageFlags usage = WGPUTextureUsage_None;
|
||||
};
|
||||
|
||||
struct DAWN_NATIVE_EXPORT ExternalImageExportInfo {
|
||||
public:
|
||||
bool isInitialized = false; // Whether the texture is initialized after export
|
||||
|
||||
Reference in New Issue
Block a user