[Mesa-dev] [PATCH 3/3] swr: [rasterizer jitter] fix logic op to work with unorm/snorm

Ilia Mirkin imirkin at alum.mit.edu
Tue Nov 8 00:18:51 UTC 2016


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 <imirkin at alum.mit.edu>
---

The gl-1.1-xor-copypixels test still fails. The image stays the same. I'm
suspecting it's for reasons outside of this patch.

I'm not too familiar with the whole swr infrastructure, perhaps there was
an eaiser way to do all this. I looked for conversion helper functions but
couldn't find anything that would fit nicely here. Feel free to point me
in the right direction.

 .../drivers/swr/rasterizer/jitter/blend_jit.cpp    | 81 +++++++++++++++++-----
 1 file changed, 64 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 1452d27..d69d503 100644
--- a/src/gallium/drivers/swr/rasterizer/jitter/blend_jit.cpp
+++ b/src/gallium/drivers/swr/rasterizer/jitter/blend_jit.cpp
@@ -649,29 +649,54 @@ 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 +704,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.7.3



More information about the mesa-dev mailing list