diff options
author | Iago Toral Quiroga <[email protected]> | 2015-03-23 13:48:43 +0100 |
---|---|---|
committer | Samuel Iglesias Gonsalvez <[email protected]> | 2015-09-25 08:39:20 +0200 |
commit | 37da6a2acd549d145b1691bb1f6bab87b65c92a6 (patch) | |
tree | 043c7281a04f69ab052d4e03826d00f5560d2b72 | |
parent | bdbabc57e302b73e2db30f6d46918afb2b442c7b (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]>
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_context.h | 6 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 64 |
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) |