[Mesa-dev] [PATCH 3/7] swr/rast: partial support for Tiled Resources

Cherniak, Bruce bruce.cherniak at intel.com
Tue Jan 15 20:40:14 UTC 2019


Reviewed-by: Bruce Cherniak <bruce.cherniak at intel.com> 

> On Dec 17, 2018, at 8:36 AM, Alok Hota <alok.hota at intel.com> wrote:
> 
> - updated sample from TRTT surfaces correctly
> - implemented mapped status return for TRTT surfaces
> - implemented per-sample instruction minLod clamp
> - updated bilinear filter weight calculation to be closer to D3D specs
> - implemented "ReducedTexcoordRange" operation from D3D specs to avoid
> loss of precision on high-value normalized coordinates
> ---
> .../swr/rasterizer/jitter/builder_misc.cpp    | 142 ++++++++++++++++++
> .../swr/rasterizer/jitter/builder_misc.h      |  22 +++
> 2 files changed, 164 insertions(+)
> 
> diff --git a/src/gallium/drivers/swr/rasterizer/jitter/builder_misc.cpp b/src/gallium/drivers/swr/rasterizer/jitter/builder_misc.cpp
> index 26d8688f5e9..65eec4e4c68 100644
> --- a/src/gallium/drivers/swr/rasterizer/jitter/builder_misc.cpp
> +++ b/src/gallium/drivers/swr/rasterizer/jitter/builder_misc.cpp
> @@ -764,6 +764,148 @@ namespace SwrJit
>     /// @brief pop count on vector mask (e.g. <8 x i1>)
>     Value* Builder::VPOPCNT(Value* a) { return POPCNT(VMOVMSK(a)); }
> 
> +    //////////////////////////////////////////////////////////////////////////
> +    /// @brief Float / Fixed-point conversions
> +    //////////////////////////////////////////////////////////////////////////
> +    Value* Builder::VCVT_F32_FIXED_SI(Value*             vFloat,
> +                                      uint32_t           numIntBits,
> +                                      uint32_t           numFracBits,
> +                                      const llvm::Twine& name)
> +    {
> +        SWR_ASSERT((numIntBits + numFracBits) <= 32, "Can only handle 32-bit fixed-point values");
> +        Value* fixed = nullptr;
> +        if constexpr (false) // This doesn't work for negative numbers!!
> +        {
> +            fixed = FP_TO_SI(VROUND(FMUL(vFloat, VIMMED1(float(1 << numFracBits))),
> +                                    C(_MM_FROUND_TO_NEAREST_INT)),
> +                             mSimdInt32Ty);
> +        }
> +        else
> +        {
> +            // Do round to nearest int on fractional bits first
> +            // Not entirely perfect for negative numbers, but close enough
> +            vFloat = VROUND(FMUL(vFloat, VIMMED1(float(1 << numFracBits))),
> +                            C(_MM_FROUND_TO_NEAREST_INT));
> +            vFloat = FMUL(vFloat, VIMMED1(1.0f / float(1 << numFracBits)));
> +
> +            // TODO: Handle INF, NAN, overflow / underflow, etc.
> +
> +            Value* vSgn      = FCMP_OLT(vFloat, VIMMED1(0.0f));
> +            Value* vFloatInt = BITCAST(vFloat, mSimdInt32Ty);
> +            Value* vFixed    = AND(vFloatInt, VIMMED1((1 << 23) - 1));
> +            vFixed           = OR(vFixed, VIMMED1(1 << 23));
> +            vFixed           = SELECT(vSgn, NEG(vFixed), vFixed);
> +
> +            Value* vExp = LSHR(SHL(vFloatInt, VIMMED1(1)), VIMMED1(24));
> +            vExp        = SUB(vExp, VIMMED1(127));
> +
> +            Value* vExtraBits = SUB(VIMMED1(23 - numFracBits), vExp);
> +
> +            fixed = ASHR(vFixed, vExtraBits, name);
> +        }
> +
> +        return fixed;
> +    }
> +
> +    Value* Builder::VCVT_FIXED_SI_F32(Value*             vFixed,
> +                                      uint32_t           numIntBits,
> +                                      uint32_t           numFracBits,
> +                                      const llvm::Twine& name)
> +    {
> +        SWR_ASSERT((numIntBits + numFracBits) <= 32, "Can only handle 32-bit fixed-point values");
> +        uint32_t extraBits = 32 - numIntBits - numFracBits;
> +        if (numIntBits && extraBits)
> +        {
> +            // Sign extend
> +            Value* shftAmt = VIMMED1(extraBits);
> +            vFixed         = ASHR(SHL(vFixed, shftAmt), shftAmt);
> +        }
> +
> +        Value* fVal  = VIMMED1(0.0f);
> +        Value* fFrac = VIMMED1(0.0f);
> +        if (numIntBits)
> +        {
> +            fVal = SI_TO_FP(ASHR(vFixed, VIMMED1(numFracBits)), mSimdFP32Ty, name);
> +        }
> +
> +        if (numFracBits)
> +        {
> +            fFrac = UI_TO_FP(AND(vFixed, VIMMED1((1 << numFracBits) - 1)), mSimdFP32Ty);
> +            fFrac = FDIV(fFrac, VIMMED1(float(1 << numFracBits)), name);
> +        }
> +
> +        return FADD(fVal, fFrac, name);
> +    }
> +
> +    Value* Builder::VCVT_F32_FIXED_UI(Value*             vFloat,
> +                                      uint32_t           numIntBits,
> +                                      uint32_t           numFracBits,
> +                                      const llvm::Twine& name)
> +    {
> +        SWR_ASSERT((numIntBits + numFracBits) <= 32, "Can only handle 32-bit fixed-point values");
> +        Value* fixed = nullptr;
> +        if constexpr (true) // KNOB_SIM_FAST_MATH?  Below works correctly from a precision
> +                            // standpoint...
> +        {
> +            fixed = FP_TO_UI(VROUND(FMUL(vFloat, VIMMED1(float(1 << numFracBits))),
> +                                    C(_MM_FROUND_TO_NEAREST_INT)),
> +                             mSimdInt32Ty);
> +        }
> +        else
> +        {
> +            // Do round to nearest int on fractional bits first
> +            vFloat = VROUND(FMUL(vFloat, VIMMED1(float(1 << numFracBits))),
> +                            C(_MM_FROUND_TO_NEAREST_INT));
> +            vFloat = FMUL(vFloat, VIMMED1(1.0f / float(1 << numFracBits)));
> +
> +            // TODO: Handle INF, NAN, overflow / underflow, etc.
> +
> +            Value* vSgn      = FCMP_OLT(vFloat, VIMMED1(0.0f));
> +            Value* vFloatInt = BITCAST(vFloat, mSimdInt32Ty);
> +            Value* vFixed    = AND(vFloatInt, VIMMED1((1 << 23) - 1));
> +            vFixed           = OR(vFixed, VIMMED1(1 << 23));
> +
> +            Value* vExp = LSHR(SHL(vFloatInt, VIMMED1(1)), VIMMED1(24));
> +            vExp        = SUB(vExp, VIMMED1(127));
> +
> +            Value* vExtraBits = SUB(VIMMED1(23 - numFracBits), vExp);
> +
> +            fixed = LSHR(vFixed, vExtraBits, name);
> +        }
> +
> +        return fixed;
> +    }
> +
> +    Value* Builder::VCVT_FIXED_UI_F32(Value*             vFixed,
> +                                      uint32_t           numIntBits,
> +                                      uint32_t           numFracBits,
> +                                      const llvm::Twine& name)
> +    {
> +        SWR_ASSERT((numIntBits + numFracBits) <= 32, "Can only handle 32-bit fixed-point values");
> +        uint32_t extraBits = 32 - numIntBits - numFracBits;
> +        if (numIntBits && extraBits)
> +        {
> +            // Sign extend
> +            Value* shftAmt = VIMMED1(extraBits);
> +            vFixed         = ASHR(SHL(vFixed, shftAmt), shftAmt);
> +        }
> +
> +        Value* fVal  = VIMMED1(0.0f);
> +        Value* fFrac = VIMMED1(0.0f);
> +        if (numIntBits)
> +        {
> +            fVal = UI_TO_FP(LSHR(vFixed, VIMMED1(numFracBits)), mSimdFP32Ty, name);
> +        }
> +
> +        if (numFracBits)
> +        {
> +            fFrac = UI_TO_FP(AND(vFixed, VIMMED1((1 << numFracBits) - 1)), mSimdFP32Ty);
> +            fFrac = FDIV(fFrac, VIMMED1(float(1 << numFracBits)), name);
> +        }
> +
> +        return FADD(fVal, fFrac, name);
> +    }
> +
>     //////////////////////////////////////////////////////////////////////////
>     /// @brief C functions called by LLVM IR
>     //////////////////////////////////////////////////////////////////////////
> diff --git a/src/gallium/drivers/swr/rasterizer/jitter/builder_misc.h b/src/gallium/drivers/swr/rasterizer/jitter/builder_misc.h
> index f8701f9ba84..91e2a32f1a1 100644
> --- a/src/gallium/drivers/swr/rasterizer/jitter/builder_misc.h
> +++ b/src/gallium/drivers/swr/rasterizer/jitter/builder_misc.h
> @@ -122,6 +122,28 @@ Value* VMASK_16(Value* mask);
> 
> Value* VMOVMSK(Value* mask);
> 
> +//////////////////////////////////////////////////////////////////////////
> +/// @brief Float / Fixed-point conversions
> +//////////////////////////////////////////////////////////////////////////
> +// Signed
> +Value* VCVT_F32_FIXED_SI(Value*             vFloat,
> +                         uint32_t           numIntBits,
> +                         uint32_t           numFracBits,
> +                         const llvm::Twine& name = "");
> +Value* VCVT_FIXED_SI_F32(Value*             vFixed,
> +                         uint32_t           numIntBits,
> +                         uint32_t           numFracBits,
> +                         const llvm::Twine& name = "");
> +// Unsigned
> +Value* VCVT_F32_FIXED_UI(Value*             vFloat,
> +                         uint32_t           numIntBits,
> +                         uint32_t           numFracBits,
> +                         const llvm::Twine& name = "");
> +Value* VCVT_FIXED_UI_F32(Value*             vFixed,
> +                         uint32_t           numIntBits,
> +                         uint32_t           numFracBits,
> +                         const llvm::Twine& name = "");
> +
> //////////////////////////////////////////////////////////////////////////
> /// @brief functions that build IR to call x86 intrinsics directly, or
> /// emulate them with other instructions if not available on the host
> -- 
> 2.17.1
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev



More information about the mesa-dev mailing list