From 700bc94dcebf4257740483d2ba467b138234fa1a Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Thu, 3 Nov 2016 16:00:37 +1100 Subject: [PATCH] mesa/glsl: move LinkedTransformFeedback from gl_shader_program to gl_program This will help allow us to store gl_program in the CurrentProgram array rather than gl_shader_program which will allow a bunch of simplifications. Note that we make LinkedTransformFeedback a pointer so we don't waste memory creating a struct for each stage. We also store a pointer to the gl_program that will contain the pointer in gl_shader_program so we can get easy access to the correct stage. Reviewed-by: Eric Anholt --- src/compiler/glsl/link_varyings.cpp | 34 +++++++++++++-------------- src/compiler/glsl/linker.cpp | 29 ++++++++++++++++------- src/mesa/drivers/dri/i965/brw_ff_gs.c | 2 +- src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp | 2 +- src/mesa/drivers/dri/i965/gen6_sol.c | 9 +++---- src/mesa/drivers/dri/i965/gen7_sol_state.c | 6 ++--- src/mesa/main/mtypes.h | 6 +++-- src/mesa/main/shader_query.cpp | 8 +++---- src/mesa/main/transformfeedback.c | 2 +- src/mesa/state_tracker/st_cb_xformfb.c | 8 +++---- src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 2 +- src/mesa/state_tracker/st_program.c | 2 +- 12 files changed, 62 insertions(+), 48 deletions(-) diff --git a/src/compiler/glsl/link_varyings.cpp b/src/compiler/glsl/link_varyings.cpp index 866570c..e1a29b0 100644 --- a/src/compiler/glsl/link_varyings.cpp +++ b/src/compiler/glsl/link_varyings.cpp @@ -1063,7 +1063,8 @@ cmp_xfb_offset(const void * x_generic, const void * y_generic) /** * Store transform feedback location assignments into - * prog->LinkedTransformFeedback based on the data stored in tfeedback_decls. + * prog->sh.LinkedTransformFeedback based on the data stored in + * tfeedback_decls. * * If an error occurs, the error is reported through linker_error() and false * is returned. @@ -1081,11 +1082,9 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog, bool separate_attribs_mode = prog->TransformFeedback.BufferMode == GL_SEPARATE_ATTRIBS; - ralloc_free(prog->LinkedTransformFeedback.Varyings); - ralloc_free(prog->LinkedTransformFeedback.Outputs); - - memset(&prog->LinkedTransformFeedback, 0, - sizeof(prog->LinkedTransformFeedback)); + struct gl_program *xfb_prog = prog->xfb_program; + xfb_prog->sh.LinkedTransformFeedback = + rzalloc(xfb_prog, struct gl_transform_feedback_info); /* The xfb_offset qualifier does not have to be used in increasing order * however some drivers expect to receive the list of transform feedback @@ -1095,9 +1094,8 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog, qsort(tfeedback_decls, num_tfeedback_decls, sizeof(*tfeedback_decls), cmp_xfb_offset); - prog->LinkedTransformFeedback.Varyings = - rzalloc_array(prog, - struct gl_transform_feedback_varying_info, + xfb_prog->sh.LinkedTransformFeedback->Varyings = + rzalloc_array(xfb_prog, struct gl_transform_feedback_varying_info, num_tfeedback_decls); unsigned num_outputs = 0; @@ -1106,9 +1104,8 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog, num_outputs += tfeedback_decls[i].get_num_outputs(); } - prog->LinkedTransformFeedback.Outputs = - rzalloc_array(prog, - struct gl_transform_feedback_output, + xfb_prog->sh.LinkedTransformFeedback->Outputs = + rzalloc_array(xfb_prog, struct gl_transform_feedback_output, num_outputs); unsigned num_buffers = 0; @@ -1117,7 +1114,8 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog, if (!has_xfb_qualifiers && separate_attribs_mode) { /* GL_SEPARATE_ATTRIBS */ for (unsigned i = 0; i < num_tfeedback_decls; ++i) { - if (!tfeedback_decls[i].store(ctx, prog, &prog->LinkedTransformFeedback, + if (!tfeedback_decls[i].store(ctx, prog, + xfb_prog->sh.LinkedTransformFeedback, num_buffers, num_buffers, num_outputs, NULL, has_xfb_qualifiers)) return false; @@ -1139,7 +1137,7 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog, if (prog->TransformFeedback.BufferStride[j]) { buffers |= 1 << j; explicit_stride[j] = true; - prog->LinkedTransformFeedback.Buffers[j].Stride = + xfb_prog->sh.LinkedTransformFeedback->Buffers[j].Stride = prog->TransformFeedback.BufferStride[j] / 4; } } @@ -1155,7 +1153,7 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog, if (tfeedback_decls[i].is_next_buffer_separator()) { if (!tfeedback_decls[i].store(ctx, prog, - &prog->LinkedTransformFeedback, + xfb_prog->sh.LinkedTransformFeedback, buffer, num_buffers, num_outputs, explicit_stride, has_xfb_qualifiers)) return false; @@ -1189,16 +1187,16 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog, buffers |= 1 << buffer; if (!tfeedback_decls[i].store(ctx, prog, - &prog->LinkedTransformFeedback, + xfb_prog->sh.LinkedTransformFeedback, buffer, num_buffers, num_outputs, explicit_stride, has_xfb_qualifiers)) return false; } } - assert(prog->LinkedTransformFeedback.NumOutputs == num_outputs); + assert(xfb_prog->sh.LinkedTransformFeedback->NumOutputs == num_outputs); - prog->LinkedTransformFeedback.ActiveBuffers = buffers; + xfb_prog->sh.LinkedTransformFeedback->ActiveBuffers = buffers; return true; } diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index e5cc6de..209129c 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -4242,25 +4242,26 @@ build_program_resource_list(struct gl_context *ctx, output_stage, GL_PROGRAM_OUTPUT)) return; + struct gl_transform_feedback_info *linked_xfb = + shProg->xfb_program->sh.LinkedTransformFeedback; + /* Add transform feedback varyings. */ - if (shProg->LinkedTransformFeedback.NumVarying > 0) { - for (int i = 0; i < shProg->LinkedTransformFeedback.NumVarying; i++) { + if (linked_xfb->NumVarying > 0) { + for (int i = 0; i < linked_xfb->NumVarying; i++) { if (!add_program_resource(shProg, resource_set, GL_TRANSFORM_FEEDBACK_VARYING, - &shProg->LinkedTransformFeedback.Varyings[i], - 0)) + &linked_xfb->Varyings[i], 0)) return; } } /* Add transform feedback buffers. */ for (unsigned i = 0; i < ctx->Const.MaxTransformFeedbackBuffers; i++) { - if ((shProg->LinkedTransformFeedback.ActiveBuffers >> i) & 1) { - shProg->LinkedTransformFeedback.Buffers[i].Binding = i; + if ((linked_xfb->ActiveBuffers >> i) & 1) { + linked_xfb->Buffers[i].Binding = i; if (!add_program_resource(shProg, resource_set, GL_TRANSFORM_FEEDBACK_BUFFER, - &shProg->LinkedTransformFeedback.Buffers[i], - 0)) + &linked_xfb->Buffers[i], 0)) return; } } @@ -4587,6 +4588,18 @@ link_varyings_and_uniforms(unsigned first, unsigned last, varying_names = prog->TransformFeedback.VaryingNames; } + /* Find the program used for xfb. Even if we don't use xfb we still want to + * set this so we can fill the default values for program interface query. + */ + prog->xfb_program = prog->_LinkedShaders[last]->Program; + for (int i = MESA_SHADER_GEOMETRY; i >= MESA_SHADER_VERTEX; i--) { + if (prog->_LinkedShaders[i] == NULL) + continue; + + prog->xfb_program = prog->_LinkedShaders[i]->Program; + break; + } + if (num_tfeedback_decls != 0) { /* From GL_EXT_transform_feedback: * A program will fail to link if: diff --git a/src/mesa/drivers/dri/i965/brw_ff_gs.c b/src/mesa/drivers/dri/i965/brw_ff_gs.c index c712939..4934af3 100644 --- a/src/mesa/drivers/dri/i965/brw_ff_gs.c +++ b/src/mesa/drivers/dri/i965/brw_ff_gs.c @@ -198,7 +198,7 @@ brw_ff_gs_populate_key(struct brw_context *brw, const struct gl_shader_program *shaderprog = ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; const struct gl_transform_feedback_info *linked_xfb_info = - &shaderprog->LinkedTransformFeedback; + shaderprog->xfb_program->sh.LinkedTransformFeedback; int i; /* Make sure that the VUE slots won't overflow the unsigned chars in diff --git a/src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp b/src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp index 7254729..4bd3788 100644 --- a/src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp @@ -534,7 +534,7 @@ gen6_gs_visitor::xfb_setup() }; const struct gl_transform_feedback_info *linked_xfb_info = - &this->shader_prog->LinkedTransformFeedback; + this->shader_prog->xfb_program->sh.LinkedTransformFeedback; int i; /* Make sure that the VUE slots won't overflow the unsigned chars in diff --git a/src/mesa/drivers/dri/i965/gen6_sol.c b/src/mesa/drivers/dri/i965/gen6_sol.c index 6574749..f6a183a 100644 --- a/src/mesa/drivers/dri/i965/gen6_sol.c +++ b/src/mesa/drivers/dri/i965/gen6_sol.c @@ -45,7 +45,8 @@ gen6_update_sol_surfaces(struct brw_context *brw) if (xfb_active) { /* BRW_NEW_TRANSFORM_FEEDBACK */ xfb_obj = ctx->TransformFeedback.CurrentObject; - linked_xfb_info = &xfb_obj->shader_program->LinkedTransformFeedback; + linked_xfb_info = + xfb_obj->shader_program->xfb_program->sh.LinkedTransformFeedback; } for (int i = 0; i < BRW_MAX_SOL_BINDINGS; ++i) { @@ -116,7 +117,7 @@ brw_gs_upload_binding_table(struct brw_context *brw) if (shaderprog) { /* Skip making a binding table if we don't have anything to put in it */ const struct gl_transform_feedback_info *linked_xfb_info = - &shaderprog->LinkedTransformFeedback; + shaderprog->xfb_program->sh.LinkedTransformFeedback; need_binding_table = linked_xfb_info->NumOutputs > 0; } if (!need_binding_table) { @@ -145,7 +146,7 @@ brw_gs_upload_binding_table(struct brw_context *brw) /* Skip making a binding table if we don't have anything to put in it */ struct brw_stage_prog_data *prog_data = brw->gs.base.prog_data; const struct gl_transform_feedback_info *linked_xfb_info = - &shaderprog->LinkedTransformFeedback; + shaderprog->xfb_program->sh.LinkedTransformFeedback; need_binding_table = linked_xfb_info->NumOutputs > 0 || prog_data->binding_table.size_bytes > 0; } @@ -241,7 +242,7 @@ brw_begin_transform_feedback(struct gl_context *ctx, GLenum mode, shaderprog = ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; } - linked_xfb_info = &shaderprog->LinkedTransformFeedback; + linked_xfb_info = shaderprog->xfb_program->sh.LinkedTransformFeedback; /* Compute the maximum number of vertices that we can write without * overflowing any of the buffers currently being used for feedback. diff --git a/src/mesa/drivers/dri/i965/gen7_sol_state.c b/src/mesa/drivers/dri/i965/gen7_sol_state.c index 1775274..5170f6a 100644 --- a/src/mesa/drivers/dri/i965/gen7_sol_state.c +++ b/src/mesa/drivers/dri/i965/gen7_sol_state.c @@ -43,7 +43,7 @@ upload_3dstate_so_buffers(struct brw_context *brw) struct gl_transform_feedback_object *xfb_obj = ctx->TransformFeedback.CurrentObject; const struct gl_transform_feedback_info *linked_xfb_info = - &xfb_obj->shader_program->LinkedTransformFeedback; + xfb_obj->shader_program->xfb_program->sh.LinkedTransformFeedback; int i; /* Set up the up to 4 output buffers. These are the ranges defined in the @@ -103,7 +103,7 @@ gen7_upload_3dstate_so_decl_list(struct brw_context *brw, struct gl_transform_feedback_object *xfb_obj = ctx->TransformFeedback.CurrentObject; const struct gl_transform_feedback_info *linked_xfb_info = - &xfb_obj->shader_program->LinkedTransformFeedback; + xfb_obj->shader_program->xfb_program->sh.LinkedTransformFeedback; uint16_t so_decl[MAX_VERTEX_STREAMS][128]; int buffer_mask[MAX_VERTEX_STREAMS] = {0, 0, 0, 0}; int next_offset[MAX_VERTEX_STREAMS] = {0, 0, 0, 0}; @@ -229,7 +229,7 @@ upload_3dstate_streamout(struct brw_context *brw, bool active, struct gl_transform_feedback_object *xfb_obj = ctx->TransformFeedback.CurrentObject; const struct gl_transform_feedback_info *linked_xfb_info = - &xfb_obj->shader_program->LinkedTransformFeedback; + xfb_obj->shader_program->xfb_program->sh.LinkedTransformFeedback; uint32_t dw1 = 0, dw2 = 0, dw3 = 0, dw4 = 0; int i; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 8842791..9b736bb 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1950,6 +1950,9 @@ struct gl_program struct { struct gl_active_atomic_buffer **AtomicBuffers; + /** Post-link transform feedback info. */ + struct gl_transform_feedback_info *LinkedTransformFeedback; + /** * Number of types for subroutine uniforms. */ @@ -2737,8 +2740,7 @@ struct gl_shader_program GLchar **VaryingNames; /**< Array [NumVarying] of char * */ } TransformFeedback; - /** Post-link transform feedback info. */ - struct gl_transform_feedback_info LinkedTransformFeedback; + struct gl_program *xfb_program; /** Post-link gl_FragDepth layout for ARB_conservative_depth. */ enum gl_frag_depth_layout FragDepthLayout; diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp index 2f15773..0f4b282 100644 --- a/src/mesa/main/shader_query.cpp +++ b/src/mesa/main/shader_query.cpp @@ -1041,10 +1041,10 @@ get_buffer_property(struct gl_shader_program *shProg, *val = RESOURCE_XFB(res)->NumVaryings; return 1; case GL_ACTIVE_VARIABLES: - int i = 0; - for ( ; i < shProg->LinkedTransformFeedback.NumVarying; i++) { - unsigned index = - shProg->LinkedTransformFeedback.Varyings[i].BufferIndex; + struct gl_transform_feedback_info *linked_xfb = + shProg->xfb_program->sh.LinkedTransformFeedback; + for (int i = 0; i < linked_xfb->NumVarying; i++) { + unsigned index = linked_xfb->Varyings[i].BufferIndex; struct gl_program_resource *buf_res = _mesa_program_resource_find_index(shProg, GL_TRANSFORM_FEEDBACK_BUFFER, diff --git a/src/mesa/main/transformfeedback.c b/src/mesa/main/transformfeedback.c index 738d63e..2088c76 100644 --- a/src/mesa/main/transformfeedback.c +++ b/src/mesa/main/transformfeedback.c @@ -418,7 +418,7 @@ _mesa_BeginTransformFeedback(GLenum mode) return; } - info = &source->LinkedTransformFeedback; + info = source->xfb_program->sh.LinkedTransformFeedback; if (info->NumOutputs == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, diff --git a/src/mesa/state_tracker/st_cb_xformfb.c b/src/mesa/state_tracker/st_cb_xformfb.c index a5cf3df..bbc9e03 100644 --- a/src/mesa/state_tracker/st_cb_xformfb.c +++ b/src/mesa/state_tracker/st_cb_xformfb.c @@ -124,8 +124,8 @@ st_begin_transform_feedback(struct gl_context *ctx, GLenum mode, struct st_buffer_object *bo = st_buffer_object(sobj->base.Buffers[i]); if (bo && bo->buffer) { - unsigned stream = - obj->shader_program->LinkedTransformFeedback.Buffers[i].Stream; + unsigned stream = obj->shader_program->xfb_program-> + sh.LinkedTransformFeedback->Buffers[i].Stream; /* Check whether we need to recreate the target. */ if (!sobj->targets[i] || @@ -203,8 +203,8 @@ st_end_transform_feedback(struct gl_context *ctx, pipe_so_target_reference(&sobj->draw_count[i], NULL); for (i = 0; i < ARRAY_SIZE(sobj->targets); i++) { - unsigned stream = - obj->shader_program->LinkedTransformFeedback.Buffers[i].Stream; + unsigned stream = obj->shader_program->xfb_program-> + sh.LinkedTransformFeedback->Buffers[i].Stream; /* Is it not bound or already set for this stream? */ if (!sobj->targets[i] || sobj->draw_count[stream]) diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index c9ebb5a..9599296 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -6919,7 +6919,7 @@ st_translate_stream_output_info(glsl_to_tgsi_visitor *glsl_to_tgsi, struct pipe_stream_output_info *so) { struct gl_transform_feedback_info *info = - &glsl_to_tgsi->shader_program->LinkedTransformFeedback; + glsl_to_tgsi->shader_program->xfb_program->sh.LinkedTransformFeedback; st_translate_stream_output_info2(info, outputMapping, so); } diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index bf15031..e9dd584 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -390,7 +390,7 @@ st_translate_vertex_program(struct st_context *st, stvp->tgsi.type = PIPE_SHADER_IR_NIR; stvp->tgsi.ir.nir = nir; - st_translate_stream_output_info2(&stvp->shader_program->LinkedTransformFeedback, + st_translate_stream_output_info2(stvp->shader_program->xfb_program->sh.LinkedTransformFeedback, stvp->result_to_output, &stvp->tgsi.stream_output); return true; -- 2.7.4