[D3D12] Adds scalar fallback for the SSE register-range check
This commit is contained in:
@@ -1636,8 +1636,11 @@ void D3D12CommandProcessor::ShutdownContext() {
|
|||||||
XE_FORCEINLINE
|
XE_FORCEINLINE
|
||||||
void D3D12CommandProcessor::WriteRegisterForceinline(uint32_t index,
|
void D3D12CommandProcessor::WriteRegisterForceinline(uint32_t index,
|
||||||
uint32_t value) {
|
uint32_t value) {
|
||||||
|
// Parallel range check: is index within any of these GPU register ranges?
|
||||||
|
// Each range maps to a bit in movmask (by byte pair position).
|
||||||
|
register_file_->values[index] = value;
|
||||||
|
#if XE_ARCH_AMD64
|
||||||
__m128i to_rangecheck = _mm_set1_epi16(static_cast<short>(index));
|
__m128i to_rangecheck = _mm_set1_epi16(static_cast<short>(index));
|
||||||
|
|
||||||
__m128i lower_bounds = _mm_setr_epi16(
|
__m128i lower_bounds = _mm_setr_epi16(
|
||||||
XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 - 1,
|
XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 - 1,
|
||||||
XE_GPU_REG_SHADER_CONSTANT_000_X - 1,
|
XE_GPU_REG_SHADER_CONSTANT_000_X - 1,
|
||||||
@@ -1648,25 +1651,33 @@ void D3D12CommandProcessor::WriteRegisterForceinline(uint32_t index,
|
|||||||
XE_GPU_REG_SHADER_CONSTANT_511_W + 1,
|
XE_GPU_REG_SHADER_CONSTANT_511_W + 1,
|
||||||
XE_GPU_REG_SHADER_CONSTANT_LOOP_31 + 1, XE_GPU_REG_SCRATCH_REG7 + 1,
|
XE_GPU_REG_SHADER_CONSTANT_LOOP_31 + 1, XE_GPU_REG_SCRATCH_REG7 + 1,
|
||||||
XE_GPU_REG_COHER_STATUS_HOST + 1, XE_GPU_REG_DC_LUT_30_COLOR + 1, 0, 0);
|
XE_GPU_REG_COHER_STATUS_HOST + 1, XE_GPU_REG_DC_LUT_30_COLOR + 1, 0, 0);
|
||||||
|
|
||||||
// quick pre-test
|
|
||||||
// todo: figure out just how unlikely this is. if very (it ought to be,
|
|
||||||
// theres a ton of registers other than these) make this predicate
|
|
||||||
// branchless and mark with unlikely, then make HandleSpecialRegisterWrite
|
|
||||||
// noinline yep, its very unlikely. these ORS here are meant to be bitwise
|
|
||||||
// ors, so that we do not do branching evaluation of the conditions (we will
|
|
||||||
// almost always take all of the branches)
|
|
||||||
/* unsigned expr =
|
|
||||||
(index - XE_GPU_REG_SCRATCH_REG0 < 8) |
|
|
||||||
(index == XE_GPU_REG_COHER_STATUS_HOST) |
|
|
||||||
((index - XE_GPU_REG_DC_LUT_RW_INDEX) <=
|
|
||||||
(XE_GPU_REG_DC_LUT_30_COLOR - XE_GPU_REG_DC_LUT_RW_INDEX));*/
|
|
||||||
__m128i is_above_lower = _mm_cmpgt_epi16(to_rangecheck, lower_bounds);
|
__m128i is_above_lower = _mm_cmpgt_epi16(to_rangecheck, lower_bounds);
|
||||||
__m128i is_below_upper = _mm_cmplt_epi16(to_rangecheck, upper_bounds);
|
__m128i is_below_upper = _mm_cmplt_epi16(to_rangecheck, upper_bounds);
|
||||||
__m128i is_within_range = _mm_and_si128(is_above_lower, is_below_upper);
|
__m128i is_within_range = _mm_and_si128(is_above_lower, is_below_upper);
|
||||||
register_file_->values[index] = value;
|
|
||||||
|
|
||||||
uint32_t movmask = static_cast<uint32_t>(_mm_movemask_epi8(is_within_range));
|
uint32_t movmask = static_cast<uint32_t>(_mm_movemask_epi8(is_within_range));
|
||||||
|
#else
|
||||||
|
auto in_range = [index](uint32_t lo, uint32_t hi) -> uint32_t {
|
||||||
|
return (index > lo && index < hi) ? 0x3 : 0;
|
||||||
|
};
|
||||||
|
uint32_t movmask = 0;
|
||||||
|
movmask |= in_range(XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 - 1,
|
||||||
|
XE_GPU_REG_SHADER_CONSTANT_FETCH_31_5 + 1)
|
||||||
|
<< 0;
|
||||||
|
movmask |= in_range(XE_GPU_REG_SHADER_CONSTANT_000_X - 1,
|
||||||
|
XE_GPU_REG_SHADER_CONSTANT_511_W + 1)
|
||||||
|
<< 2;
|
||||||
|
movmask |= in_range(XE_GPU_REG_SHADER_CONSTANT_BOOL_000_031 - 1,
|
||||||
|
XE_GPU_REG_SHADER_CONSTANT_LOOP_31 + 1)
|
||||||
|
<< 4;
|
||||||
|
movmask |= in_range(XE_GPU_REG_SCRATCH_REG0 - 1, XE_GPU_REG_SCRATCH_REG7 + 1)
|
||||||
|
<< 6;
|
||||||
|
movmask |= in_range(XE_GPU_REG_COHER_STATUS_HOST - 1,
|
||||||
|
XE_GPU_REG_COHER_STATUS_HOST + 1)
|
||||||
|
<< 8;
|
||||||
|
movmask |=
|
||||||
|
in_range(XE_GPU_REG_DC_LUT_RW_INDEX - 1, XE_GPU_REG_DC_LUT_30_COLOR + 1)
|
||||||
|
<< 10;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (movmask) {
|
if (movmask) {
|
||||||
if (movmask & (1 << 3)) {
|
if (movmask & (1 << 3)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user