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/SConscript2
-rw-r--r--src/gallium/drivers/r300/r300_blit.c4
-rw-r--r--src/gallium/drivers/r300/r300_context.c21
-rw-r--r--src/gallium/drivers/r300/r300_context.h4
-rw-r--r--src/gallium/drivers/r300/r300_emit.c4
-rw-r--r--src/gallium/drivers/r300/r300_hyperz.c32
-rw-r--r--src/gallium/drivers/r300/r300_render.c98
-rw-r--r--src/gallium/drivers/r300/r300_screen.c84
-rw-r--r--src/gallium/drivers/r300/r300_state.c30
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c86
-rw-r--r--src/gallium/drivers/r300/r300_tgsi_to_rc.c5
11 files changed, 219 insertions, 151 deletions
diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript
index bf023daaa5..b49db93799 100644
--- a/src/gallium/drivers/r300/SConscript
+++ b/src/gallium/drivers/r300/SConscript
@@ -39,5 +39,7 @@ r300 = env.ConvenienceLibrary(
'r300_transfer.c',
] + r300compiler) + r300compiler
+env.Alias('r300', r300)
+
Export('r300')
diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index 91a374a583..0ac4e4c6f1 100644
--- a/src/gallium/drivers/r300/r300_blit.c
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -176,12 +176,12 @@ static void r300_clear(struct pipe_context* pipe,
fb->zsbuf ? r300_texture(fb->zsbuf->texture) : NULL;
uint32_t width = fb->width;
uint32_t height = fb->height;
- boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ);
+ boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ);
uint32_t hyperz_dcv = hyperz->zb_depthclearvalue;
/* Enable fast Z clear.
* The zbuffer must be in micro-tiled mode, otherwise it locks up. */
- if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && has_hyperz) {
+ if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && can_hyperz) {
hyperz_dcv = hyperz->zb_depthclearvalue =
r300_depth_clear_value(fb->zsbuf->format, depth, stencil);
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 624dadd07d..e8c09b214a 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -79,6 +79,9 @@ static void r300_release_referenced_objects(struct r300_context *r300)
NULL);
}
+ /* The dummy VBO. */
+ pipe_resource_reference(&r300->dummy_vb, NULL);
+
/* The SWTCL VBO. */
pipe_resource_reference(&r300->vbo, NULL);
@@ -184,7 +187,7 @@ static void r300_setup_atoms(struct r300_context* r300)
boolean has_tcl = r300->screen->caps.has_tcl;
boolean drm_2_3_0 = r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0);
boolean drm_2_6_0 = r300->rws->get_value(r300->rws, R300_VID_DRM_2_6_0);
- boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ);
+ boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ);
boolean has_hiz_ram = r300->screen->caps.hiz_ram > 0;
/* Create the actual atom list.
@@ -240,7 +243,7 @@ static void r300_setup_atoms(struct r300_context* r300)
/* TX. */
R300_INIT_ATOM(texture_cache_inval, 2);
R300_INIT_ATOM(textures_state, 0);
- if (has_hyperz) {
+ if (can_hyperz) {
/* HiZ Clear */
if (has_hiz_ram)
R300_INIT_ATOM(hiz_clear, 0);
@@ -488,6 +491,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
rtempl.target = PIPE_TEXTURE_2D;
rtempl.format = PIPE_FORMAT_I8_UNORM;
rtempl.bind = PIPE_BIND_SAMPLER_VIEW;
+ rtempl.usage = PIPE_USAGE_IMMUTABLE;
rtempl.width0 = 1;
rtempl.height0 = 1;
rtempl.depth0 = 1;
@@ -501,6 +505,19 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
pipe_resource_reference(&tex, NULL);
}
+ {
+ struct pipe_resource vb = {};
+ vb.target = PIPE_BUFFER;
+ vb.format = PIPE_FORMAT_R8_UNORM;
+ vb.bind = PIPE_BIND_VERTEX_BUFFER;
+ vb.usage = PIPE_USAGE_IMMUTABLE;
+ vb.width0 = sizeof(float) * 16;
+ vb.height0 = 1;
+ vb.depth0 = 1;
+
+ r300->dummy_vb = screen->resource_create(screen, &vb);
+ }
+
return &r300->context;
fail:
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index b59bc00261..7217c51b95 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -480,6 +480,10 @@ struct r300_context {
* dummy texture there. */
struct r300_sampler_view *texkill_sampler;
+ /* When no vertex buffer is set, this one is used instead to prevent
+ * hardlocks. */
+ struct pipe_resource *dummy_vb;
+
/* The currently active query. */
struct r300_query *query_current;
/* The saved query for blitter operations. */
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 3a1085d2dc..c187f115da 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -358,7 +358,7 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state;
struct r300_surface* surf;
unsigned i;
- boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ);
+ boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ);
CS_LOCALS(r300);
BEGIN_CS(size);
@@ -411,7 +411,7 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1);
OUT_CS_RELOC(surf->buffer, surf->pitch, 0, surf->domain);
- if (has_hyperz) {
+ if (can_hyperz) {
uint32_t surf_pitch;
struct r300_texture *tex;
int level = surf->base.level;
diff --git a/src/gallium/drivers/r300/r300_hyperz.c b/src/gallium/drivers/r300/r300_hyperz.c
index eb5b0c36f8..79f7f8abe9 100644
--- a/src/gallium/drivers/r300/r300_hyperz.c
+++ b/src/gallium/drivers/r300/r300_hyperz.c
@@ -44,10 +44,10 @@
static bool r300_get_sc_hz_max(struct r300_context *r300)
{
struct r300_dsa_state *dsa_state = r300->dsa_state.state;
- int func = dsa_state->z_stencil_control & 0x7;
+ int func = dsa_state->z_stencil_control & R300_ZS_MASK;
int ret = R300_SC_HYPERZ_MIN;
- if (func >= 4 && func <= 7)
+ if (func >= R300_ZS_GEQUAL && func <= R300_ZS_ALWAYS)
ret = R300_SC_HYPERZ_MAX;
return ret;
}
@@ -55,23 +55,26 @@ static bool r300_get_sc_hz_max(struct r300_context *r300)
static bool r300_zfunc_same_direction(int func1, int func2)
{
/* func1 is less/lessthan */
- if (func1 == 1 || func1 == 2)
- if (func2 == 3 || func2 == 4 || func2 == 5)
+ if ((func1 == R300_ZS_LESS || func1 == R300_ZS_LEQUAL) &&
+ (func2 == R300_ZS_EQUAL || func2 == R300_ZS_GEQUAL ||
+ func2 == R300_ZS_GREATER))
return FALSE;
- if (func2 == 1 || func2 == 2)
- if (func1 == 4 || func1 == 5)
+ /* func1 is greater/greaterthan */
+ if ((func1 == R300_ZS_GEQUAL || func1 == R300_ZS_GREATER) &&
+ (func2 == R300_ZS_LESS || func2 == R300_ZS_LEQUAL))
return FALSE;
+
return TRUE;
}
-
+
static int r300_get_hiz_min(struct r300_context *r300)
{
struct r300_dsa_state *dsa_state = r300->dsa_state.state;
- int func = dsa_state->z_stencil_control & 0x7;
+ int func = dsa_state->z_stencil_control & R300_ZS_MASK;
int ret = R300_HIZ_MIN;
- if (func == 1 || func == 2)
+ if (func == R300_ZS_LESS || func == R300_ZS_LEQUAL)
ret = R300_HIZ_MAX;
return ret;
}
@@ -112,13 +115,16 @@ static boolean r300_can_hiz(struct r300_context *r300)
}
/* depth comparison function - if just cleared save and return okay */
if (z->current_func == -1) {
- int func = dsa_state->z_stencil_control & 0x7;
+ int func = dsa_state->z_stencil_control & R300_ZS_MASK;
if (func != 0 && func != 7)
- z->current_func = dsa_state->z_stencil_control & 0x7;
+ z->current_func = dsa_state->z_stencil_control & R300_ZS_MASK;
} else {
/* simple don't change */
- if (!r300_zfunc_same_direction(z->current_func, (dsa_state->z_stencil_control & 0x7))) {
- DBG(r300, DBG_HYPERZ, "z func changed direction - disabling hyper-z %d -> %d\n", z->current_func, dsa_state->z_stencil_control);
+ if (!r300_zfunc_same_direction(z->current_func,
+ (dsa_state->z_stencil_control & R300_ZS_MASK))) {
+ DBG(r300, DBG_HYPERZ,
+ "z func changed direction - disabling hyper-z %d -> %d\n",
+ z->current_func, dsa_state->z_stencil_control);
return FALSE;
}
}
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 2f00c878f5..60700cf303 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -535,29 +535,8 @@ static void r300_draw_range_elements(struct pipe_context* pipe,
r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0);
unsigned short_count;
int buffer_offset = 0, index_offset = 0; /* for index bias emulation */
- boolean translate = FALSE;
unsigned new_offset;
- if (r300->skip_rendering) {
- return;
- }
-
- if (!u_trim_pipe_prim(mode, &count)) {
- return;
- }
-
- /* Index buffer range checking. */
- if ((start + count) * indexSize > indexBuffer->width0) {
- fprintf(stderr, "r300: Invalid index buffer range. Skipping rendering.\n");
- return;
- }
-
- /* Set up fallback for incompatible vertex layout if needed. */
- if (r300->incompatible_vb_layout || r300->velems->incompatible_layout) {
- r300_begin_vertex_translate(r300);
- translate = TRUE;
- }
-
if (indexBias && !r500_index_bias_supported(r300)) {
r300_split_index_bias(r300, indexBias, &buffer_offset, &index_offset);
}
@@ -603,10 +582,6 @@ done:
if (indexBuffer != orgIndexBuffer) {
pipe_resource_reference( &indexBuffer, NULL );
}
-
- if (translate) {
- r300_end_vertex_translate(r300);
- }
}
static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
@@ -617,21 +592,6 @@ static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
count > 65536 &&
r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0);
unsigned short_count;
- boolean translate = FALSE;
-
- if (r300->skip_rendering) {
- return;
- }
-
- if (!u_trim_pipe_prim(mode, &count)) {
- return;
- }
-
- /* Set up fallback for incompatible vertex layout if needed. */
- if (r300->incompatible_vb_layout || r300->velems->incompatible_layout) {
- r300_begin_vertex_translate(r300);
- translate = TRUE;
- }
r300_update_derived_state(r300);
@@ -642,7 +602,7 @@ static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
if (!r300_prepare_for_rendering(r300,
PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS,
NULL, 9, start, 0))
- goto done;
+ return;
if (alt_num_verts || count <= 65535) {
r300_emit_draw_arrays(r300, mode, count);
@@ -659,32 +619,53 @@ static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
if (!r300_prepare_for_rendering(r300,
PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9,
start, 0))
- goto done;
+ return;
}
} while (count);
}
}
-
-done:
- if (translate) {
- r300_end_vertex_translate(r300);
- }
}
static void r300_draw_vbo(struct pipe_context* pipe,
const struct pipe_draw_info *info)
{
struct r300_context* r300 = r300_context(pipe);
+ unsigned count = info->count;
+ boolean translate = FALSE;
+ boolean indexed = info->indexed && r300->index_buffer.buffer;
+ unsigned start_indexed = 0;
- if (!r300->velems->count || !r300->vertex_buffer_count)
- return;
+ if (r300->skip_rendering) {
+ return;
+ }
- if (info->indexed && r300->index_buffer.buffer) {
- unsigned offset;
+ if (!u_trim_pipe_prim(info->mode, &count)) {
+ return;
+ }
+ /* Index buffer range checking. */
+ if (indexed) {
assert(r300->index_buffer.offset % r300->index_buffer.index_size == 0);
- offset = r300->index_buffer.offset / r300->index_buffer.index_size;
+ /* Compute start for draw_elements, taking the offset into account. */
+ start_indexed =
+ info->start +
+ (r300->index_buffer.offset / r300->index_buffer.index_size);
+
+ if ((start_indexed + count) * r300->index_buffer.index_size >
+ r300->index_buffer.buffer->width0) {
+ fprintf(stderr, "r300: Invalid index buffer range. Skipping rendering.\n");
+ return;
+ }
+ }
+
+ /* Set up fallback for incompatible vertex layout if needed. */
+ if (r300->incompatible_vb_layout || r300->velems->incompatible_layout) {
+ r300_begin_vertex_translate(r300);
+ translate = TRUE;
+ }
+
+ if (indexed) {
r300_draw_range_elements(pipe,
r300->index_buffer.buffer,
r300->index_buffer.index_size,
@@ -692,14 +673,17 @@ static void r300_draw_vbo(struct pipe_context* pipe,
info->min_index,
info->max_index,
info->mode,
- info->start + offset,
- info->count);
- }
- else {
+ start_indexed,
+ count);
+ } else {
r300_draw_arrays(pipe,
info->mode,
info->start,
- info->count);
+ count);
+ }
+
+ if (translate) {
+ r300_end_vertex_translate(r300);
}
}
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index b448924f85..759d0e6696 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -32,6 +32,8 @@
#include "r300_winsys.h"
#include "r300_public.h"
+#include "draw/draw_context.h"
+
/* Return the identifier behind whom the brave coders responsible for this
* amalgamation of code, sweat, and duct tape, routinely obscure their names.
*
@@ -44,31 +46,31 @@ static const char* r300_get_vendor(struct pipe_screen* pscreen)
}
static const char* chip_families[] = {
- "R300",
- "R350",
- "R360",
- "RV350",
- "RV370",
- "RV380",
- "R420",
- "R423",
- "R430",
- "R480",
- "R481",
- "RV410",
- "RS400",
- "RC410",
- "RS480",
- "RS482",
- "RS600",
- "RS690",
- "RS740",
- "RV515",
- "R520",
- "RV530",
- "R580",
- "RV560",
- "RV570"
+ "ATI R300",
+ "ATI R350",
+ "ATI R360",
+ "ATI RV350",
+ "ATI RV370",
+ "ATI RV380",
+ "ATI R420",
+ "ATI R423",
+ "ATI R430",
+ "ATI R480",
+ "ATI R481",
+ "ATI RV410",
+ "ATI RS400",
+ "ATI RC410",
+ "ATI RS480",
+ "ATI RS482",
+ "ATI RS600",
+ "ATI RS690",
+ "ATI RS740",
+ "ATI RV515",
+ "ATI R520",
+ "ATI RV530",
+ "ATI R580",
+ "ATI RV560",
+ "ATI RV570"
};
static const char* r300_get_name(struct pipe_screen* pscreen)
@@ -125,6 +127,8 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_DEPTH_CLAMP: /* XXX implemented, but breaks Regnum Online */
case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
case PIPE_CAP_SHADER_STENCIL_EXPORT:
+ case PIPE_CAP_STREAM_OUTPUT:
+ case PIPE_CAP_PRIMITIVE_RESTART:
return 0;
/* Texturing. */
@@ -154,8 +158,8 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 0;
default:
- fprintf(stderr, "r300: Implementation error: Bad param %d\n",
- param);
+ debug_printf("r300: Warning: Unknown CAP %d in get_param.\n",
+ param);
return 0;
}
}
@@ -205,9 +209,18 @@ static int r300_get_shader_param(struct pipe_screen *pscreen, unsigned shader, e
return is_r500 ? 1 : 0;
case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
return 1;
+ case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
+ case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
+ case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
+ case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
+ return 0;
}
break;
case PIPE_SHADER_VERTEX:
+ if (!r300screen->caps.has_tcl) {
+ return draw_get_shader_param(shader, param);
+ }
+
switch (param)
{
case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
@@ -232,6 +245,12 @@ static int r300_get_shader_param(struct pipe_screen *pscreen, unsigned shader, e
return is_r500 ? 4 : 0; /* XXX guessed. */
case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
return 1;
+ case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
+ case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
+ case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
+ return 0;
+ case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
+ return 1;
default:
break;
}
@@ -264,9 +283,16 @@ static float r300_get_paramf(struct pipe_screen* pscreen, enum pipe_cap param)
return 16.0f;
case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
return 16.0f;
+ case PIPE_CAP_GUARD_BAND_LEFT:
+ case PIPE_CAP_GUARD_BAND_TOP:
+ case PIPE_CAP_GUARD_BAND_RIGHT:
+ case PIPE_CAP_GUARD_BAND_BOTTOM:
+ /* XXX I don't know what these should be but the least we can do is
+ * silence the potential error message */
+ return 0.0f;
default:
- fprintf(stderr, "r300: Implementation error: Bad paramf %d\n",
- param);
+ debug_printf("r300: Warning: Unknown CAP %d in get_paramf.\n",
+ param);
return 0.0f;
}
}
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index f2479a994c..247c22216e 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -684,7 +684,7 @@ void r300_mark_fb_state_dirty(struct r300_context *r300,
enum r300_fb_state_change change)
{
struct pipe_framebuffer_state *state = r300->fb_state.state;
- boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ);
+ boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ);
/* What is marked as dirty depends on the enum r300_fb_state_change. */
r300->gpu_flush.dirty = TRUE;
@@ -703,7 +703,7 @@ void r300_mark_fb_state_dirty(struct r300_context *r300,
r300->fb_state.size += 10;
else if (state->zsbuf) {
r300->fb_state.size += 10;
- if (has_hyperz)
+ if (can_hyperz)
r300->fb_state.size += r300->screen->caps.hiz_ram ? 8 : 4;
}
@@ -717,7 +717,7 @@ static void
struct r300_context* r300 = r300_context(pipe);
struct r300_aa_state *aa = (struct r300_aa_state*)r300->aa_state.state;
struct pipe_framebuffer_state *old_state = r300->fb_state.state;
- boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ);
+ boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ);
unsigned max_width, max_height, i;
uint32_t zbuffer_bpp = 0;
int blocksize;
@@ -764,7 +764,7 @@ static void
zbuffer_bpp = 24;
break;
}
- if (has_hyperz) {
+ if (can_hyperz) {
struct r300_surface *zs_surf = r300_surface(state->zsbuf);
struct r300_texture *tex;
int compress = r300->screen->caps.is_rv350 ? RV350_Z_COMPRESS_88 : R300_Z_COMPRESS_44;
@@ -1448,6 +1448,15 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
struct pipe_vertex_buffer *vbo;
unsigned i, max_index = (1 << 24) - 1;
boolean any_user_buffer = FALSE;
+ struct pipe_vertex_buffer dummy_vb = {0};
+
+ /* There must be at least one vertex buffer set, otherwise it locks up. */
+ if (!count) {
+ dummy_vb.buffer = r300->dummy_vb;
+ dummy_vb.max_index = r300->dummy_vb->width0 / 4;
+ buffers = &dummy_vb;
+ count = 1;
+ }
if (count == r300->vertex_buffer_count &&
memcmp(r300->vertex_buffer, buffers,
@@ -1601,6 +1610,14 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
struct r300_vertex_element_state *velems;
unsigned i;
enum pipe_format *format;
+ struct pipe_vertex_element dummy_attrib = {0};
+
+ /* R300 Programmable Stream Control (PSC) doesn't support 0 vertex elements. */
+ if (!count) {
+ dummy_attrib.src_format = PIPE_FORMAT_R8G8B8A8_UNORM;
+ attribs = &dummy_attrib;
+ count = 1;
+ }
assert(count <= PIPE_MAX_ATTRIBS);
velems = CALLOC_STRUCT(r300_vertex_element_state);
@@ -1667,7 +1684,8 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
* swizzles are already set up.
* Also compute the vertex size. */
for (i = 0; i < count; i++) {
- /* This is OK because we check for aligned strides too. */
+ /* This is OK because we check for aligned strides too
+ * elsewhere. */
velems->hw_format_size[i] =
align(util_format_get_blocksize(velems->hw_format[i]), 4);
velems->vertex_size_dwords += velems->hw_format_size[i] / 4;
@@ -1789,7 +1807,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
{
struct r300_context* r300 = r300_context(pipe);
struct r300_constant_buffer *cbuf;
- uint32_t *mapped = r300_buffer(buf)->user_buffer;
+ uint32_t *mapped;
switch (shader) {
case PIPE_SHADER_VERTEX:
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 904736ef06..1cff3483b5 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -25,6 +25,7 @@
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "util/u_pack_color.h"
#include "r300_context.h"
#include "r300_fs.h"
@@ -433,6 +434,8 @@ static void r300_update_rs_block(struct r300_context *r300)
fp_offset++;
col_count++;
DBG(r300, DBG_RS, "r300: Rasterized FACE written to FS.\n");
+ } else if (fs_inputs->face != ATTR_UNUSED) {
+ fprintf(stderr, "r300: ERROR: FS input FACE unassigned.\n");
}
/* Rasterize texture coordinates. */
@@ -484,12 +487,10 @@ static void r300_update_rs_block(struct r300_context *r300)
}
}
- if (DBG_ON(r300, DBG_RS)) {
- for (; i < ATTR_GENERIC_COUNT; i++) {
- if (fs_inputs->generic[i] != ATTR_UNUSED) {
- DBG(r300, DBG_RS,
- "r300: FS input generic %i unassigned.\n", i);
- }
+ for (; i < ATTR_GENERIC_COUNT; i++) {
+ if (fs_inputs->generic[i] != ATTR_UNUSED) {
+ fprintf(stderr, "r300: ERROR: FS input generic %i unassigned, "
+ "not enough hardware slots.\n", i);
}
}
@@ -520,7 +521,12 @@ static void r300_update_rs_block(struct r300_context *r300)
if (fs_inputs->fog != ATTR_UNUSED) {
fp_offset++;
- DBG(r300, DBG_RS, "r300: FS input fog unassigned.\n");
+ if (tex_count < 8) {
+ DBG(r300, DBG_RS, "r300: FS input fog unassigned.\n");
+ } else {
+ fprintf(stderr, "r300: ERROR: FS input fog unassigned, "
+ "not enough hardware slots.\n");
+ }
}
}
@@ -543,6 +549,11 @@ static void r300_update_rs_block(struct r300_context *r300)
fp_offset++;
tex_count++;
tex_ptr += 4;
+ } else {
+ if (fs_inputs->wpos != ATTR_UNUSED && tex_count >= 8) {
+ fprintf(stderr, "r300: ERROR: FS input WPOS unassigned, "
+ "not enough hardware slots.\n");
+ }
}
/* Invalidate the rest of the no-TCL (GA) stream locations. */
@@ -584,53 +595,56 @@ static uint32_t r300_get_border_color(enum pipe_format format,
const float border[4])
{
const struct util_format_description *desc;
- float border_swizzled[4] = {
- border[2],
- border[1],
- border[0],
- border[3]
- };
- uint32_t r;
+ float border_swizzled[4] = {0};
+ unsigned i;
+ union util_color uc = {0};
desc = util_format_description(format);
- /* We don't use util_pack_format because it does not handle the formats
- * we want, e.g. R4G4B4A4 is non-existent in Gallium. */
+ /* Apply inverse swizzle of the format. */
+ for (i = 0; i < 4; i++) {
+ switch (desc->swizzle[i]) {
+ case UTIL_FORMAT_SWIZZLE_X:
+ border_swizzled[2] = border[i];
+ break;
+ case UTIL_FORMAT_SWIZZLE_Y:
+ border_swizzled[1] = border[i];
+ break;
+ case UTIL_FORMAT_SWIZZLE_Z:
+ border_swizzled[0] = border[i];
+ break;
+ case UTIL_FORMAT_SWIZZLE_W:
+ border_swizzled[3] = border[i];
+ break;
+ }
+ }
+
switch (desc->channel[0].size) {
case 4:
- r = ((float_to_ubyte(border_swizzled[0]) & 0xf0) >> 4) |
- ((float_to_ubyte(border_swizzled[1]) & 0xf0) << 0) |
- ((float_to_ubyte(border_swizzled[2]) & 0xf0) << 4) |
- ((float_to_ubyte(border_swizzled[3]) & 0xf0) << 8);
+ util_pack_color(border_swizzled, PIPE_FORMAT_B4G4R4A4_UNORM, &uc);
break;
case 5:
if (desc->channel[1].size == 5) {
- r = ((float_to_ubyte(border_swizzled[0]) & 0xf8) >> 3) |
- ((float_to_ubyte(border_swizzled[1]) & 0xf8) << 2) |
- ((float_to_ubyte(border_swizzled[2]) & 0xf8) << 7) |
- ((float_to_ubyte(border_swizzled[3]) & 0x80) << 8);
+ util_pack_color(border_swizzled, PIPE_FORMAT_B5G5R5A1_UNORM, &uc);
} else if (desc->channel[1].size == 6) {
- r = ((float_to_ubyte(border_swizzled[0]) & 0xf8) >> 3) |
- ((float_to_ubyte(border_swizzled[1]) & 0xfc) << 3) |
- ((float_to_ubyte(border_swizzled[2]) & 0xf8) << 8);
+ util_pack_color(border_swizzled, PIPE_FORMAT_B5G6R5_UNORM, &uc);
} else {
assert(0);
- r = 0;
}
break;
default:
- /* I think the fat formats (16, 32) are specified
- * as the 8-bit ones. I am not sure how compressed formats
- * work here. */
- r = ((float_to_ubyte(border_swizzled[0]) & 0xff) << 0) |
- ((float_to_ubyte(border_swizzled[1]) & 0xff) << 8) |
- ((float_to_ubyte(border_swizzled[2]) & 0xff) << 16) |
- ((float_to_ubyte(border_swizzled[3]) & 0xff) << 24);
+ case 8:
+ util_pack_color(border_swizzled, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
+ break;
+
+ case 10:
+ util_pack_color(border_swizzled, PIPE_FORMAT_B10G10R10A2_UNORM, &uc);
+ break;
}
- return r;
+ return uc.ui;
}
static void r300_merge_textures_and_samplers(struct r300_context* r300)
diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
index a4911b9a2a..33448bf0de 100644
--- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c
+++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
@@ -363,10 +363,7 @@ void r300_tgsi_to_rc(struct tgsi_to_rc * ttr,
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
inst = &parser.FullToken.FullInstruction;
- /* This hack with the RET opcode woudn't work with
- * conditionals. */
- if (inst->Instruction.Opcode == TGSI_OPCODE_END ||
- inst->Instruction.Opcode == TGSI_OPCODE_RET) {
+ if (inst->Instruction.Opcode == TGSI_OPCODE_END) {
break;
}