summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichel Dänzer <[email protected]>2012-09-07 16:09:08 +0200
committerMichel Dänzer <[email protected]>2012-09-11 11:06:56 +0200
commit9ccaa24f8493ebc4e5a606679490e4936ba3c624 (patch)
tree958d3aa35074bf423d8ec73eb42f1c02a00bd7a4
parent03dfa305968adcf511f822757c106912419d6664 (diff)
radeonsi: Texture border colour fixes.
* Handle arbitrary border colours. * Use correct packing format for detecting special border colours. Fixes piglit tex-border-1 and probably many other tests using border colours. Signed-off-by: Michel Dänzer <[email protected]> Reviewed-by: Alex Deucher <[email protected]>
-rw-r--r--src/gallium/drivers/radeonsi/radeonsi_pipe.c2
-rw-r--r--src/gallium/drivers/radeonsi/radeonsi_pipe.h3
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c59
3 files changed, 56 insertions, 8 deletions
diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
index 9d7ac51ef2f..03fe88dad2c 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_pipe.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
@@ -172,6 +172,8 @@ static void r600_destroy_context(struct pipe_context *context)
{
struct r600_context *rctx = (struct r600_context *)context;
+ si_resource_reference(&rctx->border_color_table, NULL);
+
if (rctx->dummy_pixel_shader) {
rctx->context.delete_fs_state(&rctx->context, rctx->dummy_pixel_shader);
}
diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.h b/src/gallium/drivers/radeonsi/radeonsi_pipe.h
index a23f34fe7b9..4253dbb19ad 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_pipe.h
+++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.h
@@ -76,6 +76,7 @@ struct si_pipe_sampler_view {
struct si_pipe_sampler_state {
uint32_t val[4];
+ float border_color[4];
};
/* needed for blitter save */
@@ -137,6 +138,8 @@ struct r600_context {
boolean alpha_ref_dirty;
struct r600_textures_info vs_samplers;
struct r600_textures_info ps_samplers;
+ struct si_resource *border_color_table;
+ unsigned border_color_offset;
boolean shader_dirty;
struct u_upload_mgr *uploader;
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 524003682ae..80da068729d 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -27,6 +27,7 @@
#include "util/u_memory.h"
#include "util/u_framebuffer.h"
#include "util/u_blitter.h"
+#include "util/u_math.h"
#include "util/u_pack_color.h"
#include "tgsi/tgsi_parse.h"
#include "radeonsi_pipe.h"
@@ -2198,7 +2199,7 @@ static void *si_create_sampler_state(struct pipe_context *ctx,
return NULL;
}
- util_pack_color(state->border_color.f, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
+ util_pack_color(state->border_color.f, PIPE_FORMAT_A8R8G8B8_UNORM, &uc);
switch (uc.ui) {
case 0x000000FF:
border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_OPAQUE_BLACK;
@@ -2229,14 +2230,11 @@ static void *si_create_sampler_state(struct pipe_context *ctx,
S_008F38_MIP_FILTER(si_tex_mipfilter(state->min_mip_filter)));
rstate->val[3] = S_008F3C_BORDER_COLOR_TYPE(border_color_type);
-#if 0
- if (border_color_type == 3) {
- si_pm4_set_reg(pm4, R_00A404_TD_PS_SAMPLER0_BORDER_RED, fui(state->border_color.f[0]));
- si_pm4_set_reg(pm4, R_00A408_TD_PS_SAMPLER0_BORDER_GREEN, fui(state->border_color.f[1]));
- si_pm4_set_reg(pm4, R_00A40C_TD_PS_SAMPLER0_BORDER_BLUE, fui(state->border_color.f[2]));
- si_pm4_set_reg(pm4, R_00A410_TD_PS_SAMPLER0_BORDER_ALPHA, fui(state->border_color.f[3]));
+ if (border_color_type == V_008F3C_SQ_TEX_BORDER_COLOR_REGISTER) {
+ memcpy(rstate->border_color, state->border_color.f,
+ sizeof(rstate->border_color));
}
-#endif
+
return rstate;
}
@@ -2300,6 +2298,7 @@ static void si_bind_ps_sampler(struct pipe_context *ctx, unsigned count, void **
struct r600_context *rctx = (struct r600_context *)ctx;
struct si_pipe_sampler_state **rstates = (struct si_pipe_sampler_state **)states;
struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
+ uint32_t *border_color_table = NULL;
int i, j;
if (!count)
@@ -2309,12 +2308,56 @@ static void si_bind_ps_sampler(struct pipe_context *ctx, unsigned count, void **
si_pm4_sh_data_begin(pm4);
for (i = 0; i < count; i++) {
+ if (rstates[i] &&
+ G_008F3C_BORDER_COLOR_TYPE(rstates[i]->val[3]) ==
+ V_008F3C_SQ_TEX_BORDER_COLOR_REGISTER) {
+ if (!rctx->border_color_table ||
+ ((rctx->border_color_offset + count - i) &
+ C_008F3C_BORDER_COLOR_PTR)) {
+ si_resource_reference(&rctx->border_color_table, NULL);
+ rctx->border_color_offset = 0;
+
+ rctx->border_color_table =
+ si_resource_create_custom(ctx->screen,
+ PIPE_USAGE_STAGING,
+ 4096 * 4 * 4);
+ }
+
+ if (!border_color_table) {
+ border_color_table =
+ rctx->ws->buffer_map(rctx->border_color_table->cs_buf,
+ rctx->cs,
+ PIPE_TRANSFER_WRITE |
+ PIPE_TRANSFER_UNSYNCHRONIZED);
+ }
+
+ for (j = 0; j < 4; j++) {
+ union fi border_color;
+
+ border_color.f = rstates[i]->border_color[j];
+ border_color_table[4 * rctx->border_color_offset + j] =
+ util_le32_to_cpu(border_color.i);
+ }
+
+ rstates[i]->val[3] &= C_008F3C_BORDER_COLOR_PTR;
+ rstates[i]->val[3] |= S_008F3C_BORDER_COLOR_PTR(rctx->border_color_offset++);
+ }
+
for (j = 0; j < Elements(rstates[i]->val); ++j) {
si_pm4_sh_data_add(pm4, rstates[i] ? rstates[i]->val[j] : 0);
}
}
si_pm4_sh_data_end(pm4, R_00B038_SPI_SHADER_USER_DATA_PS_2);
+ if (border_color_table) {
+ uint64_t va_offset =
+ r600_resource_va(ctx->screen, (void*)rctx->border_color_table);
+
+ si_pm4_set_reg(pm4, R_028080_TA_BC_BASE_ADDR, va_offset >> 8);
+ rctx->ws->buffer_unmap(rctx->border_color_table->cs_buf);
+ si_pm4_add_bo(pm4, rctx->border_color_table, RADEON_USAGE_READ);
+ }
+
memcpy(rctx->ps_samplers.samplers, states, sizeof(void*) * count);
out: