#include "util/u_framebuffer.h"
#include "util/u_helpers.h"
#include "util/u_memory.h"
+#include "util/u_simple_shaders.h"
static void si_init_atom(struct r600_atom *atom, struct r600_atom **list_elem,
void (*emit)(struct si_context *ctx, struct r600_atom *state),
struct si_state_dsa *dsa = CALLOC_STRUCT(si_state_dsa);
struct si_pm4_state *pm4 = &dsa->pm4;
unsigned db_depth_control;
- unsigned db_render_control;
uint32_t db_stencil_control = 0;
if (dsa == NULL) {
}
/* misc */
- db_render_control = 0;
si_pm4_set_reg(pm4, R_028800_DB_DEPTH_CONTROL, db_depth_control);
- si_pm4_set_reg(pm4, R_028000_DB_RENDER_CONTROL, db_render_control);
si_pm4_set_reg(pm4, R_02842C_DB_STENCIL_CONTROL, db_stencil_control);
return dsa;
si_pm4_delete_state(sctx, dsa, (struct si_state_dsa *)state);
}
-static void *si_create_db_flush_dsa(struct si_context *sctx, bool copy_depth,
- bool copy_stencil, int sample)
+static void *si_create_db_flush_dsa(struct si_context *sctx)
{
- struct pipe_depth_stencil_alpha_state dsa;
- struct si_state_dsa *state;
+ struct pipe_depth_stencil_alpha_state dsa = {};
- memset(&dsa, 0, sizeof(dsa));
+ return sctx->b.b.create_depth_stencil_alpha_state(&sctx->b.b, &dsa);
+}
+
+/* DB RENDER STATE */
+
+static void si_set_occlusion_query_state(struct pipe_context *ctx, bool enable)
+{
+ struct si_context *sctx = (struct si_context*)ctx;
+
+ sctx->db_render_state.dirty = true;
+}
+
+static void si_emit_db_render_state(struct si_context *sctx, struct r600_atom *state)
+{
+ struct radeon_winsys_cs *cs = sctx->b.rings.gfx.cs;
- state = sctx->b.b.create_depth_stencil_alpha_state(&sctx->b.b, &dsa);
- if (copy_depth || copy_stencil) {
- si_pm4_set_reg(&state->pm4, R_028000_DB_RENDER_CONTROL,
- S_028000_DEPTH_COPY(copy_depth) |
- S_028000_STENCIL_COPY(copy_stencil) |
- S_028000_COPY_CENTROID(1) |
- S_028000_COPY_SAMPLE(sample));
+ r600_write_context_reg_seq(cs, R_028000_DB_RENDER_CONTROL, 2);
+
+ /* DB_RENDER_CONTROL */
+ if (sctx->dbcb_depth_copy_enabled ||
+ sctx->dbcb_stencil_copy_enabled) {
+ radeon_emit(cs,
+ S_028000_DEPTH_COPY(sctx->dbcb_depth_copy_enabled) |
+ S_028000_STENCIL_COPY(sctx->dbcb_stencil_copy_enabled) |
+ S_028000_COPY_CENTROID(1) |
+ S_028000_COPY_SAMPLE(sctx->dbcb_copy_sample));
+ } else if (sctx->db_inplace_flush_enabled) {
+ radeon_emit(cs,
+ S_028000_DEPTH_COMPRESS_DISABLE(1) |
+ S_028000_STENCIL_COMPRESS_DISABLE(1));
+ } else if (sctx->db_depth_clear) {
+ radeon_emit(cs, S_028000_DEPTH_CLEAR_ENABLE(1));
} else {
- si_pm4_set_reg(&state->pm4, R_028000_DB_RENDER_CONTROL,
- S_028000_DEPTH_COMPRESS_DISABLE(1) |
- S_028000_STENCIL_COMPRESS_DISABLE(1));
+ radeon_emit(cs, 0);
}
- return state;
+ /* DB_COUNT_CONTROL (occlusion queries) */
+ if (sctx->b.num_occlusion_queries > 0) {
+ if (sctx->b.chip_class >= CIK) {
+ radeon_emit(cs,
+ S_028004_PERFECT_ZPASS_COUNTS(1) |
+ S_028004_SAMPLE_RATE(sctx->framebuffer.log_samples) |
+ S_028004_ZPASS_ENABLE(1) |
+ S_028004_SLICE_EVEN_ENABLE(1) |
+ S_028004_SLICE_ODD_ENABLE(1));
+ } else {
+ radeon_emit(cs,
+ S_028004_PERFECT_ZPASS_COUNTS(1) |
+ S_028004_SAMPLE_RATE(sctx->framebuffer.log_samples));
+ }
+ } else {
+ /* Disable occlusion queries. */
+ if (sctx->b.chip_class >= CIK) {
+ radeon_emit(cs, 0);
+ } else {
+ radeon_emit(cs, S_028004_ZPASS_INCREMENT_DISABLE(1));
+ }
+ }
+
+ /* DB_RENDER_OVERRIDE2 */
+ if (sctx->db_depth_disable_expclear) {
+ r600_write_context_reg(cs, R_028010_DB_RENDER_OVERRIDE2,
+ S_028010_DISABLE_ZMASK_EXPCLEAR_OPTIMIZATION(1));
+ } else {
+ r600_write_context_reg(cs, R_028010_DB_RENDER_OVERRIDE2, 0);
+ }
+
+ r600_write_context_reg(cs, R_02880C_DB_SHADER_CONTROL,
+ S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z) |
+ S_02880C_ALPHA_TO_MASK_DISABLE(sctx->framebuffer.cb0_is_integer) |
+ sctx->ps_db_shader_control);
}
/*
/* HiZ aka depth buffer htile */
/* use htile only for first level */
if (rtex->htile_buffer && !level) {
- z_info |= S_028040_TILE_SURFACE_ENABLE(1);
+ z_info |= S_028040_TILE_SURFACE_ENABLE(1) |
+ S_028040_ALLOW_EXPCLEAR(1);
/* This is optimal for the clear value of 1.0 and using
* the LESS and LEQUAL test functions. Set this to 0
struct pipe_constant_buffer constbuf = {0};
struct r600_surface *surf = NULL;
struct r600_texture *rtex;
+ bool old_cb0_is_integer = sctx->framebuffer.cb0_is_integer;
int i;
if (sctx->framebuffer.state.nr_cbufs) {
sctx->framebuffer.cb0_is_integer = state->nr_cbufs && state->cbufs[0] &&
util_format_is_pure_integer(state->cbufs[0]->format);
+ if (sctx->framebuffer.cb0_is_integer != old_cb0_is_integer)
+ sctx->db_render_state.dirty = true;
+
for (i = 0; i < state->nr_cbufs; i++) {
if (!state->cbufs[i])
continue;
si_update_fb_blend_state(sctx);
sctx->framebuffer.atom.num_dw = state->nr_cbufs*15 + (8 - state->nr_cbufs)*3;
- sctx->framebuffer.atom.num_dw += state->zsbuf ? 23 : 4;
+ sctx->framebuffer.atom.num_dw += state->zsbuf ? 26 : 4;
sctx->framebuffer.atom.num_dw += 3; /* WINDOW_SCISSOR_BR */
sctx->framebuffer.atom.num_dw += 18; /* MSAA sample locations */
sctx->framebuffer.atom.dirty = true;
radeon_emit(cs, zb->db_depth_slice); /* R_02805C_DB_DEPTH_SLICE */
r600_write_context_reg(cs, R_028ABC_DB_HTILE_SURFACE, zb->db_htile_surface);
+ r600_write_context_reg(cs, R_02802C_DB_DEPTH_CLEAR, fui(rtex->depth_clear_value));
r600_write_context_reg(cs, R_028B78_PA_SU_POLY_OFFSET_DB_FMT_CNTL,
zb->pa_su_poly_offset_db_fmt_cntl);
} else {
return;
/* use dummy shader if supplied shader is corrupt */
- if (!sel || !sel->current)
+ if (!sel || !sel->current) {
+ if (!sctx->dummy_pixel_shader) {
+ sctx->dummy_pixel_shader =
+ util_make_fragment_cloneinput_shader(&sctx->b.b, 0,
+ TGSI_SEMANTIC_GENERIC,
+ TGSI_INTERPOLATE_CONSTANT);
+ }
+
sel = sctx->dummy_pixel_shader;
+ }
sctx->ps_shader = sel;
}
return si_create_blend_state_mode(&sctx->b.b, &blend, mode);
}
-static void si_set_occlusion_query_state(struct pipe_context *ctx, bool enable)
-{
- /* XXX Turn this into a proper state. Right now the queries are
- * enabled in draw_vbo, which snoops r600_common_context to see
- * if any occlusion queries are active. */
-}
-
static void si_need_gfx_cs_space(struct pipe_context *ctx, unsigned num_dw,
bool include_draw_vbo)
{
void si_init_state_functions(struct si_context *sctx)
{
- int i;
-
si_init_atom(&sctx->framebuffer.atom, &sctx->atoms.s.framebuffer, si_emit_framebuffer_state, 0);
+ si_init_atom(&sctx->db_render_state, &sctx->atoms.s.db_render_state, si_emit_db_render_state, 10);
sctx->b.b.create_blend_state = si_create_blend_state;
sctx->b.b.bind_blend_state = si_bind_blend_state;
sctx->b.b.bind_depth_stencil_alpha_state = si_bind_dsa_state;
sctx->b.b.delete_depth_stencil_alpha_state = si_delete_dsa_state;
- for (i = 0; i < 8; i++) {
- sctx->custom_dsa_flush_depth_stencil[i] = si_create_db_flush_dsa(sctx, true, true, i);
- sctx->custom_dsa_flush_depth[i] = si_create_db_flush_dsa(sctx, true, false, i);
- sctx->custom_dsa_flush_stencil[i] = si_create_db_flush_dsa(sctx, false, true, i);
- }
- sctx->custom_dsa_flush_inplace = si_create_db_flush_dsa(sctx, false, false, 0);
+ sctx->custom_dsa_flush = si_create_db_flush_dsa(sctx);
sctx->custom_blend_resolve = si_create_blend_custom(sctx, V_028808_CB_RESOLVE);
sctx->custom_blend_decompress = si_create_blend_custom(sctx, V_028808_CB_FMASK_DECOMPRESS);
sctx->custom_blend_fastclear = si_create_blend_custom(sctx, V_028808_CB_ELIMINATE_FAST_CLEAR);
si_pm4_set_reg(pm4, R_028020_DB_DEPTH_BOUNDS_MIN, 0x00000000);
si_pm4_set_reg(pm4, R_028024_DB_DEPTH_BOUNDS_MAX, 0x00000000);
si_pm4_set_reg(pm4, R_028028_DB_STENCIL_CLEAR, 0x00000000);
- si_pm4_set_reg(pm4, R_02802C_DB_DEPTH_CLEAR, 0x3F800000);
si_pm4_set_reg(pm4, R_028AC0_DB_SRESULTS_COMPARE_STATE0, 0x0);
si_pm4_set_reg(pm4, R_028AC4_DB_SRESULTS_COMPARE_STATE1, 0x0);
si_pm4_set_reg(pm4, R_028AC8_DB_PRELOAD_CONTROL, 0x0);