#include "draw/draw_vertex.h"
+/**
+ * General-purpose fetch from user's vertex arrays, emit to driver's
+ * vertex buffer.
+ *
+ * XXX this is totally temporary.
+ */
+static void
+fetch_store_general( struct draw_context *draw,
+ float *out,
+ unsigned start,
+ unsigned count )
+{
+ const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render);
+ const unsigned nr_attrs = vinfo->num_attribs;
+ uint i, j;
+
+ const unsigned *pitch = draw->vertex_fetch.pitch;
+ const ubyte **src = draw->vertex_fetch.src_ptr;
+
+ for (i = start; i < count; i++) {
+ for (j = 0; j < nr_attrs; j++) {
+ const uint jj = vinfo->src_index[j];
+ const enum pipe_format srcFormat = draw->vertex_element[jj].src_format;
+ const ubyte *from = src[jj] + i * pitch[jj];
+ float attrib[4];
+
+ switch (srcFormat) {
+ case PIPE_FORMAT_R32G32B32A32_FLOAT:
+ {
+ float *f = (float *) from;
+ attrib[0] = f[0];
+ attrib[1] = f[1];
+ attrib[2] = f[2];
+ attrib[3] = f[3];
+ }
+ break;
+ case PIPE_FORMAT_R32G32B32_FLOAT:
+ {
+ float *f = (float *) from;
+ attrib[0] = f[0];
+ attrib[1] = f[1];
+ attrib[2] = f[2];
+ attrib[3] = 1.0;
+ }
+ break;
+ case PIPE_FORMAT_R32G32_FLOAT:
+ {
+ float *f = (float *) from;
+ attrib[0] = f[0];
+ attrib[1] = f[1];
+ attrib[2] = 0.0;
+ attrib[3] = 1.0;
+ }
+ break;
+ case PIPE_FORMAT_R32_FLOAT:
+ {
+ float *f = (float *) from;
+ attrib[0] = f[0];
+ attrib[1] = 0.0;
+ attrib[2] = 0.0;
+ attrib[3] = 1.0;
+ }
+ break;
+ default:
+ abort();
+ }
+
+ /* XXX this will probably only work for softpipe */
+ switch (vinfo->emit[j]) {
+ case EMIT_HEADER:
+ memset(out, 0, sizeof(struct vertex_header));
+ out += sizeof(struct vertex_header) / 4;
+ break;
+ case EMIT_4F:
+ out[0] = attrib[0];
+ out[1] = attrib[1];
+ out[2] = attrib[2];
+ out[3] = attrib[3];
+ out += 4;
+ break;
+ default:
+ abort();
+ }
+
+ }
+ }
+}
+
+
/* Example of a fetch/emit passthrough shader which could be
* generated when bypass_clipping is enabled on a passthrough vertex
}
}
-
static boolean update_shader( struct draw_context *draw )
{
const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render);
/* Just trying to figure out how this would work:
*/
- if (nr_attrs == 3 &&
- 0 /* some other tests */)
+ if (draw->rasterizer->bypass_vs ||
+ (nr_attrs == 3 && 0 /* some other tests */))
{
+#if 0
draw->vertex_fetch.pt_fetch = fetch_xyz_rgb_st;
- assert(vinfo->size == 10);
+#else
+ draw->vertex_fetch.pt_fetch = fetch_store_general;
+#endif
+ /*assert(vinfo->size == 10);*/
return TRUE;
}
}
-
boolean
draw_passthrough_arrays(struct draw_context *draw,
unsigned prim,
{
float *hw_verts;
+ if (draw_need_pipeline(draw))
+ return FALSE;
+
if (!set_prim(draw, prim))
return FALSE;
- if (!update_shader( draw ))
+ if (!update_shader(draw))
return FALSE;
hw_verts = draw->render->allocate_vertices( draw->render,
*/
#include "pipe/p_debug.h"
+#include "pipe/p_util.h"
#include "draw_private.h"
#include "draw_context.h"
draw_vertex_cache_unreference( draw );
}
+static INLINE void fetch_and_store(struct draw_context *draw)
+{
+ unsigned i;
+
+ /* run vertex shader on vertex cache entries, four per invokation */
+#if 0
+ {
+ const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render);
+ memcpy(draw->vs.queue[0].vertex, draw->vs.queue[i + j].elt,
+ count * vinfo->size);
+ }
+#elif 0
+ draw_update_vertex_fetch(draw);
+ for (i = 0; i < draw->vs.queue_nr; i += 4) {
+ struct vertex_header *dests[4];
+ unsigned elts[4];
+ struct tgsi_exec_machine *machine = &draw->machine;
+ int j, n = MIN2(4, draw->vs.queue_nr - i);
+
+ for (j = 0; j < n; j++) {
+ elts[j] = draw->vs.queue[i + j].elt;
+ dests[j] = draw->vs.queue[i + j].vertex;
+ }
+ for ( ; j < 4; j++) {
+ elts[j] = elts[0];
+ dests[j] = draw->vs.queue[i + j].vertex;
+ }
+ //fetch directly into dests
+ draw->vertex_fetch.fetch_func(draw, machine, dests, count);
+ }
+#endif
+
+ draw->vs.post_nr = draw->vs.queue_nr;
+ draw->vs.queue_nr = 0;
+}
void draw_do_flush( struct draw_context *draw, unsigned flags )
{
if (flags >= DRAW_FLUSH_SHADER_QUEUE) {
if (draw->vs.queue_nr)
- (*draw->shader_queue_flush)(draw);
+ if (draw->rasterizer->bypass_vs)
+ fetch_and_store(draw);
+ else
+ (*draw->shader_queue_flush)(draw);
if (flags >= DRAW_FLUSH_PRIM_QUEUE) {
if (draw->pq.queue_nr)
}
/* drawing done here: */
- draw_prim(draw, prim, start, count);
+ if (!draw->rasterizer->bypass_vs ||
+ !draw_passthrough_arrays(draw, prim, start, count)) {
+ /* we have to run the whole pipeline */
+ draw_prim(draw, prim, start, count);
+ }
}