[D3D12] Nicer DeferredCommandList uintmax_t alignment

This commit is contained in:
Triang3l 2020-10-03 14:12:30 +03:00
parent 1014458783
commit 6cb8f0aab4
2 changed files with 33 additions and 25 deletions

View File

@ -20,22 +20,22 @@ namespace d3d12 {
DeferredCommandList::DeferredCommandList( DeferredCommandList::DeferredCommandList(
D3D12CommandProcessor& command_processor, size_t initial_size) D3D12CommandProcessor& command_processor, size_t initial_size)
: command_processor_(command_processor) { : command_processor_(command_processor) {
command_stream_.reserve(initial_size); command_stream_.reserve(initial_size / sizeof(uintmax_t));
} }
void DeferredCommandList::Reset() { command_stream_.clear(); } void DeferredCommandList::Reset() { command_stream_.clear(); }
void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list, void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list,
ID3D12GraphicsCommandList1* command_list_1) { ID3D12GraphicsCommandList1* command_list_1) {
const uint8_t* stream = command_stream_.data(); const uintmax_t* stream = command_stream_.data();
size_t stream_remaining = command_stream_.size(); size_t stream_remaining = command_stream_.size();
ID3D12PipelineState* current_pipeline_state = nullptr; ID3D12PipelineState* current_pipeline_state = nullptr;
while (stream_remaining != 0) { while (stream_remaining != 0) {
const uint32_t* header = reinterpret_cast<const uint32_t*>(stream); const CommandHeader& header =
const size_t header_size = xe::align(2 * sizeof(uint32_t), kAlignment); *reinterpret_cast<const CommandHeader*>(stream);
stream += header_size; stream += kCommandHeaderSizeElements;
stream_remaining -= header_size; stream_remaining -= kCommandHeaderSizeElements;
switch (Command(header[0])) { switch (header.command) {
case Command::kD3DClearUnorderedAccessViewUint: { case Command::kD3DClearUnorderedAccessViewUint: {
auto& args = auto& args =
*reinterpret_cast<const ClearUnorderedAccessViewHeader*>(stream); *reinterpret_cast<const ClearUnorderedAccessViewHeader*>(stream);
@ -121,7 +121,7 @@ void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list,
command_list->ResourceBarrier( command_list->ResourceBarrier(
*reinterpret_cast<const UINT*>(stream), *reinterpret_cast<const UINT*>(stream),
reinterpret_cast<const D3D12_RESOURCE_BARRIER*>( reinterpret_cast<const D3D12_RESOURCE_BARRIER*>(
stream + reinterpret_cast<const uint8_t*>(stream) +
xe::align(sizeof(UINT), alignof(D3D12_RESOURCE_BARRIER)))); xe::align(sizeof(UINT), alignof(D3D12_RESOURCE_BARRIER))));
} break; } break;
case Command::kRSSetScissorRect: { case Command::kRSSetScissorRect: {
@ -221,25 +221,26 @@ void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list,
} }
} break; } break;
default: default:
assert_unhandled_case(Command(header[0])); assert_unhandled_case(header.command);
break; break;
} }
stream += header[1]; stream += header.arguments_size_elements;
stream_remaining -= header[1]; stream_remaining -= header.arguments_size_elements;
} }
} }
void* DeferredCommandList::WriteCommand(Command command, void* DeferredCommandList::WriteCommand(Command command,
size_t arguments_size) { size_t arguments_size_bytes) {
arguments_size = xe::align(arguments_size, kAlignment); size_t arguments_size_elements =
const size_t header_size = xe::align(2 * sizeof(uint32_t), kAlignment); (arguments_size_bytes + sizeof(uintmax_t) - 1) / sizeof(uintmax_t);
size_t offset = command_stream_.size(); size_t offset = command_stream_.size();
command_stream_.resize(offset + header_size + arguments_size); command_stream_.resize(offset + kCommandHeaderSizeElements +
uint32_t* header = arguments_size_elements);
reinterpret_cast<uint32_t*>(command_stream_.data() + offset); CommandHeader& header =
header[0] = uint32_t(command); *reinterpret_cast<CommandHeader*>(command_stream_.data() + offset);
header[1] = uint32_t(arguments_size); header.command = command;
return command_stream_.data() + (offset + header_size); header.arguments_size_elements = uint32_t(arguments_size_elements);
return command_stream_.data() + (offset + kCommandHeaderSizeElements);
} }
} // namespace d3d12 } // namespace d3d12

View File

@ -11,6 +11,7 @@
#define XENIA_GPU_D3D12_DEFERRED_COMMAND_LIST_H_ #define XENIA_GPU_D3D12_DEFERRED_COMMAND_LIST_H_
#include <algorithm> #include <algorithm>
#include <cstdint>
#include <cstring> #include <cstring>
#include <vector> #include <vector>
@ -26,7 +27,7 @@ class D3D12CommandProcessor;
class DeferredCommandList { class DeferredCommandList {
public: public:
DeferredCommandList(D3D12CommandProcessor& command_processor, DeferredCommandList(D3D12CommandProcessor& command_processor,
size_t initial_size = 256 * 1024); size_t initial_size_bytes = 1024 * 1024);
void Reset(); void Reset();
void Execute(ID3D12GraphicsCommandList* command_list, void Execute(ID3D12GraphicsCommandList* command_list,
@ -332,8 +333,6 @@ class DeferredCommandList {
} }
private: private:
static constexpr size_t kAlignment = std::max(sizeof(void*), sizeof(UINT64));
enum class Command : uint32_t { enum class Command : uint32_t {
kD3DClearUnorderedAccessViewUint, kD3DClearUnorderedAccessViewUint,
kD3DCopyBufferRegion, kD3DCopyBufferRegion,
@ -365,6 +364,13 @@ class DeferredCommandList {
kD3DSetSamplePositions, kD3DSetSamplePositions,
}; };
struct CommandHeader {
Command command;
uint32_t arguments_size_elements;
};
static constexpr size_t kCommandHeaderSizeElements =
(sizeof(CommandHeader) + sizeof(uintmax_t) - 1) / sizeof(uintmax_t);
struct ClearUnorderedAccessViewHeader { struct ClearUnorderedAccessViewHeader {
D3D12_GPU_DESCRIPTOR_HANDLE view_gpu_handle_in_current_heap; D3D12_GPU_DESCRIPTOR_HANDLE view_gpu_handle_in_current_heap;
D3D12_CPU_DESCRIPTOR_HANDLE view_cpu_handle; D3D12_CPU_DESCRIPTOR_HANDLE view_cpu_handle;
@ -460,11 +466,12 @@ class DeferredCommandList {
D3D12_SAMPLE_POSITION sample_positions[16]; D3D12_SAMPLE_POSITION sample_positions[16];
}; };
void* WriteCommand(Command command, size_t arguments_size); void* WriteCommand(Command command, size_t arguments_size_bytes);
D3D12CommandProcessor& command_processor_; D3D12CommandProcessor& command_processor_;
std::vector<uint8_t> command_stream_; // uintmax_t to ensure uint64_t and pointer alignment of all structures.
std::vector<uintmax_t> command_stream_;
}; };
} // namespace d3d12 } // namespace d3d12