From b90465e2e59277403b0ad400ec143dcd3a474a20 Mon Sep 17 00:00:00 2001 From: DrChat Date: Mon, 16 Apr 2018 12:54:50 -0500 Subject: [PATCH] [Vulkan] Halve the viewport dimensions when viewport scaling is disabled (10240 -> 5120) The negative part of the viewport is unused, so hijack the 2 unused parameters of the window scale to use as an offset --- src/xenia/gpu/spirv_shader_translator.cc | 10 +++++++++- src/xenia/gpu/vulkan/pipeline_cache.cc | 16 ++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index 6fd80c26e..384190124 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -532,8 +532,16 @@ std::vector SpirvShaderTranslator::CompleteTranslation() { // pos.xy *= window_scale.xy auto p_scaled = b.createBinOp(spv::Op::OpFMul, vec4_float_type_, p, window_scale); + + // Apply window offset + // pos.xy += window_scale.zw + auto window_offset = b.createOp(spv::Op::OpVectorShuffle, vec4_float_type_, + {window_scale, window_scale, 2, 3, 0, 1}); + auto p_offset = b.createBinOp(spv::Op::OpFAdd, vec4_float_type_, p_scaled, + window_offset); + p = b.createOp(spv::Op::OpVectorShuffle, vec4_float_type_, - {p, p_scaled, 4, 5, 2, 3}); + {p, p_offset, 4, 5, 2, 3}); b.createStore(p, pos_); } else { diff --git a/src/xenia/gpu/vulkan/pipeline_cache.cc b/src/xenia/gpu/vulkan/pipeline_cache.cc index b71b70c9d..b1eeec71e 100644 --- a/src/xenia/gpu/vulkan/pipeline_cache.cc +++ b/src/xenia/gpu/vulkan/pipeline_cache.cc @@ -674,10 +674,11 @@ bool PipelineCache::SetDynamicState(VkCommandBuffer command_buffer, vpx = window_width_scalar * vox - vpw / 2 + vtx_window_offset_x; vpy = window_height_scalar * voy - vph / 2 + vtx_window_offset_y; } else { - vpw = 2 * 2560.0f * window_width_scalar; - vph = 2 * 2560.0f * window_height_scalar; - vpx = -2560.0f * window_width_scalar + vtx_window_offset_x; - vpy = -2560.0f * window_height_scalar + vtx_window_offset_y; + // TODO(DrChat): This should be the width/height of the target picture + vpw = 2560.0f * window_width_scalar; + vph = 2560.0f * window_height_scalar; + vpx = vtx_window_offset_x; + vpy = vtx_window_offset_y; } if (viewport_state_dirty) { @@ -776,12 +777,15 @@ bool PipelineCache::SetDynamicState(VkCommandBuffer command_buffer, if (vport_xscale_enable) { push_constants.window_scale[0] = 1.0f; push_constants.window_scale[1] = -1.0f; + push_constants.window_scale[2] = 0.f; + push_constants.window_scale[3] = 0.f; } else { + // 1 / unscaled viewport w/h push_constants.window_scale[0] = 1.0f / 2560.0f; push_constants.window_scale[1] = 1.0f / 2560.0f; + push_constants.window_scale[2] = -1.f; + push_constants.window_scale[3] = -1.f; } - push_constants.window_scale[2] = vpw; - push_constants.window_scale[3] = vph; // http://www.x.org/docs/AMD/old/evergreen_3D_registers_v2.pdf // VTX_XY_FMT = true: the incoming XY have already been multiplied by 1/W0.