summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrChat <arkolbed@gmail.com>2018-04-14 17:33:24 -0500
committerDrChat <arkolbed@gmail.com>2018-04-14 17:34:21 -0500
commitf8319ec12fffac03f2ea3d87f436f5b9e9e3c9a2 (patch)
tree4bdfd344e68970127e533d481705978fcb31113d
parentd914791afea408f9e000e3fc5b4b83f218a67772 (diff)
[Base] Support sign-extension in bitfield
-rw-r--r--src/xenia/base/bit_field.h22
-rw-r--r--src/xenia/gpu/vulkan/vulkan_command_processor.cc11
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));