summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index a305109c010..373994186e7 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -1671,6 +1671,35 @@ generate_unswizzled_blend(struct gallivm_state *gallivm,
/* Convert */
lp_build_conv(gallivm, fs_type, blend_type, &blend_color, 1, &blend_color, 1);
+ if (out_format_desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
+ /*
+ * since blending is done with floats, there was no conversion.
+ * However, the rules according to fixed point renderbuffers still
+ * apply, that is we must clamp inputs to 0.0/1.0.
+ * (This would apply to separate alpha conversion too but we currently
+ * force has_alpha to be true.)
+ * TODO: should skip this with "fake" blend, since post-blend conversion
+ * will clamp anyway.
+ * TODO: could also skip this if fragment color clamping is enabled. We
+ * don't support it natively so it gets baked into the shader however, so
+ * can't really tell here.
+ */
+ struct lp_build_context f32_bld;
+ assert(row_type.floating);
+ lp_build_context_init(&f32_bld, gallivm, row_type);
+ for (i = 0; i < src_count; i++) {
+ src[i] = lp_build_clamp(&f32_bld, src[i], f32_bld.zero, f32_bld.one);
+ }
+ if (dual_source_blend) {
+ for (i = 0; i < src_count; i++) {
+ src1[i] = lp_build_clamp(&f32_bld, src1[i], f32_bld.zero, f32_bld.one);
+ }
+ }
+ /* probably can't be different than row_type but better safe than sorry... */
+ lp_build_context_init(&f32_bld, gallivm, blend_type);
+ blend_color = lp_build_clamp(&f32_bld, blend_color, f32_bld.zero, f32_bld.one);
+ }
+
/* Extract alpha */
blend_alpha = lp_build_extract_broadcast(gallivm, blend_type, row_type, blend_color, lp_build_const_int32(gallivm, 3));
@@ -1827,6 +1856,12 @@ generate_unswizzled_blend(struct gallivm_state *gallivm,
*/
convert_to_blend_type(gallivm, block_size, out_format_desc, dst_type, row_type, dst, src_count);
+ /*
+ * FIXME: Really should get logic ops / masks out of generic blend / row
+ * format. Logic ops will definitely not work on the blend float format
+ * used for SRGB here and I think OpenGL expects this to work as expected
+ * (that is incoming values converted to srgb then logic op applied).
+ */
for (i = 0; i < src_count; ++i) {
dst[i] = lp_build_blend_aos(gallivm,
&variant->key.blend,