#include "fd3_format.h"
#include "fd3_zsa.h"
+#define emit_const_user fd3_emit_const_user
+#define emit_const_bo fd3_emit_const_bo
#include "ir3_const.h"
static const enum adreno_state_block sb[] = {
* sizedwords: size of const value buffer
*/
static void
-fd3_emit_const(struct fd_ringbuffer *ring, gl_shader_stage type,
- uint32_t regid, uint32_t offset, uint32_t sizedwords,
- const uint32_t *dwords, struct pipe_resource *prsc)
+fd3_emit_const_user(struct fd_ringbuffer *ring,
+ const struct ir3_shader_variant *v,
+ uint32_t regid, uint32_t sizedwords, const uint32_t *dwords)
{
- uint32_t i, sz;
- enum adreno_state_src src;
-
- debug_assert((regid % 4) == 0);
- debug_assert((sizedwords % 4) == 0);
-
- if (prsc) {
- sz = 0;
- src = SS_INDIRECT;
- } else {
- sz = sizedwords;
- src = SS_DIRECT;
- }
+ emit_const_asserts(ring, v, regid, sizedwords);
- OUT_PKT3(ring, CP_LOAD_STATE, 2 + sz);
+ OUT_PKT3(ring, CP_LOAD_STATE, 2 + sizedwords);
OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(regid/2) |
- CP_LOAD_STATE_0_STATE_SRC(src) |
- CP_LOAD_STATE_0_STATE_BLOCK(sb[type]) |
+ CP_LOAD_STATE_0_STATE_SRC(SS_DIRECT) |
+ CP_LOAD_STATE_0_STATE_BLOCK(sb[v->type]) |
CP_LOAD_STATE_0_NUM_UNIT(sizedwords/2));
- if (prsc) {
- struct fd_bo *bo = fd_resource(prsc)->bo;
- OUT_RELOC(ring, bo, offset,
- CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS), 0);
- } else {
- OUT_RING(ring, CP_LOAD_STATE_1_EXT_SRC_ADDR(0) |
- CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS));
- dwords = (uint32_t *)&((uint8_t *)dwords)[offset];
- }
- for (i = 0; i < sz; i++) {
+ OUT_RING(ring, CP_LOAD_STATE_1_EXT_SRC_ADDR(0) |
+ CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS));
+ for (int i = 0; i < sizedwords; i++)
OUT_RING(ring, dwords[i]);
- }
+}
+
+static void
+fd3_emit_const_bo(struct fd_ringbuffer *ring, const struct ir3_shader_variant *v,
+ uint32_t regid, uint32_t offset, uint32_t sizedwords,
+ struct fd_bo *bo)
+{
+ emit_const_asserts(ring, v, regid, sizedwords);
+
+ OUT_PKT3(ring, CP_LOAD_STATE, 2);
+ OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(regid/2) |
+ CP_LOAD_STATE_0_STATE_SRC(SS_INDIRECT) |
+ CP_LOAD_STATE_0_STATE_BLOCK(sb[v->type]) |
+ CP_LOAD_STATE_0_NUM_UNIT(sizedwords/2));
+ OUT_RELOC(ring, bo, offset,
+ CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS), 0);
}
static void
return false;
}
-void
-emit_const(struct fd_ringbuffer *ring,
- const struct ir3_shader_variant *v, uint32_t dst_offset,
- uint32_t offset, uint32_t size, const void *user_buffer,
- struct pipe_resource *buffer)
-{
- /* TODO inline this */
- assert(dst_offset + size <= v->constlen * 4);
- fd3_emit_const(ring, v->type, dst_offset,
- offset, size, user_buffer, buffer);
-}
-
static void
emit_const_ptrs(struct fd_ringbuffer *ring,
const struct ir3_shader_variant *v, uint32_t dst_offset,
#include "fd4_format.h"
#include "fd4_zsa.h"
+#define emit_const_user fd4_emit_const_user
+#define emit_const_bo fd4_emit_const_bo
#include "ir3_const.h"
/* regid: base const register
* sizedwords: size of const value buffer
*/
static void
-fd4_emit_const(struct fd_ringbuffer *ring, gl_shader_stage type,
- uint32_t regid, uint32_t offset, uint32_t sizedwords,
- const uint32_t *dwords, struct pipe_resource *prsc)
+fd4_emit_const_user(struct fd_ringbuffer *ring,
+ const struct ir3_shader_variant *v, uint32_t regid, uint32_t sizedwords,
+ const uint32_t *dwords)
{
- uint32_t i, sz;
- enum a4xx_state_src src;
+ emit_const_asserts(ring, v, regid, sizedwords);
- debug_assert((regid % 4) == 0);
- debug_assert((sizedwords % 4) == 0);
+ OUT_PKT3(ring, CP_LOAD_STATE4, 2 + sizedwords);
+ OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(regid/4) |
+ CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) |
+ CP_LOAD_STATE4_0_STATE_BLOCK(fd4_stage2shadersb(v->type)) |
+ CP_LOAD_STATE4_0_NUM_UNIT(sizedwords/4));
+ OUT_RING(ring, CP_LOAD_STATE4_1_EXT_SRC_ADDR(0) |
+ CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS));
+ for (int i = 0; i < sizedwords; i++)
+ OUT_RING(ring, dwords[i]);
+}
- if (prsc) {
- sz = 0;
- src = SS4_INDIRECT;
- } else {
- sz = sizedwords;
- src = SS4_DIRECT;
- }
+static void
+fd4_emit_const_bo(struct fd_ringbuffer *ring, const struct ir3_shader_variant *v,
+ uint32_t regid, uint32_t offset, uint32_t sizedwords,
+ struct fd_bo *bo)
+{
+ emit_const_asserts(ring, v, regid, sizedwords);
- OUT_PKT3(ring, CP_LOAD_STATE4, 2 + sz);
+ OUT_PKT3(ring, CP_LOAD_STATE4, 2);
OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(regid/4) |
- CP_LOAD_STATE4_0_STATE_SRC(src) |
- CP_LOAD_STATE4_0_STATE_BLOCK(fd4_stage2shadersb(type)) |
+ CP_LOAD_STATE4_0_STATE_SRC(SS4_INDIRECT) |
+ CP_LOAD_STATE4_0_STATE_BLOCK(fd4_stage2shadersb(v->type)) |
CP_LOAD_STATE4_0_NUM_UNIT(sizedwords/4));
- if (prsc) {
- struct fd_bo *bo = fd_resource(prsc)->bo;
- OUT_RELOC(ring, bo, offset,
- CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS), 0);
- } else {
- OUT_RING(ring, CP_LOAD_STATE4_1_EXT_SRC_ADDR(0) |
- CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS));
- dwords = (uint32_t *)&((uint8_t *)dwords)[offset];
- }
- for (i = 0; i < sz; i++) {
- OUT_RING(ring, dwords[i]);
- }
+ OUT_RELOC(ring, bo, offset,
+ CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS), 0);
}
static void
return false;
}
-void
-emit_const(struct fd_ringbuffer *ring,
- const struct ir3_shader_variant *v, uint32_t dst_offset,
- uint32_t offset, uint32_t size, const void *user_buffer,
- struct pipe_resource *buffer)
-{
- /* TODO inline this */
- assert(dst_offset + size <= v->constlen * 4);
- fd4_emit_const(ring, v->type, dst_offset,
- offset, size, user_buffer, buffer);
-}
-
static void
emit_const_ptrs(struct fd_ringbuffer *ring,
const struct ir3_shader_variant *v, uint32_t dst_offset,
#include "fd5_format.h"
#include "fd5_zsa.h"
+#define emit_const_user fd5_emit_const_user
+#define emit_const_bo fd5_emit_const_bo
#include "ir3_const.h"
/* regid: base const register
* sizedwords: size of const value buffer
*/
static void
-fd5_emit_const(struct fd_ringbuffer *ring, gl_shader_stage type,
- uint32_t regid, uint32_t offset, uint32_t sizedwords,
- const uint32_t *dwords, struct pipe_resource *prsc)
+fd5_emit_const_user(struct fd_ringbuffer *ring,
+ const struct ir3_shader_variant *v, uint32_t regid, uint32_t sizedwords,
+ const uint32_t *dwords)
{
- uint32_t i, sz;
- enum a4xx_state_src src;
+ emit_const_asserts(ring, v, regid, sizedwords);
- debug_assert((regid % 4) == 0);
- debug_assert((sizedwords % 4) == 0);
+ OUT_PKT7(ring, CP_LOAD_STATE4, 3 + sizedwords);
+ OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(regid/4) |
+ CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) |
+ CP_LOAD_STATE4_0_STATE_BLOCK(fd4_stage2shadersb(v->type)) |
+ CP_LOAD_STATE4_0_NUM_UNIT(sizedwords/4));
+ OUT_RING(ring, CP_LOAD_STATE4_1_EXT_SRC_ADDR(0) |
+ CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS));
+ OUT_RING(ring, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));
+ for (int i = 0; i < sizedwords; i++)
+ OUT_RING(ring, ((uint32_t *)dwords)[i]);
+}
- if (prsc) {
- sz = 0;
- src = SS4_INDIRECT;
- } else {
- sz = sizedwords;
- src = SS4_DIRECT;
- }
+static void
+fd5_emit_const_bo(struct fd_ringbuffer *ring, const struct ir3_shader_variant *v,
+ uint32_t regid, uint32_t offset, uint32_t sizedwords, struct fd_bo *bo)
+{
+ emit_const_asserts(ring, v, regid, sizedwords);
- OUT_PKT7(ring, CP_LOAD_STATE4, 3 + sz);
+ OUT_PKT7(ring, CP_LOAD_STATE4, 3);
OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(regid/4) |
- CP_LOAD_STATE4_0_STATE_SRC(src) |
- CP_LOAD_STATE4_0_STATE_BLOCK(fd4_stage2shadersb(type)) |
+ CP_LOAD_STATE4_0_STATE_SRC(SS4_INDIRECT) |
+ CP_LOAD_STATE4_0_STATE_BLOCK(fd4_stage2shadersb(v->type)) |
CP_LOAD_STATE4_0_NUM_UNIT(sizedwords/4));
- if (prsc) {
- struct fd_bo *bo = fd_resource(prsc)->bo;
- OUT_RELOC(ring, bo, offset,
- CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS), 0);
- } else {
- OUT_RING(ring, CP_LOAD_STATE4_1_EXT_SRC_ADDR(0) |
- CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS));
- OUT_RING(ring, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));
- dwords = (uint32_t *)&((uint8_t *)dwords)[offset];
- }
- for (i = 0; i < sz; i++) {
- OUT_RING(ring, dwords[i]);
- }
+ OUT_RELOC(ring, bo, offset,
+ CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS), 0);
}
static void
return false;
}
-void
-emit_const(struct fd_ringbuffer *ring,
- const struct ir3_shader_variant *v, uint32_t dst_offset,
- uint32_t offset, uint32_t size, const void *user_buffer,
- struct pipe_resource *buffer)
-{
- /* TODO inline this */
- assert(dst_offset + size <= v->constlen * 4);
- fd5_emit_const(ring, v->type, dst_offset,
- offset, size, user_buffer, buffer);
-}
-
static void
emit_const_ptrs(struct fd_ringbuffer *ring,
const struct ir3_shader_variant *v, uint32_t dst_offset,
#include "fd6_const.h"
#include "fd6_pack.h"
+#define emit_const_user fd6_emit_const_user
+#define emit_const_bo fd6_emit_const_bo
#include "ir3_const.h"
/* regid: base const register
* prsc or dwords: buffer containing constant values
* sizedwords: size of const value buffer
*/
-static void
-fd6_emit_const(struct fd_ringbuffer *ring, gl_shader_stage type,
- uint32_t regid, uint32_t offset, uint32_t sizedwords,
- const uint32_t *dwords, struct pipe_resource *prsc)
+void
+fd6_emit_const_user(struct fd_ringbuffer *ring,
+ const struct ir3_shader_variant *v, uint32_t regid,
+ uint32_t sizedwords, const uint32_t *dwords)
{
- if (prsc) {
- struct fd_bo *bo = fd_resource(prsc)->bo;
-
- if (fd6_geom_stage(type)) {
- OUT_PKT(ring, CP_LOAD_STATE6_GEOM,
- CP_LOAD_STATE6_0(
- .dst_off = regid/4,
- .state_type = ST6_CONSTANTS,
- .state_src = SS6_INDIRECT,
- .state_block = fd6_stage2shadersb(type),
- .num_unit = DIV_ROUND_UP(sizedwords, 4)
- ),
- CP_LOAD_STATE6_EXT_SRC_ADDR(
- .bo = bo,
- .bo_offset = offset
- )
- );
- } else {
- OUT_PKT(ring, CP_LOAD_STATE6_FRAG,
- CP_LOAD_STATE6_0(
- .dst_off = regid/4,
- .state_type = ST6_CONSTANTS,
- .state_src = SS6_INDIRECT,
- .state_block = fd6_stage2shadersb(type),
- .num_unit = DIV_ROUND_UP(sizedwords, 4)
- ),
- CP_LOAD_STATE6_EXT_SRC_ADDR(
- .bo = bo,
- .bo_offset = offset
- )
- );
- }
+ emit_const_asserts(ring, v, regid, sizedwords);
+
+ /* NOTE we cheat a bit here, since we know mesa is aligning
+ * the size of the user buffer to 16 bytes. And we want to
+ * cut cycles in a hot path.
+ */
+ uint32_t align_sz = align(sizedwords, 4);
+
+ if (fd6_geom_stage(v->type)) {
+ OUT_PKTBUF(ring, CP_LOAD_STATE6_GEOM, dwords, align_sz,
+ CP_LOAD_STATE6_0(
+ .dst_off = regid/4,
+ .state_type = ST6_CONSTANTS,
+ .state_src = SS6_DIRECT,
+ .state_block = fd6_stage2shadersb(v->type),
+ .num_unit = DIV_ROUND_UP(sizedwords, 4)
+ ),
+ CP_LOAD_STATE6_1(),
+ CP_LOAD_STATE6_2()
+ );
} else {
- /* NOTE we cheat a bit here, since we know mesa is aligning
- * the size of the user buffer to 16 bytes. And we want to
- * cut cycles in a hot path.
- */
- uint32_t align_sz = align(sizedwords, 4);
- dwords = (uint32_t *)&((uint8_t *)dwords)[offset];
-
- if (fd6_geom_stage(type)) {
- OUT_PKTBUF(ring, CP_LOAD_STATE6_GEOM, dwords, align_sz,
- CP_LOAD_STATE6_0(
- .dst_off = regid/4,
- .state_type = ST6_CONSTANTS,
- .state_src = SS6_DIRECT,
- .state_block = fd6_stage2shadersb(type),
- .num_unit = DIV_ROUND_UP(sizedwords, 4)
- ),
- CP_LOAD_STATE6_1(),
- CP_LOAD_STATE6_2()
- );
- } else {
- OUT_PKTBUF(ring, CP_LOAD_STATE6_FRAG, dwords, align_sz,
- CP_LOAD_STATE6_0(
- .dst_off = regid/4,
- .state_type = ST6_CONSTANTS,
- .state_src = SS6_DIRECT,
- .state_block = fd6_stage2shadersb(type),
- .num_unit = DIV_ROUND_UP(sizedwords, 4)
- ),
- CP_LOAD_STATE6_1(),
- CP_LOAD_STATE6_2()
- );
- }
+ OUT_PKTBUF(ring, CP_LOAD_STATE6_FRAG, dwords, align_sz,
+ CP_LOAD_STATE6_0(
+ .dst_off = regid/4,
+ .state_type = ST6_CONSTANTS,
+ .state_src = SS6_DIRECT,
+ .state_block = fd6_stage2shadersb(v->type),
+ .num_unit = DIV_ROUND_UP(sizedwords, 4)
+ ),
+ CP_LOAD_STATE6_1(),
+ CP_LOAD_STATE6_2()
+ );
+ }
+}
+void
+fd6_emit_const_bo(struct fd_ringbuffer *ring,
+ const struct ir3_shader_variant *v, uint32_t regid,
+ uint32_t offset, uint32_t sizedwords, struct fd_bo *bo)
+{
+ emit_const_asserts(ring, v, regid, sizedwords);
+
+ if (fd6_geom_stage(v->type)) {
+ OUT_PKT(ring, CP_LOAD_STATE6_GEOM,
+ CP_LOAD_STATE6_0(
+ .dst_off = regid/4,
+ .state_type = ST6_CONSTANTS,
+ .state_src = SS6_INDIRECT,
+ .state_block = fd6_stage2shadersb(v->type),
+ .num_unit = DIV_ROUND_UP(sizedwords, 4)
+ ),
+ CP_LOAD_STATE6_EXT_SRC_ADDR(
+ .bo = bo,
+ .bo_offset = offset
+ )
+ );
+ } else {
+ OUT_PKT(ring, CP_LOAD_STATE6_FRAG,
+ CP_LOAD_STATE6_0(
+ .dst_off = regid/4,
+ .state_type = ST6_CONSTANTS,
+ .state_src = SS6_INDIRECT,
+ .state_block = fd6_stage2shadersb(v->type),
+ .num_unit = DIV_ROUND_UP(sizedwords, 4)
+ ),
+ CP_LOAD_STATE6_EXT_SRC_ADDR(
+ .bo = bo,
+ .bo_offset = offset
+ )
+ );
}
}
return true;
}
-void
-emit_const(struct fd_ringbuffer *ring,
- const struct ir3_shader_variant *v, uint32_t dst_offset,
- uint32_t offset, uint32_t size, const void *user_buffer,
- struct pipe_resource *buffer)
-{
- /* TODO inline this */
- assert(dst_offset + size <= v->constlen * 4);
- fd6_emit_const(ring, v->type, dst_offset,
- offset, size, user_buffer, buffer);
-}
-
static void
emit_const_ptrs(struct fd_ringbuffer *ring,
const struct ir3_shader_variant *v, uint32_t dst_offset,
const unsigned regid = const_state->offsets.primitive_param;
int size = MIN2(1 + regid, v->constlen) - regid;
if (size > 0)
- fd6_emit_const(ring, v->type, regid * 4, 0, num_params, params, NULL);
+ fd6_emit_const_user(ring, v, regid * 4, num_params, params);
}
static void
static bool is_stateobj(struct fd_ringbuffer *ring);
-static void emit_const(struct fd_ringbuffer *ring,
- const struct ir3_shader_variant *v, uint32_t dst_offset,
+static void emit_const_user(struct fd_ringbuffer *ring,
+ const struct ir3_shader_variant *v, uint32_t regid,
+ uint32_t size, const uint32_t *user_buffer);
+
+static void emit_const_bo(struct fd_ringbuffer *ring,
+ const struct ir3_shader_variant *v, uint32_t regid,
+ uint32_t offset, uint32_t size,
+ struct fd_bo *bo);
+
+static void emit_const_prsc(struct fd_ringbuffer *ring,
+ const struct ir3_shader_variant *v, uint32_t regid,
uint32_t offset, uint32_t size,
- const void *user_buffer, struct pipe_resource *buffer);
+ struct pipe_resource *buffer)
+{
+ struct fd_resource *rsc = fd_resource(buffer);
+ emit_const_bo(ring, v, regid, offset, size, rsc->bo);
+}
static void emit_const_ptrs(struct fd_ringbuffer *ring,
const struct ir3_shader_variant *v, uint32_t dst_offset,
uint32_t num, struct pipe_resource **prscs, uint32_t *offsets);
+static void
+emit_const_asserts(struct fd_ringbuffer *ring,
+ const struct ir3_shader_variant *v,
+ uint32_t regid, uint32_t sizedwords)
+{
+ assert((regid % 4) == 0);
+ assert((sizedwords % 4) == 0);
+ assert(regid + sizedwords <= v->constlen * 4);
+}
static void
ring_wfi(struct fd_batch *batch, struct fd_ringbuffer *ring)
debug_assert((size % 16) == 0);
debug_assert((offset % 16) == 0);
- emit_const(ring, v, state->range[i].offset / 4,
- offset, size / 4, cb->user_buffer, cb->buffer);
+ if (cb->user_buffer) {
+ emit_const_user(ring, v, state->range[i].offset / 4,
+ size / 4, cb->user_buffer + state->range[i].start);
+ } else {
+ emit_const_prsc(ring, v, state->range[i].offset / 4,
+ offset, size / 4, cb->buffer);
+ }
}
}
sizes[off] = sb->sb[index].buffer_size;
}
- emit_const(ring, v, offset * 4, 0, ARRAY_SIZE(sizes), sizes, NULL);
+ emit_const_user(ring, v, offset * 4, ARRAY_SIZE(sizes), sizes);
}
}
}
uint32_t size = MIN2(ARRAY_SIZE(dims), v->constlen * 4 - offset * 4);
- emit_const(ring, v, offset * 4, 0, size, dims, NULL);
+ emit_const_user(ring, v, offset * 4, size, dims);
}
}
size *= 4;
if (size > 0)
- emit_const(ring, v, base, 0, size, const_state->immediates, NULL);
+ emit_const_user(ring, v, base, size, const_state->immediates);
}
static inline void
size *= 4;
if (size > 0)
- emit_const(ring, v, base, 0, size, patch_locs, NULL);
+ emit_const_user(ring, v, base, size, patch_locs);
}
/* emit stream-out buffers: */
ctx->screen->mem_to_mem(ring, vertex_params_rsc, 0,
indirect->buffer, src_off, 1);
- emit_const(ring, v, offset * 4, 0,
- vertex_params_size, NULL, vertex_params_rsc);
+ emit_const_prsc(ring, v, offset * 4, 0,
+ vertex_params_size, vertex_params_rsc);
pipe_resource_reference(&vertex_params_rsc, NULL);
} else {
- emit_const(ring, v, offset * 4, 0,
- vertex_params_size, vertex_params, NULL);
+ emit_const_user(ring, v, offset * 4,
+ vertex_params_size, vertex_params);
}
/* if needed, emit stream-out buffer addresses: */
indirect_offset = info->indirect_offset;
}
- emit_const(ring, v, offset * 4, indirect_offset, 4, NULL, indirect);
+ emit_const_prsc(ring, v, offset * 4, indirect_offset, 4, indirect);
pipe_resource_reference(&indirect, NULL);
} else {
uint32_t size = MIN2(const_state->num_driver_params,
v->constlen * 4 - offset * 4);
- emit_const(ring, v, offset * 4, 0, size, compute_params, NULL);
+ emit_const_user(ring, v, offset * 4, size, compute_params);
}
}
}