#include "si_pipe.h"
#include "si_shader.h"
#include "sid.h"
-#include "../radeon/r600_cs.h"
+#include "radeon/r600_cs.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_scan.h"
#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;
+
+ 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 {
+ radeon_emit(cs, 0);
+ }
+
+ /* 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));
+ }
+ }
- 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));
+ /* 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 {
- si_pm4_set_reg(&state->pm4, R_028000_DB_RENDER_CONTROL,
- S_028000_DEPTH_COMPRESS_DISABLE(1) |
- S_028000_STENCIL_COMPRESS_DISABLE(1));
+ r600_write_context_reg(cs, R_028010_DB_RENDER_OVERRIDE2, 0);
}
- return state;
+ 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);
}
/*
if ((usage & (PIPE_BIND_RENDER_TARGET |
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SCANOUT |
- PIPE_BIND_SHARED)) &&
+ PIPE_BIND_SHARED |
+ PIPE_BIND_BLENDABLE)) &&
si_is_colorbuffer_format_supported(format)) {
retval |= usage &
(PIPE_BIND_RENDER_TARGET |
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SCANOUT |
PIPE_BIND_SHARED);
+ if (!util_format_is_pure_integer(format) &&
+ !util_format_is_depth_or_stencil(format))
+ retval |= usage & PIPE_BIND_BLENDABLE;
}
if ((usage & PIPE_BIND_DEPTH_STENCIL) &&
struct si_screen *sscreen = sctx->screen;
struct r600_texture *rtex = (struct r600_texture*)surf->base.texture;
unsigned level = surf->base.u.tex.level;
- unsigned pitch, slice, format, tile_mode_index, array_mode;
+ struct radeon_surface_level *levelinfo = &rtex->surface.level[level];
+ unsigned format, tile_mode_index, array_mode;
unsigned macro_aspect, tile_split, stile_split, bankh, bankw, nbanks, pipe_config;
uint32_t z_info, s_info, db_depth_info;
uint64_t z_offs, s_offs;
z_offs += rtex->surface.level[level].offset;
s_offs += rtex->surface.stencil_level[level].offset;
- pitch = (rtex->surface.level[level].nblk_x / 8) - 1;
- slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64;
- if (slice) {
- slice = slice - 1;
- }
-
db_depth_info = S_02803C_ADDR5_SWIZZLE_MASK(1);
z_info = S_028040_FORMAT(format);
/* HiZ aka depth buffer htile */
/* use htile only for first level */
if (rtex->htile_buffer && !level) {
- const struct util_format_description *fmt_desc;
-
- 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
* clearing. */
z_info |= S_028040_ZRANGE_PRECISION(1);
- fmt_desc = util_format_description(rtex->resource.b.b.format);
- if (!util_format_has_stencil(fmt_desc)) {
- /* Use all of the htile_buffer for depth */
- s_info |= S_028044_TILE_STENCIL_DISABLE(1);
- }
+ /* Use all of the htile_buffer for depth, because we don't
+ * use HTILE for stencil because of FAST_STENCIL_DISABLE. */
+ s_info |= S_028044_TILE_STENCIL_DISABLE(1);
uint64_t va = rtex->htile_buffer->gpu_address;
db_htile_data_base = va >> 8;
db_htile_surface = 0;
}
+ assert(levelinfo->nblk_x % 8 == 0 && levelinfo->nblk_y % 8 == 0);
+
surf->db_depth_view = S_028008_SLICE_START(surf->base.u.tex.first_layer) |
S_028008_SLICE_MAX(surf->base.u.tex.last_layer);
surf->db_htile_data_base = db_htile_data_base;
surf->db_stencil_info = s_info;
surf->db_depth_base = z_offs >> 8;
surf->db_stencil_base = s_offs >> 8;
- surf->db_depth_size = S_028058_PITCH_TILE_MAX(pitch);
- surf->db_depth_slice = S_02805C_SLICE_TILE_MAX(slice);
+ surf->db_depth_size = S_028058_PITCH_TILE_MAX((levelinfo->nblk_x / 8) - 1) |
+ S_028058_HEIGHT_TILE_MAX((levelinfo->nblk_y / 8) - 1);
+ surf->db_depth_slice = S_02805C_SLICE_TILE_MAX((levelinfo->nblk_x *
+ levelinfo->nblk_y) / 64 - 1);
surf->db_htile_surface = db_htile_surface;
surf->pa_su_poly_offset_db_fmt_cntl = pa_su_poly_offset_db_fmt_cntl;
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);
+
+ /* There is a hang if stencil is used and fast stencil is enabled
+ * regardless of whether HTILE is depth-only or not.
+ */
si_pm4_set_reg(pm4, R_02800C_DB_RENDER_OVERRIDE,
S_02800C_FORCE_HIS_ENABLE0(V_02800C_FORCE_DISABLE) |
- S_02800C_FORCE_HIS_ENABLE1(V_02800C_FORCE_DISABLE));
+ S_02800C_FORCE_HIS_ENABLE1(V_02800C_FORCE_DISABLE) |
+ S_02800C_FAST_STENCIL_DISABLE(1));
+
si_pm4_set_reg(pm4, R_028400_VGT_MAX_VTX_INDX, ~0);
si_pm4_set_reg(pm4, R_028404_VGT_MIN_VTX_INDX, 0);
si_pm4_set_reg(pm4, R_028408_VGT_INDX_OFFSET, 0);