unsigned count)
{
CS_LOCALS(r300);
- assert(count < 65536);
BEGIN_CS(4);
OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count);
unsigned start,
unsigned count)
{
+ uint32_t count_dwords;
+ uint32_t offset_dwords = indexSize * start / sizeof(uint32_t);
CS_LOCALS(r300);
+
+ /* XXX most of these are stupid */
assert(indexSize == 4 || indexSize == 2);
- assert(count < 65536);
assert((start * indexSize) % 4 == 0);
-
- uint32_t size_dwords;
- uint32_t skip_dwords = indexSize * start / sizeof(uint32_t);
- assert(skip_dwords == 0);
+ assert(offset_dwords == 0);
BEGIN_CS(10);
OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, maxIndex);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0);
if (indexSize == 4) {
- size_dwords = count + start;
+ count_dwords = count + start;
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
R300_VAP_VF_CNTL__INDEX_SIZE_32bit |
r300_translate_primitive(mode));
} else {
- size_dwords = (count + start + 1) / 2;
+ count_dwords = (count + start + 1) / 2;
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
r300_translate_primitive(mode));
}
+ /* INDX_BUFFER is a truly special packet3.
+ * Unlike most other packet3, where the offset is after the count,
+ * the order is reversed, so the relocation ends up carrying the
+ * size of the indexbuf instead of the offset.
+ *
+ * XXX Fix offset
+ */
OUT_CS_PKT3(R300_PACKET3_INDX_BUFFER, 2);
OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2) |
(0 << R300_INDX_BUFFER_SKIP_SHIFT));
- OUT_CS(skip_dwords);
- OUT_CS(size_dwords);
- /* XXX hax */
- cs_winsys->write_cs_reloc(cs_winsys,
- indexBuffer,
- RADEON_GEM_DOMAIN_GTT,
- 0,
- 0);
- cs_count -= 2;
+ OUT_CS(offset_dwords);
+ OUT_CS_RELOC(indexBuffer, count_dwords,
+ RADEON_GEM_DOMAIN_GTT, 0, 0);
END_CS;
}
-static boolean setup_vertex_buffers(struct r300_context *r300)
+static boolean r300_setup_vertex_buffers(struct r300_context *r300)
{
- unsigned vbuf_count = r300->aos_count;
- struct pipe_vertex_buffer *vbuf= r300->vertex_buffer;
- struct pipe_vertex_element *velem= r300->vertex_element;
- bool invalid = false;
+ struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
+ struct pipe_vertex_element *velem = r300->vertex_element;
validate:
- for (int i = 0; i < vbuf_count; i++) {
- if (!r300->winsys->add_buffer(r300->winsys, vbuf[velem[i].vertex_buffer_index].buffer,
+ for (int i = 0; i < r300->vertex_element_count; i++) {
+ if (!r300->winsys->add_buffer(r300->winsys,
+ vbuf[velem[i].vertex_buffer_index].buffer,
RADEON_GEM_DOMAIN_GTT, 0)) {
r300->context.flush(&r300->context, 0, NULL);
goto validate;
if (!r300->winsys->validate(r300->winsys)) {
r300->context.flush(&r300->context, 0, NULL);
- if (invalid) {
- /* Well, hell. */
- debug_printf("r300: Stuck in validation loop, gonna quit now.");
- exit(1);
- }
- invalid = true;
- goto validate;
+ return r300->winsys->validate(r300->winsys);
}
- return invalid;
+ return TRUE;
}
/* This is the fast-path drawing & emission for HW TCL. */
{
struct r300_context* r300 = r300_context(pipe);
- if (!u_trim_pipe_prim(mode, &count))
- return false;
+ if (!u_trim_pipe_prim(mode, &count)) {
+ return FALSE;
+ }
+
+ if (count > 65535) {
+ return FALSE;
+ }
r300_update_derived_state(r300);
- setup_vertex_buffers(r300);
+ if (!r300_setup_vertex_buffers(r300)) {
+ return FALSE;
+ }
setup_vertex_attributes(r300);
{
struct r300_context* r300 = r300_context(pipe);
- if (!u_trim_pipe_prim(mode, &count))
- return false;
+ if (!u_trim_pipe_prim(mode, &count)) {
+ return FALSE;
+ }
+
+ if (count > 65535) {
+ return FALSE;
+ }
r300_update_derived_state(r300);
- setup_vertex_buffers(r300);
+ if (!r300_setup_vertex_buffers(r300)) {
+ return FALSE;
+ }
setup_vertex_attributes(r300);
* keep these functions separated so that they are easier to locate. ~C. *
***************************************************************************/
-/* Draw-based drawing for SW TCL chipsets. */
+/* SW TCL arrays, using Draw. */
+boolean r300_swtcl_draw_arrays(struct pipe_context* pipe,
+ unsigned mode,
+ unsigned start,
+ unsigned count)
+{
+ struct r300_context* r300 = r300_context(pipe);
+ int i;
+
+ if (!u_trim_pipe_prim(mode, &count)) {
+ return FALSE;
+ }
+
+ for (i = 0; i < r300->vertex_buffer_count; i++) {
+ void* buf = pipe_buffer_map(pipe->screen,
+ r300->vertex_buffer[i].buffer,
+ PIPE_BUFFER_USAGE_CPU_READ);
+ draw_set_mapped_vertex_buffer(r300->draw, i, buf);
+ }
+
+ draw_set_mapped_element_buffer(r300->draw, 0, NULL);
+
+ draw_set_mapped_constant_buffer(r300->draw,
+ r300->shader_constants[PIPE_SHADER_VERTEX].constants,
+ r300->shader_constants[PIPE_SHADER_VERTEX].count *
+ (sizeof(float) * 4));
+
+ draw_arrays(r300->draw, mode, start, count);
+
+ for (i = 0; i < r300->vertex_buffer_count; i++) {
+ pipe_buffer_unmap(pipe->screen, r300->vertex_buffer[i].buffer);
+ draw_set_mapped_vertex_buffer(r300->draw, i, NULL);
+ }
+
+ return TRUE;
+}
+
+/* SW TCL elements, using Draw. */
boolean r300_swtcl_draw_range_elements(struct pipe_context* pipe,
struct pipe_buffer* indexBuffer,
unsigned indexSize,
unsigned start,
unsigned count)
{
- assert(0);
-#if 0
struct r300_context* r300 = r300_context(pipe);
int i;
for (i = 0; i < r300->vertex_buffer_count; i++) {
void* buf = pipe_buffer_map(pipe->screen,
- r300->vertex_buffers[i].buffer,
+ r300->vertex_buffer[i].buffer,
PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_vertex_buffer(r300->draw, i, buf);
}
- if (indexBuffer) {
- void* indices = pipe_buffer_map(pipe->screen, indexBuffer,
- PIPE_BUFFER_USAGE_CPU_READ);
- draw_set_mapped_element_buffer_range(r300->draw, indexSize,
- minIndex, maxIndex, indices);
- } else {
- draw_set_mapped_element_buffer(r300->draw, 0, NULL);
- }
+ void* indices = pipe_buffer_map(pipe->screen, indexBuffer,
+ PIPE_BUFFER_USAGE_CPU_READ);
+ draw_set_mapped_element_buffer_range(r300->draw, indexSize,
+ minIndex, maxIndex, indices);
draw_set_mapped_constant_buffer(r300->draw,
r300->shader_constants[PIPE_SHADER_VERTEX].constants,
draw_arrays(r300->draw, mode, start, count);
for (i = 0; i < r300->vertex_buffer_count; i++) {
- pipe_buffer_unmap(pipe->screen, r300->vertex_buffers[i].buffer);
+ pipe_buffer_unmap(pipe->screen, r300->vertex_buffer[i].buffer);
draw_set_mapped_vertex_buffer(r300->draw, i, NULL);
}
- if (indexBuffer) {
- pipe_buffer_unmap(pipe->screen, indexBuffer);
- draw_set_mapped_element_buffer_range(r300->draw, 0, start,
- start + count - 1, NULL);
- }
-#endif
+ pipe_buffer_unmap(pipe->screen, indexBuffer);
+ draw_set_mapped_element_buffer_range(r300->draw, 0, start,
+ start + count - 1, NULL);
+
return TRUE;
}