X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fr600%2Fr600_texture.c;h=efc5f820659e628ab8549092ef21a846e870c567;hb=7c1fcc41be15b6d648f84c8c1870a3a00575a48f;hp=92b4f430c57ef0465d6ccaaa68469354d3c724eb;hpb=36efb86c0570d86d8dfce87fd2416125e0e91b40;p=mesa.git diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 92b4f430c57..efc5f820659 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -24,6 +24,7 @@ * Jerome Glisse * Corbin Simpson */ +#include #include #include #include @@ -33,6 +34,7 @@ #include "r600_screen.h" #include "r600_context.h" #include "r600_resource.h" +#include "r600_state_inlines.h" #include "r600d.h" extern struct u_resource_vtbl r600_texture_vtbl; @@ -71,7 +73,7 @@ static unsigned long r600_texture_get_offset(struct r600_resource_texture *rtex, } } -static void r600_setup_miptree(struct r600_screen *rscreen, struct r600_resource_texture *rtex) +static void r600_setup_miptree(struct r600_resource_texture *rtex) { struct pipe_resource *ptex = &rtex->resource.base.b; unsigned long w, h, pitch, size, layer_size, i, offset; @@ -91,6 +93,8 @@ static void r600_setup_miptree(struct r600_screen *rscreen, struct r600_resource rtex->offset[i] = offset; rtex->layer_size[i] = layer_size; rtex->pitch[i] = pitch; + rtex->width[i] = w; + rtex->height[i] = h; offset += size; } rtex->size = offset; @@ -101,7 +105,7 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen, { struct r600_resource_texture *rtex; struct r600_resource *resource; - struct r600_screen *rscreen = r600_screen(screen); + struct radeon *radeon = (struct radeon *)screen->winsys; rtex = CALLOC_STRUCT(r600_resource_texture); if (!rtex) { @@ -112,11 +116,12 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen, resource->base.vtbl = &r600_texture_vtbl; pipe_reference_init(&resource->base.b.reference, 1); resource->base.b.screen = screen; - r600_setup_miptree(rscreen, rtex); + r600_setup_miptree(rtex); /* FIXME alignment 4096 enought ? too much ? */ resource->domain = r600_domain_from_usage(resource->base.b.bind); - resource->bo = radeon_bo(rscreen->rw, 0, rtex->size, 4096, NULL); + resource->size = rtex->size; + resource->bo = radeon_ws_bo(radeon, rtex->size, 4096, 0); if (resource->bo == NULL) { FREE(rtex); return NULL; @@ -124,16 +129,33 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen, return &resource->base.b; } +static void r600_texture_destroy_state(struct pipe_resource *ptexture) +{ + struct r600_resource_texture *rtexture = (struct r600_resource_texture*)ptexture; + + for (int i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++) { + radeon_state_fini(&rtexture->scissor[i]); + radeon_state_fini(&rtexture->db[i]); + for (int j = 0; j < 8; j++) { + radeon_state_fini(&rtexture->cb[j][i]); + } + } +} + static void r600_texture_destroy(struct pipe_screen *screen, struct pipe_resource *ptex) { struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex; struct r600_resource *resource = &rtex->resource; - struct r600_screen *rscreen = r600_screen(screen); + struct radeon *radeon = (struct radeon *)screen->winsys; if (resource->bo) { - radeon_bo_decref(rscreen->rw, resource->bo); + radeon_ws_bo_reference(radeon, &resource->bo, NULL); + } + if (rtex->uncompressed) { + radeon_ws_bo_reference(radeon, &rtex->uncompressed, NULL); } + r600_texture_destroy_state(ptex); FREE(rtex); } @@ -176,12 +198,7 @@ struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen, struct radeon *rw = (struct radeon*)screen->winsys; struct r600_resource_texture *rtex; struct r600_resource *resource; - struct radeon_bo *bo = NULL; - - bo = radeon_bo(rw, whandle->handle, 0, 0, NULL); - if (bo == NULL) { - return NULL; - } + struct radeon_ws_bo *bo = NULL; /* Support only 2D textures without mipmaps */ if ((templ->target != PIPE_TEXTURE_2D && templ->target != PIPE_TEXTURE_RECT) || @@ -192,15 +209,24 @@ struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen, if (rtex == NULL) return NULL; + bo = radeon_ws_bo_handle(rw, whandle->handle); + if (bo == NULL) { + FREE(rtex); + return NULL; + } + resource = &rtex->resource; resource->base.b = *templ; resource->base.vtbl = &r600_texture_vtbl; pipe_reference_init(&resource->base.b.reference, 1); resource->base.b.screen = screen; resource->bo = bo; + rtex->depth = 0; rtex->pitch_override = whandle->stride; rtex->bpt = util_format_get_blocksize(templ->format); rtex->pitch[0] = whandle->stride; + rtex->width[0] = templ->width0; + rtex->height[0] = templ->height0; rtex->offset[0] = 0; rtex->size = align(rtex->pitch[0] * templ->height0, 64); @@ -234,7 +260,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, trans->transfer.box = *box; trans->transfer.stride = rtex->pitch[sr.level]; trans->offset = r600_texture_get_offset(rtex, sr.level, box->z, sr.face); - if (rtex->tilled) { + if (rtex->tilled && !rtex->depth) { resource.target = PIPE_TEXTURE_2D; resource.format = texture->format; resource.width0 = box->width; @@ -289,46 +315,63 @@ void r600_texture_transfer_destroy(struct pipe_context *ctx, void* r600_texture_transfer_map(struct pipe_context *ctx, struct pipe_transfer* transfer) { + struct r600_screen *rscreen = r600_screen(ctx->screen); struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; - struct r600_resource *resource; + struct radeon_ws_bo *bo; enum pipe_format format = transfer->resource->format; - struct r600_screen *rscreen = r600_screen(ctx->screen); + struct radeon *radeon = (struct radeon *)ctx->screen->winsys; + struct r600_resource_texture *rtex; + unsigned long offset = 0; char *map; + int r; r600_flush(ctx, 0, NULL); if (rtransfer->linear_texture) { - resource = (struct r600_resource *)rtransfer->linear_texture; + bo = ((struct r600_resource *)rtransfer->linear_texture)->bo; } else { - resource = (struct r600_resource *)transfer->resource; + rtex = (struct r600_resource_texture*)transfer->resource; + if (rtex->depth && rscreen->chip_class != EVERGREEN) { + r = r600_texture_from_depth(ctx, rtex, transfer->sr.level); + if (r) { + return NULL; + } + r600_flush(ctx, 0, NULL); + bo = rtex->uncompressed; + } else { + bo = ((struct r600_resource *)transfer->resource)->bo; + } + 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 (radeon_bo_map(rscreen->rw, resource->bo)) { + map = radeon_ws_bo_map(radeon, bo, 0, r600_context(ctx)); + if (!map) { return NULL; } - radeon_bo_wait(rscreen->rw, resource->bo); + radeon_ws_bo_wait(radeon, bo); - map = resource->bo->data; - if (rtransfer->linear_texture) { - return map; - } - - return map + 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); + return map + offset; } void r600_texture_transfer_unmap(struct pipe_context *ctx, struct pipe_transfer* transfer) { struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; - struct r600_screen *rscreen = r600_screen(ctx->screen); - struct r600_resource *resource; + struct radeon *radeon = (struct radeon *)ctx->screen->winsys; + struct r600_resource_texture *rtex; + struct radeon_ws_bo *bo; if (rtransfer->linear_texture) { - resource = (struct r600_resource *)rtransfer->linear_texture; + bo = ((struct r600_resource *)rtransfer->linear_texture)->bo; } else { - resource = (struct r600_resource *)transfer->resource; + rtex = (struct r600_resource_texture*)transfer->resource; + if (rtex->depth) { + bo = rtex->uncompressed; + } else { + bo = ((struct r600_resource *)transfer->resource)->bo; + } } - radeon_bo_unmap(rscreen->rw, resource->bo); + radeon_ws_bo_unmap(radeon, bo); } struct u_resource_vtbl r600_texture_vtbl = @@ -415,6 +458,8 @@ uint32_t r600_translate_texformat(enum pipe_format format, }; desc = util_format_description(format); + word4 |= r600_get_swizzle_combined(desc->swizzle, swizzle_view); + /* Colorspace (return non-RGB formats directly). */ switch (desc->colorspace) { /* Depth stencil formats */ @@ -452,8 +497,6 @@ uint32_t r600_translate_texformat(enum pipe_format format, default: break; } - - word4 |= r600_get_swizzle_combined(desc->swizzle, swizzle_view); /* S3TC formats. TODO */ if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { @@ -483,7 +526,7 @@ uint32_t r600_translate_texformat(enum pipe_format format, if (desc->channel[0].size == 5 && desc->channel[1].size == 6 && desc->channel[2].size == 5) { - result |= V_0280A0_COLOR_5_6_5; + result = V_0280A0_COLOR_5_6_5; goto out_word4; } goto out_unknown; @@ -492,14 +535,14 @@ uint32_t r600_translate_texformat(enum pipe_format format, desc->channel[1].size == 5 && desc->channel[2].size == 5 && desc->channel[3].size == 1) { - result |= V_0280A0_COLOR_1_5_5_5; + result = V_0280A0_COLOR_1_5_5_5; goto out_word4; } if (desc->channel[0].size == 10 && desc->channel[1].size == 10 && desc->channel[2].size == 10 && desc->channel[3].size == 2) { - result |= V_0280A0_COLOR_10_10_10_2; + result = V_0280A0_COLOR_10_10_10_2; goto out_word4; } goto out_unknown; @@ -520,36 +563,36 @@ uint32_t r600_translate_texformat(enum pipe_format format, case 4: switch (desc->nr_channels) { case 2: - result |= V_0280A0_COLOR_4_4; + result = V_0280A0_COLOR_4_4; goto out_word4; case 4: - result |= V_0280A0_COLOR_4_4_4_4; + result = V_0280A0_COLOR_4_4_4_4; goto out_word4; } goto out_unknown; case 8: switch (desc->nr_channels) { case 1: - result |= V_0280A0_COLOR_8; + result = V_0280A0_COLOR_8; goto out_word4; case 2: - result |= V_0280A0_COLOR_8_8; + result = V_0280A0_COLOR_8_8; goto out_word4; case 4: - result |= V_0280A0_COLOR_8_8_8_8; + result = V_0280A0_COLOR_8_8_8_8; goto out_word4; } goto out_unknown; case 16: switch (desc->nr_channels) { case 1: - result |= V_0280A0_COLOR_16; + result = V_0280A0_COLOR_16; goto out_word4; case 2: - result |= V_0280A0_COLOR_16_16; + result = V_0280A0_COLOR_16_16; goto out_word4; case 4: - result |= V_0280A0_COLOR_16_16_16_16; + result = V_0280A0_COLOR_16_16_16_16; goto out_word4; } } @@ -560,26 +603,26 @@ uint32_t r600_translate_texformat(enum pipe_format format, case 16: switch (desc->nr_channels) { case 1: - result |= V_0280A0_COLOR_16_FLOAT; + result = V_0280A0_COLOR_16_FLOAT; goto out_word4; case 2: - result |= V_0280A0_COLOR_16_16_FLOAT; + result = V_0280A0_COLOR_16_16_FLOAT; goto out_word4; case 4: - result |= V_0280A0_COLOR_16_16_16_16_FLOAT; + result = V_0280A0_COLOR_16_16_16_16_FLOAT; goto out_word4; } goto out_unknown; case 32: switch (desc->nr_channels) { case 1: - result |= V_0280A0_COLOR_32_FLOAT; + result = V_0280A0_COLOR_32_FLOAT; goto out_word4; case 2: - result |= V_0280A0_COLOR_32_32_FLOAT; + result = V_0280A0_COLOR_32_32_FLOAT; goto out_word4; case 4: - result |= V_0280A0_COLOR_32_32_32_32_FLOAT; + result = V_0280A0_COLOR_32_32_32_32_FLOAT; goto out_word4; } } @@ -592,6 +635,84 @@ out_word4: *yuv_format_p = yuv_format; return result; out_unknown: - R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format)); +// R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format)); return ~0; } + +int r600_texture_from_depth(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level) +{ + struct r600_screen *rscreen = r600_screen(ctx->screen); + int r; + + if (!rtexture->depth) { + /* This shouldn't happen maybe print a warning */ + return 0; + } + if (rtexture->uncompressed && !rtexture->dirty) { + /* Uncompressed bo already in good state */ + return 0; + } + + /* allocate uncompressed texture */ + if (rtexture->uncompressed == NULL) { + rtexture->uncompressed = radeon_ws_bo(rscreen->rw, rtexture->size, 4096, 0); + if (rtexture->uncompressed == NULL) { + return -ENOMEM; + } + } + + /* render a rectangle covering whole buffer to uncompress depth */ + r = r600_blit_uncompress_depth(ctx, rtexture, level); + if (r) { + return r; + } + + rtexture->dirty = 0; + return 0; +} + + + +int r600_texture_scissor(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level) +{ + struct r600_screen *rscreen = r600_screen(ctx->screen); + struct r600_context *rctx = r600_context(ctx); + + if (!rtexture->scissor[level].cpm4) { + rctx->vtbl->texture_state_scissor(rscreen, rtexture, level); + } + return 0; +} + +int r600_texture_cb(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned cb, unsigned level) +{ + struct r600_screen *rscreen = r600_screen(ctx->screen); + struct r600_context *rctx = r600_context(ctx); + + if (!rtexture->cb[cb][level].cpm4) { + rctx->vtbl->texture_state_cb(rscreen, rtexture, cb, level); + } + return 0; +} + +int r600_texture_db(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level) +{ + struct r600_screen *rscreen = r600_screen(ctx->screen); + struct r600_context *rctx = r600_context(ctx); + + if (!rtexture->db[level].cpm4) { + rctx->vtbl->texture_state_db(rscreen, rtexture, level); + } + return 0; +} + +int r600_texture_viewport(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level) +{ + struct r600_screen *rscreen = r600_screen(ctx->screen); + struct r600_context *rctx = r600_context(ctx); + + if (!rtexture->viewport[level].cpm4) { + rctx->vtbl->texture_state_viewport(rscreen, rtexture, level); + } + return 0; +}