summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r300
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r300')
-rw-r--r--src/gallium/drivers/r300/r300_emit.c15
-rw-r--r--src/gallium/drivers/r300/r300_fs.c1
-rw-r--r--src/gallium/drivers/r300/r300_screen.c4
-rw-r--r--src/gallium/drivers/r300/r300_state.c41
-rw-r--r--src/gallium/drivers/r300/r300_texture.c1
-rw-r--r--src/gallium/drivers/r300/r300_tgsi_to_rc.c8
-rw-r--r--src/gallium/drivers/r300/r300_tgsi_to_rc.h6
-rw-r--r--src/gallium/drivers/r300/r300_vs.c1
8 files changed, 60 insertions, 17 deletions
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 59709e7d64..d31336ed76 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -382,6 +382,7 @@ void r500_emit_fs_constant_buffer(struct r300_context* r300,
void r300_emit_fb_state(struct r300_context* r300, void* state)
{
struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state;
+ struct r300_screen* r300screen = r300_screen(r300->context.screen);
struct r300_texture* tex;
struct pipe_surface* surf;
int i;
@@ -400,10 +401,16 @@ void r300_emit_fb_state(struct r300_context* r300, void* state)
/* Set the number of colorbuffers. */
if (fb->nr_cbufs > 1) {
- OUT_CS_REG(R300_RB3D_CCTL,
- R300_RB3D_CCTL_NUM_MULTIWRITES(fb->nr_cbufs) |
- R300_RB3D_CCTL_INDEPENDENT_COLOR_CHANNEL_MASK_ENABLE |
- R300_RB3D_CCTL_INDEPENDENT_COLORFORMAT_ENABLE_ENABLE);
+ if (r300screen->caps->is_r500) {
+ OUT_CS_REG(R300_RB3D_CCTL,
+ R300_RB3D_CCTL_NUM_MULTIWRITES(fb->nr_cbufs) |
+ R300_RB3D_CCTL_INDEPENDENT_COLORFORMAT_ENABLE_ENABLE |
+ R300_RB3D_CCTL_INDEPENDENT_COLOR_CHANNEL_MASK_ENABLE);
+ } else {
+ OUT_CS_REG(R300_RB3D_CCTL,
+ R300_RB3D_CCTL_NUM_MULTIWRITES(fb->nr_cbufs) |
+ R300_RB3D_CCTL_INDEPENDENT_COLORFORMAT_ENABLE_ENABLE);
+ }
} else {
OUT_CS_REG(R300_RB3D_CCTL, 0x0);
}
diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
index 75a05498eb..ae4c62b2f1 100644
--- a/src/gallium/drivers/r300/r300_fs.c
+++ b/src/gallium/drivers/r300/r300_fs.c
@@ -179,6 +179,7 @@ static void r300_translate_fragment_shader(
/* Translate TGSI to our internal representation */
ttr.compiler = &compiler.Base;
ttr.info = &fs->info;
+ ttr.use_half_swizzles = TRUE;
r300_tgsi_to_rc(&ttr, fs->state.tokens);
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index da4ec542ad..13cd04a80c 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -186,8 +186,10 @@ static float r300_get_paramf(struct pipe_screen* pscreen, int param)
* rendering limits. 2048 pixels should be enough for anybody. */
if (r300screen->caps->is_r500) {
return 4096.0f;
+ } else if (r300screen->caps->is_r400) {
+ return 4021.0f;
} else {
- return 2048.0f;
+ return 2560.0f;
}
case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
return 16.0f;
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 8d68aa230b..4d158cff7c 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -501,6 +501,8 @@ static void
const struct pipe_framebuffer_state* state)
{
struct r300_context* r300 = r300_context(pipe);
+ struct r300_screen* r300screen = r300_screen(pipe->screen);
+ unsigned max_width, max_height;
uint32_t zbuffer_bpp = 0;
r300->fb_state.size = (10 * state->nr_cbufs) +
@@ -513,6 +515,20 @@ static void
return;
}
+ if (r300screen->caps->is_r500) {
+ max_width = max_height = 4096;
+ } else if (r300screen->caps->is_r400) {
+ max_width = max_height = 4021;
+ } else {
+ max_width = max_height = 2560;
+ }
+
+ if (state->width > max_width || state->height > max_height) {
+ debug_printf("r300: Implementation error: Render targets are too "
+ "big in %s, refusing to bind framebuffer state!\n", __FUNCTION__);
+ return;
+ }
+
if (r300->draw) {
draw_flush(r300->draw);
}
@@ -615,6 +631,7 @@ static void r300_set_polygon_stipple(struct pipe_context* pipe,
static void* r300_create_rs_state(struct pipe_context* pipe,
const struct pipe_rasterizer_state* state)
{
+ struct r300_screen* r300screen = r300_screen(pipe->screen);
struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state);
/* Copy rasterizer state for Draw. */
@@ -629,20 +646,28 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
/* If bypassing TCL, or if no TCL engine is present, turn off the HW TCL.
* Else, enable HW TCL and force Draw's TCL off. */
if (state->bypass_vs_clip_and_viewport ||
- !r300_screen(pipe->screen)->caps->has_tcl) {
+ !r300screen->caps->has_tcl) {
rs->vap_control_status |= R300_VAP_TCL_BYPASS;
}
rs->point_size = pack_float_16_6x(state->point_size) |
(pack_float_16_6x(state->point_size) << R300_POINTSIZE_X_SHIFT);
- /* set hw limits - clamping done by state tracker in vs or point_size
- XXX always need to emit this? */
- rs->point_minmax =
- ((int)(0.0 * 6.0) <<
- R300_GA_POINT_MINMAX_MIN_SHIFT) |
- ((int)(4096.0 * 6.0) <<
- R300_GA_POINT_MINMAX_MAX_SHIFT);
+ /* Point minimum and maximum sizes. This register has to be emitted,
+ * and it'd be a step backwards to put it in invariant state. */
+ if (r300screen->caps->is_r500) {
+ rs->point_minmax =
+ ((int)(0.0 * 6.0) << R300_GA_POINT_MINMAX_MIN_SHIFT) |
+ ((int)(4096.0 * 6.0) << R300_GA_POINT_MINMAX_MAX_SHIFT);
+ } else if (r300screen->caps->is_r400) {
+ rs->point_minmax =
+ ((int)(0.0 * 6.0) << R300_GA_POINT_MINMAX_MIN_SHIFT) |
+ ((int)(4021.0 * 6.0) << R300_GA_POINT_MINMAX_MAX_SHIFT);
+ } else {
+ rs->point_minmax =
+ ((int)(0.0 * 6.0) << R300_GA_POINT_MINMAX_MIN_SHIFT) |
+ ((int)(2560.0 * 6.0) << R300_GA_POINT_MINMAX_MAX_SHIFT);
+ }
rs->line_control = pack_float_16_6x(state->line_width) |
R300_GA_LINE_CNTL_END_TYPE_COMP;
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 67bf8ce13f..417a57384c 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -80,7 +80,6 @@ static void r300_setup_texture_state(struct r300_screen* screen, struct r300_tex
state->format2 |= R500_TXHEIGHT_BIT11;
}
}
- assert(is_r500 || (pt->width0 <= 2048 && pt->height0 <= 2048));
SCREEN_DBG(screen, DBG_TEX, "r300: Set texture state (%dx%d, %d levels)\n",
pt->width0, pt->height0, pt->last_level);
diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
index 941ec17016..aff4ddd4e2 100644
--- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c
+++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
@@ -29,6 +29,7 @@
#include "tgsi/tgsi_scan.h"
#include "tgsi/tgsi_util.h"
+#include "util/u_debug.h"
static unsigned translate_opcode(unsigned opcode)
{
@@ -144,7 +145,7 @@ static unsigned translate_opcode(unsigned opcode)
case TGSI_OPCODE_KIL: return RC_OPCODE_KIL;
}
- fprintf(stderr, "Unknown opcode: %i\n", opcode);
+ debug_printf("r300: Unknown TGSI/RC opcode: %i\n", opcode);
return RC_OPCODE_ILLEGAL_OPCODE;
}
@@ -306,7 +307,7 @@ static void handle_immediate(struct tgsi_to_rc * ttr,
for (i = 0; i < 4; i++) {
if (imm->u[i].Float == 0.0f) {
swizzle |= RC_SWIZZLE_ZERO << (i * 3);
- } else if (imm->u[i].Float == 0.5f) {
+ } else if (imm->u[i].Float == 0.5f && ttr->use_half_swizzles) {
swizzle |= RC_SWIZZLE_HALF << (i * 3);
} else if (imm->u[i].Float == 1.0f) {
swizzle |= RC_SWIZZLE_ONE << (i * 3);
@@ -329,7 +330,8 @@ static void handle_immediate(struct tgsi_to_rc * ttr,
}
}
-void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens)
+void r300_tgsi_to_rc(struct tgsi_to_rc * ttr,
+ const struct tgsi_token * tokens)
{
struct tgsi_parse_context parser;
unsigned imm_index = 0;
diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.h b/src/gallium/drivers/r300/r300_tgsi_to_rc.h
index 39b473c7bf..97641a954b 100644
--- a/src/gallium/drivers/r300/r300_tgsi_to_rc.h
+++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.h
@@ -23,6 +23,8 @@
#ifndef R300_TGSI_TO_RC_H
#define R300_TGSI_TO_RC_H
+#include "pipe/p_compiler.h"
+
struct radeon_compiler;
struct tgsi_full_declaration;
@@ -41,6 +43,10 @@ struct tgsi_to_rc {
int immediate_offset;
struct swizzled_imms * imms_to_swizzle;
unsigned imms_to_swizzle_count;
+
+ /* Vertex shaders have no half swizzles, and no way to handle them, so
+ * until rc grows proper support, indicate if they're safe to use. */
+ boolean use_half_swizzles;
};
void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens);
diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c
index fb81b2439b..a6786c321c 100644
--- a/src/gallium/drivers/r300/r300_vs.c
+++ b/src/gallium/drivers/r300/r300_vs.c
@@ -340,6 +340,7 @@ void r300_translate_vertex_shader(struct r300_context* r300,
/* Translate TGSI to our internal representation */
ttr.compiler = &compiler.Base;
ttr.info = &vs->info;
+ ttr.use_half_swizzles = FALSE;
r300_tgsi_to_rc(&ttr, vs->state.tokens);