glsl: basic linking support for xfb qualifiers
This adds the initial infrastructure for enabling transform feedback mode via in shader qualifiers and adds initial buffer support. Reviewed-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
@@ -715,7 +715,8 @@ tfeedback_decl::get_num_outputs() const
|
||||
bool
|
||||
tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,
|
||||
struct gl_transform_feedback_info *info,
|
||||
unsigned buffer, const unsigned max_outputs) const
|
||||
unsigned buffer, const unsigned max_outputs,
|
||||
bool has_xfb_qualifiers) const
|
||||
{
|
||||
assert(!this->next_buffer_separator);
|
||||
|
||||
@@ -858,7 +859,7 @@ parse_tfeedback_decls(struct gl_context *ctx, struct gl_shader_program *prog,
|
||||
bool
|
||||
store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
|
||||
unsigned num_tfeedback_decls,
|
||||
tfeedback_decl *tfeedback_decls)
|
||||
tfeedback_decl *tfeedback_decls, bool has_xfb_qualifiers)
|
||||
{
|
||||
bool separate_attribs_mode =
|
||||
prog->TransformFeedback.BufferMode == GL_SEPARATE_ATTRIBS;
|
||||
@@ -885,11 +886,12 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
|
||||
|
||||
unsigned num_buffers = 0;
|
||||
|
||||
if (separate_attribs_mode) {
|
||||
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,
|
||||
num_buffers, num_outputs))
|
||||
num_buffers, num_outputs,
|
||||
has_xfb_qualifiers))
|
||||
return false;
|
||||
|
||||
num_buffers++;
|
||||
@@ -898,6 +900,9 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
|
||||
else {
|
||||
/* GL_INVERLEAVED_ATTRIBS */
|
||||
int buffer_stream_id = -1;
|
||||
unsigned buffer =
|
||||
num_tfeedback_decls ? tfeedback_decls[0].get_buffer() : 0;
|
||||
|
||||
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
|
||||
if (tfeedback_decls[i].is_next_buffer_separator()) {
|
||||
num_buffers++;
|
||||
@@ -920,9 +925,16 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (has_xfb_qualifiers) {
|
||||
buffer = tfeedback_decls[i].get_buffer();
|
||||
} else {
|
||||
buffer = num_buffers;
|
||||
}
|
||||
|
||||
if (!tfeedback_decls[i].store(ctx, prog,
|
||||
&prog->LinkedTransformFeedback,
|
||||
num_buffers, num_outputs))
|
||||
num_buffers, num_outputs,
|
||||
has_xfb_qualifiers))
|
||||
return false;
|
||||
}
|
||||
num_buffers++;
|
||||
|
@@ -98,7 +98,7 @@ public:
|
||||
unsigned get_num_outputs() const;
|
||||
bool store(struct gl_context *ctx, struct gl_shader_program *prog,
|
||||
struct gl_transform_feedback_info *info, unsigned buffer,
|
||||
const unsigned max_outputs) const;
|
||||
const unsigned max_outputs, bool has_xfb_qualifiers) const;
|
||||
const tfeedback_candidate *find_candidate(gl_shader_program *prog,
|
||||
hash_table *tfeedback_candidates);
|
||||
|
||||
@@ -301,7 +301,8 @@ remove_unused_shader_inputs_and_outputs(bool is_separate_shader_object,
|
||||
bool
|
||||
store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
|
||||
unsigned num_tfeedback_decls,
|
||||
tfeedback_decl *tfeedback_decls);
|
||||
tfeedback_decl *tfeedback_decls,
|
||||
bool has_xfb_qualifiers);
|
||||
|
||||
bool
|
||||
assign_varying_locations(struct gl_context *ctx,
|
||||
|
@@ -4169,9 +4169,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||
return;
|
||||
}
|
||||
|
||||
tfeedback_decl *tfeedback_decls = NULL;
|
||||
unsigned num_tfeedback_decls = prog->TransformFeedback.NumVarying;
|
||||
unsigned num_tfeedback_decls = 0;
|
||||
unsigned int num_explicit_uniform_locs = 0;
|
||||
bool has_xfb_qualifiers = false;
|
||||
char **varying_names = NULL;
|
||||
tfeedback_decl *tfeedback_decls = NULL;
|
||||
|
||||
void *mem_ctx = ralloc_context(NULL); // temporary linker context
|
||||
|
||||
@@ -4481,6 +4483,30 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* From the ARB_enhanced_layouts spec:
|
||||
*
|
||||
* "If the shader used to record output variables for transform feedback
|
||||
* varyings uses the "xfb_buffer", "xfb_offset", or "xfb_stride" layout
|
||||
* qualifiers, the values specified by TransformFeedbackVaryings are
|
||||
* ignored, and the set of variables captured for transform feedback is
|
||||
* instead derived from the specified layout qualifiers."
|
||||
*/
|
||||
for (int i = MESA_SHADER_FRAGMENT - 1; i >= 0; i--) {
|
||||
/* Find last stage before fragment shader */
|
||||
if (prog->_LinkedShaders[i]) {
|
||||
has_xfb_qualifiers =
|
||||
process_xfb_layout_qualifiers(mem_ctx, prog->_LinkedShaders[i],
|
||||
&num_tfeedback_decls,
|
||||
&varying_names);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_xfb_qualifiers) {
|
||||
num_tfeedback_decls = prog->TransformFeedback.NumVarying;
|
||||
varying_names = prog->TransformFeedback.VaryingNames;
|
||||
}
|
||||
|
||||
if (num_tfeedback_decls != 0) {
|
||||
/* From GL_EXT_transform_feedback:
|
||||
* A program will fail to link if:
|
||||
@@ -4497,10 +4523,9 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||
}
|
||||
|
||||
tfeedback_decls = ralloc_array(mem_ctx, tfeedback_decl,
|
||||
prog->TransformFeedback.NumVarying);
|
||||
num_tfeedback_decls);
|
||||
if (!parse_tfeedback_decls(ctx, prog, mem_ctx, num_tfeedback_decls,
|
||||
prog->TransformFeedback.VaryingNames,
|
||||
tfeedback_decls))
|
||||
varying_names, tfeedback_decls))
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -4580,7 +4605,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
|
||||
}
|
||||
}
|
||||
|
||||
if (!store_tfeedback_info(ctx, prog, num_tfeedback_decls, tfeedback_decls))
|
||||
if (!store_tfeedback_info(ctx, prog, num_tfeedback_decls, tfeedback_decls,
|
||||
has_xfb_qualifiers))
|
||||
goto done;
|
||||
|
||||
update_array_sizes(prog);
|
||||
|
Reference in New Issue
Block a user