freedreno/a3xx: alpha render-target shenanigans

We need the .w component to end up in .x, since the hw appears to fetch
gl_FragColor starting with the .x coordinate regardless of MRT format.
As long as we are doing this, we might as well throw out the remaining
unneeded components.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
(cherry picked from commit 80058c0f08)
This commit is contained in:
Rob Clark 2014-09-12 09:01:25 -04:00 committed by Emil Velikov
parent 695a4b2b4e
commit 34b62bd12e
4 changed files with 34 additions and 2 deletions

View file

@ -30,6 +30,7 @@
#include "util/u_string.h"
#include "util/u_memory.h"
#include "util/u_prim.h"
#include "util/u_format.h"
#include "freedreno_state.h"
#include "freedreno_resource.h"
@ -103,6 +104,7 @@ fd3_draw(struct fd_context *ctx, const struct pipe_draw_info *info)
/* do binning pass first: */
.binning_pass = true,
.color_two_side = ctx->rasterizer ? ctx->rasterizer->light_twoside : false,
.alpha = util_format_is_alpha(pipe_surface_format(ctx->framebuffer.cbufs[0])),
// TODO set .half_precision based on render target format,
// ie. float16 and smaller use half, float32 use full..
.half_precision = !!(fd_mesa_debug & FD_DBG_FRAGHALF),

View file

@ -2607,6 +2607,23 @@ ir3_compile_shader(struct ir3_shader_variant *so,
block->noutputs = j * 4;
}
/* for rendering to alpha format, we only need the .w component,
* and we need it to be in the .x position:
*/
if (key.alpha) {
for (i = 0, j = 0; i < so->outputs_count; i++) {
unsigned name = sem2name(so->outputs[i].semantic);
/* move .w component to .x and discard others: */
if (name == TGSI_SEMANTIC_COLOR) {
block->outputs[(i*4)+0] = block->outputs[(i*4)+3];
block->outputs[(i*4)+1] = NULL;
block->outputs[(i*4)+2] = NULL;
block->outputs[(i*4)+3] = NULL;
}
}
}
/* at this point, we want the kill's in the outputs array too,
* so that they get scheduled (since they have no dst).. we've
* already ensured that the array is big enough in push_block():

View file

@ -183,6 +183,7 @@ ir3_shader_variant(struct ir3_shader *shader, struct ir3_shader_key key)
if (shader->type == SHADER_VERTEX) {
key.color_two_side = false;
key.half_precision = false;
key.alpha = false;
}
for (v = shader->variants; v; v = v->next)

View file

@ -54,12 +54,24 @@ static inline uint16_t sem2idx(ir3_semantic sem)
* in hw (two sided color), binning-pass vertex shader, etc.
*/
struct ir3_shader_key {
/* vertex shader variant parameters: */
/*
* Vertex shader variant parameters:
*/
unsigned binning_pass : 1;
/* fragment shader variant parameters: */
/*
* Fragment shader variant parameters:
*/
unsigned color_two_side : 1;
unsigned half_precision : 1;
/* For rendering to alpha, we need a bit of special handling
* since the hw always takes gl_FragColor starting from x
* component, rather than figuring out to take the w component.
* We could be more clever and generate variants for other
* render target formats (ie. luminance formats are xxx1), but
* let's start with this and see how it goes:
*/
unsigned alpha : 1;
};
struct ir3_shader_variant {