float scale, offset;
CS_LOCALS(r300);
- BEGIN_CS(18 + (rs->polygon_offset_enable ? 5 : 0));
+ BEGIN_CS(20 + (rs->polygon_offset_enable ? 5 : 0));
OUT_CS_REG(R300_VAP_CNTL_STATUS, rs->vap_control_status);
+
+ OUT_CS_REG(R300_GB_AA_CONFIG, rs->antialiasing_config);
+
OUT_CS_REG(R300_GA_POINT_SIZE, rs->point_size);
OUT_CS_REG_SEQ(R300_GA_POINT_MINMAX, 2);
OUT_CS(rs->point_minmax);
maxy = MIN2(maxy, scissor->maxy);
}
+ /* Special case for zero-area scissor.
+ *
+ * We can't allow the variables maxx and maxy to be zero because they are
+ * subtracted from later in the code, which would cause emitting ~0 and
+ * making the kernel checker angry.
+ *
+ * Let's consider we change maxx and maxy to 1, which is effectively
+ * a one-pixel area. We must then change minx and miny to a number which is
+ * greater than 1 to get the zero area back. */
+ if (!maxx || !maxy) {
+ minx = 2;
+ miny = 2;
+ maxx = 1;
+ maxy = 1;
+ }
+
if (r300screen->caps->is_r500) {
top_left =
(minx << R300_SCISSORS_X_SHIFT) |
END_CS;
}
-static boolean r300_validate_aos(struct r300_context *r300)
-{
- struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
- struct pipe_vertex_element *velem = r300->vertex_element;
- int i;
-
- /* Check if formats and strides are aligned to the size of DWORD. */
- for (i = 0; i < r300->vertex_element_count; i++) {
- if (vbuf[velem[i].vertex_buffer_index].stride % 4 != 0 ||
- util_format_get_blocksize(velem[i].src_format) % 4 != 0) {
- return FALSE;
- }
- }
- return TRUE;
-}
-
void r300_emit_aos(struct r300_context* r300, unsigned offset)
{
struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer;
unsigned packet_size = (aos_count * 3 + 1) / 2;
CS_LOCALS(r300);
- /* XXX Move this checking to a more approriate place. */
- if (!r300_validate_aos(r300)) {
- /* XXX We should fallback using Draw. */
- assert(0);
- }
-
BEGIN_CS(2 + packet_size + aos_count * 2);
OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size);
OUT_CS(aos_count);
END_CS;
}
-/* Emit all dirty state. */
-void r300_emit_dirty_state(struct r300_context* r300)
+void r300_emit_buffer_validate(struct r300_context *r300)
{
- struct r300_screen* r300screen = r300_screen(r300->context.screen);
struct r300_texture* tex;
- struct r300_atom* atom;
- unsigned i, dwords = 1024;
- int dirty_tex = 0;
+ unsigned i;
boolean invalid = FALSE;
- /* Check the required number of dwords against the space remaining in the
- * current CS object. If we need more, then flush. */
-
- foreach(atom, &r300->atom_list) {
- if (atom->dirty || atom->always_dirty) {
- dwords += atom->size;
- }
- }
-
- /* Make sure we have at least 2*1024 spare dwords. */
- /* XXX It would be nice to know the number of dwords we really need to
- * XXX emit. */
- if (!r300->winsys->check_cs(r300->winsys, dwords)) {
- r300->context.flush(&r300->context, 0, NULL);
- }
-
/* Clean out BOs. */
r300->winsys->reset_bos(r300->winsys);
invalid = TRUE;
goto validate;
}
+}
+
+/* Emit all dirty state. */
+void r300_emit_dirty_state(struct r300_context* r300)
+{
+ struct r300_screen* r300screen = r300_screen(r300->context.screen);
+ struct r300_atom* atom;
+ unsigned i, dwords = 1024;
+ int dirty_tex = 0;
+
+ /* Check the required number of dwords against the space remaining in the
+ * current CS object. If we need more, then flush. */
+
+ foreach(atom, &r300->atom_list) {
+ if (atom->dirty || atom->always_dirty) {
+ dwords += atom->size;
+ }
+ }
+
+ /* Make sure we have at least 2*1024 spare dwords. */
+ /* XXX It would be nice to know the number of dwords we really need to
+ * XXX emit. */
+ while (!r300->winsys->check_cs(r300->winsys, dwords)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ }
if (r300->dirty_state & R300_NEW_QUERY) {
r300_emit_query_start(r300);