diff --git a/src/imagination/csbgen/rogue_cr.xml b/src/imagination/csbgen/rogue_cr.xml
index a551f954617..9444a01e324 100644
--- a/src/imagination/csbgen/rogue_cr.xml
+++ b/src/imagination/csbgen/rogue_cr.xml
@@ -488,6 +488,29 @@ SOFTWARE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/imagination/csbgen/rogue_ipf.xml b/src/imagination/csbgen/rogue_ipf.xml
index 90d7d062ee6..a1abc09dff8 100644
--- a/src/imagination/csbgen/rogue_ipf.xml
+++ b/src/imagination/csbgen/rogue_ipf.xml
@@ -28,6 +28,10 @@ SOFTWARE.
+
+
@@ -61,6 +65,60 @@ SOFTWARE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -78,6 +136,23 @@ SOFTWARE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -92,6 +167,241 @@ SOFTWARE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -131,12 +441,34 @@ SOFTWARE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/imagination/vulkan/pvr_job_transfer.c b/src/imagination/vulkan/pvr_job_transfer.c
index 44a8cf9100d..30effb0568b 100644
--- a/src/imagination/vulkan/pvr_job_transfer.c
+++ b/src/imagination/vulkan/pvr_job_transfer.c
@@ -3052,61 +3052,83 @@ static void pvr_isp_prim_block_isp_state(const struct pvr_device_info *dev_info,
bool read_bgnd,
uint32_t **const cs_ptr_out)
{
+ const bool has_simple_internal_parameter_format_v2 =
+ PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format_v2);
uint32_t *cs_ptr = *cs_ptr_out;
- if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format_v2)) {
- pvr_finishme("Unimplemented path.");
- } else {
- /* ISP state words. */
+ if (has_simple_internal_parameter_format_v2) {
+ const uint32_t tsp_data_per_vrx_in_bytes =
+ tsp_data_size_in_bytes / num_isp_vertices;
- /* clang-format off */
- pvr_csb_pack (cs_ptr, TA_STATE_ISPCTL, ispctl);
- /* clang-format on */
- cs_ptr += pvr_cmd_length(TA_STATE_ISPCTL);
+ pvr_csb_pack ((uint64_t *)cs_ptr,
+ IPF_VERTEX_FORMAT_WORD_SIPF2,
+ vert_fmt) {
+ vert_fmt.vf_isp_state_size =
+ pvr_cmd_length(TA_STATE_ISPCTL) + pvr_cmd_length(TA_STATE_ISPA);
- pvr_csb_pack (cs_ptr, TA_STATE_ISPA, ispa) {
- ispa.objtype = PVRX(TA_OBJTYPE_TRIANGLE);
- ispa.passtype = read_bgnd ? PVRX(TA_PASSTYPE_TRANSLUCENT)
- : PVRX(TA_PASSTYPE_OPAQUE);
- ispa.dcmpmode = PVRX(TA_CMPMODE_ALWAYS);
- ispa.dwritedisable = true;
+ vert_fmt.vf_tsp_vtx_raw = true;
+ vert_fmt.vf_isp_vtx_raw = true;
+
+ vert_fmt.vf_varying_vertex_bits = tsp_data_per_vrx_in_bytes * 8U;
+ vert_fmt.vf_primitive_total = (num_isp_vertices / 2U) - 1U;
+ vert_fmt.vf_vertex_total = num_isp_vertices - 1U;
}
- cs_ptr += pvr_cmd_length(TA_STATE_ISPA);
-
- /* How many bytes the TSP compression format needs? */
- pvr_csb_pack (cs_ptr, IPF_COMPRESSION_SIZE_WORD, word) {
- word.cs_isp_comp_table_size = 0U;
- word.cs_tsp_comp_format_size = tsp_comp_format_in_dw;
- word.cs_tsp_comp_table_size = 0U;
- word.cs_tsp_comp_vertex_size =
- tsp_data_size_in_bytes / num_isp_vertices;
- }
- cs_ptr += pvr_cmd_length(IPF_COMPRESSION_SIZE_WORD);
-
- /* ISP vertex compression. */
- pvr_csb_pack (cs_ptr, IPF_ISP_COMPRESSION_WORD_0, word0) {
- word0.cf_isp_comp_fmt_x0 = PVRX(IPF_COMPRESSION_FORMAT_RAW_BYTE);
- word0.cf_isp_comp_fmt_x1 = PVRX(IPF_COMPRESSION_FORMAT_RAW_BYTE);
- word0.cf_isp_comp_fmt_x2 = PVRX(IPF_COMPRESSION_FORMAT_RAW_BYTE);
- word0.cf_isp_comp_fmt_y0 = PVRX(IPF_COMPRESSION_FORMAT_RAW_BYTE);
- word0.cf_isp_comp_fmt_y1 = PVRX(IPF_COMPRESSION_FORMAT_RAW_BYTE);
- word0.cf_isp_comp_fmt_y2 = PVRX(IPF_COMPRESSION_FORMAT_RAW_BYTE);
- word0.cf_isp_comp_fmt_z0 = PVRX(IPF_COMPRESSION_FORMAT_RAW_BYTE);
- word0.cf_isp_comp_fmt_z1 = PVRX(IPF_COMPRESSION_FORMAT_RAW_BYTE);
- }
- cs_ptr += pvr_cmd_length(IPF_ISP_COMPRESSION_WORD_0);
-
- pvr_csb_pack (cs_ptr, IPF_ISP_COMPRESSION_WORD_1, word1) {
- word1.vf_prim_msaa = 0U;
- word1.vf_prim_id_pres = 0U;
- word1.vf_vertex_clipped = 0U;
- word1.vf_vertex_total = num_isp_vertices - 1U;
- word1.cf_isp_comp_fmt_z3 = PVRX(IPF_COMPRESSION_FORMAT_RAW_BYTE);
- word1.cf_isp_comp_fmt_z2 = PVRX(IPF_COMPRESSION_FORMAT_RAW_BYTE);
- }
- cs_ptr += pvr_cmd_length(IPF_ISP_COMPRESSION_WORD_1);
+ cs_ptr += pvr_cmd_length(IPF_VERTEX_FORMAT_WORD_SIPF2);
}
+ /* ISP state words. */
+
+ /* clang-format off */
+ pvr_csb_pack (cs_ptr, TA_STATE_ISPCTL, ispctl);
+ /* clang-format on */
+ cs_ptr += pvr_cmd_length(TA_STATE_ISPCTL);
+
+ pvr_csb_pack (cs_ptr, TA_STATE_ISPA, ispa) {
+ ispa.objtype = PVRX(TA_OBJTYPE_TRIANGLE);
+ ispa.passtype = read_bgnd ? PVRX(TA_PASSTYPE_TRANSLUCENT)
+ : PVRX(TA_PASSTYPE_OPAQUE);
+ ispa.dcmpmode = PVRX(TA_CMPMODE_ALWAYS);
+ ispa.dwritedisable = true;
+ }
+ cs_ptr += pvr_cmd_length(TA_STATE_ISPA);
+
+ if (has_simple_internal_parameter_format_v2) {
+ *cs_ptr_out = cs_ptr;
+ return;
+ }
+
+ /* How many bytes the TSP compression format needs? */
+ pvr_csb_pack (cs_ptr, IPF_COMPRESSION_SIZE_WORD, word) {
+ word.cs_isp_comp_table_size = 0U;
+ word.cs_tsp_comp_format_size = tsp_comp_format_in_dw;
+ word.cs_tsp_comp_table_size = 0U;
+ word.cs_tsp_comp_vertex_size = tsp_data_size_in_bytes / num_isp_vertices;
+ }
+ cs_ptr += pvr_cmd_length(IPF_COMPRESSION_SIZE_WORD);
+
+ /* ISP vertex compression. */
+ pvr_csb_pack (cs_ptr, IPF_ISP_COMPRESSION_WORD_0, word0) {
+ word0.cf_isp_comp_fmt_x0 = PVRX(IPF_COMPRESSION_FORMAT_RAW_BYTE);
+ word0.cf_isp_comp_fmt_x1 = PVRX(IPF_COMPRESSION_FORMAT_RAW_BYTE);
+ word0.cf_isp_comp_fmt_x2 = PVRX(IPF_COMPRESSION_FORMAT_RAW_BYTE);
+ word0.cf_isp_comp_fmt_y0 = PVRX(IPF_COMPRESSION_FORMAT_RAW_BYTE);
+ word0.cf_isp_comp_fmt_y1 = PVRX(IPF_COMPRESSION_FORMAT_RAW_BYTE);
+ word0.cf_isp_comp_fmt_y2 = PVRX(IPF_COMPRESSION_FORMAT_RAW_BYTE);
+ word0.cf_isp_comp_fmt_z0 = PVRX(IPF_COMPRESSION_FORMAT_RAW_BYTE);
+ word0.cf_isp_comp_fmt_z1 = PVRX(IPF_COMPRESSION_FORMAT_RAW_BYTE);
+ }
+ cs_ptr += pvr_cmd_length(IPF_ISP_COMPRESSION_WORD_0);
+
+ pvr_csb_pack (cs_ptr, IPF_ISP_COMPRESSION_WORD_1, word1) {
+ word1.vf_prim_msaa = 0U;
+ word1.vf_prim_id_pres = 0U;
+ word1.vf_vertex_clipped = 0U;
+ word1.vf_vertex_total = num_isp_vertices - 1U;
+ word1.cf_isp_comp_fmt_z3 = PVRX(IPF_COMPRESSION_FORMAT_RAW_BYTE);
+ word1.cf_isp_comp_fmt_z2 = PVRX(IPF_COMPRESSION_FORMAT_RAW_BYTE);
+ }
+ cs_ptr += pvr_cmd_length(IPF_ISP_COMPRESSION_WORD_1);
+
*cs_ptr_out = cs_ptr;
}
@@ -3118,50 +3140,76 @@ pvr_isp_prim_block_index_block(const struct pvr_device_info *dev_info,
uint32_t *cs_ptr = *cs_ptr_out;
if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format)) {
- pvr_finishme("Unimplemented path.");
- } else {
- for (uint32_t i = 0U, j = 0U; i < num_mappings; i++, j += 4U) {
- if ((i & 1U) == 0U) {
- pvr_csb_pack (cs_ptr, IPF_INDEX_DATA, word) {
- word.ix_index0_0 = j;
- word.ix_index0_1 = j + 1U;
- word.ix_index0_2 = j + 2U;
- word.ix_index1_0 = j + 3U;
- }
- cs_ptr += pvr_cmd_length(IPF_INDEX_DATA);
+ for (uint32_t i = 0U; i < DIV_ROUND_UP(num_mappings, 2U); i++) {
+ const uint32_t idx = i * 8U;
- /* Don't increment cs_ptr here. IPF_INDEX_DATA is patched in the
- * else part and then cs_ptr is incremented.
- */
- pvr_csb_pack (cs_ptr, IPF_INDEX_DATA, word) {
- word.ix_index0_0 = j + 2U;
- word.ix_index0_1 = j + 1U;
- }
- } else {
- uint32_t tmp;
+ pvr_csb_pack ((uint64_t *)cs_ptr,
+ IPF_INDEX_DATA_WORDS_SIPF,
+ idx_data_word) {
+ idx_data_word.ix_triangle3_index_2 = idx + 5U;
+ idx_data_word.ix_triangle3_index_1 = idx + 6U;
+ idx_data_word.ix_triangle3_index_0 = idx + 7U;
- pvr_csb_pack (&tmp, IPF_INDEX_DATA, word) {
- word.ix_index0_2 = j;
- word.ix_index1_0 = j + 1U;
- }
- *cs_ptr |= tmp;
- cs_ptr += pvr_cmd_length(IPF_INDEX_DATA);
+ idx_data_word.ix_triangle2_index_2 = idx + 6U;
+ idx_data_word.ix_triangle2_index_1 = idx + 5U;
+ idx_data_word.ix_triangle2_index_0 = idx + 4U;
- pvr_csb_pack (cs_ptr, IPF_INDEX_DATA, word) {
- word.ix_index0_0 = j + 2U;
- word.ix_index0_1 = j + 3U;
- word.ix_index0_2 = j + 2U;
- word.ix_index1_0 = j + 1U;
- }
- cs_ptr += pvr_cmd_length(IPF_INDEX_DATA);
+ idx_data_word.ix_triangle1_index_2 = idx + 1U;
+ idx_data_word.ix_triangle1_index_1 = idx + 2U;
+ idx_data_word.ix_triangle1_index_0 = idx + 3U;
+
+ idx_data_word.ix_triangle0_index_2 = idx + 2U;
+ idx_data_word.ix_triangle0_index_1 = idx + 1U;
+ idx_data_word.ix_triangle0_index_0 = idx + 0U;
}
+ cs_ptr += pvr_cmd_length(IPF_INDEX_DATA_WORDS_SIPF);
}
- /* The last pass didn't ++. */
- if ((num_mappings & 1U) != 0U)
- cs_ptr++;
+ *cs_ptr_out = cs_ptr;
+ return;
}
+ for (uint32_t i = 0U, j = 0U; i < num_mappings; i++, j += 4U) {
+ if ((i & 1U) == 0U) {
+ pvr_csb_pack (cs_ptr, IPF_INDEX_DATA, word) {
+ word.ix_index0_0 = j;
+ word.ix_index0_1 = j + 1U;
+ word.ix_index0_2 = j + 2U;
+ word.ix_index1_0 = j + 3U;
+ }
+ cs_ptr += pvr_cmd_length(IPF_INDEX_DATA);
+
+ /* Don't increment cs_ptr here. IPF_INDEX_DATA is patched in the
+ * else part and then cs_ptr is incremented.
+ */
+ pvr_csb_pack (cs_ptr, IPF_INDEX_DATA, word) {
+ word.ix_index0_0 = j + 2U;
+ word.ix_index0_1 = j + 1U;
+ }
+ } else {
+ uint32_t tmp;
+
+ pvr_csb_pack (&tmp, IPF_INDEX_DATA, word) {
+ word.ix_index0_2 = j;
+ word.ix_index1_0 = j + 1U;
+ }
+ *cs_ptr |= tmp;
+ cs_ptr += pvr_cmd_length(IPF_INDEX_DATA);
+
+ pvr_csb_pack (cs_ptr, IPF_INDEX_DATA, word) {
+ word.ix_index0_0 = j + 2U;
+ word.ix_index0_1 = j + 3U;
+ word.ix_index0_2 = j + 2U;
+ word.ix_index1_0 = j + 1U;
+ }
+ cs_ptr += pvr_cmd_length(IPF_INDEX_DATA);
+ }
+ }
+
+ /* The last pass didn't ++. */
+ if ((num_mappings & 1U) != 0U)
+ cs_ptr++;
+
*cs_ptr_out = cs_ptr;
}
@@ -3170,11 +3218,42 @@ pvr_isp_prim_block_index_block(const struct pvr_device_info *dev_info,
static inline VkResult
pvr_int32_to_isp_xy_vtx(const struct pvr_device_info *dev_info,
int32_t val,
- UNUSED bool bias,
+ bool bias,
uint32_t *word_out)
{
if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format)) {
- pvr_finishme("Unimplemented path.");
+ const uint32_t max_fractional = PVRX(IPF_ISP_VERTEX_XY_SIPF_FRAC_MAX_VAL);
+ const uint32_t max_integer = PVRX(IPF_ISP_VERTEX_XY_SIPF_INTEGER_MAX_VAL);
+
+ uint32_t fractional;
+ uint32_t integer;
+
+ if (bias)
+ val += PVRX(IPF_ISP_VERTEX_XY_BIAS_VALUE_SIPF);
+
+ if (val < 0 || val > max_integer + 1) {
+ mesa_loge("ISP vertex xy value out of range.");
+ return vk_error(NULL, VK_ERROR_UNKNOWN);
+ }
+
+ if (val <= max_integer) {
+ integer = val;
+ fractional = 0;
+ } else if (val == max_integer + 1) {
+ /* The integer field is 13 bits long so the max value is
+ * 2 ^ 13 - 1 = 8191. For 8k support we need to handle 8192 so we set
+ * all fractional bits to get as close as possible. The best we can do
+ * is: 0x1FFF.F = 8191.9375 ≈ 8192 .
+ */
+ integer = max_integer;
+ fractional = max_fractional;
+ }
+
+ pvr_csb_pack (word_out, IPF_ISP_VERTEX_XY_SIPF, word) {
+ word.integer = integer;
+ word.frac = fractional;
+ }
+
return VK_SUCCESS;
}
@@ -3245,66 +3324,90 @@ pvr_isp_prim_block_isp_vertices(const struct pvr_device_info *dev_info,
return result;
if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format)) {
- pvr_finishme("Unimplemented path.");
- } else {
- /* ISP vertices 0 and 1. */
- pvr_csb_pack (cs_ptr, IPF_ISP_VERTEX_WORD_0, word0) {
- word0.x0 = left;
- word0.y0 = top & 0xFF;
+ pvr_csb_pack ((uint64_t *)cs_ptr, IPF_ISP_VERTEX_WORD_SIPF, word) {
+ word.y = top;
+ word.x = left;
}
- cs_ptr++;
+ cs_ptr += pvr_cmd_length(IPF_ISP_VERTEX_WORD_SIPF);
- pvr_csb_pack (cs_ptr, IPF_ISP_VERTEX_WORD_1, word1) {
- word1.y0 = top >> PVRX(IPF_ISP_VERTEX_WORD_1_Y0_SHIFT);
+ pvr_csb_pack ((uint64_t *)cs_ptr, IPF_ISP_VERTEX_WORD_SIPF, word) {
+ word.y = top;
+ word.x = right;
}
- cs_ptr++;
+ cs_ptr += pvr_cmd_length(IPF_ISP_VERTEX_WORD_SIPF);
- pvr_csb_pack (cs_ptr, IPF_ISP_VERTEX_WORD_2, word2) {
- word2.x1 = right & 0xFFFF;
- word2.z0 = 0U;
+ pvr_csb_pack ((uint64_t *)cs_ptr, IPF_ISP_VERTEX_WORD_SIPF, word) {
+ word.y = bottom;
+ word.x = left;
}
- cs_ptr++;
+ cs_ptr += pvr_cmd_length(IPF_ISP_VERTEX_WORD_SIPF);
- pvr_csb_pack (cs_ptr, IPF_ISP_VERTEX_WORD_3, word3) {
- word3.x1 = right >> PVRX(IPF_ISP_VERTEX_WORD_3_X1_SHIFT);
- word3.y1 = top;
+ pvr_csb_pack ((uint64_t *)cs_ptr, IPF_ISP_VERTEX_WORD_SIPF, word) {
+ word.y = bottom;
+ word.x = right;
}
- cs_ptr++;
+ cs_ptr += pvr_cmd_length(IPF_ISP_VERTEX_WORD_SIPF);
- pvr_csb_pack (cs_ptr, IPF_ISP_VERTEX_WORD_4, word4) {
- word4.z1 = 0U;
- }
- cs_ptr++;
-
- /* ISP vertices 2 and 3. */
- pvr_csb_pack (cs_ptr, IPF_ISP_VERTEX_WORD_0, word0) {
- word0.x0 = left;
- word0.y0 = bottom & 0xFF;
- }
- cs_ptr++;
-
- pvr_csb_pack (cs_ptr, IPF_ISP_VERTEX_WORD_1, word1) {
- word1.y0 = bottom >> PVRX(IPF_ISP_VERTEX_WORD_1_Y0_SHIFT);
- }
- cs_ptr++;
-
- pvr_csb_pack (cs_ptr, IPF_ISP_VERTEX_WORD_2, word2) {
- word2.x1 = right & 0xFFFF;
- word2.z0 = 0U;
- }
- cs_ptr++;
-
- pvr_csb_pack (cs_ptr, IPF_ISP_VERTEX_WORD_3, word3) {
- word3.x1 = right >> PVRX(IPF_ISP_VERTEX_WORD_3_X1_SHIFT);
- word3.y1 = bottom;
- }
- cs_ptr++;
-
- pvr_csb_pack (cs_ptr, IPF_ISP_VERTEX_WORD_4, word4) {
- word4.z1 = 0U;
- }
- cs_ptr++;
+ continue;
}
+
+ /* ISP vertices 0 and 1. */
+ pvr_csb_pack (cs_ptr, IPF_ISP_VERTEX_WORD_0, word0) {
+ word0.x0 = left;
+ word0.y0 = top & 0xFF;
+ }
+ cs_ptr++;
+
+ pvr_csb_pack (cs_ptr, IPF_ISP_VERTEX_WORD_1, word1) {
+ word1.y0 = top >> PVRX(IPF_ISP_VERTEX_WORD_1_Y0_SHIFT);
+ }
+ cs_ptr++;
+
+ pvr_csb_pack (cs_ptr, IPF_ISP_VERTEX_WORD_2, word2) {
+ word2.x1 = right & 0xFFFF;
+ word2.z0 = 0U;
+ }
+ cs_ptr++;
+
+ pvr_csb_pack (cs_ptr, IPF_ISP_VERTEX_WORD_3, word3) {
+ word3.x1 = right >> PVRX(IPF_ISP_VERTEX_WORD_3_X1_SHIFT);
+ word3.y1 = top;
+ }
+ cs_ptr++;
+
+ pvr_csb_pack (cs_ptr, IPF_ISP_VERTEX_WORD_4, word4) {
+ word4.z1 = 0U;
+ }
+ cs_ptr++;
+
+ /* ISP vertices 2 and 3. */
+ pvr_csb_pack (cs_ptr, IPF_ISP_VERTEX_WORD_0, word0) {
+ word0.x0 = left;
+ word0.y0 = bottom & 0xFF;
+ }
+ cs_ptr++;
+
+ pvr_csb_pack (cs_ptr, IPF_ISP_VERTEX_WORD_1, word1) {
+ word1.y0 = bottom >> PVRX(IPF_ISP_VERTEX_WORD_1_Y0_SHIFT);
+ }
+ cs_ptr++;
+
+ pvr_csb_pack (cs_ptr, IPF_ISP_VERTEX_WORD_2, word2) {
+ word2.x1 = right & 0xFFFF;
+ word2.z0 = 0U;
+ }
+ cs_ptr++;
+
+ pvr_csb_pack (cs_ptr, IPF_ISP_VERTEX_WORD_3, word3) {
+ word3.x1 = right >> PVRX(IPF_ISP_VERTEX_WORD_3_X1_SHIFT);
+ word3.y1 = bottom;
+ }
+ cs_ptr++;
+
+ pvr_csb_pack (cs_ptr, IPF_ISP_VERTEX_WORD_4, word4) {
+ word4.z1 = 0U;
+ }
+ cs_ptr++;
}
*cs_ptr_out = cs_ptr;
@@ -3422,7 +3525,49 @@ pvr_isp_primitive_block(const struct pvr_device_info *dev_info,
cs_ptr_start = *cs_ptr_out;
if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format)) {
- pvr_finishme("Unimplemented path.");
+ /* This includes:
+ * Vertex formats.
+ * ISP state words.
+ */
+ pvr_isp_prim_block_isp_state(dev_info,
+ tsp_comp_format_in_dw,
+ tsp_data_size_in_bytes,
+ num_isp_vertices,
+ read_bgnd,
+ cs_ptr_out);
+
+ /* This include:
+ * Index data / point pitch.
+ */
+ pvr_isp_prim_block_index_block(dev_info, num_mappings, cs_ptr_out);
+
+ result = pvr_isp_prim_block_isp_vertices(dev_info,
+ state,
+ mappings,
+ num_mappings,
+ mapping_offset,
+ cs_ptr_out);
+ if (result != VK_SUCCESS)
+ return result;
+
+ pvr_isp_prim_block_pds_state(dev_info, ctx, state, cs_ptr_out);
+
+ if (!color_fill) {
+ /* This includes:
+ * TSP vertex formats.
+ */
+ pvr_isp_prim_block_tsp_vertex_block(dev_info,
+ src,
+ mappings,
+ custom_filter,
+ num_mappings,
+ mapping_offset,
+ transfer_cmd->filter,
+ tsp_comp_format_in_dw,
+ cs_ptr_out);
+ }
+
+ *cs_start_offset = 0;
} else {
if (!color_fill) {
/* This includes:
@@ -3494,6 +3639,26 @@ pvr_transfer_max_quads_per_pb(const struct pvr_device_info *dev_info)
: 16U;
}
+static inline uint8_t *pvr_isp_ctrl_stream_sipf_write_aligned(uint8_t *stream,
+ uint32_t data,
+ uint32_t size)
+{
+ const uint32_t offset = (uintptr_t)stream & 0x3U;
+ uint32_t *aligned_stream = (uint32_t *)(stream - offset);
+ const uint32_t current_data = *aligned_stream & ((1U << (offset * 8U)) - 1U);
+
+ assert(size > 0 && size <= 4U);
+
+ *aligned_stream = current_data | data << (offset * 8U);
+
+ if (offset + size > 4U) {
+ aligned_stream++;
+ *aligned_stream = data >> ((4U - offset) * 8);
+ }
+
+ return stream + size;
+}
+
/**
* Writes ISP ctrl stream.
*
@@ -3835,7 +4000,64 @@ static VkResult pvr_isp_ctrl_stream(const struct pvr_device_info *dev_info,
prim_blk_addr.addr += stream_start_offset;
if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format_v2)) {
- pvr_finishme("Unimplemented path.");
+ uint8_t *cs_byte_ptr = (uint8_t *)cs_ptr;
+ uint32_t tmp;
+
+ /* This part of the control stream is byte granular. */
+
+ pvr_csb_pack (&tmp, IPF_PRIMITIVE_HEADER_SIPF2, prim_header) {
+ prim_header.cs_prim_base_size = 1;
+ prim_header.cs_mask_num_bytes = 1;
+ prim_header.cs_valid_tile0 = true;
+ }
+ cs_byte_ptr =
+ pvr_isp_ctrl_stream_sipf_write_aligned(cs_byte_ptr, tmp, 1);
+
+ pvr_csb_pack (&tmp, IPF_PRIMITIVE_BASE_SIPF2, word) {
+ word.cs_prim_base = prim_blk_addr;
+ }
+ cs_byte_ptr =
+ pvr_isp_ctrl_stream_sipf_write_aligned(cs_byte_ptr, tmp, 4);
+
+ /* IPF_BYTE_BASED_MASK_ONE_BYTE_WORD_0_SIPF2 since
+ * IPF_PRIMITIVE_HEADER_SIPF2.cs_mask_num_bytes == 1.
+ */
+ pvr_csb_pack (&tmp,
+ IPF_BYTE_BASED_MASK_ONE_BYTE_WORD_0_SIPF2,
+ mask) {
+ switch (num_mappings) {
+ case 4:
+ mask.cs_mask_one_byte_tile0_7 = true;
+ mask.cs_mask_one_byte_tile0_6 = true;
+ FALLTHROUGH;
+ case 3:
+ mask.cs_mask_one_byte_tile0_5 = true;
+ mask.cs_mask_one_byte_tile0_4 = true;
+ FALLTHROUGH;
+ case 2:
+ mask.cs_mask_one_byte_tile0_3 = true;
+ mask.cs_mask_one_byte_tile0_2 = true;
+ FALLTHROUGH;
+ case 1:
+ mask.cs_mask_one_byte_tile0_1 = true;
+ mask.cs_mask_one_byte_tile0_0 = true;
+ break;
+ default:
+ /* Unreachable since we clamped the value earlier so reaching
+ * this is an implementation error.
+ */
+ unreachable("num_mapping exceeded max_mappings_per_pb");
+ break;
+ }
+ }
+ /* Only 1 byte since there's only 1 valid tile within the single
+ * IPF_BYTE_BASED_MASK_ONE_BYTE_WORD_0_SIPF2 mask.
+ * ROGUE_IPF_PRIMITIVE_HEADER_SIPF2.cs_valid_tile0 == true.
+ */
+ cs_byte_ptr =
+ pvr_isp_ctrl_stream_sipf_write_aligned(cs_byte_ptr, tmp, 1);
+
+ cs_ptr = (uint32_t *)cs_byte_ptr;
} else {
pvr_csb_pack (cs_ptr, IPF_PRIMITIVE_FORMAT, word) {
word.cs_type = PVRX(IPF_CS_TYPE_PRIM);
@@ -3861,10 +4083,23 @@ static VkResult pvr_isp_ctrl_stream(const struct pvr_device_info *dev_info,
if (PVR_HAS_FEATURE(dev_info, ipf_creq_pf))
pvr_finishme("Unimplemented path.");
- pvr_csb_pack (cs_ptr, IPF_CONTROL_STREAM, word) {
- word.cs_type = PVRX(IPF_CS_TYPE_TERM);
+ if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format_v2)) {
+ uint8_t *cs_byte_ptr = (uint8_t *)cs_ptr;
+ uint32_t tmp;
+
+ /* clang-format off */
+ pvr_csb_pack (&tmp, IPF_CONTROL_STREAM_TERMINATE_SIPF2, term);
+ /* clang-format on */
+
+ cs_byte_ptr = pvr_isp_ctrl_stream_sipf_write_aligned(cs_byte_ptr, tmp, 1);
+
+ cs_ptr = (uint32_t *)cs_byte_ptr;
+ } else {
+ pvr_csb_pack (cs_ptr, IPF_CONTROL_STREAM, word) {
+ word.cs_type = PVRX(IPF_CS_TYPE_TERM);
+ }
+ cs_ptr += pvr_cmd_length(IPF_CONTROL_STREAM);
}
- cs_ptr += pvr_cmd_length(IPF_CONTROL_STREAM);
pvr_csb_pack (®s->isp_mtile_base, CR_ISP_MTILE_BASE, reg) {
reg.addr =
@@ -3876,10 +4111,20 @@ static VkResult pvr_isp_ctrl_stream(const struct pvr_device_info *dev_info,
reg.mode_type = PVRX(CR_ISP_RENDER_MODE_TYPE_FAST_2D);
}
- if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format_v2))
- pvr_finishme("Unimplemented path.");
- else
- regs->isp_rgn = 0UL;
+ if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format_v2) &&
+ PVR_HAS_FEATURE(dev_info, ipf_creq_pf)) {
+ pvr_csb_pack (®s->isp_rgn, CR_ISP_RGN_SIPF, isp_rgn) {
+ /* Bit 0 in CR_ISP_RGN.cs_size_ipf_creq_pf is used to indicate the
+ * presence of a link.
+ */
+ pvr_finishme("Unimplemented isp link. Defaulting to no link.");
+ isp_rgn.cs_size_ipf_creq_pf = 0;
+ }
+ } else {
+ /* clang-format off */
+ pvr_csb_pack(®s->isp_rgn, CR_ISP_RGN, isp_rgn);
+ /* clang-format on */
+ }
return VK_SUCCESS;
}