llvmpipe: EXT_transform_feedback support (v1.1)
I'd written most of this ages ago, but never finished it off. This passes 115/130 piglit tests so far. I'll look into the others as time permits. v1.1: fix calloc return check as suggested by Jose. Reviewed-by: Jose Fonseca <jfonseca@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
71f06344a0
commit
77b26564c3
|
@ -81,12 +81,6 @@ struct llvmpipe_context {
|
||||||
struct pipe_viewport_state viewport;
|
struct pipe_viewport_state viewport;
|
||||||
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
|
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
|
||||||
struct pipe_index_buffer index_buffer;
|
struct pipe_index_buffer index_buffer;
|
||||||
struct {
|
|
||||||
struct llvmpipe_resource *buffer[PIPE_MAX_SO_BUFFERS];
|
|
||||||
int offset[PIPE_MAX_SO_BUFFERS];
|
|
||||||
int so_count[PIPE_MAX_SO_BUFFERS];
|
|
||||||
int num_buffers;
|
|
||||||
} so_target;
|
|
||||||
struct pipe_resource *mapped_vs_tex[PIPE_MAX_SAMPLERS];
|
struct pipe_resource *mapped_vs_tex[PIPE_MAX_SAMPLERS];
|
||||||
|
|
||||||
unsigned num_samplers[PIPE_SHADER_TYPES];
|
unsigned num_samplers[PIPE_SHADER_TYPES];
|
||||||
|
@ -94,6 +88,11 @@ struct llvmpipe_context {
|
||||||
|
|
||||||
unsigned num_vertex_buffers;
|
unsigned num_vertex_buffers;
|
||||||
|
|
||||||
|
struct draw_so_target *so_targets[PIPE_MAX_SO_BUFFERS];
|
||||||
|
int num_so_targets;
|
||||||
|
struct pipe_query_data_so_statistics so_stats;
|
||||||
|
unsigned num_primitives_generated;
|
||||||
|
|
||||||
unsigned dirty; /**< Mask of LP_NEW_x flags */
|
unsigned dirty; /**< Mask of LP_NEW_x flags */
|
||||||
|
|
||||||
unsigned active_occlusion_query;
|
unsigned active_occlusion_query;
|
||||||
|
|
|
@ -88,6 +88,13 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
||||||
lp->index_buffer.index_size);
|
lp->index_buffer.index_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < lp->num_so_targets; i++) {
|
||||||
|
void *buf = llvmpipe_resource(lp->so_targets[i]->target.buffer)->data;
|
||||||
|
lp->so_targets[i]->mapping = buf;
|
||||||
|
}
|
||||||
|
draw_set_mapped_so_targets(draw, lp->num_so_targets,
|
||||||
|
lp->so_targets);
|
||||||
|
|
||||||
llvmpipe_prepare_vertex_sampling(lp,
|
llvmpipe_prepare_vertex_sampling(lp,
|
||||||
lp->num_sampler_views[PIPE_SHADER_VERTEX],
|
lp->num_sampler_views[PIPE_SHADER_VERTEX],
|
||||||
lp->sampler_views[PIPE_SHADER_VERTEX]);
|
lp->sampler_views[PIPE_SHADER_VERTEX]);
|
||||||
|
@ -104,6 +111,8 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
||||||
if (mapped_indices) {
|
if (mapped_indices) {
|
||||||
draw_set_indexes(draw, NULL, 0);
|
draw_set_indexes(draw, NULL, 0);
|
||||||
}
|
}
|
||||||
|
draw_set_mapped_so_targets(draw, 0, NULL);
|
||||||
|
|
||||||
llvmpipe_cleanup_vertex_sampling(lp);
|
llvmpipe_cleanup_vertex_sampling(lp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -138,6 +138,12 @@ llvmpipe_get_query_result(struct pipe_context *pipe,
|
||||||
*result = os_time_get_nano();
|
*result = os_time_get_nano();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PIPE_QUERY_PRIMITIVES_GENERATED:
|
||||||
|
*result = pq->num_primitives_generated;
|
||||||
|
break;
|
||||||
|
case PIPE_QUERY_PRIMITIVES_EMITTED:
|
||||||
|
*result = pq->num_primitives_written;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
|
@ -165,6 +171,16 @@ llvmpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q)
|
||||||
memset(pq->count, 0, sizeof(pq->count));
|
memset(pq->count, 0, sizeof(pq->count));
|
||||||
lp_setup_begin_query(llvmpipe->setup, pq);
|
lp_setup_begin_query(llvmpipe->setup, pq);
|
||||||
|
|
||||||
|
if (pq->type == PIPE_QUERY_PRIMITIVES_EMITTED) {
|
||||||
|
pq->num_primitives_written = 0;
|
||||||
|
llvmpipe->so_stats.num_primitives_written = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pq->type == PIPE_QUERY_PRIMITIVES_GENERATED) {
|
||||||
|
pq->num_primitives_generated = 0;
|
||||||
|
llvmpipe->num_primitives_generated = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER) {
|
if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER) {
|
||||||
llvmpipe->active_occlusion_query = TRUE;
|
llvmpipe->active_occlusion_query = TRUE;
|
||||||
llvmpipe->dirty |= LP_NEW_OCCLUSION_QUERY;
|
llvmpipe->dirty |= LP_NEW_OCCLUSION_QUERY;
|
||||||
|
@ -180,6 +196,14 @@ llvmpipe_end_query(struct pipe_context *pipe, struct pipe_query *q)
|
||||||
|
|
||||||
lp_setup_end_query(llvmpipe->setup, pq);
|
lp_setup_end_query(llvmpipe->setup, pq);
|
||||||
|
|
||||||
|
if (pq->type == PIPE_QUERY_PRIMITIVES_EMITTED) {
|
||||||
|
pq->num_primitives_written = llvmpipe->so_stats.num_primitives_written;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pq->type == PIPE_QUERY_PRIMITIVES_GENERATED) {
|
||||||
|
pq->num_primitives_generated = llvmpipe->num_primitives_generated;
|
||||||
|
}
|
||||||
|
|
||||||
if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER) {
|
if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER) {
|
||||||
assert(llvmpipe->active_occlusion_query);
|
assert(llvmpipe->active_occlusion_query);
|
||||||
llvmpipe->active_occlusion_query = FALSE;
|
llvmpipe->active_occlusion_query = FALSE;
|
||||||
|
|
|
@ -45,6 +45,8 @@ struct llvmpipe_query {
|
||||||
uint64_t count[LP_MAX_THREADS]; /* a counter for each thread */
|
uint64_t count[LP_MAX_THREADS]; /* a counter for each thread */
|
||||||
struct lp_fence *fence; /* fence from last scene this was binned in */
|
struct lp_fence *fence; /* fence from last scene this was binned in */
|
||||||
unsigned type; /* PIPE_QUERY_* */
|
unsigned type; /* PIPE_QUERY_* */
|
||||||
|
unsigned num_primitives_generated;
|
||||||
|
unsigned num_primitives_written;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -440,6 +440,9 @@ lp_rast_begin_query(struct lp_rasterizer_task *task,
|
||||||
case PIPE_QUERY_TIME_ELAPSED:
|
case PIPE_QUERY_TIME_ELAPSED:
|
||||||
task->query_start = os_time_get_nano();
|
task->query_start = os_time_get_nano();
|
||||||
break;
|
break;
|
||||||
|
case PIPE_QUERY_PRIMITIVES_GENERATED:
|
||||||
|
case PIPE_QUERY_PRIMITIVES_EMITTED:
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
|
@ -471,6 +474,9 @@ lp_rast_end_query(struct lp_rasterizer_task *task,
|
||||||
case PIPE_QUERY_TIMESTAMP:
|
case PIPE_QUERY_TIMESTAMP:
|
||||||
pq->count[task->thread_index] = os_time_get_nano();
|
pq->count[task->thread_index] = os_time_get_nano();
|
||||||
break;
|
break;
|
||||||
|
case PIPE_QUERY_PRIMITIVES_GENERATED:
|
||||||
|
case PIPE_QUERY_PRIMITIVES_EMITTED:
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
|
@ -606,7 +612,7 @@ rasterize_scene(struct lp_rasterizer_task *task,
|
||||||
{
|
{
|
||||||
task->scene = scene;
|
task->scene = scene;
|
||||||
|
|
||||||
if (!task->rast->no_rast) {
|
if (!task->rast->no_rast && !scene->discard) {
|
||||||
/* loop over scene bins, rasterize each */
|
/* loop over scene bins, rasterize each */
|
||||||
#if 0
|
#if 0
|
||||||
{
|
{
|
||||||
|
|
|
@ -472,10 +472,11 @@ end:
|
||||||
|
|
||||||
|
|
||||||
void lp_scene_begin_binning( struct lp_scene *scene,
|
void lp_scene_begin_binning( struct lp_scene *scene,
|
||||||
struct pipe_framebuffer_state *fb )
|
struct pipe_framebuffer_state *fb, boolean discard )
|
||||||
{
|
{
|
||||||
assert(lp_scene_is_empty(scene));
|
assert(lp_scene_is_empty(scene));
|
||||||
|
|
||||||
|
scene->discard = discard;
|
||||||
util_copy_framebuffer_state(&scene->fb, fb);
|
util_copy_framebuffer_state(&scene->fb, fb);
|
||||||
|
|
||||||
scene->tiles_x = align(fb->width, TILE_SIZE) / TILE_SIZE;
|
scene->tiles_x = align(fb->width, TILE_SIZE) / TILE_SIZE;
|
||||||
|
|
|
@ -157,7 +157,7 @@ struct lp_scene {
|
||||||
|
|
||||||
boolean alloc_failed;
|
boolean alloc_failed;
|
||||||
boolean has_depthstencil_clear;
|
boolean has_depthstencil_clear;
|
||||||
|
boolean discard;
|
||||||
/**
|
/**
|
||||||
* Number of active tiles in each dimension.
|
* Number of active tiles in each dimension.
|
||||||
* This basically the framebuffer size divided by tile size
|
* This basically the framebuffer size divided by tile size
|
||||||
|
@ -381,7 +381,8 @@ lp_scene_bin_iter_next( struct lp_scene *scene );
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
lp_scene_begin_binning( struct lp_scene *scene,
|
lp_scene_begin_binning( struct lp_scene *scene,
|
||||||
struct pipe_framebuffer_state *fb );
|
struct pipe_framebuffer_state *fb,
|
||||||
|
boolean discard );
|
||||||
|
|
||||||
void
|
void
|
||||||
lp_scene_end_binning( struct lp_scene *scene );
|
lp_scene_end_binning( struct lp_scene *scene );
|
||||||
|
|
|
@ -117,7 +117,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
|
||||||
case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
|
case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
|
||||||
return 0;
|
return 0;
|
||||||
case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
|
case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
|
||||||
return 0;
|
return PIPE_MAX_SO_BUFFERS;
|
||||||
case PIPE_CAP_ANISOTROPIC_FILTER:
|
case PIPE_CAP_ANISOTROPIC_FILTER:
|
||||||
return 0;
|
return 0;
|
||||||
case PIPE_CAP_POINT_SPRITE:
|
case PIPE_CAP_POINT_SPRITE:
|
||||||
|
@ -186,6 +186,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
|
||||||
return 0;
|
return 0;
|
||||||
case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
|
case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
|
||||||
case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
|
case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
|
||||||
|
return 16*4;
|
||||||
case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
|
case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
|
||||||
return 0;
|
return 0;
|
||||||
case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
|
case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
|
||||||
|
|
|
@ -65,7 +65,9 @@ static boolean try_update_scene_state( struct lp_setup_context *setup );
|
||||||
static void
|
static void
|
||||||
lp_setup_get_empty_scene(struct lp_setup_context *setup)
|
lp_setup_get_empty_scene(struct lp_setup_context *setup)
|
||||||
{
|
{
|
||||||
|
struct llvmpipe_context *lp = llvmpipe_context(setup->pipe);
|
||||||
assert(setup->scene == NULL);
|
assert(setup->scene == NULL);
|
||||||
|
boolean discard = lp->rasterizer ? lp->rasterizer->rasterizer_discard : FALSE;
|
||||||
|
|
||||||
setup->scene_idx++;
|
setup->scene_idx++;
|
||||||
setup->scene_idx %= Elements(setup->scenes);
|
setup->scene_idx %= Elements(setup->scenes);
|
||||||
|
@ -80,7 +82,7 @@ lp_setup_get_empty_scene(struct lp_setup_context *setup)
|
||||||
lp_fence_wait(setup->scene->fence);
|
lp_fence_wait(setup->scene->fence);
|
||||||
}
|
}
|
||||||
|
|
||||||
lp_scene_begin_binning(setup->scene, &setup->fb);
|
lp_scene_begin_binning(setup->scene, &setup->fb, discard);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -620,6 +622,13 @@ lp_setup_set_flatshade_first( struct lp_setup_context *setup,
|
||||||
setup->flatshade_first = flatshade_first;
|
setup->flatshade_first = flatshade_first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
lp_setup_set_rasterizer_discard( struct lp_setup_context *setup,
|
||||||
|
boolean rasterizer_discard )
|
||||||
|
{
|
||||||
|
setup->rasterizer_discard = rasterizer_discard;
|
||||||
|
set_scene_state( setup, SETUP_FLUSHED, __FUNCTION__ );
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
lp_setup_set_vertex_info( struct lp_setup_context *setup,
|
lp_setup_set_vertex_info( struct lp_setup_context *setup,
|
||||||
|
@ -1057,6 +1066,7 @@ lp_setup_create( struct pipe_context *pipe,
|
||||||
struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
|
struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
|
||||||
struct lp_setup_context *setup;
|
struct lp_setup_context *setup;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
struct llvmpipe_context *lp = llvmpipe_context(pipe);
|
||||||
|
|
||||||
setup = CALLOC_STRUCT(lp_setup_context);
|
setup = CALLOC_STRUCT(lp_setup_context);
|
||||||
if (!setup) {
|
if (!setup) {
|
||||||
|
|
|
@ -137,6 +137,10 @@ void
|
||||||
lp_setup_set_flatshade_first( struct lp_setup_context *setup,
|
lp_setup_set_flatshade_first( struct lp_setup_context *setup,
|
||||||
boolean flatshade_first );
|
boolean flatshade_first );
|
||||||
|
|
||||||
|
void
|
||||||
|
lp_setup_set_rasterizer_discard( struct lp_setup_context *setup,
|
||||||
|
boolean rasterizer_discard );
|
||||||
|
|
||||||
void
|
void
|
||||||
lp_setup_set_vertex_info( struct lp_setup_context *setup,
|
lp_setup_set_vertex_info( struct lp_setup_context *setup,
|
||||||
struct vertex_info *info );
|
struct vertex_info *info );
|
||||||
|
|
|
@ -95,6 +95,7 @@ struct lp_setup_context
|
||||||
boolean ccw_is_frontface;
|
boolean ccw_is_frontface;
|
||||||
boolean scissor_test;
|
boolean scissor_test;
|
||||||
boolean point_size_per_vertex;
|
boolean point_size_per_vertex;
|
||||||
|
boolean rasterizer_discard;
|
||||||
unsigned cullmode;
|
unsigned cullmode;
|
||||||
float pixel_offset;
|
float pixel_offset;
|
||||||
float line_width;
|
float line_width;
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
|
|
||||||
|
|
||||||
#include "lp_setup_context.h"
|
#include "lp_setup_context.h"
|
||||||
|
#include "lp_context.h"
|
||||||
#include "draw/draw_vbuf.h"
|
#include "draw/draw_vbuf.h"
|
||||||
#include "draw/draw_vertex.h"
|
#include "draw/draw_vertex.h"
|
||||||
#include "util/u_memory.h"
|
#include "util/u_memory.h"
|
||||||
|
@ -533,6 +534,18 @@ lp_setup_vbuf_destroy(struct vbuf_render *vbr)
|
||||||
lp_setup_destroy(setup);
|
lp_setup_destroy(setup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
lp_setup_so_info(struct vbuf_render *vbr, uint primitives, uint vertices,
|
||||||
|
uint prim_generated)
|
||||||
|
{
|
||||||
|
struct lp_setup_context *setup = lp_setup_context(vbr);
|
||||||
|
struct llvmpipe_context *lp = llvmpipe_context(setup->pipe);
|
||||||
|
|
||||||
|
lp->so_stats.num_primitives_written += primitives;
|
||||||
|
lp->so_stats.primitives_storage_needed =
|
||||||
|
vertices * 4 /*sizeof(float|int32)*/ * 4 /*x,y,z,w*/;
|
||||||
|
lp->num_primitives_generated += prim_generated;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the post-transform vertex handler for the given context.
|
* Create the post-transform vertex handler for the given context.
|
||||||
|
@ -552,4 +565,5 @@ lp_setup_init_vbuf(struct lp_setup_context *setup)
|
||||||
setup->base.draw_arrays = lp_setup_draw_arrays;
|
setup->base.draw_arrays = lp_setup_draw_arrays;
|
||||||
setup->base.release_vertices = lp_setup_release_vertices;
|
setup->base.release_vertices = lp_setup_release_vertices;
|
||||||
setup->base.destroy = lp_setup_vbuf_destroy;
|
setup->base.destroy = lp_setup_vbuf_destroy;
|
||||||
|
setup->base.set_stream_output_info = lp_setup_so_info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,6 +114,8 @@ llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, void *handle)
|
||||||
state->lp_state.gl_rasterization_rules);
|
state->lp_state.gl_rasterization_rules);
|
||||||
lp_setup_set_flatshade_first( llvmpipe->setup,
|
lp_setup_set_flatshade_first( llvmpipe->setup,
|
||||||
state->lp_state.flatshade_first);
|
state->lp_state.flatshade_first);
|
||||||
|
lp_setup_set_rasterizer_discard( llvmpipe->setup,
|
||||||
|
state->lp_state.rasterizer_discard);
|
||||||
lp_setup_set_line_state( llvmpipe->setup,
|
lp_setup_set_line_state( llvmpipe->setup,
|
||||||
state->lp_state.line_width);
|
state->lp_state.line_width);
|
||||||
lp_setup_set_point_state( llvmpipe->setup,
|
lp_setup_set_point_state( llvmpipe->setup,
|
||||||
|
|
|
@ -32,106 +32,56 @@
|
||||||
#include "util/u_memory.h"
|
#include "util/u_memory.h"
|
||||||
#include "draw/draw_context.h"
|
#include "draw/draw_context.h"
|
||||||
|
|
||||||
|
static struct pipe_stream_output_target *
|
||||||
static void *
|
llvmpipe_create_so_target(struct pipe_context *pipe,
|
||||||
llvmpipe_create_stream_output_state(struct pipe_context *pipe,
|
struct pipe_resource *buffer,
|
||||||
const struct pipe_stream_output_info *templ)
|
unsigned buffer_offset,
|
||||||
|
unsigned buffer_size)
|
||||||
{
|
{
|
||||||
struct lp_so_state *so;
|
struct draw_so_target *t;
|
||||||
so = (struct lp_so_state *) CALLOC_STRUCT(lp_so_state);
|
|
||||||
|
|
||||||
if (so) {
|
t = CALLOC_STRUCT(draw_so_target);
|
||||||
so->base.num_outputs = templ->num_outputs;
|
if (!t)
|
||||||
memcpy(so->base.stride, templ->stride, sizeof(templ->stride));
|
return NULL;
|
||||||
memcpy(so->base.output, templ->output,
|
|
||||||
templ->num_outputs * sizeof(templ->output[0]));
|
t->target.context = pipe;
|
||||||
}
|
t->target.reference.count = 1;
|
||||||
return so;
|
pipe_resource_reference(&t->target.buffer, buffer);
|
||||||
|
t->target.buffer_offset = buffer_offset;
|
||||||
|
t->target.buffer_size = buffer_size;
|
||||||
|
return &t->target;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
llvmpipe_bind_stream_output_state(struct pipe_context *pipe,
|
llvmpipe_so_target_destroy(struct pipe_context *pipe,
|
||||||
void *so)
|
struct pipe_stream_output_target *target)
|
||||||
{
|
{
|
||||||
struct llvmpipe_context *lp = llvmpipe_context(pipe);
|
pipe_resource_reference(&target->buffer, NULL);
|
||||||
struct lp_so_state *lp_so = (struct lp_so_state *) so;
|
FREE(target);
|
||||||
|
|
||||||
lp->so = lp_so;
|
|
||||||
|
|
||||||
lp->dirty |= LP_NEW_SO;
|
|
||||||
|
|
||||||
if (lp_so)
|
|
||||||
draw_set_so_state(lp->draw, &lp_so->base);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
llvmpipe_delete_stream_output_state(struct pipe_context *pipe, void *so)
|
llvmpipe_set_so_targets(struct pipe_context *pipe,
|
||||||
|
unsigned num_targets,
|
||||||
|
struct pipe_stream_output_target **targets,
|
||||||
|
unsigned append_bitmask)
|
||||||
{
|
{
|
||||||
FREE( so );
|
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
llvmpipe_set_stream_output_buffers(struct pipe_context *pipe,
|
|
||||||
struct pipe_resource **buffers,
|
|
||||||
int *offsets,
|
|
||||||
int num_buffers)
|
|
||||||
{
|
|
||||||
struct llvmpipe_context *lp = llvmpipe_context(pipe);
|
|
||||||
int i;
|
int i;
|
||||||
void *map_buffers[PIPE_MAX_SO_BUFFERS];
|
for (i = 0; i < num_targets; i++) {
|
||||||
|
pipe_so_target_reference((struct pipe_stream_output_target **)&llvmpipe->so_targets[i], targets[i]);
|
||||||
assert(num_buffers <= PIPE_MAX_SO_BUFFERS);
|
|
||||||
if (num_buffers > PIPE_MAX_SO_BUFFERS)
|
|
||||||
num_buffers = PIPE_MAX_SO_BUFFERS;
|
|
||||||
|
|
||||||
lp->dirty |= LP_NEW_SO_BUFFERS;
|
|
||||||
|
|
||||||
for (i = 0; i < num_buffers; ++i) {
|
|
||||||
void *mapped;
|
|
||||||
struct llvmpipe_resource *res = llvmpipe_resource(buffers[i]);
|
|
||||||
|
|
||||||
if (!res) {
|
|
||||||
/* the whole call is invalid, bail out */
|
|
||||||
lp->so_target.num_buffers = 0;
|
|
||||||
draw_set_mapped_so_buffers(lp->draw, 0, 0);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lp->so_target.buffer[i] = res;
|
for (; i < llvmpipe->num_so_targets; i++) {
|
||||||
lp->so_target.offset[i] = offsets[i];
|
pipe_so_target_reference((struct pipe_stream_output_target **)&llvmpipe->so_targets[i], NULL);
|
||||||
lp->so_target.so_count[i] = 0;
|
|
||||||
|
|
||||||
mapped = res->data;
|
|
||||||
if (offsets[i] >= 0)
|
|
||||||
map_buffers[i] = ((char*)mapped) + offsets[i];
|
|
||||||
else {
|
|
||||||
/* this is a buffer append */
|
|
||||||
assert(!"appending not implemented");
|
|
||||||
map_buffers[i] = mapped;
|
|
||||||
}
|
}
|
||||||
}
|
llvmpipe->num_so_targets = num_targets;
|
||||||
lp->so_target.num_buffers = num_buffers;
|
|
||||||
|
|
||||||
draw_set_mapped_so_buffers(lp->draw, map_buffers, num_buffers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
llvmpipe_init_so_funcs(struct llvmpipe_context *llvmpipe)
|
llvmpipe_init_so_funcs(struct llvmpipe_context *pipe)
|
||||||
{
|
{
|
||||||
#if 0
|
pipe->pipe.create_stream_output_target = llvmpipe_create_so_target;
|
||||||
llvmpipe->pipe.create_stream_output_state =
|
pipe->pipe.stream_output_target_destroy = llvmpipe_so_target_destroy;
|
||||||
llvmpipe_create_stream_output_state;
|
pipe->pipe.set_stream_output_targets = llvmpipe_set_so_targets;
|
||||||
llvmpipe->pipe.bind_stream_output_state =
|
|
||||||
llvmpipe_bind_stream_output_state;
|
|
||||||
llvmpipe->pipe.delete_stream_output_state =
|
|
||||||
llvmpipe_delete_stream_output_state;
|
|
||||||
|
|
||||||
llvmpipe->pipe.set_stream_output_buffers =
|
|
||||||
llvmpipe_set_stream_output_buffers;
|
|
||||||
#else
|
|
||||||
(void) llvmpipe_create_stream_output_state;
|
|
||||||
(void) llvmpipe_bind_stream_output_state;
|
|
||||||
(void) llvmpipe_delete_stream_output_state;
|
|
||||||
(void) llvmpipe_set_stream_output_buffers;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,8 +208,8 @@ static void lp_blit(struct pipe_context *pipe,
|
||||||
util_blitter_save_vertex_elements(lp->blitter, (void*)lp->velems);
|
util_blitter_save_vertex_elements(lp->blitter, (void*)lp->velems);
|
||||||
util_blitter_save_vertex_shader(lp->blitter, (void*)lp->vs);
|
util_blitter_save_vertex_shader(lp->blitter, (void*)lp->vs);
|
||||||
util_blitter_save_geometry_shader(lp->blitter, (void*)lp->gs);
|
util_blitter_save_geometry_shader(lp->blitter, (void*)lp->gs);
|
||||||
/*util_blitter_save_so_targets(lp->blitter, lp->num_so_targets,
|
util_blitter_save_so_targets(lp->blitter, lp->num_so_targets,
|
||||||
(struct pipe_stream_output_target**)lp->so_targets);*/
|
(struct pipe_stream_output_target**)lp->so_targets);
|
||||||
util_blitter_save_rasterizer(lp->blitter, (void*)lp->rasterizer);
|
util_blitter_save_rasterizer(lp->blitter, (void*)lp->rasterizer);
|
||||||
util_blitter_save_viewport(lp->blitter, &lp->viewport);
|
util_blitter_save_viewport(lp->blitter, &lp->viewport);
|
||||||
util_blitter_save_scissor(lp->blitter, &lp->scissor);
|
util_blitter_save_scissor(lp->blitter, &lp->scissor);
|
||||||
|
|
Loading…
Reference in New Issue