intel: emit 3DSTATE_CONSTANT_*
diff --git a/icd/intel/cmd_pipeline.c b/icd/intel/cmd_pipeline.c
index e5de71b..dcb6048 100644
--- a/icd/intel/cmd_pipeline.c
+++ b/icd/intel/cmd_pipeline.c
@@ -750,6 +750,117 @@
}
}
+static void gen6_pcb(struct intel_cmd *cmd, int subop,
+ const XGL_PIPELINE_SHADER *sh)
+{
+ const uint8_t cmd_len = 5;
+ const XGL_UINT alignment = 32;
+ const XGL_UINT max_size =
+ (subop == GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS) ? 1024 : 2048;
+ const XGL_UINT max_pcb = 4;
+ uint32_t pcb[4] = { 0, 0, 0, 0 };
+ XGL_FLAGS pcb_enables = 0;
+ XGL_SIZE total_size = 0;
+ uint32_t dw0;
+ XGL_UINT i;
+
+ for (i = 0; i < sh->linkConstBufferCount; i++) {
+ const XGL_LINK_CONST_BUFFER *info = &sh->pLinkConstBufferInfo[i];
+ const XGL_SIZE size = u_align(info->bufferSize, alignment);
+ void *ptr;
+
+ if (info->bufferId >= max_pcb ||
+ pcb_enables & ((1 << info->bufferId)) ||
+ total_size + info->bufferSize > max_size) {
+ cmd->result = XGL_ERROR_UNKNOWN;
+ return;
+ }
+ if (!size)
+ continue;
+
+ pcb_enables |= 1 << info->bufferId;
+ total_size += size;
+
+ ptr = cmd_state_reserve(cmd, size / sizeof(uint32_t),
+ alignment / sizeof(uint32_t), &pcb[info->bufferId]);
+ memcpy(ptr, info->pBufferData, info->bufferSize);
+ cmd_state_advance(cmd, size / sizeof(uint32_t));
+
+ pcb[info->bufferId] |= size / alignment - 1;
+ }
+
+ dw0 = GEN6_RENDER_TYPE_RENDER |
+ GEN6_RENDER_SUBTYPE_3D |
+ subop |
+ pcb_enables << 12 |
+ (cmd_len - 2);
+
+ cmd_batch_reserve(cmd, cmd_len);
+ cmd_batch_write(cmd, dw0);
+ cmd_batch_write(cmd, pcb[0]);
+ cmd_batch_write(cmd, pcb[1]);
+ cmd_batch_write(cmd, pcb[2]);
+ cmd_batch_write(cmd, pcb[3]);
+}
+
+static void gen7_pcb(struct intel_cmd *cmd, int subop,
+ const XGL_PIPELINE_SHADER *sh)
+{
+ const uint8_t cmd_len = 7;
+ const uint32_t dw0 = GEN6_RENDER_TYPE_RENDER |
+ GEN6_RENDER_SUBTYPE_3D |
+ subop |
+ (cmd_len - 2);
+ const XGL_UINT alignment = 32;
+ const XGL_UINT max_size = 2048;
+ const XGL_UINT max_pcb = 4;
+ uint16_t pcb_len[4] = { 0, 0, 0, 0 };
+ uint32_t pcb[4] = { 0, 0, 0, 0 };
+ XGL_FLAGS pcb_enables = 0;
+ XGL_SIZE total_size = 0;
+ XGL_UINT i;
+
+ for (i = 0; i < sh->linkConstBufferCount; i++) {
+ const XGL_LINK_CONST_BUFFER *info = &sh->pLinkConstBufferInfo[i];
+ const XGL_SIZE size = u_align(info->bufferSize, alignment);
+ void *ptr;
+
+ if (info->bufferId >= max_pcb ||
+ pcb_enables & ((1 << info->bufferId)) ||
+ total_size + info->bufferSize > max_size) {
+ cmd->result = XGL_ERROR_UNKNOWN;
+ return;
+ }
+ if (!size)
+ continue;
+
+ pcb_enables |= 1 << info->bufferId;
+ total_size += size;
+
+ pcb_len[info->bufferId] = size / alignment;
+
+ ptr = cmd_state_reserve(cmd, size / sizeof(uint32_t),
+ alignment / sizeof(uint32_t), &pcb[info->bufferId]);
+ memcpy(ptr, info->pBufferData, info->bufferSize);
+ cmd_state_advance(cmd, size / sizeof(uint32_t));
+ }
+
+ /* no holes */
+ if (!u_is_pow2(pcb_enables + 1)) {
+ cmd->result = XGL_ERROR_UNKNOWN;
+ return;
+ }
+
+ cmd_batch_reserve(cmd, cmd_len);
+ cmd_batch_write(cmd, dw0);
+ cmd_batch_write(cmd, pcb_len[1] << 16 | pcb_len[0]);
+ cmd_batch_write(cmd, pcb_len[3] << 16 | pcb_len[2]);
+ cmd_batch_write(cmd, pcb[0]);
+ cmd_batch_write(cmd, pcb[1]);
+ cmd_batch_write(cmd, pcb[2]);
+ cmd_batch_write(cmd, pcb[3]);
+}
+
static void emit_ps_resources(struct intel_cmd *cmd,
const struct intel_rmap *rmap)
{
@@ -825,9 +936,19 @@
if (cmd_gen(cmd) >= INTEL_GEN(7)) {
gen7_cc_states(cmd);
gen7_viewport_states(cmd);
+
+ gen7_pcb(cmd, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS,
+ &cmd->bind.pipeline.graphics->vs);
+ gen7_pcb(cmd, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_PS,
+ &cmd->bind.pipeline.graphics->fs);
} else {
gen6_cc_states(cmd);
gen6_viewport_states(cmd);
+
+ gen6_pcb(cmd, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS,
+ &cmd->bind.pipeline.graphics->vs);
+ gen6_pcb(cmd, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_PS,
+ &cmd->bind.pipeline.graphics->fs);
}
emit_ps_resources(cmd, cmd->bind.pipeline.graphics->fs_rmap);