/**************************************************************************
*
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2008 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS 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.
#include "draw/draw_pt.h"
#include "translate/translate.h"
#include "translate/translate_cache.h"
+#include "util/u_prim.h"
struct pt_emit {
struct draw_context *draw;
unsigned prim;
const struct vertex_info *vinfo;
+
+ float zero4[4];
+
};
-void draw_pt_emit_prepare( struct pt_emit *emit,
- unsigned prim,
- unsigned *max_vertices )
+
+void
+draw_pt_emit_prepare(struct pt_emit *emit,
+ unsigned prim,
+ unsigned *max_vertices)
{
struct draw_context *draw = emit->draw;
const struct vertex_info *vinfo;
unsigned dst_offset;
struct translate_key hw_key;
unsigned i;
- boolean ok;
-
- /* XXX: need to flush to get prim_vbuf.c to release its allocation??
- */
- draw_do_flush( draw, DRAW_FLUSH_BACKEND );
+ /* XXX: need to flush to get prim_vbuf.c to release its allocation??
+ */
+ draw_do_flush(draw, DRAW_FLUSH_BACKEND);
/* XXX: may need to defensively reset this later on as clipping can
* clobber this state in the render backend.
*/
emit->prim = prim;
- ok = draw->render->set_primitive(draw->render, emit->prim);
- if (!ok) {
- assert(0);
- return;
- }
+ draw->render->set_primitive(draw->render, emit->prim);
/* Must do this after set_primitive() above:
*/
emit->vinfo = vinfo = draw->render->get_vertex_info(draw->render);
-
/* Translate from pipeline vertices to hw vertices.
*/
dst_offset = 0;
unsigned emit_sz = 0;
unsigned src_buffer = 0;
unsigned output_format;
- unsigned src_offset = (vinfo->attrib[i].src_index * 4 * sizeof(float) );
-
-
-
- switch (vinfo->attrib[i].emit) {
- case EMIT_4F:
- output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- emit_sz = 4 * sizeof(float);
- break;
- case EMIT_3F:
- output_format = PIPE_FORMAT_R32G32B32_FLOAT;
- emit_sz = 3 * sizeof(float);
- break;
- case EMIT_2F:
- output_format = PIPE_FORMAT_R32G32_FLOAT;
- emit_sz = 2 * sizeof(float);
- break;
- case EMIT_1F:
- output_format = PIPE_FORMAT_R32_FLOAT;
- emit_sz = 1 * sizeof(float);
- break;
- case EMIT_1F_PSIZE:
- output_format = PIPE_FORMAT_R32_FLOAT;
- emit_sz = 1 * sizeof(float);
- src_buffer = 1;
- src_offset = 0;
- break;
- case EMIT_4UB:
- output_format = PIPE_FORMAT_B8G8R8A8_UNORM;
- emit_sz = 4 * sizeof(ubyte);
- break;
- default:
- assert(0);
- output_format = PIPE_FORMAT_NONE;
- emit_sz = 0;
- break;
+ unsigned src_offset = vinfo->attrib[i].src_index * 4 * sizeof(float);
+
+ output_format = draw_translate_vinfo_format(vinfo->attrib[i].emit);
+ emit_sz = draw_translate_vinfo_size(vinfo->attrib[i].emit);
+
+ /* doesn't handle EMIT_OMIT */
+ assert(emit_sz != 0);
+
+ if (vinfo->attrib[i].emit == EMIT_1F_PSIZE) {
+ src_buffer = 1;
+ src_offset = 0;
+ }
+ else if (vinfo->attrib[i].src_index == DRAW_ATTR_NONEXIST) {
+ /* elements which don't exist will get assigned zeros */
+ src_buffer = 2;
+ src_offset = 0;
}
-
+
+ hw_key.element[i].type = TRANSLATE_ELEMENT_NORMAL;
hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
hw_key.element[i].input_buffer = src_buffer;
hw_key.element[i].input_offset = src_offset;
+ hw_key.element[i].instance_divisor = 0;
hw_key.element[i].output_format = output_format;
hw_key.element[i].output_offset = dst_offset;
hw_key.output_stride = vinfo->size * 4;
if (!emit->translate ||
- translate_key_compare(&emit->translate->key, &hw_key) != 0)
- {
+ translate_key_compare(&emit->translate->key, &hw_key) != 0) {
translate_key_sanitize(&hw_key);
emit->translate = translate_cache_find(emit->cache, &hw_key);
- }
- *max_vertices = (draw->render->max_vertex_buffer_bytes /
- (vinfo->size * 4));
+ emit->translate->set_buffer(emit->translate, 2, &emit->zero4[0], 0, ~0);
+ }
- /* even number */
- *max_vertices = *max_vertices & ~1;
+ if (!vinfo->size)
+ *max_vertices = 0;
+ else
+ *max_vertices = (draw->render->max_vertex_buffer_bytes /
+ (vinfo->size * 4));
}
-void draw_pt_emit( struct pt_emit *emit,
- const float (*vertex_data)[4],
- unsigned vertex_count,
- unsigned stride,
- const ushort *elts,
- unsigned count )
+void
+draw_pt_emit(struct pt_emit *emit,
+ const struct draw_vertex_info *vert_info,
+ const struct draw_prim_info *prim_info)
{
+ const float (*vertex_data)[4] = (const float (*)[4])vert_info->verts->data;
+ unsigned vertex_count = vert_info->count;
+ unsigned stride = vert_info->stride;
+ const ushort *elts = prim_info->elts;
struct draw_context *draw = emit->draw;
struct translate *translate = emit->translate;
struct vbuf_render *render = draw->render;
+ unsigned start, i;
void *hw_verts;
- /* XXX: need to flush to get prim_vbuf.c to release its allocation??
+ /* XXX: need to flush to get prim_vbuf.c to release its allocation??
*/
- draw_do_flush( draw, DRAW_FLUSH_BACKEND );
+ draw_do_flush(draw, DRAW_FLUSH_BACKEND);
if (vertex_count == 0)
return;
- if (vertex_count >= UNDEFINED_VERTEX_ID) {
- assert(0);
- return;
- }
-
/* XXX: and work out some way to coordinate the render primitive
* between vbuf.c and here...
*/
- if (!draw->render->set_primitive(draw->render, emit->prim)) {
- assert(0);
- return;
- }
+ render->set_primitive(draw->render, prim_info->prim);
+ assert(vertex_count <= 65535);
render->allocate_vertices(render,
(ushort)translate->key.output_stride,
(ushort)vertex_count);
- hw_verts = render->map_vertices( render );
+ hw_verts = render->map_vertices(render);
if (!hw_verts) {
- assert(0);
+ debug_warn_once("map of vertex buffer failed (out of memory?)");
return;
}
- translate->set_buffer(translate,
- 0,
- vertex_data,
- stride );
+ translate->set_buffer(translate,
+ 0,
+ vertex_data,
+ stride,
+ ~0);
- translate->set_buffer(translate,
- 1,
- &draw->rasterizer->point_size,
- 0);
+ translate->set_buffer(translate,
+ 1,
+ &draw->rasterizer->point_size,
+ 0,
+ ~0);
- translate->run( translate,
- 0,
- vertex_count,
- hw_verts );
+ /* fetch/translate vertex attribs to fill hw_verts[] */
+ translate->run(translate,
+ 0,
+ vertex_count,
+ 0,
+ 0,
+ hw_verts);
- render->unmap_vertices( render,
- 0,
- vertex_count - 1 );
+ render->unmap_vertices(render, 0, vertex_count - 1);
- render->draw(render,
- elts,
- count);
+ for (start = i = 0;
+ i < prim_info->primitive_count;
+ start += prim_info->primitive_lengths[i], i++)
+ {
+ render->draw_elements(render,
+ elts + start,
+ prim_info->primitive_lengths[i]);
+ }
render->release_vertices(render);
}
-void draw_pt_emit_linear(struct pt_emit *emit,
- const float (*vertex_data)[4],
- unsigned stride,
- unsigned count)
+void
+draw_pt_emit_linear(struct pt_emit *emit,
+ const struct draw_vertex_info *vert_info,
+ const struct draw_prim_info *prim_info)
{
+ const float (*vertex_data)[4] = (const float (*)[4])vert_info->verts->data;
+ unsigned stride = vert_info->stride;
+ unsigned count = vert_info->count;
struct draw_context *draw = emit->draw;
struct translate *translate = emit->translate;
struct vbuf_render *render = draw->render;
void *hw_verts;
+ unsigned start, i;
#if 0
debug_printf("Linear emit\n");
#endif
- /* XXX: need to flush to get prim_vbuf.c to release its allocation??
+ /* XXX: need to flush to get prim_vbuf.c to release its allocation??
*/
- draw_do_flush( draw, DRAW_FLUSH_BACKEND );
-
- if (count >= UNDEFINED_VERTEX_ID)
- goto fail;
+ draw_do_flush(draw, DRAW_FLUSH_BACKEND);
/* XXX: and work out some way to coordinate the render primitive
* between vbuf.c and here...
*/
- if (!draw->render->set_primitive(draw->render, emit->prim))
- goto fail;
+ render->set_primitive(draw->render, prim_info->prim);
+ assert(count <= 65535);
if (!render->allocate_vertices(render,
(ushort)translate->key.output_stride,
(ushort)count))
goto fail;
- hw_verts = render->map_vertices( render );
+ hw_verts = render->map_vertices(render);
if (!hw_verts)
goto fail;
translate->set_buffer(translate, 0,
- vertex_data, stride);
+ vertex_data, stride, count - 1);
translate->set_buffer(translate, 1,
- &draw->rasterizer->point_size,
- 0);
+ &draw->rasterizer->point_size,
+ 0, ~0);
translate->run(translate,
0,
count,
+ 0,
+ 0,
hw_verts);
if (0) {
unsigned i;
for (i = 0; i < count; i++) {
debug_printf("\n\n%s vertex %d:\n", __FUNCTION__, i);
- draw_dump_emitted_vertex( emit->vinfo,
- (const uint8_t *)hw_verts +
- translate->key.output_stride * i );
+ draw_dump_emitted_vertex(emit->vinfo,
+ (const uint8_t *)hw_verts +
+ translate->key.output_stride * i);
}
}
- render->unmap_vertices( render, 0, count - 1 );
+ render->unmap_vertices(render, 0, count - 1);
- render->draw_arrays(render, 0, count);
+ for (start = i = 0;
+ i < prim_info->primitive_count;
+ start += prim_info->primitive_lengths[i], i++)
+ {
+ render->draw_arrays(render,
+ start,
+ prim_info->primitive_lengths[i]);
+ }
render->release_vertices(render);
return;
fail:
- assert(0);
+ debug_warn_once("allocate or map of vertex buffer failed (out of memory?)");
return;
}
-struct pt_emit *draw_pt_emit_create( struct draw_context *draw )
+
+struct pt_emit *
+draw_pt_emit_create(struct draw_context *draw)
{
struct pt_emit *emit = CALLOC_STRUCT(pt_emit);
if (!emit)
return NULL;
}
+ emit->zero4[0] = emit->zero4[1] = emit->zero4[2] = emit->zero4[3] = 0.0f;
+
return emit;
}
-void draw_pt_emit_destroy( struct pt_emit *emit )
+
+void
+draw_pt_emit_destroy(struct pt_emit *emit)
{
if (emit->cache)
translate_cache_destroy(emit->cache);