elements, stride, false);
}
+/**
+ * Create the buffer surface. Shader buffer variables will be
+ * read from / write to this buffer with Data Port Read/Write
+ * instructions/messages.
+ */
+void
+brw_create_buffer_surface(struct brw_context *brw,
+ drm_intel_bo *bo,
+ uint32_t offset,
+ uint32_t size,
+ uint32_t *out_offset,
+ bool dword_pitch)
+{
+ /* Use a raw surface so we can reuse existing untyped read/write/atomic
+ * messages. We need these specifically for the fragment shader since they
+ * include a pixel mask header that we need to ensure correct behavior
+ * with helper invocations, which cannot write to the buffer.
+ */
+ brw->vtbl.emit_buffer_surface_state(brw, out_offset, bo, offset,
+ BRW_SURFACEFORMAT_RAW,
+ size, 1, true);
+}
+
/**
* Set up a binding table entry for use by stream output logic (transform
* feedback).
uint32_t *surf_offsets =
&stage_state->surf_offset[prog_data->binding_table.ubo_start];
- for (unsigned i = 0; i < shader->NumUniformBlocks; i++) {
- struct gl_uniform_buffer_binding *binding;
+ for (int i = 0; i < shader->NumUniformBlocks; i++) {
struct intel_buffer_object *intel_bo;
- binding = &ctx->UniformBufferBindings[shader->UniformBlocks[i].Binding];
- intel_bo = intel_buffer_object(binding->BufferObject);
- drm_intel_bo *bo =
- intel_bufferobj_buffer(brw, intel_bo,
- binding->Offset,
- binding->BufferObject->Size - binding->Offset);
-
/* Because behavior for referencing outside of the binding's size in the
* glBindBufferRange case is undefined, we can just bind the whole buffer
* glBindBufferBase wants and be a correct implementation.
*/
- brw_create_constant_surface(brw, bo, binding->Offset,
- bo->size - binding->Offset,
- &surf_offsets[i],
- dword_pitch);
+ if (!shader->UniformBlocks[i].IsShaderStorage) {
+ struct gl_uniform_buffer_binding *binding;
+ binding =
+ &ctx->UniformBufferBindings[shader->UniformBlocks[i].Binding];
+ intel_bo = intel_buffer_object(binding->BufferObject);
+ drm_intel_bo *bo =
+ intel_bufferobj_buffer(brw, intel_bo,
+ binding->Offset,
+ binding->BufferObject->Size - binding->Offset);
+ brw_create_constant_surface(brw, bo, binding->Offset,
+ bo->size - binding->Offset,
+ &surf_offsets[i],
+ dword_pitch);
+ } else {
+ struct gl_shader_storage_buffer_binding *binding;
+ binding =
+ &ctx->ShaderStorageBufferBindings[shader->UniformBlocks[i].Binding];
+ intel_bo = intel_buffer_object(binding->BufferObject);
+ drm_intel_bo *bo =
+ intel_bufferobj_buffer(brw, intel_bo,
+ binding->Offset,
+ binding->BufferObject->Size - binding->Offset);
+ brw_create_buffer_surface(brw, bo, binding->Offset,
+ bo->size - binding->Offset,
+ &surf_offsets[i],
+ dword_pitch);
+ }
}
if (shader->NumUniformBlocks)