native guest output renderer hook (D3D12) + shared-memory accessor
This commit is contained in:
parent
fac7ab2616
commit
c4b0dfe2c9
8 changed files with 292 additions and 7 deletions
|
|
@ -103,6 +103,8 @@ class D3D12CommandProcessor : public CommandProcessor {
|
||||||
|
|
||||||
ui::d3d12::D3D12UploadBufferPool& GetConstantBufferPool() const { return *constant_buffer_pool_; }
|
ui::d3d12::D3D12UploadBufferPool& GetConstantBufferPool() const { return *constant_buffer_pool_; }
|
||||||
|
|
||||||
|
D3D12SharedMemory& GetSharedMemory() const { return *shared_memory_; }
|
||||||
|
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE GetViewBindlessHeapCPUStart() const {
|
D3D12_CPU_DESCRIPTOR_HANDLE GetViewBindlessHeapCPUStart() const {
|
||||||
assert_true(bindless_resources_used_);
|
assert_true(bindless_resources_used_);
|
||||||
return view_bindless_heap_cpu_start_;
|
return view_bindless_heap_cpu_start_;
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,23 @@ class DeferredCommandList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void D3DClearUnorderedAccessViewFloat(
|
||||||
|
D3D12_GPU_DESCRIPTOR_HANDLE view_gpu_handle_in_current_heap,
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE view_cpu_handle, ID3D12Resource* resource,
|
||||||
|
const FLOAT values[4], UINT num_rects, const D3D12_RECT* rects) {
|
||||||
|
auto args = reinterpret_cast<ClearUnorderedAccessViewHeader*>(
|
||||||
|
WriteCommand(Command::kD3DClearUnorderedAccessViewFloat,
|
||||||
|
sizeof(ClearUnorderedAccessViewHeader) + num_rects * sizeof(D3D12_RECT)));
|
||||||
|
args->view_gpu_handle_in_current_heap = view_gpu_handle_in_current_heap;
|
||||||
|
args->view_cpu_handle = view_cpu_handle;
|
||||||
|
args->resource = resource;
|
||||||
|
std::memcpy(args->values_float, values, 4 * sizeof(FLOAT));
|
||||||
|
args->num_rects = num_rects;
|
||||||
|
if (num_rects != 0) {
|
||||||
|
std::memcpy(args + 1, rects, num_rects * sizeof(D3D12_RECT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void D3DCopyBufferRegion(ID3D12Resource* dst_buffer, UINT64 dst_offset,
|
void D3DCopyBufferRegion(ID3D12Resource* dst_buffer, UINT64 dst_offset,
|
||||||
ID3D12Resource* src_buffer, UINT64 src_offset, UINT64 num_bytes) {
|
ID3D12Resource* src_buffer, UINT64 src_offset, UINT64 num_bytes) {
|
||||||
auto& args = *reinterpret_cast<D3DCopyBufferRegionArguments*>(
|
auto& args = *reinterpret_cast<D3DCopyBufferRegionArguments*>(
|
||||||
|
|
@ -456,6 +473,7 @@ class DeferredCommandList {
|
||||||
kD3DClearDepthStencilView,
|
kD3DClearDepthStencilView,
|
||||||
kD3DClearRenderTargetView,
|
kD3DClearRenderTargetView,
|
||||||
kD3DClearUnorderedAccessViewUint,
|
kD3DClearUnorderedAccessViewUint,
|
||||||
|
kD3DClearUnorderedAccessViewFloat,
|
||||||
kD3DCopyBufferRegion,
|
kD3DCopyBufferRegion,
|
||||||
kD3DCopyResource,
|
kD3DCopyResource,
|
||||||
kCopyTexture,
|
kCopyTexture,
|
||||||
|
|
|
||||||
89
include/rex/graphics/native_guest_renderer.h
Normal file
89
include/rex/graphics/native_guest_renderer.h
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#if REX_HAS_D3D12
|
||||||
|
#include <rex/ui/d3d12/d3d12_api.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace rex::graphics::d3d12 {
|
||||||
|
class D3D12CommandProcessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace rex::graphics {
|
||||||
|
|
||||||
|
enum class NativeGuestOutputBackend : uint32_t {
|
||||||
|
kUnknown = 0,
|
||||||
|
kD3D12,
|
||||||
|
kVulkan,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NativeGuestOutputRenderContext {
|
||||||
|
NativeGuestOutputBackend backend = NativeGuestOutputBackend::kUnknown;
|
||||||
|
uint32_t guest_output_width = 0;
|
||||||
|
uint32_t guest_output_height = 0;
|
||||||
|
uint32_t display_width = 0;
|
||||||
|
uint32_t display_height = 0;
|
||||||
|
|
||||||
|
#if REX_HAS_D3D12
|
||||||
|
struct D3D12Context {
|
||||||
|
d3d12::D3D12CommandProcessor* command_processor = nullptr;
|
||||||
|
void* command_processor_user_data = nullptr;
|
||||||
|
ID3D12Device* device = nullptr;
|
||||||
|
ID3D12Resource* guest_output_resource = nullptr;
|
||||||
|
DXGI_FORMAT guest_output_format = DXGI_FORMAT_UNKNOWN;
|
||||||
|
D3D12_RESOURCE_STATES guest_output_initial_state = D3D12_RESOURCE_STATE_COMMON;
|
||||||
|
bool (*request_one_use_view_descriptor)(void* user_data,
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE* cpu_out,
|
||||||
|
D3D12_GPU_DESCRIPTOR_HANDLE* gpu_out) = nullptr;
|
||||||
|
bool (*create_root_signature)(void* user_data, const D3D12_ROOT_SIGNATURE_DESC* desc,
|
||||||
|
ID3D12RootSignature** root_signature_out) = nullptr;
|
||||||
|
bool (*push_transition_barrier)(void* user_data, ID3D12Resource* resource,
|
||||||
|
D3D12_RESOURCE_STATES old_state,
|
||||||
|
D3D12_RESOURCE_STATES new_state) = nullptr;
|
||||||
|
void (*submit_barriers)(void* user_data) = nullptr;
|
||||||
|
void (*copy_texture_region)(void* user_data, const D3D12_TEXTURE_COPY_LOCATION* dst,
|
||||||
|
UINT dst_x, UINT dst_y, UINT dst_z,
|
||||||
|
const D3D12_TEXTURE_COPY_LOCATION* src,
|
||||||
|
const D3D12_BOX* src_box) = nullptr;
|
||||||
|
void (*clear_render_target_view)(void* user_data, D3D12_CPU_DESCRIPTOR_HANDLE rtv,
|
||||||
|
const FLOAT color[4]) = nullptr;
|
||||||
|
void (*clear_unordered_access_view_float)(void* user_data,
|
||||||
|
D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle,
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle,
|
||||||
|
ID3D12Resource* resource,
|
||||||
|
const FLOAT values[4]) = nullptr;
|
||||||
|
void (*set_graphics_root_signature)(void* user_data,
|
||||||
|
ID3D12RootSignature* root_signature) = nullptr;
|
||||||
|
void (*set_graphics_root_32bit_constants)(void* user_data, UINT root_parameter_index,
|
||||||
|
UINT num_32bit_values_to_set,
|
||||||
|
const void* src_data,
|
||||||
|
UINT dest_offset_in_32bit_values) = nullptr;
|
||||||
|
void (*set_graphics_root_descriptor_table)(void* user_data, UINT root_parameter_index,
|
||||||
|
D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor) =
|
||||||
|
nullptr;
|
||||||
|
void (*set_pipeline_state)(void* user_data, ID3D12PipelineState* pipeline_state) = nullptr;
|
||||||
|
void (*ia_set_primitive_topology)(void* user_data,
|
||||||
|
D3D12_PRIMITIVE_TOPOLOGY primitive_topology) = nullptr;
|
||||||
|
void (*ia_set_vertex_buffers)(void* user_data, UINT start_slot, UINT num_views,
|
||||||
|
const D3D12_VERTEX_BUFFER_VIEW* views) = nullptr;
|
||||||
|
void (*om_set_render_targets)(void* user_data, 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) =
|
||||||
|
nullptr;
|
||||||
|
void (*rs_set_viewport)(void* user_data, const D3D12_VIEWPORT* viewport) = nullptr;
|
||||||
|
void (*rs_set_scissor_rect)(void* user_data, const D3D12_RECT* rect) = nullptr;
|
||||||
|
void (*draw_instanced)(void* user_data, UINT vertex_count_per_instance, UINT instance_count,
|
||||||
|
UINT start_vertex_location, UINT start_instance_location) = nullptr;
|
||||||
|
} d3d12;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
using NativeGuestOutputRenderer = bool (*)(const NativeGuestOutputRenderContext& context,
|
||||||
|
void* user_data);
|
||||||
|
|
||||||
|
void SetNativeGuestOutputRenderer(NativeGuestOutputRenderer renderer, void* user_data);
|
||||||
|
bool TryRenderNativeGuestOutput(const NativeGuestOutputRenderContext& context);
|
||||||
|
|
||||||
|
} // namespace rex::graphics
|
||||||
|
|
@ -24,6 +24,7 @@ set(REXGRAPHICS_SYSTEM_SOURCES
|
||||||
util/draw_extent_estimator.cpp
|
util/draw_extent_estimator.cpp
|
||||||
util/draw.cpp
|
util/draw.cpp
|
||||||
packet_disassembler.cpp
|
packet_disassembler.cpp
|
||||||
|
native_guest_renderer.cpp
|
||||||
primitive_processor.cpp
|
primitive_processor.cpp
|
||||||
pipeline/render_target/cache.cpp
|
pipeline/render_target/cache.cpp
|
||||||
shared_memory.cpp
|
shared_memory.cpp
|
||||||
|
|
@ -148,4 +149,3 @@ if(REXGLUE_USE_D3D12)
|
||||||
)
|
)
|
||||||
target_compile_definitions(rexgraphics PUBLIC REX_HAS_D3D12=1)
|
target_compile_definitions(rexgraphics PUBLIC REX_HAS_D3D12=1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#include <rex/dbg.h>
|
#include <rex/dbg.h>
|
||||||
#include <rex/perf/counter.h>
|
#include <rex/perf/counter.h>
|
||||||
#include <rex/graphics/d3d12/command_processor.h>
|
#include <rex/graphics/d3d12/command_processor.h>
|
||||||
|
#include <rex/graphics/native_guest_renderer.h>
|
||||||
#include <rex/graphics/d3d12/graphics_system.h>
|
#include <rex/graphics/d3d12/graphics_system.h>
|
||||||
#include <rex/graphics/d3d12/shader.h>
|
#include <rex/graphics/d3d12/shader.h>
|
||||||
#include <rex/graphics/flags.h>
|
#include <rex/graphics/flags.h>
|
||||||
|
|
@ -2320,7 +2321,8 @@ void D3D12CommandProcessor::IssueSwap(uint32_t frontbuffer_ptr, uint32_t frontbu
|
||||||
presenter->RefreshGuestOutput(
|
presenter->RefreshGuestOutput(
|
||||||
guest_output_width, guest_output_height, display_width, display_height,
|
guest_output_width, guest_output_height, display_width, display_height,
|
||||||
[this, &swap_texture_srv_desc, frontbuffer_format, swap_texture_resource, guest_output_width,
|
[this, &swap_texture_srv_desc, frontbuffer_format, swap_texture_resource, guest_output_width,
|
||||||
guest_output_height](ui::Presenter::GuestOutputRefreshContext& context) -> bool {
|
guest_output_height, display_width,
|
||||||
|
display_height](ui::Presenter::GuestOutputRefreshContext& context) -> bool {
|
||||||
const ui::d3d12::D3D12Provider& provider = GetD3D12Provider();
|
const ui::d3d12::D3D12Provider& provider = GetD3D12Provider();
|
||||||
ID3D12Device* device = provider.GetDevice();
|
ID3D12Device* device = provider.GetDevice();
|
||||||
|
|
||||||
|
|
@ -2378,6 +2380,148 @@ void D3D12CommandProcessor::IssueSwap(uint32_t frontbuffer_ptr, uint32_t frontbu
|
||||||
|
|
||||||
context.SetIs8bpc(!use_pwl_gamma_ramp && !use_fxaa);
|
context.SetIs8bpc(!use_pwl_gamma_ramp && !use_fxaa);
|
||||||
|
|
||||||
|
ID3D12Resource* guest_output_resource =
|
||||||
|
static_cast<ui::d3d12::D3D12Presenter::D3D12GuestOutputRefreshContext&>(context)
|
||||||
|
.resource_uav_capable();
|
||||||
|
|
||||||
|
NativeGuestOutputRenderContext native_context;
|
||||||
|
native_context.backend = NativeGuestOutputBackend::kD3D12;
|
||||||
|
native_context.guest_output_width = guest_output_width;
|
||||||
|
native_context.guest_output_height = guest_output_height;
|
||||||
|
native_context.display_width = display_width;
|
||||||
|
native_context.display_height = display_height;
|
||||||
|
native_context.d3d12.command_processor = this;
|
||||||
|
native_context.d3d12.command_processor_user_data = this;
|
||||||
|
native_context.d3d12.device = device;
|
||||||
|
native_context.d3d12.guest_output_resource = guest_output_resource;
|
||||||
|
native_context.d3d12.guest_output_format = ui::d3d12::D3D12Presenter::kGuestOutputFormat;
|
||||||
|
native_context.d3d12.guest_output_initial_state =
|
||||||
|
ui::d3d12::D3D12Presenter::kGuestOutputInternalState;
|
||||||
|
native_context.d3d12.request_one_use_view_descriptor =
|
||||||
|
[](void* user_data, D3D12_CPU_DESCRIPTOR_HANDLE* cpu_out,
|
||||||
|
D3D12_GPU_DESCRIPTOR_HANDLE* gpu_out) -> bool {
|
||||||
|
auto* command_processor = static_cast<D3D12CommandProcessor*>(user_data);
|
||||||
|
ui::d3d12::util::DescriptorCpuGpuHandlePair descriptor;
|
||||||
|
if (!command_processor->RequestOneUseSingleViewDescriptors(1, &descriptor)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*cpu_out = descriptor.first;
|
||||||
|
*gpu_out = descriptor.second;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
native_context.d3d12.create_root_signature =
|
||||||
|
[](void* user_data, const D3D12_ROOT_SIGNATURE_DESC* desc,
|
||||||
|
ID3D12RootSignature** root_signature_out) -> bool {
|
||||||
|
auto* command_processor = static_cast<D3D12CommandProcessor*>(user_data);
|
||||||
|
*root_signature_out =
|
||||||
|
ui::d3d12::util::CreateRootSignature(command_processor->GetD3D12Provider(), *desc);
|
||||||
|
return *root_signature_out != nullptr;
|
||||||
|
};
|
||||||
|
native_context.d3d12.push_transition_barrier =
|
||||||
|
[](void* user_data, ID3D12Resource* resource, D3D12_RESOURCE_STATES old_state,
|
||||||
|
D3D12_RESOURCE_STATES new_state) -> bool {
|
||||||
|
return static_cast<D3D12CommandProcessor*>(user_data)->PushTransitionBarrier(
|
||||||
|
resource, old_state, new_state);
|
||||||
|
};
|
||||||
|
native_context.d3d12.submit_barriers = [](void* user_data) {
|
||||||
|
static_cast<D3D12CommandProcessor*>(user_data)->SubmitBarriers();
|
||||||
|
};
|
||||||
|
native_context.d3d12.copy_texture_region =
|
||||||
|
[](void* user_data, const D3D12_TEXTURE_COPY_LOCATION* dst, UINT dst_x, UINT dst_y,
|
||||||
|
UINT dst_z, const D3D12_TEXTURE_COPY_LOCATION* src, const D3D12_BOX* src_box) {
|
||||||
|
static_cast<D3D12CommandProcessor*>(user_data)
|
||||||
|
->GetDeferredCommandList()
|
||||||
|
.D3DCopyTextureRegion(dst, dst_x, dst_y, dst_z, src, src_box);
|
||||||
|
};
|
||||||
|
native_context.d3d12.clear_render_target_view =
|
||||||
|
[](void* user_data, D3D12_CPU_DESCRIPTOR_HANDLE rtv, const FLOAT color[4]) {
|
||||||
|
static_cast<D3D12CommandProcessor*>(user_data)
|
||||||
|
->GetDeferredCommandList()
|
||||||
|
.D3DClearRenderTargetView(rtv, color, 0, nullptr);
|
||||||
|
};
|
||||||
|
native_context.d3d12.clear_unordered_access_view_float =
|
||||||
|
[](void* user_data, D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle,
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, ID3D12Resource* resource,
|
||||||
|
const FLOAT values[4]) {
|
||||||
|
static_cast<D3D12CommandProcessor*>(user_data)
|
||||||
|
->GetDeferredCommandList()
|
||||||
|
.D3DClearUnorderedAccessViewFloat(gpu_handle, cpu_handle, resource, values, 0,
|
||||||
|
nullptr);
|
||||||
|
};
|
||||||
|
native_context.d3d12.set_graphics_root_signature =
|
||||||
|
[](void* user_data, ID3D12RootSignature* root_signature) {
|
||||||
|
static_cast<D3D12CommandProcessor*>(user_data)
|
||||||
|
->GetDeferredCommandList()
|
||||||
|
.D3DSetGraphicsRootSignature(root_signature);
|
||||||
|
};
|
||||||
|
native_context.d3d12.set_graphics_root_32bit_constants =
|
||||||
|
[](void* user_data, UINT root_parameter_index, UINT num_32bit_values_to_set,
|
||||||
|
const void* src_data, UINT dest_offset_in_32bit_values) {
|
||||||
|
static_cast<D3D12CommandProcessor*>(user_data)
|
||||||
|
->GetDeferredCommandList()
|
||||||
|
.D3DSetGraphicsRoot32BitConstants(root_parameter_index, num_32bit_values_to_set,
|
||||||
|
src_data, dest_offset_in_32bit_values);
|
||||||
|
};
|
||||||
|
native_context.d3d12.set_graphics_root_descriptor_table =
|
||||||
|
[](void* user_data, UINT root_parameter_index,
|
||||||
|
D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor) {
|
||||||
|
static_cast<D3D12CommandProcessor*>(user_data)
|
||||||
|
->GetDeferredCommandList()
|
||||||
|
.D3DSetGraphicsRootDescriptorTable(root_parameter_index, base_descriptor);
|
||||||
|
};
|
||||||
|
native_context.d3d12.set_pipeline_state =
|
||||||
|
[](void* user_data, ID3D12PipelineState* pipeline_state) {
|
||||||
|
static_cast<D3D12CommandProcessor*>(user_data)
|
||||||
|
->GetDeferredCommandList()
|
||||||
|
.D3DSetPipelineState(pipeline_state);
|
||||||
|
};
|
||||||
|
native_context.d3d12.ia_set_primitive_topology =
|
||||||
|
[](void* user_data, D3D12_PRIMITIVE_TOPOLOGY primitive_topology) {
|
||||||
|
static_cast<D3D12CommandProcessor*>(user_data)
|
||||||
|
->GetDeferredCommandList()
|
||||||
|
.D3DIASetPrimitiveTopology(primitive_topology);
|
||||||
|
};
|
||||||
|
native_context.d3d12.ia_set_vertex_buffers =
|
||||||
|
[](void* user_data, UINT start_slot, UINT num_views,
|
||||||
|
const D3D12_VERTEX_BUFFER_VIEW* views) {
|
||||||
|
static_cast<D3D12CommandProcessor*>(user_data)
|
||||||
|
->GetDeferredCommandList()
|
||||||
|
.D3DIASetVertexBuffers(start_slot, num_views, views);
|
||||||
|
};
|
||||||
|
native_context.d3d12.om_set_render_targets =
|
||||||
|
[](void* user_data, 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) {
|
||||||
|
static_cast<D3D12CommandProcessor*>(user_data)
|
||||||
|
->GetDeferredCommandList()
|
||||||
|
.D3DOMSetRenderTargets(num_render_target_descriptors, render_target_descriptors,
|
||||||
|
rts_single_handle_to_descriptor_range,
|
||||||
|
depth_stencil_descriptor);
|
||||||
|
};
|
||||||
|
native_context.d3d12.rs_set_viewport = [](void* user_data,
|
||||||
|
const D3D12_VIEWPORT* viewport) {
|
||||||
|
static_cast<D3D12CommandProcessor*>(user_data)
|
||||||
|
->GetDeferredCommandList()
|
||||||
|
.RSSetViewport(*viewport);
|
||||||
|
};
|
||||||
|
native_context.d3d12.rs_set_scissor_rect = [](void* user_data, const D3D12_RECT* rect) {
|
||||||
|
static_cast<D3D12CommandProcessor*>(user_data)->GetDeferredCommandList().RSSetScissorRect(
|
||||||
|
*rect);
|
||||||
|
};
|
||||||
|
native_context.d3d12.draw_instanced =
|
||||||
|
[](void* user_data, UINT vertex_count_per_instance, UINT instance_count,
|
||||||
|
UINT start_vertex_location, UINT start_instance_location) {
|
||||||
|
static_cast<D3D12CommandProcessor*>(user_data)
|
||||||
|
->GetDeferredCommandList()
|
||||||
|
.D3DDrawInstanced(vertex_count_per_instance, instance_count, start_vertex_location,
|
||||||
|
start_instance_location);
|
||||||
|
};
|
||||||
|
if (TryRenderNativeGuestOutput(native_context)) {
|
||||||
|
EndSubmission(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Upload the new gamma ramp, using the upload buffer for the current
|
// Upload the new gamma ramp, using the upload buffer for the current
|
||||||
// frame (will close the frame after this anyway, so can't write
|
// frame (will close the frame after this anyway, so can't write
|
||||||
// multiple times per frame).
|
// multiple times per frame).
|
||||||
|
|
@ -2438,10 +2582,6 @@ void D3D12CommandProcessor::IssueSwap(uint32_t frontbuffer_ptr, uint32_t frontbu
|
||||||
WriteGammaRampSRV(use_pwl_gamma_ramp, apply_gamma_descriptor_gamma_ramp.first);
|
WriteGammaRampSRV(use_pwl_gamma_ramp, apply_gamma_descriptor_gamma_ramp.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D12Resource* guest_output_resource =
|
|
||||||
static_cast<ui::d3d12::D3D12Presenter::D3D12GuestOutputRefreshContext&>(context)
|
|
||||||
.resource_uav_capable();
|
|
||||||
|
|
||||||
if (use_fxaa) {
|
if (use_fxaa) {
|
||||||
fxaa_source_texture_submission_ = submission_current_;
|
fxaa_source_texture_submission_ = submission_current_;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ DeferredCommandPerfCategory GetPerfCategory(DeferredCommandList::Command command
|
||||||
case Command::kD3DClearDepthStencilView:
|
case Command::kD3DClearDepthStencilView:
|
||||||
case Command::kD3DClearRenderTargetView:
|
case Command::kD3DClearRenderTargetView:
|
||||||
case Command::kD3DClearUnorderedAccessViewUint:
|
case Command::kD3DClearUnorderedAccessViewUint:
|
||||||
|
case Command::kD3DClearUnorderedAccessViewFloat:
|
||||||
return {CounterId::kDeferredClearCount, CounterId::kDeferredClearUs,
|
return {CounterId::kDeferredClearCount, CounterId::kDeferredClearUs,
|
||||||
CounterId::kGpuClearUs};
|
CounterId::kGpuClearUs};
|
||||||
case Command::kD3DResourceBarrier:
|
case Command::kD3DResourceBarrier:
|
||||||
|
|
@ -146,6 +147,13 @@ void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list,
|
||||||
args.values_uint, args.num_rects,
|
args.values_uint, args.num_rects,
|
||||||
args.num_rects ? reinterpret_cast<const D3D12_RECT*>(&args + 1) : nullptr);
|
args.num_rects ? reinterpret_cast<const D3D12_RECT*>(&args + 1) : nullptr);
|
||||||
} break;
|
} break;
|
||||||
|
case Command::kD3DClearUnorderedAccessViewFloat: {
|
||||||
|
auto& args = *reinterpret_cast<const ClearUnorderedAccessViewHeader*>(stream);
|
||||||
|
command_list->ClearUnorderedAccessViewFloat(
|
||||||
|
args.view_gpu_handle_in_current_heap, args.view_cpu_handle, args.resource,
|
||||||
|
args.values_float, args.num_rects,
|
||||||
|
args.num_rects ? reinterpret_cast<const D3D12_RECT*>(&args + 1) : nullptr);
|
||||||
|
} break;
|
||||||
case Command::kD3DCopyBufferRegion: {
|
case Command::kD3DCopyBufferRegion: {
|
||||||
auto& args = *reinterpret_cast<const D3DCopyBufferRegionArguments*>(stream);
|
auto& args = *reinterpret_cast<const D3DCopyBufferRegionArguments*>(stream);
|
||||||
PERF_counter_add(kDeferredCopyBufferBytes, static_cast<int64_t>(args.num_bytes));
|
PERF_counter_add(kDeferredCopyBufferBytes, static_cast<int64_t>(args.num_bytes));
|
||||||
|
|
|
||||||
27
src/graphics/native_guest_renderer.cpp
Normal file
27
src/graphics/native_guest_renderer.cpp
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
#include <rex/graphics/native_guest_renderer.h>
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
namespace rex::graphics {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
std::atomic<NativeGuestOutputRenderer> g_renderer{nullptr};
|
||||||
|
std::atomic<void*> g_renderer_user_data{nullptr};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void SetNativeGuestOutputRenderer(NativeGuestOutputRenderer renderer, void* user_data) {
|
||||||
|
g_renderer_user_data.store(user_data, std::memory_order_release);
|
||||||
|
g_renderer.store(renderer, std::memory_order_release);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TryRenderNativeGuestOutput(const NativeGuestOutputRenderContext& context) {
|
||||||
|
NativeGuestOutputRenderer renderer = g_renderer.load(std::memory_order_acquire);
|
||||||
|
if (renderer == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
void* user_data = g_renderer_user_data.load(std::memory_order_acquire);
|
||||||
|
return renderer(context, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace rex::graphics
|
||||||
|
|
@ -626,7 +626,8 @@ bool D3D12Presenter::RefreshGuestOutputImpl(
|
||||||
guest_output_resource_new_desc.SampleDesc.Count = 1;
|
guest_output_resource_new_desc.SampleDesc.Count = 1;
|
||||||
guest_output_resource_new_desc.SampleDesc.Quality = 0;
|
guest_output_resource_new_desc.SampleDesc.Quality = 0;
|
||||||
guest_output_resource_new_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
guest_output_resource_new_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
||||||
guest_output_resource_new_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
|
guest_output_resource_new_desc.Flags =
|
||||||
|
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS | D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
||||||
if (FAILED(device->CreateCommittedResource(
|
if (FAILED(device->CreateCommittedResource(
|
||||||
&util::kHeapPropertiesDefault, provider_.GetHeapFlagCreateNotZeroed(),
|
&util::kHeapPropertiesDefault, provider_.GetHeapFlagCreateNotZeroed(),
|
||||||
&guest_output_resource_new_desc, kGuestOutputInternalState, nullptr,
|
&guest_output_resource_new_desc, kGuestOutputInternalState, nullptr,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue