if (r300->screen->caps.has_tcl) {
memcpy(r300->clip_state.state, state, sizeof(struct pipe_clip_state));
r300->clip_state.size = 29;
+
+ r300->clip_state.dirty = TRUE;
} else {
draw_flush(r300->draw);
draw_set_clip_state(r300->draw, state);
r300->clip_state.size = 2;
}
+}
- r300->clip_state.dirty = TRUE;
+static void
+r300_set_sample_mask(struct pipe_context *pipe,
+ unsigned sample_mask)
+{
}
+
/* Create a new depth, stencil, and alpha state based on the CSO dsa state.
*
* This contains the depth buffer, stencil buffer, alpha test, and such.
if (caps->is_r500) {
dsa->z_buffer_control |= R500_STENCIL_REFMASK_FRONT_BACK;
} else {
- dsa->stencil_ref_bf_fallback =
+ dsa->two_sided_stencil_ref =
(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)
}
UPDATE_STATE(state, r300->dsa_state);
-
- r300_update_stencil_ref_fallback_status(r300);
}
/* Free DSA state. */
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. */
level = new_state->cbufs[i]->level;
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
- tex->pitch[0],
- tex->microtile,
- tex->mip_macrotile[level]);
+ tex->pitch[0] * util_format_get_blocksize(tex->b.b.format),
+ tex->microtile,
+ tex->mip_macrotile[level]);
}
if (new_state->zsbuf) {
tex = r300_texture(new_state->zsbuf->texture);
level = new_state->zsbuf->level;
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
- tex->pitch[0],
- tex->microtile,
- tex->mip_macrotile[level]);
+ tex->pitch[0] * util_format_get_blocksize(tex->b.b.format),
+ tex->microtile,
+ tex->mip_macrotile[level]);
}
}
+static void r300_print_fb_surf_info(struct pipe_surface *surf, unsigned index,
+ const char *binding)
+{
+ struct pipe_resource *tex = surf->texture;
+ struct r300_texture *rtex = r300_texture(tex);
+
+ fprintf(stderr,
+ "r300: %s[%i] Dim: %ix%i, Offset: %i, ZSlice: %i, "
+ "Face: %i, Level: %i, Format: %s\n"
+
+ "r300: TEX: Macro: %s, Micro: %s, Pitch: %i, "
+ "Dim: %ix%ix%i, LastLevel: %i, Format: %s\n",
+
+ binding, index, surf->width, surf->height, surf->offset,
+ surf->zslice, surf->face, surf->level,
+ util_format_short_name(surf->format),
+
+ rtex->macrotile ? "YES" : " NO", rtex->microtile ? "YES" : " NO",
+ rtex->hwpitch[0], tex->width0, tex->height0, tex->depth0,
+ tex->last_level, util_format_short_name(tex->format));
+}
+
static void
r300_set_framebuffer_state(struct pipe_context* pipe,
const struct pipe_framebuffer_state* state)
{
struct r300_context* r300 = r300_context(pipe);
struct pipe_framebuffer_state *old_state = r300->fb_state.state;
- unsigned max_width, max_height;
+ unsigned max_width, max_height, i;
uint32_t zbuffer_bpp = 0;
if (state->nr_cbufs > 4) {
r300->rs_state.dirty = TRUE;
}
}
+
+ if (DBG_ON(r300, DBG_FB)) {
+ fprintf(stderr, "r300: set_framebuffer_state:\n");
+ for (i = 0; i < state->nr_cbufs; i++) {
+ r300_print_fb_surf_info(state->cbufs[i], i, "CB");
+ }
+ if (state->zsbuf) {
+ r300_print_fb_surf_info(state->zsbuf, 0, "ZB");
+ }
+ }
}
/* Create fragment shader state. */
int i;
float psiz;
- /* Copy rasterizer state for Draw. */
+ /* Copy rasterizer state. */
rs->rs = *state;
+ rs->rs_draw = *state;
+
+ /* Override some states for Draw. */
+ rs->rs_draw.sprite_coord_enable = 0; /* We can do this in HW. */
#ifdef PIPE_ARCH_LITTLE_ENDIAN
rs->vap_control_status = R300_VC_NO_SWAP;
R300_GA_LINE_CNTL_END_TYPE_COMP;
/* Enable polygon mode */
- if (state->fill_cw != PIPE_POLYGON_MODE_FILL ||
- state->fill_ccw != PIPE_POLYGON_MODE_FILL) {
+ if (state->fill_front != PIPE_POLYGON_MODE_FILL ||
+ state->fill_back != PIPE_POLYGON_MODE_FILL) {
rs->polygon_mode = R300_GA_POLY_MODE_DUAL;
}
- /* Radeons don't think in "CW/CCW", they think in "front/back". */
- if (state->front_winding == PIPE_WINDING_CW) {
- rs->cull_mode = R300_FRONT_FACE_CW;
-
- /* Polygon offset */
- if (state->offset_cw) {
- rs->polygon_offset_enable |= R300_FRONT_ENABLE;
- }
- if (state->offset_ccw) {
- rs->polygon_offset_enable |= R300_BACK_ENABLE;
- }
-
- /* Polygon mode */
- if (rs->polygon_mode) {
- rs->polygon_mode |=
- r300_translate_polygon_mode_front(state->fill_cw);
- rs->polygon_mode |=
- r300_translate_polygon_mode_back(state->fill_ccw);
- }
- } else {
+ /* Front face */
+ if (state->front_ccw)
rs->cull_mode = R300_FRONT_FACE_CCW;
+ else
+ rs->cull_mode = R300_FRONT_FACE_CW;
- /* Polygon offset */
- if (state->offset_ccw) {
- rs->polygon_offset_enable |= R300_FRONT_ENABLE;
- }
- if (state->offset_cw) {
- rs->polygon_offset_enable |= R300_BACK_ENABLE;
- }
+ /* Polygon offset */
+ if (util_get_offset(state, state->fill_front)) {
+ rs->polygon_offset_enable |= R300_FRONT_ENABLE;
+ }
+ if (util_get_offset(state, state->fill_back)) {
+ rs->polygon_offset_enable |= R300_BACK_ENABLE;
+ }
- /* Polygon mode */
- if (rs->polygon_mode) {
- rs->polygon_mode |=
- r300_translate_polygon_mode_front(state->fill_ccw);
- rs->polygon_mode |=
- r300_translate_polygon_mode_back(state->fill_cw);
- }
+ /* Polygon mode */
+ if (rs->polygon_mode) {
+ rs->polygon_mode |=
+ r300_translate_polygon_mode_front(state->fill_front);
+ rs->polygon_mode |=
+ r300_translate_polygon_mode_back(state->fill_back);
}
- if (state->front_winding & state->cull_mode) {
+
+ if (state->cull_face & PIPE_FACE_FRONT) {
rs->cull_mode |= R300_CULL_FRONT;
}
- if (~(state->front_winding) & state->cull_mode) {
+ if (state->cull_face & PIPE_FACE_BACK) {
rs->cull_mode |= R300_CULL_BACK;
}
int last_sprite_coord_enable = r300->sprite_coord_enable;
boolean last_two_sided_color = r300->two_sided_color;
- if (r300->draw) {
+ if (r300->draw && rs) {
draw_flush(r300->draw);
- draw_set_rasterizer_state(r300->draw, &rs->rs, state);
+ draw_set_rasterizer_state(r300->draw, &rs->rs_draw, state);
}
if (rs) {
- r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw;
+ r300->polygon_offset_enabled = (rs->rs.offset_point ||
+ rs->rs.offset_line ||
+ rs->rs.offset_tri);
r300->sprite_coord_enable = rs->rs.sprite_coord_enable;
r300->two_sided_color = rs->rs.light_twoside;
} else {
r300->viewport = *state;
+ if (r300->draw) {
+ draw_flush(r300->draw);
+ draw_set_viewport_state(r300->draw, state);
+ viewport->vte_control = R300_VTX_XY_FMT | R300_VTX_Z_FMT;
+ return;
+ }
+
/* Do the transform in HW. */
viewport->vte_control = R300_VTX_W0_FMT;
return;
}
- /* Check if the stride is aligned to the size of DWORD. */
- for (i = 0; i < count; i++) {
- if (buffers[i].buffer) {
- if (buffers[i].stride % 4 != 0) {
- // XXX Shouldn't we align the buffer?
- fprintf(stderr, "r300: set_vertex_buffers: "
- "Unaligned buffer stride %i isn't supported.\n",
- buffers[i].stride);
- abort();
+ if (r300->screen->caps.has_tcl) {
+ /* HW TCL. */
+ /* Check if the stride is aligned to the size of DWORD. */
+ for (i = 0; i < count; i++) {
+ if (buffers[i].buffer) {
+ if (buffers[i].stride % 4 != 0) {
+ // XXX Shouldn't we align the buffer?
+ fprintf(stderr, "r300: set_vertex_buffers: "
+ "Unaligned buffer stride %i isn't supported.\n",
+ buffers[i].stride);
+ abort();
+ }
}
}
- }
- for (i = 0; i < count; i++) {
- /* Why, yes, I AM casting away constness. How did you know? */
- vbo = (struct pipe_vertex_buffer*)&buffers[i];
+ for (i = 0; i < count; i++) {
+ /* Why, yes, I AM casting away constness. How did you know? */
+ vbo = (struct pipe_vertex_buffer*)&buffers[i];
- /* Reference our buffer. */
- pipe_resource_reference(&r300->vertex_buffer[i].buffer, vbo->buffer);
+ /* Skip NULL buffers */
+ if (!buffers[i].buffer) {
+ continue;
+ }
- /* Skip NULL buffers */
- if (!buffers[i].buffer) {
- continue;
- }
+ if (r300_buffer_is_user_buffer(vbo->buffer)) {
+ any_user_buffer = TRUE;
+ }
- if (r300_buffer_is_user_buffer(vbo->buffer)) {
- any_user_buffer = TRUE;
- }
+ if (vbo->max_index == ~0) {
+ /* 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;
+ }
- if (vbo->max_index == ~0) {
- /* 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);
}
- max_index = MIN2(vbo->max_index, max_index);
+ r300->any_user_vbs = any_user_buffer;
+ r300->vertex_buffer_max_index = max_index;
+
+ } else {
+ /* SW TCL. */
+ draw_flush(r300->draw);
+ draw_set_vertex_buffers(r300->draw, count, buffers);
}
+ /* Common code. */
+ for (i = 0; i < count; i++) {
+ /* Reference our buffer. */
+ pipe_resource_reference(&r300->vertex_buffer[i].buffer, buffers[i].buffer);
+ }
for (; i < r300->vertex_buffer_count; i++) {
/* Dereference any old buffers. */
pipe_resource_reference(&r300->vertex_buffer[i].buffer, NULL);
memcpy(r300->vertex_buffer, buffers,
sizeof(struct pipe_vertex_buffer) * count);
-
r300->vertex_buffer_count = count;
- r300->vertex_buffer_max_index = max_index;
- r300->any_user_vbs = any_user_buffer;
-
- if (r300->draw) {
- draw_flush(r300->draw);
- draw_set_vertex_buffers(r300->draw, count, buffers);
- }
}
-/* Update the PSC tables. */
+/* Initialize the PSC tables. */
static void r300_vertex_psc(struct r300_vertex_element_state *velems)
{
struct r300_vertex_stream_state *vstream = &velems->vertex_stream;
for (i = 0; i < velems->count; i++) {
format = velems->velem[i].src_format;
- type = r300_translate_vertex_data_type(format) |
- (i << R300_DST_VEC_LOC_SHIFT);
+ type = r300_translate_vertex_data_type(format);
+ if (type == R300_INVALID_FORMAT) {
+ fprintf(stderr, "r300: Bad vertex format %s.\n",
+ util_format_short_name(format));
+ assert(0);
+ abort();
+ }
+
+ type |= i << R300_DST_VEC_LOC_SHIFT;
swizzle = r300_translate_vertex_data_swizzle(format);
if (i & 1) {
abort();
}
}
-
}
}
return velems;
if (r300->draw) {
draw_flush(r300->draw);
draw_set_vertex_elements(r300->draw, velems->count, velems->velem);
+ return;
}
UPDATE_STATE(&velems->vertex_stream, r300->vertex_stream_state);
vs->state.tokens = tgsi_dup_tokens(shader->tokens);
if (r300->screen->caps.has_tcl) {
- r300_translate_vertex_shader(r300, vs, vs->state.tokens);
+ r300_init_vs_outputs(vs);
+ r300_translate_vertex_shader(r300, vs);
} else {
- vs->draw_vs = draw_create_vertex_shader(r300->draw, shader);
+ r300_draw_init_vertex_shader(r300->draw, vs);
}
return vs;
struct r300_constant_buffer *cbuf;
struct pipe_transfer *tr;
void *mapped;
- int max_size = 0;
+ int max_size = 0, max_size_bytes = 0, clamped_size = 0;
switch (shader) {
case PIPE_SHADER_VERTEX:
assert(0);
return;
}
+ max_size_bytes = max_size * 4 * sizeof(float);
if (buf == NULL || buf->width0 == 0 ||
(mapped = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &tr)) == NULL)
return;
}
- assert((buf->width0 % 4 * sizeof(float)) == 0);
+ if (shader == PIPE_SHADER_FRAGMENT ||
+ (shader == PIPE_SHADER_VERTEX && r300->screen->caps.has_tcl)) {
+ assert((buf->width0 % (4 * sizeof(float))) == 0);
- /* Check the size of the constant buffer. */
- /* XXX Subtract immediates and RC_STATE_* variables. */
- 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();
- }
+ /* Check the size of the constant buffer. */
+ /* XXX Subtract immediates and RC_STATE_* variables. */
+ if (buf->width0 > max_size_bytes) {
+ fprintf(stderr, "r300: Max size of the constant buffer is "
+ "%i*4 floats.\n", max_size);
+ }
+ clamped_size = MIN2(buf->width0, max_size_bytes);
- memcpy(cbuf->constants, mapped, buf->width0);
- cbuf->count = buf->width0 / (4 * sizeof(float));
- pipe_buffer_unmap(pipe, buf, tr);
+ memcpy(cbuf->constants, mapped, clamped_size);
+ cbuf->count = clamped_size / (4 * sizeof(float));
+ }
if (shader == PIPE_SHADER_VERTEX) {
if (r300->screen->caps.has_tcl) {
r300->pvs_flush.dirty = TRUE;
} else if (r300->draw) {
draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX,
- 0, cbuf->constants,
- buf->width0);
+ 0, mapped, buf->width0);
}
} else if (shader == PIPE_SHADER_FRAGMENT) {
r300->fs_constants.dirty = TRUE;
}
+
+ pipe_buffer_unmap(pipe, buf, tr);
}
void r300_init_state_functions(struct r300_context* r300)
r300->context.set_blend_color = r300_set_blend_color;
r300->context.set_clip_state = r300_set_clip_state;
+ r300->context.set_sample_mask = r300_set_sample_mask;
r300->context.set_constant_buffer = r300_set_constant_buffer;