aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGert Wollny <[email protected]>2019-03-19 17:24:26 +0100
committerGert Wollny <[email protected]>2019-04-02 09:58:16 +0000
commit33d9b9436c3c9026229f7cb33ad6f5f1c65e6900 (patch)
tree7e84e0c2d3ee98c4d1a0ffced48cae0398779298
parent4f153fcd5cee9d3ffeb45488a0ea83e0a2ff5658 (diff)
softpipe: Implement ATOMFADD and enable cap TGSI_ATOMFADD
This enables the following piglits with PASS: nv_shader_atomic_float/execution/ shared-atomicadd-float shared-atomicexchange-float ssbo-atomicadd-float ssbo-atomicexchange-float v2: Minimize the patch by using type punning (Eric Anholt) Signed-off-by: Gert Wollny <[email protected]> Reviewed-by: Eric Anholt <[email protected]>
-rw-r--r--src/gallium/drivers/softpipe/sp_buffer.c27
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c1
2 files changed, 18 insertions, 10 deletions
diff --git a/src/gallium/drivers/softpipe/sp_buffer.c b/src/gallium/drivers/softpipe/sp_buffer.c
index e91d2af78e9..3ec738527af 100644
--- a/src/gallium/drivers/softpipe/sp_buffer.c
+++ b/src/gallium/drivers/softpipe/sp_buffer.c
@@ -155,14 +155,14 @@ sp_tgsi_store(const struct tgsi_buffer *buffer,
* Implement atomic operations on unsigned integers.
*/
static void
-handle_op_uint(const struct pipe_shader_buffer *bview,
- bool just_read,
- unsigned char *data_ptr,
- uint qi,
- enum tgsi_opcode opcode,
- unsigned writemask,
- float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE],
- float rgba2[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
+handle_op_atomic(const struct pipe_shader_buffer *bview,
+ bool just_read,
+ unsigned char *data_ptr,
+ uint qi,
+ enum tgsi_opcode opcode,
+ unsigned writemask,
+ float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE],
+ float rgba2[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
{
uint c;
const struct util_format_description *format_desc = util_format_description(PIPE_FORMAT_R32_UINT);
@@ -260,6 +260,13 @@ handle_op_uint(const struct pipe_shader_buffer *bview,
((uint32_t *)rgba[c])[qi] = dst_x;
}
break;
+ case TGSI_OPCODE_ATOMFADD:
+ for (c = 0; c < 4; c++) {
+ float temp = uif(sdata[c]);
+ sdata[c] = fui(temp + rgba[c][qi]);
+ rgba[c][qi] = temp;
+ }
+ break;
default:
assert(!"Unexpected TGSI opcode in sp_tgsi_op");
break;
@@ -324,8 +331,8 @@ sp_tgsi_op(const struct tgsi_buffer *buffer,
data_ptr = (unsigned char *)spr->data + bview->buffer_offset + s_coord;
/* we should see atomic operations on r32 formats */
- handle_op_uint(bview, just_read, data_ptr, j,
- opcode, params->writemask, rgba, rgba2);
+ handle_op_atomic(bview, just_read, data_ptr, j,
+ opcode, params->writemask, rgba, rgba2);
}
return;
fail_write_all_zero:
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 438557e146a..37ee9b82a12 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -129,6 +129,7 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
return 1;
case PIPE_CAP_SHADER_STENCIL_EXPORT:
return 1;
+ case PIPE_CAP_TGSI_ATOMFADD:
case PIPE_CAP_TGSI_INSTANCEID:
case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
case PIPE_CAP_START_INSTANCE: