* Jerome Glisse
* Corbin Simpson
*/
+#include <errno.h>
#include <pipe/p_screen.h>
#include <util/u_format.h>
#include <util/u_math.h>
#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;
}
}
-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;
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;
{
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) {
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;
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);
}
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) ||
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);
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;
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 =
};
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 */
default:
break;
}
-
- word4 |= r600_get_swizzle_combined(desc->swizzle, swizzle_view);
/* S3TC formats. TODO */
if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
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;
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;
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;
}
}
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;
}
}
*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;
+}