summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorCorbin Simpson <[email protected]>2009-11-07 12:01:48 -0800
committerCorbin Simpson <[email protected]>2009-11-07 12:03:04 -0800
commitb7322fd874b99ca16d209c783c0b3db7c5f9a366 (patch)
treed40d8751b06669257c7a246f16f8d76d0978f6ef /src/gallium/drivers
parent57d77c6a4474beecdd22b97a8f5af6e4d2833d97 (diff)
parent0fe5f0c09abce9d540d51942eab08b2248243943 (diff)
Merge branch 'r300g-vbo'
This is an experimental HW TCL fastpath for r300g. It should run alright. Thanks to osiris for making this possible.
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/r300/Makefile1
-rw-r--r--src/gallium/drivers/r300/r300_context.c14
-rw-r--r--src/gallium/drivers/r300/r300_context.h26
-rw-r--r--src/gallium/drivers/r300/r300_cs.h4
-rw-r--r--src/gallium/drivers/r300/r300_emit.c50
-rw-r--r--src/gallium/drivers/r300/r300_emit.h2
-rw-r--r--src/gallium/drivers/r300/r300_render.c209
-rw-r--r--src/gallium/drivers/r300/r300_render.h2
-rw-r--r--src/gallium/drivers/r300/r300_state.c15
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c14
-rw-r--r--src/gallium/drivers/r300/r300_state_inlines.h16
-rw-r--r--src/gallium/drivers/r300/r300_vbo.c170
-rw-r--r--src/gallium/drivers/r300/r300_vbo.h36
13 files changed, 446 insertions, 113 deletions
diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile
index f73d80de882..d13bb7a36b1 100644
--- a/src/gallium/drivers/r300/Makefile
+++ b/src/gallium/drivers/r300/Makefile
@@ -17,6 +17,7 @@ C_SOURCES = \
r300_state.c \
r300_state_derived.c \
r300_state_invariant.c \
+ r300_vbo.c \
r300_vs.c \
r300_texture.c \
r300_tgsi_to_rc.c
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index f974147ea43..b520e5929e2 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -104,6 +104,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
struct r300_winsys* r300_winsys)
{
struct r300_context* r300 = CALLOC_STRUCT(r300_context);
+ struct r300_screen* r300screen = r300_screen(screen);
if (!r300)
return NULL;
@@ -119,9 +120,16 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300->context.clear = r300_clear;
- r300->context.draw_arrays = r300_draw_arrays;
- r300->context.draw_elements = r300_draw_elements;
- r300->context.draw_range_elements = r300_swtcl_draw_range_elements;
+ if (r300screen->caps->has_tcl)
+ {
+ r300->context.draw_arrays = r300_draw_arrays;
+ r300->context.draw_elements = r300_draw_elements;
+ r300->context.draw_range_elements = r300_draw_range_elements;
+ }
+ else
+ {
+ assert(0);
+ }
r300->context.is_texture_referenced = r300_is_texture_referenced;
r300->context.is_buffer_referenced = r300_is_buffer_referenced;
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 850e5a41c91..8d14c53f492 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -216,18 +216,19 @@ struct r300_texture {
struct r300_texture_state state;
};
-struct r300_vertex_format {
+struct r300_vertex_info {
/* Parent class */
struct vertex_info vinfo;
- /* R300_VAP_PROG_STREAK_CNTL_[0-7] */
- uint32_t vap_prog_stream_cntl[8];
- /* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */
- uint32_t vap_prog_stream_cntl_ext[8];
/* Map of vertex attributes into PVS memory for HW TCL,
* or GA memory for SW TCL. */
int vs_tab[16];
/* Map of rasterizer attributes from GB through RS to US. */
int fs_tab[16];
+
+ /* R300_VAP_PROG_STREAK_CNTL_[0-7] */
+ uint32_t vap_prog_stream_cntl[8];
+ /* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */
+ uint32_t vap_prog_stream_cntl_ext[8];
};
extern struct pipe_viewport_state r300_viewport_identity;
@@ -256,7 +257,7 @@ struct r300_context {
* depends on the combination of both currently loaded shaders. */
struct util_hash_table* shader_hash_table;
/* Vertex formatting information. */
- struct r300_vertex_format* vertex_info;
+ struct r300_vertex_info* vertex_info;
/* Various CSO state objects. */
/* Blend state. */
@@ -285,12 +286,6 @@ struct r300_context {
/* Texture states. */
struct r300_texture* textures[8];
int texture_count;
- /* Vertex buffers for Gallium. */
- struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
- int vertex_buffer_count;
- /* Vertex elements for Gallium. */
- struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS];
- int vertex_element_count;
/* Vertex shader. */
struct r300_vertex_shader* vs;
/* Viewport state. */
@@ -298,6 +293,13 @@ struct r300_context {
/* ZTOP state. */
struct r300_ztop_state ztop_state;
+ /* Vertex buffers for Gallium. */
+ struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
+ int vbuf_count;
+ /* Vertex elements for Gallium. */
+ struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
+ int aos_count;
+
/* Bitmask of dirty state objects. */
uint32_t dirty_state;
/* Flag indicating whether or not the HW is dirty. */
diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h
index 883f0a02dc5..86ba91db52e 100644
--- a/src/gallium/drivers/r300/r300_cs.h
+++ b/src/gallium/drivers/r300/r300_cs.h
@@ -34,8 +34,8 @@
#define MAX_CS_SIZE 64 * 1024 / 4
-#define VERY_VERBOSE_CS 0
-#define VERY_VERBOSE_REGISTERS 0
+#define VERY_VERBOSE_CS 1
+#define VERY_VERBOSE_REGISTERS 1
/* XXX stolen from radeon_drm.h */
#define RADEON_GEM_DOMAIN_CPU 0x1
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 69ce5966e80..ec1d521800c 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -582,7 +582,48 @@ void r300_emit_texture(struct r300_context* r300,
END_CS;
}
-void r300_emit_vertex_buffer(struct r300_context* r300)
+void r300_emit_aos(struct r300_context* r300, unsigned offset)
+{
+ struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
+ struct pipe_vertex_element *velem = r300->vertex_element;
+ CS_LOCALS(r300);
+ int i;
+ unsigned packet_size = (r300->aos_count * 3 + 1) / 2;
+ BEGIN_CS(2 + packet_size + r300->aos_count * 2);
+ OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size);
+ OUT_CS(r300->aos_count);
+ for (i = 0; i < r300->aos_count - 1; i += 2) {
+ int buf_num1 = velem[i].vertex_buffer_index;
+ int buf_num2 = velem[i+1].vertex_buffer_index;
+ assert(vbuf[buf_num1].stride % 4 == 0 && pf_get_size(velem[i].src_format) % 4 == 0);
+ assert(vbuf[buf_num2].stride % 4 == 0 && pf_get_size(velem[i+1].src_format) % 4 == 0);
+ OUT_CS((pf_get_size(velem[i].src_format) >> 2) | (vbuf[buf_num1].stride << 6) |
+ (pf_get_size(velem[i+1].src_format) << 14) | (vbuf[buf_num2].stride << 22));
+ OUT_CS(vbuf[buf_num1].buffer_offset + velem[i].src_offset +
+ offset * vbuf[buf_num1].stride);
+ OUT_CS(vbuf[buf_num2].buffer_offset + velem[i+1].src_offset +
+ offset * vbuf[buf_num2].stride);
+ }
+ if (r300->aos_count & 1) {
+ int buf_num = velem[i].vertex_buffer_index;
+ assert(vbuf[buf_num].stride % 4 == 0 && pf_get_size(velem[i].src_format) % 4 == 0);
+ OUT_CS((pf_get_size(velem[i].src_format) >> 2) | (vbuf[buf_num].stride << 6));
+ OUT_CS(vbuf[buf_num].buffer_offset + velem[i].src_offset +
+ offset * vbuf[buf_num].stride);
+ }
+
+ for (i = 0; i < r300->aos_count; i++) {
+ cs_winsys->write_cs_reloc(cs_winsys,
+ vbuf[velem[i].vertex_buffer_index].buffer,
+ RADEON_GEM_DOMAIN_GTT,
+ 0,
+ 0);
+ cs_count -= 2;
+ }
+ END_CS;
+}
+#if 0
+void r300_emit_draw_packet(struct r300_context* r300)
{
CS_LOCALS(r300);
@@ -605,6 +646,7 @@ void r300_emit_vertex_buffer(struct r300_context* r300)
OUT_CS_RELOC(r300->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0);
END_CS;
}
+#endif
void r300_emit_vertex_format_state(struct r300_context* r300)
{
@@ -771,8 +813,6 @@ void r300_emit_dirty_state(struct r300_context* r300)
return;
}
- r300_update_derived_state(r300);
-
/* Clean out BOs. */
r300->winsys->reset_bos(r300->winsys);
@@ -823,7 +863,7 @@ validate:
goto validate;
}
} else {
- debug_printf("No VBO while emitting dirty state!\n");
+ // debug_printf("No VBO while emitting dirty state!\n");
}
if (!r300->winsys->validate(r300->winsys)) {
r300->context.flush(&r300->context, 0, NULL);
@@ -951,7 +991,7 @@ validate:
*/
/* Finally, emit the VBO. */
- r300_emit_vertex_buffer(r300);
+ //r300_emit_vertex_buffer(r300);
r300->dirty_hw++;
}
diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h
index 6befca72ced..7c83c5166de 100644
--- a/src/gallium/drivers/r300/r300_emit.h
+++ b/src/gallium/drivers/r300/r300_emit.h
@@ -29,6 +29,8 @@
struct rX00_fragment_program_code;
struct r300_vertex_program_code;
+void r300_emit_aos(struct r300_context* r300, unsigned offset);
+
void r300_emit_blend_state(struct r300_context* r300,
struct r300_blend_state* blend);
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index c36350d29e2..0df9a946102 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -20,6 +20,9 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/* r300_render: Vertex and index buffer primitive emission. Contains both
+ * HW TCL fastpath rendering, and SW TCL Draw-assisted rendering. */
+
#include "draw/draw_context.h"
#include "draw/draw_vbuf.h"
@@ -34,11 +37,12 @@
#include "r300_reg.h"
#include "r300_render.h"
#include "r300_state_derived.h"
+#include "r300_vbo.h"
/* r300_render: Vertex and index buffer primitive emission. */
#define R300_MAX_VBO_SIZE (1024 * 1024)
-static uint32_t r300_translate_primitive(unsigned prim)
+uint32_t r300_translate_primitive(unsigned prim)
{
switch (prim) {
case PIPE_PRIM_POINTS:
@@ -66,6 +70,94 @@ static uint32_t r300_translate_primitive(unsigned prim)
}
}
+static void r300_emit_draw_arrays(struct r300_context *r300,
+ unsigned mode,
+ unsigned count)
+{
+ CS_LOCALS(r300);
+
+ BEGIN_CS(4);
+ OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count);
+ OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
+ OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) |
+ r300_translate_primitive(mode));
+ END_CS;
+}
+
+static void r300_emit_draw_elements(struct r300_context *r300,
+ struct pipe_buffer* indexBuffer,
+ unsigned indexSize,
+ unsigned minIndex,
+ unsigned maxIndex,
+ unsigned mode,
+ 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((start * indexSize) % 4 == 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) {
+ 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 {
+ 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(offset_dwords);
+ OUT_CS_RELOC(indexBuffer, count_dwords,
+ RADEON_GEM_DOMAIN_GTT, 0, 0);
+
+ END_CS;
+}
+
+
+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;
+
+validate:
+ for (int i = 0; i < vbuf_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);
+ return r300->winsys->validate(r300->winsys);
+ }
+
+ return TRUE;
+}
+
/* This is the fast-path drawing & emission for HW TCL. */
boolean r300_draw_range_elements(struct pipe_context* pipe,
struct pipe_buffer* indexBuffer,
@@ -77,87 +169,31 @@ boolean r300_draw_range_elements(struct pipe_context* pipe,
unsigned count)
{
struct r300_context* r300 = r300_context(pipe);
- uint32_t prim = r300_translate_primitive(mode);
- struct pipe_vertex_buffer* aos = r300->vertex_buffers;
- unsigned aos_count = r300->vertex_buffer_count;
- short* indices;
- unsigned packet_size;
- unsigned i;
- bool invalid = FALSE;
-
- CS_LOCALS(r300);
if (!u_trim_pipe_prim(mode, &count)) {
return FALSE;
}
-validate:
- for (i = 0; i < aos_count; i++) {
- if (!r300->winsys->add_buffer(r300->winsys, aos[i].buffer,
- RADEON_GEM_DOMAIN_GTT, 0)) {
- pipe->flush(pipe, 0, NULL);
- goto validate;
- }
- }
- if (!r300->winsys->validate(r300->winsys)) {
- pipe->flush(pipe, 0, NULL);
- if (invalid) {
- /* Well, hell. */
- debug_printf("r300: Stuck in validation loop, gonna quit now.");
- exit(1);
- }
- invalid = TRUE;
- goto validate;
+ if (count > 65535) {
+ return FALSE;
}
- r300_emit_dirty_state(r300);
+ r300_update_derived_state(r300);
- packet_size = (aos_count >> 1) * 3 + (aos_count & 1) * 2;
-
- BEGIN_CS(3 + packet_size + (aos_count * 2));
- OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size);
- OUT_CS(aos_count);
- for (i = 0; i < aos_count - 1; i += 2) {
- OUT_CS(aos[i].stride |
- (aos[i].stride << 8) |
- (aos[i + 1].stride << 16) |
- (aos[i + 1].stride << 24));
- OUT_CS(aos[i].buffer_offset + start * 4 * aos[i].stride);
- OUT_CS(aos[i + 1].buffer_offset + start * 4 * aos[i + 1].stride);
- }
- if (aos_count & 1) {
- OUT_CS(aos[i].stride | (aos[i].stride << 8));
- OUT_CS(aos[i].buffer_offset + start * 4 * aos[i].stride);
- }
- for (i = 0; i < aos_count; i++) {
- OUT_CS_RELOC(aos[i].buffer, 0, RADEON_GEM_DOMAIN_GTT, 0, 0);
+ if (!r300_setup_vertex_buffers(r300)) {
+ return FALSE;
}
- END_CS;
- if (indexBuffer) {
- indices = (short*)pipe_buffer_map(pipe->screen, indexBuffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ setup_vertex_attributes(r300);
- /* Set the starting point. */
- indices += start;
+ setup_index_buffer(r300, indexBuffer, indexSize);
- BEGIN_CS(2 + (count+1)/2);
- OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (count + 1)/2);
- OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | prim);
- for (i = 0; i < count - 1; i += 2) {
- OUT_CS(indices[i + 1] << 16 | indices[i]);
- }
- if (count % 2) {
- OUT_CS(indices[count - 1]);
- }
- END_CS;
- } else {
- BEGIN_CS(2);
- OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
- OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) |
- prim);
- END_CS;
- }
+ r300_emit_dirty_state(r300);
+
+ r300_emit_aos(r300, 0);
+
+ r300_emit_draw_elements(r300, indexBuffer, indexSize, minIndex, maxIndex,
+ mode, start, count);
return TRUE;
}
@@ -175,7 +211,31 @@ boolean r300_draw_elements(struct pipe_context* pipe,
boolean r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
unsigned start, unsigned count)
{
- return pipe->draw_elements(pipe, NULL, 0, mode, start, count);
+ struct r300_context* r300 = r300_context(pipe);
+
+ if (!u_trim_pipe_prim(mode, &count)) {
+ return FALSE;
+ }
+
+ if (count > 65535) {
+ return FALSE;
+ }
+
+ r300_update_derived_state(r300);
+
+ if (!r300_setup_vertex_buffers(r300)) {
+ return FALSE;
+ }
+
+ setup_vertex_attributes(r300);
+
+ r300_emit_dirty_state(r300);
+
+ r300_emit_aos(r300, start);
+
+ r300_emit_draw_arrays(r300, mode, count);
+
+ return TRUE;
}
/****************************************************************************
@@ -183,7 +243,8 @@ boolean r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
* keep these functions separated so that they are easier to locate. ~C. *
***************************************************************************/
-/* Draw-based drawing for SW TCL chipsets. */
+/* Draw-based drawing for SW TCL chipsets.
+ * XXX currently broken as fucking hell. */
boolean r300_swtcl_draw_range_elements(struct pipe_context* pipe,
struct pipe_buffer* indexBuffer,
unsigned indexSize,
@@ -193,6 +254,8 @@ boolean r300_swtcl_draw_range_elements(struct pipe_context* pipe,
unsigned start,
unsigned count)
{
+ assert(0);
+#if 0
struct r300_context* r300 = r300_context(pipe);
int i;
@@ -233,7 +296,7 @@ boolean r300_swtcl_draw_range_elements(struct pipe_context* pipe,
draw_set_mapped_element_buffer_range(r300->draw, 0, start,
start + count - 1, NULL);
}
-
+#endif
return TRUE;
}
diff --git a/src/gallium/drivers/r300/r300_render.h b/src/gallium/drivers/r300/r300_render.h
index 3d8f47ba75f..3f8ac1fb7a4 100644
--- a/src/gallium/drivers/r300/r300_render.h
+++ b/src/gallium/drivers/r300/r300_render.h
@@ -23,6 +23,8 @@
#ifndef R300_RENDER_H
#define R300_RENDER_H
+uint32_t r300_translate_primitive(unsigned prim);
+
boolean r300_draw_range_elements(struct pipe_context* pipe,
struct pipe_buffer* indexBuffer,
unsigned indexSize,
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 658a8cba132..e0b85ab768b 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -577,6 +577,8 @@ static void r300_set_sampler_textures(struct pipe_context* pipe,
if (count > 8) {
return;
}
+
+ r300->context.flush(&r300->context, 0, NULL);
for (i = 0; i < count; i++) {
if (r300->textures[i] != (struct r300_texture*)texture[i]) {
@@ -664,10 +666,9 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
{
struct r300_context* r300 = r300_context(pipe);
- memcpy(r300->vertex_buffers, buffers,
+ memcpy(r300->vertex_buffer, buffers,
sizeof(struct pipe_vertex_buffer) * count);
-
- r300->vertex_buffer_count = count;
+ r300->vbuf_count = count;
if (r300->draw) {
draw_flush(r300->draw);
@@ -681,10 +682,10 @@ static void r300_set_vertex_elements(struct pipe_context* pipe,
{
struct r300_context* r300 = r300_context(pipe);
- memcpy(r300->vertex_elements, elements,
- sizeof(struct pipe_vertex_element) * count);
-
- r300->vertex_element_count = count;
+ memcpy(r300->vertex_element,
+ elements,
+ sizeof(struct pipe_vertex_element) * count);
+ r300->aos_count = count;
if (r300->draw) {
draw_flush(r300->draw);
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 7d000e9e2da..14d7bb094c5 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -63,7 +63,7 @@ int r300_shader_key_compare(void* key1, void* key2) {
/* Set up the vs_tab and routes. */
static void r300_vs_tab_routes(struct r300_context* r300,
- struct r300_vertex_format* vformat)
+ struct r300_vertex_info* vformat)
{
struct r300_screen* r300screen = r300_screen(r300->context.screen);
struct vertex_info* vinfo = &vformat->vinfo;
@@ -219,7 +219,7 @@ static void r300_vs_tab_routes(struct r300_context* r300,
/* Update the PSC tables. */
static void r300_vertex_psc(struct r300_context* r300,
- struct r300_vertex_format* vformat)
+ struct r300_vertex_info* vformat)
{
struct r300_screen* r300screen = r300_screen(r300->context.screen);
struct vertex_info* vinfo = &vformat->vinfo;
@@ -282,7 +282,7 @@ static void r300_vertex_psc(struct r300_context* r300,
/* Set up the mappings from GB to US, for RS block. */
static void r300_update_fs_tab(struct r300_context* r300,
- struct r300_vertex_format* vformat)
+ struct r300_vertex_info* vformat)
{
struct tgsi_shader_info* info = &r300->fs->info;
int i, cols = 0, texs = 0, cols_emitted = 0;
@@ -455,13 +455,13 @@ static void r300_update_rs_block(struct r300_context* r300,
/* Update the vertex format. */
static void r300_update_derived_shader_state(struct r300_context* r300)
{
- struct r300_shader_key* key;
- struct r300_vertex_format* vformat;
+ struct r300_vertex_info* vformat;
struct r300_rs_block* rs_block;
- struct r300_shader_derived_value* value;
int i;
/*
+ struct r300_shader_key* key;
+ struct r300_shader_derived_value* value;
key = CALLOC_STRUCT(r300_shader_key);
key->vs = r300->vs;
key->fs = r300->fs;
@@ -486,7 +486,7 @@ static void r300_update_derived_shader_state(struct r300_context* r300)
} */
/* XXX This will be refactored ASAP. */
- vformat = CALLOC_STRUCT(r300_vertex_format);
+ vformat = CALLOC_STRUCT(r300_vertex_info);
rs_block = CALLOC_STRUCT(r300_rs_block);
for (i = 0; i < 16; i++) {
diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h
index 52b9650fc16..e53db3d0b55 100644
--- a/src/gallium/drivers/r300/r300_state_inlines.h
+++ b/src/gallium/drivers/r300/r300_state_inlines.h
@@ -434,8 +434,8 @@ r300_translate_vertex_data_type(enum pipe_format format) {
unsigned components = pf_component_count(format);
if (pf_layout(format) != PIPE_FORMAT_LAYOUT_RGBAZS) {
- debug_printf("r300: Bad format %s in %s\n", pf_name(format),
- __FUNCTION__);
+ debug_printf("r300: Bad format %s in %s:%d\n", pf_name(format),
+ __FUNCTION__, __LINE__);
return 0;
}
@@ -447,6 +447,8 @@ r300_translate_vertex_data_type(enum pipe_format format) {
result = R300_DATA_TYPE_FLOAT_1 + (components - 1);
break;
default:
+ debug_printf("r300: Bad format %s in %s:%d\n",
+ pf_name(format), __FUNCTION__, __LINE__);
assert(0);
}
break;
@@ -470,10 +472,16 @@ r300_translate_vertex_data_type(enum pipe_format format) {
}
break;
default:
+ debug_printf("r300: Bad format %s in %s:%d\n",
+ pf_name(format), __FUNCTION__, __LINE__);
+ debug_printf("r300: pf_size_x(format) == %d\n",
+ pf_size_x(format));
assert(0);
}
break;
default:
+ debug_printf("r300: Bad format %s in %s:%d\n",
+ pf_name(format), __FUNCTION__, __LINE__);
assert(0);
}
@@ -492,8 +500,8 @@ static INLINE uint16_t
r300_translate_vertex_data_swizzle(enum pipe_format format) {
if (pf_layout(format) != PIPE_FORMAT_LAYOUT_RGBAZS) {
- debug_printf("r300: Bad format %s in %s\n", pf_name(format),
- __FUNCTION__);
+ debug_printf("r300: Bad format %s in %s:%d\n",
+ pf_name(format), __FUNCTION__, __LINE__);
return 0;
}
diff --git a/src/gallium/drivers/r300/r300_vbo.c b/src/gallium/drivers/r300/r300_vbo.c
new file mode 100644
index 00000000000..d8b356a0617
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_vbo.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2009 Maciej Cencora <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* r300_vbo: Various helpers for emitting vertex buffers. Needs cleanup,
+ * refactoring, etc. */
+
+#include "r300_vbo.h"
+
+#include "pipe/p_format.h"
+
+#include "r300_cs.h"
+#include "r300_context.h"
+#include "r300_state_inlines.h"
+#include "r300_reg.h"
+#include "r300_winsys.h"
+
+static INLINE void setup_vertex_attribute(struct r300_vertex_info *vinfo,
+ struct pipe_vertex_element *vert_elem,
+ unsigned attr_num)
+{
+ uint16_t hw_fmt1, hw_fmt2;
+
+ hw_fmt1 = r300_translate_vertex_data_type(vert_elem->src_format) |
+ (attr_num << R300_DST_VEC_LOC_SHIFT);
+ hw_fmt2 = r300_translate_vertex_data_swizzle(vert_elem->src_format);
+
+ if (attr_num % 2 == 0)
+ {
+ vinfo->vap_prog_stream_cntl[attr_num >> 1] = hw_fmt1;
+ vinfo->vap_prog_stream_cntl_ext[attr_num >> 1] = hw_fmt2;
+ }
+ else
+ {
+ vinfo->vap_prog_stream_cntl[attr_num >> 1] |= hw_fmt1 << 16;
+ vinfo->vap_prog_stream_cntl_ext[attr_num >> 1] |= hw_fmt2 << 16;
+ }
+}
+
+static void finish_vertex_attribs_setup(struct r300_vertex_info *vinfo,
+ unsigned attribs_num)
+{
+ uint32_t last_vec_bit = (attribs_num % 2 == 0) ?
+ (R300_LAST_VEC << 16) : R300_LAST_VEC;
+
+ assert(attribs_num > 0 && attribs_num <= 16);
+ vinfo->vap_prog_stream_cntl[(attribs_num - 1) >> 1] |= last_vec_bit;
+}
+
+void setup_vertex_attributes(struct r300_context *r300)
+{
+ struct pipe_vertex_element *vert_elem;
+ int i;
+
+ for (i = 0; i < r300->aos_count; i++) {
+ vert_elem = &r300->vertex_element[i];
+ setup_vertex_attribute(r300->vertex_info, vert_elem, i);
+ }
+
+ finish_vertex_attribs_setup(r300->vertex_info, r300->aos_count);
+}
+
+/* XXX WTF are these doing? */
+static void setup_vertex_array(struct r300_context *r300, struct pipe_vertex_element *element)
+{
+}
+
+static void finish_vertex_arrays_setup(struct r300_context *r300)
+{
+}
+
+/* XXX move/integrate this with the checks in r300_state_inlines */
+static boolean format_is_supported(enum pipe_format format, int nr_components)
+{
+ if (pf_layout(format) != PIPE_FORMAT_LAYOUT_RGBAZS)
+ return FALSE;
+
+ if ((pf_size_x(format) != pf_size_y(format)) ||
+ (pf_size_x(format) != pf_size_z(format)) ||
+ (pf_size_x(format) != pf_size_w(format)))
+ return FALSE;
+
+ /* Following should be supported as long as stride is 4 bytes aligned */
+ if (pf_size_x(format) != 1 && nr_components != 4)
+ return FALSE;
+
+ if (pf_size_x(format) != 2 && !(nr_components == 2 || nr_components == 4))
+ return FALSE;
+
+ if (pf_size_x(format) == 3 || pf_size_x(format) > 4)
+ return FALSE;
+
+ return TRUE;
+}
+
+static INLINE int get_buffer_offset(struct r300_context *r300,
+ unsigned int buf_nr,
+ unsigned int elem_offset)
+{
+ return r300->vertex_buffer[buf_nr].buffer_offset + elem_offset;
+}
+
+/**
+ */
+static void setup_vertex_buffers(struct r300_context *r300)
+{
+ struct pipe_vertex_element *vert_elem;
+ int i;
+
+ for (i = 0; i < r300->aos_count; i++)
+ {
+ vert_elem = &r300->vertex_element[i];
+ if (!format_is_supported(vert_elem->src_format,
+ vert_elem->nr_components)) {
+ /* XXX use translate module to convert the data */
+ assert(0);
+ /*
+ struct pipe_buffer *buf;
+ const unsigned int max_index = r300->vertex_buffers[vert_elem->vertex_buffer_index].max_index;
+ buf = pipe_buffer_create(r300->context.screen, 4, usage, vert_elem->nr_components * max_index * sizeof(float));
+ */
+ }
+
+ if (get_buffer_offset(r300,
+ vert_elem->vertex_buffer_index,
+ vert_elem->src_offset) % 4) {
+ /* XXX need to align buffer */
+ assert(0);
+ }
+ setup_vertex_array(r300, vert_elem);
+ }
+
+ finish_vertex_arrays_setup(r300);
+}
+
+void setup_index_buffer(struct r300_context *r300,
+ struct pipe_buffer* indexBuffer,
+ unsigned indexSize)
+{
+ /* XXX I call BS; why is this different from the assert in r300_render? */
+ assert(indexSize = 2);
+
+ if (!r300->winsys->add_buffer(r300->winsys, indexBuffer,
+ RADEON_GEM_DOMAIN_GTT, 0)) {
+ assert(0);
+ }
+
+ if (!r300->winsys->validate(r300->winsys)) {
+ assert(0);
+ }
+}
diff --git a/src/gallium/drivers/r300/r300_vbo.h b/src/gallium/drivers/r300/r300_vbo.h
new file mode 100644
index 00000000000..7afa75899cf
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_vbo.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2009 Maciej Cencora <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef R300_VBO_H
+#define R300_VBO_H
+
+struct r300_context;
+struct pipe_buffer;
+
+void setup_vertex_attributes(struct r300_context *r300);
+
+void setup_index_buffer(struct r300_context *r300,
+ struct pipe_buffer* indexBuffer,
+ unsigned indexSize);
+
+#endif