diff --git a/src/xenia/gpu/d3d12/deferred_command_list.cc b/src/xenia/gpu/d3d12/deferred_command_list.cc index f6eede18b..8bbd08224 100644 --- a/src/xenia/gpu/d3d12/deferred_command_list.cc +++ b/src/xenia/gpu/d3d12/deferred_command_list.cc @@ -20,22 +20,22 @@ namespace d3d12 { DeferredCommandList::DeferredCommandList( D3D12CommandProcessor& command_processor, size_t initial_size) : 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::Execute(ID3D12GraphicsCommandList* command_list, 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(); ID3D12PipelineState* current_pipeline_state = nullptr; while (stream_remaining != 0) { - const uint32_t* header = reinterpret_cast(stream); - const size_t header_size = xe::align(2 * sizeof(uint32_t), kAlignment); - stream += header_size; - stream_remaining -= header_size; - switch (Command(header[0])) { + const CommandHeader& header = + *reinterpret_cast(stream); + stream += kCommandHeaderSizeElements; + stream_remaining -= kCommandHeaderSizeElements; + switch (header.command) { case Command::kD3DClearUnorderedAccessViewUint: { auto& args = *reinterpret_cast(stream); @@ -121,7 +121,7 @@ void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list, command_list->ResourceBarrier( *reinterpret_cast(stream), reinterpret_cast( - stream + + reinterpret_cast(stream) + xe::align(sizeof(UINT), alignof(D3D12_RESOURCE_BARRIER)))); } break; case Command::kRSSetScissorRect: { @@ -221,25 +221,26 @@ void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list, } } break; default: - assert_unhandled_case(Command(header[0])); + assert_unhandled_case(header.command); break; } - stream += header[1]; - stream_remaining -= header[1]; + stream += header.arguments_size_elements; + stream_remaining -= header.arguments_size_elements; } } void* DeferredCommandList::WriteCommand(Command command, - size_t arguments_size) { - arguments_size = xe::align(arguments_size, kAlignment); - const size_t header_size = xe::align(2 * sizeof(uint32_t), kAlignment); + size_t arguments_size_bytes) { + size_t arguments_size_elements = + (arguments_size_bytes + sizeof(uintmax_t) - 1) / sizeof(uintmax_t); size_t offset = command_stream_.size(); - command_stream_.resize(offset + header_size + arguments_size); - uint32_t* header = - reinterpret_cast(command_stream_.data() + offset); - header[0] = uint32_t(command); - header[1] = uint32_t(arguments_size); - return command_stream_.data() + (offset + header_size); + command_stream_.resize(offset + kCommandHeaderSizeElements + + arguments_size_elements); + CommandHeader& header = + *reinterpret_cast(command_stream_.data() + offset); + header.command = command; + header.arguments_size_elements = uint32_t(arguments_size_elements); + return command_stream_.data() + (offset + kCommandHeaderSizeElements); } } // namespace d3d12 diff --git a/src/xenia/gpu/d3d12/deferred_command_list.h b/src/xenia/gpu/d3d12/deferred_command_list.h index 78f1b605b..64118d651 100644 --- a/src/xenia/gpu/d3d12/deferred_command_list.h +++ b/src/xenia/gpu/d3d12/deferred_command_list.h @@ -11,6 +11,7 @@ #define XENIA_GPU_D3D12_DEFERRED_COMMAND_LIST_H_ #include +#include #include #include @@ -26,7 +27,7 @@ class D3D12CommandProcessor; class DeferredCommandList { public: DeferredCommandList(D3D12CommandProcessor& command_processor, - size_t initial_size = 256 * 1024); + size_t initial_size_bytes = 1024 * 1024); void Reset(); void Execute(ID3D12GraphicsCommandList* command_list, @@ -332,8 +333,6 @@ class DeferredCommandList { } private: - static constexpr size_t kAlignment = std::max(sizeof(void*), sizeof(UINT64)); - enum class Command : uint32_t { kD3DClearUnorderedAccessViewUint, kD3DCopyBufferRegion, @@ -365,6 +364,13 @@ class DeferredCommandList { 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 { D3D12_GPU_DESCRIPTOR_HANDLE view_gpu_handle_in_current_heap; D3D12_CPU_DESCRIPTOR_HANDLE view_cpu_handle; @@ -460,11 +466,12 @@ class DeferredCommandList { 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_; - std::vector command_stream_; + // uintmax_t to ensure uint64_t and pointer alignment of all structures. + std::vector command_stream_; }; } // namespace d3d12