/*
* Inferred framebuffer and blender state.
*
- * One of the reasons CB_TARGET_MASK must be derived from the framebuffer state
- * is that:
- * - The blend state mask is 0xf most of the time.
- * - The COLOR1 format isn't INVALID because of possible dual-source blending,
- * so COLOR1 is enabled pretty much all the time.
- * So CB_TARGET_MASK is the only register that can disable COLOR1.
- *
- * Another reason is to avoid a hang with dual source blending.
+ * CB_TARGET_MASK is emitted here to avoid a hang with dual source blending
+ * if there is not enough PS outputs.
*/
static void si_emit_cb_render_state(struct si_context *sctx, struct r600_atom *atom)
{
struct radeon_winsys_cs *cs = sctx->b.gfx.cs;
struct si_state_blend *blend = sctx->queued.named.blend;
- uint32_t cb_target_mask = 0, i;
-
- for (i = 0; i < sctx->framebuffer.state.nr_cbufs; i++)
- if (sctx->framebuffer.state.cbufs[i])
- cb_target_mask |= 0xf << (4*i);
+ uint32_t cb_target_mask, i;
+ /* CB_COLORn_INFO.FORMAT=INVALID disables empty colorbuffer slots. */
if (blend)
- cb_target_mask &= blend->cb_target_mask;
+ cb_target_mask = blend->cb_target_mask;
+ else
+ cb_target_mask = 0xffffffff;
/* Avoid a hang that happens when dual source blending is enabled
* but there is not enough color outputs. This is undefined behavior,
S_028C70_BLEND_CLAMP(blend_clamp) |
S_028C70_BLEND_BYPASS(blend_bypass) |
S_028C70_SIMPLE_FLOAT(1) |
+ S_028C70_ROUND_MODE(ntype != V_028C70_NUMBER_UNORM &&
+ ntype != V_028C70_NUMBER_SNORM &&
+ ntype != V_028C70_NUMBER_SRGB &&
+ format != V_028C70_COLOR_8_24 &&
+ format != V_028C70_COLOR_24_8) |
S_028C70_NUMBER_TYPE(ntype) |
S_028C70_ENDIAN(endian);
vi_separate_dcc_start_query(ctx, rtex);
}
}
- /* Set the second SPI format for possible dual-src blending. */
- if (i == 1 && surf) {
- sctx->framebuffer.spi_shader_col_format |=
- surf->spi_shader_col_format << (i * 4);
- sctx->framebuffer.spi_shader_col_format_alpha |=
- surf->spi_shader_col_format_alpha << (i * 4);
- sctx->framebuffer.spi_shader_col_format_blend |=
- surf->spi_shader_col_format_blend << (i * 4);
- sctx->framebuffer.spi_shader_col_format_blend_alpha |=
- surf->spi_shader_col_format_blend_alpha << (i * 4);
- }
if (state->zsbuf) {
surf = (struct r600_surface*)state->zsbuf;
tex->dcc_offset +
tex->surface.level[cb->base.u.tex.level].dcc_offset) >> 8);
}
- /* set CB_COLOR1_INFO for possible dual-src blending */
- if (i == 1 && state->cbufs[0] &&
- sctx->framebuffer.dirty_cbufs & (1 << 0)) {
- radeon_set_context_reg(cs, R_028C70_CB_COLOR0_INFO + 1 * 0x3C,
- cb_color_info);
- i++;
- }
for (; i < 8 ; i++)
if (sctx->framebuffer.dirty_cbufs & (1 << i))
radeon_set_context_reg(cs, R_028C70_CB_COLOR0_INFO + i * 0x3C, 0);
void
si_make_buffer_descriptor(struct si_screen *screen, struct r600_resource *buf,
enum pipe_format format,
- unsigned first_element, unsigned last_element,
+ unsigned offset, unsigned size,
uint32_t *state)
{
const struct util_format_description *desc;
desc = util_format_description(format);
first_non_void = util_format_get_first_non_void_channel(format);
stride = desc->block.bits / 8;
- va = buf->gpu_address + first_element * stride;
+ va = buf->gpu_address + offset;
num_format = si_translate_buffer_numformat(&screen->b.b, desc, first_non_void);
data_format = si_translate_buffer_dataformat(&screen->b.b, desc, first_non_void);
- num_records = last_element + 1 - first_element;
+ num_records = size / stride;
num_records = MIN2(num_records, buf->b.b.width0 / stride);
if (screen->b.chip_class >= VI)
si_make_buffer_descriptor(sctx->screen,
(struct r600_resource *)texture,
state->format,
- state->u.buf.first_element,
- state->u.buf.last_element,
+ state->u.buf.offset,
+ state->u.buf.size,
view->state);
LIST_ADDTAIL(&view->list, &sctx->b.texture_buffers);