diff options
| author | DrChat <arkolbed@gmail.com> | 2018-04-14 17:33:24 -0500 |
|---|---|---|
| committer | DrChat <arkolbed@gmail.com> | 2018-04-14 17:34:21 -0500 |
| commit | f8319ec12fffac03f2ea3d87f436f5b9e9e3c9a2 (patch) | |
| tree | 4bdfd344e68970127e533d481705978fcb31113d | |
| parent | d914791afea408f9e000e3fc5b4b83f218a67772 (diff) | |
[Base] Support sign-extension in bitfield
| -rw-r--r-- | src/xenia/base/bit_field.h | 22 | ||||
| -rw-r--r-- | src/xenia/gpu/vulkan/vulkan_command_processor.cc | 11 |
2 files changed, 17 insertions, 16 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 <typename T, size_t position, size_t n_bits> struct bf { + // For enum values, we strip them down to an underlying type. + typedef + typename std::conditional<std::is_enum<T>::value, std::underlying_type<T>, + std::remove_reference<T>>::type::type + value_type; + bf() = default; inline operator T() const { return value(); } inline T value() const { - return static_cast<T>((storage & mask()) >> position); + auto value = (storage & mask()) >> position; + if (std::is_signed<value_type>::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<T>(value); } - // For enum values, we strip them down to an underlying type. - typedef - typename std::conditional<std::is_enum<T>::value, std::underlying_type<T>, - std::remove_reference<T>>::type::type - value_type; 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)); |
