blob: 06f50491de7276c411c1835ff33a667ed3dff0a2 [file] [log] [blame]
// Copyright 2024 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <d3d12.h>
#include <vector>
#include "dawn/native/D3D12Backend.h"
#include "dawn/native/d3d12/DeviceD3D12.h"
#include "dawn/tests/DawnTest.h"
#include "dawn/tests/white_box/SharedBufferMemoryTests.h"
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
#include "dawn/utils/WGPUHelpers.h"
namespace dawn {
namespace {
constexpr uint32_t kBufferWidth = 32;
class Backend : public SharedBufferMemoryTestBackend {
public:
static Backend* GetInstance() {
static Backend b;
return &b;
}
std::vector<wgpu::FeatureName> RequiredFeatures(const wgpu::Adapter& adapter) const override {
return {wgpu::FeatureName::SharedBufferMemoryD3D12Resource};
}
wgpu::SharedBufferMemory CreateSharedBufferMemory(const wgpu::Device& device) override {
ComPtr<ID3D12Device> d3d12Device = CreateD3D12Device(device);
ComPtr<ID3D12Resource> d3d12Resource =
CreateD3D12Buffer(d3d12Device.Get(), D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_FLAG_NONE);
wgpu::SharedBufferMemoryDescriptor desc;
native::d3d12::SharedBufferMemoryD3D12ResourceDescriptor sharedD3d12ResourceDesc;
sharedD3d12ResourceDesc.resource = d3d12Resource.Get();
desc.nextInChain = &sharedD3d12ResourceDesc;
return device.ImportSharedBufferMemory(&desc);
}
private:
ComPtr<ID3D12Device> CreateD3D12Device(const wgpu::Device& device) {
ComPtr<IDXGIAdapter> dxgiAdapter = native::d3d::GetDXGIAdapter(device.GetAdapter().Get());
DXGI_ADAPTER_DESC adapterDesc;
dxgiAdapter->GetDesc(&adapterDesc);
ComPtr<IDXGIFactory4> dxgiFactory;
CreateDXGIFactory2(0, IID_PPV_ARGS(&dxgiFactory));
dxgiAdapter = nullptr;
dxgiFactory->EnumAdapterByLuid(adapterDesc.AdapterLuid, IID_PPV_ARGS(&dxgiAdapter));
ComPtr<ID3D12Device> d3d12Device;
D3D12CreateDevice(dxgiAdapter.Get(), D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device),
&d3d12Device);
return d3d12Device;
}
ComPtr<ID3D12Resource> CreateD3D12Buffer(ID3D12Device* device,
D3D12_HEAP_TYPE heapType,
D3D12_RESOURCE_FLAGS resourceFlags) {
D3D12_RESOURCE_STATES initialResourceState = D3D12_RESOURCE_STATE_COMMON;
if (heapType == D3D12_HEAP_TYPE_UPLOAD) {
initialResourceState = D3D12_RESOURCE_STATE_GENERIC_READ;
}
D3D12_HEAP_PROPERTIES heapProperties = {heapType, D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
D3D12_MEMORY_POOL_UNKNOWN, 0, 0};
D3D12_RESOURCE_DESC descriptor;
descriptor.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
descriptor.Alignment = 0;
descriptor.Width = kBufferWidth;
descriptor.Height = 1;
descriptor.DepthOrArraySize = 1;
descriptor.MipLevels = 1;
descriptor.Format = DXGI_FORMAT_UNKNOWN;
descriptor.SampleDesc.Count = 1;
descriptor.SampleDesc.Quality = 0;
descriptor.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
descriptor.Flags = resourceFlags;
ComPtr<ID3D12Resource> resource;
device->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &descriptor,
initialResourceState, {}, IID_PPV_ARGS(&resource));
return resource;
}
private:
Backend() {}
};
// TODO(dawn:2382): Add D3D12-specific tests for:
// - Test importing an {UPLOAD, READBACK, DEFAULT} buffer.
// - Test reading to an {UPLOAD, READBACK, DEFAULT} buffer.
// - Test Writing to an {UPLOAD, READBACK, DEFAULT} buffer
// - Ensure BeginAccess works with SharedFence.
// - Ensure EndAccess works with SharedFence.
// - Validate that importing a nullptr ID3D12Resource results in error.
// - Validate that importing an ID3D12Resource from another device results in error.
// - Check using a non-mappable buffers between multiple devices.
// - Check using the mappable buffers between multiple devices
// - Check validation that isInitialized must be true (for now).
// TODO(dawn:2382): Add backend-agnostic tests for:
// - Ensure that EndAccess cannot be called on a mapped buffer.
// - Ensure no operations {mapping, use on queue} can occur before calling BeginAccess.
// - Ensure multiple buffers created from a SharedBufferMemory cannot be accessed simultaneously.
// - Validate that calling EndAccess before BeginAccess produces an error.
// - Validate that calling BeginAccess twice produces an error.
DAWN_INSTANTIATE_TEST_P(SharedBufferMemoryTests, {D3D12Backend()}, {Backend::GetInstance()});
} // anonymous namespace
} // namespace dawn