Commit a45b7f47 authored by Zack Rusin's avatar Zack Rusin Committed by Zack Rusin

gallium: basic and initial implementation of the stream output interface

aka transform feedback
parent a2817f6a
......@@ -574,3 +574,25 @@ draw_get_rasterizer_no_cull( struct draw_context *draw,
}
return draw->rasterizer_no_cull[scissor][flatshade];
}
void
draw_set_mapped_so_buffers(struct draw_context *draw,
void *buffers[PIPE_MAX_SO_BUFFERS],
unsigned num_buffers)
{
int i;
for (i = 0; i < num_buffers; ++i) {
draw->so.buffers[i] = buffers[i];
}
draw->so.num_buffers = num_buffers;
}
void
draw_set_so_state(struct draw_context *draw,
struct pipe_stream_output_state *state)
{
memcpy(&draw->so.state,
state,
sizeof(struct pipe_stream_output_state));
}
......@@ -162,6 +162,14 @@ draw_set_mapped_constant_buffer(struct draw_context *draw,
const void *buffer,
unsigned size);
void
draw_set_mapped_so_buffers(struct draw_context *draw,
void *buffers[PIPE_MAX_SO_BUFFERS],
unsigned num_buffers);
void
draw_set_so_state(struct draw_context *draw,
struct pipe_stream_output_state *state);
/***********************************************************************
* draw_prim.c
......
......@@ -235,6 +235,12 @@ struct draw_context
struct tgsi_sampler **samplers;
} gs;
struct {
struct pipe_stream_output_state state;
void *buffers[PIPE_MAX_SO_BUFFERS];
uint num_buffers;
} so;
/* Clip derived state:
*/
float plane[12][4];
......
......@@ -33,11 +33,13 @@
#include "draw/draw_pt.h"
#include "translate/translate.h"
#include "translate/translate_cache.h"
#include "util/u_format.h"
struct pt_emit {
struct draw_context *draw;
struct translate *translate;
struct translate *so_translate;
struct translate_cache *cache;
unsigned prim;
......@@ -45,6 +47,51 @@ struct pt_emit {
const struct vertex_info *vinfo;
};
static void
prepare_so_emit( struct pt_emit *emit,
const struct vertex_info *vinfo )
{
struct draw_context *draw = emit->draw;
unsigned i;
struct translate_key hw_key;
unsigned dst_offset = 0;
unsigned output_stride = 0;
boolean has_so = (draw->so.state.num_outputs > 0);
if (has_so) {
for (i = 0; i < draw->so.state.num_outputs; ++i) {
unsigned src_offset = (vinfo->attrib[i].src_index * 4 * sizeof(float) );
unsigned output_format = draw->so.state.format[i];
unsigned output_bytes = util_format_get_blocksize(output_format);
hw_key.element[i].type = TRANSLATE_ELEMENT_NORMAL;
hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
hw_key.element[i].input_buffer = 0;
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;
dst_offset += output_bytes;
output_stride += output_bytes;
}
hw_key.nr_elements = draw->so.state.num_outputs;
hw_key.output_stride = output_stride;
if (!emit->so_translate ||
translate_key_compare(&emit->so_translate->key, &hw_key) != 0)
{
translate_key_sanitize(&hw_key);
emit->so_translate = translate_cache_find(emit->cache, &hw_key);
}
} else {
/* no stream output */
emit->so_translate = NULL;
}
}
void draw_pt_emit_prepare( struct pt_emit *emit,
unsigned prim,
unsigned *max_vertices )
......@@ -121,6 +168,8 @@ void draw_pt_emit_prepare( struct pt_emit *emit,
*max_vertices = (draw->render->max_vertex_buffer_bytes /
(vinfo->size * 4));
prepare_so_emit( emit, vinfo );
/* even number */
*max_vertices = *max_vertices & ~1;
}
......@@ -135,6 +184,7 @@ void draw_pt_emit( struct pt_emit *emit,
{
struct draw_context *draw = emit->draw;
struct translate *translate = emit->translate;
struct translate *so_translate = emit->so_translate;
struct vbuf_render *render = draw->render;
void *hw_verts;
......@@ -186,6 +236,18 @@ void draw_pt_emit( struct pt_emit *emit,
draw->instance_id,
hw_verts );
if (so_translate) {
void *so_buffer = draw->so.buffers[0];
/* XXX we only support single output buffer right now */
debug_assert(draw->so.num_buffers >= 0);
so_translate->set_buffer(translate, 0, vertex_data,
stride, ~0);
so_translate->run(translate, 0, vertex_count,
draw->instance_id, so_buffer);
}
render->unmap_vertices( render,
0,
vertex_count - 1 );
......@@ -205,6 +267,7 @@ void draw_pt_emit_linear(struct pt_emit *emit,
{
struct draw_context *draw = emit->draw;
struct translate *translate = emit->translate;
struct translate *so_translate = emit->so_translate;
struct vbuf_render *render = draw->render;
void *hw_verts;
......@@ -246,6 +309,18 @@ void draw_pt_emit_linear(struct pt_emit *emit,
draw->instance_id,
hw_verts);
if (so_translate) {
void *so_buffer = draw->so.buffers[0];
/* XXX we only support single output buffer right now */
debug_assert(draw->so.num_buffers >= 0);
so_translate->set_buffer(translate, 0,
vertex_data, stride, count - 1);
so_translate->run(translate, 0, count,
draw->instance_id, so_buffer);
}
if (0) {
unsigned i;
for (i = 0; i < count; i++) {
......
......@@ -27,6 +27,7 @@ softpipe = env.ConvenienceLibrary(
'sp_state_fs.c',
'sp_state_rasterizer.c',
'sp_state_sampler.c',
'sp_state_so.c',
'sp_state_surface.c',
'sp_state_vertex.c',
'sp_surface.c',
......
......@@ -251,6 +251,10 @@ softpipe_create_context( struct pipe_screen *screen,
softpipe->pipe.bind_vertex_elements_state = softpipe_bind_vertex_elements_state;
softpipe->pipe.delete_vertex_elements_state = softpipe_delete_vertex_elements_state;
softpipe->pipe.create_stream_output_state = softpipe_create_stream_output_state;
softpipe->pipe.bind_stream_output_state = softpipe_bind_stream_output_state;
softpipe->pipe.delete_stream_output_state = softpipe_delete_stream_output_state;
softpipe->pipe.set_blend_color = softpipe_set_blend_color;
softpipe->pipe.set_stencil_ref = softpipe_set_stencil_ref;
softpipe->pipe.set_clip_state = softpipe_set_clip_state;
......@@ -264,7 +268,7 @@ softpipe_create_context( struct pipe_screen *screen,
softpipe->pipe.create_sampler_view = softpipe_create_sampler_view;
softpipe->pipe.sampler_view_destroy = softpipe_sampler_view_destroy;
softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
softpipe->pipe.set_stream_output_buffers = softpipe_set_stream_output_buffers;
softpipe->pipe.set_vertex_buffers = softpipe_set_vertex_buffers;
softpipe->pipe.draw_arrays = softpipe_draw_arrays;
......
......@@ -50,6 +50,7 @@ struct softpipe_tex_tile_cache;
struct sp_fragment_shader;
struct sp_vertex_shader;
struct sp_velems_state;
struct sp_so_state;
struct softpipe_context {
......@@ -65,6 +66,7 @@ struct softpipe_context {
struct sp_vertex_shader *vs;
struct sp_geometry_shader *gs;
struct sp_velems_state *velems;
struct sp_so_state *so;
/** Other rendering state */
struct pipe_blend_color blend_color;
......
......@@ -51,6 +51,8 @@
#define SP_NEW_VS 0x2000
#define SP_NEW_QUERY 0x4000
#define SP_NEW_GS 0x8000
#define SP_NEW_SO 0x10000
#define SP_NEW_SO_BUFFERS 0x20000
struct tgsi_sampler;
......@@ -105,6 +107,10 @@ struct sp_velems_state {
struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
};
struct sp_so_state {
struct pipe_stream_output_state base;
};
void *
softpipe_create_blend_state(struct pipe_context *,
......@@ -263,5 +269,20 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe);
struct vertex_info *
softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe);
void *
softpipe_create_stream_output_state(
struct pipe_context *pipe,
const struct pipe_stream_output_state *templ);
void
softpipe_bind_stream_output_state(struct pipe_context *pipe,
void *so);
void
softpipe_delete_stream_output_state(struct pipe_context *pipe, void *so);
void
softpipe_set_stream_output_buffers(struct pipe_context *pipe,
struct pipe_resource **buffers,
int *offsets,
int num_buffers);
#endif
......@@ -186,6 +186,11 @@ struct pipe_context {
void (*bind_vertex_elements_state)(struct pipe_context *, void *);
void (*delete_vertex_elements_state)(struct pipe_context *, void *);
void * (*create_stream_output_state)(struct pipe_context *,
const struct pipe_stream_output_state *);
void (*bind_stream_output_state)(struct pipe_context *, void *);
void (*delete_stream_output_state)(struct pipe_context*, void*);
/*@}*/
/**
......@@ -232,6 +237,13 @@ struct pipe_context {
unsigned num_buffers,
const struct pipe_vertex_buffer * );
void (*set_stream_output_buffers)(struct pipe_context *,
struct pipe_resource **buffers,
int *offsets, /*array of offsets
from the start of each
of the buffers */
int num_buffers);
/*@}*/
......
......@@ -288,6 +288,7 @@ enum pipe_transfer_usage {
#define PIPE_BIND_DISPLAY_TARGET (1 << 8) /* flush_front_buffer */
#define PIPE_BIND_TRANSFER_WRITE (1 << 9) /* get_transfer */
#define PIPE_BIND_TRANSFER_READ (1 << 10) /* get_transfer */
#define PIPE_BIND_STREAM_OUTPUT (1 << 11) /* set_stream_output_buffers */
#define PIPE_BIND_CUSTOM (1 << 16) /* state-tracker/winsys usages */
/* The first two flags above were previously part of the amorphous
......@@ -322,6 +323,7 @@ enum pipe_transfer_usage {
#define PIPE_USAGE_STATIC 2 /* same as immutable?? */
#define PIPE_USAGE_IMMUTABLE 3 /* no change after first upload */
#define PIPE_USAGE_STREAM 4 /* upload, draw, upload, draw */
#define PIPE_USAGE_STAGING 5 /* supports data transfers from the GPU to the CPU */
/* These are intended to be used in calls to is_format_supported, but
......
......@@ -63,6 +63,7 @@ extern "C" {
#define PIPE_MAX_SHADER_INPUTS 16
#define PIPE_MAX_SHADER_OUTPUTS 16
#define PIPE_MAX_TEXTURE_LEVELS 16
#define PIPE_MAX_SO_BUFFERS 4
struct pipe_reference
......@@ -345,6 +346,12 @@ struct pipe_resource
unsigned flags; /**< bitmask of PIPE_RESOURCE_FLAG_x */
};
struct pipe_stream_output_state
{
/**< format for each output */
enum pipe_format format[PIPE_MAX_SHADER_OUTPUTS];
int num_outputs;
};
/**
* Extra indexing info for (cube) texture resources.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment