summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorIago Toral Quiroga <[email protected]>2015-03-23 13:48:43 +0100
committerSamuel Iglesias Gonsalvez <[email protected]>2015-09-25 08:39:20 +0200
commit37da6a2acd549d145b1691bb1f6bab87b65c92a6 (patch)
tree043c7281a04f69ab052d4e03826d00f5560d2b72 /src
parentbdbabc57e302b73e2db30f6d46918afb2b442c7b (diff)
i965: Upload Shader Storage Buffer Object surfaces
Since these are a special kind of UBOs we emit them together reusing the same infrastructure, however, we use a RAW surface so we can reuse existing untyped read/write/atomic messages which include a pixel mask header that we need to set to obtain correct behavior with helper invocations of the fragment shader. Reviewed-by: Jordan Justen <[email protected]> Reviewed-by: Kristian Høgsberg <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.h6
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_surface_state.c64
2 files changed, 57 insertions, 13 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index b05b8bd69bf..144d3e327d4 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -1779,6 +1779,12 @@ void brw_create_constant_surface(struct brw_context *brw,
uint32_t size,
uint32_t *out_offset,
bool dword_pitch);
+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);
void brw_update_buffer_texture_surface(struct gl_context *ctx,
unsigned unit,
uint32_t *surf_offset);
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index 3af4b995a94..24ff2d6a443 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -411,6 +411,29 @@ brw_create_constant_surface(struct brw_context *brw,
}
/**
+ * 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).
*
@@ -905,25 +928,40 @@ brw_upload_ubo_surfaces(struct brw_context *brw,
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)