From aed517f98592bd7969f893bbabdb64acf2f6623f Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Mon, 7 Nov 2016 19:12:23 -0500 Subject: [PATCH] swr: [rasterizer jitter] fix logic op to work with unorm/snorm Most logic op usage is probably going to end up with normalized textures. Scale the floating point values and convert to integer before performing the logic operations. Signed-off-by: Ilia Mirkin Reviewed-by: Tim Rowley --- .../swr/rasterizer/jitter/blend_jit.cpp | 82 +++++++++++++++---- 1 file changed, 65 insertions(+), 17 deletions(-) diff --git a/src/gallium/drivers/swr/rasterizer/jitter/blend_jit.cpp b/src/gallium/drivers/swr/rasterizer/jitter/blend_jit.cpp index 1452d27675a..46ea4951e87 100644 --- a/src/gallium/drivers/swr/rasterizer/jitter/blend_jit.cpp +++ b/src/gallium/drivers/swr/rasterizer/jitter/blend_jit.cpp @@ -649,29 +649,55 @@ struct BlendJit : public Builder if(state.blendState.logicOpEnable) { const SWR_FORMAT_INFO& info = GetFormatInfo(state.format); - SWR_ASSERT(info.type[0] == SWR_TYPE_UINT); Value* vMask[4]; + float scale[4]; + + if (!state.blendState.blendEnable) + { + Clamp(state.format, src); + Clamp(state.format, dst); + } + for(uint32_t i = 0; i < 4; i++) { - switch(info.bpc[i]) + if (info.type[i] == SWR_TYPE_UNUSED) { - case 0: vMask[i] = VIMMED1(0x00000000); break; - case 2: vMask[i] = VIMMED1(0x00000003); break; - case 5: vMask[i] = VIMMED1(0x0000001F); break; - case 6: vMask[i] = VIMMED1(0x0000003F); break; - case 8: vMask[i] = VIMMED1(0x000000FF); break; - case 10: vMask[i] = VIMMED1(0x000003FF); break; - case 11: vMask[i] = VIMMED1(0x000007FF); break; - case 16: vMask[i] = VIMMED1(0x0000FFFF); break; - case 24: vMask[i] = VIMMED1(0x00FFFFFF); break; - case 32: vMask[i] = VIMMED1(0xFFFFFFFF); break; + continue; + } + + if (info.bpc[i] >= 32) { + vMask[i] = VIMMED1(0xFFFFFFFF); + scale[i] = 0xFFFFFFFF; + } else { + vMask[i] = VIMMED1((1 << info.bpc[i]) - 1); + if (info.type[i] == SWR_TYPE_SNORM) + scale[i] = (1 << (info.bpc[i] - 1)) - 1; + else + scale[i] = (1 << info.bpc[i]) - 1; + } + + switch (info.type[i]) { default: - vMask[i] = VIMMED1(0x0); - SWR_ASSERT(0, "Unsupported bpc for logic op\n"); + SWR_ASSERT(0, "Unsupported type for logic op\n"); + /* fallthrough */ + case SWR_TYPE_UINT: + case SWR_TYPE_SINT: + src[i] = BITCAST(src[i], mSimdInt32Ty); + dst[i] = BITCAST(dst[i], mSimdInt32Ty); + break; + case SWR_TYPE_SNORM: + src[i] = FADD(src[i], VIMMED1(0.5f)); + dst[i] = FADD(dst[i], VIMMED1(0.5f)); + /* fallthrough */ + case SWR_TYPE_UNORM: + src[i] = FP_TO_UI( + FMUL(src[i], VIMMED1(scale[i])), + mSimdInt32Ty); + dst[i] = FP_TO_UI( + FMUL(dst[i], VIMMED1(scale[i])), + mSimdInt32Ty); break; } - src[i] = BITCAST(src[i], mSimdInt32Ty);//, vMask[i]); - dst[i] = BITCAST(dst[i], mSimdInt32Ty); } LogicOpFunc(state.blendState.logicOpFunc, src, dst, result); @@ -679,10 +705,32 @@ struct BlendJit : public Builder // store results out for(uint32_t i = 0; i < 4; ++i) { + if (info.type[i] == SWR_TYPE_UNUSED) + { + continue; + } + // clear upper bits from PS output not in RT format after doing logic op result[i] = AND(result[i], vMask[i]); - STORE(BITCAST(result[i], mSimdFP32Ty), pResult, {i}); + switch (info.type[i]) { + default: + SWR_ASSERT(0, "Unsupported type for logic op\n"); + /* fallthrough */ + case SWR_TYPE_UINT: + case SWR_TYPE_SINT: + result[i] = BITCAST(result[i], mSimdFP32Ty); + break; + case SWR_TYPE_SNORM: + case SWR_TYPE_UNORM: + result[i] = FMUL(UI_TO_FP(result[i], mSimdFP32Ty), + VIMMED1(1.0f / scale[i])); + if (info.type[i] == SWR_TYPE_SNORM) + result[i] = FADD(result[i], VIMMED1(-0.5f)); + break; + } + + STORE(result[i], pResult, {i}); } } -- 2.30.2