From f8319ec12fffac03f2ea3d87f436f5b9e9e3c9a2 Mon Sep 17 00:00:00 2001 From: DrChat Date: Sat, 14 Apr 2018 17:33:24 -0500 Subject: [PATCH] [Base] Support sign-extension in bitfield --- src/xenia/base/bit_field.h | 24 ++++++++++++------- .../gpu/vulkan/vulkan_command_processor.cc | 11 ++------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/xenia/base/bit_field.h b/src/xenia/base/bit_field.h index 034f43d9e..98a8bfbf8 100644 --- a/src/xenia/base/bit_field.h +++ b/src/xenia/base/bit_field.h @@ -19,20 +19,28 @@ namespace xe { // Bitfield, where position starts at the LSB. template struct bf { - bf() = default; - inline operator T() const { return value(); } - - inline T value() const { - return static_cast((storage & mask()) >> position); - } - // For enum values, we strip them down to an underlying type. typedef typename std::conditional::value, std::underlying_type, std::remove_reference>::type::type value_type; + + bf() = default; + inline operator T() const { return value(); } + + inline T value() const { + auto value = (storage & mask()) >> position; + if (std::is_signed::value) { + // If the value is signed, sign-extend it. + value_type sign_mask = value_type(1) << (n_bits - 1); + value = (sign_mask ^ value) - sign_mask; + } + + return static_cast(value); + } + inline value_type mask() const { - return (((value_type)~0) >> (8 * sizeof(value_type) - n_bits)) << position; + return ((value_type(1) << n_bits) - 1) << position; } value_type storage; diff --git a/src/xenia/gpu/vulkan/vulkan_command_processor.cc b/src/xenia/gpu/vulkan/vulkan_command_processor.cc index b4020bea8..52f5ba7fc 100644 --- a/src/xenia/gpu/vulkan/vulkan_command_processor.cc +++ b/src/xenia/gpu/vulkan/vulkan_command_processor.cc @@ -912,15 +912,8 @@ bool VulkanCommandProcessor::IssueCopy() { // vtx_window_offset_enable assert_true(regs[XE_GPU_REG_PA_SU_SC_MODE_CNTL].u32 & 0x00010000); uint32_t window_offset = regs[XE_GPU_REG_PA_SC_WINDOW_OFFSET].u32; - int16_t window_offset_x = window_offset & 0x7FFF; - int16_t window_offset_y = (window_offset >> 16) & 0x7FFF; - // Sign-extension - if (window_offset_x & 0x4000) { - window_offset_x |= 0x8000; - } - if (window_offset_y & 0x4000) { - window_offset_y |= 0x8000; - } + int32_t window_offset_x = window_regs->window_offset.window_x_offset; + int32_t window_offset_y = window_regs->window_offset.window_y_offset; uint32_t dest_texel_size = uint32_t(GetTexelSize(copy_dest_format));