diff options
author | Zack Rusin <[email protected]> | 2013-12-06 01:28:25 -0500 |
---|---|---|
committer | Zack Rusin <[email protected]> | 2013-12-10 16:39:48 -0500 |
commit | 155139059ba588da1161eaa692515cacdead9f4e (patch) | |
tree | f64daec33014ca5ea6ccf8d93a58ae064dda28eb /src/gallium/drivers/llvmpipe | |
parent | 1e71493afa263791b2ff10afd2fbc36a7effa73f (diff) |
llvmpipe: fix blending with half-float formats
The fact that we flush denorms to zero breaks our half-float
conversion and blending. This patches enables denorms for
blending. It's a little tricky due to the llvm bug that makes
it incorrectly reorder the mxcsr intrinsics:
http://llvm.org/bugs/show_bug.cgi?id=6393
Signed-off-by: Zack Rusin <[email protected]>
Reviewed-by: José Fonseca <[email protected]>
Reviewed-by: Roland Scheidegger <[email protected]>
Signed-off-by: Zack Rusin <[email protected]>
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_fs.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 74c7360bfbb..93c24f6ba38 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -1554,6 +1554,28 @@ generate_unswizzled_blend(struct gallivm_state *gallivm, const boolean is_1d = variant->key.resource_1d; unsigned num_fullblock_fs = is_1d ? 2 * num_fs : num_fs; + LLVMValueRef fpstate = 0; + + /* Get type from output format */ + lp_blend_type_from_format_desc(out_format_desc, &row_type); + lp_mem_type_from_format_desc(out_format_desc, &dst_type); + + /* + * Technically this code should go into lp_build_smallfloat_to_float + * and lp_build_float_to_smallfloat but due to the + * http://llvm.org/bugs/show_bug.cgi?id=6393 + * llvm reorders the mxcsr intrinsics in a way that breaks the code. + * So the ordering is important here and there shouldn't be any + * llvm ir instrunctions in this function before + * this, otherwise half-float format conversions won't work + * (again due to llvm bug #6393). + */ + if (dst_type.floating && dst_type.width != 32) { + /* We need to make sure that denorms are ok for half float + conversions */ + fpstate = lp_build_fpstate_get(gallivm); + lp_build_fpstate_set_denorms_zero(gallivm, FALSE); + } mask_type = lp_int32_vec4_type(); mask_type.length = fs_type.length; @@ -1587,11 +1609,6 @@ generate_unswizzled_blend(struct gallivm_state *gallivm, undef_src_val = lp_build_undef(gallivm, fs_type); #endif - - /* Get type from output format */ - lp_blend_type_from_format_desc(out_format_desc, &row_type); - lp_mem_type_from_format_desc(out_format_desc, &dst_type); - row_type.length = fs_type.length; vector_width = dst_type.floating ? lp_native_vector_width : lp_integer_vector_width; @@ -2051,6 +2068,10 @@ generate_unswizzled_blend(struct gallivm_state *gallivm, dst, dst_type, dst_count, dst_alignment); } + if (dst_type.floating && dst_type.width != 32) { + lp_build_fpstate_set(gallivm, fpstate); + } + if (do_branch) { lp_build_mask_end(&mask_ctx); } |