[D3D12] Use deferred command list
This commit is contained in:
parent
f0c662fa1e
commit
364cae6cc8
|
@ -66,24 +66,6 @@ void D3D12CommandProcessor::RequestFrameTrace(const std::wstring& root_path) {
|
|||
CommandProcessor::RequestFrameTrace(root_path);
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList* D3D12CommandProcessor::GetCurrentCommandList()
|
||||
const {
|
||||
assert_true(current_queue_frame_ != UINT_MAX);
|
||||
if (current_queue_frame_ == UINT_MAX) {
|
||||
return nullptr;
|
||||
}
|
||||
return command_lists_[current_queue_frame_]->GetCommandList();
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList1* D3D12CommandProcessor::GetCurrentCommandList1()
|
||||
const {
|
||||
assert_true(current_queue_frame_ != UINT_MAX);
|
||||
if (current_queue_frame_ == UINT_MAX) {
|
||||
return nullptr;
|
||||
}
|
||||
return command_lists_[current_queue_frame_]->GetCommandList1();
|
||||
}
|
||||
|
||||
bool D3D12CommandProcessor::IsROVUsedForEDRAM() const {
|
||||
if (!FLAGS_d3d12_edram_rov) {
|
||||
return false;
|
||||
|
@ -144,7 +126,7 @@ void D3D12CommandProcessor::PushUAVBarrier(ID3D12Resource* resource) {
|
|||
void D3D12CommandProcessor::SubmitBarriers() {
|
||||
UINT barrier_count = UINT(barriers_.size());
|
||||
if (barrier_count != 0) {
|
||||
GetCurrentCommandList()->ResourceBarrier(barrier_count, barriers_.data());
|
||||
deferred_command_list_->D3DResourceBarrier(barrier_count, barriers_.data());
|
||||
barriers_.clear();
|
||||
}
|
||||
}
|
||||
|
@ -451,15 +433,9 @@ uint64_t D3D12CommandProcessor::RequestViewDescriptors(
|
|||
}
|
||||
ID3D12DescriptorHeap* heap = view_heap_pool_->GetLastRequestHeap();
|
||||
if (current_view_heap_ != heap) {
|
||||
// Bind the new descriptor heaps if needed.
|
||||
current_view_heap_ = heap;
|
||||
ID3D12DescriptorHeap* heaps[2];
|
||||
uint32_t heap_count = 0;
|
||||
heaps[heap_count++] = heap;
|
||||
if (current_sampler_heap_ != nullptr) {
|
||||
heaps[heap_count++] = current_sampler_heap_;
|
||||
}
|
||||
GetCurrentCommandList()->SetDescriptorHeaps(heap_count, heaps);
|
||||
deferred_command_list_->SetDescriptorHeaps(current_view_heap_,
|
||||
current_sampler_heap_);
|
||||
}
|
||||
auto provider = GetD3D12Context()->GetD3D12Provider();
|
||||
cpu_handle_out = provider->OffsetViewDescriptor(
|
||||
|
@ -483,15 +459,9 @@ uint64_t D3D12CommandProcessor::RequestSamplerDescriptors(
|
|||
}
|
||||
ID3D12DescriptorHeap* heap = sampler_heap_pool_->GetLastRequestHeap();
|
||||
if (current_sampler_heap_ != heap) {
|
||||
// Bind the new descriptor heaps if needed.
|
||||
current_sampler_heap_ = heap;
|
||||
ID3D12DescriptorHeap* heaps[2];
|
||||
uint32_t heap_count = 0;
|
||||
heaps[heap_count++] = heap;
|
||||
if (current_view_heap_ != nullptr) {
|
||||
heaps[heap_count++] = current_view_heap_;
|
||||
}
|
||||
GetCurrentCommandList()->SetDescriptorHeaps(heap_count, heaps);
|
||||
deferred_command_list_->SetDescriptorHeaps(current_view_heap_,
|
||||
current_sampler_heap_);
|
||||
}
|
||||
uint32_t descriptor_offset =
|
||||
descriptor_index *
|
||||
|
@ -567,8 +537,8 @@ void D3D12CommandProcessor::SetSamplePositions(MsaaSamples sample_positions) {
|
|||
if (FLAGS_d3d12_ssaa_custom_sample_positions && !IsROVUsedForEDRAM()) {
|
||||
auto provider = GetD3D12Context()->GetD3D12Provider();
|
||||
auto tier = provider->GetProgrammableSamplePositionsTier();
|
||||
auto command_list = GetCurrentCommandList1();
|
||||
if (tier >= 2 && command_list != nullptr) {
|
||||
if (tier >= 2 &&
|
||||
command_lists_[current_queue_frame_]->GetCommandList1() != nullptr) {
|
||||
// Depth buffer transitions are affected by sample positions.
|
||||
SubmitBarriers();
|
||||
// Standard sample positions in Direct3D 10.1, but adjusted to take the
|
||||
|
@ -606,9 +576,10 @@ void D3D12CommandProcessor::SetSamplePositions(MsaaSamples sample_positions) {
|
|||
d3d_sample_positions[3].X = 4;
|
||||
d3d_sample_positions[3].Y = 4 - 4;
|
||||
}
|
||||
command_list->SetSamplePositions(1, 4, d3d_sample_positions);
|
||||
deferred_command_list_->D3DSetSamplePositions(1, 4,
|
||||
d3d_sample_positions);
|
||||
} else {
|
||||
command_list->SetSamplePositions(0, 0, nullptr);
|
||||
deferred_command_list_->D3DSetSamplePositions(0, 0, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -617,7 +588,7 @@ void D3D12CommandProcessor::SetSamplePositions(MsaaSamples sample_positions) {
|
|||
|
||||
void D3D12CommandProcessor::SetComputePipeline(ID3D12PipelineState* pipeline) {
|
||||
if (current_pipeline_ != pipeline) {
|
||||
GetCurrentCommandList()->SetPipelineState(pipeline);
|
||||
deferred_command_list_->D3DSetPipelineState(pipeline);
|
||||
current_pipeline_ = pipeline;
|
||||
}
|
||||
}
|
||||
|
@ -630,7 +601,7 @@ void D3D12CommandProcessor::SetExternalGraphicsPipeline(
|
|||
ID3D12PipelineState* pipeline, bool reset_viewport, bool reset_blend_factor,
|
||||
bool reset_stencil_ref) {
|
||||
if (current_pipeline_ != pipeline) {
|
||||
GetCurrentCommandList()->SetPipelineState(pipeline);
|
||||
deferred_command_list_->D3DSetPipelineState(pipeline);
|
||||
current_pipeline_ = pipeline;
|
||||
}
|
||||
current_graphics_root_signature_ = nullptr;
|
||||
|
@ -680,6 +651,7 @@ bool D3D12CommandProcessor::SetupContext() {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
deferred_command_list_ = std::make_unique<DeferredCommandList>(this);
|
||||
|
||||
constant_buffer_pool_ =
|
||||
std::make_unique<ui::d3d12::UploadBufferPool>(context, 1024 * 1024);
|
||||
|
@ -902,6 +874,7 @@ void D3D12CommandProcessor::ShutdownContext() {
|
|||
|
||||
shared_memory_.reset();
|
||||
|
||||
deferred_command_list_.reset();
|
||||
for (uint32_t i = 0; i < ui::d3d12::D3D12Context::kQueuedFrames; ++i) {
|
||||
command_lists_[i].reset();
|
||||
}
|
||||
|
@ -959,7 +932,6 @@ void D3D12CommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
|||
|
||||
auto provider = GetD3D12Context()->GetD3D12Provider();
|
||||
auto device = provider->GetDevice();
|
||||
auto command_list = GetCurrentCommandList();
|
||||
|
||||
// Upload the new gamma ramps.
|
||||
if (dirty_gamma_ramp_normal_) {
|
||||
|
@ -985,8 +957,7 @@ void D3D12CommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
|||
location_dest.pResource = gamma_ramp_texture_;
|
||||
location_dest.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
location_dest.SubresourceIndex = 0;
|
||||
command_list->CopyTextureRegion(&location_dest, 0, 0, 0, &location_source,
|
||||
nullptr);
|
||||
deferred_command_list_->CopyTexture(location_dest, location_source);
|
||||
dirty_gamma_ramp_normal_ = false;
|
||||
}
|
||||
if (dirty_gamma_ramp_pwl_) {
|
||||
|
@ -1011,8 +982,7 @@ void D3D12CommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
|||
location_dest.pResource = gamma_ramp_texture_;
|
||||
location_dest.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
location_dest.SubresourceIndex = 1;
|
||||
command_list->CopyTextureRegion(&location_dest, 0, 0, 0, &location_source,
|
||||
nullptr);
|
||||
deferred_command_list_->CopyTexture(location_dest, location_source);
|
||||
dirty_gamma_ramp_pwl_ = false;
|
||||
}
|
||||
|
||||
|
@ -1063,7 +1033,8 @@ void D3D12CommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
|||
}
|
||||
|
||||
// Draw the stretching rectangle.
|
||||
command_list->OMSetRenderTargets(1, &swap_texture_rtv_, TRUE, nullptr);
|
||||
deferred_command_list_->D3DOMSetRenderTargets(1, &swap_texture_rtv_, TRUE,
|
||||
nullptr);
|
||||
D3D12_VIEWPORT viewport;
|
||||
viewport.TopLeftX = 0.0f;
|
||||
viewport.TopLeftY = 0.0f;
|
||||
|
@ -1071,20 +1042,21 @@ void D3D12CommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
|||
viewport.Height = float(swap_texture_height);
|
||||
viewport.MinDepth = 0.0f;
|
||||
viewport.MaxDepth = 0.0f;
|
||||
command_list->RSSetViewports(1, &viewport);
|
||||
deferred_command_list_->RSSetViewport(viewport);
|
||||
D3D12_RECT scissor;
|
||||
scissor.left = 0;
|
||||
scissor.top = 0;
|
||||
scissor.right = swap_texture_width;
|
||||
scissor.bottom = swap_texture_height;
|
||||
command_list->RSSetScissorRects(1, &scissor);
|
||||
deferred_command_list_->RSSetScissorRect(scissor);
|
||||
D3D12GraphicsSystem* graphics_system =
|
||||
static_cast<D3D12GraphicsSystem*>(graphics_system_);
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE gamma_ramp_gpu_handle =
|
||||
provider->OffsetViewDescriptor(descriptor_gpu_start, 1);
|
||||
graphics_system->StretchTextureToFrontBuffer(
|
||||
descriptor_gpu_start, &gamma_ramp_gpu_handle,
|
||||
use_pwl_gamma_ramp ? (1.0f / 128.0f) : (1.0f / 256.0f), command_list);
|
||||
use_pwl_gamma_ramp ? (1.0f / 128.0f) : (1.0f / 256.0f),
|
||||
*deferred_command_list_);
|
||||
// Ending the current frame's command list anyway, so no need to unbind
|
||||
// the render targets when using ROV.
|
||||
|
||||
|
@ -1219,7 +1191,6 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
|||
}
|
||||
|
||||
bool new_frame = BeginFrame();
|
||||
auto command_list = GetCurrentCommandList();
|
||||
|
||||
// Set up the render targets - this may bind pipelines.
|
||||
if (!render_target_cache_->UpdateRenderTargets(pixel_shader)) {
|
||||
|
@ -1299,7 +1270,7 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
|||
}
|
||||
if (primitive_topology_ != primitive_topology) {
|
||||
primitive_topology_ = primitive_topology;
|
||||
command_list->IASetPrimitiveTopology(primitive_topology);
|
||||
deferred_command_list_->D3DIASetPrimitiveTopology(primitive_topology);
|
||||
}
|
||||
|
||||
// Update the textures - this may bind pipelines.
|
||||
|
@ -1317,12 +1288,12 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
|||
return false;
|
||||
}
|
||||
if (current_pipeline_ != pipeline) {
|
||||
GetCurrentCommandList()->SetPipelineState(pipeline);
|
||||
deferred_command_list_->D3DSetPipelineState(pipeline);
|
||||
current_pipeline_ = pipeline;
|
||||
}
|
||||
|
||||
// Update viewport, scissor, blend factor and stencil reference.
|
||||
UpdateFixedFunctionState(command_list);
|
||||
UpdateFixedFunctionState();
|
||||
|
||||
// Update system constants before uploading them.
|
||||
UpdateSystemConstantValues(
|
||||
|
@ -1332,8 +1303,7 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
|||
color_mask, pipeline_render_targets);
|
||||
|
||||
// Update constant buffers, descriptors and root parameters.
|
||||
if (!UpdateBindings(command_list, vertex_shader, pixel_shader,
|
||||
root_signature)) {
|
||||
if (!UpdateBindings(vertex_shader, pixel_shader, root_signature)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1532,13 +1502,13 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
|||
} else {
|
||||
shared_memory_->UseForReading();
|
||||
}
|
||||
command_list->IASetIndexBuffer(&index_buffer_view);
|
||||
deferred_command_list_->D3DIASetIndexBuffer(&index_buffer_view);
|
||||
SubmitBarriers();
|
||||
if (adaptive_tessellation) {
|
||||
// Index buffer used for per-edge factors.
|
||||
command_list->DrawInstanced(index_count, 1, 0, 0);
|
||||
deferred_command_list_->D3DDrawInstanced(index_count, 1, 0, 0);
|
||||
} else {
|
||||
command_list->DrawIndexedInstanced(index_count, 1, 0, 0, 0);
|
||||
deferred_command_list_->D3DDrawIndexedInstanced(index_count, 1, 0, 0, 0);
|
||||
}
|
||||
} else {
|
||||
// Check if need to draw using a conversion index buffer.
|
||||
|
@ -1557,10 +1527,11 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
|||
index_buffer_view.BufferLocation = conversion_gpu_address;
|
||||
index_buffer_view.SizeInBytes = converted_index_count * sizeof(uint16_t);
|
||||
index_buffer_view.Format = DXGI_FORMAT_R16_UINT;
|
||||
command_list->IASetIndexBuffer(&index_buffer_view);
|
||||
command_list->DrawIndexedInstanced(converted_index_count, 1, 0, 0, 0);
|
||||
deferred_command_list_->D3DIASetIndexBuffer(&index_buffer_view);
|
||||
deferred_command_list_->D3DDrawIndexedInstanced(converted_index_count, 1,
|
||||
0, 0, 0);
|
||||
} else {
|
||||
command_list->DrawInstanced(index_count, 1, 0, 0);
|
||||
deferred_command_list_->D3DDrawInstanced(index_count, 1, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1659,7 +1630,7 @@ bool D3D12CommandProcessor::BeginFrame() {
|
|||
graphics_analysis->BeginCapture();
|
||||
}
|
||||
}
|
||||
command_lists_[current_queue_frame_]->BeginRecording();
|
||||
deferred_command_list_->Reset();
|
||||
|
||||
constant_buffer_pool_->BeginFrame();
|
||||
view_heap_pool_->BeginFrame();
|
||||
|
@ -1694,7 +1665,13 @@ bool D3D12CommandProcessor::EndFrame() {
|
|||
// Submit barriers now because resources the queued barriers are for may be
|
||||
// destroyed between frames.
|
||||
SubmitBarriers();
|
||||
command_lists_[current_queue_frame_]->Execute();
|
||||
|
||||
// Submit the command list.
|
||||
auto current_command_list = command_lists_[current_queue_frame_].get();
|
||||
current_command_list->BeginRecording();
|
||||
deferred_command_list_->Execute(current_command_list->GetCommandList(),
|
||||
current_command_list->GetCommandList1());
|
||||
current_command_list->Execute();
|
||||
|
||||
if (pix_capturing_) {
|
||||
IDXGraphicsAnalysis* graphics_analysis =
|
||||
|
@ -1716,8 +1693,7 @@ bool D3D12CommandProcessor::EndFrame() {
|
|||
return true;
|
||||
}
|
||||
|
||||
void D3D12CommandProcessor::UpdateFixedFunctionState(
|
||||
ID3D12GraphicsCommandList* command_list) {
|
||||
void D3D12CommandProcessor::UpdateFixedFunctionState() {
|
||||
auto& regs = *register_file_;
|
||||
|
||||
#if FINE_GRAINED_DRAW_SCOPES
|
||||
|
@ -1814,7 +1790,7 @@ void D3D12CommandProcessor::UpdateFixedFunctionState(
|
|||
ff_viewport_update_needed_ |= ff_viewport_.MaxDepth != viewport.MaxDepth;
|
||||
if (ff_viewport_update_needed_) {
|
||||
ff_viewport_ = viewport;
|
||||
command_list->RSSetViewports(1, &viewport);
|
||||
deferred_command_list_->RSSetViewport(viewport);
|
||||
ff_viewport_update_needed_ = false;
|
||||
}
|
||||
|
||||
|
@ -1845,7 +1821,7 @@ void D3D12CommandProcessor::UpdateFixedFunctionState(
|
|||
ff_scissor_update_needed_ |= ff_scissor_.bottom != scissor.bottom;
|
||||
if (ff_scissor_update_needed_) {
|
||||
ff_scissor_ = scissor;
|
||||
command_list->RSSetScissorRects(1, &scissor);
|
||||
deferred_command_list_->RSSetScissorRect(scissor);
|
||||
ff_scissor_update_needed_ = false;
|
||||
}
|
||||
|
||||
|
@ -1864,7 +1840,7 @@ void D3D12CommandProcessor::UpdateFixedFunctionState(
|
|||
ff_blend_factor_[1] = regs[XE_GPU_REG_RB_BLEND_GREEN].f32;
|
||||
ff_blend_factor_[2] = regs[XE_GPU_REG_RB_BLEND_BLUE].f32;
|
||||
ff_blend_factor_[3] = regs[XE_GPU_REG_RB_BLEND_ALPHA].f32;
|
||||
command_list->OMSetBlendFactor(ff_blend_factor_);
|
||||
deferred_command_list_->D3DOMSetBlendFactor(ff_blend_factor_);
|
||||
ff_blend_factor_update_needed_ = false;
|
||||
}
|
||||
|
||||
|
@ -1873,7 +1849,7 @@ void D3D12CommandProcessor::UpdateFixedFunctionState(
|
|||
ff_stencil_ref_update_needed_ |= ff_stencil_ref_ != stencil_ref;
|
||||
if (ff_stencil_ref_update_needed_) {
|
||||
ff_stencil_ref_ = stencil_ref;
|
||||
command_list->OMSetStencilRef(stencil_ref);
|
||||
deferred_command_list_->D3DOMSetStencilRef(stencil_ref);
|
||||
ff_stencil_ref_update_needed_ = false;
|
||||
}
|
||||
}
|
||||
|
@ -2493,8 +2469,8 @@ void D3D12CommandProcessor::UpdateSystemConstantValues(
|
|||
}
|
||||
|
||||
bool D3D12CommandProcessor::UpdateBindings(
|
||||
ID3D12GraphicsCommandList* command_list, const D3D12Shader* vertex_shader,
|
||||
const D3D12Shader* pixel_shader, ID3D12RootSignature* root_signature) {
|
||||
const D3D12Shader* vertex_shader, const D3D12Shader* pixel_shader,
|
||||
ID3D12RootSignature* root_signature) {
|
||||
auto provider = GetD3D12Context()->GetD3D12Provider();
|
||||
auto device = provider->GetDevice();
|
||||
auto& regs = *register_file_;
|
||||
|
@ -2510,7 +2486,7 @@ bool D3D12CommandProcessor::UpdateBindings(
|
|||
current_graphics_root_extras_);
|
||||
// We don't know which root parameters are up to date anymore.
|
||||
current_graphics_root_up_to_date_ = 0;
|
||||
command_list->SetGraphicsRootSignature(root_signature);
|
||||
deferred_command_list_->D3DSetGraphicsRootSignature(root_signature);
|
||||
}
|
||||
|
||||
XXH64_state_t hash_state;
|
||||
|
@ -2953,13 +2929,13 @@ bool D3D12CommandProcessor::UpdateBindings(
|
|||
// Update the root parameters.
|
||||
if (!(current_graphics_root_up_to_date_ &
|
||||
(1u << kRootParameter_FetchConstants))) {
|
||||
command_list->SetGraphicsRootDescriptorTable(kRootParameter_FetchConstants,
|
||||
gpu_handle_fetch_constants_);
|
||||
deferred_command_list_->D3DSetGraphicsRootDescriptorTable(
|
||||
kRootParameter_FetchConstants, gpu_handle_fetch_constants_);
|
||||
current_graphics_root_up_to_date_ |= 1u << kRootParameter_FetchConstants;
|
||||
}
|
||||
if (!(current_graphics_root_up_to_date_ &
|
||||
(1u << kRootParameter_FloatConstantsVertex))) {
|
||||
command_list->SetGraphicsRootDescriptorTable(
|
||||
deferred_command_list_->D3DSetGraphicsRootDescriptorTable(
|
||||
kRootParameter_FloatConstantsVertex,
|
||||
gpu_handle_float_constants_vertex_);
|
||||
current_graphics_root_up_to_date_ |= 1u
|
||||
|
@ -2967,26 +2943,26 @@ bool D3D12CommandProcessor::UpdateBindings(
|
|||
}
|
||||
if (!(current_graphics_root_up_to_date_ &
|
||||
(1u << kRootParameter_FloatConstantsPixel))) {
|
||||
command_list->SetGraphicsRootDescriptorTable(
|
||||
deferred_command_list_->D3DSetGraphicsRootDescriptorTable(
|
||||
kRootParameter_FloatConstantsPixel, gpu_handle_float_constants_pixel_);
|
||||
current_graphics_root_up_to_date_ |= 1u
|
||||
<< kRootParameter_FloatConstantsPixel;
|
||||
}
|
||||
if (!(current_graphics_root_up_to_date_ &
|
||||
(1u << kRootParameter_SystemConstants))) {
|
||||
command_list->SetGraphicsRootDescriptorTable(kRootParameter_SystemConstants,
|
||||
gpu_handle_system_constants_);
|
||||
deferred_command_list_->D3DSetGraphicsRootDescriptorTable(
|
||||
kRootParameter_SystemConstants, gpu_handle_system_constants_);
|
||||
current_graphics_root_up_to_date_ |= 1u << kRootParameter_SystemConstants;
|
||||
}
|
||||
if (!(current_graphics_root_up_to_date_ &
|
||||
(1u << kRootParameter_BoolLoopConstants))) {
|
||||
command_list->SetGraphicsRootDescriptorTable(
|
||||
deferred_command_list_->D3DSetGraphicsRootDescriptorTable(
|
||||
kRootParameter_BoolLoopConstants, gpu_handle_bool_loop_constants_);
|
||||
current_graphics_root_up_to_date_ |= 1u << kRootParameter_BoolLoopConstants;
|
||||
}
|
||||
if (!(current_graphics_root_up_to_date_ &
|
||||
(1u << kRootParameter_SharedMemoryAndEDRAM))) {
|
||||
command_list->SetGraphicsRootDescriptorTable(
|
||||
deferred_command_list_->D3DSetGraphicsRootDescriptorTable(
|
||||
kRootParameter_SharedMemoryAndEDRAM,
|
||||
gpu_handle_shared_memory_and_edram_);
|
||||
current_graphics_root_up_to_date_ |= 1u
|
||||
|
@ -2996,29 +2972,29 @@ bool D3D12CommandProcessor::UpdateBindings(
|
|||
extra_index = current_graphics_root_extras_.textures_pixel;
|
||||
if (extra_index != RootExtraParameterIndices::kUnavailable &&
|
||||
!(current_graphics_root_up_to_date_ & (1u << extra_index))) {
|
||||
command_list->SetGraphicsRootDescriptorTable(extra_index,
|
||||
gpu_handle_textures_pixel_);
|
||||
deferred_command_list_->D3DSetGraphicsRootDescriptorTable(
|
||||
extra_index, gpu_handle_textures_pixel_);
|
||||
current_graphics_root_up_to_date_ |= 1u << extra_index;
|
||||
}
|
||||
extra_index = current_graphics_root_extras_.samplers_pixel;
|
||||
if (extra_index != RootExtraParameterIndices::kUnavailable &&
|
||||
!(current_graphics_root_up_to_date_ & (1u << extra_index))) {
|
||||
command_list->SetGraphicsRootDescriptorTable(extra_index,
|
||||
gpu_handle_samplers_pixel_);
|
||||
deferred_command_list_->D3DSetGraphicsRootDescriptorTable(
|
||||
extra_index, gpu_handle_samplers_pixel_);
|
||||
current_graphics_root_up_to_date_ |= 1u << extra_index;
|
||||
}
|
||||
extra_index = current_graphics_root_extras_.textures_vertex;
|
||||
if (extra_index != RootExtraParameterIndices::kUnavailable &&
|
||||
!(current_graphics_root_up_to_date_ & (1u << extra_index))) {
|
||||
command_list->SetGraphicsRootDescriptorTable(extra_index,
|
||||
gpu_handle_textures_vertex_);
|
||||
deferred_command_list_->D3DSetGraphicsRootDescriptorTable(
|
||||
extra_index, gpu_handle_textures_vertex_);
|
||||
current_graphics_root_up_to_date_ |= 1u << extra_index;
|
||||
}
|
||||
extra_index = current_graphics_root_extras_.samplers_vertex;
|
||||
if (extra_index != RootExtraParameterIndices::kUnavailable &&
|
||||
!(current_graphics_root_up_to_date_ & (1u << extra_index))) {
|
||||
command_list->SetGraphicsRootDescriptorTable(extra_index,
|
||||
gpu_handle_samplers_vertex_);
|
||||
deferred_command_list_->D3DSetGraphicsRootDescriptorTable(
|
||||
extra_index, gpu_handle_samplers_vertex_);
|
||||
current_graphics_root_up_to_date_ |= 1u << extra_index;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "xenia/gpu/command_processor.h"
|
||||
#include "xenia/gpu/d3d12/d3d12_graphics_system.h"
|
||||
#include "xenia/gpu/d3d12/deferred_command_list.h"
|
||||
#include "xenia/gpu/d3d12/pipeline_cache.h"
|
||||
#include "xenia/gpu/d3d12/primitive_converter.h"
|
||||
#include "xenia/gpu/d3d12/render_target_cache.h"
|
||||
|
@ -49,9 +50,10 @@ class D3D12CommandProcessor : public CommandProcessor {
|
|||
return static_cast<xe::ui::d3d12::D3D12Context*>(context_.get());
|
||||
}
|
||||
|
||||
// Returns the drawing command list for the currently open frame.
|
||||
ID3D12GraphicsCommandList* GetCurrentCommandList() const;
|
||||
ID3D12GraphicsCommandList1* GetCurrentCommandList1() const;
|
||||
// Returns the deferred drawing command list for the currently open frame.
|
||||
DeferredCommandList* GetDeferredCommandList() {
|
||||
return deferred_command_list_.get();
|
||||
}
|
||||
|
||||
// Should a rasterizer-ordered UAV of the EDRAM buffer with format conversion
|
||||
// and blending performed in pixel shaders be used instead of host render
|
||||
|
@ -200,13 +202,12 @@ class D3D12CommandProcessor : public CommandProcessor {
|
|||
// Returns true if an open frame was ended.
|
||||
bool EndFrame();
|
||||
|
||||
void UpdateFixedFunctionState(ID3D12GraphicsCommandList* command_list);
|
||||
void UpdateFixedFunctionState();
|
||||
void UpdateSystemConstantValues(
|
||||
bool shared_memory_is_uav, PrimitiveType primitive_type,
|
||||
Endian index_endian, uint32_t edge_factor_base, uint32_t color_mask,
|
||||
const RenderTargetCache::PipelineRenderTarget render_targets[4]);
|
||||
bool UpdateBindings(ID3D12GraphicsCommandList* command_list,
|
||||
const D3D12Shader* vertex_shader,
|
||||
bool UpdateBindings(const D3D12Shader* vertex_shader,
|
||||
const D3D12Shader* pixel_shader,
|
||||
ID3D12RootSignature* root_signature);
|
||||
|
||||
|
@ -221,6 +222,7 @@ class D3D12CommandProcessor : public CommandProcessor {
|
|||
|
||||
std::unique_ptr<ui::d3d12::CommandList>
|
||||
command_lists_[ui::d3d12::D3D12Context::kQueuedFrames] = {};
|
||||
std::unique_ptr<DeferredCommandList> deferred_command_list_ = nullptr;
|
||||
|
||||
std::unique_ptr<SharedMemory> shared_memory_ = nullptr;
|
||||
|
||||
|
|
|
@ -210,6 +210,25 @@ void D3D12GraphicsSystem::StretchTextureToFrontBuffer(
|
|||
command_list->DrawInstanced(3, 1, 0, 0);
|
||||
}
|
||||
|
||||
void D3D12GraphicsSystem::StretchTextureToFrontBuffer(
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE handle,
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE* gamma_ramp_handle, float gamma_ramp_inv_size,
|
||||
DeferredCommandList& command_list) {
|
||||
if (gamma_ramp_handle != nullptr) {
|
||||
command_list.D3DSetPipelineState(stretch_gamma_pipeline_);
|
||||
command_list.D3DSetGraphicsRootSignature(stretch_gamma_root_signature_);
|
||||
command_list.D3DSetGraphicsRootDescriptorTable(1, *gamma_ramp_handle);
|
||||
command_list.D3DSetGraphicsRoot32BitConstants(2, 1, &gamma_ramp_inv_size,
|
||||
0);
|
||||
} else {
|
||||
command_list.D3DSetPipelineState(stretch_pipeline_);
|
||||
command_list.D3DSetGraphicsRootSignature(stretch_root_signature_);
|
||||
}
|
||||
command_list.D3DSetGraphicsRootDescriptorTable(0, handle);
|
||||
command_list.D3DIASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
command_list.D3DDrawInstanced(3, 1, 0, 0);
|
||||
}
|
||||
|
||||
std::unique_ptr<CommandProcessor>
|
||||
D3D12GraphicsSystem::CreateCommandProcessor() {
|
||||
return std::unique_ptr<CommandProcessor>(
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <memory>
|
||||
|
||||
#include "xenia/gpu/command_processor.h"
|
||||
#include "xenia/gpu/d3d12/deferred_command_list.h"
|
||||
#include "xenia/gpu/graphics_system.h"
|
||||
#include "xenia/ui/d3d12/d3d12_context.h"
|
||||
|
||||
|
@ -42,6 +43,10 @@ class D3D12GraphicsSystem : public GraphicsSystem {
|
|||
D3D12_GPU_DESCRIPTOR_HANDLE handle,
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE* gamma_ramp_handle, float gamma_ramp_inv_size,
|
||||
ID3D12GraphicsCommandList* command_list);
|
||||
void StretchTextureToFrontBuffer(
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE handle,
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE* gamma_ramp_handle, float gamma_ramp_inv_size,
|
||||
DeferredCommandList& command_list);
|
||||
|
||||
private:
|
||||
std::unique_ptr<CommandProcessor> CreateCommandProcessor() override;
|
||||
|
|
|
@ -66,6 +66,13 @@ void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list,
|
|||
args.start_index_location, args.base_vertex_location,
|
||||
args.start_instance_location);
|
||||
} break;
|
||||
case Command::kD3DDrawInstanced: {
|
||||
auto& args =
|
||||
*reinterpret_cast<const D3DDrawInstancedArguments*>(stream);
|
||||
command_list->DrawInstanced(
|
||||
args.vertex_count_per_instance, args.instance_count,
|
||||
args.start_vertex_location, args.start_instance_location);
|
||||
} break;
|
||||
case Command::kD3DIASetIndexBuffer: {
|
||||
auto view = reinterpret_cast<const D3D12_INDEX_BUFFER_VIEW*>(stream);
|
||||
command_list->IASetIndexBuffer(
|
||||
|
@ -188,7 +195,6 @@ void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list,
|
|||
stream += header[1];
|
||||
stream_remaining -= header[1];
|
||||
}
|
||||
Reset();
|
||||
}
|
||||
|
||||
void* DeferredCommandList::WriteCommand(Command command,
|
||||
|
|
|
@ -127,7 +127,7 @@ void PrimitiveConverter::BeginFrame() {
|
|||
auto context = command_processor_->GetD3D12Context();
|
||||
if (static_ib_upload_frame_ == UINT64_MAX) {
|
||||
// Not uploaded yet - upload.
|
||||
command_processor_->GetCurrentCommandList()->CopyResource(
|
||||
command_processor_->GetDeferredCommandList()->D3DCopyResource(
|
||||
static_ib_, static_ib_upload_);
|
||||
command_processor_->PushTransitionBarrier(
|
||||
static_ib_, D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
|
|
|
@ -466,10 +466,7 @@ bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) {
|
|||
// - New render target is added, but doesn't overlap unsaved data from other
|
||||
// currently or previously used render targets, and it doesn't require a
|
||||
// bigger size.
|
||||
auto command_list = command_processor_->GetCurrentCommandList();
|
||||
if (command_list == nullptr) {
|
||||
return false;
|
||||
}
|
||||
auto command_list = command_processor_->GetDeferredCommandList();
|
||||
auto& regs = *register_file_;
|
||||
|
||||
#if FINE_GRAINED_DRAW_SCOPES
|
||||
|
@ -856,7 +853,8 @@ bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) {
|
|||
current_pipeline_render_targets_[4].format = DXGI_FORMAT_UNKNOWN;
|
||||
}
|
||||
command_processor_->SubmitBarriers();
|
||||
command_list->OMSetRenderTargets(rtv_count, rtv_handles, FALSE, dsv_handle);
|
||||
command_list->D3DOMSetRenderTargets(rtv_count, rtv_handles, FALSE,
|
||||
dsv_handle);
|
||||
}
|
||||
|
||||
// Update the dirty regions.
|
||||
|
@ -1054,10 +1052,7 @@ bool RenderTargetCache::ResolveCopy(SharedMemory* shared_memory,
|
|||
return false;
|
||||
}
|
||||
|
||||
auto command_list = command_processor_->GetCurrentCommandList();
|
||||
if (command_list == nullptr) {
|
||||
return false;
|
||||
}
|
||||
auto command_list = command_processor_->GetDeferredCommandList();
|
||||
|
||||
// Get the destination region and clamp the source region to it.
|
||||
uint32_t rb_copy_dest_pitch = regs[XE_GPU_REG_RB_COPY_DEST_PITCH].u32;
|
||||
|
@ -1251,7 +1246,7 @@ bool RenderTargetCache::ResolveCopy(SharedMemory* shared_memory,
|
|||
command_processor_->SubmitBarriers();
|
||||
|
||||
// Dispatch the computation.
|
||||
command_list->SetComputeRootSignature(edram_load_store_root_signature_);
|
||||
command_list->D3DSetComputeRootSignature(edram_load_store_root_signature_);
|
||||
EDRAMLoadStoreRootConstants root_constants;
|
||||
// Only 5 bits - assuming pre-offset address.
|
||||
assert_true(dest_offset_x <= 31 && dest_offset_y <= 31);
|
||||
|
@ -1301,9 +1296,9 @@ bool RenderTargetCache::ResolveCopy(SharedMemory* shared_memory,
|
|||
root_constants.base_samples_2x_depth_pitch |= 1 << 12;
|
||||
}
|
||||
}
|
||||
command_list->SetComputeRoot32BitConstants(
|
||||
command_list->D3DSetComputeRoot32BitConstants(
|
||||
0, sizeof(root_constants) / sizeof(uint32_t), &root_constants, 0);
|
||||
command_list->SetComputeRootDescriptorTable(1, descriptor_gpu_start);
|
||||
command_list->D3DSetComputeRootDescriptorTable(1, descriptor_gpu_start);
|
||||
command_processor_->SetComputePipeline(
|
||||
src_64bpp ? edram_tile_sample_64bpp_pipeline_
|
||||
: edram_tile_sample_32bpp_pipeline_);
|
||||
|
@ -1319,7 +1314,7 @@ bool RenderTargetCache::ResolveCopy(SharedMemory* shared_memory,
|
|||
// is 80x16 destination pixels after applying the resolution scale.
|
||||
group_count_x <<= resolution_scale_log2;
|
||||
group_count_y <<= resolution_scale_log2;
|
||||
command_list->Dispatch(group_count_x, group_count_y, 1);
|
||||
command_list->D3DDispatch(group_count_x, group_count_y, 1);
|
||||
|
||||
// Commit the write.
|
||||
command_processor_->PushUAVBarrier(
|
||||
|
@ -1407,7 +1402,7 @@ bool RenderTargetCache::ResolveCopy(SharedMemory* shared_memory,
|
|||
TransitionEDRAMBuffer(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
|
||||
command_processor_->SubmitBarriers();
|
||||
|
||||
command_list->SetComputeRootSignature(edram_load_store_root_signature_);
|
||||
command_list->D3DSetComputeRootSignature(edram_load_store_root_signature_);
|
||||
|
||||
EDRAMLoadStoreRootConstants load_root_constants;
|
||||
load_root_constants.rt_color_depth_offset = uint32_t(footprint.Offset);
|
||||
|
@ -1422,7 +1417,7 @@ bool RenderTargetCache::ResolveCopy(SharedMemory* shared_memory,
|
|||
load_root_constants.base_samples_2x_depth_pitch |= 1 << 12;
|
||||
}
|
||||
}
|
||||
command_list->SetComputeRoot32BitConstants(
|
||||
command_list->D3DSetComputeRoot32BitConstants(
|
||||
0, sizeof(load_root_constants) / sizeof(uint32_t), &load_root_constants,
|
||||
0);
|
||||
|
||||
|
@ -1431,14 +1426,14 @@ bool RenderTargetCache::ResolveCopy(SharedMemory* shared_memory,
|
|||
ui::d3d12::util::CreateRawBufferUAV(
|
||||
device, provider->OffsetViewDescriptor(descriptor_cpu_start, 1),
|
||||
copy_buffer, render_target->copy_buffer_size);
|
||||
command_list->SetComputeRootDescriptorTable(1, descriptor_gpu_start);
|
||||
command_list->D3DSetComputeRootDescriptorTable(1, descriptor_gpu_start);
|
||||
|
||||
EDRAMLoadStoreMode mode = GetLoadStoreMode(false, src_format);
|
||||
command_processor_->SetComputePipeline(
|
||||
resolution_scale_2x_ ? edram_load_2x_resolve_pipelines_[size_t(mode)]
|
||||
: edram_load_pipelines_[size_t(mode)]);
|
||||
// 1 group per 80x16 samples, with both 1x and 2x resolution scales.
|
||||
command_list->Dispatch(row_width_ss_div_80, rows, 1);
|
||||
command_list->D3DDispatch(row_width_ss_div_80, rows, 1);
|
||||
command_processor_->PushUAVBarrier(copy_buffer);
|
||||
|
||||
// Go to the next descriptor set.
|
||||
|
@ -1468,8 +1463,7 @@ bool RenderTargetCache::ResolveCopy(SharedMemory* shared_memory,
|
|||
location_dest.pResource = render_target->resource;
|
||||
location_dest.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
location_dest.SubresourceIndex = 0;
|
||||
command_list->CopyTextureRegion(&location_dest, 0, 0, 0, &location_source,
|
||||
nullptr);
|
||||
command_list->CopyTexture(location_dest, location_source);
|
||||
|
||||
// Do the resolve. Render targets unbound already, safe to call
|
||||
// OMSetRenderTargets.
|
||||
|
@ -1486,7 +1480,7 @@ bool RenderTargetCache::ResolveCopy(SharedMemory* shared_memory,
|
|||
D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
resolve_target->state = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
|
||||
command_list->SetGraphicsRootSignature(resolve_root_signature_);
|
||||
command_list->D3DSetGraphicsRootSignature(resolve_root_signature_);
|
||||
|
||||
ResolveRootConstants resolve_root_constants;
|
||||
uint32_t samples_x_log2 = msaa_samples >= MsaaSamples::k4X ? 1 : 0;
|
||||
|
@ -1542,7 +1536,7 @@ bool RenderTargetCache::ResolveCopy(SharedMemory* shared_memory,
|
|||
break;
|
||||
}
|
||||
}
|
||||
command_list->SetGraphicsRoot32BitConstants(
|
||||
command_list->D3DSetGraphicsRoot32BitConstants(
|
||||
0, sizeof(resolve_root_constants) / sizeof(uint32_t),
|
||||
&resolve_root_constants, 0);
|
||||
|
||||
|
@ -1583,13 +1577,13 @@ bool RenderTargetCache::ResolveCopy(SharedMemory* shared_memory,
|
|||
rt_srv_desc.Texture2D.ResourceMinLODClamp = 0.0f;
|
||||
device->CreateShaderResourceView(render_target->resource, &rt_srv_desc,
|
||||
descriptor_cpu_start);
|
||||
command_list->SetGraphicsRootDescriptorTable(1, descriptor_gpu_start);
|
||||
command_list->D3DSetGraphicsRootDescriptorTable(1, descriptor_gpu_start);
|
||||
|
||||
command_processor_->SubmitBarriers();
|
||||
command_processor_->SetSamplePositions(MsaaSamples::k1X);
|
||||
command_processor_->SetExternalGraphicsPipeline(resolve_pipeline);
|
||||
command_list->OMSetRenderTargets(1, &resolve_target->rtv_handle, TRUE,
|
||||
nullptr);
|
||||
command_list->D3DOMSetRenderTargets(1, &resolve_target->rtv_handle, TRUE,
|
||||
nullptr);
|
||||
D3D12_VIEWPORT viewport;
|
||||
viewport.TopLeftX = 0.0f;
|
||||
viewport.TopLeftY = 0.0f;
|
||||
|
@ -1597,19 +1591,20 @@ bool RenderTargetCache::ResolveCopy(SharedMemory* shared_memory,
|
|||
viewport.Height = float(copy_height << resolution_scale_log2);
|
||||
viewport.MinDepth = 0.0f;
|
||||
viewport.MaxDepth = 1.0f;
|
||||
command_list->RSSetViewports(1, &viewport);
|
||||
command_list->RSSetViewport(viewport);
|
||||
D3D12_RECT scissor;
|
||||
scissor.left = 0;
|
||||
scissor.top = 0;
|
||||
scissor.right = copy_width << resolution_scale_log2;
|
||||
scissor.bottom = copy_height << resolution_scale_log2;
|
||||
command_list->RSSetScissorRects(1, &scissor);
|
||||
command_list->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
command_list->DrawInstanced(3, 1, 0, 0);
|
||||
command_list->RSSetScissorRect(scissor);
|
||||
command_list->D3DIASetPrimitiveTopology(
|
||||
D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
command_list->D3DDrawInstanced(3, 1, 0, 0);
|
||||
if (command_processor_->IsROVUsedForEDRAM()) {
|
||||
// Clean up - the ROV path doesn't need render targets bound and has
|
||||
// non-zero ForcedSampleCount.
|
||||
command_list->OMSetRenderTargets(0, nullptr, FALSE, nullptr);
|
||||
command_list->D3DOMSetRenderTargets(0, nullptr, FALSE, nullptr);
|
||||
}
|
||||
|
||||
// Copy the resolve target to the buffer.
|
||||
|
@ -1628,8 +1623,7 @@ bool RenderTargetCache::ResolveCopy(SharedMemory* shared_memory,
|
|||
location_dest.pResource = copy_buffer;
|
||||
location_dest.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
location_dest.PlacedFootprint = resolve_target->footprint;
|
||||
command_list->CopyTextureRegion(&location_dest, 0, 0, 0, &location_source,
|
||||
nullptr);
|
||||
command_list->CopyTexture(location_dest, location_source);
|
||||
|
||||
// Tile the resolved texture. The texture cache expects the buffer to be a
|
||||
// non-pixel-shader SRV.
|
||||
|
@ -1681,10 +1675,7 @@ bool RenderTargetCache::ResolveClear(uint32_t edram_base,
|
|||
uint32_t samples_y_log2 = msaa_samples >= MsaaSamples::k2X ? 1 : 0;
|
||||
|
||||
// Get everything needed for clearing.
|
||||
auto command_list = command_processor_->GetCurrentCommandList();
|
||||
if (command_list == nullptr) {
|
||||
return false;
|
||||
}
|
||||
auto command_list = command_processor_->GetDeferredCommandList();
|
||||
auto device =
|
||||
command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice();
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE descriptor_cpu_start;
|
||||
|
@ -1738,14 +1729,14 @@ bool RenderTargetCache::ResolveClear(uint32_t edram_base,
|
|||
root_constants.clear_color_high = regs[reg].u32;
|
||||
command_processor_->SetComputePipeline(edram_clear_32bpp_pipeline_);
|
||||
}
|
||||
command_list->SetComputeRootSignature(edram_clear_root_signature_);
|
||||
command_list->SetComputeRoot32BitConstants(
|
||||
command_list->D3DSetComputeRootSignature(edram_clear_root_signature_);
|
||||
command_list->D3DSetComputeRoot32BitConstants(
|
||||
0, sizeof(root_constants) / sizeof(uint32_t), &root_constants, 0);
|
||||
ui::d3d12::util::CreateRawBufferUAV(device, descriptor_cpu_start,
|
||||
edram_buffer_, GetEDRAMBufferSize());
|
||||
command_list->SetComputeRootDescriptorTable(1, descriptor_gpu_start);
|
||||
command_list->D3DSetComputeRootDescriptorTable(1, descriptor_gpu_start);
|
||||
// 1 group per 80x16 samples. Resolution scale handled in the shader itself.
|
||||
command_list->Dispatch(row_width_ss_div_80, rows, 1);
|
||||
command_list->D3DDispatch(row_width_ss_div_80, rows, 1);
|
||||
command_processor_->PushUAVBarrier(edram_buffer_);
|
||||
|
||||
return true;
|
||||
|
@ -2350,10 +2341,7 @@ RenderTargetCache::EDRAMLoadStoreMode RenderTargetCache::GetLoadStoreMode(
|
|||
}
|
||||
|
||||
void RenderTargetCache::StoreRenderTargetsToEDRAM() {
|
||||
auto command_list = command_processor_->GetCurrentCommandList();
|
||||
if (command_list == nullptr) {
|
||||
return;
|
||||
}
|
||||
auto command_list = command_processor_->GetDeferredCommandList();
|
||||
|
||||
// Extract only the render targets that need to be stored, transition them to
|
||||
// copy sources and calculate copy buffer size.
|
||||
|
@ -2406,13 +2394,13 @@ void RenderTargetCache::StoreRenderTargetsToEDRAM() {
|
|||
// Set up the bindings.
|
||||
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider();
|
||||
auto device = provider->GetDevice();
|
||||
command_list->SetComputeRootSignature(edram_load_store_root_signature_);
|
||||
command_list->D3DSetComputeRootSignature(edram_load_store_root_signature_);
|
||||
ui::d3d12::util::CreateRawBufferSRV(device, descriptor_cpu_start, copy_buffer,
|
||||
copy_buffer_size);
|
||||
ui::d3d12::util::CreateRawBufferUAV(
|
||||
device, provider->OffsetViewDescriptor(descriptor_cpu_start, 1),
|
||||
edram_buffer_, GetEDRAMBufferSize());
|
||||
command_list->SetComputeRootDescriptorTable(1, descriptor_gpu_start);
|
||||
command_list->D3DSetComputeRootDescriptorTable(1, descriptor_gpu_start);
|
||||
|
||||
// Sort the bindings in ascending order of EDRAM base so data in the render
|
||||
// targets placed farther in EDRAM isn't lost in case of overlap.
|
||||
|
@ -2461,8 +2449,7 @@ void RenderTargetCache::StoreRenderTargetsToEDRAM() {
|
|||
location_dest.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
location_dest.PlacedFootprint = render_target->footprints[0];
|
||||
// TODO(Triang3l): Box for color render targets.
|
||||
command_list->CopyTextureRegion(&location_dest, 0, 0, 0, &location_source,
|
||||
nullptr);
|
||||
command_list->CopyTexture(location_dest, location_source);
|
||||
EDRAMLoadStoreRootConstants root_constants;
|
||||
uint32_t rt_pitch_tiles = surface_pitch_tiles;
|
||||
if (!render_target->key.is_depth &&
|
||||
|
@ -2481,8 +2468,7 @@ void RenderTargetCache::StoreRenderTargetsToEDRAM() {
|
|||
root_constants.base_samples_2x_depth_pitch |= 1 << 15;
|
||||
location_source.SubresourceIndex = 1;
|
||||
location_dest.PlacedFootprint = render_target->footprints[1];
|
||||
command_list->CopyTextureRegion(&location_dest, 0, 0, 0, &location_source,
|
||||
nullptr);
|
||||
command_list->CopyTexture(location_dest, location_source);
|
||||
root_constants.rt_stencil_offset =
|
||||
uint32_t(location_dest.PlacedFootprint.Offset);
|
||||
root_constants.rt_stencil_pitch =
|
||||
|
@ -2497,14 +2483,14 @@ void RenderTargetCache::StoreRenderTargetsToEDRAM() {
|
|||
command_processor_->SubmitBarriers();
|
||||
|
||||
// Store the data.
|
||||
command_list->SetComputeRoot32BitConstants(
|
||||
command_list->D3DSetComputeRoot32BitConstants(
|
||||
0, sizeof(root_constants) / sizeof(uint32_t), &root_constants, 0);
|
||||
EDRAMLoadStoreMode mode = GetLoadStoreMode(render_target->key.is_depth,
|
||||
render_target->key.format);
|
||||
command_processor_->SetComputePipeline(
|
||||
edram_store_pipelines_[size_t(mode)]);
|
||||
// 1 group per 80x16 samples.
|
||||
command_list->Dispatch(surface_pitch_tiles, binding.edram_dirty_rows, 1);
|
||||
command_list->D3DDispatch(surface_pitch_tiles, binding.edram_dirty_rows, 1);
|
||||
|
||||
// Commit the UAV write.
|
||||
command_processor_->PushUAVBarrier(edram_buffer_);
|
||||
|
@ -2521,10 +2507,7 @@ void RenderTargetCache::LoadRenderTargetsFromEDRAM(
|
|||
return;
|
||||
}
|
||||
|
||||
auto command_list = command_processor_->GetCurrentCommandList();
|
||||
if (command_list == nullptr) {
|
||||
return;
|
||||
}
|
||||
auto command_list = command_processor_->GetDeferredCommandList();
|
||||
|
||||
// Allocate descriptors for the buffers.
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE descriptor_cpu_start;
|
||||
|
@ -2562,13 +2545,13 @@ void RenderTargetCache::LoadRenderTargetsFromEDRAM(
|
|||
// Set up the bindings.
|
||||
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider();
|
||||
auto device = provider->GetDevice();
|
||||
command_list->SetComputeRootSignature(edram_load_store_root_signature_);
|
||||
command_list->D3DSetComputeRootSignature(edram_load_store_root_signature_);
|
||||
ui::d3d12::util::CreateRawBufferSRV(device, descriptor_cpu_start,
|
||||
edram_buffer_, GetEDRAMBufferSize());
|
||||
ui::d3d12::util::CreateRawBufferUAV(
|
||||
device, provider->OffsetViewDescriptor(descriptor_cpu_start, 1),
|
||||
copy_buffer, copy_buffer_size);
|
||||
command_list->SetComputeRootDescriptorTable(1, descriptor_gpu_start);
|
||||
command_list->D3DSetComputeRootDescriptorTable(1, descriptor_gpu_start);
|
||||
|
||||
// Load each render target.
|
||||
for (uint32_t i = 0; i < render_target_count; ++i) {
|
||||
|
@ -2615,13 +2598,14 @@ void RenderTargetCache::LoadRenderTargetsFromEDRAM(
|
|||
root_constants.rt_stencil_pitch =
|
||||
render_target->footprints[1].Footprint.RowPitch;
|
||||
}
|
||||
command_list->SetComputeRoot32BitConstants(
|
||||
command_list->D3DSetComputeRoot32BitConstants(
|
||||
0, sizeof(root_constants) / sizeof(uint32_t), &root_constants, 0);
|
||||
EDRAMLoadStoreMode mode = GetLoadStoreMode(render_target->key.is_depth,
|
||||
render_target->key.format);
|
||||
command_processor_->SetComputePipeline(edram_load_pipelines_[size_t(mode)]);
|
||||
// 1 group per 80x16 samples.
|
||||
command_list->Dispatch(render_target->key.width_ss_div_80, edram_rows, 1);
|
||||
command_list->D3DDispatch(render_target->key.width_ss_div_80, edram_rows,
|
||||
1);
|
||||
|
||||
// Commit the UAV write and transition the copy buffer to copy source now.
|
||||
command_processor_->PushUAVBarrier(copy_buffer);
|
||||
|
@ -2638,13 +2622,11 @@ void RenderTargetCache::LoadRenderTargetsFromEDRAM(
|
|||
location_dest.pResource = render_target->resource;
|
||||
location_dest.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
location_dest.SubresourceIndex = 0;
|
||||
command_list->CopyTextureRegion(&location_dest, 0, 0, 0, &location_source,
|
||||
nullptr);
|
||||
command_list->CopyTexture(location_dest, location_source);
|
||||
if (render_target->key.is_depth) {
|
||||
location_source.PlacedFootprint = render_target->footprints[1];
|
||||
location_dest.SubresourceIndex = 1;
|
||||
command_list->CopyTextureRegion(&location_dest, 0, 0, 0, &location_source,
|
||||
nullptr);
|
||||
command_list->CopyTexture(location_dest, location_source);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -319,10 +319,7 @@ bool SharedMemory::RequestRange(uint32_t start, uint32_t length) {
|
|||
}
|
||||
uint32_t last = start + length - 1;
|
||||
|
||||
auto command_list = command_processor_->GetCurrentCommandList();
|
||||
if (command_list == nullptr) {
|
||||
return false;
|
||||
}
|
||||
auto command_list = command_processor_->GetDeferredCommandList();
|
||||
|
||||
#if FINE_GRAINED_DRAW_SCOPES
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
|
@ -360,7 +357,7 @@ bool SharedMemory::RequestRange(uint32_t start, uint32_t length) {
|
|||
upload_buffer_mapping,
|
||||
memory_->TranslatePhysical(upload_range_start << page_size_log2_),
|
||||
upload_buffer_size);
|
||||
command_list->CopyBufferRegion(
|
||||
command_list->D3DCopyBufferRegion(
|
||||
buffer_, upload_range_start << page_size_log2_, upload_buffer,
|
||||
upload_buffer_offset, upload_buffer_size);
|
||||
upload_range_start += upload_buffer_pages;
|
||||
|
|
|
@ -644,10 +644,6 @@ void TextureCache::EndFrame() {
|
|||
|
||||
void TextureCache::RequestTextures(uint32_t used_vertex_texture_mask,
|
||||
uint32_t used_pixel_texture_mask) {
|
||||
auto command_list = command_processor_->GetCurrentCommandList();
|
||||
if (command_list == nullptr) {
|
||||
return;
|
||||
}
|
||||
auto& regs = *register_file_;
|
||||
|
||||
#if FINE_GRAINED_DRAW_SCOPES
|
||||
|
@ -1061,10 +1057,7 @@ bool TextureCache::TileResolvedTexture(
|
|||
const ResolveTileModeInfo& resolve_tile_mode_info =
|
||||
resolve_tile_mode_info_[uint32_t(resolve_tile_mode)];
|
||||
|
||||
auto command_list = command_processor_->GetCurrentCommandList();
|
||||
if (command_list == nullptr) {
|
||||
return false;
|
||||
}
|
||||
auto command_list = command_processor_->GetDeferredCommandList();
|
||||
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider();
|
||||
auto device = provider->GetDevice();
|
||||
uint32_t resolution_scale_log2 = IsResolutionScale2X() ? 1 : 0;
|
||||
|
@ -1122,7 +1115,7 @@ bool TextureCache::TileResolvedTexture(
|
|||
shared_memory_->UseForWriting();
|
||||
}
|
||||
command_processor_->SubmitBarriers();
|
||||
command_list->SetComputeRootSignature(resolve_tile_root_signature_);
|
||||
command_list->D3DSetComputeRootSignature(resolve_tile_root_signature_);
|
||||
ResolveTileConstants resolve_tile_constants;
|
||||
resolve_tile_constants.info = uint32_t(endian) | (uint32_t(format) << 3) |
|
||||
(resolution_scale_log2 << 9) |
|
||||
|
@ -1170,17 +1163,17 @@ bool TextureCache::TileResolvedTexture(
|
|||
shared_memory_->CreateRawUAV(descriptor_cpu_uav);
|
||||
}
|
||||
}
|
||||
command_list->SetComputeRootDescriptorTable(1, descriptor_gpu_start);
|
||||
command_list->SetComputeRoot32BitConstants(
|
||||
command_list->D3DSetComputeRootDescriptorTable(1, descriptor_gpu_start);
|
||||
command_list->D3DSetComputeRoot32BitConstants(
|
||||
0, sizeof(resolve_tile_constants) / sizeof(uint32_t),
|
||||
&resolve_tile_constants, 0);
|
||||
command_processor_->SetComputePipeline(
|
||||
resolve_tile_pipelines_[uint32_t(resolve_tile_mode)]);
|
||||
// Each group processes 32x32 texels after resolution scaling has been
|
||||
// applied.
|
||||
command_list->Dispatch(((resolve_width << resolution_scale_log2) + 31) >> 5,
|
||||
((resolve_height << resolution_scale_log2) + 31) >> 5,
|
||||
1);
|
||||
command_list->D3DDispatch(
|
||||
((resolve_width << resolution_scale_log2) + 31) >> 5,
|
||||
((resolve_height << resolution_scale_log2) + 31) >> 5, 1);
|
||||
|
||||
// Commit the write.
|
||||
command_processor_->PushUAVBarrier(resolution_scale_log2
|
||||
|
@ -1687,10 +1680,7 @@ bool TextureCache::LoadTextureData(Texture* texture) {
|
|||
return true;
|
||||
}
|
||||
|
||||
auto command_list = command_processor_->GetCurrentCommandList();
|
||||
if (command_list == nullptr) {
|
||||
return false;
|
||||
}
|
||||
auto command_list = command_processor_->GetDeferredCommandList();
|
||||
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider();
|
||||
auto device = provider->GetDevice();
|
||||
|
||||
|
@ -1818,10 +1808,10 @@ bool TextureCache::LoadTextureData(Texture* texture) {
|
|||
copy_buffer, uint32_t(host_slice_size));
|
||||
}
|
||||
command_processor_->SetComputePipeline(pipeline);
|
||||
command_list->SetComputeRootSignature(load_root_signature_);
|
||||
command_list->D3DSetComputeRootSignature(load_root_signature_);
|
||||
if (!separate_base_and_mips_descriptors) {
|
||||
// Will be bound later.
|
||||
command_list->SetComputeRootDescriptorTable(1, descriptor_gpu_start);
|
||||
command_list->D3DSetComputeRootDescriptorTable(1, descriptor_gpu_start);
|
||||
}
|
||||
|
||||
// Submit commands.
|
||||
|
@ -1896,12 +1886,13 @@ bool TextureCache::LoadTextureData(Texture* texture) {
|
|||
return false;
|
||||
}
|
||||
std::memcpy(cbuffer_mapping, &load_constants, sizeof(load_constants));
|
||||
command_list->SetComputeRootConstantBufferView(0, cbuffer_gpu_address);
|
||||
command_list->D3DSetComputeRootConstantBufferView(0, cbuffer_gpu_address);
|
||||
if (separate_base_and_mips_descriptors) {
|
||||
if (j == 0) {
|
||||
command_list->SetComputeRootDescriptorTable(1, descriptor_gpu_start);
|
||||
command_list->D3DSetComputeRootDescriptorTable(1,
|
||||
descriptor_gpu_start);
|
||||
} else if (j == 1) {
|
||||
command_list->SetComputeRootDescriptorTable(
|
||||
command_list->D3DSetComputeRootDescriptorTable(
|
||||
1, provider->OffsetViewDescriptor(descriptor_gpu_start, 2));
|
||||
}
|
||||
}
|
||||
|
@ -1916,8 +1907,8 @@ bool TextureCache::LoadTextureData(Texture* texture) {
|
|||
}
|
||||
group_count_x = (group_count_x + 31) >> 5;
|
||||
group_count_y = (group_count_y + 31) >> 5;
|
||||
command_list->Dispatch(group_count_x, group_count_y,
|
||||
load_constants.size_blocks[2]);
|
||||
command_list->D3DDispatch(group_count_x, group_count_y,
|
||||
load_constants.size_blocks[2]);
|
||||
}
|
||||
command_processor_->PushUAVBarrier(copy_buffer);
|
||||
command_processor_->PushTransitionBarrier(copy_buffer, copy_buffer_state,
|
||||
|
@ -1933,8 +1924,7 @@ bool TextureCache::LoadTextureData(Texture* texture) {
|
|||
location_dest.pResource = texture->resource;
|
||||
location_dest.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
location_dest.SubresourceIndex = slice_first_subresource + j;
|
||||
command_list->CopyTextureRegion(&location_dest, 0, 0, 0, &location_source,
|
||||
nullptr);
|
||||
command_list->CopyTexture(location_dest, location_source);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue