/**
* 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.
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
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;
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;
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;
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;
}
}
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;
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;
}
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;
}
}
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:
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
};
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
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) {
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) {
/* 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;
}
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.
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
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};
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;
struct {
struct gl_active_atomic_buffer **AtomicBuffers;
+ /** Post-link transform feedback info. */
+ struct gl_transform_feedback_info *LinkedTransformFeedback;
+
/**
* Number of types for subroutine uniforms.
*/
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;
*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,
return;
}
- info = &source->LinkedTransformFeedback;
+ info = source->xfb_program->sh.LinkedTransformFeedback;
if (info->NumOutputs == 0) {
_mesa_error(ctx, GL_INVALID_OPERATION,
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] ||
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])
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);
}
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;