#include "util/u_upload_mgr.h"
#include "util/u_format_s3tc.h"
#include "tgsi/tgsi_parse.h"
-#include "radeonsi_pipe.h"
-#include "radeonsi_shader.h"
+#include "tgsi/tgsi_scan.h"
+#include "si_pipe.h"
+#include "si_shader.h"
#include "si_state.h"
#include "../radeon/r600_cs.h"
#include "sid.h"
-static uint32_t cik_num_banks(uint32_t nbanks)
+static uint32_t cik_num_banks(struct si_screen *rscreen, unsigned bpe, unsigned tile_split)
{
- switch (nbanks) {
+ if (rscreen->b.info.cik_macrotile_mode_array_valid) {
+ unsigned index, tileb;
+
+ tileb = 8 * 8 * bpe;
+ tileb = MIN2(tile_split, tileb);
+
+ for (index = 0; tileb > 64; index++) {
+ tileb >>= 1;
+ }
+
+ assert(index < 16);
+
+ return (rscreen->b.info.cik_macrotile_mode_array[index] >> 6) & 0x3;
+ }
+
+ /* The old way. */
+ switch (rscreen->b.tiling_info.num_banks) {
case 2:
return V_02803C_ADDR_SURF_2_BANK;
case 4:
}
}
-
static unsigned cik_tile_split(unsigned tile_split)
{
switch (tile_split) {
return bankwh;
}
-static unsigned cik_db_pipe_config(unsigned tile_pipes,
- unsigned num_rbs)
+static unsigned cik_db_pipe_config(struct si_screen *rscreen, unsigned tile_mode)
{
- unsigned pipe_config;
+ if (rscreen->b.info.si_tile_mode_array_valid) {
+ uint32_t gb_tile_mode = rscreen->b.info.si_tile_mode_array[tile_mode];
+
+ return G_009910_PIPE_CONFIG(gb_tile_mode);
+ }
- switch (tile_pipes) {
+ /* This is probably broken for a lot of chips, but it's only used
+ * if the kernel cannot return the tile mode array for CIK. */
+ switch (rscreen->b.info.r600_num_tile_pipes) {
+ case 16:
+ return V_02803C_X_ADDR_SURF_P16_32X32_16X16;
case 8:
- pipe_config = V_02803C_X_ADDR_SURF_P8_32X32_16X16;
- break;
+ return V_02803C_X_ADDR_SURF_P8_32X32_16X16;
case 4:
default:
- if (num_rbs == 4)
- pipe_config = V_02803C_X_ADDR_SURF_P4_16X16;
+ if (rscreen->b.info.r600_num_backends == 4)
+ return V_02803C_X_ADDR_SURF_P4_16X16;
else
- pipe_config = V_02803C_X_ADDR_SURF_P4_8X16;
- break;
+ return V_02803C_X_ADDR_SURF_P4_8X16;
case 2:
- pipe_config = V_02803C_ADDR_SURF_P2;
- break;
+ return V_02803C_ADDR_SURF_P2;
}
- return pipe_config;
}
/*
* inferred framebuffer and blender state
*/
-static void si_update_fb_blend_state(struct r600_context *rctx)
+static void si_update_fb_blend_state(struct si_context *rctx)
{
struct si_pm4_state *pm4;
struct si_state_blend *blend = rctx->queued.named.blend;
struct si_state_blend *blend = CALLOC_STRUCT(si_state_blend);
struct si_pm4_state *pm4 = &blend->pm4;
- uint32_t color_control;
+ uint32_t color_control = 0;
if (blend == NULL)
return NULL;
blend->alpha_to_one = state->alpha_to_one;
- color_control = S_028808_MODE(mode);
if (state->logicop_enable) {
color_control |= S_028808_ROP3(state->logicop_func | (state->logicop_func << 4));
} else {
color_control |= S_028808_ROP3(0xcc);
}
- si_pm4_set_reg(pm4, R_028808_CB_COLOR_CONTROL, color_control);
si_pm4_set_reg(pm4, R_028B70_DB_ALPHA_TO_MASK,
S_028B70_ALPHA_TO_MASK_ENABLE(state->alpha_to_coverage) |
si_pm4_set_reg(pm4, R_028780_CB_BLEND0_CONTROL + i * 4, blend_cntl);
}
+ if (blend->cb_target_mask) {
+ color_control |= S_028808_MODE(mode);
+ } else {
+ color_control |= S_028808_MODE(V_028808_CB_DISABLE);
+ }
+ si_pm4_set_reg(pm4, R_028808_CB_COLOR_CONTROL, color_control);
+
return blend;
}
static void si_bind_blend_state(struct pipe_context *ctx, void *state)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
si_pm4_bind_state(rctx, blend, (struct si_state_blend *)state);
si_update_fb_blend_state(rctx);
}
static void si_delete_blend_state(struct pipe_context *ctx, void *state)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
si_pm4_delete_state(rctx, blend, (struct si_state_blend *)state);
}
static void si_set_blend_color(struct pipe_context *ctx,
const struct pipe_blend_color *state)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
struct si_pm4_state *pm4 = si_pm4_alloc_state(rctx);
if (pm4 == NULL)
static void si_set_clip_state(struct pipe_context *ctx,
const struct pipe_clip_state *state)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
struct si_pm4_state *pm4 = si_pm4_alloc_state(rctx);
struct pipe_constant_buffer cb;
unsigned num_scissors,
const struct pipe_scissor_state *state)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
struct si_pm4_state *pm4 = si_pm4_alloc_state(rctx);
uint32_t tl, br;
unsigned num_viewports,
const struct pipe_viewport_state *state)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
struct si_state_viewport *viewport = CALLOC_STRUCT(si_state_viewport);
struct si_pm4_state *pm4 = &viewport->pm4;
return;
viewport->viewport = *state;
- si_pm4_set_reg(pm4, R_0282D0_PA_SC_VPORT_ZMIN_0, 0x00000000);
- si_pm4_set_reg(pm4, R_0282D4_PA_SC_VPORT_ZMAX_0, 0x3F800000);
si_pm4_set_reg(pm4, R_02843C_PA_CL_VPORT_XSCALE_0, fui(state->scale[0]));
si_pm4_set_reg(pm4, R_028440_PA_CL_VPORT_XOFFSET_0, fui(state->translate[0]));
si_pm4_set_reg(pm4, R_028444_PA_CL_VPORT_YSCALE_0, fui(state->scale[1]));
si_pm4_set_reg(pm4, R_028448_PA_CL_VPORT_YOFFSET_0, fui(state->translate[1]));
si_pm4_set_reg(pm4, R_02844C_PA_CL_VPORT_ZSCALE_0, fui(state->scale[2]));
si_pm4_set_reg(pm4, R_028450_PA_CL_VPORT_ZOFFSET_0, fui(state->translate[2]));
- si_pm4_set_reg(pm4, R_028818_PA_CL_VTE_CNTL, 0x0000043F);
si_pm4_set_state(rctx, viewport, viewport);
}
/*
* inferred state between framebuffer and rasterizer
*/
-static void si_update_fb_rs_state(struct r600_context *rctx)
+static void si_update_fb_rs_state(struct si_context *rctx)
{
struct si_state_rasterizer *rs = rctx->queued.named.rasterizer;
struct si_pm4_state *pm4;
}
si_pm4_set_reg(pm4, R_0286D4_SPI_INTERP_CONTROL_0, tmp);
- si_pm4_set_reg(pm4, R_028820_PA_CL_NANINF_CNTL, 0x00000000);
/* point size 12.4 fixed point */
tmp = (unsigned)(state->point_size * 8.0);
si_pm4_set_reg(pm4, R_028A00_PA_SU_POINT_SIZE, S_028A00_HEIGHT(tmp) | S_028A00_WIDTH(tmp));
si_pm4_set_reg(pm4, R_028BE4_PA_SU_VTX_CNTL,
S_028BE4_PIX_CENTER(state->half_pixel_center) |
S_028BE4_QUANT_MODE(V_028BE4_X_16_8_FIXED_POINT_1_256TH));
- si_pm4_set_reg(pm4, R_028BE8_PA_CL_GB_VERT_CLIP_ADJ, 0x3F800000);
- si_pm4_set_reg(pm4, R_028BEC_PA_CL_GB_VERT_DISC_ADJ, 0x3F800000);
- si_pm4_set_reg(pm4, R_028BF0_PA_CL_GB_HORZ_CLIP_ADJ, 0x3F800000);
- si_pm4_set_reg(pm4, R_028BF4_PA_CL_GB_HORZ_DISC_ADJ, 0x3F800000);
si_pm4_set_reg(pm4, R_028B7C_PA_SU_POLY_OFFSET_CLAMP, fui(state->offset_clamp));
si_pm4_set_reg(pm4, R_02820C_PA_SC_CLIPRECT_RULE, clip_rule);
static void si_bind_rs_state(struct pipe_context *ctx, void *state)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
struct si_state_rasterizer *rs = (struct si_state_rasterizer *)state;
if (state == NULL)
static void si_delete_rs_state(struct pipe_context *ctx, void *state)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
si_pm4_delete_state(rctx, rasterizer, (struct si_state_rasterizer *)state);
}
/*
* infeered state between dsa and stencil ref
*/
-static void si_update_dsa_stencil_ref(struct r600_context *rctx)
+static void si_update_dsa_stencil_ref(struct si_context *rctx)
{
struct si_pm4_state *pm4 = si_pm4_alloc_state(rctx);
struct pipe_stencil_ref *ref = &rctx->stencil_ref;
static void si_set_pipe_stencil_ref(struct pipe_context *ctx,
const struct pipe_stencil_ref *state)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
rctx->stencil_ref = *state;
si_update_dsa_stencil_ref(rctx);
}
struct si_state_dsa *dsa = CALLOC_STRUCT(si_state_dsa);
struct si_pm4_state *pm4 = &dsa->pm4;
unsigned db_depth_control;
- unsigned db_render_override, db_render_control;
+ unsigned db_render_control;
uint32_t db_stencil_control = 0;
if (dsa == NULL) {
/* misc */
db_render_control = 0;
- db_render_override = S_02800C_FORCE_HIZ_ENABLE(V_02800C_FORCE_DISABLE) |
- S_02800C_FORCE_HIS_ENABLE0(V_02800C_FORCE_DISABLE) |
- S_02800C_FORCE_HIS_ENABLE1(V_02800C_FORCE_DISABLE);
- /* TODO db_render_override depends on query */
- 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_028410_SX_ALPHA_TEST_CONTROL, alpha_test_control);
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_02800C_DB_RENDER_OVERRIDE, db_render_override);
si_pm4_set_reg(pm4, R_02842C_DB_STENCIL_CONTROL, db_stencil_control);
- 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);
- dsa->db_render_override = db_render_override;
return dsa;
}
static void si_bind_dsa_state(struct pipe_context *ctx, void *state)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
struct si_state_dsa *dsa = state;
if (state == NULL)
static void si_delete_dsa_state(struct pipe_context *ctx, void *state)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
si_pm4_delete_state(rctx, dsa, (struct si_state_dsa *)state);
}
-static void *si_create_db_flush_dsa(struct r600_context *rctx, bool copy_depth,
+static void *si_create_db_flush_dsa(struct si_context *rctx, bool copy_depth,
bool copy_stencil, int sample)
{
struct pipe_depth_stencil_alpha_state dsa;
si_pm4_set_reg(&state->pm4, R_028000_DB_RENDER_CONTROL,
S_028000_DEPTH_COMPRESS_DISABLE(1) |
S_028000_STENCIL_COMPRESS_DISABLE(1));
- si_pm4_set_reg(&state->pm4, R_02800C_DB_RENDER_OVERRIDE,
- S_02800C_FORCE_HIZ_ENABLE(V_02800C_FORCE_DISABLE) |
- S_02800C_FORCE_HIS_ENABLE0(V_02800C_FORCE_DISABLE) |
- S_02800C_FORCE_HIS_ENABLE1(V_02800C_FORCE_DISABLE) |
- S_02800C_DISABLE_TILE_RATE_TILES(1));
}
return state;
const struct util_format_description *desc,
int first_non_void)
{
- struct r600_screen *rscreen = (struct r600_screen*)screen;
+ struct si_screen *rscreen = (struct si_screen*)screen;
bool enable_s3tc = rscreen->b.info.drm_minor >= 31;
boolean uniform = TRUE;
int i;
if (type == UTIL_FORMAT_TYPE_FIXED)
return V_008F0C_BUF_DATA_FORMAT_INVALID;
+ if (desc->nr_channels == 4 &&
+ desc->channel[0].size == 10 &&
+ desc->channel[1].size == 10 &&
+ desc->channel[2].size == 10 &&
+ desc->channel[3].size == 2)
+ return V_008F0C_BUF_DATA_FORMAT_2_10_10_10;
+
/* See whether the components are of the same size. */
for (i = 0; i < desc->nr_channels; i++) {
if (desc->channel[first_non_void].size != desc->channel[i].size)
unsigned sample_count,
unsigned usage)
{
- struct r600_screen *rscreen = (struct r600_screen *)screen;
+ struct si_screen *rscreen = (struct si_screen *)screen;
unsigned retval = 0;
if (target >= PIPE_MAX_TEXTURE_TYPES) {
return FALSE;
if (sample_count > 1) {
- if (HAVE_LLVM < 0x0304 || rscreen->b.chip_class != SI)
+ if (HAVE_LLVM < 0x0304)
+ return FALSE;
+
+ /* 2D tiling on CIK is supported since DRM 2.35.0 */
+ if (rscreen->b.chip_class >= CIK && rscreen->b.info.drm_minor < 35)
return FALSE;
switch (sample_count) {
* framebuffer handling
*/
-static void si_cb(struct r600_context *rctx, struct si_pm4_state *pm4,
+static void si_cb(struct si_context *rctx, struct si_pm4_state *pm4,
const struct pipe_framebuffer_state *state, int cb)
{
struct r600_texture *rtex;
- struct r600_surface *surf;
+ struct si_surface *surf;
unsigned level = state->cbufs[cb]->u.tex.level;
unsigned pitch, slice;
- unsigned color_info, color_attrib;
+ unsigned color_info, color_attrib, color_pitch, color_view;
unsigned tile_mode_index;
unsigned format, swap, ntype, endian;
uint64_t offset;
unsigned blend_clamp = 0, blend_bypass = 0;
unsigned max_comp_size;
- surf = (struct r600_surface *)state->cbufs[cb];
+ surf = (struct si_surface *)state->cbufs[cb];
rtex = (struct r600_texture*)state->cbufs[cb]->texture;
offset = rtex->surface.level[level].offset;
- if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
+
+ /* Layered rendering doesn't work with LINEAR_GENERAL.
+ * (LINEAR_ALIGNED and others work) */
+ if (rtex->surface.level[level].mode == RADEON_SURF_MODE_LINEAR) {
+ assert(state->cbufs[cb]->u.tex.first_layer == state->cbufs[cb]->u.tex.last_layer);
offset += rtex->surface.level[level].slice_size *
state->cbufs[cb]->u.tex.first_layer;
+ color_view = 0;
+ } else {
+ color_view = S_028C6C_SLICE_START(state->cbufs[cb]->u.tex.first_layer) |
+ S_028C6C_SLICE_MAX(state->cbufs[cb]->u.tex.last_layer);
}
+
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) {
S_028C70_NUMBER_TYPE(ntype) |
S_028C70_ENDIAN(endian);
+ color_pitch = S_028C64_TILE_MAX(pitch);
+
color_attrib = S_028C74_TILE_MODE_INDEX(tile_mode_index) |
S_028C74_FORCE_DST_ALPHA_1(desc->swizzle[3] == UTIL_FORMAT_SWIZZLE_1);
color_info |= S_028C70_COMPRESSION(1);
unsigned fmask_bankh = util_logbase2(rtex->fmask.bank_height);
- /* due to a bug in the hw, FMASK_BANK_HEIGHT must be set on SI too */
- color_attrib |= S_028C74_FMASK_TILE_MODE_INDEX(rtex->fmask.tile_mode_index) |
- S_028C74_FMASK_BANK_HEIGHT(fmask_bankh);
+ color_attrib |= S_028C74_FMASK_TILE_MODE_INDEX(rtex->fmask.tile_mode_index);
+
+ if (rctx->b.chip_class == SI) {
+ /* due to a hw bug, FMASK_BANK_HEIGHT must be set on SI too */
+ color_attrib |= S_028C74_FMASK_BANK_HEIGHT(fmask_bankh);
+ }
+ if (rctx->b.chip_class >= CIK) {
+ color_pitch |= S_028C64_FMASK_TILE_MAX(rtex->fmask.pitch / 8 - 1);
+ }
}
}
offset += r600_resource_va(rctx->b.b.screen, state->cbufs[cb]->texture);
offset >>= 8;
- /* FIXME handle enabling of CB beyond BASE8 which has different offset */
si_pm4_add_bo(pm4, &rtex->resource, RADEON_USAGE_READWRITE);
si_pm4_set_reg(pm4, R_028C60_CB_COLOR0_BASE + cb * 0x3C, offset);
- si_pm4_set_reg(pm4, R_028C64_CB_COLOR0_PITCH + cb * 0x3C, S_028C64_TILE_MAX(pitch));
+ si_pm4_set_reg(pm4, R_028C64_CB_COLOR0_PITCH + cb * 0x3C, color_pitch);
si_pm4_set_reg(pm4, R_028C68_CB_COLOR0_SLICE + cb * 0x3C, S_028C68_TILE_MAX(slice));
-
- if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
- si_pm4_set_reg(pm4, R_028C6C_CB_COLOR0_VIEW + cb * 0x3C, 0x00000000);
- } else {
- si_pm4_set_reg(pm4, R_028C6C_CB_COLOR0_VIEW + cb * 0x3C,
- S_028C6C_SLICE_START(state->cbufs[cb]->u.tex.first_layer) |
- S_028C6C_SLICE_MAX(state->cbufs[cb]->u.tex.last_layer));
- }
+ si_pm4_set_reg(pm4, R_028C6C_CB_COLOR0_VIEW + cb * 0x3C, color_view);
si_pm4_set_reg(pm4, R_028C70_CB_COLOR0_INFO + cb * 0x3C, color_info);
si_pm4_set_reg(pm4, R_028C74_CB_COLOR0_ATTRIB + cb * 0x3C, color_attrib);
}
}
-static void si_db(struct r600_context *rctx, struct si_pm4_state *pm4,
+static void si_db(struct si_context *rctx, struct si_pm4_state *pm4,
const struct pipe_framebuffer_state *state)
{
- struct r600_screen *rscreen = rctx->screen;
+ struct si_screen *rscreen = rctx->screen;
struct r600_texture *rtex;
- struct r600_surface *surf;
+ struct si_surface *surf;
unsigned level, pitch, slice, 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;
+ uint32_t db_htile_data_base, db_htile_surface;
if (state->zsbuf == NULL) {
si_pm4_set_reg(pm4, R_028040_DB_Z_INFO, S_028040_FORMAT(V_028040_Z_INVALID));
return;
}
- surf = (struct r600_surface *)state->zsbuf;
+ surf = (struct si_surface *)state->zsbuf;
level = surf->base.u.tex.level;
rtex = (struct r600_texture*)surf->base.texture;
macro_aspect = cik_macro_tile_aspect(macro_aspect);
bankw = cik_bank_wh(bankw);
bankh = cik_bank_wh(bankh);
- nbanks = cik_num_banks(rscreen->b.tiling_info.num_banks);
- pipe_config = cik_db_pipe_config(rscreen->b.info.r600_num_tile_pipes,
- rscreen->b.info.r600_num_backends);
+ nbanks = cik_num_banks(rscreen, rtex->surface.bpe, rtex->surface.tile_split);
+ tile_mode_index = si_tile_mode_index(rtex, level, false);
+ pipe_config = cik_db_pipe_config(rscreen, tile_mode_index);
db_depth_info |= S_02803C_ARRAY_MODE(array_mode) |
S_02803C_PIPE_CONFIG(pipe_config) |
s_info |= S_028044_TILE_MODE_INDEX(tile_mode_index);
}
+ /* 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);
+
+ /* This is optimal for the clear value of 1.0 and using
+ * the LESS and LEQUAL test functions. Set this to 0
+ * for the opposite case. This can only be changed when
+ * 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);
+ }
+
+ uint64_t va = r600_resource_va(&rctx->screen->b.b, &rtex->htile_buffer->b.b);
+ db_htile_data_base = va >> 8;
+ db_htile_surface = S_028ABC_FULL_CACHE(1);
+
+ si_pm4_add_bo(pm4, rtex->htile_buffer, RADEON_USAGE_READWRITE);
+ } else {
+ db_htile_data_base = 0;
+ db_htile_surface = 0;
+ }
+
si_pm4_set_reg(pm4, R_028008_DB_DEPTH_VIEW,
S_028008_SLICE_START(state->zsbuf->u.tex.first_layer) |
S_028008_SLICE_MAX(state->zsbuf->u.tex.last_layer));
+ si_pm4_set_reg(pm4, R_028014_DB_HTILE_DATA_BASE, db_htile_data_base);
si_pm4_set_reg(pm4, R_02803C_DB_DEPTH_INFO, db_depth_info);
si_pm4_set_reg(pm4, R_028040_DB_Z_INFO, z_info);
si_pm4_set_reg(pm4, R_028058_DB_DEPTH_SIZE, S_028058_PITCH_TILE_MAX(pitch));
si_pm4_set_reg(pm4, R_02805C_DB_DEPTH_SLICE, S_02805C_SLICE_TILE_MAX(slice));
+
+ si_pm4_set_reg(pm4, R_028ABC_DB_HTILE_SURFACE, db_htile_surface);
}
#define FILL_SREG(s0x, s0y, s1x, s1y, s2x, s2y, s3x, s3y) \
}
}
-static void si_set_msaa_state(struct r600_context *rctx, struct si_pm4_state *pm4, int nr_samples)
+static void si_set_msaa_state(struct si_context *rctx, struct si_pm4_state *pm4, int nr_samples)
{
unsigned max_dist = 0;
static void si_set_framebuffer_state(struct pipe_context *ctx,
const struct pipe_framebuffer_state *state)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
struct si_pm4_state *pm4 = si_pm4_alloc_state(rctx);
uint32_t tl, br;
int tl_x, tl_y, br_x, br_y, nr_samples, i;
R600_CONTEXT_FLUSH_AND_INV_CB_META;
}
if (rctx->framebuffer.zsbuf) {
- rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV_DB;
+ rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV_DB |
+ R600_CONTEXT_FLUSH_AND_INV_DB_META;
}
util_copy_framebuffer_state(&rctx->framebuffer, state);
rctx->export_16bpc = 0;
rctx->fb_compressed_cb_mask = 0;
for (i = 0; i < state->nr_cbufs; i++) {
- struct r600_texture *rtex =
- (struct r600_texture*)state->cbufs[i]->texture;
+ struct r600_texture *rtex;
+
+ if (!state->cbufs[i]) {
+ si_pm4_set_reg(pm4, R_028C70_CB_COLOR0_INFO + i * 0x3C,
+ S_028C70_FORMAT(V_028C70_COLOR_INVALID));
+ continue;
+ }
+
+ rtex = (struct r600_texture*)state->cbufs[i]->texture;
si_cb(rctx, pm4, state, i);
si_pm4_set_reg(pm4, R_028034_PA_SC_SCREEN_SCISSOR_BR, br);
si_pm4_set_reg(pm4, R_028204_PA_SC_WINDOW_SCISSOR_TL, tl);
si_pm4_set_reg(pm4, R_028208_PA_SC_WINDOW_SCISSOR_BR, br);
- si_pm4_set_reg(pm4, R_028200_PA_SC_WINDOW_OFFSET, 0x00000000);
- si_pm4_set_reg(pm4, R_028230_PA_SC_EDGERULE, 0xAAAAAAAA);
- if (state->nr_cbufs)
- nr_samples = state->cbufs[0]->texture->nr_samples;
- else if (state->zsbuf)
- nr_samples = state->zsbuf->texture->nr_samples;
- else
- nr_samples = 0;
+ nr_samples = util_framebuffer_get_num_samples(state);
si_set_msaa_state(rctx, pm4, nr_samples);
rctx->fb_log_samples = util_logbase2(nr_samples);
- rctx->fb_cb0_is_integer = state->nr_cbufs &&
+ rctx->fb_cb0_is_integer = state->nr_cbufs && state->cbufs[0] &&
util_format_is_pure_integer(state->cbufs[0]->format);
si_pm4_set_state(rctx, framebuffer, pm4);
struct si_pipe_shader_selector *sel,
union si_shader_key *key)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
memset(key, 0, sizeof(*key));
if (sel->type == PIPE_SHADER_VERTEX) {
FREE(shader);
return r;
}
-
- /* We don't know the value of fs_write_all property until we built
- * at least one variant, so we may need to recompute the key (include
- * rctx->framebuffer.nr_cbufs) after building first variant. */
- if (sel->type == PIPE_SHADER_FRAGMENT &&
- sel->num_shaders == 0 &&
- shader->shader.fs_write_all) {
- sel->fs_write_all = 1;
- si_shader_selector_key(ctx, sel, &shader->key);
- }
-
sel->num_shaders++;
}
sel->tokens = tgsi_dup_tokens(state->tokens);
sel->so = state->stream_output;
+ if (pipe_shader_type == PIPE_SHADER_FRAGMENT) {
+ struct tgsi_shader_info info;
+
+ tgsi_scan_shader(state->tokens, &info);
+ sel->fs_write_all = info.color0_writes_all_cbufs;
+ }
+
r = si_shader_select(ctx, sel, NULL);
if (r) {
free(sel);
static void si_bind_vs_shader(struct pipe_context *ctx, void *state)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
struct si_pipe_shader_selector *sel = state;
if (rctx->vs_shader == sel)
return;
- rctx->vs_shader = sel;
-
- if (sel && sel->current) {
- si_pm4_bind_state(rctx, vs, sel->current->pm4);
- rctx->b.streamout.stride_in_dw = sel->so.stride;
- } else {
- si_pm4_bind_state(rctx, vs, rctx->dummy_pixel_shader->pm4);
- }
+ if (!sel || !sel->current)
+ return;
+ rctx->vs_shader = sel;
+ si_pm4_bind_state(rctx, vs, sel->current->pm4);
+ rctx->b.streamout.stride_in_dw = sel->so.stride;
rctx->b.flags |= R600_CONTEXT_INV_SHADER_CACHE;
}
static void si_bind_ps_shader(struct pipe_context *ctx, void *state)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
struct si_pipe_shader_selector *sel = state;
if (rctx->ps_shader == sel)
return;
- rctx->ps_shader = sel;
-
- if (sel && sel->current)
- si_pm4_bind_state(rctx, ps, sel->current->pm4);
- else
- si_pm4_bind_state(rctx, ps, rctx->dummy_pixel_shader->pm4);
+ if (!sel || !sel->current)
+ sel = rctx->dummy_pixel_shader;
+ rctx->ps_shader = sel;
+ si_pm4_bind_state(rctx, ps, sel->current->pm4);
rctx->b.flags |= R600_CONTEXT_INV_SHADER_CACHE;
}
static void si_delete_shader_selector(struct pipe_context *ctx,
struct si_pipe_shader_selector *sel)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
struct si_pipe_shader *p = sel->current, *c;
while (p) {
static void si_delete_vs_shader(struct pipe_context *ctx, void *state)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
struct si_pipe_shader_selector *sel = (struct si_pipe_shader_selector *)state;
if (rctx->vs_shader == sel) {
static void si_delete_ps_shader(struct pipe_context *ctx, void *state)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
struct si_pipe_shader_selector *sel = (struct si_pipe_shader_selector *)state;
if (rctx->ps_shader == sel) {
unsigned count,
struct pipe_sampler_view **views)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
- struct r600_textures_info *samplers = &rctx->samplers[shader];
+ struct si_context *rctx = (struct si_context *)ctx;
+ struct si_textures_info *samplers = &rctx->samplers[shader];
struct si_pipe_sampler_view **rviews = (struct si_pipe_sampler_view **)views;
int i;
rctx->b.flags |= R600_CONTEXT_INV_TEX_CACHE;
}
-static struct si_pm4_state *si_set_sampler_states(struct r600_context *rctx, unsigned count,
+static struct si_pm4_state *si_set_sampler_states(struct si_context *rctx, unsigned count,
void **states,
- struct r600_textures_info *samplers,
+ struct si_textures_info *samplers,
unsigned user_data_reg)
{
struct si_pipe_sampler_state **rstates = (struct si_pipe_sampler_state **)states;
static void si_bind_vs_sampler_states(struct pipe_context *ctx, unsigned count, void **states)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
struct si_pm4_state *pm4;
pm4 = si_set_sampler_states(rctx, count, states, &rctx->samplers[PIPE_SHADER_VERTEX],
static void si_bind_ps_sampler_states(struct pipe_context *ctx, unsigned count, void **states)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
struct si_pm4_state *pm4;
pm4 = si_set_sampler_states(rctx, count, states, &rctx->samplers[PIPE_SHADER_FRAGMENT],
static void si_set_sample_mask(struct pipe_context *ctx, unsigned sample_mask)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
struct si_pm4_state *pm4 = si_pm4_alloc_state(rctx);
uint16_t mask = sample_mask;
static void si_bind_vertex_elements(struct pipe_context *ctx, void *state)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
struct si_vertex_element *v = (struct si_vertex_element*)state;
rctx->vertex_elements = v;
static void si_delete_vertex_element(struct pipe_context *ctx, void *state)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
if (rctx->vertex_elements == state)
rctx->vertex_elements = NULL;
static void si_set_vertex_buffers(struct pipe_context *ctx, unsigned start_slot, unsigned count,
const struct pipe_vertex_buffer *buffers)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
util_set_vertex_buffers_count(rctx->vertex_buffer, &rctx->nr_vertex_buffers, buffers, start_slot, count);
}
static void si_set_index_buffer(struct pipe_context *ctx,
const struct pipe_index_buffer *ib)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
if (ib) {
pipe_resource_reference(&rctx->index_buffer.buffer, ib->buffer);
static void si_texture_barrier(struct pipe_context *ctx)
{
- struct r600_context *rctx = (struct r600_context *)ctx;
+ struct si_context *rctx = (struct si_context *)ctx;
rctx->b.flags |= R600_CONTEXT_INV_TEX_CACHE |
R600_CONTEXT_FLUSH_AND_INV_CB;
}
-static void *si_create_blend_custom(struct r600_context *rctx, unsigned mode)
+static void *si_create_blend_custom(struct si_context *rctx, unsigned mode)
{
struct pipe_blend_state blend;
const struct pipe_surface *surf_tmpl)
{
struct r600_texture *rtex = (struct r600_texture*)texture;
- struct r600_surface *surface = CALLOC_STRUCT(r600_surface);
+ struct si_surface *surface = CALLOC_STRUCT(si_surface);
unsigned level = surf_tmpl->u.tex.level;
if (surface == NULL)
assert(surf_tmpl->u.tex.first_layer <= util_max_layer(texture, surf_tmpl->u.tex.level));
assert(surf_tmpl->u.tex.last_layer <= util_max_layer(texture, surf_tmpl->u.tex.level));
- assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
pipe_reference_init(&surface->base.reference, 1);
pipe_resource_reference(&surface->base.texture, texture);
return FALSE;
}
-void si_init_state_functions(struct r600_context *rctx)
+void si_init_state_functions(struct si_context *rctx)
{
int i;
rctx->b.b.draw_vbo = si_draw_vbo;
}
-void si_init_config(struct r600_context *rctx)
+void si_init_config(struct si_context *rctx)
{
struct si_pm4_state *pm4 = si_pm4_alloc_state(rctx);
si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG, 0x16000012);
si_pm4_set_reg(pm4, R_028354_PA_SC_RASTER_CONFIG_1, 0x00000000);
break;
+ case CHIP_HAWAII:
+ si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG, 0x3a00161a);
+ si_pm4_set_reg(pm4, R_028354_PA_SC_RASTER_CONFIG_1, 0x0000002e);
+ break;
case CHIP_KAVERI:
/* XXX todo */
case CHIP_KABINI:
}
}
+ si_pm4_set_reg(pm4, R_028200_PA_SC_WINDOW_OFFSET, 0x00000000);
+ si_pm4_set_reg(pm4, R_028230_PA_SC_EDGERULE, 0xAAAAAAAA);
+ si_pm4_set_reg(pm4, R_0282D0_PA_SC_VPORT_ZMIN_0, 0x00000000);
+ si_pm4_set_reg(pm4, R_0282D4_PA_SC_VPORT_ZMAX_0, 0x3F800000);
+ si_pm4_set_reg(pm4, R_028818_PA_CL_VTE_CNTL, 0x0000043F);
+ si_pm4_set_reg(pm4, R_028820_PA_CL_NANINF_CNTL, 0x00000000);
+ si_pm4_set_reg(pm4, R_028BE8_PA_CL_GB_VERT_CLIP_ADJ, 0x3F800000);
+ si_pm4_set_reg(pm4, R_028BEC_PA_CL_GB_VERT_DISC_ADJ, 0x3F800000);
+ si_pm4_set_reg(pm4, R_028BF0_PA_CL_GB_HORZ_CLIP_ADJ, 0x3F800000);
+ si_pm4_set_reg(pm4, R_028BF4_PA_CL_GB_HORZ_DISC_ADJ, 0x3F800000);
+ 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);
+ 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));
+ si_pm4_set_reg(pm4, R_028400_VGT_MAX_VTX_INDX, ~0);
+ si_pm4_set_reg(pm4, R_028404_VGT_MIN_VTX_INDX, 0);
+
+ if (rctx->b.chip_class >= CIK) {
+ si_pm4_set_reg(pm4, R_00B118_SPI_SHADER_PGM_RSRC3_VS, S_00B118_CU_EN(0xffff));
+ si_pm4_set_reg(pm4, R_00B11C_SPI_SHADER_LATE_ALLOC_VS, S_00B11C_LIMIT(0));
+ si_pm4_set_reg(pm4, R_00B01C_SPI_SHADER_PGM_RSRC3_PS, S_00B01C_CU_EN(0xffff));
+ }
+
si_pm4_set_state(rctx, init, pm4);
}