[UI] Image post-processing and full presentation/window rework

[GPU] Add FXAA post-processing
[UI] Add FidelityFX FSR and CAS post-processing
[UI] Add blue noise dithering from 10bpc to 8bpc
[GPU] Apply the DC PWL gamma ramp closer to the spec, supporting fully white color
[UI] Allow the GPU CP thread to present on the host directly, bypassing the UI thread OS paint event
[UI] Allow variable refresh rate (or tearing)
[UI] Present the newest frame (restart) on DXGI
[UI] Replace GraphicsContext with a far more advanced Presenter with more coherent surface connection and UI overlay state management
[UI] Connect presentation to windows via the Surface class, not native window handles
[Vulkan] Switch to simpler Vulkan setup with no instance/device separation due to interdependencies and to pass fewer objects around
[Vulkan] Lower the minimum required Vulkan version to 1.0
[UI/GPU] Various cleanup, mainly ComPtr usage
[UI] Support per-monitor DPI awareness v2 on Windows
[UI] DPI-scale Dear ImGui
[UI] Replace the remaining non-detachable window delegates with unified window event and input listeners
[UI] Allow listeners to safely destroy or close the window, and to register/unregister listeners without use-after-free and the ABA problem
[UI] Explicit Z ordering of input listeners and UI overlays, top-down for input, bottom-up for drawing
[UI] Add explicit window lifecycle phases
[UI] Replace Window virtual functions with explicit desired state, its application, actual state, its feedback
[UI] GTK: Apply the initial size to the drawing area
[UI] Limit internal UI frame rate to that of the monitor
[UI] Hide the cursor using a timer instead of polling due to no repeated UI thread paints with GPU CP thread presentation, and only within the window
This commit is contained in:
Triang3l
2022-01-29 13:22:03 +03:00
parent 372bdd3ec9
commit fe3f0f26e4
428 changed files with 75942 additions and 18360 deletions

View File

@@ -2,7 +2,7 @@
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2020 Ben Vanik. All rights reserved. *
* Copyright 2022 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
@@ -32,8 +32,8 @@
#include "xenia/gpu/dxbc_shader_translator.h"
#include "xenia/gpu/xenos.h"
#include "xenia/kernel/kernel_state.h"
#include "xenia/ui/d3d12/d3d12_context.h"
#include "xenia/ui/d3d12/d3d12_descriptor_heap_pool.h"
#include "xenia/ui/d3d12/d3d12_provider.h"
#include "xenia/ui/d3d12/d3d12_upload_buffer_pool.h"
#include "xenia/ui/d3d12/d3d12_util.h"
@@ -58,8 +58,9 @@ class D3D12CommandProcessor : public CommandProcessor {
void RestoreEdramSnapshot(const void* snapshot) override;
ui::d3d12::D3D12Context& GetD3D12Context() const {
return static_cast<ui::d3d12::D3D12Context&>(*context_);
ui::d3d12::D3D12Provider& GetD3D12Provider() const {
return *static_cast<ui::d3d12::D3D12Provider*>(
graphics_system_->provider());
}
// Returns the deferred drawing command list for the currently open
@@ -153,7 +154,7 @@ class D3D12CommandProcessor : public CommandProcessor {
kEdramR32G32UintUAV,
kEdramR32G32B32A32UintUAV,
kGammaRampNormalSRV,
kGammaRampTableSRV,
kGammaRampPWLSRV,
// Beyond this point, SRVs are accessible to shaders through an unbounded
@@ -210,16 +211,14 @@ class D3D12CommandProcessor : public CommandProcessor {
// Returns the text to display in the GPU backend name in the window title.
std::string GetWindowTitleText() const;
std::unique_ptr<xe::ui::RawImage> Capture();
protected:
bool SetupContext() override;
void ShutdownContext() override;
void WriteRegister(uint32_t index, uint32_t value) override;
void PerformSwap(uint32_t frontbuffer_ptr, uint32_t frontbuffer_width,
uint32_t frontbuffer_height) override;
void IssueSwap(uint32_t frontbuffer_ptr, uint32_t frontbuffer_width,
uint32_t frontbuffer_height) override;
void OnPrimaryBufferEnd() override;
@@ -321,8 +320,9 @@ class D3D12CommandProcessor : public CommandProcessor {
void CheckSubmissionFence(uint64_t await_submission);
// If is_guest_command is true, a new full frame - with full cleanup of
// resources and, if needed, starting capturing - is opened if pending (as
// opposed to simply resuming after mid-frame synchronization).
void BeginSubmission(bool is_guest_command);
// opposed to simply resuming after mid-frame synchronization). Returns
// whether a submission is open currently and the device is not removed.
bool BeginSubmission(bool is_guest_command);
// If is_swap is true, a full frame is closed - with, if needed, cache
// clearing and stopping capturing. Returns whether the submission was done
// successfully, if it has failed, leaves it open.
@@ -380,6 +380,8 @@ class D3D12CommandProcessor : public CommandProcessor {
void WriteGammaRampSRV(bool is_pwl, D3D12_CPU_DESCRIPTOR_HANDLE handle) const;
bool device_removed_ = false;
bool cache_clear_requested_ = false;
HANDLE fence_completion_event_ = nullptr;
@@ -497,42 +499,73 @@ class D3D12CommandProcessor : public CommandProcessor {
std::unique_ptr<TextureCache> texture_cache_;
// Mip 0 contains the normal gamma ramp (256 entries), mip 1 contains the PWL
// ramp (128 entries). DXGI_FORMAT_R10G10B10A2_UNORM 1D.
ID3D12Resource* gamma_ramp_texture_ = nullptr;
D3D12_RESOURCE_STATES gamma_ramp_texture_state_;
// Bytes 0x0...0x3FF - 256-entry R10G10B10X2 gamma ramp (red and blue must be
// read as swapped - 535107D4 has settings allowing separate configuration).
// Bytes 0x400...0x9FF - 128-entry PWL R16G16 gamma ramp (R - base, G - delta,
// low 6 bits of each are zero, 3 elements per entry).
// https://www.x.org/docs/AMD/old/42590_m76_rrg_1.01o.pdf
Microsoft::WRL::ComPtr<ID3D12Resource> gamma_ramp_buffer_;
D3D12_RESOURCE_STATES gamma_ramp_buffer_state_;
// Upload buffer for an image that is the same as gamma_ramp_, but with
// kQueueFrames array layers.
ID3D12Resource* gamma_ramp_upload_ = nullptr;
uint8_t* gamma_ramp_upload_mapping_ = nullptr;
D3D12_PLACED_SUBRESOURCE_FOOTPRINT gamma_ramp_footprints_[kQueueFrames * 2];
Microsoft::WRL::ComPtr<ID3D12Resource> gamma_ramp_upload_buffer_;
uint8_t* gamma_ramp_upload_buffer_mapping_ = nullptr;
static constexpr uint32_t kSwapTextureWidth = 1280;
static constexpr uint32_t kSwapTextureHeight = 720;
std::pair<uint32_t, uint32_t> GetSwapTextureSize() const {
return std::make_pair(
kSwapTextureWidth * texture_cache_->GetDrawResolutionScaleX(),
kSwapTextureHeight * texture_cache_->GetDrawResolutionScaleY());
}
std::pair<uint32_t, uint32_t> GetSwapScreenSize() const {
uint32_t resolution_scale =
std::max(texture_cache_->GetDrawResolutionScaleX(),
texture_cache_->GetDrawResolutionScaleY());
return std::make_pair(kSwapTextureWidth * resolution_scale,
kSwapTextureHeight * resolution_scale);
}
ID3D12Resource* swap_texture_ = nullptr;
D3D12_PLACED_SUBRESOURCE_FOOTPRINT swap_texture_copy_footprint_;
UINT64 swap_texture_copy_size_;
ID3D12DescriptorHeap* swap_texture_rtv_descriptor_heap_ = nullptr;
D3D12_CPU_DESCRIPTOR_HANDLE swap_texture_rtv_;
ID3D12DescriptorHeap* swap_texture_srv_descriptor_heap_ = nullptr;
struct ApplyGammaConstants {
uint32_t size[2];
};
enum class ApplyGammaRootParameter : UINT {
kConstants,
kDestination,
kSource,
kRamp,
kCount,
};
Microsoft::WRL::ComPtr<ID3D12RootSignature> apply_gamma_root_signature_;
Microsoft::WRL::ComPtr<ID3D12PipelineState> apply_gamma_table_pipeline_;
Microsoft::WRL::ComPtr<ID3D12PipelineState>
apply_gamma_table_fxaa_luma_pipeline_;
Microsoft::WRL::ComPtr<ID3D12PipelineState> apply_gamma_pwl_pipeline_;
Microsoft::WRL::ComPtr<ID3D12PipelineState>
apply_gamma_pwl_fxaa_luma_pipeline_;
struct FxaaConstants {
uint32_t size[2];
float size_inv[2];
};
enum class FxaaRootParameter : UINT {
kConstants,
kDestination,
kSource,
kCount,
};
Microsoft::WRL::ComPtr<ID3D12RootSignature> fxaa_root_signature_;
Microsoft::WRL::ComPtr<ID3D12PipelineState> fxaa_pipeline_;
Microsoft::WRL::ComPtr<ID3D12PipelineState> fxaa_extreme_pipeline_;
// PWL gamma ramp can result in values with more precision than 10bpc. Though
// those sub-10bpc bits don't have any noticeable visual effect, so normally
// R10G10B10A2_UNORM is enough. But what's the most important is that for the
// original FXAA shader, the luma needs to be written to the alpha channel.
// For simplicity (to avoid modifying the FXAA shader and adding more texture
// fetches into it), and for the highest quality (preserving all 13 bits that
// may be generated by applying the PWL gamma ramp with an increment of 2^3,
// and also leaving some space for the result of applying fractional weights
// to calculate the luma), using R16G16B16A16_UNORM instead of
// R10G10B10X2_UNORM with a separate alpha texture.
static constexpr DXGI_FORMAT kFxaaSourceTextureFormat =
DXGI_FORMAT_R16G16B16A16_UNORM;
// Kept in NON_PIXEL_SHADER_RESOURCE state.
Microsoft::WRL::ComPtr<ID3D12Resource> fxaa_source_texture_;
uint64_t fxaa_source_texture_submission_ = 0;
// Unsubmitted barrier batch.
std::vector<D3D12_RESOURCE_BARRIER> barriers_;
// <Resource, submission where requested>, sorted by the submission number.
std::deque<std::pair<ID3D12Resource*, uint64_t>> buffers_for_deletion_;
std::deque<std::pair<uint64_t, ID3D12Resource*>> resources_for_deletion_;
static constexpr uint32_t kScratchBufferSizeIncrement = 16 * 1024 * 1024;
ID3D12Resource* scratch_buffer_ = nullptr;