From: Iago Toral Quiroga Date: Mon, 23 Mar 2015 12:48:43 +0000 (+0100) Subject: i965: Upload Shader Storage Buffer Object surfaces X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=37da6a2acd549d145b1691bb1f6bab87b65c92a6;p=mesa.git 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 Reviewed-by: Kristian Høgsberg --- 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 @@ -410,6 +410,29 @@ brw_create_constant_surface(struct brw_context *brw, 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). @@ -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)