summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r600')
-rw-r--r--src/gallium/drivers/r600/Makefile1
-rw-r--r--src/gallium/drivers/r600/SConscript1
-rw-r--r--src/gallium/drivers/r600/eg_state_inlines.h100
-rw-r--r--src/gallium/drivers/r600/evergreen_state.c52
-rw-r--r--src/gallium/drivers/r600/evergreend.h9
-rw-r--r--src/gallium/drivers/r600/r600.h1
-rw-r--r--src/gallium/drivers/r600/r600_asm.c148
-rw-r--r--src/gallium/drivers/r600/r600_buffer.c44
-rw-r--r--src/gallium/drivers/r600/r600_formats.h28
-rw-r--r--src/gallium/drivers/r600/r600_helper.c69
-rw-r--r--src/gallium/drivers/r600/r600_pipe.c46
-rw-r--r--src/gallium/drivers/r600/r600_pipe.h20
-rw-r--r--src/gallium/drivers/r600/r600_shader.c34
-rw-r--r--src/gallium/drivers/r600/r600_state.c71
-rw-r--r--src/gallium/drivers/r600/r600_state_common.c106
-rw-r--r--src/gallium/drivers/r600/r600_state_inlines.h99
-rw-r--r--src/gallium/drivers/r600/r600_texture.c14
-rw-r--r--src/gallium/drivers/r600/r600d.h5
18 files changed, 458 insertions, 390 deletions
diff --git a/src/gallium/drivers/r600/Makefile b/src/gallium/drivers/r600/Makefile
index 436de9c4dbd..3dda3a6339f 100644
--- a/src/gallium/drivers/r600/Makefile
+++ b/src/gallium/drivers/r600/Makefile
@@ -10,7 +10,6 @@ C_SOURCES = \
r600_asm.c \
r600_blit.c \
r600_buffer.c \
- r600_helper.c \
r600_pipe.c \
r600_query.c \
r600_resource.c \
diff --git a/src/gallium/drivers/r600/SConscript b/src/gallium/drivers/r600/SConscript
index 5a5fa6d65fd..0135808f10a 100644
--- a/src/gallium/drivers/r600/SConscript
+++ b/src/gallium/drivers/r600/SConscript
@@ -19,7 +19,6 @@ r600 = env.ConvenienceLibrary(
'r600_asm.c',
'r600_buffer.c',
'r600_blit.c',
- 'r600_helper.c',
'r600_pipe.c',
'r600_query.c',
'r600_resource.c',
diff --git a/src/gallium/drivers/r600/eg_state_inlines.h b/src/gallium/drivers/r600/eg_state_inlines.h
index f20d45f48de..a2ba73febdd 100644
--- a/src/gallium/drivers/r600/eg_state_inlines.h
+++ b/src/gallium/drivers/r600/eg_state_inlines.h
@@ -348,7 +348,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format)
case PIPE_FORMAT_A8B8G8R8_UNORM:
case PIPE_FORMAT_X8B8G8R8_UNORM:
- // case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
+ /* case PIPE_FORMAT_R8SG8SB8UX8U_NORM: */
return V_028C70_SWAP_STD_REV;
case PIPE_FORMAT_Z24X8_UNORM:
@@ -367,6 +367,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format)
case PIPE_FORMAT_B10G10R10A2_UNORM:
return V_028C70_SWAP_ALT;
+ case PIPE_FORMAT_R11G11B10_FLOAT:
case PIPE_FORMAT_R32_FLOAT:
case PIPE_FORMAT_R16G16_FLOAT:
case PIPE_FORMAT_R16G16_UNORM:
@@ -469,6 +470,9 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format)
case PIPE_FORMAT_R16G16_UNORM:
return V_028C70_COLOR_16_16;
+ case PIPE_FORMAT_R11G11B10_FLOAT:
+ return V_028C70_COLOR_10_11_11_FLOAT;
+
/* 64-bit buffers. */
case PIPE_FORMAT_R16G16B16_USCALED:
case PIPE_FORMAT_R16G16B16A16_USCALED:
@@ -502,60 +506,60 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format)
case PIPE_FORMAT_UYVY:
case PIPE_FORMAT_YUYV:
default:
- //R600_ERR("unsupported color format %d\n", format);
+ /* R600_ERR("unsupported color format %d\n", format); */
return ~0; /* Unsupported. */
}
}
static INLINE uint32_t r600_colorformat_endian_swap(uint32_t colorformat)
{
-#ifdef PIPE_ARCH_BIG_ENDIAN
- switch(colorformat) {
- case V_0280A0_COLOR_4_4:
- return(ENDIAN_NONE);
-
- /* 8-bit buffers. */
- case V_0280A0_COLOR_8:
- return(ENDIAN_NONE);
-
- /* 16-bit buffers. */
- case V_0280A0_COLOR_5_6_5:
- case V_0280A0_COLOR_1_5_5_5:
- case V_0280A0_COLOR_4_4_4_4:
- case V_0280A0_COLOR_16:
- case V_0280A0_COLOR_8_8:
- return(ENDIAN_8IN16);
-
- /* 32-bit buffers. */
- case V_0280A0_COLOR_8_8_8_8:
- case V_0280A0_COLOR_2_10_10_10:
- case V_0280A0_COLOR_8_24:
- case V_0280A0_COLOR_24_8:
- case V_0280A0_COLOR_32_FLOAT:
- case V_0280A0_COLOR_16_16_FLOAT:
- case V_0280A0_COLOR_16_16:
- return(ENDIAN_8IN32);
-
- /* 64-bit buffers. */
- case V_0280A0_COLOR_16_16_16_16:
- case V_0280A0_COLOR_16_16_16_16_FLOAT:
- return(ENDIAN_8IN16);
-
- case V_0280A0_COLOR_32_32_FLOAT:
- case V_0280A0_COLOR_32_32:
- return(ENDIAN_8IN32);
-
- /* 128-bit buffers. */
- case V_0280A0_COLOR_32_32_32_FLOAT:
- case V_0280A0_COLOR_32_32_32_32_FLOAT:
- case V_0280A0_COLOR_32_32_32_32:
- return(ENDIAN_8IN32);
- default:
- return ENDIAN_NONE; /* Unsupported. */
+ if (R600_BIG_ENDIAN) {
+ switch(colorformat) {
+ case V_028C70_COLOR_4_4:
+ return(ENDIAN_NONE);
+
+ /* 8-bit buffers. */
+ case V_028C70_COLOR_8:
+ return(ENDIAN_NONE);
+
+ /* 16-bit buffers. */
+ case V_028C70_COLOR_5_6_5:
+ case V_028C70_COLOR_1_5_5_5:
+ case V_028C70_COLOR_4_4_4_4:
+ case V_028C70_COLOR_16:
+ case V_028C70_COLOR_8_8:
+ return(ENDIAN_8IN16);
+
+ /* 32-bit buffers. */
+ case V_028C70_COLOR_8_8_8_8:
+ case V_028C70_COLOR_2_10_10_10:
+ case V_028C70_COLOR_8_24:
+ case V_028C70_COLOR_24_8:
+ case V_028C70_COLOR_32_FLOAT:
+ case V_028C70_COLOR_16_16_FLOAT:
+ case V_028C70_COLOR_16_16:
+ return(ENDIAN_8IN32);
+
+ /* 64-bit buffers. */
+ case V_028C70_COLOR_16_16_16_16:
+ case V_028C70_COLOR_16_16_16_16_FLOAT:
+ return(ENDIAN_8IN16);
+
+ case V_028C70_COLOR_32_32_FLOAT:
+ case V_028C70_COLOR_32_32:
+ return(ENDIAN_8IN32);
+
+ /* 128-bit buffers. */
+ case V_028C70_COLOR_32_32_32_FLOAT:
+ case V_028C70_COLOR_32_32_32_32_FLOAT:
+ case V_028C70_COLOR_32_32_32_32:
+ return(ENDIAN_8IN32);
+ default:
+ return ENDIAN_NONE; /* Unsupported. */
+ }
+ } else {
+ return ENDIAN_NONE;
}
-#else
- return ENDIAN_NONE;
-#endif
}
static INLINE boolean r600_is_sampler_format_supported(struct pipe_screen *screen, enum pipe_format format)
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index a972f82fb1d..502f2663e8b 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -143,14 +143,17 @@ static void *evergreen_create_blend_state(struct pipe_context *ctx,
static void *evergreen_create_dsa_state(struct pipe_context *ctx,
const struct pipe_depth_stencil_alpha_state *state)
{
- struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
+ struct r600_pipe_dsa *dsa = CALLOC_STRUCT(r600_pipe_dsa);
unsigned db_depth_control, alpha_test_control, alpha_ref, db_shader_control;
unsigned stencil_ref_mask, stencil_ref_mask_bf, db_render_override, db_render_control;
+ struct r600_pipe_state *rstate;
- if (rstate == NULL) {
+ if (dsa == NULL) {
return NULL;
}
+ rstate = &dsa->rstate;
+
rstate->id = R600_PIPE_STATE_DSA;
/* depth TODO some of those db_shader_control field depend on shader adjust mask & add it to shader */
db_shader_control = S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z);
@@ -190,6 +193,7 @@ static void *evergreen_create_dsa_state(struct pipe_context *ctx,
alpha_test_control |= S_028410_ALPHA_TEST_ENABLE(1);
alpha_ref = fui(state->alpha.ref_value);
}
+ dsa->alpha_ref = alpha_ref;
/* misc */
db_render_control = 0;
@@ -206,7 +210,6 @@ static void *evergreen_create_dsa_state(struct pipe_context *ctx,
r600_pipe_state_add_reg(rstate,
R_028434_DB_STENCILREFMASK_BF, stencil_ref_mask_bf,
0xFFFFFFFF & C_028434_STENCILREF_BF, NULL);
- r600_pipe_state_add_reg(rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_0286DC_SPI_FOG_CNTL, 0x00000000, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_028800_DB_DEPTH_CONTROL, db_depth_control, 0xFFFFFFFF, NULL);
/* The DB_SHADER_CONTROL mask is 0xFFFFFFBC since Z_EXPORT_ENABLE,
@@ -307,16 +310,11 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx,
{
struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
union util_color uc;
- uint32_t coord_trunc = 0;
if (rstate == NULL) {
return NULL;
}
- if ((state->mag_img_filter == PIPE_TEX_FILTER_NEAREST) ||
- (state->min_img_filter == PIPE_TEX_FILTER_NEAREST))
- coord_trunc = 1;
-
rstate->id = R600_PIPE_STATE_SAMPLER;
util_pack_color(state->border_color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
r600_pipe_state_add_reg(rstate, R_03C000_SQ_TEX_SAMPLER_WORD0_0,
@@ -328,14 +326,13 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx,
S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) |
S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func)) |
S_03C000_BORDER_COLOR_TYPE(uc.ui ? V_03C000_SQ_TEX_BORDER_COLOR_REGISTER : 0), 0xFFFFFFFF, NULL);
- /* FIXME LOD it depends on texture base level ... */
r600_pipe_state_add_reg(rstate, R_03C004_SQ_TEX_SAMPLER_WORD1_0,
S_03C004_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 8)) |
S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 8)),
0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_03C008_SQ_TEX_SAMPLER_WORD2_0,
S_03C008_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 8)) |
- S_03C008_MC_COORD_TRUNCATE(coord_trunc) |
+ (state->seamless_cube_map ? 0 : S_03C008_DISABLE_CUBE_WRAP(1)) |
S_03C008_TYPE(1),
0xFFFFFFFF, NULL);
@@ -409,7 +406,6 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
array_mode = tmp->array_mode[0];
tile_type = tmp->tile_type;
- /* FIXME properly handle first level != 0 */
r600_pipe_state_add_reg(rstate, R_030000_RESOURCE0_WORD0,
S_030000_DIM(r600_tex_dim(texture->target)) |
S_030000_PITCH((pitch / 8) - 1) |
@@ -715,12 +711,26 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
S_028C70_ENDIAN(endian);
- /* we can only set the export size if any thing is snorm/unorm component is > 11 bits,
- if we aren't a float, sint or uint */
+ /* EXPORT_NORM is an optimzation that can be enabled for better
+ * performance in certain cases.
+ * EXPORT_NORM can be enabled if:
+ * - 11-bit or smaller UNORM/SNORM/SRGB
+ * - 16-bit or smaller FLOAT
+ */
+ /* FIXME: This should probably be the same for all CBs if we want
+ * useful alpha tests. */
if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS &&
- desc->channel[i].size < 12 && desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT &&
- ntype != V_028C70_NUMBER_UINT && ntype != V_028C70_NUMBER_SINT)
+ ((desc->channel[i].size < 12 &&
+ desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT &&
+ ntype != V_028C70_NUMBER_UINT && ntype != V_028C70_NUMBER_SINT) ||
+ (desc->channel[i].size < 17 &&
+ desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT))) {
color_info |= S_028C70_SOURCE_FORMAT(V_028C70_EXPORT_4C_16BPC);
+ rctx->export_16bpc = true;
+ } else {
+ rctx->export_16bpc = false;
+ }
+ rctx->alpha_ref_dirty = true;
if (rtex->array_mode[level] > V_028C70_ARRAY_LINEAR_ALIGNED) {
tile_type = rtex->tile_type;
@@ -922,7 +932,7 @@ void evergreen_init_state_functions(struct r600_pipe_context *rctx)
rctx->context.create_vertex_elements_state = r600_create_vertex_elements;
rctx->context.create_vs_state = r600_create_shader_state;
rctx->context.bind_blend_state = r600_bind_blend_state;
- rctx->context.bind_depth_stencil_alpha_state = r600_bind_state;
+ rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state;
rctx->context.bind_fragment_sampler_states = evergreen_bind_ps_sampler;
rctx->context.bind_fs_state = r600_bind_ps_shader;
rctx->context.bind_rasterizer_state = r600_bind_rs_state;
@@ -1232,9 +1242,11 @@ void evergreen_init_config(struct r600_pipe_context *rctx)
r600_pipe_state_add_reg(rstate, R_009100_SPI_CONFIG_CNTL, 0x0, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_00913C_SPI_CONFIG_CNTL_1, S_00913C_VTX_DONE_DELAY(4), 0xFFFFFFFF, NULL);
-// r600_pipe_state_add_reg(rstate, R_028350_SX_MISC, 0x0, 0xFFFFFFFF, NULL);
+#if 0
+ r600_pipe_state_add_reg(rstate, R_028350_SX_MISC, 0x0, 0xFFFFFFFF, NULL);
-// r600_pipe_state_add_reg(rstate, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0x0, 0xFFFFFFFF, NULL);
+ r600_pipe_state_add_reg(rstate, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0x0, 0xFFFFFFFF, NULL);
+#endif
r600_pipe_state_add_reg(rstate, R_028A48_PA_SC_MODE_CNTL_0, 0x0, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_028A4C_PA_SC_MODE_CNTL_1, 0x0, 0xFFFFFFFF, NULL);
@@ -1574,9 +1586,7 @@ void evergreen_pipe_set_buffer_resource(struct r600_pipe_context *rctx,
r600_pipe_state_add_reg(rstate, R_030004_RESOURCE0_WORD1,
rbuffer->bo_size - offset - 1, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_030008_RESOURCE0_WORD2,
-#ifdef PIPE_ARCH_BIG_ENDIAN
- S_030008_ENDIAN_SWAP(ENDIAN_8IN32) |
-#endif
+ S_030008_ENDIAN_SWAP(r600_endian_swap(32)) |
S_030008_STRIDE(stride), 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_03000C_RESOURCE0_WORD3,
S_03000C_DST_SEL_X(V_03000C_SQ_SEL_X) |
diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h
index de445b879a1..670606d9b07 100644
--- a/src/gallium/drivers/r600/evergreend.h
+++ b/src/gallium/drivers/r600/evergreend.h
@@ -1194,6 +1194,15 @@
#define S_03C008_FORCE_DEGAMMA(x) (((x) & 0x1) << 21)
#define G_03C008_FORCE_DEGAMMA(x) (((x) >> 21) & 0x1)
#define C_03C008_FORCE_DEGAMMA 0xFFDFFFFF
+#define S_03C008_ANISO_BIAS(x) (((x) & 0x3f) << 22)
+#define G_03C008_ANISO_BIAS(x) (((x) >> 22) & 0x3f)
+#define C_03C008_ANISO_BIAS (~(0x3f << 22))
+#define S_03C008_TRUNCATE_COORD(x) (((x) & 0x1) << 28)
+#define G_03C008_TRUNCATE_COORD(x) (((x) >> 28) & 0x1)
+#define C_03C008_TRUNCATE_COORD (~(1 << 28))
+#define S_03C008_DISABLE_CUBE_WRAP(x) (((x) & 0x1) << 29)
+#define G_03C008_DISABLE_CUBE_WRAP(x) (((x) >> 29) & 0x1)
+#define C_03C008_DISABLE_CUBE_WRAP (~(1 << 29))
#define S_03C008_TYPE(x) (((x) & 0x1) << 31)
#define G_03C008_TYPE(x) (((x) >> 31) & 0x1)
#define C_03C008_TYPE 0x7FFFFFFF
diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h
index 0b0df9d019b..33aa45088a8 100644
--- a/src/gallium/drivers/r600/r600.h
+++ b/src/gallium/drivers/r600/r600.h
@@ -235,6 +235,7 @@ struct r600_query {
#define R600_CONTEXT_DRAW_PENDING (1 << 0)
#define R600_CONTEXT_DST_CACHES_DIRTY (1 << 1)
+#define R600_CONTEXT_CHECK_EVENT_FLUSH (1 << 2)
struct r600_context {
struct radeon *radeon;
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
index 7e854b1b81d..033e84665f5 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -33,12 +33,6 @@
#include "r600_formats.h"
#include "r600d.h"
-#ifdef PIPE_ARCH_BIG_ENDIAN
-#define CPU_TO_LE32(x) bswap_32(x)
-#else
-#define CPU_TO_LE32(x) (x)
-#endif
-
#define NUM_OF_CYCLES 3
#define NUM_OF_COMPONENTS 4
@@ -531,19 +525,19 @@ static int assign_alu_units(struct r600_bc *bc, struct r600_bc_alu *alu_first,
else if (is_alu_vec_unit_inst(bc, alu))
trans = 0;
else if (assignment[chan])
- trans = 1; // assume ALU_INST_PREFER_VECTOR
+ trans = 1; /* Assume ALU_INST_PREFER_VECTOR. */
else
trans = 0;
if (trans) {
if (assignment[4]) {
- assert(0); //ALU.Trans has already been allocated
+ assert(0); /* ALU.Trans has already been allocated. */
return -1;
}
assignment[4] = alu;
} else {
if (assignment[chan]) {
- assert(0); //ALU.chan has already been allocated
+ assert(0); /* ALU.chan has already been allocated. */
return -1;
}
assignment[chan] = alu;
@@ -595,7 +589,7 @@ static int reserve_gpr(struct alu_bank_swizzle *bs, unsigned sel, unsigned chan,
if (bs->hw_gpr[cycle][chan] == -1)
bs->hw_gpr[cycle][chan] = sel;
else if (bs->hw_gpr[cycle][chan] != (int)sel) {
- // Another scalar operation has already used GPR read port for channel
+ /* Another scalar operation has already used the GPR read port for the channel. */
return -1;
}
return 0;
@@ -615,9 +609,9 @@ static int reserve_cfile(struct r600_bc *bc, struct alu_bank_swizzle *bs, unsign
return 0;
} else if (bs->hw_cfile_addr[res] == sel &&
bs->hw_cfile_elem[res] == chan)
- return 0; // Read for this scalar element already reserved, nothing to do here.
+ return 0; /* Read for this scalar element already reserved, nothing to do here. */
}
- // All cfile read ports are used, cannot reference vector element
+ /* All cfile read ports are used, cannot reference vector element. */
return -1;
}
@@ -632,8 +626,8 @@ static int is_gpr(unsigned sel)
static int is_cfile(unsigned sel)
{
return (sel > 255 && sel < 512) ||
- (sel > 511 && sel < 4607) || // Kcache before translate
- (sel > 127 && sel < 192); // Kcache after translate
+ (sel > 511 && sel < 4607) || /* Kcache before translation. */
+ (sel > 127 && sel < 192); /* Kcache after translation. */
}
static int is_const(int sel)
@@ -655,8 +649,8 @@ static int check_vector(struct r600_bc *bc, struct r600_bc_alu *alu,
if (is_gpr(sel)) {
cycle = cycle_for_bank_swizzle_vec[bank_swizzle][src];
if (src == 1 && sel == alu->src[0].sel && elem == alu->src[0].chan)
- // Nothing to do; special-case optimization,
- // second source uses first source’s reservation
+ /* Nothing to do; special-case optimization,
+ * second source uses first source’s reservation. */
continue;
else {
r = reserve_gpr(bs, sel, elem, cycle);
@@ -668,7 +662,7 @@ static int check_vector(struct r600_bc *bc, struct r600_bc_alu *alu,
if (r)
return r;
}
- // No restrictions on PV, PS, literal or special constants
+ /* No restrictions on PV, PS, literal or special constants. */
}
return 0;
}
@@ -682,10 +676,10 @@ static int check_scalar(struct r600_bc *bc, struct r600_bc_alu *alu,
for (const_count = 0, src = 0; src < num_src; ++src) {
sel = alu->src[src].sel;
elem = alu->src[src].chan;
- if (is_const(sel)) { // Any constant, including literal and inline constants
+ if (is_const(sel)) { /* Any constant, including literal and inline constants. */
if (const_count >= 2)
- // More than two references to a constant in
- // transcendental operation.
+ /* More than two references to a constant in
+ * transcendental operation. */
return -1;
else
const_count++;
@@ -702,15 +696,19 @@ static int check_scalar(struct r600_bc *bc, struct r600_bc_alu *alu,
if (is_gpr(sel)) {
cycle = cycle_for_bank_swizzle_scl[bank_swizzle][src];
if (cycle < const_count)
- // Cycle for GPR load conflicts with
- // constant load in transcendental operation.
+ /* Cycle for GPR load conflicts with
+ * constant load in transcendental operation. */
return -1;
r = reserve_gpr(bs, sel, elem, cycle);
if (r)
return r;
}
- // Constants already processed
- // No restrictions on PV, PS
+ /* PV PS restrictions */
+ if (const_count && (sel == 254 || sel == 255)) {
+ cycle = cycle_for_bank_swizzle_scl[bank_swizzle][src];
+ if (cycle < const_count)
+ return -1;
+ }
}
return 0;
}
@@ -721,30 +719,36 @@ static int check_and_set_bank_swizzle(struct r600_bc *bc,
struct alu_bank_swizzle bs;
int bank_swizzle[5];
int i, r = 0, forced = 0;
-
- for (i = 0; i < 5; i++)
+ boolean scalar_only = true;
+ for (i = 0; i < 5; i++) {
if (slots[i] && slots[i]->bank_swizzle_force) {
slots[i]->bank_swizzle = slots[i]->bank_swizzle_force;
forced = 1;
}
-
+ if (i < 4 && slots[i])
+ scalar_only = false;
+ }
if (forced)
return 0;
- // just check every possible combination of bank swizzle
- // not very efficent, but works on the first try in most of the cases
+ /* Just check every possible combination of bank swizzle.
+ * Not very efficent, but works on the first try in most of the cases. */
for (i = 0; i < 4; i++)
bank_swizzle[i] = SQ_ALU_VEC_012;
bank_swizzle[4] = SQ_ALU_SCL_210;
while(bank_swizzle[4] <= SQ_ALU_SCL_221) {
init_bank_swizzle(&bs);
- for (i = 0; i < 4; i++) {
- if (slots[i]) {
- r = check_vector(bc, slots[i], &bs, bank_swizzle[i]);
- if (r)
- break;
+ if (scalar_only == false) {
+ for (i = 0; i < 4; i++) {
+ if (slots[i]) {
+ r = check_vector(bc, slots[i], &bs, bank_swizzle[i]);
+ if (r)
+ break;
+ }
}
- }
+ } else
+ r = 0;
+
if (!r && slots[4]) {
r = check_scalar(bc, slots[4], &bs, bank_swizzle[4]);
}
@@ -756,16 +760,20 @@ static int check_and_set_bank_swizzle(struct r600_bc *bc,
return 0;
}
- for (i = 0; i < 5; i++) {
- bank_swizzle[i]++;
- if (bank_swizzle[i] <= SQ_ALU_VEC_210)
- break;
- else
- bank_swizzle[i] = SQ_ALU_VEC_012;
+ if (scalar_only) {
+ bank_swizzle[4]++;
+ } else {
+ for (i = 0; i < 5; i++) {
+ bank_swizzle[i]++;
+ if (bank_swizzle[i] <= SQ_ALU_VEC_210)
+ break;
+ else
+ bank_swizzle[i] = SQ_ALU_VEC_012;
+ }
}
}
- // couldn't find a working swizzle
+ /* Couldn't find a working swizzle. */
return -1;
}
@@ -835,17 +843,17 @@ void r600_bc_special_constants(u32 value, unsigned *sel, unsigned *neg)
case -1:
*sel = V_SQ_ALU_SRC_M_1_INT;
break;
- case 0x3F800000: // 1.0f
+ case 0x3F800000: /* 1.0f */
*sel = V_SQ_ALU_SRC_1;
break;
- case 0x3F000000: // 0.5f
+ case 0x3F000000: /* 0.5f */
*sel = V_SQ_ALU_SRC_0_5;
break;
- case 0xBF800000: // -1.0f
+ case 0xBF800000: /* -1.0f */
*sel = V_SQ_ALU_SRC_1;
*neg ^= 1;
break;
- case 0xBF000000: // -0.5f
+ case 0xBF000000: /* -0.5f */
*sel = V_SQ_ALU_SRC_0_5;
*neg ^= 1;
break;
@@ -938,13 +946,13 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5],
if (slots[i] && r600_bc_alu_nliterals(bc, slots[i], literal, &nliteral))
return 0;
- // let's check used slots
+ /* Let's check used slots. */
if (prev[i] && !slots[i]) {
result[i] = prev[i];
continue;
} else if (prev[i] && slots[i]) {
if (result[4] == NULL && prev[4] == NULL && slots[4] == NULL) {
- // trans unit is still free try to use it
+ /* Trans unit is still free try to use it. */
if (is_alu_any_unit_inst(bc, slots[i])) {
result[i] = prev[i];
result[4] = slots[i];
@@ -963,14 +971,14 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5],
alu = slots[i];
num_once_inst += is_alu_once_inst(bc, alu);
- // let's check dst gpr
+ /* Let's check dst gpr. */
if (alu->dst.rel) {
if (have_mova)
return 0;
have_rel = 1;
}
- // let's check source gprs
+ /* Let's check source gprs */
num_src = r600_bc_get_num_operands(bc, alu);
for (src = 0; src < num_src; ++src) {
if (alu->src[src].rel) {
@@ -979,7 +987,7 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5],
have_rel = 1;
}
- // constants doesn't matter
+ /* Constants don't matter. */
if (!is_gpr(alu->src[src].sel))
continue;
@@ -987,7 +995,7 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5],
if (!prev[j] || !prev[j]->dst.write)
continue;
- // if it's relative then we can't determin which gpr is really used
+ /* If it's relative then we can't determin which gpr is really used. */
if (prev[j]->dst.chan == alu->src[src].chan &&
(prev[j]->dst.sel == alu->src[src].sel ||
prev[j]->dst.rel || alu->src[src].rel))
@@ -1390,7 +1398,7 @@ static int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsign
S_SQ_VTX_WORD1_SRF_MODE_ALL(vtx->srf_mode_all) |
S_SQ_VTX_WORD1_GPR_DST_GPR(vtx->dst_gpr);
bc->bytecode[id++] = S_SQ_VTX_WORD2_OFFSET(vtx->offset) |
- S_SQ_VTX_WORD2_ENDIAN_SWAP(vtx->endian) |
+ S_SQ_VTX_WORD2_ENDIAN_SWAP(vtx->endian) |
S_SQ_VTX_WORD2_MEGA_FETCH(1);
bc->bytecode[id++] = 0;
return 0;
@@ -1927,7 +1935,7 @@ void r600_bc_dump(struct r600_bc *bc)
fprintf(stderr, "%04d %08X ", id, bc->bytecode[id]);
fprintf(stderr, "ENDIAN:%d ", vtx->endian);
fprintf(stderr, "OFFSET:%d\n", vtx->offset);
- //TODO
+ /* TODO */
id++;
fprintf(stderr, "%04d %08X \n", id, bc->bytecode[id]);
id++;
@@ -1960,6 +1968,8 @@ static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format,
}
}
+ *endian = r600_endian_swap(desc->channel[i].size);
+
switch (desc->channel[i].type) {
/* Half-floats, floats, ints */
case UTIL_FORMAT_TYPE_FLOAT:
@@ -1977,9 +1987,6 @@ static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format,
*format = FMT_16_16_16_16_FLOAT;
break;
}
-#ifdef PIPE_ARCH_BIG_ENDIAN
- *endian = ENDIAN_8IN16;
-#endif
break;
case 32:
switch (desc->nr_channels) {
@@ -1996,9 +2003,6 @@ static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format,
*format = FMT_32_32_32_32_FLOAT;
break;
}
-#ifdef PIPE_ARCH_BIG_ENDIAN
- *endian = ENDIAN_8IN32;
-#endif
break;
default:
goto out_unknown;
@@ -2036,9 +2040,6 @@ static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format,
*format = FMT_16_16_16_16;
break;
}
-#ifdef PIPE_ARCH_BIG_ENDIAN
- *endian = ENDIAN_8IN16;
-#endif
break;
case 32:
switch (desc->nr_channels) {
@@ -2055,9 +2056,6 @@ static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format,
*format = FMT_32_32_32_32;
break;
}
-#ifdef PIPE_ARCH_BIG_ENDIAN
- *endian = ENDIAN_8IN32;
-#endif
break;
default:
goto out_unknown;
@@ -2093,11 +2091,11 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru
u32 *bytecode;
int i, r;
- /* vertex elements offset need special handling, if offset is bigger
- + * than what we can put in fetch instruction then we need to alterate
- * the vertex resource offset. In such case in order to simplify code
- * we will bound one resource per elements. It's a worst case scenario.
- */
+ /* Vertex element offsets need special handling. If the offset is
+ * bigger than what we can put in the fetch instruction we need to
+ * alter the vertex resource offset. In order to simplify code we
+ * will bind one resource per element in such cases. It's a worst
+ * case scenario. */
for (i = 0; i < ve->count; i++) {
ve->vbuffer_offset[i] = C_SQ_VTX_WORD2_OFFSET & elements[i].src_offset;
if (ve->vbuffer_offset[i]) {
@@ -2202,8 +2200,12 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru
return -ENOMEM;
}
- for(i = 0; i < ve->fs_size / 4; i++) {
- *(bytecode + i) = CPU_TO_LE32(*(bc.bytecode + i));
+ if (R600_BIG_ENDIAN) {
+ for (i = 0; i < ve->fs_size / 4; ++i) {
+ bytecode[i] = bswap_32(bc.bytecode[i]);
+ }
+ } else {
+ memcpy(bytecode, bc.bytecode, ve->fs_size);
}
r600_bo_unmap(rctx->radeon, ve->fetch_shader);
diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c
index 71b47e1b056..72f352df3c3 100644
--- a/src/gallium/drivers/r600/r600_buffer.c
+++ b/src/gallium/drivers/r600/r600_buffer.c
@@ -81,18 +81,11 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
struct r600_resource_buffer *rbuffer = r600_buffer(transfer->resource);
- int write = 0;
uint8_t *data;
if (rbuffer->r.b.user_ptr)
return (uint8_t*)rbuffer->r.b.user_ptr + transfer->box.x;
- if (transfer->usage & PIPE_TRANSFER_DONTBLOCK) {
- /* FIXME */
- }
- if (transfer->usage & PIPE_TRANSFER_WRITE) {
- write = 1;
- }
data = r600_bo_map((struct radeon*)pipe->winsys, rbuffer->r.bo, transfer->usage, pipe);
if (!data)
return NULL;
@@ -268,31 +261,30 @@ void r600_upload_const_buffer(struct r600_pipe_context *rctx, struct r600_resour
uint8_t *ptr = (*rbuffer)->r.b.user_ptr;
unsigned size = (*rbuffer)->r.b.b.b.width0;
boolean flushed;
-#ifdef PIPE_ARCH_BIG_ENDIAN
- int i;
- uint32_t *tmpPtr;
*rbuffer = NULL;
- tmpPtr = (uint32_t *)malloc(size);
- /* big endian swap */
- if(tmpPtr == NULL) {
- return;
- }
- for(i = 0; i < size / 4; i++) {
- tmpPtr[i] = bswap_32(*((uint32_t *)ptr + i));
- }
+ if (R600_BIG_ENDIAN) {
+ uint32_t *tmpPtr;
+ unsigned i;
- u_upload_data(rctx->vbuf_mgr->uploader, 0, size, tmpPtr, const_offset,
- (struct pipe_resource**)rbuffer, &flushed);
+ if (!(tmpPtr = malloc(size))) {
+ R600_ERR("Failed to allocate BE swap buffer.\n");
+ return;
+ }
- free(tmpPtr);
-#else
- *rbuffer = NULL;
+ for (i = 0; i < size / 4; ++i) {
+ tmpPtr[i] = bswap_32(((uint32_t *)ptr)[i]);
+ }
+
+ u_upload_data(rctx->vbuf_mgr->uploader, 0, size, tmpPtr, const_offset,
+ (struct pipe_resource**)rbuffer, &flushed);
- u_upload_data(rctx->vbuf_mgr->uploader, 0, size, ptr, const_offset,
- (struct pipe_resource**)rbuffer, &flushed);
-#endif
+ free(tmpPtr);
+ } else {
+ u_upload_data(rctx->vbuf_mgr->uploader, 0, size, ptr, const_offset,
+ (struct pipe_resource**)rbuffer, &flushed);
+ }
} else {
*const_offset = 0;
}
diff --git a/src/gallium/drivers/r600/r600_formats.h b/src/gallium/drivers/r600/r600_formats.h
index 0c91a212384..ae0bc432ad2 100644
--- a/src/gallium/drivers/r600/r600_formats.h
+++ b/src/gallium/drivers/r600/r600_formats.h
@@ -1,6 +1,8 @@
#ifndef R600_FORMATS_H
#define R600_FORMATS_H
+#include "r600_pipe.h"
+
/* list of formats from R700 ISA document - apply across GPUs in different registers */
#define FMT_INVALID 0x00000000
#define FMT_8 0x00000001
@@ -52,5 +54,31 @@
#define FMT_BC3 0x00000033
#define FMT_BC4 0x00000034
#define FMT_BC5 0x00000035
+#define FMT_BC6 0x00000036
+#define FMT_BC7 0x00000037
+#define FMT_32_AS_32_32_32_32 0x00000038
+
+#define ENDIAN_NONE 0
+#define ENDIAN_8IN16 1
+#define ENDIAN_8IN32 2
+#define ENDIAN_8IN64 3
+
+static INLINE unsigned r600_endian_swap(unsigned size)
+{
+ if (R600_BIG_ENDIAN) {
+ switch (size) {
+ case 64:
+ return ENDIAN_8IN64;
+ case 32:
+ return ENDIAN_8IN32;
+ case 16:
+ return ENDIAN_8IN16;
+ default:
+ return ENDIAN_NONE;
+ }
+ } else {
+ return ENDIAN_NONE;
+ }
+}
#endif
diff --git a/src/gallium/drivers/r600/r600_helper.c b/src/gallium/drivers/r600/r600_helper.c
deleted file mode 100644
index 7e131093060..00000000000
--- a/src/gallium/drivers/r600/r600_helper.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2010 Jerome Glisse <[email protected]>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Jerome Glisse
- */
-#include <stdio.h>
-#include <errno.h>
-#include <util/u_inlines.h>
-#include "r600_pipe.h"
-#include "r600d.h"
-
-int r600_conv_pipe_prim(unsigned pprim, unsigned *prim)
-{
- switch (pprim) {
- case PIPE_PRIM_POINTS:
- *prim = V_008958_DI_PT_POINTLIST;
- return 0;
- case PIPE_PRIM_LINES:
- *prim = V_008958_DI_PT_LINELIST;
- return 0;
- case PIPE_PRIM_LINE_STRIP:
- *prim = V_008958_DI_PT_LINESTRIP;
- return 0;
- case PIPE_PRIM_LINE_LOOP:
- *prim = V_008958_DI_PT_LINELOOP;
- return 0;
- case PIPE_PRIM_TRIANGLES:
- *prim = V_008958_DI_PT_TRILIST;
- return 0;
- case PIPE_PRIM_TRIANGLE_STRIP:
- *prim = V_008958_DI_PT_TRISTRIP;
- return 0;
- case PIPE_PRIM_TRIANGLE_FAN:
- *prim = V_008958_DI_PT_TRIFAN;
- return 0;
- case PIPE_PRIM_POLYGON:
- *prim = V_008958_DI_PT_POLYGON;
- return 0;
- case PIPE_PRIM_QUADS:
- *prim = V_008958_DI_PT_QUADLIST;
- return 0;
- case PIPE_PRIM_QUAD_STRIP:
- *prim = V_008958_DI_PT_QUADSTRIP;
- return 0;
- default:
- fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pprim);
- return -EINVAL;
- }
-}
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index 89b46f5ad7e..ec13e48e14e 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -374,27 +374,29 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_SHADER_STENCIL_EXPORT:
case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
+
+ /* Supported except the original R600. */
case PIPE_CAP_INDEP_BLEND_ENABLE:
+ case PIPE_CAP_INDEP_BLEND_FUNC:
/* R600 doesn't support per-MRT blends */
- if (family == CHIP_R600)
- return 0;
- else
- return 1;
+ return family == CHIP_R600 ? 0 : 1;
- case PIPE_CAP_TGSI_INSTANCEID:
- return 0;
+ /* Supported on Evergreen. */
+ case PIPE_CAP_SEAMLESS_CUBE_MAP:
+ case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
+ return family >= CHIP_CEDAR ? 1 : 0;
- /* Unsupported features (boolean caps). */
+ /* Unsupported features. */
case PIPE_CAP_STREAM_OUTPUT:
case PIPE_CAP_PRIMITIVE_RESTART:
- case PIPE_CAP_INDEP_BLEND_FUNC: /* FIXME allow this */
case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL:
- /* R600 doesn't support per-MRT blends */
- if (family == CHIP_R600)
- return 0;
- else
- return 0;
+ case PIPE_CAP_TGSI_INSTANCEID:
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+ return 0;
case PIPE_CAP_ARRAY_TEXTURES:
/* fix once the CS checker upstream is fixed */
@@ -409,25 +411,16 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
else
return 14;
case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
- /* FIXME allow this once infrastructure is there */
- return 16;
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
- case PIPE_CAP_MAX_COMBINED_SAMPLERS:
return 16;
+ case PIPE_CAP_MAX_COMBINED_SAMPLERS:
+ return 32;
/* Render targets. */
case PIPE_CAP_MAX_RENDER_TARGETS:
/* FIXME some r6xx are buggy and can only do 4 */
return 8;
- /* Fragment coordinate conventions. */
- case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
- case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
- return 1;
- case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
- case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
- return 0;
-
/* Timer queries, present when the clock frequency is non zero. */
case PIPE_CAP_TIMER_QUERY:
return r600_get_clock_crystal_freq(rscreen->radeon) != 0;
@@ -492,9 +485,10 @@ static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, e
else
return 16;
case PIPE_SHADER_CAP_MAX_TEMPS:
- return 256; //max native temporaries
+ return 256; /* Max native temporaries. */
case PIPE_SHADER_CAP_MAX_ADDRS:
- return 1; //max native address registers/* FIXME Isn't this equal to TEMPS? */
+ /* FIXME Isn't this equal to TEMPS? */
+ return 1; /* Max native address registers */
case PIPE_SHADER_CAP_MAX_CONSTS:
return R600_MAX_CONST_BUFFER_SIZE;
case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index 88aff0e81bb..aa5ef4efb3b 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -40,6 +40,12 @@
#define R600_MAX_CONST_BUFFERS 1
#define R600_MAX_CONST_BUFFER_SIZE 4096
+#ifdef PIPE_ARCH_BIG_ENDIAN
+#define R600_BIG_ENDIAN 1
+#else
+#define R600_BIG_ENDIAN 0
+#endif
+
enum r600_pipe_state_id {
R600_PIPE_STATE_BLEND = 0,
R600_PIPE_STATE_BLEND_COLOR,
@@ -91,6 +97,11 @@ struct r600_pipe_blend {
unsigned cb_target_mask;
};
+struct r600_pipe_dsa {
+ struct r600_pipe_state rstate;
+ unsigned alpha_ref;
+};
+
struct r600_vertex_element
{
unsigned count;
@@ -180,6 +191,9 @@ struct r600_pipe_context {
/* shader information */
unsigned sprite_coord_enable;
bool flatshade;
+ bool export_16bpc;
+ unsigned alpha_ref;
+ bool alpha_ref_dirty;
struct r600_textures_info ps_samplers;
struct r600_pipe_fences fences;
@@ -241,7 +255,6 @@ int r600_find_vs_semantic_index(struct r600_shader *vs,
/* r600_state.c */
void r600_init_state_functions(struct r600_pipe_context *rctx);
-void r600_spi_update(struct r600_pipe_context *rctx);
void r600_init_config(struct r600_pipe_context *rctx);
void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader);
void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader);
@@ -253,9 +266,6 @@ void r600_pipe_set_buffer_resource(struct r600_pipe_context *rctx,
struct r600_resource *rbuffer,
unsigned offset, unsigned stride);
-/* r600_helper.h */
-int r600_conv_pipe_prim(unsigned pprim, unsigned *prim);
-
/* r600_texture.c */
void r600_init_screen_texture_functions(struct pipe_screen *screen);
void r600_init_surface_functions(struct r600_pipe_context *r600);
@@ -281,11 +291,11 @@ void *r600_create_vertex_elements(struct pipe_context *ctx,
const struct pipe_vertex_element *elements);
void r600_delete_vertex_element(struct pipe_context *ctx, void *state);
void r600_bind_blend_state(struct pipe_context *ctx, void *state);
+void r600_bind_dsa_state(struct pipe_context *ctx, void *state);
void r600_bind_rs_state(struct pipe_context *ctx, void *state);
void r600_delete_rs_state(struct pipe_context *ctx, void *state);
void r600_sampler_view_destroy(struct pipe_context *ctx,
struct pipe_sampler_view *state);
-void r600_bind_state(struct pipe_context *ctx, void *state);
void r600_delete_state(struct pipe_context *ctx, void *state);
void r600_bind_vertex_elements(struct pipe_context *ctx, void *state);
void *r600_create_shader_state(struct pipe_context *ctx,
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index 188cea0ff88..845d41ace02 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -21,6 +21,7 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "pipe/p_shader_tokens.h"
+#include "tgsi/tgsi_info.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_scan.h"
#include "tgsi/tgsi_dump.h"
@@ -35,12 +36,6 @@
#include <errno.h>
#include <byteswap.h>
-#ifdef PIPE_ARCH_BIG_ENDIAN
-#define CPU_TO_LE32(x) bswap_32(x)
-#else
-#define CPU_TO_LE32(x) (x)
-#endif
-
int r600_find_vs_semantic_index(struct r600_shader *vs,
struct r600_shader *ps, int id)
{
@@ -69,8 +64,12 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *s
return -ENOMEM;
}
ptr = (uint32_t*)r600_bo_map(rctx->radeon, shader->bo, 0, NULL);
- for(i = 0; i < rshader->bc.ndw; i++) {
- *(ptr + i) = CPU_TO_LE32(*(rshader->bc.bytecode + i));
+ if (R600_BIG_ENDIAN) {
+ for (i = 0; i < rshader->bc.ndw; ++i) {
+ ptr[i] = bswap_32(rshader->bc.bytecode[i]);
+ }
+ } else {
+ memcpy(ptr, rshader->bc.bytecode, rshader->bc.ndw * sizeof(*ptr));
}
r600_bo_unmap(rctx->radeon, shader->bo);
}
@@ -477,11 +476,7 @@ static int tgsi_fetch_rel_const(struct r600_shader_ctx *ctx, unsigned int offset
vtx.num_format_all = 2; /* NUM_FORMAT_SCALED */
vtx.format_comp_all = 1; /* FORMAT_COMP_SIGNED */
vtx.srf_mode_all = 1; /* SRF_MODE_NO_ZERO */
-#ifdef PIPE_ARCH_BIG_ENDIAN
- vtx.endian = ENDIAN_8IN32;
-#else
- vtx.endian = ENDIAN_NONE;
-#endif
+ vtx.endian = r600_endian_swap(32);
if ((r = r600_bc_add_vtx(ctx->bc, &vtx)))
return r;
@@ -830,7 +825,8 @@ out_err:
static int tgsi_unsupported(struct r600_shader_ctx *ctx)
{
- R600_ERR("%d tgsi opcode unsupported\n", ctx->inst_info->tgsi_opcode);
+ R600_ERR("%s tgsi opcode unsupported\n",
+ tgsi_get_opcode_name(ctx->inst_info->tgsi_opcode));
return -EINVAL;
}
@@ -911,6 +907,8 @@ static int tgsi_op2_s(struct r600_shader_ctx *ctx, int swap)
break;
case TGSI_OPCODE_ABS:
alu.src[0].abs = 1;
+ if (alu.src[0].neg)
+ alu.src[0].neg = 0;
break;
default:
break;
@@ -1997,9 +1995,11 @@ static int tgsi_exp(struct r600_shader_ctx *ctx)
r600_bc_src(&alu.src[0], &ctx->src[0], 0);
alu.dst.sel = ctx->temp_reg;
-// r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst);
-// if (r)
-// return r;
+#if 0
+ r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst);
+ if (r)
+ return r;
+#endif
alu.dst.write = 1;
alu.dst.chan = 1;
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 8646b9f4905..b9084c953ee 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -199,14 +199,17 @@ static void *r600_create_blend_state(struct pipe_context *ctx,
static void *r600_create_dsa_state(struct pipe_context *ctx,
const struct pipe_depth_stencil_alpha_state *state)
{
- struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
+ struct r600_pipe_dsa *dsa = CALLOC_STRUCT(r600_pipe_dsa);
unsigned db_depth_control, alpha_test_control, alpha_ref, db_shader_control;
unsigned stencil_ref_mask, stencil_ref_mask_bf, db_render_override, db_render_control;
+ struct r600_pipe_state *rstate;
- if (rstate == NULL) {
+ if (dsa == NULL) {
return NULL;
}
+ rstate = &dsa->rstate;
+
rstate->id = R600_PIPE_STATE_DSA;
/* depth TODO some of those db_shader_control field depend on shader adjust mask & add it to shader */
db_shader_control = S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z);
@@ -246,6 +249,7 @@ static void *r600_create_dsa_state(struct pipe_context *ctx,
alpha_test_control |= S_028410_ALPHA_TEST_ENABLE(1);
alpha_ref = fui(state->alpha.ref_value);
}
+ dsa->alpha_ref = alpha_ref;
/* misc */
db_render_control = 0;
@@ -262,7 +266,6 @@ static void *r600_create_dsa_state(struct pipe_context *ctx,
r600_pipe_state_add_reg(rstate,
R_028434_DB_STENCILREFMASK_BF, stencil_ref_mask_bf,
0xFFFFFFFF & C_028434_STENCILREF_BF, NULL);
- r600_pipe_state_add_reg(rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_0286E0_SPI_FOG_FUNC_SCALE, 0x00000000, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_0286E4_SPI_FOG_FUNC_BIAS, 0x00000000, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_0286DC_SPI_FOG_CNTL, 0x00000000, 0xFFFFFFFF, NULL);
@@ -371,16 +374,11 @@ static void *r600_create_sampler_state(struct pipe_context *ctx,
{
struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
union util_color uc;
- uint32_t coord_trunc = 0;
if (rstate == NULL) {
return NULL;
}
- if ((state->mag_img_filter == PIPE_TEX_FILTER_NEAREST) ||
- (state->min_img_filter == PIPE_TEX_FILTER_NEAREST))
- coord_trunc = 1;
-
rstate->id = R600_PIPE_STATE_SAMPLER;
util_pack_color(state->border_color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
r600_pipe_state_add_reg(rstate, R_03C000_SQ_TEX_SAMPLER_WORD0_0,
@@ -392,14 +390,11 @@ static void *r600_create_sampler_state(struct pipe_context *ctx,
S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) |
S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func)) |
S_03C000_BORDER_COLOR_TYPE(uc.ui ? V_03C000_SQ_TEX_BORDER_COLOR_REGISTER : 0), 0xFFFFFFFF, NULL);
- /* FIXME LOD it depends on texture base level ... */
r600_pipe_state_add_reg(rstate, R_03C004_SQ_TEX_SAMPLER_WORD1_0,
S_03C004_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 6)) |
S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 6)) |
S_03C004_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 6)), 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(rstate, R_03C008_SQ_TEX_SAMPLER_WORD2_0,
- S_03C008_MC_COORD_TRUNCATE(coord_trunc) |
- S_03C008_TYPE(1), 0xFFFFFFFF, NULL);
+ r600_pipe_state_add_reg(rstate, R_03C008_SQ_TEX_SAMPLER_WORD2_0, S_03C008_TYPE(1), 0xFFFFFFFF, NULL);
if (uc.ui) {
r600_pipe_state_add_reg(rstate, R_00A400_TD_PS_SAMPLER0_BORDER_RED, fui(state->border_color[0]), 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_00A404_TD_PS_SAMPLER0_BORDER_GREEN, fui(state->border_color[1]), 0xFFFFFFFF, NULL);
@@ -477,7 +472,6 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c
depth = texture->array_size;
}
- /* FIXME properly handle first level != 0 */
r600_pipe_state_add_reg(rstate, R_038000_RESOURCE0_WORD0,
S_038000_DIM(r600_tex_dim(texture->target)) |
S_038000_TILE_MODE(array_mode) |
@@ -724,7 +718,7 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta
struct r600_surface *surf;
unsigned level = state->cbufs[cb]->u.tex.level;
unsigned pitch, slice;
- unsigned color_info, color_info_mask;
+ unsigned color_info;
unsigned format, swap, ntype, endian;
unsigned offset;
const struct util_format_description *desc;
@@ -780,17 +774,36 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta
S_0280A0_NUMBER_TYPE(ntype) |
S_0280A0_ENDIAN(endian);
- color_info_mask = 0xFFFFFFFF & ~S_0280A0_BLEND_CLAMP(1);
-
- /* on R600 this can't be set if BLEND_CLAMP isn't set,
- if BLEND_FLOAT32 is set of > 11 bits in a UNORM or SNORM */
- if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS && desc->channel[i].size < 12) {
- //TODO: Seems to work on RV710, but i have no idea what to do between R600-RV710
- if (rctx->family < CHIP_RV710) {
- color_info |= S_0280A0_BLEND_CLAMP(1);
- color_info_mask |= S_0280A0_BLEND_CLAMP(1);
- }
- color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM);
+ /* EXPORT_NORM is an optimzation that can be enabled for better
+ * performance in certain cases
+ */
+ if (rctx->family < CHIP_RV770) {
+ /* EXPORT_NORM can be enabled if:
+ * - 11-bit or smaller UNORM/SNORM/SRGB
+ * - BLEND_CLAMP is enabled
+ * - BLEND_FLOAT32 is disabled
+ */
+ // TODO get BLEND_CLAMP state from rasterizer state
+ if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS &&
+ (desc->channel[i].size < 12 &&
+ desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT &&
+ ntype != V_0280A0_NUMBER_UINT &&
+ ntype != V_0280A0_NUMBER_SINT) &&
+ G_0280A0_BLEND_CLAMP(color_info) &&
+ !G_0280A0_BLEND_FLOAT32(color_info))
+ color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM);
+ } else {
+ /* EXPORT_NORM can be enabled if:
+ * - 11-bit or smaller UNORM/SNORM/SRGB
+ * - 16-bit or smaller FLOAT
+ */
+ if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS &&
+ ((desc->channel[i].size < 12 &&
+ desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT &&
+ ntype != V_0280A0_NUMBER_UINT && ntype != V_0280A0_NUMBER_SINT) ||
+ (desc->channel[i].size < 17 &&
+ desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT)))
+ color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM);
}
r600_pipe_state_add_reg(rstate,
@@ -798,7 +811,7 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta
(offset + r600_bo_offset(bo[0])) >> 8, 0xFFFFFFFF, bo[0]);
r600_pipe_state_add_reg(rstate,
R_0280A0_CB_COLOR0_INFO + cb * 4,
- color_info, color_info_mask, NULL);
+ color_info, ~S_0280A0_BLEND_CLAMP(1), NULL);
r600_pipe_state_add_reg(rstate,
R_028060_CB_COLOR0_SIZE + cb * 4,
S_028060_PITCH_TILE_MAX(pitch) |
@@ -984,7 +997,7 @@ void r600_init_state_functions(struct r600_pipe_context *rctx)
rctx->context.create_vertex_elements_state = r600_create_vertex_elements;
rctx->context.create_vs_state = r600_create_shader_state;
rctx->context.bind_blend_state = r600_bind_blend_state;
- rctx->context.bind_depth_stencil_alpha_state = r600_bind_state;
+ rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state;
rctx->context.bind_fragment_sampler_states = r600_bind_ps_sampler;
rctx->context.bind_fs_state = r600_bind_ps_shader;
rctx->context.bind_rasterizer_state = r600_bind_rs_state;
@@ -1472,9 +1485,7 @@ void r600_pipe_set_buffer_resource(struct r600_pipe_context *rctx,
r600_pipe_state_add_reg(rstate, R_038004_RESOURCE0_WORD1,
rbuffer->bo_size - offset - 1, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_038008_RESOURCE0_WORD2,
-#ifdef PIPE_ARCH_BIG_ENDIAN
- S_038008_ENDIAN_SWAP(ENDIAN_8IN32) |
-#endif
+ S_038008_ENDIAN_SWAP(r600_endian_swap(32)) |
S_038008_STRIDE(stride), 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_03800C_RESOURCE0_WORD3,
0x00000000, 0xFFFFFFFF, NULL);
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index 997c9a597ee..de1b811ce89 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -28,9 +28,49 @@
#include <util/u_format.h>
#include <pipebuffer/pb_buffer.h>
#include "pipe/p_shader_tokens.h"
+#include "r600_formats.h"
#include "r600_pipe.h"
#include "r600d.h"
+static int r600_conv_pipe_prim(unsigned pprim, unsigned *prim)
+{
+ switch (pprim) {
+ case PIPE_PRIM_POINTS:
+ *prim = V_008958_DI_PT_POINTLIST;
+ return 0;
+ case PIPE_PRIM_LINES:
+ *prim = V_008958_DI_PT_LINELIST;
+ return 0;
+ case PIPE_PRIM_LINE_STRIP:
+ *prim = V_008958_DI_PT_LINESTRIP;
+ return 0;
+ case PIPE_PRIM_LINE_LOOP:
+ *prim = V_008958_DI_PT_LINELOOP;
+ return 0;
+ case PIPE_PRIM_TRIANGLES:
+ *prim = V_008958_DI_PT_TRILIST;
+ return 0;
+ case PIPE_PRIM_TRIANGLE_STRIP:
+ *prim = V_008958_DI_PT_TRISTRIP;
+ return 0;
+ case PIPE_PRIM_TRIANGLE_FAN:
+ *prim = V_008958_DI_PT_TRIFAN;
+ return 0;
+ case PIPE_PRIM_POLYGON:
+ *prim = V_008958_DI_PT_POLYGON;
+ return 0;
+ case PIPE_PRIM_QUADS:
+ *prim = V_008958_DI_PT_QUADLIST;
+ return 0;
+ case PIPE_PRIM_QUAD_STRIP:
+ *prim = V_008958_DI_PT_QUADSTRIP;
+ return 0;
+ default:
+ fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pprim);
+ return -1;
+ }
+}
+
/* common state between evergreen and r600 */
void r600_bind_blend_state(struct pipe_context *ctx, void *state)
{
@@ -46,6 +86,21 @@ void r600_bind_blend_state(struct pipe_context *ctx, void *state)
r600_context_pipe_state_set(&rctx->ctx, rstate);
}
+void r600_bind_dsa_state(struct pipe_context *ctx, void *state)
+{
+ struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
+ struct r600_pipe_dsa *dsa = state;
+ struct r600_pipe_state *rstate;
+
+ if (state == NULL)
+ return;
+ rstate = &dsa->rstate;
+ rctx->states[rstate->id] = rstate;
+ rctx->alpha_ref = dsa->alpha_ref;
+ rctx->alpha_ref_dirty = true;
+ r600_context_pipe_state_set(&rctx->ctx, rstate);
+}
+
void r600_bind_rs_state(struct pipe_context *ctx, void *state)
{
struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state;
@@ -91,17 +146,6 @@ void r600_sampler_view_destroy(struct pipe_context *ctx,
FREE(resource);
}
-void r600_bind_state(struct pipe_context *ctx, void *state)
-{
- struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
- struct r600_pipe_state *rstate = (struct r600_pipe_state *)state;
-
- if (state == NULL)
- return;
- rctx->states[rstate->id] = rstate;
- r600_context_pipe_state_set(&rctx->ctx, rstate);
-}
-
void r600_delete_state(struct pipe_context *ctx, void *state)
{
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
@@ -276,8 +320,25 @@ void r600_delete_vs_shader(struct pipe_context *ctx, void *state)
free(shader);
}
+static void r600_update_alpha_ref(struct r600_pipe_context *rctx)
+{
+ unsigned alpha_ref = rctx->alpha_ref;
+ struct r600_pipe_state rstate;
+
+ if (!rctx->alpha_ref_dirty)
+ return;
+
+ rstate.nregs = 0;
+ if (rctx->export_16bpc)
+ alpha_ref &= ~0x1FFF;
+ r600_pipe_state_add_reg(&rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL);
+
+ r600_context_pipe_state_set(&rctx->ctx, &rstate);
+ rctx->alpha_ref_dirty = false;
+}
+
/* FIXME optimize away spi update when it's not needed */
-void r600_spi_update(struct r600_pipe_context *rctx)
+static void r600_spi_update(struct r600_pipe_context *rctx, unsigned prim)
{
struct r600_pipe_shader *shader = rctx->ps_shader;
struct r600_pipe_state rstate;
@@ -309,6 +370,12 @@ void r600_spi_update(struct r600_pipe_context *rctx)
r600_pipe_state_add_reg(&rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, tmp, 0xFFFFFFFF, NULL);
}
+
+ if (prim == PIPE_PRIM_QUADS || prim == PIPE_PRIM_QUAD_STRIP || prim == PIPE_PRIM_POLYGON) {
+ r600_pipe_state_add_reg(&rstate, R_028814_PA_SU_SC_MODE_CNTL,
+ S_028814_PROVOKING_VTX_LAST(1),
+ S_028814_PROVOKING_VTX_LAST(1), NULL);
+ }
r600_context_pipe_state_set(&rctx->ctx, &rstate);
}
@@ -472,16 +539,16 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
case 2:
vgt_draw_initiator = 0;
vgt_dma_index_type = 0;
-#ifdef PIPE_ARCH_BIG_ENDIAN
- vgt_dma_swap_mode = ENDIAN_8IN16;
-#endif
+ if (R600_BIG_ENDIAN) {
+ vgt_dma_swap_mode = ENDIAN_8IN16;
+ }
break;
case 4:
vgt_draw_initiator = 0;
vgt_dma_index_type = 1;
-#ifdef PIPE_ARCH_BIG_ENDIAN
- vgt_dma_swap_mode = ENDIAN_8IN32;
-#endif
+ if (R600_BIG_ENDIAN) {
+ vgt_dma_swap_mode = ENDIAN_8IN32;
+ }
break;
case 0:
vgt_draw_initiator = 2;
@@ -508,7 +575,8 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
return;
}
- r600_spi_update(rctx);
+ r600_update_alpha_ref(rctx);
+ r600_spi_update(rctx, draw.info.mode);
mask = 0;
for (int i = 0; i < rctx->framebuffer.nr_cbufs; i++) {
diff --git a/src/gallium/drivers/r600/r600_state_inlines.h b/src/gallium/drivers/r600/r600_state_inlines.h
index 5eabfdc2bc6..39c647835a6 100644
--- a/src/gallium/drivers/r600/r600_state_inlines.h
+++ b/src/gallium/drivers/r600/r600_state_inlines.h
@@ -343,7 +343,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format)
case PIPE_FORMAT_A8B8G8R8_UNORM:
case PIPE_FORMAT_X8B8G8R8_UNORM:
- // case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
+ /* case PIPE_FORMAT_R8SG8SB8UX8U_NORM: */
return V_0280A0_SWAP_STD_REV;
case PIPE_FORMAT_Z24X8_UNORM:
@@ -362,6 +362,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format)
case PIPE_FORMAT_B10G10R10A2_UNORM:
return V_0280A0_SWAP_ALT;
+ case PIPE_FORMAT_R11G11B10_FLOAT:
case PIPE_FORMAT_R16G16_UNORM:
case PIPE_FORMAT_R16G16_FLOAT:
case PIPE_FORMAT_R32_FLOAT:
@@ -465,6 +466,8 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format)
case PIPE_FORMAT_R16G16_UNORM:
return V_0280A0_COLOR_16_16;
+ case PIPE_FORMAT_R11G11B10_FLOAT:
+ return V_0280A0_COLOR_10_11_11_FLOAT;
/* 64-bit buffers. */
case PIPE_FORMAT_R16G16B16_USCALED:
@@ -499,60 +502,60 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format)
case PIPE_FORMAT_UYVY:
case PIPE_FORMAT_YUYV:
default:
- //R600_ERR("unsupported color format %d %s\n", format, util_format_name(format));
+ /* R600_ERR("unsupported color format %d %s\n", format, util_format_name(format)); */
return ~0; /* Unsupported. */
}
}
static INLINE uint32_t r600_colorformat_endian_swap(uint32_t colorformat)
{
-#ifdef PIPE_ARCH_BIG_ENDIAN
- switch(colorformat) {
- case V_0280A0_COLOR_4_4:
- return(ENDIAN_NONE);
-
- /* 8-bit buffers. */
- case V_0280A0_COLOR_8:
- return(ENDIAN_NONE);
-
- /* 16-bit buffers. */
- case V_0280A0_COLOR_5_6_5:
- case V_0280A0_COLOR_1_5_5_5:
- case V_0280A0_COLOR_4_4_4_4:
- case V_0280A0_COLOR_16:
- case V_0280A0_COLOR_8_8:
- return(ENDIAN_8IN16);
-
- /* 32-bit buffers. */
- case V_0280A0_COLOR_8_8_8_8:
- case V_0280A0_COLOR_2_10_10_10:
- case V_0280A0_COLOR_8_24:
- case V_0280A0_COLOR_24_8:
- case V_0280A0_COLOR_32_FLOAT:
- case V_0280A0_COLOR_16_16_FLOAT:
- case V_0280A0_COLOR_16_16:
- return(ENDIAN_8IN32);
-
- /* 64-bit buffers. */
- case V_0280A0_COLOR_16_16_16_16:
- case V_0280A0_COLOR_16_16_16_16_FLOAT:
- return(ENDIAN_8IN16);
-
- case V_0280A0_COLOR_32_32_FLOAT:
- case V_0280A0_COLOR_32_32:
- return(ENDIAN_8IN32);
-
- /* 128-bit buffers. */
- case V_0280A0_COLOR_32_32_32_FLOAT:
- case V_0280A0_COLOR_32_32_32_32_FLOAT:
- case V_0280A0_COLOR_32_32_32_32:
- return(ENDIAN_8IN32);
- default:
- return ENDIAN_NONE; /* Unsupported. */
+ if (R600_BIG_ENDIAN) {
+ switch(colorformat) {
+ case V_0280A0_COLOR_4_4:
+ return(ENDIAN_NONE);
+
+ /* 8-bit buffers. */
+ case V_0280A0_COLOR_8:
+ return(ENDIAN_NONE);
+
+ /* 16-bit buffers. */
+ case V_0280A0_COLOR_5_6_5:
+ case V_0280A0_COLOR_1_5_5_5:
+ case V_0280A0_COLOR_4_4_4_4:
+ case V_0280A0_COLOR_16:
+ case V_0280A0_COLOR_8_8:
+ return(ENDIAN_8IN16);
+
+ /* 32-bit buffers. */
+ case V_0280A0_COLOR_8_8_8_8:
+ case V_0280A0_COLOR_2_10_10_10:
+ case V_0280A0_COLOR_8_24:
+ case V_0280A0_COLOR_24_8:
+ case V_0280A0_COLOR_32_FLOAT:
+ case V_0280A0_COLOR_16_16_FLOAT:
+ case V_0280A0_COLOR_16_16:
+ return(ENDIAN_8IN32);
+
+ /* 64-bit buffers. */
+ case V_0280A0_COLOR_16_16_16_16:
+ case V_0280A0_COLOR_16_16_16_16_FLOAT:
+ return(ENDIAN_8IN16);
+
+ case V_0280A0_COLOR_32_32_FLOAT:
+ case V_0280A0_COLOR_32_32:
+ return(ENDIAN_8IN32);
+
+ /* 128-bit buffers. */
+ case V_0280A0_COLOR_32_32_32_FLOAT:
+ case V_0280A0_COLOR_32_32_32_32_FLOAT:
+ case V_0280A0_COLOR_32_32_32_32:
+ return(ENDIAN_8IN32);
+ default:
+ return ENDIAN_NONE; /* Unsupported. */
+ }
+ } else {
+ return ENDIAN_NONE;
}
-#else
- return ENDIAN_NONE;
-#endif
}
static INLINE boolean r600_is_sampler_format_supported(struct pipe_screen *screen, enum pipe_format format)
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index 690aeafcc52..77cdd8dc33d 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -892,13 +892,17 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen,
switch (format) {
case PIPE_FORMAT_RGTC1_SNORM:
+ case PIPE_FORMAT_LATC1_SNORM:
word4 |= sign_bit[0];
case PIPE_FORMAT_RGTC1_UNORM:
+ case PIPE_FORMAT_LATC1_UNORM:
result = FMT_BC4;
goto out_word4;
case PIPE_FORMAT_RGTC2_SNORM:
+ case PIPE_FORMAT_LATC2_SNORM:
word4 |= sign_bit[0] | sign_bit[1];
case PIPE_FORMAT_RGTC2_UNORM:
+ case PIPE_FORMAT_LATC2_UNORM:
result = FMT_BC5;
goto out_word4;
default:
@@ -935,6 +939,14 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen,
}
}
+ if (format == PIPE_FORMAT_R9G9B9E5_FLOAT) {
+ result = FMT_5_9_9_9_SHAREDEXP;
+ goto out_word4;
+ } else if (format == PIPE_FORMAT_R11G11B10_FLOAT) {
+ result = FMT_10_11_11_FLOAT;
+ goto out_word4;
+ }
+
for (i = 0; i < desc->nr_channels; i++) {
if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
@@ -1088,6 +1100,6 @@ 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;
}
diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h
index 2bff52bec8c..8296b52eb94 100644
--- a/src/gallium/drivers/r600/r600d.h
+++ b/src/gallium/drivers/r600/r600d.h
@@ -3461,9 +3461,4 @@
#define SQ_TEX_INST_SAMPLE_L 0x11
#define SQ_TEX_INST_SAMPLE_C 0x18
-#define ENDIAN_NONE 0
-#define ENDIAN_8IN16 1
-#define ENDIAN_8IN32 2
-#define ENDIAN_8IN64 3
-
#endif