From a07fa6516b0157aaae1213b284e3817c2148bf52 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 10 Jul 2023 17:34:50 +1000 Subject: [PATCH] llvmpipe/linear: add support for rgba color buffers. This adds support to the linear rast for rgba outputs. Reviewed-by: Brian Paul Part-of: --- src/gallium/drivers/llvmpipe/lp_linear.c | 14 +++++++++----- src/gallium/drivers/llvmpipe/lp_state_derived.c | 8 +++++--- src/gallium/drivers/llvmpipe/lp_state_fs.c | 4 +++- .../drivers/llvmpipe/lp_state_fs_linear_llvm.c | 9 ++++++--- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_linear.c b/src/gallium/drivers/llvmpipe/lp_linear.c index 1fbb8787e9c..40326b46d2a 100644 --- a/src/gallium/drivers/llvmpipe/lp_linear.c +++ b/src/gallium/drivers/llvmpipe/lp_linear.c @@ -122,15 +122,19 @@ lp_fs_linear_run(const struct lp_rast_state *state, struct lp_jit_linear_context jit; jit.constants = (const uint8_t (*)[4])constants; - /* We assume BGRA ordering */ - assert(variant->key.cbuf_format[0] == PIPE_FORMAT_B8G8R8X8_UNORM || - variant->key.cbuf_format[0] == PIPE_FORMAT_B8G8R8A8_UNORM); - - jit.blend_color = + if (!rgba_order) { + jit.blend_color = state->jit_context.u8_blend_color[32] + (state->jit_context.u8_blend_color[16] << 8) + (state->jit_context.u8_blend_color[0] << 16) + (state->jit_context.u8_blend_color[48] << 24); + } else { + jit.blend_color = + (state->jit_context.u8_blend_color[32] << 24) + + (state->jit_context.u8_blend_color[16] << 16) + + (state->jit_context.u8_blend_color[0] << 8) + + (state->jit_context.u8_blend_color[48] << 0); + } jit.alpha_ref_value = float_to_ubyte(state->jit_context.alpha_ref_value); diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index 1ca5eed7601..fc871def559 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -186,18 +186,20 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe) static void check_linear_rasterizer(struct llvmpipe_context *lp) { - const bool bgr8 = + const bool valid_cb_format = (lp->framebuffer.nr_cbufs == 1 && lp->framebuffer.cbufs[0] && util_res_sample_count(lp->framebuffer.cbufs[0]->texture) == 1 && lp->framebuffer.cbufs[0]->texture->target == PIPE_TEXTURE_2D && (lp->framebuffer.cbufs[0]->format == PIPE_FORMAT_B8G8R8A8_UNORM || - lp->framebuffer.cbufs[0]->format == PIPE_FORMAT_B8G8R8X8_UNORM)); + lp->framebuffer.cbufs[0]->format == PIPE_FORMAT_B8G8R8X8_UNORM || + lp->framebuffer.cbufs[0]->format == PIPE_FORMAT_R8G8B8A8_UNORM || + lp->framebuffer.cbufs[0]->format == PIPE_FORMAT_R8G8B8X8_UNORM)); /* permit_linear means guardband, hence fake scissor, which we can only * handle if there's just one vp. */ const bool single_vp = lp->viewport_index_slot < 0; const bool permit_linear = (!lp->framebuffer.zsbuf && - bgr8 && + valid_cb_format && single_vp); /* Tell draw that we're happy doing our own x/y clipping. diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index eddfadd81bd..68993555561 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -3863,7 +3863,9 @@ generate_variant(struct llvmpipe_context *lp, !shader->info.base.uses_kill && !key->blend.logicop_enable && (key->cbuf_format[0] == PIPE_FORMAT_B8G8R8A8_UNORM || - key->cbuf_format[0] == PIPE_FORMAT_B8G8R8X8_UNORM); + key->cbuf_format[0] == PIPE_FORMAT_B8G8R8X8_UNORM || + key->cbuf_format[0] == PIPE_FORMAT_R8G8B8A8_UNORM || + key->cbuf_format[0] == PIPE_FORMAT_R8G8B8X8_UNORM); memcpy(&variant->key, key, sizeof *key); diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs_linear_llvm.c b/src/gallium/drivers/llvmpipe/lp_state_fs_linear_llvm.c index 9f11357c429..8d946913f14 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs_linear_llvm.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs_linear_llvm.c @@ -137,11 +137,14 @@ llvm_fragment_body(struct lp_build_context *bld, LLVMValueRef dst) { static const unsigned char bgra_swizzles[4] = {2, 1, 0, 3}; + static const unsigned char rgba_swizzles[4] = {0, 1, 2, 3}; LLVMValueRef inputs[PIPE_MAX_SHADER_INPUTS]; LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS]; LLVMBuilderRef builder = bld->gallivm->builder; struct gallivm_state *gallivm = bld->gallivm; LLVMValueRef result = NULL; + bool rgba_order = (variant->key.cbuf_format[0] == PIPE_FORMAT_R8G8B8A8_UNORM || + variant->key.cbuf_format[0] == PIPE_FORMAT_R8G8B8X8_UNORM); sampler->instance = 0; @@ -164,14 +167,14 @@ llvm_fragment_body(struct lp_build_context *bld, if (shader->base.type == PIPE_SHADER_IR_TGSI) { lp_build_tgsi_aos(gallivm, shader->base.tokens, fs_type, - bgra_swizzles, + rgba_order ? rgba_swizzles : bgra_swizzles, consts_ptr, inputs, outputs, &sampler->base, &shader->info.base); } else { nir_shader *clone = nir_shader_clone(NULL, shader->base.ir.nir); lp_build_nir_aos(gallivm, clone, fs_type, - bgra_swizzles, + rgba_order ? rgba_swizzles : bgra_swizzles, consts_ptr, inputs, outputs, &sampler->base, &shader->info.base); @@ -226,7 +229,7 @@ llvm_fragment_body(struct lp_build_context *bld, mask, blend_color, /* const_ */ NULL, /* const_alpha */ - bgra_swizzles, + rgba_order ? rgba_swizzles : bgra_swizzles, 4); }