#include "r300_reg.h"
#include "r300_screen.h"
#include "r300_screen_buffer.h"
+#include "r300_state.h"
#include "r300_state_inlines.h"
#include "r300_fs.h"
#include "r300_texture.h"
return (void*)fs;
}
-static void r300_mark_fs_code_dirty(struct r300_context *r300)
+void r300_mark_fs_code_dirty(struct r300_context *r300)
{
struct r300_fragment_shader* fs = r300_fs(r300);
const struct pipe_rasterizer_state* state)
{
struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state);
+ int i;
/* Copy rasterizer state for Draw. */
rs->rs = *state;
rs->clip_rule = state->scissor ? 0xAAAA : 0xFFFF;
+ /* Point sprites */
+ if (state->sprite_coord_enable) {
+ rs->stuffing_enable = R300_GB_POINT_STUFF_ENABLE;
+ for (i = 0; i < 8; i++) {
+ if (state->sprite_coord_enable & (1 << i))
+ rs->stuffing_enable |=
+ R300_GB_TEX_STR << (R300_GB_TEX0_SOURCE_SHIFT + (i*2));
+ }
+
+ rs->point_texcoord_left = 0.0f;
+ rs->point_texcoord_right = 1.0f;
+
+ switch (state->sprite_coord_mode) {
+ case PIPE_SPRITE_COORD_UPPER_LEFT:
+ rs->point_texcoord_top = 0.0f;
+ rs->point_texcoord_bottom = 1.0f;
+ break;
+ case PIPE_SPRITE_COORD_LOWER_LEFT:
+ rs->point_texcoord_top = 1.0f;
+ rs->point_texcoord_bottom = 0.0f;
+ break;
+ }
+ }
+
return (void*)rs;
}
{
struct r300_context* r300 = r300_context(pipe);
struct r300_rs_state* rs = (struct r300_rs_state*)state;
+ int last_sprite_coord_enable = r300->sprite_coord_enable;
if (r300->draw) {
draw_flush(r300->draw);
- draw_set_rasterizer_state(r300->draw, &rs->rs);
+ draw_set_rasterizer_state(r300->draw, &rs->rs, state);
}
if (rs) {
r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw;
+ r300->sprite_coord_enable = rs->rs.sprite_coord_enable;
} else {
r300->polygon_offset_enabled = FALSE;
+ r300->sprite_coord_enable = 0;
}
UPDATE_STATE(state, r300->rs_state);
- r300->rs_state.size = 19 + (r300->polygon_offset_enabled ? 5 : 0);
+ r300->rs_state.size = 26 + (r300->polygon_offset_enabled ? 5 : 0);
+
+ if (last_sprite_coord_enable != r300->sprite_coord_enable) {
+ r300->rs_block_state.dirty = TRUE;
+ }
}
/* Free rasterizer state. */
state->sampler_state_count = count;
r300->textures_state.dirty = TRUE;
-
- /* Pick a fragment shader based on the texture compare state. */
- if (r300->fs.state && count) {
- if (r300_pick_fragment_shader(r300)) {
- r300_mark_fs_code_dirty(r300);
- }
- }
}
static void r300_lacks_vertex_textures(struct pipe_context* pipe,
struct r300_texture *texture;
unsigned i;
unsigned tex_units = r300->screen->caps.num_tex_units;
- boolean is_r500 = r300->screen->caps.is_r500;
boolean dirty_tex = FALSE;
if (count > tex_units) {
/* A new sampler view (= texture)... */
dirty_tex = TRUE;
- /* R300-specific - set the texrect factor in the fragment shader */
+ /* Set the texrect factor in the fragment shader.
+ * Needed for RECT and NPOT fallback. */
texture = r300_texture(views[i]->texture);
- if (!is_r500 && texture->uses_pitch) {
+ if (texture->uses_pitch) {
r300->fs_rc_constant_state.dirty = TRUE;
}
}
}
if (vbo->max_index == ~0) {
- /* Bogus value from broken state tracker; hax it. */
- /* TODO - more hax - fixes doom3 from almos on irc */
- if (!vbo->stride) {
- fprintf(stderr, "r300: got a VBO with stride 0 fixing up to stide 4\n");
- vbo->stride = 4;
- }
- vbo->max_index =
- (vbo->buffer->width0 - vbo->buffer_offset) / vbo->stride;
+ /* if no VBO stride then only one vertex value so max index is 1 */
+ /* should think about converting to VS constants like svga does */
+ if (!vbo->stride)
+ vbo->max_index = 1;
+ else
+ vbo->max_index =
+ (vbo->buffer->width0 - vbo->buffer_offset) / vbo->stride;
}
max_index = MIN2(vbo->max_index, max_index);
if (r300->screen->caps.has_tcl) {
r300->vs_state.dirty = TRUE;
- r300->vs_state.size = vs->code.length + 9;
+ r300->vs_state.size =
+ vs->code.length + 9 +
+ (vs->immediates_count ? vs->immediates_count * 4 + 3 : 0);
- r300->pvs_flush.dirty = TRUE;
+ if (vs->externals_count) {
+ r300->vs_constants.dirty = TRUE;
+ r300->vs_constants.size = vs->externals_count * 4 + 3;
+ } else {
+ r300->vs_constants.size = 0;
+ }
- r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS;
+ r300->pvs_flush.dirty = TRUE;
} else {
draw_flush(r300->draw);
draw_bind_vertex_shader(r300->draw,
switch (shader) {
case PIPE_SHADER_VERTEX:
- cbuf = &r300->shader_constants[PIPE_SHADER_VERTEX];
+ cbuf = (struct r300_constant_buffer*)r300->vs_constants.state;
max_size = 256;
break;
case PIPE_SHADER_FRAGMENT:
break;
default:
assert(0);
+ return;
}
if (buf == NULL || buf->width0 == 0 ||
if (shader == PIPE_SHADER_VERTEX) {
if (r300->screen->caps.has_tcl) {
- r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS;
+ if (r300->vs_constants.size) {
+ r300->vs_constants.dirty = TRUE;
+ }
r300->pvs_flush.dirty = TRUE;
} else if (r300->draw) {
draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX,