Merge branch 'master' into vulkan

This commit is contained in:
Triang3l 2022-07-01 12:51:34 +03:00
commit d174762a40
3 changed files with 32 additions and 29 deletions

View File

@ -1745,12 +1745,9 @@ void D3D12CommandProcessor::IssueSwap(uint32_t frontbuffer_ptr,
} }
D3D12_RESOURCE_DESC swap_texture_desc = swap_texture_resource->GetDesc(); D3D12_RESOURCE_DESC swap_texture_desc = swap_texture_resource->GetDesc();
uint32_t draw_resolution_scale_max =
std::max(texture_cache_->draw_resolution_scale_x(),
texture_cache_->draw_resolution_scale_y());
presenter->RefreshGuestOutput( presenter->RefreshGuestOutput(
uint32_t(swap_texture_desc.Width), uint32_t(swap_texture_desc.Height), uint32_t(swap_texture_desc.Width), uint32_t(swap_texture_desc.Height),
1280 * draw_resolution_scale_max, 720 * draw_resolution_scale_max, 1280, 720,
[this, &swap_texture_srv_desc, frontbuffer_format, swap_texture_resource, [this, &swap_texture_srv_desc, frontbuffer_format, swap_texture_resource,
&swap_texture_desc]( &swap_texture_desc](
ui::Presenter::GuestOutputRefreshContext& context) -> bool { ui::Presenter::GuestOutputRefreshContext& context) -> bool {

View File

@ -354,14 +354,14 @@ void Presenter::PaintFromUIThread(bool force_paint) {
bool Presenter::RefreshGuestOutput( bool Presenter::RefreshGuestOutput(
uint32_t frontbuffer_width, uint32_t frontbuffer_height, uint32_t frontbuffer_width, uint32_t frontbuffer_height,
uint32_t screen_width, uint32_t screen_height, uint32_t display_aspect_ratio_x, uint32_t display_aspect_ratio_y,
std::function<bool(GuestOutputRefreshContext& context)> refresher) { std::function<bool(GuestOutputRefreshContext& context)> refresher) {
GuestOutputProperties& writable_properties = GuestOutputProperties& writable_properties =
guest_output_properties_[guest_output_mailbox_writable_]; guest_output_properties_[guest_output_mailbox_writable_];
writable_properties.frontbuffer_width = frontbuffer_width; writable_properties.frontbuffer_width = frontbuffer_width;
writable_properties.frontbuffer_height = frontbuffer_height; writable_properties.frontbuffer_height = frontbuffer_height;
writable_properties.screen_width = screen_width; writable_properties.display_aspect_ratio_x = display_aspect_ratio_x;
writable_properties.screen_height = screen_height; writable_properties.display_aspect_ratio_y = display_aspect_ratio_y;
writable_properties.is_8bpc = false; writable_properties.is_8bpc = false;
bool is_active = writable_properties.IsActive(); bool is_active = writable_properties.IsActive();
if (is_active) { if (is_active) {
@ -706,8 +706,10 @@ Presenter::GuestOutputPaintFlow Presenter::GetGuestOutputPaintFlow(
// All host location calculations are DPI-independent, conceptually depending // All host location calculations are DPI-independent, conceptually depending
// only on the aspect ratios, not the absolute values. // only on the aspect ratios, not the absolute values.
uint32_t output_width, output_height; uint32_t output_width, output_height;
if (uint64_t(surface_width_in_paint_connection_) * properties.screen_height > if (uint64_t(surface_width_in_paint_connection_) *
uint64_t(properties.screen_width) * surface_height_in_paint_connection_) { properties.display_aspect_ratio_y >
uint64_t(surface_height_in_paint_connection_) *
properties.display_aspect_ratio_x) {
// The window is wider that the source - crop along Y to preserve the aspect // The window is wider that the source - crop along Y to preserve the aspect
// ratio while stretching throughout the entire surface's width, then limit // ratio while stretching throughout the entire surface's width, then limit
// the Y cropping via letterboxing or stretching along X. // the Y cropping via letterboxing or stretching along X.
@ -719,9 +721,9 @@ Presenter::GuestOutputPaintFlow Presenter::GetGuestOutputPaintFlow(
} }
// Scale the desired width by the H:W aspect ratio (inverse of W:H) to get // Scale the desired width by the H:W aspect ratio (inverse of W:H) to get
// the height. // the height.
output_height = output_height = rescale_unsigned(surface_width_in_paint_connection_,
rescale_unsigned(surface_width_in_paint_connection_, properties.display_aspect_ratio_y,
properties.screen_height, properties.screen_width); properties.display_aspect_ratio_x);
bool letterbox = false; bool letterbox = false;
if (output_height * present_safe_area > if (output_height * present_safe_area >
surface_height_in_paint_connection_ * 100) { surface_height_in_paint_connection_ * 100) {
@ -732,8 +734,9 @@ Presenter::GuestOutputPaintFlow Presenter::GetGuestOutputPaintFlow(
} }
if (letterbox && cvars::present_letterbox) { if (letterbox && cvars::present_letterbox) {
output_width = rescale_unsigned( output_width = rescale_unsigned(
properties.screen_width, surface_height_in_paint_connection_ * 100, surface_height_in_paint_connection_ * 100,
properties.screen_height * present_safe_area); properties.display_aspect_ratio_x,
properties.display_aspect_ratio_y * present_safe_area);
// output_width might have been rounded up already by rescale_unsigned, so // output_width might have been rounded up already by rescale_unsigned, so
// rounding down in this division. // rounding down in this division.
flow.output_x = (int32_t(surface_width_in_paint_connection_) - flow.output_x = (int32_t(surface_width_in_paint_connection_) -
@ -759,9 +762,9 @@ Presenter::GuestOutputPaintFlow Presenter::GetGuestOutputPaintFlow(
present_safe_area = 100; present_safe_area = 100;
} }
// Scale the desired height by the W:H aspect ratio to get the width. // Scale the desired height by the W:H aspect ratio to get the width.
output_width = output_width = rescale_unsigned(surface_height_in_paint_connection_,
rescale_unsigned(surface_height_in_paint_connection_, properties.display_aspect_ratio_x,
properties.screen_width, properties.screen_height); properties.display_aspect_ratio_y);
bool letterbox = false; bool letterbox = false;
if (output_width * present_safe_area > if (output_width * present_safe_area >
surface_width_in_paint_connection_ * 100) { surface_width_in_paint_connection_ * 100) {
@ -772,8 +775,9 @@ Presenter::GuestOutputPaintFlow Presenter::GetGuestOutputPaintFlow(
} }
if (letterbox && cvars::present_letterbox) { if (letterbox && cvars::present_letterbox) {
output_height = rescale_unsigned( output_height = rescale_unsigned(
properties.screen_height, surface_width_in_paint_connection_ * 100, surface_width_in_paint_connection_ * 100,
properties.screen_width * present_safe_area); properties.display_aspect_ratio_y,
properties.display_aspect_ratio_x * present_safe_area);
// output_height might have been rounded up already by rescale_unsigned, // output_height might have been rounded up already by rescale_unsigned,
// so rounding down in this division. // so rounding down in this division.
flow.output_y = (int32_t(surface_height_in_paint_connection_) - flow.output_y = (int32_t(surface_height_in_paint_connection_) -

View File

@ -299,7 +299,9 @@ class Presenter {
void PaintFromUIThread(bool force_paint = false); void PaintFromUIThread(bool force_paint = false);
// Pass 0 as width or height to disable guest output until the next refresh // Pass 0 as width or height to disable guest output until the next refresh
// with an actual size. The callback will receive a backend-specific context, // with an actual size. The display aspect ratio may be specified like 16:9 or
// like 1280:720, both are accepted, for simplicity, the guest display size
// may just be passed. The callback will receive a backend-specific context,
// and will not be called in case of an error such as the wrong size, or if // and will not be called in case of an error such as the wrong size, or if
// guest output is disabled. Returns whether the callback was called and it // guest output is disabled. Returns whether the callback was called and it
// returned true. The callback must submit all updating work to the host GPU // returned true. The callback must submit all updating work to the host GPU
@ -307,7 +309,7 @@ class Presenter {
// primitives required by the GuestOutputRefreshContext implementation. // primitives required by the GuestOutputRefreshContext implementation.
bool RefreshGuestOutput( bool RefreshGuestOutput(
uint32_t frontbuffer_width, uint32_t frontbuffer_height, uint32_t frontbuffer_width, uint32_t frontbuffer_height,
uint32_t screen_width, uint32_t screen_height, uint32_t display_aspect_ratio_x, uint32_t display_aspect_ratio_y,
std::function<bool(GuestOutputRefreshContext& context)> refresher); std::function<bool(GuestOutputRefreshContext& context)> refresher);
// The implementation must be callable from any thread, including from // The implementation must be callable from any thread, including from
// multiple at the same time, and it should acquire the latest guest output // multiple at the same time, and it should acquire the latest guest output
@ -354,24 +356,24 @@ class Presenter {
// this frame. // this frame.
uint32_t frontbuffer_width; uint32_t frontbuffer_width;
uint32_t frontbuffer_height; uint32_t frontbuffer_height;
// Guest screen size (primarily for the target aspect ratio, which may be // Guest display aspect ratio numerator and denominator (both 16:9 and
// different than that of the frontbuffer). // 1280:720 kinds of values are accepted).
uint32_t screen_width; uint32_t display_aspect_ratio_x;
uint32_t screen_height; uint32_t display_aspect_ratio_y;
bool is_8bpc; bool is_8bpc;
GuestOutputProperties() { SetToInactive(); } GuestOutputProperties() { SetToInactive(); }
bool IsActive() const { bool IsActive() const {
return frontbuffer_width && frontbuffer_height && screen_width && return frontbuffer_width && frontbuffer_height &&
screen_height; display_aspect_ratio_x && display_aspect_ratio_y;
} }
void SetToInactive() { void SetToInactive() {
frontbuffer_width = 0; frontbuffer_width = 0;
frontbuffer_height = 0; frontbuffer_height = 0;
screen_width = 0; display_aspect_ratio_x = 0;
screen_height = 0; display_aspect_ratio_y = 0;
is_8bpc = false; is_8bpc = false;
} }
}; };