summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/r600/r600_blit.c27
-rw-r--r--src/gallium/drivers/r600/r600_context.c8
-rw-r--r--src/gallium/drivers/r600/r600_resource.h3
-rw-r--r--src/gallium/drivers/r600/r600_screen.h1
-rw-r--r--src/gallium/drivers/r600/r600_shader.c6
-rw-r--r--src/gallium/drivers/r600/r600_state.c7
-rw-r--r--src/gallium/drivers/r600/r600_texture.c179
7 files changed, 165 insertions, 66 deletions
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
index aef4fbd9af9..dc57b333a03 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -120,7 +120,8 @@ static void r600_clear_depth_stencil(struct pipe_context *ctx,
r600_queries_resume(ctx);
}
-static void r600_resource_copy_region(struct pipe_context *pipe,
+
+static void r600_resource_copy_region(struct pipe_context *ctx,
struct pipe_resource *dst,
struct pipe_subresource subdst,
unsigned dstx, unsigned dsty, unsigned dstz,
@@ -129,8 +130,28 @@ static void r600_resource_copy_region(struct pipe_context *pipe,
unsigned srcx, unsigned srcy, unsigned srcz,
unsigned width, unsigned height)
{
- util_resource_copy_region(pipe, dst, subdst, dstx, dsty, dstz,
- src, subsrc, srcx, srcy, srcz, width, height);
+ struct r600_context *rctx = r600_context(ctx);
+ struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer;
+ struct pipe_sampler_state *samplers[PIPE_MAX_ATTRIBS];
+ struct pipe_sampler_view_state *sampler_views[PIPE_MAX_ATTRIBS];
+ unsigned i;
+
+ for (i = 0; i < rctx->ps_nsampler_view; i++) {
+ sampler_views[i] = &rctx->ps_sampler_view[i]->state.sampler_view;
+ }
+ for (i = 0; i < rctx->ps_nsampler; i++) {
+ samplers[i] = &rctx->ps_sampler[i]->state.sampler;
+ }
+ r600_blitter_save_states(ctx);
+ util_blitter_save_framebuffer(rctx->blitter, fb);
+ util_blitter_save_fragment_sampler_states(rctx->blitter, rctx->ps_nsampler, samplers);
+ util_blitter_save_fragment_sampler_views(rctx->blitter, rctx->ps_nsampler_view, sampler_views);
+
+ util_blitter_copy_region(rctx->blitter, dst, subdst, dstx, dsty, dstz,
+ src, subsrc, srcx, srcy, srcz, width, height,
+ TRUE);
+ /* resume queries */
+ r600_queries_resume(ctx);
}
void r600_init_blit_functions(struct r600_context *rctx)
diff --git a/src/gallium/drivers/r600/r600_context.c b/src/gallium/drivers/r600/r600_context.c
index 2f59a550f56..9af28356c5c 100644
--- a/src/gallium/drivers/r600/r600_context.c
+++ b/src/gallium/drivers/r600/r600_context.c
@@ -52,7 +52,7 @@ void r600_flush(struct pipe_context *ctx, unsigned flags,
char dname[256];
/* suspend queries */
- r600_queries_suspend(rctx);
+ r600_queries_suspend(ctx);
if (radeon_ctx_pm4(rctx->ctx))
goto out;
/* FIXME dumping should be removed once shader support instructions
@@ -61,8 +61,10 @@ void r600_flush(struct pipe_context *ctx, unsigned flags,
if (!rctx->ctx->cpm4)
goto out;
sprintf(dname, "gallium-%08d.bof", dc);
- if (dc < 10)
+ if (dc < 2) {
radeon_ctx_dump_bof(rctx->ctx, dname);
+ R600_ERR("dumped %s\n", dname);
+ }
#if 1
radeon_ctx_submit(rctx->ctx);
#endif
@@ -74,7 +76,7 @@ out:
rctx->ctx = radeon_ctx_decref(rctx->ctx);
rctx->ctx = radeon_ctx(rscreen->rw);
/* resume queries */
- r600_queries_resume(rctx);
+ r600_queries_resume(ctx);
}
static void r600_init_config(struct r600_context *rctx)
diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h
index bb90e76fb78..5ebda027e91 100644
--- a/src/gallium/drivers/r600/r600_resource.h
+++ b/src/gallium/drivers/r600/r600_resource.h
@@ -48,6 +48,9 @@ struct r600_resource_texture {
unsigned long pitch_override;
unsigned long bpt;
unsigned long size;
+ unsigned tilled;
+ unsigned array_mode;
+ unsigned tile_type;
};
void r600_init_context_resource_functions(struct r600_context *r600);
diff --git a/src/gallium/drivers/r600/r600_screen.h b/src/gallium/drivers/r600/r600_screen.h
index 53b560c617f..147be3c4ac0 100644
--- a/src/gallium/drivers/r600/r600_screen.h
+++ b/src/gallium/drivers/r600/r600_screen.h
@@ -38,6 +38,7 @@ struct r600_transfer {
/* Buffer transfer. */
struct pipe_transfer *buffer_transfer;
unsigned offset;
+ struct pipe_resource *linear_texture;
};
struct r600_screen {
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index da1af6702c3..79fc04a9fe3 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -105,8 +105,8 @@ int r600_pipe_shader_create(struct pipe_context *ctx,
struct r600_screen *rscreen = r600_screen(ctx->screen);
int r;
-fprintf(stderr, "--------------------------------------------------------------\n");
-tgsi_dump(tokens, 0);
+//fprintf(stderr, "--------------------------------------------------------------\n");
+//tgsi_dump(tokens, 0);
if (rpshader == NULL)
return -ENOMEM;
rpshader->shader.family = radeon_get_family(rscreen->rw);
@@ -120,7 +120,7 @@ tgsi_dump(tokens, 0);
R600_ERR("building bytecode failed !\n");
return r;
}
-fprintf(stderr, "______________________________________________________________\n");
+//fprintf(stderr, "______________________________________________________________\n");
return 0;
}
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 93fc68e42ef..e9b03f571ad 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -773,6 +773,9 @@ static struct radeon_state *r600_db(struct r600_context *rctx)
return NULL;
rtex = (struct r600_resource_texture*)state->zsbuf->texture;
+ rtex->tilled = 1;
+ rtex->array_mode = 2;
+ rtex->tile_type = 1;
rbuffer = &rtex->resource;
rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
rstate->nbo = 1;
@@ -1258,7 +1261,9 @@ static struct radeon_state *r600_resource(struct r600_context *rctx,
/* FIXME properly handle first level != 0 */
rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD0] =
S_038000_DIM(r600_tex_dim(view->texture->target)) |
- S_038000_PITCH((pitch / 8) - 1) |
+ S_038000_TILE_MODE(tmp->array_mode) |
+ S_038000_TILE_TYPE(tmp->tile_type) |
+ S_038000_PITCH((pitch / 8) - 1) |
S_038000_TEX_WIDTH(view->texture->width0 - 1);
rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD1] =
S_038004_TEX_HEIGHT(view->texture->height0 - 1) |
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index 8a6b5f87648..92b4f430c57 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -37,6 +37,21 @@
extern struct u_resource_vtbl r600_texture_vtbl;
+/* Copy from a tiled texture to a detiled one. */
+static void r600_copy_from_tiled_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer)
+{
+ struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer;
+ struct pipe_resource *texture = transfer->resource;
+ struct pipe_subresource subdst;
+
+ subdst.face = 0;
+ subdst.level = 0;
+ ctx->resource_copy_region(ctx, rtransfer->linear_texture,
+ subdst, 0, 0, 0, texture, transfer->sr,
+ transfer->box.x, transfer->box.y, transfer->box.z,
+ transfer->box.width, transfer->box.height);
+}
+
static unsigned long r600_texture_get_offset(struct r600_resource_texture *rtex,
unsigned level, unsigned zslice,
unsigned face)
@@ -106,7 +121,6 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
FREE(rtex);
return NULL;
}
-
return &resource->base.b;
}
@@ -208,6 +222,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
const struct pipe_box *box)
{
struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
+ struct pipe_resource resource;
struct r600_transfer *trans;
trans = CALLOC_STRUCT(r600_transfer);
@@ -219,14 +234,56 @@ 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) {
+ resource.target = PIPE_TEXTURE_2D;
+ resource.format = texture->format;
+ resource.width0 = box->width;
+ resource.height0 = box->height;
+ resource.depth0 = 0;
+ resource.last_level = 0;
+ resource.nr_samples = 0;
+ resource.usage = PIPE_USAGE_DYNAMIC;
+ resource.bind = 0;
+ resource.flags = 0;
+ /* For texture reading, the temporary (detiled) texture is used as
+ * a render target when blitting from a tiled texture. */
+ if (usage & PIPE_TRANSFER_READ) {
+ resource.bind |= PIPE_BIND_RENDER_TARGET;
+ }
+ /* For texture writing, the temporary texture is used as a sampler
+ * when blitting into a tiled texture. */
+ if (usage & PIPE_TRANSFER_WRITE) {
+ resource.bind |= PIPE_BIND_SAMPLER_VIEW;
+ }
+ /* Create the temporary texture. */
+ trans->linear_texture = ctx->screen->resource_create(ctx->screen, &resource);
+ if (trans->linear_texture == NULL) {
+ R600_ERR("failed to create temporary texture to hold untiled copy\n");
+ pipe_resource_reference(&trans->transfer.resource, NULL);
+ FREE(trans);
+ return NULL;
+ }
+ if (usage & PIPE_TRANSFER_READ) {
+ /* We cannot map a tiled texture directly because the data is
+ * in a different order, therefore we do detiling using a blit. */
+ r600_copy_from_tiled_texture(ctx, trans);
+ /* Always referenced in the blit. */
+ ctx->flush(ctx, 0, NULL);
+ }
+ }
return &trans->transfer;
}
void r600_texture_transfer_destroy(struct pipe_context *ctx,
- struct pipe_transfer *trans)
+ struct pipe_transfer *transfer)
{
- pipe_resource_reference(&trans->resource, NULL);
- FREE(trans);
+ struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
+
+ if (rtransfer->linear_texture) {
+ pipe_resource_reference(&rtransfer->linear_texture, NULL);
+ }
+ pipe_resource_reference(&transfer->resource, NULL);
+ FREE(transfer);
}
void* r600_texture_transfer_map(struct pipe_context *ctx,
@@ -239,14 +296,20 @@ void* r600_texture_transfer_map(struct pipe_context *ctx,
char *map;
r600_flush(ctx, 0, NULL);
-
- resource = (struct r600_resource *)transfer->resource;
+ if (rtransfer->linear_texture) {
+ resource = (struct r600_resource *)rtransfer->linear_texture;
+ } else {
+ resource = (struct r600_resource *)transfer->resource;
+ }
if (radeon_bo_map(rscreen->rw, resource->bo)) {
return NULL;
}
radeon_bo_wait(rscreen->rw, resource->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 +
@@ -256,10 +319,15 @@ void* r600_texture_transfer_map(struct pipe_context *ctx,
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;
- resource = (struct r600_resource *)transfer->resource;
+ if (rtransfer->linear_texture) {
+ resource = (struct r600_resource *)rtransfer->linear_texture;
+ } else {
+ resource = (struct r600_resource *)transfer->resource;
+ }
radeon_bo_unmap(rscreen->rw, resource->bo);
}
@@ -283,51 +351,51 @@ void r600_init_screen_texture_functions(struct pipe_screen *screen)
}
static unsigned r600_get_swizzle_combined(const unsigned char *swizzle_format,
- const unsigned char *swizzle_view)
+ const unsigned char *swizzle_view)
{
- unsigned i;
- unsigned char swizzle[4];
- unsigned result = 0;
- const uint32_t swizzle_shift[4] = {
- 16, 19, 22, 25,
- };
- const uint32_t swizzle_bit[4] = {
- 0, 1, 2, 3,
- };
-
- if (swizzle_view) {
- /* Combine two sets of swizzles. */
- for (i = 0; i < 4; i++) {
- swizzle[i] = swizzle_view[i] <= UTIL_FORMAT_SWIZZLE_W ?
- swizzle_format[swizzle_view[i]] : swizzle_view[i];
- }
- } else {
- memcpy(swizzle, swizzle_format, 4);
- }
-
- /* Get swizzle. */
- for (i = 0; i < 4; i++) {
- switch (swizzle[i]) {
- case UTIL_FORMAT_SWIZZLE_Y:
- result |= swizzle_bit[1] << swizzle_shift[i];
- break;
- case UTIL_FORMAT_SWIZZLE_Z:
- result |= swizzle_bit[2] << swizzle_shift[i];
- break;
- case UTIL_FORMAT_SWIZZLE_W:
- result |= swizzle_bit[3] << swizzle_shift[i];
- break;
- case UTIL_FORMAT_SWIZZLE_0:
- result |= V_038010_SQ_SEL_0 << swizzle_shift[i];
- break;
- case UTIL_FORMAT_SWIZZLE_1:
- result |= V_038010_SQ_SEL_1 << swizzle_shift[i];
- break;
- default: /* UTIL_FORMAT_SWIZZLE_X */
- result |= swizzle_bit[0] << swizzle_shift[i];
- }
- }
- return result;
+ unsigned i;
+ unsigned char swizzle[4];
+ unsigned result = 0;
+ const uint32_t swizzle_shift[4] = {
+ 16, 19, 22, 25,
+ };
+ const uint32_t swizzle_bit[4] = {
+ 0, 1, 2, 3,
+ };
+
+ if (swizzle_view) {
+ /* Combine two sets of swizzles. */
+ for (i = 0; i < 4; i++) {
+ swizzle[i] = swizzle_view[i] <= UTIL_FORMAT_SWIZZLE_W ?
+ swizzle_format[swizzle_view[i]] : swizzle_view[i];
+ }
+ } else {
+ memcpy(swizzle, swizzle_format, 4);
+ }
+
+ /* Get swizzle. */
+ for (i = 0; i < 4; i++) {
+ switch (swizzle[i]) {
+ case UTIL_FORMAT_SWIZZLE_Y:
+ result |= swizzle_bit[1] << swizzle_shift[i];
+ break;
+ case UTIL_FORMAT_SWIZZLE_Z:
+ result |= swizzle_bit[2] << swizzle_shift[i];
+ break;
+ case UTIL_FORMAT_SWIZZLE_W:
+ result |= swizzle_bit[3] << swizzle_shift[i];
+ break;
+ case UTIL_FORMAT_SWIZZLE_0:
+ result |= V_038010_SQ_SEL_0 << swizzle_shift[i];
+ break;
+ case UTIL_FORMAT_SWIZZLE_1:
+ result |= V_038010_SQ_SEL_1 << swizzle_shift[i];
+ break;
+ default: /* UTIL_FORMAT_SWIZZLE_X */
+ result |= swizzle_bit[0] << swizzle_shift[i];
+ }
+ }
+ return result;
}
/* texture format translate */
@@ -353,13 +421,13 @@ uint32_t r600_translate_texformat(enum pipe_format format,
case UTIL_FORMAT_COLORSPACE_ZS:
switch (format) {
case PIPE_FORMAT_Z16_UNORM:
- result = V_028010_DEPTH_16;
+ result = V_0280A0_COLOR_16;
goto out_word4;
case PIPE_FORMAT_Z24X8_UNORM:
- result = V_028010_DEPTH_X8_24;
+ result = V_0280A0_COLOR_8_24;
goto out_word4;
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
- result = V_028010_DEPTH_8_24;
+ result = V_0280A0_COLOR_8_24;
goto out_word4;
default:
goto out_unknown;
@@ -522,9 +590,8 @@ out_word4:
*word4_p = word4;
if (yuv_format_p)
*yuv_format_p = yuv_format;
-// fprintf(stderr,"returning %08x %08x %08x\n", result, word4, 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;
}