Files
Xenia-Canary/src/xenia/gpu/d3d12/d3d12_shared_memory.h
Triang3l 80dad41454 [GPU/WGF] Use ByteAddressBuffer in precompiled shaders
Drivers and hardware may provide more optimal paths for untyped buffers
compared to typed.

Also, ByteAddressBuffer may be bound via a root descriptor in Direct3D 12,
greatly simplifying the binding logic.

ByteAddressBuffer also doesn't have the 128 * 2^20 element count limit that
typed and structured buffers have, and doesn't require the structure stride
to be specified at resource creation time in Direct3D 11.
2026-02-17 23:28:42 +03:00

132 lines
4.4 KiB
C++

/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2020 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_GPU_D3D12_D3D12_SHARED_MEMORY_H_
#define XENIA_GPU_D3D12_D3D12_SHARED_MEMORY_H_
#include <algorithm>
#include <memory>
#include <utility>
#include <vector>
#include "xenia/gpu/shared_memory.h"
#include "xenia/gpu/trace_writer.h"
#include "xenia/memory.h"
#include "xenia/ui/d3d12/d3d12_api.h"
#include "xenia/ui/d3d12/d3d12_upload_buffer_pool.h"
namespace xe {
namespace gpu {
namespace d3d12 {
class D3D12CommandProcessor;
class D3D12SharedMemory : public SharedMemory {
public:
D3D12SharedMemory(D3D12CommandProcessor& command_processor, Memory& memory,
TraceWriter& trace_writer);
~D3D12SharedMemory() override;
bool Initialize();
void Shutdown(bool from_destructor = false);
void ClearCache() override;
ID3D12Resource* GetBuffer() const { return buffer_; }
D3D12_GPU_VIRTUAL_ADDRESS GetGPUAddress() const {
return buffer_gpu_address_;
}
void CompletedSubmissionUpdated();
void BeginSubmission();
// RequestRange may transition the buffer to copy destination - call it before
// UseForReading or UseForWriting.
// Makes the buffer usable for vertices, indices and texture untiling.
void UseForReading() {
// Vertex fetch is also allowed in pixel shaders.
CommitUAVWritesAndTransitionBuffer(
D3D12_RESOURCE_STATE_INDEX_BUFFER |
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE |
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
}
// Makes the buffer usable for texture tiling after a resolve.
void UseForWriting() {
CommitUAVWritesAndTransitionBuffer(D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
}
// Makes the buffer usable as a source for copy commands.
void UseAsCopySource() {
CommitUAVWritesAndTransitionBuffer(D3D12_RESOURCE_STATE_COPY_SOURCE);
}
// Must be called when doing draws/dispatches modifying data within the shared
// memory buffer as a UAV, to make sure that when UseForWriting is called the
// next time, a UAV barrier will be done, and subsequent overlapping UAV
// writes and reads are ordered.
void MarkUAVWritesCommitNeeded() {
if (buffer_state_ == D3D12_RESOURCE_STATE_UNORDERED_ACCESS) {
buffer_uav_writes_commit_needed_ = true;
}
}
void WriteRawSRVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle);
void WriteRawUAVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle);
// Returns true if any downloads were submitted to the command processor.
bool InitializeTraceSubmitDownloads();
void InitializeTraceCompleteDownloads();
protected:
bool AllocateSparseHostGpuMemoryRange(uint32_t offset_allocations,
uint32_t length_allocations) override;
bool UploadRanges(const std::vector<std::pair<uint32_t, uint32_t>>&
upload_page_ranges) override;
private:
D3D12CommandProcessor& command_processor_;
TraceWriter& trace_writer_;
// The 512 MB tiled buffer.
ID3D12Resource* buffer_ = nullptr;
D3D12_GPU_VIRTUAL_ADDRESS buffer_gpu_address_ = 0;
std::vector<ID3D12Heap*> buffer_tiled_heaps_;
D3D12_RESOURCE_STATES buffer_state_ = D3D12_RESOURCE_STATE_COPY_DEST;
bool buffer_uav_writes_commit_needed_ = false;
void CommitUAVWritesAndTransitionBuffer(D3D12_RESOURCE_STATES new_state);
// Non-shader-visible buffer descriptor heap for faster binding (via copying
// rather than creation).
enum class BufferDescriptorIndex : uint32_t {
kRawSRV,
kR32UintSRV,
kR32G32UintSRV,
kR32G32B32A32UintSRV,
kRawUAV,
kR32UintUAV,
kR32G32UintUAV,
kR32G32B32A32UintUAV,
kCount,
};
ID3D12DescriptorHeap* buffer_descriptor_heap_ = nullptr;
D3D12_CPU_DESCRIPTOR_HANDLE buffer_descriptor_heap_start_;
std::unique_ptr<ui::d3d12::D3D12UploadBufferPool> upload_buffer_pool_;
// Created temporarily, only for downloading.
ID3D12Resource* trace_download_buffer_ = nullptr;
void ResetTraceDownload();
};
} // namespace d3d12
} // namespace gpu
} // namespace xe
#endif // XENIA_GPU_D3D12_D3D12_SHARED_MEMORY_H_