#include "si_query.h"
#include "util/u_dual_blend.h"
-#include "util/u_format.h"
-#include "util/u_format_s3tc.h"
+#include "util/format/u_format.h"
+#include "util/format/u_format_s3tc.h"
#include "util/u_memory.h"
#include "util/u_resource.h"
#include "util/u_upload_mgr.h"
S_028424_OVERWRITE_COMBINER_MRT_SHARING_DISABLE(sctx->chip_class <= GFX9) |
S_028424_OVERWRITE_COMBINER_WATERMARK(watermark) |
S_028424_OVERWRITE_COMBINER_DISABLE(oc_disable) |
- S_028424_DISABLE_CONSTANT_ENCODE_REG(sctx->screen->has_dcc_constant_encode));
+ S_028424_DISABLE_CONSTANT_ENCODE_REG(sctx->screen->info.has_dcc_constant_encode));
}
/* RB+ register settings. */
- if (sctx->screen->rbplus_allowed) {
+ if (sctx->screen->info.rbplus_allowed) {
unsigned spi_shader_col_format =
sctx->ps_shader.cso ?
sctx->ps_shader.current->key.part.ps.epilog.spi_shader_col_format : 0;
color_control |= S_028808_MODE(V_028808_CB_DISABLE);
}
- if (sctx->screen->rbplus_allowed) {
+ if (sctx->screen->info.rbplus_allowed) {
/* Disable RB+ blend optimizations for dual source blending.
* Vulkan does this.
*/
static void si_delete_blend_state(struct pipe_context *ctx, void *state)
{
struct si_context *sctx = (struct si_context *)ctx;
+
+ if (sctx->queued.named.blend == state)
+ si_bind_blend_state(ctx, sctx->noop_blend);
+
si_pm4_delete_state(sctx, blend, (struct si_state_blend *)state);
}
culldist_mask |= clipdist_mask;
unsigned initial_cdw = sctx->gfx_cs->current.cdw;
- radeon_opt_set_context_reg(sctx, R_02881C_PA_CL_VS_OUT_CNTL,
- SI_TRACKED_PA_CL_VS_OUT_CNTL,
- vs_sel->pa_cl_vs_out_cntl |
- S_02881C_VS_OUT_CCDIST0_VEC_ENA((total_mask & 0x0F) != 0) |
- S_02881C_VS_OUT_CCDIST1_VEC_ENA((total_mask & 0xF0) != 0) |
- clipdist_mask | (culldist_mask << 8));
+ unsigned pa_cl_cntl = S_02881C_VS_OUT_CCDIST0_VEC_ENA((total_mask & 0x0F) != 0) |
+ S_02881C_VS_OUT_CCDIST1_VEC_ENA((total_mask & 0xF0) != 0) |
+ clipdist_mask | (culldist_mask << 8);
+
+ if (sctx->chip_class >= GFX10) {
+ radeon_opt_set_context_reg_rmw(sctx, R_02881C_PA_CL_VS_OUT_CNTL,
+ SI_TRACKED_PA_CL_VS_OUT_CNTL__CL,
+ pa_cl_cntl,
+ ~SI_TRACKED_PA_CL_VS_OUT_CNTL__VS_MASK);
+ } else {
+ radeon_opt_set_context_reg(sctx, R_02881C_PA_CL_VS_OUT_CNTL,
+ SI_TRACKED_PA_CL_VS_OUT_CNTL__CL,
+ vs_sel->pa_cl_vs_out_cntl | pa_cl_cntl);
+ }
radeon_opt_set_context_reg(sctx, R_028810_PA_CL_CLIP_CNTL,
SI_TRACKED_PA_CL_CLIP_CNTL,
rs->pa_cl_clip_cntl |
rs->flatshade_first = state->flatshade_first;
rs->sprite_coord_enable = state->sprite_coord_enable;
rs->rasterizer_discard = state->rasterizer_discard;
+ rs->polygon_mode_enabled = state->fill_front != PIPE_POLYGON_MODE_FILL ||
+ state->fill_back != PIPE_POLYGON_MODE_FILL;
rs->pa_sc_line_stipple = state->line_stipple_enable ?
S_028A0C_LINE_PATTERN(state->line_stipple_pattern) |
S_028A0C_REPEAT_COUNT(state->line_stipple_factor) : 0;
S_028814_POLY_OFFSET_FRONT_ENABLE(util_get_offset(state, state->fill_front)) |
S_028814_POLY_OFFSET_BACK_ENABLE(util_get_offset(state, state->fill_back)) |
S_028814_POLY_OFFSET_PARA_ENABLE(state->offset_point || state->offset_line) |
- S_028814_POLY_MODE(state->fill_front != PIPE_POLYGON_MODE_FILL ||
- state->fill_back != PIPE_POLYGON_MODE_FILL) |
+ S_028814_POLY_MODE(rs->polygon_mode_enabled) |
S_028814_POLYMODE_FRONT_PTYPE(si_translate_fill(state->fill_front)) |
S_028814_POLYMODE_BACK_PTYPE(si_translate_fill(state->fill_back)));
si_mark_atom_dirty(sctx, &sctx->atoms.s.db_render_state);
/* Update the small primitive filter workaround if necessary. */
- if (sctx->screen->has_msaa_sample_loc_bug &&
+ if (sctx->screen->info.has_msaa_sample_loc_bug &&
sctx->framebuffer.nr_samples > 1)
si_mark_atom_dirty(sctx, &sctx->atoms.s.msaa_sample_locs);
}
struct si_state_rasterizer *rs = (struct si_state_rasterizer *)state;
if (sctx->queued.named.rasterizer == state)
- si_pm4_bind_state(sctx, poly_offset, NULL);
+ si_bind_rs_state(ctx, sctx->discard_rasterizer_state);
FREE(rs->pm4_poly_offset);
si_pm4_delete_state(sctx, rasterizer, rs);
static void si_delete_dsa_state(struct pipe_context *ctx, void *state)
{
struct si_context *sctx = (struct si_context *)ctx;
+
+ if (sctx->queued.named.dsa == state)
+ si_bind_dsa_state(ctx, sctx->noop_dsa);
+
si_pm4_delete_state(sctx, dsa, (struct si_state_dsa *)state);
}
if (!rs->multisample_enable)
db_shader_control &= C_02880C_MASK_EXPORT_ENABLE;
- if (sctx->screen->has_rbplus &&
- !sctx->screen->rbplus_allowed)
+ if (sctx->screen->info.has_rbplus &&
+ !sctx->screen->info.rbplus_allowed)
db_shader_control |= S_02880C_DUAL_QUAD_DISABLE(1);
radeon_opt_set_context_reg(sctx, R_02880C_DB_SHADER_CONTROL,
return false;
}
+ if (util_format_get_num_planes(format) >= 2) {
+ return util_format_planar_is_supported(screen, format, target,
+ sample_count,
+ storage_sample_count,
+ usage);
+ }
+
if (MAX2(1, sample_count) < MAX2(1, storage_sample_count))
return false;
if (!screen->get_param(screen, PIPE_CAP_TEXTURE_MULTISAMPLE))
return false;
- if (usage & PIPE_BIND_SHADER_IMAGE)
- return false;
-
/* Only power-of-two sample counts are supported. */
if (!util_is_power_of_two_or_zero(sample_count) ||
!util_is_power_of_two_or_zero(storage_sample_count))
color_attrib |= S_028C74_NUM_SAMPLES(log_samples) |
S_028C74_NUM_FRAGMENTS(log_fragments);
- if (tex->fmask_offset) {
+ if (tex->surface.fmask_offset) {
color_info |= S_028C70_COMPRESSION(1);
unsigned fmask_bankh = util_logbase2(tex->surface.u.legacy.fmask.bankh);
}
surf->db_htile_data_base = (tex->buffer.gpu_address +
- tex->htile_offset) >> 8;
+ tex->surface.htile_offset) >> 8;
surf->db_htile_surface = S_028ABC_FULL_CACHE(1) |
S_028ABC_PIPE_ALIGNED(tex->surface.u.gfx9.htile.pipe_aligned);
if (sctx->chip_class == GFX9) {
}
surf->db_htile_data_base = (tex->buffer.gpu_address +
- tex->htile_offset) >> 8;
+ tex->surface.htile_offset) >> 8;
surf->db_htile_surface = S_028ABC_FULL_CACHE(1);
if (tex->tc_compatible_htile) {
struct pipe_surface *surf = sctx->framebuffer.state.cbufs[i];
struct si_texture *tex = (struct si_texture*)surf->texture;
- if (tex->fmask_offset)
+ if (tex->surface.fmask_offset) {
tex->dirty_level_mask |= 1 << surf->u.tex.level;
+ tex->fmask_is_not_identity = true;
+ }
if (tex->dcc_gather_statistics)
tex->separate_dcc_dirty = true;
}
sctx->framebuffer.compressed_cb_mask = 0;
sctx->framebuffer.uncompressed_cb_mask = 0;
+ sctx->framebuffer.displayable_dcc_cb_mask = 0;
sctx->framebuffer.nr_samples = util_framebuffer_get_num_samples(state);
sctx->framebuffer.nr_color_samples = sctx->framebuffer.nr_samples;
sctx->framebuffer.log_samples = util_logbase2(sctx->framebuffer.nr_samples);
if (surf->color_is_int10)
sctx->framebuffer.color_is_int10 |= 1 << i;
- if (tex->fmask_offset)
+ if (tex->surface.fmask_offset)
sctx->framebuffer.compressed_cb_mask |= 1 << i;
else
sctx->framebuffer.uncompressed_cb_mask |= 1 << i;
+ if (tex->surface.dcc_offset)
+ sctx->framebuffer.displayable_dcc_cb_mask |= 1 << i;
+
/* Don't update nr_color_samples for non-AA buffers.
* (e.g. destination of MSAA resolve)
*/
if (cb->base.u.tex.level > 0)
cb_color_info &= C_028C70_FAST_CLEAR;
- if (tex->fmask_offset) {
- cb_color_fmask = (tex->buffer.gpu_address + tex->fmask_offset) >> 8;
+ if (tex->surface.fmask_offset) {
+ cb_color_fmask = (tex->buffer.gpu_address + tex->surface.fmask_offset) >> 8;
cb_color_fmask |= tex->surface.fmask_tile_swizzle;
}
cb_color_info |= S_028C70_DCC_ENABLE(1);
cb_dcc_base = ((!tex->dcc_separate_buffer ? tex->buffer.gpu_address : 0) +
- tex->dcc_offset) >> 8;
+ tex->surface.dcc_offset) >> 8;
unsigned dcc_tile_swizzle = tex->surface.tile_swizzle;
dcc_tile_swizzle &= (tex->surface.dcc_alignment - 1) >> 8;
/* Set mutable surface parameters. */
cb_color_base += tex->surface.u.gfx9.surf_offset >> 8;
cb_color_base |= tex->surface.tile_swizzle;
- if (!tex->fmask_offset)
+ if (!tex->surface.fmask_offset)
cb_color_fmask = cb_color_base;
if (cb->base.u.tex.level > 0)
cb_color_cmask = cb_color_base;
} else if (sctx->chip_class == GFX9) {
struct gfx9_surf_meta_flags meta;
- if (tex->dcc_offset)
+ if (tex->surface.dcc_offset)
meta = tex->surface.u.gfx9.dcc;
else
meta = tex->surface.u.gfx9.cmask;
/* Set mutable surface parameters. */
cb_color_base += tex->surface.u.gfx9.surf_offset >> 8;
cb_color_base |= tex->surface.tile_swizzle;
- if (!tex->fmask_offset)
+ if (!tex->surface.fmask_offset)
cb_color_fmask = cb_color_base;
if (cb->base.u.tex.level > 0)
cb_color_cmask = cb_color_base;
if (level_info->mode == RADEON_SURF_MODE_2D)
cb_color_base |= tex->surface.tile_swizzle;
- if (!tex->fmask_offset)
+ if (!tex->surface.fmask_offset)
cb_color_fmask = cb_color_base;
if (cb->base.u.tex.level > 0)
cb_color_cmask = cb_color_base;
cb_color_pitch = S_028C64_TILE_MAX(pitch_tile_max);
cb_color_slice = S_028C68_TILE_MAX(slice_tile_max);
- if (tex->fmask_offset) {
+ if (tex->surface.fmask_offset) {
if (sctx->chip_class >= GFX7)
cb_color_pitch |= S_028C64_FMASK_TILE_MAX(tex->surface.u.legacy.fmask.pitch_in_pixels / 8 - 1);
cb_color_attrib |= S_028C74_FMASK_TILE_MODE_INDEX(tex->surface.u.legacy.fmask.tiling_index);
struct radeon_cmdbuf *cs = sctx->gfx_cs;
struct si_state_rasterizer *rs = sctx->queued.named.rasterizer;
unsigned nr_samples = sctx->framebuffer.nr_samples;
- bool has_msaa_sample_loc_bug = sctx->screen->has_msaa_sample_loc_bug;
+ bool has_msaa_sample_loc_bug = sctx->screen->info.has_msaa_sample_loc_bug;
/* Smoothing (only possible with nr_samples == 1) uses the same
* sample locations as the MSAA it simulates.
* - For VMEM and inst.IDXEN == 0 or STRIDE == 0, it's in byte units.
* - For VMEM and inst.IDXEN == 1 and STRIDE != 0, it's in units of STRIDE.
*/
- if (screen->info.chip_class == GFX9 && HAVE_LLVM < 0x0800)
- /* When vindex == 0, LLVM < 8.0 sets IDXEN = 0, thus changing units
- * from STRIDE to bytes. This works around it by setting
- * NUM_RECORDS to at least the size of one element, so that
- * the first element is readable when IDXEN == 0.
- */
- num_records = num_records ? MAX2(num_records, stride) : 0;
- else if (screen->info.chip_class == GFX8)
+ if (screen->info.chip_class == GFX8)
num_records *= stride;
state[4] = 0;
* else: swizzle_address >= NUM_RECORDS
*/
state[7] |= S_008F0C_FORMAT(fmt->img_format) |
- S_008F0C_OOB_SELECT(0) |
+ S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_STRUCTURED_WITH_OFFSET) |
S_008F0C_RESOURCE_LEVEL(1);
} else {
int first_non_void;
state[6] = 0;
state[7] = 0;
- if (tex->dcc_offset) {
+ if (tex->surface.dcc_offset) {
state[6] |= S_00A018_MAX_UNCOMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_256B) |
S_00A018_MAX_COMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_128B) |
S_00A018_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(screen, pipe_format));
}
/* Initialize the sampler view for FMASK. */
- if (tex->fmask_offset) {
+ if (tex->surface.fmask_offset) {
uint32_t format;
- va = tex->buffer.gpu_address + tex->fmask_offset;
+ va = tex->buffer.gpu_address + tex->surface.fmask_offset;
#define FMASK(s,f) (((unsigned)(MAX2(1, s)) * 16) + (MAX2(1, f)))
switch (FMASK(res->nr_samples, res->nr_storage_samples)) {
state[5] |= S_008F24_LAST_ARRAY(last_layer);
}
- if (tex->dcc_offset) {
+ if (tex->surface.dcc_offset) {
state[6] = S_008F28_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(screen, pipe_format));
} else {
/* The last dword is unused by hw. The shader uses it to clear
}
/* Initialize the sampler view for FMASK. */
- if (tex->fmask_offset) {
+ if (tex->surface.fmask_offset) {
uint32_t data_format, num_format;
- va = tex->buffer.gpu_address + tex->fmask_offset;
+ va = tex->buffer.gpu_address + tex->surface.fmask_offset;
#define FMASK(s,f) (((unsigned)(MAX2(1, s)) * 16) + (MAX2(1, f)))
if (screen->info.chip_class == GFX9) {
{
struct si_screen *sscreen = sctx->screen;
uint64_t border_color_va = sctx->border_color_buffer->gpu_address;
- bool has_clear_state = sscreen->has_clear_state;
+ bool has_clear_state = sscreen->info.has_clear_state;
struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
if (!pm4)
return;
- /* Since amdgpu version 3.6.0, CONTEXT_CONTROL is emitted by the kernel */
- if (!sscreen->info.is_amdgpu || sscreen->info.drm_minor < 6) {
- si_pm4_cmd_begin(pm4, PKT3_CONTEXT_CONTROL);
- si_pm4_cmd_add(pm4, CONTEXT_CONTROL_LOAD_ENABLE(1));
- si_pm4_cmd_add(pm4, CONTEXT_CONTROL_SHADOW_ENABLE(1));
- si_pm4_cmd_end(pm4, false);
- }
+ si_pm4_cmd_begin(pm4, PKT3_CONTEXT_CONTROL);
+ si_pm4_cmd_add(pm4, CONTEXT_CONTROL_LOAD_ENABLE(1));
+ si_pm4_cmd_add(pm4, CONTEXT_CONTROL_SHADOW_ENABLE(1));
+ si_pm4_cmd_end(pm4, false);
if (has_clear_state) {
si_pm4_cmd_begin(pm4, PKT3_CLEAR_STATE);
si_pm4_set_reg(pm4, R_028B98_VGT_STRMOUT_BUFFER_CONFIG, 0x0);
}
- si_pm4_set_reg(pm4, R_028AA0_VGT_INSTANCE_STEP_RATE_0, 1);
+ if (sscreen->info.chip_class <= GFX9)
+ si_pm4_set_reg(pm4, R_028AA0_VGT_INSTANCE_STEP_RATE_0, 1);
if (!has_clear_state)
si_pm4_set_reg(pm4, R_028AB8_VGT_VTX_CNT_EN, 0x0);
if (sctx->chip_class < GFX7)
si_pm4_set_reg(pm4, R_008A14_PA_CL_ENHANCE, S_008A14_NUM_CLIP_SEQ(3) |
S_008A14_CLIP_VTX_REORDER_ENA(1));
+ /* CLEAR_STATE doesn't restore these correctly. */
+ si_pm4_set_reg(pm4, R_028240_PA_SC_GENERIC_SCISSOR_TL, S_028240_WINDOW_OFFSET_DISABLE(1));
+ si_pm4_set_reg(pm4, R_028244_PA_SC_GENERIC_SCISSOR_BR,
+ S_028244_BR_X(16384) | S_028244_BR_Y(16384));
+
/* CLEAR_STATE doesn't clear these correctly on certain generations.
* I don't know why. Deduced by trial and error.
*/
if (sctx->chip_class <= GFX7 || !has_clear_state) {
si_pm4_set_reg(pm4, R_028B28_VGT_STRMOUT_DRAW_OPAQUE_OFFSET, 0);
si_pm4_set_reg(pm4, R_028204_PA_SC_WINDOW_SCISSOR_TL, S_028204_WINDOW_OFFSET_DISABLE(1));
- si_pm4_set_reg(pm4, R_028240_PA_SC_GENERIC_SCISSOR_TL, S_028240_WINDOW_OFFSET_DISABLE(1));
- si_pm4_set_reg(pm4, R_028244_PA_SC_GENERIC_SCISSOR_BR,
- S_028244_BR_X(16384) | S_028244_BR_Y(16384));
si_pm4_set_reg(pm4, R_028030_PA_SC_SCREEN_SCISSOR_TL, 0);
si_pm4_set_reg(pm4, R_028034_PA_SC_SCREEN_SCISSOR_BR,
S_028034_BR_X(16384) | S_028034_BR_Y(16384));
si_pm4_set_reg(pm4, R_028C50_PA_SC_NGG_MODE_CNTL,
S_028C50_MAX_DEALLOCS_IN_WAVE(512));
si_pm4_set_reg(pm4, R_028C58_VGT_VERTEX_REUSE_BLOCK_CNTL, 14);
- si_pm4_set_reg(pm4, R_02835C_PA_SC_TILE_STEERING_OVERRIDE,
- sscreen->info.pa_sc_tile_steering_override);
+
+ if (!has_clear_state) {
+ si_pm4_set_reg(pm4, R_02835C_PA_SC_TILE_STEERING_OVERRIDE,
+ sscreen->info.pa_sc_tile_steering_override);
+ }
si_pm4_set_reg(pm4, R_02807C_DB_RMI_L2_CACHE_CONTROL,
S_02807C_Z_WR_POLICY(V_02807C_CACHE_STREAM_WR) |
RADEON_PRIO_BORDER_COLORS);
if (sctx->chip_class >= GFX9) {
- unsigned num_se = sscreen->info.max_se;
- unsigned pc_lines = 0;
- unsigned max_alloc_count = 0;
-
- switch (sctx->family) {
- case CHIP_VEGA10:
- case CHIP_VEGA12:
- case CHIP_VEGA20:
- pc_lines = 2048;
- break;
- case CHIP_RAVEN:
- case CHIP_RAVEN2:
- case CHIP_RENOIR:
- case CHIP_NAVI10:
- case CHIP_NAVI12:
- pc_lines = 1024;
- break;
- case CHIP_NAVI14:
- pc_lines = 512;
- break;
- default:
- assert(0);
- }
-
- if (sctx->chip_class >= GFX10) {
- max_alloc_count = pc_lines / 3;
- } else {
- max_alloc_count = MIN2(128, pc_lines / (4 * num_se));
- }
-
si_pm4_set_reg(pm4, R_028C48_PA_SC_BINNER_CNTL_1,
- S_028C48_MAX_ALLOC_COUNT(max_alloc_count - 1) |
+ S_028C48_MAX_ALLOC_COUNT(sscreen->info.pbb_max_alloc_count - 1) |
S_028C48_MAX_PRIM_PER_BATCH(1023));
si_pm4_set_reg(pm4, R_028C4C_PA_SC_CONSERVATIVE_RASTERIZATION_CNTL,
S_028C4C_NULL_SQUAD_AA_MASK_ENABLE(1));