exec_store_buf(struct tgsi_exec_machine *mach,
const struct tgsi_full_instruction *inst)
{
- union tgsi_exec_channel r[3];
- union tgsi_exec_channel value[4];
- float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
- struct tgsi_buffer_params params;
- int i, j;
- uint unit;
- int kilmask = mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0];
+ uint32_t unit = fetch_store_img_unit(mach, &inst->Dst[0]);
+ uint32_t size;
+ char *ptr = mach->Buffer->lookup(mach->Buffer, unit, &size);
- unit = fetch_store_img_unit(mach, &inst->Dst[0]);
+ int kilmask = mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0];
+ int execmask = mach->ExecMask & mach->NonHelperMask & ~kilmask;
- params.execmask = mach->ExecMask & mach->NonHelperMask & ~kilmask;
- params.unit = unit;
- params.writemask = inst->Dst[0].Register.WriteMask;
+ union tgsi_exec_channel offset;
+ IFETCH(&offset, 0, TGSI_CHAN_X);
- IFETCH(&r[0], 0, TGSI_CHAN_X);
- for (i = 0; i < 4; i++) {
+ union tgsi_exec_channel value[4];
+ for (int i = 0; i < 4; i++)
FETCH(&value[i], 1, TGSI_CHAN_X + i);
- }
- for (j = 0; j < TGSI_QUAD_SIZE; j++) {
- rgba[0][j] = value[0].f[j];
- rgba[1][j] = value[1].f[j];
- rgba[2][j] = value[2].f[j];
- rgba[3][j] = value[3].f[j];
- }
+ for (int j = 0; j < TGSI_QUAD_SIZE; j++) {
+ if (!(execmask & (1 << j)))
+ continue;
+ if (size < offset.u[j])
+ continue;
- mach->Buffer->store(mach->Buffer, ¶ms,
- r[0].i,
- rgba);
+ uint32_t *invocation_ptr = (uint32_t *)(ptr + offset.u[j]);
+ uint32_t size_avail = size - offset.u[j];
+
+ for (int chan = 0; chan < MIN2(4, size_avail / 4); chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan))
+ memcpy(&invocation_ptr[chan], &value[chan].u[j], 4);
+ }
+ }
}
static void
return true;
}
-/*
- * Implement the buffer STORE operation.
- */
-static void
-sp_tgsi_store(const struct tgsi_buffer *buffer,
- const struct tgsi_buffer_params *params,
- const int s[TGSI_QUAD_SIZE],
- float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
-{
- struct sp_tgsi_buffer *sp_buf = (struct sp_tgsi_buffer *)buffer;
- struct pipe_shader_buffer *bview;
- struct softpipe_resource *spr;
- unsigned width;
- int j, c;
-
- if (params->unit >= PIPE_MAX_SHADER_BUFFERS)
- return;
-
- bview = &sp_buf->sp_bview[params->unit];
- spr = softpipe_resource(bview->buffer);
- if (!spr)
- return;
-
- if (!get_dimensions(bview, spr, &width))
- return;
-
- for (j = 0; j < TGSI_QUAD_SIZE; j++) {
- int s_coord;
-
- if (!(params->execmask & (1 << j)))
- continue;
-
- s_coord = s[j];
- if (s_coord >= width)
- continue;
-
- uint32_t *dst = (uint32_t *)((unsigned char *)spr->data +
- bview->buffer_offset + s_coord);
-
- for (c = 0; c < 4; c++) {
- if (params->writemask & (1 << c))
- memcpy(&dst[c], &rgba[c][j], 4);
- }
- }
-}
-
static void *
sp_tgsi_ssbo_lookup(const struct tgsi_buffer *buffer,
uint32_t unit,
if (!buf)
return NULL;
- buf->base.store = sp_tgsi_store;
buf->base.lookup = sp_tgsi_ssbo_lookup;
buf->base.get_dims = sp_tgsi_get_dims;
return buf;