fix Vulkan ultrawide shadow skip and macOS libc++ build
This commit is contained in:
parent
eed2883e74
commit
4329f6d049
2 changed files with 60 additions and 8 deletions
|
|
@ -141,11 +141,34 @@ struct DrawFingerprintKeyHash {
|
||||||
std::mutex g_mutex;
|
std::mutex g_mutex;
|
||||||
std::unordered_map<TargetKey, TargetEntry, TargetKeyHash> g_targets;
|
std::unordered_map<TargetKey, TargetEntry, TargetKeyHash> g_targets;
|
||||||
std::unordered_map<uint64_t, bool> g_hash_overrides;
|
std::unordered_map<uint64_t, bool> g_hash_overrides;
|
||||||
std::atomic<std::shared_ptr<const std::unordered_map<uint64_t, bool>>> g_hash_overrides_snapshot =
|
// std::atomic<std::shared_ptr<T>> is not available on every target toolchain
|
||||||
|
// (libc++ gates it behind a newer macOS deployment target than we target), so
|
||||||
|
// publish copy-on-write snapshots through a small mutex-guarded holder. The
|
||||||
|
// expensive map rebuild happens before store(), outside this lock, so readers
|
||||||
|
// never block on a writer's rebuild -- only the pointer swap/copy is guarded.
|
||||||
|
template <typename T>
|
||||||
|
class SnapshotPtr {
|
||||||
|
public:
|
||||||
|
SnapshotPtr() = default;
|
||||||
|
SnapshotPtr(std::shared_ptr<T> initial) : ptr_(std::move(initial)) {}
|
||||||
|
std::shared_ptr<T> load(std::memory_order = std::memory_order_seq_cst) const {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
return ptr_;
|
||||||
|
}
|
||||||
|
void store(std::shared_ptr<T> next, std::memory_order = std::memory_order_seq_cst) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
ptr_ = std::move(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable std::mutex mutex_;
|
||||||
|
std::shared_ptr<T> ptr_;
|
||||||
|
};
|
||||||
|
|
||||||
|
SnapshotPtr<const std::unordered_map<uint64_t, bool>> g_hash_overrides_snapshot =
|
||||||
std::make_shared<const std::unordered_map<uint64_t, bool>>();
|
std::make_shared<const std::unordered_map<uint64_t, bool>>();
|
||||||
std::unordered_map<SemanticTargetKey, bool, SemanticTargetKeyHash> g_semantic_overrides;
|
std::unordered_map<SemanticTargetKey, bool, SemanticTargetKeyHash> g_semantic_overrides;
|
||||||
std::atomic<std::shared_ptr<const std::unordered_map<SemanticTargetKey, bool,
|
SnapshotPtr<const std::unordered_map<SemanticTargetKey, bool, SemanticTargetKeyHash>>
|
||||||
SemanticTargetKeyHash>>>
|
|
||||||
g_semantic_overrides_snapshot =
|
g_semantic_overrides_snapshot =
|
||||||
std::make_shared<const std::unordered_map<SemanticTargetKey, bool,
|
std::make_shared<const std::unordered_map<SemanticTargetKey, bool,
|
||||||
SemanticTargetKeyHash>>();
|
SemanticTargetKeyHash>>();
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,25 @@ REXCVAR_DEFINE_BOOL(vulkan_skip_inert_no_pixel_draws, false, "GPU/Vulkan",
|
||||||
"occlusion side effects")
|
"occlusion side effects")
|
||||||
.lifecycle(rex::cvar::Lifecycle::kHotReload);
|
.lifecycle(rex::cvar::Lifecycle::kHotReload);
|
||||||
|
|
||||||
|
// Skate 3 ultrawide cvars. These mirror the Direct3D 12 backend's definitions
|
||||||
|
// so the Hor+ classifier behaves identically on Vulkan; the D3D12 translation
|
||||||
|
// unit is not compiled on this platform, so without these the queries below
|
||||||
|
// would resolve to an unregistered flag (empty string -> false/0) and silently
|
||||||
|
// disable the shadow-map skip.
|
||||||
|
REXCVAR_DEFINE_BOOL(skate3_ultrawide_skip_shadow_targets, true, "Skate 3",
|
||||||
|
"Do not apply Skate 3 Hor+ NDC correction while rendering likely shadow maps")
|
||||||
|
.lifecycle(rex::cvar::Lifecycle::kHotReload);
|
||||||
|
REXCVAR_DEFINE_INT32(skate3_ultrawide_shadow_skip_mode, 2, "Skate 3",
|
||||||
|
"Shadow pass skip mode: 1 = square atlases, 2 = plus large offscreen, "
|
||||||
|
"3 = plus all depth-only")
|
||||||
|
.range(1, 3)
|
||||||
|
.lifecycle(rex::cvar::Lifecycle::kHotReload);
|
||||||
|
REXCVAR_DEFINE_BOOL(skate3_ultrawide_skip_screen_space_targets, false, "Skate 3",
|
||||||
|
"Exclude screen-space/orthographic (pre-divided XY) passes from Skate 3 Hor+ "
|
||||||
|
"NDC correction. Off by default so the Vulkan default classifier matches the "
|
||||||
|
"Direct3D 12 build; enable if menu/HUD fragments appear in the side areas")
|
||||||
|
.lifecycle(rex::cvar::Lifecycle::kHotReload);
|
||||||
|
|
||||||
namespace rex::graphics::vulkan {
|
namespace rex::graphics::vulkan {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
@ -160,6 +179,7 @@ bool IsGameplayStateActive(const system::KernelState* kernel_state) {
|
||||||
struct Skate3UltrawideDrawState {
|
struct Skate3UltrawideDrawState {
|
||||||
bool correction_active = false;
|
bool correction_active = false;
|
||||||
bool skip_shadow_targets = false;
|
bool skip_shadow_targets = false;
|
||||||
|
bool skip_screen_space_targets = false;
|
||||||
uint32_t shadow_skip_mode = 1;
|
uint32_t shadow_skip_mode = 1;
|
||||||
float hor_plus_scale = 1.0f;
|
float hor_plus_scale = 1.0f;
|
||||||
};
|
};
|
||||||
|
|
@ -236,6 +256,8 @@ Skate3UltrawideDrawState QuerySkate3UltrawideDrawState() {
|
||||||
|
|
||||||
state.hor_plus_scale = ComputeSkate3UltrawideHorPlusScale();
|
state.hor_plus_scale = ComputeSkate3UltrawideHorPlusScale();
|
||||||
state.skip_shadow_targets = rex::cvar::Query<bool>("skate3_ultrawide_skip_shadow_targets");
|
state.skip_shadow_targets = rex::cvar::Query<bool>("skate3_ultrawide_skip_shadow_targets");
|
||||||
|
state.skip_screen_space_targets =
|
||||||
|
rex::cvar::Query<bool>("skate3_ultrawide_skip_screen_space_targets");
|
||||||
state.shadow_skip_mode = uint32_t(std::clamp(
|
state.shadow_skip_mode = uint32_t(std::clamp(
|
||||||
rex::cvar::Query<int32_t>("skate3_ultrawide_shadow_skip_mode"), 1, 3));
|
rex::cvar::Query<int32_t>("skate3_ultrawide_shadow_skip_mode"), 1, 3));
|
||||||
return state;
|
return state;
|
||||||
|
|
@ -275,12 +297,19 @@ bool ShouldApplySkate3UltrawideHorPlus(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pre-divided XY is used by screen-space and orthographic passes. Widening
|
// The base classifier matches the Direct3D 12 build exactly. Pre-divided XY
|
||||||
// those produces the menu/HUD fragments seen in the side areas.
|
// (screen-space/orthographic passes), non-kVertex host shaders, and depth
|
||||||
|
// passes without a depth write can leak widening into the side areas as
|
||||||
|
// menu/HUD fragments; excluding them is gated behind
|
||||||
|
// skate3_ultrawide_skip_screen_space_targets (off by default) so the Vulkan
|
||||||
|
// default matches the D3D12-tuned target list unless opted in.
|
||||||
|
const bool screen_space_pass =
|
||||||
|
host_vertex_shader_type != Shader::HostVertexShaderType::kVertex ||
|
||||||
|
!normalized_depth_control.z_write_enable || pa_cl_vte_cntl.vtx_xy_fmt;
|
||||||
const bool default_enabled =
|
const bool default_enabled =
|
||||||
host_vertex_shader_type == Shader::HostVertexShaderType::kVertex && primitive_polygonal &&
|
primitive_polygonal && normalized_depth_control.z_enable &&
|
||||||
normalized_depth_control.z_enable && normalized_depth_control.z_write_enable &&
|
IsSkate3UltrawideDisplayViewport(viewport_info) &&
|
||||||
!pa_cl_vte_cntl.vtx_xy_fmt && IsSkate3UltrawideDisplayViewport(viewport_info);
|
!(ultrawide_state.skip_screen_space_targets && screen_space_pass);
|
||||||
const bool selected = ultrawide_debug::ShouldApplyAndRecord(target_key, default_enabled);
|
const bool selected = ultrawide_debug::ShouldApplyAndRecord(target_key, default_enabled);
|
||||||
if (selected && ultrawide_state.skip_shadow_targets &&
|
if (selected && ultrawide_state.skip_shadow_targets &&
|
||||||
ultrawide_debug::IsShadowMapCandidate(target_key, ultrawide_state.shadow_skip_mode)) {
|
ultrawide_debug::IsShadowMapCandidate(target_key, ultrawide_state.shadow_skip_mode)) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue