st/mesa: implement EXT_transform_feedback and ARB_transform_feedback2
This commit is contained in:

committed by
Christoph Bumiller

parent
36d66f8d4a
commit
c05fafa4a0
@@ -79,6 +79,7 @@ struct cso_context {
|
||||
struct cso_cache *cache;
|
||||
|
||||
boolean has_geometry_shader;
|
||||
boolean has_streamout;
|
||||
|
||||
struct sampler_info fragment_samplers;
|
||||
struct sampler_info vertex_samplers;
|
||||
@@ -89,6 +90,12 @@ struct cso_context {
|
||||
uint nr_vertex_buffers_saved;
|
||||
struct pipe_vertex_buffer vertex_buffers_saved[PIPE_MAX_ATTRIBS];
|
||||
|
||||
unsigned nr_so_targets;
|
||||
struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS];
|
||||
|
||||
unsigned nr_so_targets_saved;
|
||||
struct pipe_stream_output_target *so_targets_saved[PIPE_MAX_SO_BUFFERS];
|
||||
|
||||
/** Current and saved state.
|
||||
* The saved state is used as a 1-deep stack.
|
||||
*/
|
||||
@@ -276,6 +283,10 @@ struct cso_context *cso_create_context( struct pipe_context *pipe )
|
||||
PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) {
|
||||
ctx->has_geometry_shader = TRUE;
|
||||
}
|
||||
if (pipe->screen->get_param(pipe->screen,
|
||||
PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0) {
|
||||
ctx->has_streamout = TRUE;
|
||||
}
|
||||
|
||||
return ctx;
|
||||
|
||||
@@ -306,6 +317,7 @@ void cso_release_all( struct cso_context *ctx )
|
||||
ctx->pipe->set_fragment_sampler_views(ctx->pipe, 0, NULL);
|
||||
if (ctx->pipe->set_vertex_sampler_views)
|
||||
ctx->pipe->set_vertex_sampler_views(ctx->pipe, 0, NULL);
|
||||
ctx->pipe->set_stream_output_targets(ctx->pipe, 0, NULL, 0);
|
||||
}
|
||||
|
||||
/* free fragment samplers, views */
|
||||
@@ -332,6 +344,11 @@ void cso_release_all( struct cso_context *ctx )
|
||||
&ctx->nr_vertex_buffers_saved,
|
||||
NULL, 0);
|
||||
|
||||
for (i = 0; i < PIPE_MAX_SO_BUFFERS; i++) {
|
||||
pipe_so_target_reference(&ctx->so_targets[i], NULL);
|
||||
pipe_so_target_reference(&ctx->so_targets_saved[i], NULL);
|
||||
}
|
||||
|
||||
if (ctx->cache) {
|
||||
cso_cache_delete( ctx->cache );
|
||||
ctx->cache = NULL;
|
||||
@@ -1311,3 +1328,87 @@ cso_restore_vertex_sampler_views(struct cso_context *ctx)
|
||||
restore_sampler_views(ctx, &ctx->vertex_samplers,
|
||||
ctx->pipe->set_vertex_sampler_views);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cso_set_stream_outputs(struct cso_context *ctx,
|
||||
unsigned num_targets,
|
||||
struct pipe_stream_output_target **targets,
|
||||
unsigned append_bitmask)
|
||||
{
|
||||
struct pipe_context *pipe = ctx->pipe;
|
||||
uint i;
|
||||
|
||||
if (!ctx->has_streamout) {
|
||||
assert(num_targets == 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->nr_so_targets == 0 && num_targets == 0) {
|
||||
/* Nothing to do. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* reference new targets */
|
||||
for (i = 0; i < num_targets; i++) {
|
||||
pipe_so_target_reference(&ctx->so_targets[i], targets[i]);
|
||||
}
|
||||
/* unref extra old targets, if any */
|
||||
for (; i < ctx->nr_so_targets; i++) {
|
||||
pipe_so_target_reference(&ctx->so_targets[i], NULL);
|
||||
}
|
||||
|
||||
pipe->set_stream_output_targets(pipe, num_targets, targets,
|
||||
append_bitmask);
|
||||
ctx->nr_so_targets = num_targets;
|
||||
}
|
||||
|
||||
void
|
||||
cso_save_stream_outputs(struct cso_context *ctx)
|
||||
{
|
||||
uint i;
|
||||
|
||||
if (!ctx->has_streamout) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx->nr_so_targets_saved = ctx->nr_so_targets;
|
||||
|
||||
for (i = 0; i < ctx->nr_so_targets; i++) {
|
||||
assert(!ctx->so_targets_saved[i]);
|
||||
pipe_so_target_reference(&ctx->so_targets_saved[i], ctx->so_targets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cso_restore_stream_outputs(struct cso_context *ctx)
|
||||
{
|
||||
struct pipe_context *pipe = ctx->pipe;
|
||||
uint i;
|
||||
|
||||
if (!ctx->has_streamout) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->nr_so_targets == 0 && ctx->nr_so_targets_saved == 0) {
|
||||
/* Nothing to do. */
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ctx->nr_so_targets_saved; i++) {
|
||||
pipe_so_target_reference(&ctx->so_targets[i], NULL);
|
||||
/* move the reference from one pointer to another */
|
||||
ctx->so_targets[i] = ctx->so_targets_saved[i];
|
||||
ctx->so_targets_saved[i] = NULL;
|
||||
}
|
||||
for (; i < ctx->nr_so_targets; i++) {
|
||||
pipe_so_target_reference(&ctx->so_targets[i], NULL);
|
||||
}
|
||||
|
||||
/* ~0 means append */
|
||||
pipe->set_stream_output_targets(pipe, ctx->nr_so_targets_saved,
|
||||
ctx->so_targets, ~0);
|
||||
|
||||
ctx->nr_so_targets = ctx->nr_so_targets_saved;
|
||||
ctx->nr_so_targets_saved = 0;
|
||||
}
|
||||
|
@@ -117,6 +117,14 @@ void cso_save_vertex_buffers(struct cso_context *ctx);
|
||||
void cso_restore_vertex_buffers(struct cso_context *ctx);
|
||||
|
||||
|
||||
void cso_set_stream_outputs(struct cso_context *ctx,
|
||||
unsigned num_targets,
|
||||
struct pipe_stream_output_target **targets,
|
||||
unsigned append_bitmask);
|
||||
void cso_save_stream_outputs(struct cso_context *ctx);
|
||||
void cso_restore_stream_outputs(struct cso_context *ctx);
|
||||
|
||||
|
||||
/* These aren't really sensible -- most of the time the api provides
|
||||
* object semantics for shaders anyway, and the cases where it doesn't
|
||||
* (eg mesa's internall-generated texenv programs), it will be up to
|
||||
|
@@ -529,6 +529,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
|
||||
cso_save_rasterizer(ctx->cso);
|
||||
cso_save_samplers(ctx->cso);
|
||||
cso_save_fragment_sampler_views(ctx->cso);
|
||||
cso_save_stream_outputs(ctx->cso);
|
||||
cso_save_viewport(ctx->cso);
|
||||
cso_save_framebuffer(ctx->cso);
|
||||
cso_save_fragment_shader(ctx->cso);
|
||||
@@ -546,6 +547,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
|
||||
cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
|
||||
cso_set_clip(ctx->cso, &ctx->clip);
|
||||
cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
|
||||
cso_set_stream_outputs(ctx->cso, 0, NULL, 0);
|
||||
|
||||
/* sampler */
|
||||
ctx->sampler.normalized_coords = normalized;
|
||||
@@ -622,6 +624,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
|
||||
cso_restore_clip(ctx->cso);
|
||||
cso_restore_vertex_elements(ctx->cso);
|
||||
cso_restore_vertex_buffers(ctx->cso);
|
||||
cso_restore_stream_outputs(ctx->cso);
|
||||
|
||||
pipe_sampler_view_reference(&sampler_view, NULL);
|
||||
if (dst_surface != dst)
|
||||
@@ -722,6 +725,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
|
||||
cso_save_rasterizer(ctx->cso);
|
||||
cso_save_samplers(ctx->cso);
|
||||
cso_save_fragment_sampler_views(ctx->cso);
|
||||
cso_save_stream_outputs(ctx->cso);
|
||||
cso_save_viewport(ctx->cso);
|
||||
cso_save_framebuffer(ctx->cso);
|
||||
cso_save_fragment_shader(ctx->cso);
|
||||
@@ -737,6 +741,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
|
||||
cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
|
||||
cso_set_clip(ctx->cso, &ctx->clip);
|
||||
cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
|
||||
cso_set_stream_outputs(ctx->cso, 0, NULL, 0);
|
||||
|
||||
/* sampler */
|
||||
ctx->sampler.normalized_coords = normalized;
|
||||
@@ -801,4 +806,5 @@ util_blit_pixels_tex(struct blit_state *ctx,
|
||||
cso_restore_clip(ctx->cso);
|
||||
cso_restore_vertex_elements(ctx->cso);
|
||||
cso_restore_vertex_buffers(ctx->cso);
|
||||
cso_restore_stream_outputs(ctx->cso);
|
||||
}
|
||||
|
@@ -1558,6 +1558,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
|
||||
cso_save_rasterizer(ctx->cso);
|
||||
cso_save_samplers(ctx->cso);
|
||||
cso_save_fragment_sampler_views(ctx->cso);
|
||||
cso_save_stream_outputs(ctx->cso);
|
||||
cso_save_framebuffer(ctx->cso);
|
||||
cso_save_fragment_shader(ctx->cso);
|
||||
cso_save_vertex_shader(ctx->cso);
|
||||
@@ -1572,6 +1573,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
|
||||
cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
|
||||
cso_set_clip(ctx->cso, &ctx->clip);
|
||||
cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
|
||||
cso_set_stream_outputs(ctx->cso, 0, NULL, 0);
|
||||
|
||||
set_fragment_shader(ctx, type);
|
||||
set_vertex_shader(ctx);
|
||||
@@ -1688,4 +1690,5 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
|
||||
cso_restore_viewport(ctx->cso);
|
||||
cso_restore_clip(ctx->cso);
|
||||
cso_restore_vertex_elements(ctx->cso);
|
||||
cso_restore_stream_outputs(ctx->cso);
|
||||
}
|
||||
|
@@ -256,9 +256,11 @@ static void update_raster_state( struct st_context *st )
|
||||
|
||||
/* _NEW_FRAG_CLAMP */
|
||||
raster->clamp_fragment_color = ctx->Color._ClampFragmentColor;
|
||||
|
||||
raster->gl_rasterization_rules = 1;
|
||||
|
||||
/* _NEW_TRANSFORM */
|
||||
raster->rasterizer_discard = ctx->TransformFeedback.RasterDiscard;
|
||||
|
||||
cso_set_rasterizer(st->cso_context, raster);
|
||||
}
|
||||
|
||||
@@ -273,7 +275,8 @@ const struct st_tracked_state st_update_rasterizer = {
|
||||
_NEW_POLYGON |
|
||||
_NEW_PROGRAM |
|
||||
_NEW_SCISSOR |
|
||||
_NEW_FRAG_CLAMP), /* mesa state dependencies*/
|
||||
_NEW_FRAG_CLAMP |
|
||||
_NEW_TRANSFORM), /* mesa state dependencies*/
|
||||
ST_NEW_VERTEX_PROGRAM, /* state tracker dependencies */
|
||||
},
|
||||
update_raster_state /* update function */
|
||||
|
@@ -483,6 +483,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
|
||||
cso_save_fragment_sampler_views(cso);
|
||||
cso_save_viewport(cso);
|
||||
cso_save_fragment_shader(cso);
|
||||
cso_save_stream_outputs(cso);
|
||||
cso_save_vertex_shader(cso);
|
||||
cso_save_geometry_shader(cso);
|
||||
cso_save_vertex_elements(cso);
|
||||
@@ -542,6 +543,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
|
||||
}
|
||||
|
||||
cso_set_vertex_elements(cso, 3, st->velems_util_draw);
|
||||
cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
|
||||
|
||||
/* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */
|
||||
z = z * 2.0f - 1.0f;
|
||||
@@ -568,6 +570,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
|
||||
cso_restore_geometry_shader(cso);
|
||||
cso_restore_vertex_elements(cso);
|
||||
cso_restore_vertex_buffers(cso);
|
||||
cso_restore_stream_outputs(cso);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -250,6 +250,7 @@ clear_with_quad(struct gl_context *ctx,
|
||||
cso_save_viewport(st->cso_context);
|
||||
cso_save_clip(st->cso_context);
|
||||
cso_save_fragment_shader(st->cso_context);
|
||||
cso_save_stream_outputs(st->cso_context);
|
||||
cso_save_vertex_shader(st->cso_context);
|
||||
cso_save_geometry_shader(st->cso_context);
|
||||
cso_save_vertex_elements(st->cso_context);
|
||||
@@ -306,6 +307,7 @@ clear_with_quad(struct gl_context *ctx,
|
||||
}
|
||||
|
||||
cso_set_vertex_elements(st->cso_context, 2, st->velems_util_draw);
|
||||
cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
|
||||
|
||||
cso_set_rasterizer(st->cso_context, &st->clear.raster);
|
||||
|
||||
@@ -350,6 +352,7 @@ clear_with_quad(struct gl_context *ctx,
|
||||
cso_restore_geometry_shader(st->cso_context);
|
||||
cso_restore_vertex_elements(st->cso_context);
|
||||
cso_restore_vertex_buffers(st->cso_context);
|
||||
cso_restore_stream_outputs(st->cso_context);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -671,6 +671,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
|
||||
cso_save_samplers(cso);
|
||||
cso_save_fragment_sampler_views(cso);
|
||||
cso_save_fragment_shader(cso);
|
||||
cso_save_stream_outputs(cso);
|
||||
cso_save_vertex_shader(cso);
|
||||
cso_save_geometry_shader(cso);
|
||||
cso_save_vertex_elements(cso);
|
||||
@@ -761,6 +762,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
|
||||
}
|
||||
|
||||
cso_set_vertex_elements(cso, 3, st->velems_util_draw);
|
||||
cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
|
||||
|
||||
/* texture state: */
|
||||
cso_set_fragment_sampler_views(cso, num_sampler_view, sv);
|
||||
@@ -796,6 +798,7 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
|
||||
cso_restore_geometry_shader(cso);
|
||||
cso_restore_vertex_elements(cso);
|
||||
cso_restore_vertex_buffers(cso);
|
||||
cso_restore_stream_outputs(cso);
|
||||
if (write_stencil) {
|
||||
cso_restore_depth_stencil_alpha(cso);
|
||||
cso_restore_blend(cso);
|
||||
|
@@ -227,6 +227,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
|
||||
|
||||
|
||||
cso_save_viewport(cso);
|
||||
cso_save_stream_outputs(cso);
|
||||
cso_save_vertex_shader(cso);
|
||||
cso_save_geometry_shader(cso);
|
||||
cso_save_vertex_elements(cso);
|
||||
@@ -246,6 +247,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
|
||||
velements[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
}
|
||||
cso_set_vertex_elements(cso, numAttribs, velements);
|
||||
cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
|
||||
|
||||
/* viewport state: viewport matching window dims */
|
||||
{
|
||||
@@ -281,6 +283,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
|
||||
cso_restore_geometry_shader(cso);
|
||||
cso_restore_vertex_elements(cso);
|
||||
cso_restore_vertex_buffers(cso);
|
||||
cso_restore_stream_outputs(cso);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -30,70 +30,122 @@
|
||||
* Transform feedback functions.
|
||||
*
|
||||
* \author Brian Paul
|
||||
* Marek Olšák
|
||||
*/
|
||||
|
||||
|
||||
#include "main/imports.h"
|
||||
#include "main/bufferobj.h"
|
||||
#include "main/context.h"
|
||||
#include "main/mfeatures.h"
|
||||
#include "main/transformfeedback.h"
|
||||
|
||||
#include "st_cb_bufferobjects.h"
|
||||
#include "st_cb_xformfb.h"
|
||||
#include "st_context.h"
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "util/u_draw.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "cso_cache/cso_context.h"
|
||||
|
||||
#if FEATURE_EXT_transform_feedback
|
||||
|
||||
#if 0
|
||||
struct st_transform_feedback_object {
|
||||
struct gl_transform_feedback_object base;
|
||||
|
||||
unsigned num_targets;
|
||||
struct pipe_stream_output_target *targets[PIPE_MAX_SO_BUFFERS];
|
||||
};
|
||||
|
||||
|
||||
static struct gl_transform_feedback_object *
|
||||
st_new_transform_feedback(struct gl_context *ctx, GLuint name)
|
||||
{
|
||||
struct gl_transform_feedback_object *obj;
|
||||
obj = CALLOC_STRUCT(gl_transform_feedback_object);
|
||||
if (obj) {
|
||||
obj->Name = name;
|
||||
obj->RefCount = 1;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
#endif
|
||||
struct st_transform_feedback_object *obj;
|
||||
|
||||
obj = CALLOC_STRUCT(st_transform_feedback_object);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
obj->base.Name = name;
|
||||
obj->base.RefCount = 1;
|
||||
return &obj->base;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static void
|
||||
st_delete_transform_feedback(struct gl_context *ctx,
|
||||
struct gl_transform_feedback_object *obj)
|
||||
{
|
||||
GLuint i;
|
||||
struct st_transform_feedback_object *sobj =
|
||||
(struct st_transform_feedback_object*)obj;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < Elements(obj->Buffers); i++) {
|
||||
_mesa_reference_buffer_object(ctx, &obj->Buffers[i], NULL);
|
||||
/* Unreference targets. */
|
||||
for (i = 0; i < sobj->num_targets; i++) {
|
||||
pipe_so_target_reference(&sobj->targets[i], NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < Elements(sobj->base.Buffers); i++) {
|
||||
_mesa_reference_buffer_object(ctx, &sobj->base.Buffers[i], NULL);
|
||||
}
|
||||
|
||||
free(obj);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* XXX Do we really need the mode? */
|
||||
static void
|
||||
st_begin_transform_feedback(struct gl_context *ctx, GLenum mode,
|
||||
struct gl_transform_feedback_object *obj)
|
||||
{
|
||||
/* to-do */
|
||||
struct st_context *st = st_context(ctx);
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
struct st_transform_feedback_object *sobj =
|
||||
(struct st_transform_feedback_object*)obj;
|
||||
unsigned i, max_num_targets;
|
||||
|
||||
max_num_targets = MIN2(Elements(sobj->base.Buffers),
|
||||
Elements(sobj->targets));
|
||||
|
||||
/* Convert the transform feedback state into the gallium representation. */
|
||||
for (i = 0; i < max_num_targets; i++) {
|
||||
struct st_buffer_object *bo = st_buffer_object(sobj->base.Buffers[i]);
|
||||
|
||||
if (bo) {
|
||||
/* Check whether we need to recreate the target. */
|
||||
if (!sobj->targets[i] ||
|
||||
sobj->targets[i]->buffer != bo->buffer ||
|
||||
sobj->targets[i]->buffer_offset != sobj->base.Offset[i] ||
|
||||
sobj->targets[i]->buffer_size != sobj->base.Size[i]) {
|
||||
/* Create a new target. */
|
||||
struct pipe_stream_output_target *so_target =
|
||||
pipe->create_stream_output_target(pipe, bo->buffer,
|
||||
sobj->base.Offset[i],
|
||||
sobj->base.Size[i]);
|
||||
|
||||
pipe_so_target_reference(&sobj->targets[i], NULL);
|
||||
sobj->targets[i] = so_target;
|
||||
}
|
||||
|
||||
sobj->num_targets = i+1;
|
||||
} else {
|
||||
pipe_so_target_reference(&sobj->targets[i], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Start writing at the beginning of each target. */
|
||||
cso_set_stream_outputs(st->cso_context, sobj->num_targets, sobj->targets,
|
||||
0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
st_end_transform_feedback(struct gl_context *ctx,
|
||||
st_stop_transform_feedback(struct gl_context *ctx,
|
||||
struct gl_transform_feedback_object *obj)
|
||||
{
|
||||
/* to-do */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
st_pause_transform_feedback(struct gl_context *ctx,
|
||||
struct gl_transform_feedback_object *obj)
|
||||
{
|
||||
/* to-do */
|
||||
struct st_context *st = st_context(ctx);
|
||||
cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -101,20 +153,44 @@ static void
|
||||
st_resume_transform_feedback(struct gl_context *ctx,
|
||||
struct gl_transform_feedback_object *obj)
|
||||
{
|
||||
/* to-do */
|
||||
struct st_context *st = st_context(ctx);
|
||||
struct st_transform_feedback_object *sobj =
|
||||
(struct st_transform_feedback_object*)obj;
|
||||
|
||||
cso_set_stream_outputs(st->cso_context, sobj->num_targets, sobj->targets,
|
||||
~0);
|
||||
}
|
||||
|
||||
/* Set count_from_stream_output to any stream output target
|
||||
* from the transform feedback object. */
|
||||
void
|
||||
st_transform_feedback_draw_init(struct gl_transform_feedback_object *obj,
|
||||
struct pipe_draw_info *out)
|
||||
{
|
||||
struct st_transform_feedback_object *sobj =
|
||||
(struct st_transform_feedback_object*)obj;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < Elements(sobj->targets); i++) {
|
||||
if (sobj->targets[i]) {
|
||||
out->count_from_stream_output = sobj->targets[i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
assert(0);
|
||||
out->count_from_stream_output = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
st_init_xformfb_functions(struct dd_function_table *functions)
|
||||
{
|
||||
/* let core Mesa plug in its functions */
|
||||
_mesa_init_transform_feedback_functions(functions);
|
||||
|
||||
/* then override a few: */
|
||||
functions->NewTransformFeedback = st_new_transform_feedback;
|
||||
functions->DeleteTransformFeedback = st_delete_transform_feedback;
|
||||
functions->BeginTransformFeedback = st_begin_transform_feedback;
|
||||
functions->EndTransformFeedback = st_end_transform_feedback;
|
||||
functions->PauseTransformFeedback = st_pause_transform_feedback;
|
||||
functions->EndTransformFeedback = st_stop_transform_feedback;
|
||||
functions->PauseTransformFeedback = st_stop_transform_feedback;
|
||||
functions->ResumeTransformFeedback = st_resume_transform_feedback;
|
||||
}
|
||||
|
||||
|
@@ -33,12 +33,18 @@
|
||||
#include "main/mfeatures.h"
|
||||
|
||||
struct dd_function_table;
|
||||
struct gl_transform_feedback_object;
|
||||
struct pipe_draw_info;
|
||||
|
||||
#if FEATURE_EXT_transform_feedback
|
||||
|
||||
extern void
|
||||
st_init_xformfb_functions(struct dd_function_table *functions);
|
||||
|
||||
extern void
|
||||
st_transform_feedback_draw_init(struct gl_transform_feedback_object *obj,
|
||||
struct pipe_draw_info *out);
|
||||
|
||||
#else
|
||||
|
||||
static INLINE void
|
||||
@@ -46,6 +52,12 @@ st_init_xformfb_functions(struct dd_function_table *functions)
|
||||
{
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
st_transform_feedback_draw_init(struct gl_transform_feedback_object *obj,
|
||||
struct pipe_draw_info *out)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* FEATURE_EXT_transform_feedback */
|
||||
|
||||
#endif /* ST_CB_XFORMFB_H */
|
||||
|
@@ -51,6 +51,7 @@
|
||||
#include "st_context.h"
|
||||
#include "st_atom.h"
|
||||
#include "st_cb_bufferobjects.h"
|
||||
#include "st_cb_xformfb.h"
|
||||
#include "st_draw.h"
|
||||
#include "st_program.h"
|
||||
|
||||
@@ -940,7 +941,6 @@ st_draw_vbo(struct gl_context *ctx,
|
||||
|
||||
/* Mesa core state should have been validated already */
|
||||
assert(ctx->NewState == 0x0);
|
||||
assert(!tfb_vertcount);
|
||||
|
||||
if (ib) {
|
||||
/* Gallium probably doesn't want this in some cases. */
|
||||
@@ -1034,6 +1034,11 @@ st_draw_vbo(struct gl_context *ctx,
|
||||
info.restart_index = ctx->Array.RestartIndex;
|
||||
}
|
||||
|
||||
/* Set info.count_from_stream_output. */
|
||||
if (tfb_vertcount) {
|
||||
st_transform_feedback_draw_init(tfb_vertcount, &info);
|
||||
}
|
||||
|
||||
/* do actual drawing */
|
||||
for (i = 0; i < nr_prims; i++) {
|
||||
info.mode = translate_prim( ctx, prims[i].mode );
|
||||
@@ -1046,7 +1051,10 @@ st_draw_vbo(struct gl_context *ctx,
|
||||
info.max_index = info.start + info.count - 1;
|
||||
}
|
||||
|
||||
if (info.primitive_restart) {
|
||||
if (info.count_from_stream_output) {
|
||||
pipe->draw_vbo(pipe, &info);
|
||||
}
|
||||
else if (info.primitive_restart) {
|
||||
if (st->sw_primitive_restart) {
|
||||
/* Handle primitive restart for drivers that doesn't support it */
|
||||
handle_fallback_primitive_restart(pipe, ib, &ibuffer, &info);
|
||||
|
@@ -221,6 +221,13 @@ void st_init_limits(struct st_context *st)
|
||||
|
||||
c->UniformBooleanTrue = ~0;
|
||||
|
||||
c->MaxTransformFeedbackSeparateAttribs =
|
||||
screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_ATTRIBS);
|
||||
c->MaxTransformFeedbackSeparateComponents =
|
||||
screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS);
|
||||
c->MaxTransformFeedbackInterleavedComponents =
|
||||
screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS);
|
||||
|
||||
c->StripTextureBorder = GL_TRUE;
|
||||
|
||||
c->GLSLSkipStrictMaxUniformLimitCheck =
|
||||
@@ -682,4 +689,12 @@ void st_init_extensions(struct st_context *st)
|
||||
PIPE_BIND_SAMPLER_VIEW))
|
||||
ctx->Extensions.ARB_texture_rgb10_a2ui = GL_TRUE;
|
||||
|
||||
if (screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0) {
|
||||
ctx->Extensions.EXT_transform_feedback = GL_TRUE;
|
||||
|
||||
if (screen->get_param(screen,
|
||||
PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME) != 0) {
|
||||
ctx->Extensions.ARB_transform_feedback2 = GL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -5095,4 +5095,31 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
st_translate_stream_output_info(struct glsl_to_tgsi_visitor *glsl_to_tgsi,
|
||||
const GLuint outputMapping[],
|
||||
struct pipe_stream_output_info *so)
|
||||
{
|
||||
static unsigned comps_to_mask[] = {
|
||||
0,
|
||||
TGSI_WRITEMASK_X,
|
||||
TGSI_WRITEMASK_XY,
|
||||
TGSI_WRITEMASK_XYZ,
|
||||
TGSI_WRITEMASK_XYZW
|
||||
};
|
||||
unsigned i;
|
||||
struct gl_transform_feedback_info *info =
|
||||
&glsl_to_tgsi->shader_program->LinkedTransformFeedback;
|
||||
|
||||
for (i = 0; i < info->NumOutputs; i++) {
|
||||
assert(info->Outputs[i].NumComponents < Elements(comps_to_mask));
|
||||
so->output[i].register_index =
|
||||
outputMapping[info->Outputs[i].OutputRegister];
|
||||
so->output[i].register_mask =
|
||||
comps_to_mask[info->Outputs[i].NumComponents];
|
||||
so->output[i].output_buffer = info->Outputs[i].OutputBuffer;
|
||||
}
|
||||
so->num_outputs = info->NumOutputs;
|
||||
}
|
||||
|
||||
} /* extern "C" */
|
||||
|
@@ -66,6 +66,12 @@ st_new_shader_program(struct gl_context *ctx, GLuint name);
|
||||
|
||||
GLboolean st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog);
|
||||
|
||||
void
|
||||
st_translate_stream_output_info(struct glsl_to_tgsi_visitor *glsl_to_tgsi,
|
||||
const GLuint outputMapping[],
|
||||
struct pipe_stream_output_info *so);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -367,6 +367,12 @@ st_translate_vertex_program(struct st_context *st,
|
||||
|
||||
ureg_destroy( ureg );
|
||||
|
||||
if (stvp->glsl_to_tgsi) {
|
||||
st_translate_stream_output_info(stvp->glsl_to_tgsi,
|
||||
stvp->result_to_output,
|
||||
&vpv->tgsi.stream_output);
|
||||
}
|
||||
|
||||
vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->tgsi);
|
||||
|
||||
if (ST_DEBUG & DEBUG_TGSI) {
|
||||
@@ -994,6 +1000,12 @@ st_translate_geometry_program(struct st_context *st,
|
||||
stgp->tgsi.tokens = ureg_get_tokens( ureg, NULL );
|
||||
ureg_destroy( ureg );
|
||||
|
||||
if (stgp->glsl_to_tgsi) {
|
||||
st_translate_stream_output_info(stgp->glsl_to_tgsi,
|
||||
outputMapping,
|
||||
&stgp->tgsi.stream_output);
|
||||
}
|
||||
|
||||
/* fill in new variant */
|
||||
gpv->driver_shader = pipe->create_gs_state(pipe, &stgp->tgsi);
|
||||
gpv->key = *key;
|
||||
|
Reference in New Issue
Block a user