[D3D12] Deferred command list class
This commit is contained in:
parent
a97fc28ee2
commit
f0c662fa1e
|
@ -0,0 +1,209 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "xenia/gpu/d3d12/deferred_command_list.h"
|
||||
|
||||
#include "xenia/base/assert.h"
|
||||
#include "xenia/base/math.h"
|
||||
#include "xenia/gpu/d3d12/d3d12_command_processor.h"
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
namespace d3d12 {
|
||||
|
||||
constexpr size_t DeferredCommandList::kAlignment;
|
||||
|
||||
DeferredCommandList::DeferredCommandList(
|
||||
D3D12CommandProcessor* command_processor, size_t initial_size)
|
||||
: command_processor_(command_processor) {
|
||||
command_stream_.reserve(initial_size);
|
||||
}
|
||||
|
||||
void DeferredCommandList::Reset() { command_stream_.clear(); }
|
||||
|
||||
void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list,
|
||||
ID3D12GraphicsCommandList1* command_list_1) {
|
||||
const uint8_t* stream = command_stream_.data();
|
||||
size_t stream_remaining = command_stream_.size();
|
||||
while (stream_remaining != 0) {
|
||||
const uint32_t* header = reinterpret_cast<const uint32_t*>(stream);
|
||||
const size_t header_size = xe::align(2 * sizeof(uint32_t), kAlignment);
|
||||
stream += header_size;
|
||||
stream_remaining -= header_size;
|
||||
switch (Command(header[0])) {
|
||||
case Command::kD3DCopyBufferRegion: {
|
||||
auto& args =
|
||||
*reinterpret_cast<const D3DCopyBufferRegionArguments*>(stream);
|
||||
command_list->CopyBufferRegion(args.dst_buffer, args.dst_offset,
|
||||
args.src_buffer, args.src_offset,
|
||||
args.num_bytes);
|
||||
} break;
|
||||
case Command::kD3DCopyResource: {
|
||||
auto& args = *reinterpret_cast<const D3DCopyResourceArguments*>(stream);
|
||||
command_list->CopyResource(args.dst_resource, args.src_resource);
|
||||
} break;
|
||||
case Command::kCopyTexture: {
|
||||
auto& args = *reinterpret_cast<const CopyTextureArguments*>(stream);
|
||||
command_list->CopyTextureRegion(&args.dst, 0, 0, 0, &args.src, nullptr);
|
||||
} break;
|
||||
case Command::kD3DDispatch: {
|
||||
auto& args = *reinterpret_cast<const D3DDispatchArguments*>(stream);
|
||||
command_list->Dispatch(args.thread_group_count_x,
|
||||
args.thread_group_count_y,
|
||||
args.thread_group_count_z);
|
||||
} break;
|
||||
case Command::kD3DDrawIndexedInstanced: {
|
||||
auto& args =
|
||||
*reinterpret_cast<const D3DDrawIndexedInstancedArguments*>(stream);
|
||||
command_list->DrawIndexedInstanced(
|
||||
args.index_count_per_instance, args.instance_count,
|
||||
args.start_index_location, args.base_vertex_location,
|
||||
args.start_instance_location);
|
||||
} break;
|
||||
case Command::kD3DIASetIndexBuffer: {
|
||||
auto view = reinterpret_cast<const D3D12_INDEX_BUFFER_VIEW*>(stream);
|
||||
command_list->IASetIndexBuffer(
|
||||
view->Format != DXGI_FORMAT_UNKNOWN ? view : nullptr);
|
||||
} break;
|
||||
case Command::kD3DIASetPrimitiveTopology: {
|
||||
command_list->IASetPrimitiveTopology(
|
||||
*reinterpret_cast<const D3D12_PRIMITIVE_TOPOLOGY*>(stream));
|
||||
} break;
|
||||
case Command::kD3DOMSetBlendFactor: {
|
||||
command_list->OMSetBlendFactor(reinterpret_cast<const FLOAT*>(stream));
|
||||
} break;
|
||||
case Command::kD3DOMSetRenderTargets: {
|
||||
auto& args =
|
||||
*reinterpret_cast<const D3DOMSetRenderTargetsArguments*>(stream);
|
||||
command_list->OMSetRenderTargets(
|
||||
args.num_render_target_descriptors, args.render_target_descriptors,
|
||||
args.rts_single_handle_to_descriptor_range ? TRUE : FALSE,
|
||||
args.depth_stencil ? &args.depth_stencil_descriptor : nullptr);
|
||||
} break;
|
||||
case Command::kD3DOMSetStencilRef: {
|
||||
command_list->OMSetStencilRef(*reinterpret_cast<const UINT*>(stream));
|
||||
} break;
|
||||
case Command::kD3DResourceBarrier: {
|
||||
command_list->ResourceBarrier(
|
||||
*reinterpret_cast<const UINT*>(stream),
|
||||
reinterpret_cast<const D3D12_RESOURCE_BARRIER*>(
|
||||
stream +
|
||||
xe::align(sizeof(UINT), alignof(D3D12_RESOURCE_BARRIER))));
|
||||
} break;
|
||||
case Command::kRSSetScissorRect: {
|
||||
command_list->RSSetScissorRects(
|
||||
1, reinterpret_cast<const D3D12_RECT*>(stream));
|
||||
} break;
|
||||
case Command::kRSSetViewport: {
|
||||
command_list->RSSetViewports(
|
||||
1, reinterpret_cast<const D3D12_VIEWPORT*>(stream));
|
||||
} break;
|
||||
case Command::kD3DSetComputeRoot32BitConstants: {
|
||||
auto args =
|
||||
reinterpret_cast<const SetRoot32BitConstantsHeader*>(stream);
|
||||
command_list->SetComputeRoot32BitConstants(
|
||||
args->root_parameter_index, args->num_32bit_values_to_set, args + 1,
|
||||
args->dest_offset_in_32bit_values);
|
||||
} break;
|
||||
case Command::kD3DSetGraphicsRoot32BitConstants: {
|
||||
auto args =
|
||||
reinterpret_cast<const SetRoot32BitConstantsHeader*>(stream);
|
||||
command_list->SetGraphicsRoot32BitConstants(
|
||||
args->root_parameter_index, args->num_32bit_values_to_set, args + 1,
|
||||
args->dest_offset_in_32bit_values);
|
||||
} break;
|
||||
case Command::kD3DSetComputeRootConstantBufferView: {
|
||||
auto& args =
|
||||
*reinterpret_cast<const SetRootConstantBufferViewArguments*>(
|
||||
stream);
|
||||
command_list->SetComputeRootConstantBufferView(
|
||||
args.root_parameter_index, args.buffer_location);
|
||||
} break;
|
||||
case Command::kD3DSetGraphicsRootConstantBufferView: {
|
||||
auto& args =
|
||||
*reinterpret_cast<const SetRootConstantBufferViewArguments*>(
|
||||
stream);
|
||||
command_list->SetGraphicsRootConstantBufferView(
|
||||
args.root_parameter_index, args.buffer_location);
|
||||
} break;
|
||||
case Command::kD3DSetComputeRootDescriptorTable: {
|
||||
auto& args =
|
||||
*reinterpret_cast<const SetRootDescriptorTableArguments*>(stream);
|
||||
command_list->SetComputeRootDescriptorTable(args.root_parameter_index,
|
||||
args.base_descriptor);
|
||||
} break;
|
||||
case Command::kD3DSetGraphicsRootDescriptorTable: {
|
||||
auto& args =
|
||||
*reinterpret_cast<const SetRootDescriptorTableArguments*>(stream);
|
||||
command_list->SetGraphicsRootDescriptorTable(args.root_parameter_index,
|
||||
args.base_descriptor);
|
||||
} break;
|
||||
case Command::kD3DSetComputeRootSignature: {
|
||||
command_list->SetComputeRootSignature(
|
||||
*reinterpret_cast<ID3D12RootSignature* const*>(stream));
|
||||
} break;
|
||||
case Command::kD3DSetGraphicsRootSignature: {
|
||||
command_list->SetGraphicsRootSignature(
|
||||
*reinterpret_cast<ID3D12RootSignature* const*>(stream));
|
||||
} break;
|
||||
case Command::kSetDescriptorHeaps: {
|
||||
auto& args =
|
||||
*reinterpret_cast<const SetDescriptorHeapsArguments*>(stream);
|
||||
UINT num_descriptor_heaps = 0;
|
||||
ID3D12DescriptorHeap* descriptor_heaps[2];
|
||||
if (args.cbv_srv_uav_descriptor_heap != nullptr) {
|
||||
descriptor_heaps[num_descriptor_heaps++] =
|
||||
args.cbv_srv_uav_descriptor_heap;
|
||||
}
|
||||
if (args.sampler_descriptor_heap != nullptr) {
|
||||
descriptor_heaps[num_descriptor_heaps++] =
|
||||
args.sampler_descriptor_heap;
|
||||
}
|
||||
command_list->SetDescriptorHeaps(num_descriptor_heaps,
|
||||
descriptor_heaps);
|
||||
} break;
|
||||
case Command::kD3DSetPipelineState: {
|
||||
command_list->SetPipelineState(
|
||||
*reinterpret_cast<ID3D12PipelineState* const*>(stream));
|
||||
} break;
|
||||
case Command::kD3DSetSamplePositions: {
|
||||
if (command_list_1 != nullptr) {
|
||||
auto& args =
|
||||
*reinterpret_cast<const D3DSetSamplePositionsArguments*>(stream);
|
||||
command_list_1->SetSamplePositions(
|
||||
args.num_samples_per_pixel, args.num_pixels,
|
||||
const_cast<D3D12_SAMPLE_POSITION*>(args.sample_positions));
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
assert_unhandled_case(Command(header[0]));
|
||||
break;
|
||||
}
|
||||
stream += header[1];
|
||||
stream_remaining -= header[1];
|
||||
}
|
||||
Reset();
|
||||
}
|
||||
|
||||
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 offset = command_stream_.size();
|
||||
command_stream_.resize(offset + header_size + arguments_size);
|
||||
uint32_t* header =
|
||||
reinterpret_cast<uint32_t*>(command_stream_.data() + offset);
|
||||
header[0] = uint32_t(command);
|
||||
header[1] = uint32_t(arguments_size);
|
||||
return command_stream_.data() + (offset + header_size);
|
||||
}
|
||||
|
||||
} // namespace d3d12
|
||||
} // namespace gpu
|
||||
} // namespace xe
|
|
@ -0,0 +1,413 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_GPU_D3D12_DEFERRED_COMMAND_LIST_H_
|
||||
#define XENIA_GPU_D3D12_DEFERRED_COMMAND_LIST_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
#include "xenia/base/math.h"
|
||||
#include "xenia/ui/d3d12/command_list.h"
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
namespace d3d12 {
|
||||
|
||||
class D3D12CommandProcessor;
|
||||
|
||||
class DeferredCommandList {
|
||||
public:
|
||||
DeferredCommandList(D3D12CommandProcessor* command_processor,
|
||||
size_t initial_size = 256 * 1024);
|
||||
|
||||
void Reset();
|
||||
void Execute(ID3D12GraphicsCommandList* command_list,
|
||||
ID3D12GraphicsCommandList1* command_list_1);
|
||||
|
||||
inline void D3DCopyBufferRegion(ID3D12Resource* dst_buffer, UINT64 dst_offset,
|
||||
ID3D12Resource* src_buffer, UINT64 src_offset,
|
||||
UINT64 num_bytes) {
|
||||
auto& args = *reinterpret_cast<D3DCopyBufferRegionArguments*>(WriteCommand(
|
||||
Command::kD3DCopyBufferRegion, sizeof(D3DCopyBufferRegionArguments)));
|
||||
args.dst_buffer = dst_buffer;
|
||||
args.dst_offset = dst_offset;
|
||||
args.src_buffer = src_buffer;
|
||||
args.src_offset = src_offset;
|
||||
args.num_bytes = num_bytes;
|
||||
}
|
||||
|
||||
inline void D3DCopyResource(ID3D12Resource* dst_resource,
|
||||
ID3D12Resource* src_resource) {
|
||||
auto& args = *reinterpret_cast<D3DCopyResourceArguments*>(WriteCommand(
|
||||
Command::kD3DCopyResource, sizeof(D3DCopyResourceArguments)));
|
||||
args.dst_resource = dst_resource;
|
||||
args.src_resource = src_resource;
|
||||
}
|
||||
|
||||
inline void CopyTexture(const D3D12_TEXTURE_COPY_LOCATION& dst,
|
||||
const D3D12_TEXTURE_COPY_LOCATION& src) {
|
||||
auto& args = *reinterpret_cast<CopyTextureArguments*>(
|
||||
WriteCommand(Command::kCopyTexture, sizeof(CopyTextureArguments)));
|
||||
std::memcpy(&args.dst, &dst, sizeof(D3D12_TEXTURE_COPY_LOCATION));
|
||||
std::memcpy(&args.src, &src, sizeof(D3D12_TEXTURE_COPY_LOCATION));
|
||||
}
|
||||
|
||||
inline void D3DDispatch(UINT thread_group_count_x, UINT thread_group_count_y,
|
||||
UINT thread_group_count_z) {
|
||||
auto& args = *reinterpret_cast<D3DDispatchArguments*>(
|
||||
WriteCommand(Command::kD3DDispatch, sizeof(D3DDispatchArguments)));
|
||||
args.thread_group_count_x = thread_group_count_x;
|
||||
args.thread_group_count_y = thread_group_count_y;
|
||||
args.thread_group_count_z = thread_group_count_z;
|
||||
}
|
||||
|
||||
inline void D3DDrawIndexedInstanced(UINT index_count_per_instance,
|
||||
UINT instance_count,
|
||||
UINT start_index_location,
|
||||
INT base_vertex_location,
|
||||
UINT start_instance_location) {
|
||||
auto& args = *reinterpret_cast<D3DDrawIndexedInstancedArguments*>(
|
||||
WriteCommand(Command::kD3DDrawIndexedInstanced,
|
||||
sizeof(D3DDrawIndexedInstancedArguments)));
|
||||
args.index_count_per_instance = index_count_per_instance;
|
||||
args.instance_count = instance_count;
|
||||
args.start_index_location = start_index_location;
|
||||
args.base_vertex_location = base_vertex_location;
|
||||
args.start_instance_location = start_instance_location;
|
||||
}
|
||||
|
||||
inline void D3DDrawInstanced(UINT vertex_count_per_instance,
|
||||
UINT instance_count, UINT start_vertex_location,
|
||||
UINT start_instance_location) {
|
||||
auto& args = *reinterpret_cast<D3DDrawInstancedArguments*>(WriteCommand(
|
||||
Command::kD3DDrawInstanced, sizeof(D3DDrawInstancedArguments)));
|
||||
args.vertex_count_per_instance = vertex_count_per_instance;
|
||||
args.instance_count = instance_count;
|
||||
args.start_vertex_location = start_vertex_location;
|
||||
args.start_instance_location = start_instance_location;
|
||||
}
|
||||
|
||||
inline void D3DIASetIndexBuffer(const D3D12_INDEX_BUFFER_VIEW* view) {
|
||||
auto& args = *reinterpret_cast<D3D12_INDEX_BUFFER_VIEW*>(WriteCommand(
|
||||
Command::kD3DIASetIndexBuffer, sizeof(D3D12_INDEX_BUFFER_VIEW)));
|
||||
if (view != nullptr) {
|
||||
args.BufferLocation = view->BufferLocation;
|
||||
args.SizeInBytes = view->SizeInBytes;
|
||||
args.Format = view->Format;
|
||||
} else {
|
||||
args.BufferLocation = D3D12_GPU_VIRTUAL_ADDRESS(0);
|
||||
args.SizeInBytes = 0;
|
||||
args.Format = DXGI_FORMAT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
inline void D3DIASetPrimitiveTopology(
|
||||
D3D12_PRIMITIVE_TOPOLOGY primitive_topology) {
|
||||
auto& arg = *reinterpret_cast<D3D12_PRIMITIVE_TOPOLOGY*>(WriteCommand(
|
||||
Command::kD3DIASetPrimitiveTopology, sizeof(D3D12_PRIMITIVE_TOPOLOGY)));
|
||||
arg = primitive_topology;
|
||||
}
|
||||
|
||||
inline void D3DOMSetBlendFactor(const FLOAT blend_factor[4]) {
|
||||
auto args = reinterpret_cast<FLOAT*>(
|
||||
WriteCommand(Command::kD3DOMSetBlendFactor, 4 * sizeof(FLOAT)));
|
||||
args[0] = blend_factor[0];
|
||||
args[1] = blend_factor[1];
|
||||
args[2] = blend_factor[2];
|
||||
args[3] = blend_factor[3];
|
||||
}
|
||||
|
||||
inline void D3DOMSetRenderTargets(
|
||||
UINT num_render_target_descriptors,
|
||||
const D3D12_CPU_DESCRIPTOR_HANDLE* render_target_descriptors,
|
||||
BOOL rts_single_handle_to_descriptor_range,
|
||||
const D3D12_CPU_DESCRIPTOR_HANDLE* depth_stencil_descriptor) {
|
||||
auto& args = *reinterpret_cast<D3DOMSetRenderTargetsArguments*>(
|
||||
WriteCommand(Command::kD3DOMSetRenderTargets,
|
||||
sizeof(D3DOMSetRenderTargetsArguments)));
|
||||
num_render_target_descriptors =
|
||||
std::min(num_render_target_descriptors,
|
||||
UINT(D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT));
|
||||
args.num_render_target_descriptors = num_render_target_descriptors;
|
||||
args.rts_single_handle_to_descriptor_range =
|
||||
rts_single_handle_to_descriptor_range ? 1 : 0;
|
||||
if (num_render_target_descriptors != 0) {
|
||||
std::memcpy(args.render_target_descriptors, render_target_descriptors,
|
||||
(rts_single_handle_to_descriptor_range
|
||||
? 1
|
||||
: num_render_target_descriptors) *
|
||||
sizeof(D3D12_CPU_DESCRIPTOR_HANDLE));
|
||||
}
|
||||
args.depth_stencil = (depth_stencil_descriptor != nullptr) ? 1 : 0;
|
||||
if (depth_stencil_descriptor != nullptr) {
|
||||
args.depth_stencil_descriptor.ptr = depth_stencil_descriptor->ptr;
|
||||
}
|
||||
}
|
||||
|
||||
inline void D3DOMSetStencilRef(UINT stencil_ref) {
|
||||
auto& arg = *reinterpret_cast<UINT*>(
|
||||
WriteCommand(Command::kD3DOMSetStencilRef, sizeof(UINT)));
|
||||
arg = stencil_ref;
|
||||
}
|
||||
|
||||
inline void D3DResourceBarrier(UINT num_barriers,
|
||||
const D3D12_RESOURCE_BARRIER* barriers) {
|
||||
if (num_barriers == 0) {
|
||||
return;
|
||||
}
|
||||
const size_t header_size =
|
||||
xe::align(sizeof(UINT), alignof(D3D12_RESOURCE_BARRIER));
|
||||
uint8_t* args = reinterpret_cast<uint8_t*>(WriteCommand(
|
||||
Command::kD3DResourceBarrier,
|
||||
header_size + num_barriers * sizeof(D3D12_RESOURCE_BARRIER)));
|
||||
*reinterpret_cast<UINT*>(args) = num_barriers;
|
||||
std::memcpy(args + header_size, barriers,
|
||||
num_barriers * sizeof(D3D12_RESOURCE_BARRIER));
|
||||
}
|
||||
|
||||
inline void RSSetScissorRect(const D3D12_RECT& rect) {
|
||||
auto& arg = *reinterpret_cast<D3D12_RECT*>(
|
||||
WriteCommand(Command::kRSSetScissorRect, sizeof(D3D12_RECT)));
|
||||
arg = rect;
|
||||
}
|
||||
|
||||
inline void RSSetViewport(const D3D12_VIEWPORT& viewport) {
|
||||
auto& arg = *reinterpret_cast<D3D12_VIEWPORT*>(
|
||||
WriteCommand(Command::kRSSetViewport, sizeof(D3D12_VIEWPORT)));
|
||||
arg = viewport;
|
||||
}
|
||||
|
||||
inline void D3DSetComputeRoot32BitConstants(
|
||||
UINT root_parameter_index, UINT num_32bit_values_to_set,
|
||||
const void* src_data, UINT dest_offset_in_32bit_values) {
|
||||
if (num_32bit_values_to_set == 0) {
|
||||
return;
|
||||
}
|
||||
auto args = reinterpret_cast<SetRoot32BitConstantsHeader*>(
|
||||
WriteCommand(Command::kD3DSetComputeRoot32BitConstants,
|
||||
sizeof(SetRoot32BitConstantsHeader) +
|
||||
num_32bit_values_to_set * sizeof(uint32_t)));
|
||||
args->root_parameter_index = root_parameter_index;
|
||||
args->num_32bit_values_to_set = num_32bit_values_to_set;
|
||||
args->dest_offset_in_32bit_values = dest_offset_in_32bit_values;
|
||||
std::memcpy(args + 1, src_data, num_32bit_values_to_set * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
inline void D3DSetGraphicsRoot32BitConstants(
|
||||
UINT root_parameter_index, UINT num_32bit_values_to_set,
|
||||
const void* src_data, UINT dest_offset_in_32bit_values) {
|
||||
if (num_32bit_values_to_set == 0) {
|
||||
return;
|
||||
}
|
||||
auto args = reinterpret_cast<SetRoot32BitConstantsHeader*>(
|
||||
WriteCommand(Command::kD3DSetGraphicsRoot32BitConstants,
|
||||
sizeof(SetRoot32BitConstantsHeader) +
|
||||
num_32bit_values_to_set * sizeof(uint32_t)));
|
||||
args->root_parameter_index = root_parameter_index;
|
||||
args->num_32bit_values_to_set = num_32bit_values_to_set;
|
||||
args->dest_offset_in_32bit_values = dest_offset_in_32bit_values;
|
||||
std::memcpy(args + 1, src_data, num_32bit_values_to_set * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
inline void D3DSetComputeRootConstantBufferView(
|
||||
UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS buffer_location) {
|
||||
auto& args = *reinterpret_cast<SetRootConstantBufferViewArguments*>(
|
||||
WriteCommand(Command::kD3DSetComputeRootConstantBufferView,
|
||||
sizeof(SetRootConstantBufferViewArguments)));
|
||||
args.root_parameter_index = root_parameter_index;
|
||||
args.buffer_location = buffer_location;
|
||||
}
|
||||
|
||||
inline void D3DSetGraphicsRootConstantBufferView(
|
||||
UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS buffer_location) {
|
||||
auto& args = *reinterpret_cast<SetRootConstantBufferViewArguments*>(
|
||||
WriteCommand(Command::kD3DSetGraphicsRootConstantBufferView,
|
||||
sizeof(SetRootConstantBufferViewArguments)));
|
||||
args.root_parameter_index = root_parameter_index;
|
||||
args.buffer_location = buffer_location;
|
||||
}
|
||||
|
||||
inline void D3DSetComputeRootDescriptorTable(
|
||||
UINT root_parameter_index, D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor) {
|
||||
auto& args = *reinterpret_cast<SetRootDescriptorTableArguments*>(
|
||||
WriteCommand(Command::kD3DSetComputeRootDescriptorTable,
|
||||
sizeof(SetRootDescriptorTableArguments)));
|
||||
args.root_parameter_index = root_parameter_index;
|
||||
args.base_descriptor.ptr = base_descriptor.ptr;
|
||||
}
|
||||
|
||||
inline void D3DSetGraphicsRootDescriptorTable(
|
||||
UINT root_parameter_index, D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor) {
|
||||
auto& args = *reinterpret_cast<SetRootDescriptorTableArguments*>(
|
||||
WriteCommand(Command::kD3DSetGraphicsRootDescriptorTable,
|
||||
sizeof(SetRootDescriptorTableArguments)));
|
||||
args.root_parameter_index = root_parameter_index;
|
||||
args.base_descriptor.ptr = base_descriptor.ptr;
|
||||
}
|
||||
|
||||
inline void D3DSetComputeRootSignature(ID3D12RootSignature* root_signature) {
|
||||
auto& arg = *reinterpret_cast<ID3D12RootSignature**>(WriteCommand(
|
||||
Command::kD3DSetComputeRootSignature, sizeof(ID3D12RootSignature*)));
|
||||
arg = root_signature;
|
||||
}
|
||||
|
||||
inline void D3DSetGraphicsRootSignature(ID3D12RootSignature* root_signature) {
|
||||
auto& arg = *reinterpret_cast<ID3D12RootSignature**>(WriteCommand(
|
||||
Command::kD3DSetGraphicsRootSignature, sizeof(ID3D12RootSignature*)));
|
||||
arg = root_signature;
|
||||
}
|
||||
|
||||
inline void SetDescriptorHeaps(
|
||||
ID3D12DescriptorHeap* cbv_srv_uav_descriptor_heap,
|
||||
ID3D12DescriptorHeap* sampler_descriptor_heap) {
|
||||
auto& args = *reinterpret_cast<SetDescriptorHeapsArguments*>(WriteCommand(
|
||||
Command::kSetDescriptorHeaps, sizeof(SetDescriptorHeapsArguments)));
|
||||
args.cbv_srv_uav_descriptor_heap = cbv_srv_uav_descriptor_heap;
|
||||
args.sampler_descriptor_heap = sampler_descriptor_heap;
|
||||
}
|
||||
|
||||
inline void D3DSetPipelineState(ID3D12PipelineState* pipeline_state) {
|
||||
auto& arg = *reinterpret_cast<ID3D12PipelineState**>(WriteCommand(
|
||||
Command::kD3DSetPipelineState, sizeof(ID3D12PipelineState*)));
|
||||
arg = pipeline_state;
|
||||
}
|
||||
|
||||
inline void D3DSetSamplePositions(
|
||||
UINT num_samples_per_pixel, UINT num_pixels,
|
||||
const D3D12_SAMPLE_POSITION* sample_positions) {
|
||||
auto& args = *reinterpret_cast<D3DSetSamplePositionsArguments*>(
|
||||
WriteCommand(Command::kD3DSetSamplePositions,
|
||||
sizeof(D3DSetSamplePositionsArguments)));
|
||||
args.num_samples_per_pixel = num_samples_per_pixel;
|
||||
args.num_pixels = num_pixels;
|
||||
std::memcpy(args.sample_positions, sample_positions,
|
||||
std::min(num_samples_per_pixel * num_pixels, UINT(16)) *
|
||||
sizeof(D3D12_SAMPLE_POSITION));
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr size_t kAlignment = std::max(sizeof(void*), sizeof(UINT64));
|
||||
|
||||
enum class Command : uint32_t {
|
||||
kD3DCopyBufferRegion,
|
||||
kD3DCopyResource,
|
||||
kCopyTexture,
|
||||
kD3DDispatch,
|
||||
kD3DDrawIndexedInstanced,
|
||||
kD3DDrawInstanced,
|
||||
kD3DIASetIndexBuffer,
|
||||
kD3DIASetPrimitiveTopology,
|
||||
kD3DOMSetBlendFactor,
|
||||
kD3DOMSetRenderTargets,
|
||||
kD3DOMSetStencilRef,
|
||||
kD3DResourceBarrier,
|
||||
kRSSetScissorRect,
|
||||
kRSSetViewport,
|
||||
kD3DSetComputeRoot32BitConstants,
|
||||
kD3DSetGraphicsRoot32BitConstants,
|
||||
kD3DSetComputeRootConstantBufferView,
|
||||
kD3DSetGraphicsRootConstantBufferView,
|
||||
kD3DSetComputeRootDescriptorTable,
|
||||
kD3DSetGraphicsRootDescriptorTable,
|
||||
kD3DSetComputeRootSignature,
|
||||
kD3DSetGraphicsRootSignature,
|
||||
kSetDescriptorHeaps,
|
||||
kD3DSetPipelineState,
|
||||
kD3DSetSamplePositions,
|
||||
};
|
||||
|
||||
struct D3DCopyBufferRegionArguments {
|
||||
ID3D12Resource* dst_buffer;
|
||||
UINT64 dst_offset;
|
||||
ID3D12Resource* src_buffer;
|
||||
UINT64 src_offset;
|
||||
UINT64 num_bytes;
|
||||
};
|
||||
|
||||
struct D3DCopyResourceArguments {
|
||||
ID3D12Resource* dst_resource;
|
||||
ID3D12Resource* src_resource;
|
||||
};
|
||||
|
||||
struct CopyTextureArguments {
|
||||
D3D12_TEXTURE_COPY_LOCATION dst;
|
||||
D3D12_TEXTURE_COPY_LOCATION src;
|
||||
};
|
||||
|
||||
struct D3DDispatchArguments {
|
||||
UINT thread_group_count_x;
|
||||
UINT thread_group_count_y;
|
||||
UINT thread_group_count_z;
|
||||
};
|
||||
|
||||
struct D3DDrawIndexedInstancedArguments {
|
||||
UINT index_count_per_instance;
|
||||
UINT instance_count;
|
||||
UINT start_index_location;
|
||||
INT base_vertex_location;
|
||||
UINT start_instance_location;
|
||||
};
|
||||
|
||||
struct D3DDrawInstancedArguments {
|
||||
UINT vertex_count_per_instance;
|
||||
UINT instance_count;
|
||||
UINT start_vertex_location;
|
||||
UINT start_instance_location;
|
||||
};
|
||||
|
||||
struct D3DOMSetRenderTargetsArguments {
|
||||
uint8_t num_render_target_descriptors;
|
||||
bool rts_single_handle_to_descriptor_range;
|
||||
bool depth_stencil;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE
|
||||
render_target_descriptors[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT];
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE depth_stencil_descriptor;
|
||||
};
|
||||
|
||||
struct SetRoot32BitConstantsHeader {
|
||||
UINT root_parameter_index;
|
||||
UINT num_32bit_values_to_set;
|
||||
UINT dest_offset_in_32bit_values;
|
||||
};
|
||||
|
||||
struct SetRootConstantBufferViewArguments {
|
||||
UINT root_parameter_index;
|
||||
D3D12_GPU_VIRTUAL_ADDRESS buffer_location;
|
||||
};
|
||||
|
||||
struct SetRootDescriptorTableArguments {
|
||||
UINT root_parameter_index;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor;
|
||||
};
|
||||
|
||||
struct SetDescriptorHeapsArguments {
|
||||
ID3D12DescriptorHeap* cbv_srv_uav_descriptor_heap;
|
||||
ID3D12DescriptorHeap* sampler_descriptor_heap;
|
||||
};
|
||||
|
||||
struct D3DSetSamplePositionsArguments {
|
||||
UINT num_samples_per_pixel;
|
||||
UINT num_pixels;
|
||||
D3D12_SAMPLE_POSITION sample_positions[16];
|
||||
};
|
||||
|
||||
void* WriteCommand(Command command, size_t arguments_size);
|
||||
|
||||
D3D12CommandProcessor* command_processor_;
|
||||
|
||||
std::vector<uint8_t> command_stream_;
|
||||
};
|
||||
|
||||
} // namespace d3d12
|
||||
} // namespace gpu
|
||||
} // namespace xe
|
||||
|
||||
#endif // XENIA_GPU_D3D12_DEFERRED_COMMAND_LIST_H_
|
Loading…
Reference in New Issue