[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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user