summaryrefslogtreecommitdiffstats
path: root/src/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/lower_ubo_reference.cpp78
1 files changed, 43 insertions, 35 deletions
diff --git a/src/glsl/lower_ubo_reference.cpp b/src/glsl/lower_ubo_reference.cpp
index 3f241a6f630..5f332857350 100644
--- a/src/glsl/lower_ubo_reference.cpp
+++ b/src/glsl/lower_ubo_reference.cpp
@@ -172,6 +172,9 @@ public:
ssbo_atomic_access,
} buffer_access_type;
+ void insert_buffer_access(ir_dereference *deref, const glsl_type *type,
+ ir_rvalue *offset, unsigned mask, int channel);
+
void emit_access(bool is_write, ir_dereference *deref,
ir_variable *base_offset, unsigned int deref_offset,
bool row_major, int matrix_columns,
@@ -691,6 +694,41 @@ lower_ubo_reference_visitor::ssbo_load(const struct glsl_type *type,
return new(mem_ctx) ir_call(sig, deref_result, &call_params);
}
+void
+lower_ubo_reference_visitor::insert_buffer_access(ir_dereference *deref,
+ const glsl_type *type,
+ ir_rvalue *offset,
+ unsigned mask,
+ int channel)
+{
+ switch (this->buffer_access_type) {
+ case ubo_load_access:
+ base_ir->insert_before(assign(deref->clone(mem_ctx, NULL),
+ ubo_load(type, offset),
+ mask));
+ break;
+ case ssbo_load_access: {
+ ir_call *load_ssbo = ssbo_load(type, offset);
+ base_ir->insert_before(load_ssbo);
+ ir_rvalue *value = load_ssbo->return_deref->as_rvalue()->clone(mem_ctx, NULL);
+ ir_assignment *assignment =
+ assign(deref->clone(mem_ctx, NULL), value, mask);
+ base_ir->insert_before(assignment);
+ break;
+ }
+ case ssbo_store_access:
+ if (channel >= 0) {
+ base_ir->insert_after(ssbo_store(swizzle(deref, channel, 1),
+ offset, 1));
+ } else {
+ base_ir->insert_after(ssbo_store(deref, offset, mask));
+ }
+ break;
+ default:
+ unreachable("invalid buffer_access_type in insert_buffer_access");
+ }
+}
+
static inline int
writemask_for_size(unsigned n)
{
@@ -804,19 +842,9 @@ lower_ubo_reference_visitor::emit_access(bool is_write,
if (!row_major) {
ir_rvalue *offset =
add(base_offset, new(mem_ctx) ir_constant(deref_offset));
- if (is_write)
- base_ir->insert_after(ssbo_store(deref, offset, write_mask));
- else {
- if (this->buffer_access_type == ubo_load_access) {
- base_ir->insert_before(assign(deref->clone(mem_ctx, NULL),
- ubo_load(deref->type, offset)));
- } else {
- ir_call *load_ssbo = ssbo_load(deref->type, offset);
- base_ir->insert_before(load_ssbo);
- ir_rvalue *value = load_ssbo->return_deref->as_rvalue()->clone(mem_ctx, NULL);
- base_ir->insert_before(assign(deref->clone(mem_ctx, NULL), value));
- }
- }
+ unsigned mask =
+ is_write ? write_mask : (1 << deref->type->vector_elements) - 1;
+ insert_buffer_access(deref, deref->type, offset, mask, -1);
} else {
unsigned N = deref->type->is_double() ? 8 : 4;
@@ -865,28 +893,8 @@ lower_ubo_reference_visitor::emit_access(bool is_write,
ir_rvalue *chan_offset =
add(base_offset,
new(mem_ctx) ir_constant(deref_offset + i * matrix_stride));
- if (is_write) {
- /* If the component is not in the writemask, then don't
- * store any value.
- */
- if (!((1 << i) & write_mask))
- continue;
-
- base_ir->insert_after(ssbo_store(swizzle(deref, i, 1), chan_offset, 1));
- } else {
- if (this->buffer_access_type == ubo_load_access) {
- base_ir->insert_before(assign(deref->clone(mem_ctx, NULL),
- ubo_load(deref_type, chan_offset),
- (1U << i)));
- } else {
- ir_call *load_ssbo = ssbo_load(deref_type, chan_offset);
- base_ir->insert_before(load_ssbo);
- ir_rvalue *value = load_ssbo->return_deref->as_rvalue()->clone(mem_ctx, NULL);
- base_ir->insert_before(assign(deref->clone(mem_ctx, NULL),
- value,
- (1U << i)));
- }
- }
+ if (!is_write || ((1U << i) & write_mask))
+ insert_buffer_access(deref, deref_type, chan_offset, (1U << i), i);
}
}
}