return r600_translate_dbformat(format) != ~0U;
}
-boolean r600_is_format_supported(struct pipe_screen *screen,
- enum pipe_format format,
- enum pipe_texture_target target,
- unsigned sample_count,
- unsigned usage)
+bool r600_is_format_supported(struct pipe_screen *screen,
+ enum pipe_format format,
+ enum pipe_texture_target target,
+ unsigned sample_count,
+ unsigned storage_sample_count,
+ unsigned usage)
{
struct r600_screen *rscreen = (struct r600_screen*)screen;
unsigned retval = 0;
if (target >= PIPE_MAX_TEXTURE_TYPES) {
R600_ERR("r600: unsupported texture type %d\n", target);
- return FALSE;
+ return false;
}
- if (!util_format_is_supported(format, usage))
- return FALSE;
+ if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
+ return false;
if (sample_count > 1) {
if (!rscreen->has_msaa)
- return FALSE;
+ return false;
/* R11G11B10 is broken on R6xx. */
if (rscreen->b.chip_class == R600 &&
format == PIPE_FORMAT_R11G11B10_FLOAT)
- return FALSE;
+ return false;
/* MSAA integer colorbuffers hang. */
if (util_format_is_pure_integer(format) &&
!util_format_is_depth_or_stencil(format))
- return FALSE;
+ return false;
switch (sample_count) {
case 2:
case 8:
break;
default:
- return FALSE;
+ return false;
}
}
retval |= PIPE_BIND_VERTEX_BUFFER;
}
- if (usage & PIPE_BIND_TRANSFER_READ)
- retval |= PIPE_BIND_TRANSFER_READ;
- if (usage & PIPE_BIND_TRANSFER_WRITE)
- retval |= PIPE_BIND_TRANSFER_WRITE;
-
if ((usage & PIPE_BIND_LINEAR) &&
!util_format_is_compressed(format) &&
!(usage & PIPE_BIND_DEPTH_STENCIL))
static void r600_emit_polygon_offset(struct r600_context *rctx, struct r600_atom *a)
{
- struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+ struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
struct r600_poly_offset_state *state = (struct r600_poly_offset_state*)a;
float offset_units = state->offset_units;
float offset_scale = state->offset_scale;
rs->clip_halfz = state->clip_halfz;
rs->flatshade = state->flatshade;
rs->sprite_coord_enable = state->sprite_coord_enable;
+ rs->rasterizer_discard = state->rasterizer_discard;
rs->two_side = state->light_twoside;
rs->clip_plane_enable = state->clip_plane_enable;
rs->pa_sc_line_stipple = state->line_stipple_enable ?
S_028A0C_REPEAT_COUNT(state->line_stipple_factor) : 0;
rs->pa_cl_clip_cntl =
S_028810_DX_CLIP_SPACE_DEF(state->clip_halfz) |
- S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip) |
- S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip) |
+ S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip_near) |
+ S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip_far) |
S_028810_DX_LINEAR_ATTR_CLIP_ENA(1);
if (rctx->b.chip_class == R700) {
rs->pa_cl_clip_cntl |=
static struct pipe_sampler_view *
texture_buffer_sampler_view(struct r600_pipe_sampler_view *view,
unsigned width0, unsigned height0)
-
+
{
struct r600_texture *tmp = (struct r600_texture*)view->base.texture;
int stride = util_format_get_blocksize(view->base.format);
width = width_first_level;
height = height_first_level;
depth = u_minify(texture->depth0, offset_level);
- pitch = tmp->surface.level[offset_level].nblk_x * util_format_get_blockwidth(state->format);
+ pitch = tmp->surface.u.legacy.level[offset_level].nblk_x * util_format_get_blockwidth(state->format);
if (texture->target == PIPE_TEXTURE_1D_ARRAY) {
height = 1;
} else if (texture->target == PIPE_TEXTURE_CUBE_ARRAY)
depth = texture->array_size / 6;
- switch (tmp->surface.level[offset_level].mode) {
+ switch (tmp->surface.u.legacy.level[offset_level].mode) {
default:
case RADEON_SURF_MODE_LINEAR_ALIGNED:
array_mode = V_038000_ARRAY_LINEAR_ALIGNED;
view->tex_resource_words[1] = (S_038004_TEX_HEIGHT(height - 1) |
S_038004_TEX_DEPTH(depth - 1) |
S_038004_DATA_FORMAT(format));
- view->tex_resource_words[2] = tmp->surface.level[offset_level].offset >> 8;
- if (offset_level >= tmp->surface.last_level) {
- view->tex_resource_words[3] = tmp->surface.level[offset_level].offset >> 8;
+ view->tex_resource_words[2] = tmp->surface.u.legacy.level[offset_level].offset >> 8;
+ if (offset_level >= tmp->resource.b.b.last_level) {
+ view->tex_resource_words[3] = tmp->surface.u.legacy.level[offset_level].offset >> 8;
} else {
- view->tex_resource_words[3] = tmp->surface.level[offset_level + 1].offset >> 8;
+ view->tex_resource_words[3] = tmp->surface.u.legacy.level[offset_level + 1].offset >> 8;
}
view->tex_resource_words[4] = (word4 |
S_038010_REQUEST_SIZE(1) |
static void r600_emit_clip_state(struct r600_context *rctx, struct r600_atom *atom)
{
- struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+ struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
struct pipe_clip_state *state = &rctx->clip_state.state;
radeon_set_context_reg_seq(cs, R_028E20_PA_CL_UCP0_X, 6*4);
{
}
-static struct r600_resource *r600_buffer_create_helper(struct r600_screen *rscreen,
- unsigned size, unsigned alignment)
-{
- struct pipe_resource buffer;
-
- memset(&buffer, 0, sizeof buffer);
- buffer.target = PIPE_BUFFER;
- buffer.format = PIPE_FORMAT_R8_UNORM;
- buffer.bind = PIPE_BIND_CUSTOM;
- buffer.usage = PIPE_USAGE_DEFAULT;
- buffer.flags = 0;
- buffer.width0 = size;
- buffer.height0 = 1;
- buffer.depth0 = 1;
- buffer.array_size = 1;
-
- return (struct r600_resource*)
- r600_buffer_create(&rscreen->b.b, &buffer, alignment);
-}
-
static void r600_init_color_surface(struct r600_context *rctx,
struct r600_surface *surf,
bool force_cmask_fmask)
unsigned offset;
const struct util_format_description *desc;
int i;
- bool blend_bypass = 0, blend_clamp = 1, do_endian_swap = FALSE;
+ bool blend_bypass = 0, blend_clamp = 0, do_endian_swap = FALSE;
if (rtex->db_compatible && !r600_can_sample_zs(rtex, false)) {
r600_init_flushed_depth_texture(&rctx->b.b, surf->base.texture, NULL);
assert(rtex);
}
- offset = rtex->surface.level[level].offset;
+ offset = rtex->surface.u.legacy.level[level].offset;
color_view = S_028080_SLICE_START(surf->base.u.tex.first_layer) |
S_028080_SLICE_MAX(surf->base.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;
+ pitch = rtex->surface.u.legacy.level[level].nblk_x / 8 - 1;
+ slice = (rtex->surface.u.legacy.level[level].nblk_x * rtex->surface.u.legacy.level[level].nblk_y) / 64;
if (slice) {
slice = slice - 1;
}
color_info = 0;
- switch (rtex->surface.level[level].mode) {
+ switch (rtex->surface.u.legacy.level[level].mode) {
default:
case RADEON_SURF_MODE_LINEAR_ALIGNED:
color_info = S_0280A0_ARRAY_MODE(V_038000_ARRAY_LINEAR_ALIGNED);
ntype = V_0280A0_NUMBER_UNORM;
else if (desc->channel[i].pure_integer)
ntype = V_0280A0_NUMBER_UINT;
+ } else if (desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT) {
+ ntype = V_0280A0_NUMBER_FLOAT;
}
if (R600_BIG_ENDIAN)
endian = r600_colorformat_endian_swap(format, do_endian_swap);
+ /* blend clamp should be set for all NORM/SRGB types */
+ if (ntype == V_0280A0_NUMBER_UNORM || ntype == V_0280A0_NUMBER_SNORM ||
+ ntype == V_0280A0_NUMBER_SRGB)
+ blend_clamp = 1;
+
/* set blend bypass according to docs if SINT/UINT or
8/24 COLOR variants */
if (ntype == V_0280A0_NUMBER_UINT || ntype == V_0280A0_NUMBER_SINT ||
S_0280A0_COMP_SWAP(swap) |
S_0280A0_BLEND_BYPASS(blend_bypass) |
S_0280A0_BLEND_CLAMP(blend_clamp) |
+ S_0280A0_SIMPLE_FLOAT(1) |
S_0280A0_NUMBER_TYPE(ntype) |
S_0280A0_ENDIAN(endian);
ntype != V_0280A0_NUMBER_UINT &&
ntype != V_0280A0_NUMBER_SINT) &&
G_0280A0_BLEND_CLAMP(color_info) &&
+ /* XXX this condition is always true since BLEND_FLOAT32 is never set (bug?). */
!G_0280A0_BLEND_FLOAT32(color_info)) {
color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM);
surf->export_16bpc = true;
void *ptr;
r600_resource_reference(&rctx->dummy_cmask, NULL);
- rctx->dummy_cmask = r600_buffer_create_helper(rscreen, cmask.size, cmask.alignment);
+ rctx->dummy_cmask = (struct r600_resource*)
+ r600_aligned_buffer_create(&rscreen->b.b, 0,
+ PIPE_USAGE_DEFAULT,
+ cmask.size, cmask.alignment);
+
+ if (unlikely(!rctx->dummy_cmask)) {
+ surf->color_initialized = false;
+ return;
+ }
/* Set the contents to 0xCC. */
ptr = pipe_buffer_map(&rctx->b.b, &rctx->dummy_cmask->b.b, PIPE_TRANSFER_WRITE, &transfer);
rctx->dummy_fmask->b.b.width0 < fmask.size ||
rctx->dummy_fmask->buf->alignment % fmask.alignment != 0) {
r600_resource_reference(&rctx->dummy_fmask, NULL);
- rctx->dummy_fmask = r600_buffer_create_helper(rscreen, fmask.size, fmask.alignment);
+ rctx->dummy_fmask = (struct r600_resource*)
+ r600_aligned_buffer_create(&rscreen->b.b, 0,
+ PIPE_USAGE_DEFAULT,
+ fmask.size, fmask.alignment);
+ if (unlikely(!rctx->dummy_fmask)) {
+ surf->color_initialized = false;
+ return;
+ }
}
r600_resource_reference(&surf->cb_buffer_fmask, rctx->dummy_fmask);
unsigned level, pitch, slice, format, offset, array_mode;
level = surf->base.u.tex.level;
- offset = rtex->surface.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;
+ offset = rtex->surface.u.legacy.level[level].offset;
+ pitch = rtex->surface.u.legacy.level[level].nblk_x / 8 - 1;
+ slice = (rtex->surface.u.legacy.level[level].nblk_x * rtex->surface.u.legacy.level[level].nblk_y) / 64;
if (slice) {
slice = slice - 1;
}
- switch (rtex->surface.level[level].mode) {
+ switch (rtex->surface.u.legacy.level[level].mode) {
case RADEON_SURF_MODE_2D:
array_mode = V_0280A0_ARRAY_2D_TILED_THIN1;
break;
surf->db_depth_view = S_028004_SLICE_START(surf->base.u.tex.first_layer) |
S_028004_SLICE_MAX(surf->base.u.tex.last_layer);
surf->db_depth_size = S_028000_PITCH_TILE_MAX(pitch) | S_028000_SLICE_TILE_MAX(slice);
- surf->db_prefetch_limit = (rtex->surface.level[level].nblk_y / 8) - 1;
+ surf->db_prefetch_limit = (rtex->surface.u.legacy.level[level].nblk_y / 8) - 1;
- /* use htile only for first level */
- if (rtex->htile_buffer && !level) {
- surf->db_htile_data_base = 0;
+ if (r600_htile_enabled(rtex, level)) {
+ surf->db_htile_data_base = rtex->htile_offset >> 8;
surf->db_htile_surface = S_028D24_HTILE_WIDTH(1) |
S_028D24_HTILE_HEIGHT(1) |
S_028D24_FULL_CACHE(1);
struct r600_surface *surf;
struct r600_texture *rtex;
unsigned i;
+ uint32_t target_mask = 0;
/* Flush TC when changing the framebuffer state, because the only
* client not using TC that can change textures is the framebuffer.
rtex = (struct r600_texture*)surf->base.texture;
r600_context_add_resource_size(ctx, state->cbufs[i]->texture);
+ target_mask |= (0xf << (i * 4));
+
if (!surf->color_initialized || force_cmask_fmask) {
r600_init_color_surface(rctx, surf, force_cmask_fmask);
if (force_cmask_fmask) {
rctx->framebuffer.export_16bpc = false;
}
- if (rtex->fmask.size && rtex->cmask.size) {
+ if (rtex->fmask.size) {
rctx->framebuffer.compressed_cb_mask |= 1 << i;
}
}
r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom);
}
- if (rctx->cb_misc_state.nr_cbufs != state->nr_cbufs) {
+ if (rctx->cb_misc_state.nr_cbufs != state->nr_cbufs ||
+ rctx->cb_misc_state.bound_cbufs_target_mask != target_mask) {
+ rctx->cb_misc_state.bound_cbufs_target_mask = target_mask;
rctx->cb_misc_state.nr_cbufs = state->nr_cbufs;
r600_mark_atom_dirty(rctx, &rctx->cb_misc_state.atom);
}
r600_mark_atom_dirty(rctx, &rctx->framebuffer.atom);
r600_set_sample_locations_constant_buffer(rctx);
+ rctx->framebuffer.do_update_surf_dirtiness = true;
}
-static uint32_t sample_locs_2x[] = {
+static const uint32_t sample_locs_2x[] = {
FILL_SREG(-4, 4, 4, -4, -4, 4, 4, -4),
FILL_SREG(-4, 4, 4, -4, -4, 4, 4, -4),
};
-static unsigned max_dist_2x = 4;
+static const unsigned max_dist_2x = 4;
-static uint32_t sample_locs_4x[] = {
+static const uint32_t sample_locs_4x[] = {
FILL_SREG(-2, -2, 2, 2, -6, 6, 6, -6),
FILL_SREG(-2, -2, 2, 2, -6, 6, 6, -6),
};
-static unsigned max_dist_4x = 6;
-static uint32_t sample_locs_8x[] = {
+static const unsigned max_dist_4x = 6;
+static const uint32_t sample_locs_8x[] = {
FILL_SREG(-1, 1, 1, 5, 3, -5, 5, 3),
FILL_SREG(-7, -1, -3, -7, 7, -3, -5, 7),
};
-static unsigned max_dist_8x = 7;
+static const unsigned max_dist_8x = 7;
static void r600_get_sample_position(struct pipe_context *ctx,
unsigned sample_count,
static void r600_emit_msaa_state(struct r600_context *rctx, int nr_samples)
{
- struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+ struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
unsigned max_dist = 0;
if (rctx->b.family == CHIP_R600) {
static void r600_emit_framebuffer_state(struct r600_context *rctx, struct r600_atom *atom)
{
- struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+ struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
struct pipe_framebuffer_state *state = &rctx->framebuffer.state;
unsigned nr_cbufs = state->nr_cbufs;
struct r600_surface **cb = (struct r600_surface**)&state->cbufs[0];
radeon_emit(cs, cb[i] ? cb[i]->cb_color_info : 0);
}
/* set CB_COLOR1_INFO for possible dual-src blending */
- if (i == 1 && cb[0]) {
+ if (rctx->framebuffer.dual_src_blend && i == 1 && cb[0]) {
radeon_emit(cs, cb[0]->cb_color_info);
i++;
}
static void r600_emit_cb_misc_state(struct r600_context *rctx, struct r600_atom *atom)
{
- struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+ struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
struct r600_cb_misc_state *a = (struct r600_cb_misc_state*)atom;
if (G_028808_SPECIAL_OP(a->cb_color_control) == V_028808_SPECIAL_RESOLVE_BOX) {
}
radeon_set_context_reg(cs, R_028808_CB_COLOR_CONTROL, a->cb_color_control);
} else {
- unsigned fb_colormask = (1ULL << ((unsigned)a->nr_cbufs * 4)) - 1;
- unsigned ps_colormask = (1ULL << ((unsigned)a->nr_ps_color_outputs * 4)) - 1;
+ unsigned fb_colormask = a->bound_cbufs_target_mask;
+ unsigned ps_colormask = a->ps_color_export_mask;
unsigned multiwrite = a->multiwrite && a->nr_cbufs > 1;
radeon_set_context_reg_seq(cs, R_028238_CB_TARGET_MASK, 2);
static void r600_emit_db_state(struct r600_context *rctx, struct r600_atom *atom)
{
- struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+ struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
struct r600_db_state *a = (struct r600_db_state*)atom;
if (a->rsurf && a->rsurf->db_htile_surface) {
radeon_set_context_reg(cs, R_02802C_DB_DEPTH_CLEAR, fui(rtex->depth_clear_value));
radeon_set_context_reg(cs, R_028D24_DB_HTILE_SURFACE, a->rsurf->db_htile_surface);
radeon_set_context_reg(cs, R_028014_DB_HTILE_DATA_BASE, a->rsurf->db_htile_data_base);
- reloc_idx = radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, rtex->htile_buffer,
- RADEON_USAGE_READWRITE, RADEON_PRIO_HTILE);
+ reloc_idx = radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, &rtex->resource,
+ RADEON_USAGE_READWRITE, RADEON_PRIO_SEPARATE_META);
radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
radeon_emit(cs, reloc_idx);
} else {
static void r600_emit_db_misc_state(struct r600_context *rctx, struct r600_atom *atom)
{
- struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+ struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
struct r600_db_misc_state *a = (struct r600_db_misc_state*)atom;
unsigned db_render_control = 0;
unsigned db_render_override =
static void r600_emit_config_state(struct r600_context *rctx, struct r600_atom *atom)
{
- struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+ struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
struct r600_config_state *a = (struct r600_config_state*)atom;
radeon_set_config_reg(cs, R_008C04_SQ_GPR_RESOURCE_MGMT_1, a->sq_gpr_resource_mgmt_1);
static void r600_emit_vertex_buffers(struct r600_context *rctx, struct r600_atom *atom)
{
- struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+ struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
uint32_t dirty_mask = rctx->vertex_buffer_state.dirty_mask;
while (dirty_mask) {
unsigned buffer_index = u_bit_scan(&dirty_mask);
vb = &rctx->vertex_buffer_state.vb[buffer_index];
- rbuffer = (struct r600_resource*)vb->buffer;
+ rbuffer = (struct r600_resource*)vb->buffer.resource;
assert(rbuffer);
offset = vb->buffer_offset;
unsigned reg_alu_constbuf_size,
unsigned reg_alu_const_cache)
{
- struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+ struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
uint32_t dirty_mask = state->dirty_mask;
while (dirty_mask) {
offset = cb->buffer_offset;
if (!gs_ring_buffer) {
+ assert(buffer_index < R600_MAX_HW_CONST_BUFFERS);
radeon_set_context_reg(cs, reg_alu_constbuf_size + buffer_index * 4,
DIV_ROUND_UP(cb->buffer_size, 256));
radeon_set_context_reg(cs, reg_alu_const_cache + buffer_index * 4, offset >> 8);
+ radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
+ radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, rbuffer,
+ RADEON_USAGE_READ, RADEON_PRIO_CONST_BUFFER));
}
- radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
- radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, rbuffer,
- RADEON_USAGE_READ, RADEON_PRIO_CONST_BUFFER));
-
radeon_emit(cs, PKT3(PKT3_SET_RESOURCE, 7, 0));
radeon_emit(cs, (buffer_id_base + buffer_index) * 7);
radeon_emit(cs, offset); /* RESOURCEi_WORD0 */
- radeon_emit(cs, rbuffer->b.b.width0 - offset - 1); /* RESOURCEi_WORD1 */
+ radeon_emit(cs, cb->buffer_size - 1); /* RESOURCEi_WORD1 */
radeon_emit(cs, /* RESOURCEi_WORD2 */
S_038008_ENDIAN_SWAP(gs_ring_buffer ? ENDIAN_NONE : r600_endian_swap(32)) |
S_038008_STRIDE(gs_ring_buffer ? 4 : 16));
struct r600_samplerview_state *state,
unsigned resource_id_base)
{
- struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+ struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
uint32_t dirty_mask = state->dirty_mask;
while (dirty_mask) {
unsigned resource_id_base,
unsigned border_color_reg)
{
- struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+ struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
uint32_t dirty_mask = texinfo->states.dirty_mask;
while (dirty_mask) {
/* TEX_ARRAY_OVERRIDE must be set for array textures to disable
* filtering between layers.
- * Don't update TEX_ARRAY_OVERRIDE if we don't have the sampler view.
*/
- if (rview) {
- enum pipe_texture_target target = rview->base.texture->target;
- if (target == PIPE_TEXTURE_1D_ARRAY ||
- target == PIPE_TEXTURE_2D_ARRAY) {
- rstate->tex_sampler_words[0] |= S_03C000_TEX_ARRAY_OVERRIDE(1);
- texinfo->is_array_sampler[i] = true;
- } else {
- rstate->tex_sampler_words[0] &= C_03C000_TEX_ARRAY_OVERRIDE;
- texinfo->is_array_sampler[i] = false;
- }
+ enum pipe_texture_target target = PIPE_BUFFER;
+ if (rview)
+ target = rview->base.texture->target;
+ if (target == PIPE_TEXTURE_1D_ARRAY ||
+ target == PIPE_TEXTURE_2D_ARRAY) {
+ rstate->tex_sampler_words[0] |= S_03C000_TEX_ARRAY_OVERRIDE(1);
+ texinfo->is_array_sampler[i] = true;
+ } else {
+ rstate->tex_sampler_words[0] &= C_03C000_TEX_ARRAY_OVERRIDE;
+ texinfo->is_array_sampler[i] = false;
}
radeon_emit(cs, PKT3(PKT3_SET_SAMPLER, 3, 0));
static void r600_emit_seamless_cube_map(struct r600_context *rctx, struct r600_atom *atom)
{
- struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+ struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
unsigned tmp;
tmp = S_009508_DISABLE_CUBE_ANISO(1) |
static void r600_emit_vertex_fetch_shader(struct r600_context *rctx, struct r600_atom *a)
{
- struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+ struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
struct r600_cso_state *state = (struct r600_cso_state*)a;
struct r600_fetch_shader *shader = (struct r600_fetch_shader*)state->cso;
+ if (!shader)
+ return;
+
radeon_set_context_reg(cs, R_028894_SQ_PGM_START_FS, shader->offset >> 8);
radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, shader->buffer,
static void r600_emit_shader_stages(struct r600_context *rctx, struct r600_atom *a)
{
- struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+ struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
struct r600_shader_stages_state *state = (struct r600_shader_stages_state*)a;
uint32_t v2 = 0, primid = 0;
static void r600_emit_gs_rings(struct r600_context *rctx, struct r600_atom *a)
{
- struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+ struct radeon_cmdbuf *cs = rctx->b.gfx.cs;
struct r600_gs_rings_state *state = (struct r600_gs_rings_state*)a;
struct r600_resource *rbuffer;
}
shader->nr_ps_color_outputs = num_cout;
+ shader->ps_color_export_mask = rshader->ps_color_export_mask;
spi_ps_in_control_0 = S_0286CC_NUM_INTERP(rshader->ninput) |
S_0286CC_PERSP_GRADIENT_ENA(1)|
r600_store_context_reg_seq(cb, R_028850_SQ_PGM_RESOURCES_PS, 2);
r600_store_value(cb, /* R_028850_SQ_PGM_RESOURCES_PS*/
S_028850_NUM_GPRS(rshader->bc.ngpr) |
+ /*
+ * docs are misleading about the dx10_clamp bit. This only affects
+ * instructions using CLAMP dst modifier, in which case they will
+ * return 0 with this set for a NaN (otherwise NaN).
+ */
+ S_028850_DX10_CLAMP(1) |
S_028850_STACK_SIZE(rshader->bc.nstack) |
S_028850_UNCACHED_FIRST_INST(ufi));
r600_store_value(cb, exports_ps); /* R_028854_SQ_PGM_EXPORTS_PS */
S_0286C4_VS_EXPORT_COUNT(nparams - 1));
r600_store_context_reg(cb, R_028868_SQ_PGM_RESOURCES_VS,
S_028868_NUM_GPRS(rshader->bc.ngpr) |
+ S_028868_DX10_CLAMP(1) |
S_028868_STACK_SIZE(rshader->bc.nstack));
if (rshader->vs_position_window_space) {
r600_store_context_reg(cb, R_028818_PA_CL_VTE_CNTL,
r600_store_context_reg(cb, R_02887C_SQ_PGM_RESOURCES_GS,
S_02887C_NUM_GPRS(rshader->bc.ngpr) |
+ S_02887C_DX10_CLAMP(1) |
S_02887C_STACK_SIZE(rshader->bc.nstack));
r600_store_context_reg(cb, R_02886C_SQ_PGM_START_GS, 0);
/* After that, the NOP relocation packet must be emitted (shader->bo, RADEON_USAGE_READ). */
r600_store_context_reg(cb, R_028890_SQ_PGM_RESOURCES_ES,
S_028890_NUM_GPRS(rshader->bc.ngpr) |
+ S_028890_DX10_CLAMP(1) |
S_028890_STACK_SIZE(rshader->bc.nstack));
r600_store_context_reg(cb, R_028880_SQ_PGM_START_ES, 0);
/* After that, the NOP relocation packet must be emitted (shader->bo, RADEON_USAGE_READ). */
unsigned pitch,
unsigned bpp)
{
- struct radeon_winsys_cs *cs = rctx->b.dma.cs;
+ struct radeon_cmdbuf *cs = rctx->b.dma.cs;
struct r600_texture *rsrc = (struct r600_texture*)src;
struct r600_texture *rdst = (struct r600_texture*)dst;
unsigned array_mode, lbpp, pitch_tile_max, slice_tile_max, size;
unsigned ncopy, height, cheight, detile, i, x, y, z, src_mode, dst_mode;
uint64_t base, addr;
- dst_mode = rdst->surface.level[dst_level].mode;
- src_mode = rsrc->surface.level[src_level].mode;
+ dst_mode = rdst->surface.u.legacy.level[dst_level].mode;
+ src_mode = rsrc->surface.u.legacy.level[src_level].mode;
assert(dst_mode != src_mode);
y = 0;
if (dst_mode == RADEON_SURF_MODE_LINEAR_ALIGNED) {
/* T2L */
array_mode = r600_array_mode(src_mode);
- slice_tile_max = (rsrc->surface.level[src_level].nblk_x * rsrc->surface.level[src_level].nblk_y) / (8*8);
+ slice_tile_max = (rsrc->surface.u.legacy.level[src_level].nblk_x * rsrc->surface.u.legacy.level[src_level].nblk_y) / (8*8);
slice_tile_max = slice_tile_max ? slice_tile_max - 1 : 0;
/* linear height must be the same as the slice tile max height, it's ok even
* if the linear destination/source have smaller heigh as the size of the
* dma packet will be using the copy_height which is always smaller or equal
* to the linear height
*/
- height = rsrc->surface.level[src_level].npix_y;
+ height = u_minify(rsrc->resource.b.b.height0, src_level);
detile = 1;
x = src_x;
y = src_y;
z = src_z;
- base = rsrc->surface.level[src_level].offset;
- addr = rdst->surface.level[dst_level].offset;
- addr += rdst->surface.level[dst_level].slice_size * dst_z;
+ base = rsrc->surface.u.legacy.level[src_level].offset;
+ addr = rdst->surface.u.legacy.level[dst_level].offset;
+ addr += (uint64_t)rdst->surface.u.legacy.level[dst_level].slice_size_dw * 4 * dst_z;
addr += dst_y * pitch + dst_x * bpp;
} else {
/* L2T */
array_mode = r600_array_mode(dst_mode);
- slice_tile_max = (rdst->surface.level[dst_level].nblk_x * rdst->surface.level[dst_level].nblk_y) / (8*8);
+ slice_tile_max = (rdst->surface.u.legacy.level[dst_level].nblk_x * rdst->surface.u.legacy.level[dst_level].nblk_y) / (8*8);
slice_tile_max = slice_tile_max ? slice_tile_max - 1 : 0;
/* linear height must be the same as the slice tile max height, it's ok even
* if the linear destination/source have smaller heigh as the size of the
* dma packet will be using the copy_height which is always smaller or equal
* to the linear height
*/
- height = rdst->surface.level[dst_level].npix_y;
+ height = u_minify(rdst->resource.b.b.height0, dst_level);
detile = 0;
x = dst_x;
y = dst_y;
z = dst_z;
- base = rdst->surface.level[dst_level].offset;
- addr = rsrc->surface.level[src_level].offset;
- addr += rsrc->surface.level[src_level].slice_size * src_z;
+ base = rdst->surface.u.legacy.level[dst_level].offset;
+ addr = rsrc->surface.u.legacy.level[src_level].offset;
+ addr += (uint64_t)rsrc->surface.u.legacy.level[src_level].slice_size_dw * 4 * src_z;
addr += src_y * pitch + src_x * bpp;
}
/* check that we are in dw/base alignment constraint */
cheight = cheight > copy_height ? copy_height : cheight;
size = (cheight * pitch) / 4;
/* emit reloc before writing cs so that cs is always in consistent state */
- radeon_add_to_buffer_list(&rctx->b, &rctx->b.dma, &rsrc->resource, RADEON_USAGE_READ,
- RADEON_PRIO_SDMA_TEXTURE);
- radeon_add_to_buffer_list(&rctx->b, &rctx->b.dma, &rdst->resource, RADEON_USAGE_WRITE,
- RADEON_PRIO_SDMA_TEXTURE);
+ radeon_add_to_buffer_list(&rctx->b, &rctx->b.dma, &rsrc->resource, RADEON_USAGE_READ, 0);
+ radeon_add_to_buffer_list(&rctx->b, &rctx->b.dma, &rdst->resource, RADEON_USAGE_WRITE, 0);
radeon_emit(cs, DMA_PACKET(DMA_PACKET_COPY, 1, 0, size));
radeon_emit(cs, base >> 8);
radeon_emit(cs, (detile << 31) | (array_mode << 27) |
addr += cheight * pitch;
y += cheight;
}
- r600_dma_emit_wait_idle(&rctx->b);
return TRUE;
}
dst_y = util_format_get_nblocksy(src->format, dst_y);
bpp = rdst->surface.bpe;
- dst_pitch = rdst->surface.level[dst_level].pitch_bytes;
- src_pitch = rsrc->surface.level[src_level].pitch_bytes;
- src_w = rsrc->surface.level[src_level].npix_x;
- dst_w = rdst->surface.level[dst_level].npix_x;
+ dst_pitch = rdst->surface.u.legacy.level[dst_level].nblk_x * rdst->surface.bpe;
+ src_pitch = rsrc->surface.u.legacy.level[src_level].nblk_x * rsrc->surface.bpe;
+ src_w = u_minify(rsrc->resource.b.b.width0, src_level);
+ dst_w = u_minify(rdst->resource.b.b.width0, dst_level);
copy_height = src_box->height / rsrc->surface.blk_h;
- dst_mode = rdst->surface.level[dst_level].mode;
- src_mode = rsrc->surface.level[src_level].mode;
+ dst_mode = rdst->surface.u.legacy.level[dst_level].mode;
+ src_mode = rsrc->surface.u.legacy.level[src_level].mode;
if (src_pitch != dst_pitch || src_box->x || dst_x || src_w != dst_w) {
/* strict requirement on r6xx/r7xx */
* dst_x/y == 0
* dst_pitch == src_pitch
*/
- src_offset= rsrc->surface.level[src_level].offset;
- src_offset += rsrc->surface.level[src_level].slice_size * src_box->z;
+ src_offset= rsrc->surface.u.legacy.level[src_level].offset;
+ src_offset += (uint64_t)rsrc->surface.u.legacy.level[src_level].slice_size_dw * 4 * src_box->z;
src_offset += src_y * src_pitch + src_x * bpp;
- dst_offset = rdst->surface.level[dst_level].offset;
- dst_offset += rdst->surface.level[dst_level].slice_size * dst_z;
+ dst_offset = rdst->surface.u.legacy.level[dst_level].offset;
+ dst_offset += (uint64_t)rdst->surface.u.legacy.level[dst_level].slice_size_dw * 4 * dst_z;
dst_offset += dst_y * dst_pitch + dst_x * bpp;
size = src_box->height * src_pitch;
/* must be dw aligned */