X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fr600%2Fr600_state.c;h=b20a9d2a2f00d78b8dd996d6b03f8091216d6ad3;hb=295be0e8dfcc28366bcd193c44abc7913d5132d8;hp=c55c5322bfed78ded716348ec954246f18f5845c;hpb=0d7ec8b7d0554382d5af6c59a69ca9672d2583cd;p=mesa.git diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index c55c5322bfe..b20a9d2a2f0 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -158,36 +158,37 @@ static bool r600_is_zs_format_supported(enum pipe_format format) 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: @@ -195,7 +196,7 @@ boolean r600_is_format_supported(struct pipe_screen *screen, case 8: break; default: - return FALSE; + return false; } } @@ -235,11 +236,6 @@ boolean r600_is_format_supported(struct pipe_screen *screen, 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)) @@ -250,7 +246,7 @@ boolean r600_is_format_supported(struct pipe_screen *screen, 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; @@ -475,6 +471,7 @@ static void *r600_create_rs_state(struct pipe_context *ctx, 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 ? @@ -482,8 +479,8 @@ static void *r600_create_rs_state(struct pipe_context *ctx, 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 |= @@ -627,7 +624,7 @@ static void *r600_create_sampler_state(struct pipe_context *ctx, 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); @@ -728,7 +725,7 @@ r600_create_sampler_view_custom(struct pipe_context *ctx, 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; @@ -738,7 +735,7 @@ r600_create_sampler_view_custom(struct pipe_context *ctx, } 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; @@ -760,11 +757,11 @@ r600_create_sampler_view_custom(struct pipe_context *ctx, 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) | @@ -795,7 +792,7 @@ r600_create_sampler_view(struct pipe_context *ctx, 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); @@ -807,26 +804,6 @@ static void r600_set_polygon_stipple(struct pipe_context *ctx, { } -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) @@ -841,7 +818,7 @@ static void r600_init_color_surface(struct r600_context *rctx, 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); @@ -849,17 +826,17 @@ static void r600_init_color_surface(struct r600_context *rctx, 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); @@ -893,6 +870,8 @@ static void r600_init_color_surface(struct r600_context *rctx, 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) @@ -907,6 +886,11 @@ static void r600_init_color_surface(struct r600_context *rctx, 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 || @@ -922,6 +906,7 @@ static void r600_init_color_surface(struct r600_context *rctx, 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); @@ -940,6 +925,7 @@ static void r600_init_color_surface(struct r600_context *rctx, 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; @@ -1003,7 +989,15 @@ static void r600_init_color_surface(struct r600_context *rctx, 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); @@ -1017,8 +1011,15 @@ static void r600_init_color_surface(struct r600_context *rctx, 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); @@ -1042,13 +1043,13 @@ static void r600_init_depth_surface(struct r600_context *rctx, 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; @@ -1067,11 +1068,10 @@ static void r600_init_depth_surface(struct r600_context *rctx, 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); @@ -1089,6 +1089,7 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx, 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. @@ -1129,6 +1130,8 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx, 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) { @@ -1141,7 +1144,7 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx, rctx->framebuffer.export_16bpc = false; } - if (rtex->fmask.size && rtex->cmask.size) { + if (rtex->fmask.size) { rctx->framebuffer.compressed_cb_mask |= 1 << i; } } @@ -1188,7 +1191,9 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx, 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); } @@ -1218,24 +1223,25 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx, 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, @@ -1278,7 +1284,7 @@ static void r600_get_sample_position(struct pipe_context *ctx, 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) { @@ -1345,7 +1351,7 @@ static void r600_emit_msaa_state(struct r600_context *rctx, int nr_samples) 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]; @@ -1357,7 +1363,7 @@ static void r600_emit_framebuffer_state(struct r600_context *rctx, struct r600_a 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++; } @@ -1511,7 +1517,7 @@ static void r600_set_min_samples(struct pipe_context *ctx, unsigned min_samples) 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) { @@ -1525,8 +1531,8 @@ static void r600_emit_cb_misc_state(struct r600_context *rctx, struct r600_atom } 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); @@ -1541,7 +1547,7 @@ static void r600_emit_cb_misc_state(struct r600_context *rctx, struct r600_atom 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) { @@ -1551,8 +1557,8 @@ static void r600_emit_db_state(struct r600_context *rctx, struct r600_atom *atom 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 { @@ -1562,7 +1568,7 @@ static void r600_emit_db_state(struct r600_context *rctx, struct r600_atom *atom 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 = @@ -1647,7 +1653,7 @@ static void r600_emit_db_misc_state(struct r600_context *rctx, struct r600_atom 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); @@ -1656,7 +1662,7 @@ static void r600_emit_config_state(struct r600_context *rctx, struct r600_atom * 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) { @@ -1666,7 +1672,7 @@ static void r600_emit_vertex_buffers(struct r600_context *rctx, struct r600_atom 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; @@ -1696,7 +1702,7 @@ static void r600_emit_constant_buffers(struct r600_context *rctx, 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) { @@ -1712,19 +1718,19 @@ static void r600_emit_constant_buffers(struct r600_context *rctx, 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)); @@ -1770,7 +1776,7 @@ static void r600_emit_sampler_views(struct r600_context *rctx, 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) { @@ -1817,7 +1823,7 @@ static void r600_emit_sampler_states(struct r600_context *rctx, 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) { @@ -1831,18 +1837,17 @@ static void r600_emit_sampler_states(struct r600_context *rctx, /* 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)); @@ -1878,7 +1883,7 @@ static void r600_emit_ps_sampler_states(struct r600_context *rctx, struct r600_a 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) | @@ -1902,10 +1907,13 @@ static void r600_emit_sample_mask(struct r600_context *rctx, struct r600_atom *a 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, @@ -1915,7 +1923,7 @@ static void r600_emit_vertex_fetch_shader(struct r600_context *rctx, struct r600 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; @@ -1950,7 +1958,7 @@ static void r600_emit_shader_stages(struct r600_context *rctx, struct r600_atom 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; @@ -2517,6 +2525,7 @@ void r600_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader *sha } 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)| @@ -2554,6 +2563,12 @@ void r600_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader *sha 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 */ @@ -2603,6 +2618,7 @@ void r600_update_vs_state(struct pipe_context *ctx, struct r600_pipe_shader *sha 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, @@ -2687,6 +2703,7 @@ void r600_update_gs_state(struct pipe_context *ctx, struct r600_pipe_shader *sha 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). */ @@ -2701,6 +2718,7 @@ void r600_update_es_state(struct pipe_context *ctx, struct r600_pipe_shader *sha 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). */ @@ -2837,15 +2855,15 @@ static boolean r600_dma_copy_tile(struct r600_context *rctx, 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; @@ -2855,40 +2873,40 @@ static boolean r600_dma_copy_tile(struct r600_context *rctx, 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 */ @@ -2907,10 +2925,8 @@ static boolean r600_dma_copy_tile(struct r600_context *rctx, 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) | @@ -2924,7 +2940,6 @@ static boolean r600_dma_copy_tile(struct r600_context *rctx, addr += cheight * pitch; y += cheight; } - r600_dma_emit_wait_idle(&rctx->b); return TRUE; } @@ -2967,14 +2982,14 @@ static void r600_dma_copy(struct pipe_context *ctx, 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 */ @@ -2993,11 +3008,11 @@ static void r600_dma_copy(struct pipe_context *ctx, * 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 */