X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fi915%2Fi915_state_emit.c;h=590a1baa42093213dd83cb2cd62918c5c4e04a72;hb=26097c4855b97ee6e362c19df11d51fb7fd42192;hp=426c683502ac5322d7b495ca2bdd24bf3cb0736e;hpb=305bcda4b583641bab5a7bfa6ce4e30a8559a868;p=mesa.git diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c index 426c683502a..590a1baa420 100644 --- a/src/gallium/drivers/i915/i915_state_emit.c +++ b/src/gallium/drivers/i915/i915_state_emit.c @@ -30,6 +30,7 @@ #include "i915_context.h" #include "i915_batch.h" #include "i915_debug.h" +#include "i915_fpc.h" #include "i915_resource.h" #include "pipe/p_context.h" @@ -151,8 +152,25 @@ emit_immediate(struct i915_context *i915) } for (i = 1; i < I915_MAX_IMMEDIATE; i++) { - if (dirty & (1 << i)) - OUT_BATCH(i915->current.immediate[i]); + if (dirty & (1 << i)) { + /* Fixup blend function for A8 dst buffers. + * When we blend to an A8 buffer, the GPU thinks it's a G8 buffer, + * and therefore we need to use the color factor for alphas. */ + if ((i == I915_IMMEDIATE_S6) && + (i915->current.target_fixup_format == PIPE_FORMAT_A8_UNORM)) { + uint32_t imm = i915->current.immediate[i]; + uint32_t srcRGB = (imm >> S6_CBUF_SRC_BLEND_FACT_SHIFT) & BLENDFACT_MASK; + if (srcRGB == BLENDFACT_DST_ALPHA) + srcRGB = BLENDFACT_DST_COLR; + else if (srcRGB == BLENDFACT_INV_DST_ALPHA) + srcRGB = BLENDFACT_INV_DST_COLR; + imm &= ~SRC_BLND_FACT(BLENDFACT_MASK); + imm |= SRC_BLND_FACT(srcRGB); + OUT_BATCH(imm); + } else { + OUT_BATCH(i915->current.immediate[i]); + } + } } } @@ -299,8 +317,10 @@ emit_sampler(struct i915_context *i915) static void validate_constants(struct i915_context *i915, unsigned *batch_space) { - *batch_space = i915->fs->num_constants ? + int nr = i915->fs->num_constants ? 2 + 4*i915->fs->num_constants : 0; + + *batch_space = nr; } static void @@ -310,6 +330,8 @@ emit_constants(struct i915_context *i915) * immediates according to the constant_flags[] array. */ const uint nr = i915->fs->num_constants; + + assert(nr < I915_MAX_CONSTANT); if (nr) { uint i; @@ -346,34 +368,48 @@ emit_constants(struct i915_context *i915) static void validate_program(struct i915_context *i915, unsigned *batch_space) { - uint additional_size = i915->current.need_target_fixup; + uint additional_size = 0; + + additional_size += i915->current.target_fixup_format ? 3 : 0; /* we need more batch space if we want to emulate rgba framebuffers */ - *batch_space = i915->fs->program_len + 3 * additional_size; + *batch_space = i915->fs->decl_len + i915->fs->program_len + additional_size; } static void emit_program(struct i915_context *i915) { - uint target_fixup = i915->current.need_target_fixup; + uint additional_size = 0; uint i; + /* count how much additional space we'll need */ + validate_program(i915, &additional_size); + additional_size -= i915->fs->decl_len + i915->fs->program_len; + /* we should always have, at least, a pass-through program */ assert(i915->fs->program_len > 0); + /* output the declarations */ { /* first word has the size, we have to adjust that */ - uint size = (i915->fs->program[0]); - size += target_fixup * 3; + uint size = (i915->fs->decl[0]); + size += additional_size; OUT_BATCH(size); } - /* output the declarations of the program */ - for (i=1 ; i < i915->fs->program_len; i++) + for (i = 1 ; i < i915->fs->decl_len; i++) + OUT_BATCH(i915->fs->decl[i]); + + /* output the program */ + assert(i915->fs->program_len % 3 == 0); + for (i = 0 ; i < i915->fs->program_len; i+=3) { OUT_BATCH(i915->fs->program[i]); + OUT_BATCH(i915->fs->program[i+1]); + OUT_BATCH(i915->fs->program[i+2]); + } /* we emit an additional mov with swizzle to fake RGBA framebuffers */ - if (target_fixup) { + if (i915->current.target_fixup_format) { /* mov out_color, out_color.zyxw */ OUT_BATCH(A0_MOV | (REG_TYPE_OC << A0_DEST_TYPE_SHIFT) | @@ -408,10 +444,22 @@ i915_validate_state(struct i915_context *i915, unsigned *batch_space) else *batch_space = 0; +#if 0 +static int counter_total = 0; +#define VALIDATE_ATOM(atom, hw_dirty) \ + if (i915->hardware_dirty & hw_dirty) { \ + static int counter_##atom = 0;\ + validate_##atom(i915, &tmp); \ + *batch_space += tmp;\ + counter_##atom += tmp;\ + counter_total += tmp;\ + printf("%s: \t%d/%d \t%2.2f\n",#atom, counter_##atom, counter_total, counter_##atom*100.f/counter_total);} +#else #define VALIDATE_ATOM(atom, hw_dirty) \ if (i915->hardware_dirty & hw_dirty) { \ validate_##atom(i915, &tmp); \ *batch_space += tmp; } +#endif VALIDATE_ATOM(flush, I915_HW_FLUSH); VALIDATE_ATOM(immediate, I915_HW_IMMEDIATE); VALIDATE_ATOM(dynamic, I915_HW_DYNAMIC);