X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fradeon%2Fr600_texture.c;h=ab8ce7bd7136d9be8d0f6cd2173dc4c3b6c70ce5;hb=76039b38f0ef54ca61cbe72b899dfcf0f0c724e4;hp=3a37465b13eb9cc6df288e435de417163747cb68;hpb=bf701a84eb000910015a3c3ee9860141cde4990d;p=mesa.git diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index 3a37465b13e..ab8ce7bd713 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -380,7 +380,8 @@ void r600_texture_get_cmask_info(struct r600_common_screen *rscreen, out->slice_tile_max = ((pitch_elements * height) / (128*128)) - 1; out->alignment = MAX2(256, base_align); - out->size = rtex->surface.array_size * align(slice_bytes, base_align); + out->size = (util_max_layer(&rtex->resource.b.b, 0) + 1) * + align(slice_bytes, base_align); } static void si_texture_get_cmask_info(struct r600_common_screen *rscreen, @@ -427,7 +428,8 @@ static void si_texture_get_cmask_info(struct r600_common_screen *rscreen, out->slice_tile_max -= 1; out->alignment = MAX2(256, base_align); - out->size = rtex->surface.array_size * align(slice_bytes, base_align); + out->size = (util_max_layer(&rtex->resource.b.b, 0) + 1) * + align(slice_bytes, base_align); } static void r600_texture_allocate_cmask(struct r600_common_screen *rscreen, @@ -471,8 +473,7 @@ static void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen } /* update colorbuffer state bits */ - rtex->cmask.base_address_reg = - r600_resource_va(&rscreen->b, &rtex->cmask_buffer->b.b) >> 8; + rtex->cmask.base_address_reg = rtex->cmask_buffer->gpu_address >> 8; if (rscreen->chip_class >= SI) rtex->cb_color_info |= SI_S_028C70_FAST_CLEAR(1); @@ -480,19 +481,34 @@ static void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen rtex->cb_color_info |= EG_S_028C70_FAST_CLEAR(1); } -static unsigned si_texture_htile_alloc_size(struct r600_common_screen *rscreen, +static unsigned r600_texture_get_htile_size(struct r600_common_screen *rscreen, struct r600_texture *rtex) { unsigned cl_width, cl_height, width, height; unsigned slice_elements, slice_bytes, pipe_interleave_bytes, base_align; unsigned num_pipes = rscreen->tiling_info.num_channels; + if (rscreen->chip_class <= EVERGREEN && + rscreen->info.drm_minor < 26) + return 0; + + /* HW bug on R6xx. */ + if (rscreen->chip_class == R600 && + (rtex->surface.level[0].npix_x > 7680 || + rtex->surface.level[0].npix_y > 7680)) + return 0; + /* HTILE is broken with 1D tiling on old kernels and CIK. */ - if (rtex->surface.level[0].mode == RADEON_SURF_MODE_1D && - rscreen->chip_class >= CIK && rscreen->info.drm_minor < 38) + if (rscreen->chip_class >= CIK && + rtex->surface.level[0].mode == RADEON_SURF_MODE_1D && + rscreen->info.drm_minor < 38) return 0; switch (num_pipes) { + case 1: + cl_width = 32; + cl_height = 16; + break; case 2: cl_width = 32; cl_height = 32; @@ -523,54 +539,18 @@ static unsigned si_texture_htile_alloc_size(struct r600_common_screen *rscreen, pipe_interleave_bytes = rscreen->tiling_info.group_bytes; base_align = num_pipes * pipe_interleave_bytes; - return rtex->surface.array_size * align(slice_bytes, base_align); -} - -static unsigned r600_texture_htile_alloc_size(struct r600_common_screen *rscreen, - struct r600_texture *rtex) -{ - unsigned sw = rtex->surface.level[0].nblk_x * rtex->surface.blk_w; - unsigned sh = rtex->surface.level[0].nblk_y * rtex->surface.blk_h; - unsigned npipes = rscreen->info.r600_num_tile_pipes; - unsigned htile_size; - - /* XXX also use it for other texture targets */ - if (rscreen->info.drm_minor < 26 || - rtex->resource.b.b.target != PIPE_TEXTURE_2D || - rtex->surface.level[0].nblk_x < 32 || - rtex->surface.level[0].nblk_y < 32) { - return 0; - } - - /* HW bug on R6xx. */ - if (rscreen->chip_class == R600 && - (rtex->surface.level[0].npix_x > 7680 || - rtex->surface.level[0].npix_y > 7680)) - return 0; - - /* this alignment and htile size only apply to linear htile buffer */ - sw = align(sw, 16 << 3); - sh = align(sh, npipes << 3); - htile_size = (sw >> 3) * (sh >> 3) * 4; - /* must be aligned with 2K * npipes */ - htile_size = align(htile_size, (2 << 10) * npipes); - return htile_size; + return (util_max_layer(&rtex->resource.b.b, 0) + 1) * + align(slice_bytes, base_align); } static void r600_texture_allocate_htile(struct r600_common_screen *rscreen, struct r600_texture *rtex) { - unsigned htile_size; - if (rscreen->chip_class >= SI) { - htile_size = si_texture_htile_alloc_size(rscreen, rtex); - } else { - htile_size = r600_texture_htile_alloc_size(rscreen, rtex); - } + unsigned htile_size = r600_texture_get_htile_size(rscreen, rtex); if (!htile_size) return; - /* XXX don't allocate it separately */ rtex->htile_buffer = (struct r600_resource*) pipe_buffer_create(&rscreen->b, PIPE_BIND_CUSTOM, PIPE_USAGE_DEFAULT, htile_size); @@ -579,7 +559,8 @@ static void r600_texture_allocate_htile(struct r600_common_screen *rscreen, * without htile buffer */ R600_ERR("Failed to create buffer object for htile buffer.\n"); } else { - r600_screen_clear_buffer(rscreen, &rtex->htile_buffer->b.b, 0, htile_size, 0); + r600_screen_clear_buffer(rscreen, &rtex->htile_buffer->b.b, 0, + htile_size, 0, true); } } @@ -594,7 +575,6 @@ r600_texture_create_object(struct pipe_screen *screen, struct r600_texture *rtex; struct r600_resource *resource; struct r600_common_screen *rscreen = (struct r600_common_screen*)screen; - uint64_t va; rtex = CALLOC_STRUCT(r600_texture); if (rtex == NULL) @@ -624,7 +604,7 @@ r600_texture_create_object(struct pipe_screen *screen, if (rtex->is_depth) { if (!(base->flags & (R600_RESOURCE_FLAG_TRANSFER | R600_RESOURCE_FLAG_FLUSHED_DEPTH)) && - (rscreen->debug_flags & DBG_HYPERZ)) { + !(rscreen->debug_flags & DBG_NO_HYPERZ)) { r600_texture_allocate_htile(rscreen, rtex); } @@ -652,23 +632,25 @@ r600_texture_create_object(struct pipe_screen *screen, } else { resource->buf = buf; resource->cs_buf = rscreen->ws->buffer_get_cs_handle(buf); + resource->gpu_address = rscreen->ws->buffer_get_virtual_address(resource->cs_buf); resource->domains = rscreen->ws->buffer_get_initial_domain(resource->cs_buf); } if (rtex->cmask.size) { /* Initialize the cmask to 0xCC (= compressed state). */ r600_screen_clear_buffer(rscreen, &rtex->cmask_buffer->b.b, - rtex->cmask.offset, rtex->cmask.size, 0xCCCCCCCC); + rtex->cmask.offset, rtex->cmask.size, + 0xCCCCCCCC, true); } /* Initialize the CMASK base register value. */ - va = r600_resource_va(&rscreen->b, &rtex->resource.b.b); - rtex->cmask.base_address_reg = (va + rtex->cmask.offset) >> 8; + rtex->cmask.base_address_reg = + (rtex->resource.gpu_address + rtex->cmask.offset) >> 8; if (rscreen->debug_flags & DBG_VM) { - fprintf(stderr, "VM start=0x%"PRIu64" end=0x%"PRIu64" | Texture %ix%ix%i, %i levels, %i samples, %s\n", - r600_resource_va(screen, &rtex->resource.b.b), - r600_resource_va(screen, &rtex->resource.b.b) + rtex->resource.buf->size, + fprintf(stderr, "VM start=0x%"PRIX64" end=0x%"PRIX64" | Texture %ix%ix%i, %i levels, %i samples, %s\n", + rtex->resource.gpu_address, + rtex->resource.gpu_address + rtex->resource.buf->size, base->width0, base->height0, util_max_layer(base, 0)+1, base->last_level+1, base->nr_samples ? base->nr_samples : 1, util_format_short_name(base->format)); } @@ -737,9 +719,15 @@ static unsigned r600_choose_tiling(struct r600_common_screen *rscreen, * Compressed textures must always be tiled. */ if (!(templ->flags & R600_RESOURCE_FLAG_FORCE_TILING) && !util_format_is_compressed(templ->format)) { - /* Tiling doesn't work with the 422 (SUBSAMPLED) formats on R600-Cayman. */ - if (rscreen->chip_class <= CAYMAN && - desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) + /* Not everything can be linear, so we cannot enforce it + * for all textures. */ + if ((rscreen->debug_flags & DBG_NO_TILING) && + (!util_format_is_depth_or_stencil(templ->format) || + !(templ->flags & R600_RESOURCE_FLAG_FLUSHED_DEPTH))) + return RADEON_SURF_MODE_LINEAR_ALIGNED; + + /* Tiling doesn't work with the 422 (SUBSAMPLED) formats on R600+. */ + if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) return RADEON_SURF_MODE_LINEAR_ALIGNED; /* Cursors are linear on SI. @@ -764,7 +752,8 @@ static unsigned r600_choose_tiling(struct r600_common_screen *rscreen, } /* Make small textures 1D tiled. */ - if (templ->width0 <= 16 || templ->height0 <= 16) + if (templ->width0 <= 16 || templ->height0 <= 16 || + (rscreen->debug_flags & DBG_NO_2D_TILING)) return RADEON_SURF_MODE_1D; /* The allocator will switch to 1D if needed. */ @@ -937,19 +926,16 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx, * the CPU is much happier reading out of cached system memory * than uncached VRAM. */ - if (rtex->surface.level[level].mode >= RADEON_SURF_MODE_1D) + if (rtex->surface.level[0].mode >= RADEON_SURF_MODE_1D) { use_staging_texture = TRUE; - - /* Untiled buffers in VRAM, which is slow for CPU reads */ - if ((usage & PIPE_TRANSFER_READ) && !(usage & PIPE_TRANSFER_MAP_DIRECTLY) && + } else if ((usage & PIPE_TRANSFER_READ) && !(usage & PIPE_TRANSFER_MAP_DIRECTLY) && (rtex->resource.domains == RADEON_DOMAIN_VRAM)) { + /* Untiled buffers in VRAM, which is slow for CPU reads */ use_staging_texture = TRUE; - } - - /* Use a staging texture for uploads if the underlying BO is busy. */ - if (!(usage & PIPE_TRANSFER_READ) && + } else if (!(usage & PIPE_TRANSFER_READ) && (r600_rings_is_buffer_referenced(rctx, rtex->resource.cs_buf, RADEON_USAGE_READWRITE) || rctx->ws->buffer_is_busy(rtex->resource.buf, RADEON_USAGE_READWRITE))) { + /* Use a staging texture for uploads if the underlying BO is busy. */ use_staging_texture = TRUE; } @@ -1028,6 +1014,8 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx, r600_init_temp_resource_from_box(&resource, texture, box, level, R600_RESOURCE_FLAG_TRANSFER); + resource.usage = (usage & PIPE_TRANSFER_READ) ? + PIPE_USAGE_STAGING : PIPE_USAGE_STREAM; /* Create the temporary texture. */ staging = (struct r600_texture*)ctx->screen->resource_create(ctx->screen, &resource); @@ -1287,7 +1275,7 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx, /* Do the fast clear. */ evergreen_set_clear_color(tex, fb->cbufs[i]->format, color); rctx->clear_buffer(&rctx->b, &tex->cmask_buffer->b.b, - tex->cmask.offset, tex->cmask.size, 0); + tex->cmask.offset, tex->cmask.size, 0, true); tex->dirty_level_mask |= 1 << fb->cbufs[i]->u.tex.level; fb_state->dirty = true;