X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fr600%2Fr600_texture.c;h=a5a94d4aee6e22db42b3eda4598e045fbd73773e;hb=62f44f670bb0162e89fd4786af877f8da9ff607c;hp=691cc48dea7c0d5d10a1b78fe1e7e6fa50b7d586;hpb=8f4ec55f77a993ec44db56726187bdd4f041880e;p=mesa.git diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 691cc48dea7..a5a94d4aee6 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -43,7 +43,7 @@ static void r600_copy_to_staging_texture(struct pipe_context *ctx, struct r600_t struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer; struct pipe_resource *texture = transfer->resource; - ctx->resource_copy_region(ctx, rtransfer->staging_texture, + ctx->resource_copy_region(ctx, &rtransfer->staging->b.b.b, 0, 0, 0, 0, texture, transfer->level, &transfer->box); } @@ -63,10 +63,8 @@ static void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600 sbox.depth = 1; ctx->resource_copy_region(ctx, texture, transfer->level, transfer->box.x, transfer->box.y, transfer->box.z, - rtransfer->staging_texture, + &rtransfer->staging->b.b.b, 0, &sbox); - - r600_flush(ctx, NULL, RADEON_FLUSH_ASYNC); } unsigned r600_texture_get_offset(struct r600_resource_texture *rtex, @@ -93,19 +91,19 @@ static unsigned r600_get_block_alignment(struct pipe_screen *screen, switch(array_mode) { case V_038000_ARRAY_1D_TILED_THIN1: p_align = MAX2(8, - ((rscreen->tiling_info->group_bytes / 8 / pixsize))); + ((rscreen->tiling_info.group_bytes / 8 / pixsize))); break; case V_038000_ARRAY_2D_TILED_THIN1: - p_align = MAX2(rscreen->tiling_info->num_banks, - (((rscreen->tiling_info->group_bytes / 8 / pixsize)) * - rscreen->tiling_info->num_banks)) * 8; + p_align = MAX2(rscreen->tiling_info.num_banks, + (((rscreen->tiling_info.group_bytes / 8 / pixsize)) * + rscreen->tiling_info.num_banks)) * 8; break; case V_038000_ARRAY_LINEAR_ALIGNED: - p_align = MAX2(64, rscreen->tiling_info->group_bytes / pixsize); + p_align = MAX2(64, rscreen->tiling_info.group_bytes / pixsize); break; case V_038000_ARRAY_LINEAR_GENERAL: default: - p_align = rscreen->tiling_info->group_bytes / pixsize; + p_align = rscreen->tiling_info.group_bytes / pixsize; break; } return p_align; @@ -119,7 +117,7 @@ static unsigned r600_get_height_alignment(struct pipe_screen *screen, switch (array_mode) { case V_038000_ARRAY_2D_TILED_THIN1: - h_align = rscreen->tiling_info->num_channels * 8; + h_align = rscreen->tiling_info.num_channels * 8; break; case V_038000_ARRAY_1D_TILED_THIN1: case V_038000_ARRAY_LINEAR_ALIGNED: @@ -145,14 +143,14 @@ static unsigned r600_get_base_alignment(struct pipe_screen *screen, switch (array_mode) { case V_038000_ARRAY_2D_TILED_THIN1: - b_align = MAX2(rscreen->tiling_info->num_banks * rscreen->tiling_info->num_channels * 8 * 8 * pixsize, + b_align = MAX2(rscreen->tiling_info.num_banks * rscreen->tiling_info.num_channels * 8 * 8 * pixsize, p_align * pixsize * h_align); break; case V_038000_ARRAY_1D_TILED_THIN1: case V_038000_ARRAY_LINEAR_ALIGNED: case V_038000_ARRAY_LINEAR_GENERAL: default: - b_align = rscreen->tiling_info->group_bytes; + b_align = rscreen->tiling_info.group_bytes; break; } return b_align; @@ -243,13 +241,137 @@ static void r600_texture_set_array_mode(struct pipe_screen *screen, } } +static int r600_init_surface(struct radeon_surface *surface, + const struct pipe_resource *ptex, + unsigned array_mode) +{ + surface->npix_x = ptex->width0; + surface->npix_y = ptex->height0; + surface->npix_z = ptex->depth0; + surface->blk_w = util_format_get_blockwidth(ptex->format); + surface->blk_h = util_format_get_blockheight(ptex->format); + surface->blk_d = 1; + surface->array_size = 1; + surface->last_level = ptex->last_level; + surface->bpe = util_format_get_blocksize(ptex->format); + /* align byte per element on dword */ + if (surface->bpe == 3) { + surface->bpe = 4; + } + surface->nsamples = 1; + surface->flags = 0; + switch (array_mode) { + case V_038000_ARRAY_1D_TILED_THIN1: + surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); + break; + case V_038000_ARRAY_2D_TILED_THIN1: + surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); + break; + case V_038000_ARRAY_LINEAR_ALIGNED: + surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE); + break; + case V_038000_ARRAY_LINEAR_GENERAL: + default: + surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE); + break; + } + switch (ptex->target) { + case PIPE_TEXTURE_1D: + surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE); + break; + case PIPE_TEXTURE_RECT: + case PIPE_TEXTURE_2D: + surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE); + break; + case PIPE_TEXTURE_3D: + surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE); + break; + case PIPE_TEXTURE_1D_ARRAY: + surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE); + surface->array_size = ptex->array_size; + break; + case PIPE_TEXTURE_2D_ARRAY: + surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE); + surface->array_size = ptex->array_size; + break; + case PIPE_TEXTURE_CUBE: + surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_CUBEMAP, TYPE); + break; + case PIPE_BUFFER: + default: + return -EINVAL; + } + if (ptex->bind & PIPE_BIND_SCANOUT) { + surface->flags |= RADEON_SURF_SCANOUT; + } + if (util_format_is_depth_and_stencil(ptex->format)) { + surface->flags |= RADEON_SURF_ZBUFFER; + surface->flags |= RADEON_SURF_SBUFFER; + } + + return 0; +} + +static int r600_setup_surface(struct pipe_screen *screen, + struct r600_resource_texture *rtex, + unsigned array_mode, + unsigned pitch_in_bytes_override) +{ + struct pipe_resource *ptex = &rtex->resource.b.b.b; + struct r600_screen *rscreen = (struct r600_screen*)screen; + unsigned i; + int r; + + if (util_format_is_depth_or_stencil(rtex->real_format)) { + rtex->surface.flags |= RADEON_SURF_ZBUFFER; + rtex->surface.flags |= RADEON_SURF_SBUFFER; + } + + r = rscreen->ws->surface_init(rscreen->ws, &rtex->surface); + if (r) { + return r; + } + rtex->size = rtex->surface.bo_size; + if (pitch_in_bytes_override && pitch_in_bytes_override != rtex->surface.level[0].pitch_bytes) { + /* old ddx on evergreen over estimate alignment for 1d, only 1 level + * for those + */ + rtex->surface.level[0].nblk_x = pitch_in_bytes_override / rtex->surface.bpe; + rtex->surface.level[0].pitch_bytes = pitch_in_bytes_override; + rtex->surface.level[0].slice_size = pitch_in_bytes_override * rtex->surface.level[0].nblk_y; + if (rtex->surface.flags & RADEON_SURF_SBUFFER) { + rtex->surface.stencil_offset = rtex->surface.level[0].slice_size; + } + } + for (i = 0; i <= ptex->last_level; i++) { + rtex->offset[i] = rtex->surface.level[i].offset; + rtex->layer_size[i] = rtex->surface.level[i].slice_size; + rtex->pitch_in_bytes[i] = rtex->surface.level[i].pitch_bytes; + switch (rtex->surface.level[i].mode) { + case RADEON_SURF_MODE_LINEAR_ALIGNED: + rtex->array_mode[i] = V_038000_ARRAY_LINEAR_ALIGNED; + break; + case RADEON_SURF_MODE_1D: + rtex->array_mode[i] = V_038000_ARRAY_1D_TILED_THIN1; + break; + case RADEON_SURF_MODE_2D: + rtex->array_mode[i] = V_038000_ARRAY_2D_TILED_THIN1; + break; + default: + case RADEON_SURF_MODE_LINEAR: + rtex->array_mode[i] = 0; + break; + } + } + return 0; +} + static void r600_setup_miptree(struct pipe_screen *screen, struct r600_resource_texture *rtex, unsigned array_mode) { struct pipe_resource *ptex = &rtex->resource.b.b.b; - struct radeon *radeon = ((struct r600_screen*)screen)->radeon; - enum chip_class chipc = r600_get_family_class(radeon); + enum chip_class chipc = ((struct r600_screen*)screen)->chip_class; unsigned size, layer_size, i, offset; unsigned nblocksx, nblocksy; @@ -307,7 +429,7 @@ static boolean permit_hardware_blit(struct pipe_screen *screen, /* hackaround for S3TC */ if (util_format_is_compressed(res->format)) return TRUE; - + if (!screen->is_format_supported(screen, res->format, res->target, @@ -338,10 +460,10 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen, { struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex; struct r600_resource *resource = &rtex->resource; - struct radeon *radeon = ((struct r600_screen*)screen)->radeon; + struct r600_screen *rscreen = (struct r600_screen*)screen; - return r600_bo_get_winsys_handle(radeon, resource->bo, - rtex->pitch_in_bytes[0], whandle); + return rscreen->ws->buffer_get_handle(resource->buf, + rtex->pitch_in_bytes[0], whandle); } static void r600_texture_destroy(struct pipe_screen *screen, @@ -353,9 +475,10 @@ static void r600_texture_destroy(struct pipe_screen *screen, if (rtex->flushed_depth_texture) pipe_resource_reference((struct pipe_resource **)&rtex->flushed_depth_texture, NULL); - if (resource->bo) { - r600_bo_reference(&resource->bo, NULL); - } + if (rtex->stencil) + pipe_resource_reference((struct pipe_resource **)&rtex->stencil, NULL); + + pb_reference(&resource->buf, NULL); FREE(rtex); } @@ -366,9 +489,9 @@ static const struct u_resource_vtbl r600_texture_vtbl = r600_texture_get_transfer, /* get_transfer */ r600_texture_transfer_destroy, /* transfer_destroy */ r600_texture_transfer_map, /* transfer_map */ - u_default_transfer_flush_region,/* transfer_flush_region */ + NULL, /* transfer_flush_region */ r600_texture_transfer_unmap, /* transfer_unmap */ - u_default_transfer_inline_write /* transfer_inline_write */ + NULL /* transfer_inline_write */ }; static struct r600_resource_texture * @@ -377,12 +500,14 @@ r600_texture_create_object(struct pipe_screen *screen, unsigned array_mode, unsigned pitch_in_bytes_override, unsigned max_buffer_size, - struct r600_bo *bo, - boolean alloc_bo) + struct pb_buffer *buf, + boolean alloc_bo, + struct radeon_surface *surface) { struct r600_resource_texture *rtex; struct r600_resource *resource; - struct radeon *radeon = ((struct r600_screen*)screen)->radeon; + struct r600_screen *rscreen = (struct r600_screen*)screen; + int r; rtex = CALLOC_STRUCT(r600_resource_texture); if (rtex == NULL) @@ -393,25 +518,25 @@ r600_texture_create_object(struct pipe_screen *screen, resource->b.b.vtbl = &r600_texture_vtbl; pipe_reference_init(&resource->b.b.b.reference, 1); resource->b.b.b.screen = screen; - resource->bo = bo; rtex->pitch_override = pitch_in_bytes_override; rtex->real_format = base->format; /* We must split depth and stencil into two separate buffers on Evergreen. */ if (!(base->flags & R600_RESOURCE_FLAG_TRANSFER) && - r600_get_family_class(((struct r600_screen*)screen)->radeon) >= EVERGREEN && - util_format_is_depth_and_stencil(base->format)) { + ((struct r600_screen*)screen)->chip_class >= EVERGREEN && + util_format_is_depth_and_stencil(base->format) && + !rscreen->use_surface_alloc) { struct pipe_resource stencil; unsigned stencil_pitch_override = 0; switch (base->format) { - case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + case PIPE_FORMAT_Z24_UNORM_S8_UINT: rtex->real_format = PIPE_FORMAT_Z24X8_UNORM; break; - case PIPE_FORMAT_S8_USCALED_Z24_UNORM: + case PIPE_FORMAT_S8_UINT_Z24_UNORM: rtex->real_format = PIPE_FORMAT_X8Z24_UNORM; break; - case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED: + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: rtex->real_format = PIPE_FORMAT_Z32_FLOAT; break; default: @@ -422,17 +547,17 @@ r600_texture_create_object(struct pipe_screen *screen, /* Divide the pitch in bytes by 4 for stencil, because it has a smaller pixel size. */ if (pitch_in_bytes_override) { - assert(base->format == PIPE_FORMAT_Z24_UNORM_S8_USCALED || - base->format == PIPE_FORMAT_S8_USCALED_Z24_UNORM); + assert(base->format == PIPE_FORMAT_Z24_UNORM_S8_UINT || + base->format == PIPE_FORMAT_S8_UINT_Z24_UNORM); stencil_pitch_override = pitch_in_bytes_override / 4; } /* Allocate the stencil buffer. */ stencil = *base; - stencil.format = PIPE_FORMAT_S8_USCALED; + stencil.format = PIPE_FORMAT_S8_UINT; rtex->stencil = r600_texture_create_object(screen, &stencil, array_mode, stencil_pitch_override, - max_buffer_size, NULL, FALSE); + max_buffer_size, NULL, FALSE, surface); if (!rtex->stencil) { FREE(rtex); return NULL; @@ -442,9 +567,17 @@ r600_texture_create_object(struct pipe_screen *screen, /* only mark depth textures the HW can hit as depth textures */ if (util_format_is_depth_or_stencil(rtex->real_format) && permit_hardware_blit(screen, base)) - rtex->depth = 1; + rtex->is_depth = true; r600_setup_miptree(screen, rtex, array_mode); + if (rscreen->use_surface_alloc) { + rtex->surface = *surface; + r = r600_setup_surface(screen, rtex, array_mode, pitch_in_bytes_override); + if (r) { + FREE(rtex); + return NULL; + } + } /* If we initialized separate stencil for Evergreen. place it after depth. */ if (rtex->stencil) { @@ -459,48 +592,65 @@ r600_texture_create_object(struct pipe_screen *screen, rtex->size = stencil_offset + rtex->stencil->size; } - resource->size = rtex->size; - /* Now create the backing buffer. */ - if (!resource->bo && alloc_bo) { + if (!buf && alloc_bo) { struct pipe_resource *ptex = &rtex->resource.b.b.b; unsigned base_align = r600_get_base_alignment(screen, ptex->format, array_mode); - resource->bo = r600_bo(radeon, rtex->size, base_align, base->bind, base->usage); - if (!resource->bo) { + if (rscreen->use_surface_alloc) { + base_align = rtex->surface.bo_alignment; + } else if (util_format_is_depth_or_stencil(rtex->real_format)) { + /* ugly work around depth buffer need stencil room at end of bo */ + rtex->size += ptex->width0 * ptex->height0; + } + if (!r600_init_resource(rscreen, resource, rtex->size, base_align, base->bind, base->usage)) { pipe_resource_reference((struct pipe_resource**)&rtex->stencil, NULL); FREE(rtex); return NULL; } + } else if (buf) { + resource->buf = buf; + resource->cs_buf = rscreen->ws->buffer_get_cs_handle(buf); + resource->domains = RADEON_DOMAIN_GTT | RADEON_DOMAIN_VRAM; } - if (rtex->stencil) - rtex->stencil->resource.bo = rtex->resource.bo; + if (rtex->stencil) { + pb_reference(&rtex->stencil->resource.buf, rtex->resource.buf); + rtex->stencil->resource.cs_buf = rtex->resource.cs_buf; + rtex->stencil->resource.domains = rtex->resource.domains; + } return rtex; } -DEBUG_GET_ONCE_BOOL_OPTION(tiling_enabled, "R600_TILING", FALSE); - struct pipe_resource *r600_texture_create(struct pipe_screen *screen, const struct pipe_resource *templ) { - struct radeon *radeon = ((struct r600_screen*)screen)->radeon; + struct r600_screen *rscreen = (struct r600_screen*)screen; + struct radeon_surface surface; unsigned array_mode = 0; + int r; if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) && !(templ->bind & PIPE_BIND_SCANOUT)) { - if (util_format_is_compressed(templ->format)) { + if (rscreen->use_surface_alloc) { + if (permit_hardware_blit(screen, templ)) { + array_mode = V_038000_ARRAY_2D_TILED_THIN1; + } + } else if (util_format_is_compressed(templ->format)) { array_mode = V_038000_ARRAY_1D_TILED_THIN1; } - else if (debug_get_option_tiling_enabled() && - r600_get_minor_version(radeon) >= 9 && - permit_hardware_blit(screen, templ)) { - array_mode = V_038000_ARRAY_2D_TILED_THIN1; - } } + r = r600_init_surface(&surface, templ, array_mode); + if (r) { + return NULL; + } + r = rscreen->ws->surface_best(rscreen->ws, &surface); + if (r) { + return NULL; + } return (struct pipe_resource *)r600_texture_create_object(screen, templ, array_mode, - 0, 0, NULL, TRUE); + 0, 0, NULL, TRUE, &surface); } static struct pipe_surface *r600_create_surface(struct pipe_context *pipe, @@ -540,28 +690,46 @@ static void r600_surface_destroy(struct pipe_context *pipe, FREE(surface); } - struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen, const struct pipe_resource *templ, struct winsys_handle *whandle) { - struct radeon *rw = ((struct r600_screen*)screen)->radeon; - struct r600_bo *bo = NULL; + struct r600_screen *rscreen = (struct r600_screen*)screen; + struct pb_buffer *buf = NULL; unsigned stride = 0; unsigned array_mode = 0; + enum radeon_bo_layout micro, macro; + struct radeon_surface surface; + int r; /* Support only 2D textures without mipmaps */ if ((templ->target != PIPE_TEXTURE_2D && templ->target != PIPE_TEXTURE_RECT) || templ->depth0 != 1 || templ->last_level != 0) return NULL; - bo = r600_bo_handle(rw, whandle, &stride, &array_mode); - if (bo == NULL) { + buf = rscreen->ws->buffer_from_handle(rscreen->ws, whandle, &stride); + if (!buf) return NULL; - } + rscreen->ws->buffer_get_tiling(buf, µ, ¯o, + &surface.bankw, &surface.bankh, + &surface.tile_split, + &surface.stencil_tile_split, + &surface.mtilea); + + if (macro == RADEON_LAYOUT_TILED) + array_mode = V_0280A0_ARRAY_2D_TILED_THIN1; + else if (micro == RADEON_LAYOUT_TILED) + array_mode = V_0280A0_ARRAY_1D_TILED_THIN1; + else + array_mode = 0; + + r = r600_init_surface(&surface, templ, array_mode); + if (r) { + return NULL; + } return (struct pipe_resource *)r600_texture_create_object(screen, templ, array_mode, - stride, 0, bo, FALSE); + stride, 0, buf, FALSE, &surface); } int r600_texture_depth_flush(struct pipe_context *ctx, @@ -573,19 +741,17 @@ int r600_texture_depth_flush(struct pipe_context *ctx, if (rtex->flushed_depth_texture) goto out; - resource.target = PIPE_TEXTURE_2D; + resource.target = texture->target; resource.format = texture->format; resource.width0 = texture->width0; resource.height0 = texture->height0; - resource.depth0 = 1; - resource.array_size = 1; + resource.depth0 = texture->depth0; + resource.array_size = texture->array_size; resource.last_level = texture->last_level; - resource.nr_samples = 0; + resource.nr_samples = texture->nr_samples; resource.usage = PIPE_USAGE_DYNAMIC; - resource.bind = 0; - resource.flags = R600_RESOURCE_FLAG_TRANSFER; - - resource.bind |= PIPE_BIND_DEPTH_STENCIL; + resource.bind = texture->bind | PIPE_BIND_DEPTH_STENCIL; + resource.flags = R600_RESOURCE_FLAG_TRANSFER | texture->flags; rtex->flushed_depth_texture = (struct r600_resource_texture *)ctx->screen->resource_create(ctx->screen, &resource); if (rtex->flushed_depth_texture == NULL) { @@ -617,6 +783,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, unsigned usage, const struct pipe_box *box) { + struct r600_context *rctx = (struct r600_context*)ctx; struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture; struct pipe_resource resource; struct r600_transfer *trans; @@ -636,15 +803,10 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, if ((usage & PIPE_TRANSFER_READ) && u_box_volume(box) > 1024) use_staging_texture = TRUE; - /* XXX: Use a staging texture for uploads if the underlying BO - * is busy. No interface for checking that currently? so do - * it eagerly whenever the transfer doesn't require a readback - * and might block. - */ - if ((usage & PIPE_TRANSFER_WRITE) && - !(usage & (PIPE_TRANSFER_READ | - PIPE_TRANSFER_DONTBLOCK | - PIPE_TRANSFER_UNSYNCHRONIZED))) + /* Use a staging texture for uploads if the underlying BO is busy. */ + if (!(usage & PIPE_TRANSFER_READ) && + (rctx->ws->cs_is_buffer_referenced(rctx->cs, rtex->resource.cs_buf) || + rctx->ws->buffer_is_busy(rtex->resource.buf, RADEON_USAGE_READWRITE))) use_staging_texture = TRUE; if (!permit_hardware_blit(ctx->screen, texture) || @@ -661,7 +823,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, trans->transfer.level = level; trans->transfer.usage = usage; trans->transfer.box = *box; - if (rtex->depth) { + if (rtex->is_depth) { /* XXX: only readback the rectangle which is being mapped? */ /* XXX: when discard is true, no need to read back from depth texture @@ -699,8 +861,8 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, resource.bind |= PIPE_BIND_SAMPLER_VIEW; } /* Create the temporary texture. */ - trans->staging_texture = ctx->screen->resource_create(ctx->screen, &resource); - if (trans->staging_texture == NULL) { + trans->staging = (struct r600_resource*)ctx->screen->resource_create(ctx->screen, &resource); + if (trans->staging == NULL) { R600_ERR("failed to create temporary texture to hold untiled copy\n"); pipe_resource_reference(&trans->transfer.resource, NULL); FREE(trans); @@ -708,7 +870,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, } trans->transfer.stride = - ((struct r600_resource_texture *)trans->staging_texture)->pitch_in_bytes[0]; + ((struct r600_resource_texture *)trans->staging)->pitch_in_bytes[0]; if (usage & PIPE_TRANSFER_READ) { r600_copy_to_staging_texture(ctx, trans); /* Always referenced in the blit. */ @@ -729,14 +891,14 @@ void r600_texture_transfer_destroy(struct pipe_context *ctx, struct pipe_resource *texture = transfer->resource; struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture; - if (rtransfer->staging_texture) { + if (rtransfer->staging) { if (transfer->usage & PIPE_TRANSFER_WRITE) { r600_copy_from_staging_texture(ctx, rtransfer); } - pipe_resource_reference(&rtransfer->staging_texture, NULL); + pipe_resource_reference((struct pipe_resource**)&rtransfer->staging, NULL); } - if (rtex->depth && !rtex->is_flushing_texture) { + if (rtex->is_depth && !rtex->is_flushing_texture) { if ((transfer->usage & PIPE_TRANSFER_WRITE) && rtex->flushed_depth_texture) r600_blit_push_depth(ctx, rtex); } @@ -748,30 +910,29 @@ void r600_texture_transfer_destroy(struct pipe_context *ctx, void* r600_texture_transfer_map(struct pipe_context *ctx, struct pipe_transfer* transfer) { - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + struct r600_context *rctx = (struct r600_context *)ctx; struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; - struct r600_bo *bo; + struct pb_buffer *buf; enum pipe_format format = transfer->resource->format; - struct radeon *radeon = rctx->screen->radeon; unsigned offset = 0; char *map; - if (rtransfer->staging_texture) { - bo = ((struct r600_resource *)rtransfer->staging_texture)->bo; + if (rtransfer->staging) { + buf = ((struct r600_resource *)rtransfer->staging)->buf; } else { struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource; if (rtex->flushed_depth_texture) - bo = ((struct r600_resource *)rtex->flushed_depth_texture)->bo; + buf = ((struct r600_resource *)rtex->flushed_depth_texture)->buf; else - bo = ((struct r600_resource *)transfer->resource)->bo; + buf = ((struct r600_resource *)transfer->resource)->buf; offset = rtransfer->offset + transfer->box.y / util_format_get_blockheight(format) * transfer->stride + transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); } - if (!(map = r600_bo_map(radeon, bo, rctx->ctx.cs, transfer->usage))) { + if (!(map = rctx->ws->buffer_map(buf, rctx->cs, transfer->usage))) { return NULL; } @@ -782,24 +943,24 @@ void r600_texture_transfer_unmap(struct pipe_context *ctx, struct pipe_transfer* transfer) { struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; - struct radeon *radeon = ((struct r600_screen*)ctx->screen)->radeon; - struct r600_bo *bo; + struct r600_context *rctx = (struct r600_context*)ctx; + struct pb_buffer *buf; - if (rtransfer->staging_texture) { - bo = ((struct r600_resource *)rtransfer->staging_texture)->bo; + if (rtransfer->staging) { + buf = ((struct r600_resource *)rtransfer->staging)->buf; } else { struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource; if (rtex->flushed_depth_texture) { - bo = ((struct r600_resource *)rtex->flushed_depth_texture)->bo; + buf = ((struct r600_resource *)rtex->flushed_depth_texture)->buf; } else { - bo = ((struct r600_resource *)transfer->resource)->bo; + buf = ((struct r600_resource *)transfer->resource)->buf; } } - r600_bo_unmap(radeon, bo); + rctx->ws->buffer_unmap(buf); } -void r600_init_surface_functions(struct r600_pipe_context *r600) +void r600_init_surface_functions(struct r600_context *r600) { r600->context.create_surface = r600_create_surface; r600->context.surface_destroy = r600_surface_destroy; @@ -859,6 +1020,7 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen, const struct util_format_description *desc; boolean uniform = TRUE; static int r600_enable_s3tc = -1; + bool is_srgb_valid = FALSE; int i; const uint32_t sign_bit[4] = { @@ -879,26 +1041,26 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen, case PIPE_FORMAT_Z16_UNORM: result = FMT_16; goto out_word4; - case PIPE_FORMAT_X24S8_USCALED: + case PIPE_FORMAT_X24S8_UINT: word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + case PIPE_FORMAT_Z24_UNORM_S8_UINT: result = FMT_8_24; goto out_word4; - case PIPE_FORMAT_S8X24_USCALED: + case PIPE_FORMAT_S8X24_UINT: word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); case PIPE_FORMAT_X8Z24_UNORM: - case PIPE_FORMAT_S8_USCALED_Z24_UNORM: + case PIPE_FORMAT_S8_UINT_Z24_UNORM: result = FMT_24_8; goto out_word4; - case PIPE_FORMAT_S8_USCALED: + case PIPE_FORMAT_S8_UINT: result = FMT_8; word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); goto out_word4; case PIPE_FORMAT_Z32_FLOAT: result = FMT_32_FLOAT; goto out_word4; - case PIPE_FORMAT_Z32_FLOAT_S8X24_USCALED: + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: result = FMT_X24_8_32_FLOAT; goto out_word4; default: @@ -925,7 +1087,7 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen, if (r600_enable_s3tc == -1) { struct r600_screen *rscreen = (struct r600_screen *)screen; - if (r600_get_minor_version(rscreen->radeon) >= 9) + if (rscreen->info.drm_minor >= 9) r600_enable_s3tc = 1; else r600_enable_s3tc = debug_get_bool_option("R600_ENABLE_S3TC", FALSE); @@ -970,14 +1132,17 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen, case PIPE_FORMAT_DXT1_SRGB: case PIPE_FORMAT_DXT1_SRGBA: result = FMT_BC1; + is_srgb_valid = TRUE; goto out_word4; case PIPE_FORMAT_DXT3_RGBA: case PIPE_FORMAT_DXT3_SRGBA: result = FMT_BC2; + is_srgb_valid = TRUE; goto out_word4; case PIPE_FORMAT_DXT5_RGBA: case PIPE_FORMAT_DXT5_SRGBA: result = FMT_BC3; + is_srgb_valid = TRUE; goto out_word4; default: goto out_unknown; @@ -1008,6 +1173,9 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen, /* Non-uniform formats. */ if (!uniform) { + if (desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB && + desc->channel[0].pure_integer) + word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); switch(desc->nr_channels) { case 3: if (desc->channel[0].size == 5 && @@ -1051,10 +1219,15 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen, switch (desc->channel[i].type) { case UTIL_FORMAT_TYPE_UNSIGNED: case UTIL_FORMAT_TYPE_SIGNED: +#if 0 if (!desc->channel[i].normalized && desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) { goto out_unknown; } +#endif + if (desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB && + desc->channel[i].pure_integer) + word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); switch (desc->channel[i].size) { case 4: @@ -1077,6 +1250,7 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen, goto out_word4; case 4: result = FMT_8_8_8_8; + is_srgb_valid = TRUE; goto out_word4; } goto out_unknown; @@ -1140,6 +1314,9 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen, } out_word4: + + if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB && !is_srgb_valid) + return ~0; if (word4_p) *word4_p = word4; if (yuv_format_p)