---
src/amd/vulkan/radv_pipeline.c | 66 ++++++++++++++++++++++++++++++++++++++++++
src/amd/vulkan/radv_private.h | 19 ++++++++++++
2 files changed, 85 insertions(+)
diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c
index 82d9546cc3..ffd5aab7f9 100644
--- a/src/amd/vulkan/radv_pipeline.c
+++ b/src/amd/vulkan/radv_pipeline.c
@@ -2831,3 +2831,69 @@ VkResult radv_CreateComputePipelines(
return result;
}
+
+
+void radv_pm4_init(struct radv_pm4_builder *builder, struct radv_pm4_chunk
*chunk) {
+ builder->chunk = chunk;
+ builder->data_capacity = 0;
+
+ chunk->data = NULL;
+ chunk->data_word_count = 0;
+}
+
+void radv_pm4_finish(struct radv_pm4_builder *builder)
+{
+ /* Actually a nop for now */
+}
+
+void radv_pm4_start_reg_set_idx(struct radv_pm4_builder *builder, uint32_t
reg, uint32_t index, uint32_t count)
+{
+ if (reg >= SI_CONFIG_REG_OFFSET && reg < SI_CONFIG_REG_END) {
+ radv_pm4_emit(builder, PKT3(PKT3_SET_CONFIG_REG, count, 0));
+ radv_pm4_emit(builder, (reg - SI_CONFIG_REG_OFFSET) >> 2 | (index
<< 28));
+ } else if (reg >= SI_SH_REG_OFFSET && reg < SI_SH_REG_END) {
+ radv_pm4_emit(builder, PKT3(PKT3_SET_SH_REG, count, 0));
+ radv_pm4_emit(builder, (reg - SI_SH_REG_OFFSET) >> 2 | (index
<< 28));
+ } else if (reg >= SI_CONTEXT_REG_OFFSET && reg < SI_CONTEXT_REG_END) {
+ radv_pm4_emit(builder, PKT3(PKT3_SET_CONTEXT_REG, count, 0));
+ radv_pm4_emit(builder, (reg - SI_CONTEXT_REG_OFFSET) >> 2 | (index
<< 28));
+ } else if (reg >= CIK_UCONFIG_REG_OFFSET && reg < CIK_UCONFIG_REG_END) {
+ radv_pm4_emit(builder, PKT3(PKT3_SET_UCONFIG_REG, count, 0));
+ radv_pm4_emit(builder, (reg - CIK_UCONFIG_REG_OFFSET) >> 2 | (index
<< 28));
+ } else
+ unreachable("Unknown register space for register!");
+}
+
+void radv_pm4_start_reg_set(struct radv_pm4_builder *builder, uint32_t reg,
uint32_t count)
+{
+ radv_pm4_start_reg_set_idx(builder, reg, 0, count);
+}
+
+void radv_pm4_emit(struct radv_pm4_builder *builder, uint32_t value)
+{
+ if (builder->data_capacity <= builder->chunk->data_word_count) {
+ unsigned new_capacity = MAX2(64, builder->data_capacity * 2);
+ builder->chunk->data = realloc(builder->chunk->data,
new_capacity * 4);
+ builder->data_capacity = new_capacity;
+ }
+
+ builder->chunk->data[builder->chunk->data_word_count++] = value;
+}
+
+void radv_pm4_emit_array(struct radv_pm4_builder *builder, const uint32_t
*values, unsigned count)
+{
+ for (unsigned i = 0; i < count; ++i)
+ radv_pm4_emit(builder, values[i]);
+}
+
+void radv_pm4_set_reg(struct radv_pm4_builder *builder, uint32_t reg, uint32_t
value)
+{
+ radv_pm4_start_reg_set(builder, reg, 1);
+ radv_pm4_emit(builder, value);
+}
+
+void radv_pm4_set_reg_idx(struct radv_pm4_builder *builder, uint32_t reg,
uint32_t idx, uint32_t value)
+{
+ radv_pm4_start_reg_set_idx(builder, reg, idx, 1);
+ radv_pm4_emit(builder, value);
+}
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index 619c4bac35..07112c4332 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -1201,6 +1201,25 @@ struct radv_binning_state {
uint32_t db_dfsm_control;
};
+struct radv_pm4_chunk {
+ uint32_t *data;
+ unsigned data_word_count;
+};
+
+struct radv_pm4_builder {
+ struct radv_pm4_chunk *chunk;
+ unsigned data_capacity;
+};
+
+void radv_pm4_init(struct radv_pm4_builder *builder, struct radv_pm4_chunk
*chunk);
+void radv_pm4_finish(struct radv_pm4_builder *builder);
+void radv_pm4_start_reg_set(struct radv_pm4_builder *builder, uint32_t reg,
uint32_t count);
+void radv_pm4_start_reg_set_idx(struct radv_pm4_builder *builder, uint32_t
reg, uint32_t index, uint32_t count);
+void radv_pm4_emit(struct radv_pm4_builder *builder, uint32_t value);
+void radv_pm4_emit_array(struct radv_pm4_builder *builder, const uint32_t
*values, unsigned count);
+void radv_pm4_set_reg(struct radv_pm4_builder *builder, uint32_t reg, uint32_t
value);
+void radv_pm4_set_reg_idx(struct radv_pm4_builder *builder, uint32_t reg,
uint32_t idx, uint32_t value);
+
#define SI_GS_PER_ES 128
struct radv_pipeline {