#include "r300_screen_buffer.h"
#include "r300_state_inlines.h"
#include "r300_fs.h"
+#include "r300_texture.h"
#include "r300_vs.h"
#include "r300_winsys.h"
(state->stencil[0].writemask << R300_STENCILWRITEMASK_SHIFT);
if (state->stencil[1].enabled) {
+ dsa->two_sided = TRUE;
+
dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK;
dsa->z_stencil_control |=
(r300_translate_depth_stencil_function(state->stencil[1].func) <<
(r300_translate_stencil_op(state->stencil[1].zfail_op) <<
R300_S_BACK_ZFAIL_OP_SHIFT);
- if (caps->is_r500)
- {
+ dsa->stencil_ref_bf =
+ (state->stencil[1].valuemask << R300_STENCILMASK_SHIFT) |
+ (state->stencil[1].writemask << R300_STENCILWRITEMASK_SHIFT);
+
+ if (caps->is_r500) {
dsa->z_buffer_control |= R500_STENCIL_REFMASK_FRONT_BACK;
- dsa->stencil_ref_bf =
- (state->stencil[1].valuemask <<
- R300_STENCILMASK_SHIFT) |
- (state->stencil[1].writemask <<
- R300_STENCILWRITEMASK_SHIFT);
+ } else {
+ dsa->stencil_ref_bf_fallback =
+ (state->stencil[0].valuemask != state->stencil[1].valuemask ||
+ state->stencil[0].writemask != state->stencil[1].writemask);
}
}
}
return (void*)dsa;
}
+static void r300_update_stencil_ref_fallback_status(struct r300_context *r300)
+{
+ struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state;
+
+ if (r300->screen->caps.is_r500) {
+ return;
+ }
+
+ r300->stencil_ref_bf_fallback =
+ dsa->stencil_ref_bf_fallback ||
+ (dsa->two_sided &&
+ r300->stencil_ref.ref_value[0] != r300->stencil_ref.ref_value[1]);
+}
+
/* Bind DSA state. */
static void r300_bind_dsa_state(struct pipe_context* pipe,
void* state)
{
struct r300_context* r300 = r300_context(pipe);
+ if (!state) {
+ return;
+ }
+
UPDATE_STATE(state, r300->dsa_state);
+
+ r300_update_stencil_ref_fallback_status(r300);
}
/* Free DSA state. */
const struct pipe_stencil_ref* sr)
{
struct r300_context* r300 = r300_context(pipe);
+
r300->stencil_ref = *sr;
r300->dsa_state.dirty = TRUE;
+
+ r300_update_stencil_ref_fallback_status(r300);
}
/* This switcheroo is needed just because of goddamned MACRO_SWITCH. */
continue;
}
- tex = (struct r300_texture*)old_state->cbufs[i]->texture;
+ tex = r300_texture(old_state->cbufs[i]->texture);
if (tex) {
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
if (old_state->zsbuf &&
(!new_state->zsbuf ||
old_state->zsbuf->texture != new_state->zsbuf->texture)) {
- tex = (struct r300_texture*)old_state->zsbuf->texture;
+ tex = r300_texture(old_state->zsbuf->texture);
if (tex) {
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
/* Set tiling flags for new surfaces. */
for (i = 0; i < new_state->nr_cbufs; i++) {
- tex = (struct r300_texture*)new_state->cbufs[i]->texture;
+ tex = r300_texture(new_state->cbufs[i]->texture);
level = new_state->cbufs[i]->level;
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
tex->mip_macrotile[level]);
}
if (new_state->zsbuf) {
- tex = (struct r300_texture*)new_state->zsbuf->texture;
+ tex = r300_texture(new_state->zsbuf->texture);
level = new_state->zsbuf->level;
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
if (!!old_state->zsbuf != !!state->zsbuf) {
r300->dsa_state.dirty = TRUE;
}
- if (!r300->scissor_enabled) {
- r300->scissor_state.dirty = TRUE;
- }
r300_fb_update_tiling_flags(r300, r300->fb_state.state, state);
memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state));
r300->fb_state.size = (10 * state->nr_cbufs) + (2 * (4 - state->nr_cbufs)) +
- (state->zsbuf ? 10 : 0) + 8;
+ (state->zsbuf ? 10 : 0) + 11;
/* Polygon offset depends on the zbuffer bit depth. */
if (state->zsbuf && r300->polygon_offset_enabled) {
fs->state = *shader;
fs->state.tokens = tgsi_dup_tokens(shader->tokens);
- tgsi_scan_shader(shader->tokens, &fs->info);
- r300_shader_read_fs_inputs(&fs->info, &fs->inputs);
-
return (void*)fs;
}
rs->color_control = R300_SHADE_MODEL_SMOOTH;
}
+ rs->clip_rule = state->scissor ? 0xAAAA : 0xFFFF;
+
return (void*)rs;
}
{
struct r300_context* r300 = r300_context(pipe);
struct r300_rs_state* rs = (struct r300_rs_state*)state;
- boolean scissor_was_enabled = r300->scissor_enabled;
if (r300->draw) {
draw_flush(r300->draw);
if (rs) {
r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw;
- r300->scissor_enabled = rs->rs.scissor;
} else {
r300->polygon_offset_enabled = FALSE;
- r300->scissor_enabled = FALSE;
}
UPDATE_STATE(state, r300->rs_state);
- r300->rs_state.size = 17 + (r300->polygon_offset_enabled ? 5 : 0);
-
- if (scissor_was_enabled != r300->scissor_enabled) {
- r300->scissor_state.dirty = TRUE;
- }
+ r300->rs_state.size = 19 + (r300->polygon_offset_enabled ? 5 : 0);
}
/* Free rasterizer state. */
}
memcpy(state->sampler_states, states, sizeof(void*) * count);
- state->sampler_count = count;
+ state->sampler_state_count = count;
r300->textures_state.dirty = TRUE;
}
for (i = 0; i < count; i++) {
- if (state->fragment_sampler_views[i] != views[i]) {
- pipe_sampler_view_reference(&state->fragment_sampler_views[i],
- views[i]);
+ if (&state->sampler_views[i]->base != views[i]) {
+ pipe_sampler_view_reference(
+ (struct pipe_sampler_view**)&state->sampler_views[i],
+ views[i]);
if (!views[i]) {
continue;
dirty_tex = TRUE;
/* R300-specific - set the texrect factor in the fragment shader */
- texture = (struct r300_texture *)views[i]->texture;
+ texture = r300_texture(views[i]->texture);
if (!is_r500 && texture->uses_pitch) {
/* XXX It would be nice to re-emit just 1 constant,
* XXX not all of them */
}
for (i = count; i < tex_units; i++) {
- if (state->fragment_sampler_views[i]) {
- pipe_sampler_view_reference(&state->fragment_sampler_views[i],
- NULL);
+ if (state->sampler_views[i]) {
+ pipe_sampler_view_reference(
+ (struct pipe_sampler_view**)&state->sampler_views[i],
+ NULL);
}
}
- state->texture_count = count;
+ state->sampler_view_count = count;
r300->textures_state.dirty = TRUE;
static struct pipe_sampler_view *
r300_create_sampler_view(struct pipe_context *pipe,
- struct pipe_texture *texture,
+ struct pipe_resource *texture,
const struct pipe_sampler_view *templ)
{
- struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
-
- if (view) {
- *view = *templ;
- view->reference.count = 1;
- view->texture = NULL;
- pipe_texture_reference(&view->texture, texture);
- view->context = pipe;
- }
+ struct r300_sampler_view *view = CALLOC_STRUCT(r300_sampler_view);
+ struct r300_texture *tex = r300_texture(texture);
+ unsigned char swizzle[4];
+
+ if (view) {
+ view->base = *templ;
+ view->base.reference.count = 1;
+ view->base.context = pipe;
+ view->base.texture = NULL;
+ pipe_resource_reference(&view->base.texture, texture);
+
+ swizzle[0] = templ->swizzle_r;
+ swizzle[1] = templ->swizzle_g;
+ swizzle[2] = templ->swizzle_b;
+ swizzle[3] = templ->swizzle_a;
+
+ /* XXX Enable swizzles when they become supported. Now we get RGBA
+ * everywhere. And do testing! */
+ view->format = tex->tx_format;
+ view->format.format1 |= r300_translate_texformat(templ->format,
+ 0); /*swizzle);*/
+ if (r300_screen(pipe->screen)->caps.is_r500) {
+ view->format.format2 |= r500_tx_format_msb_bit(templ->format);
+ }
+ }
- return view;
+ return (struct pipe_sampler_view*)view;
}
static void
r300_sampler_view_destroy(struct pipe_context *pipe,
struct pipe_sampler_view *view)
{
- pipe_texture_reference(&view->texture, NULL);
+ pipe_resource_reference(&view->texture, NULL);
FREE(view);
}
memcpy(r300->scissor_state.state, state,
sizeof(struct pipe_scissor_state));
- if (r300->scissor_enabled) {
- r300->scissor_state.dirty = TRUE;
- }
+ r300->scissor_state.dirty = TRUE;
}
static void r300_set_viewport_state(struct pipe_context* pipe,
}
r300->viewport_state.dirty = TRUE;
- if (r300->fs && r300->fs->inputs.wpos != ATTR_UNUSED) {
+ if (r300->fs && r300->fs->shader->inputs.wpos != ATTR_UNUSED) {
r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
}
}
if (buffers[i].buffer) {
if (buffers[i].stride % 4 != 0) {
// XXX Shouldn't we align the buffer?
- fprintf(stderr, "r300_set_vertex_buffers: "
+ fprintf(stderr, "r300: set_vertex_buffers: "
"Unaligned buffer stride %i isn't supported.\n",
buffers[i].stride);
- assert(0);
abort();
}
}
vbo = (struct pipe_vertex_buffer*)&buffers[i];
/* Reference our buffer. */
- pipe_buffer_reference(&r300->vertex_buffer[i].buffer, vbo->buffer);
+ pipe_resource_reference(&r300->vertex_buffer[i].buffer, vbo->buffer);
/* Skip NULL buffers */
if (!buffers[i].buffer) {
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->size - vbo->buffer_offset) / vbo->stride;
+ (vbo->buffer->width0 - vbo->buffer_offset) / vbo->stride;
}
max_index = MIN2(vbo->max_index, max_index);
for (; i < r300->vertex_buffer_count; i++) {
/* Dereference any old buffers. */
- pipe_buffer_reference(&r300->vertex_buffer[i].buffer, NULL);
+ pipe_resource_reference(&r300->vertex_buffer[i].buffer, NULL);
}
memcpy(r300->vertex_buffer, buffers,
enum pipe_format format;
unsigned i;
- assert(velems->count <= 16);
+ if (velems->count > 16) {
+ fprintf(stderr, "r300: More than 16 vertex elements are not supported,"
+ " requested %i, using 16.\n", velems->count);
+ velems->count = 16;
+ }
/* Vertex shaders have no semantics on their inputs,
* so PSC should just route stuff based on the vertex elements,
struct r300_context* r300 = r300_context(pipe);
struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader);
- r300_vertex_shader_common_init(vs, shader);
+
+ /* Copy state directly into shader. */
+ vs->state = *shader;
+ vs->state.tokens = tgsi_dup_tokens(shader->tokens);
if (r300->screen->caps.has_tcl) {
- r300_translate_vertex_shader(r300, vs);
+ r300_translate_vertex_shader(r300, vs, vs->state.tokens);
} else {
vs->draw_vs = draw_create_vertex_shader(r300->draw, shader);
}
static void r300_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
- struct pipe_buffer *buf)
+ struct pipe_resource *buf)
{
struct r300_context* r300 = r300_context(pipe);
+ struct pipe_transfer *tr;
void *mapped;
int max_size = 0;
- if (buf == NULL || buf->size == 0 ||
- (mapped = pipe_buffer_map(pipe->screen, buf, PIPE_BUFFER_USAGE_CPU_READ)) == NULL)
+ if (buf == NULL || buf->width0 == 0 ||
+ (mapped = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &tr)) == NULL)
{
r300->shader_constants[shader].count = 0;
return;
}
- assert((buf->size % 4 * sizeof(float)) == 0);
+ assert((buf->width0 % 4 * sizeof(float)) == 0);
/* Check the size of the constant buffer. */
switch (shader) {
}
/* XXX Subtract immediates and RC_STATE_* variables. */
- if (buf->size > (sizeof(float) * 4 * max_size)) {
+ if (buf->width0 > (sizeof(float) * 4 * max_size)) {
fprintf(stderr, "r300: Max size of the constant buffer is "
"%i*4 floats.\n", max_size);
abort();
}
- memcpy(r300->shader_constants[shader].constants, mapped, buf->size);
- r300->shader_constants[shader].count = buf->size / (4 * sizeof(float));
- pipe_buffer_unmap(pipe->screen, buf);
+ memcpy(r300->shader_constants[shader].constants, mapped, buf->width0);
+ r300->shader_constants[shader].count = buf->width0 / (4 * sizeof(float));
+ pipe_buffer_unmap(pipe, buf, tr);
if (shader == PIPE_SHADER_VERTEX) {
if (r300->screen->caps.has_tcl) {
} else if (r300->draw) {
draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX,
0, r300->shader_constants[PIPE_SHADER_VERTEX].constants,
- buf->size);
+ buf->width0);
}
} else if (shader == PIPE_SHADER_FRAGMENT) {
r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;