glsl: validate global out xfb_stride qualifiers and set stride on empty buffers
Here we use the built-in validation in ast_layout_expression::process_qualifier_constant() to check for mismatching global out strides on buffers in a single shader. From the ARB_enhanced_layouts spec: "While *xfb_stride* can be declared multiple times for the same buffer, it is a compile-time or link-time error to have different values specified for the stride for the same buffer." For intrastage validation a new helper link_xfb_stride_layout_qualifiers() is created. We also take this opportunity to make sure stride is at least a multiple of 4, we will validate doubles at a later stage. From the ARB_enhanced_layouts spec: "If the buffer is capturing any double-typed outputs, the stride must be a multiple of 8, otherwise it must be a multiple of 4, or a compile-time or link-time error results." Finally we update store_tfeedback_info() to apply the strides to LinkedTransformFeedback and update the buffers bitmask to mark any global buffers with a stride as active. For example a shader with: layout (xfb_buffer = 0, xfb_offset = 0) out vec4 gs_fs; layout (xfb_buffer = 1, xfb_stride = 64) out; Is expected to have a buffer bound to both 0 and 1. From the ARB_enhanced_layouts spec: "A binding point requires a bound buffer object if and only if its associated stride in the program object used for transform feedback primitive capture is non-zero." Reviewed-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
@@ -930,6 +930,17 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
|
||||
unsigned buffer =
|
||||
num_tfeedback_decls ? tfeedback_decls[0].get_buffer() : 0;
|
||||
|
||||
/* Apply any xfb_stride global qualifiers */
|
||||
if (has_xfb_qualifiers) {
|
||||
for (unsigned j = 0; j < MAX_FEEDBACK_BUFFERS; j++) {
|
||||
if (prog->TransformFeedback.BufferStride[j]) {
|
||||
buffers |= 1 << j;
|
||||
prog->LinkedTransformFeedback.Buffers[j].Stride =
|
||||
prog->TransformFeedback.BufferStride[j] / 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
|
||||
if (tfeedback_decls[i].is_next_buffer_separator()) {
|
||||
num_buffers++;
|
||||
|
Reference in New Issue
Block a user