pvr: Implement simple internal format v2 transfer paths.
authorKarmjit Mahil <Karmjit.Mahil@imgtec.com>
Mon, 15 Aug 2022 08:11:21 +0000 (09:11 +0100)
committerMarge Bot <emma+marge@anholt.net>
Wed, 19 Apr 2023 11:01:06 +0000 (11:01 +0000)
This commit fixes the triangle demo on the AM62 by implementing
the paths that were left unimplemented due to the Chromebook not
having the simple internal format v2 feature.

Signed-off-by: Karmjit Mahil <Karmjit.Mahil@imgtec.com>
Acked-by: Frank Binns <frank.binns@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21550>

src/imagination/csbgen/rogue_cr.xml
src/imagination/csbgen/rogue_ipf.xml
src/imagination/vulkan/pvr_job_transfer.c

index a551f95..9444a01 100644 (file)
@@ -488,6 +488,29 @@ SOFTWARE.
     <field name="y" start="0" end="9" type="uint"/>
   </struct>
 
+  <struct name="ISP_RGN" length="1">
+    <field name="size" start="0" end="23" type="uint">
+      <define name="UNIT_SIZE" value="4"/>
+    </field>
+  </struct>
+
+  <!-- FIXME: This is the SIMPLE_INTERNAL_PARAMETER_FORMAT variant.
+       Should we use the "condition" tag for this?
+  -->
+  <struct name="ISP_RGN_SIPF" length="1">
+    <condition type="if" check="IPF_CREQ_PF"/>
+    <!-- FIXME: This should have a default value of 0x1F not setting it since
+        csbgen doesn't check if the feature is present or not so this will
+        be set even when the feature is not present.
+    -->
+    <field name="cs_size_ipf_creq_pf" start="24" end="28" type="uint"/>
+    <condition type="endif" check="IPF_CREQ_PF"/>
+    <field name="size" start="0" end="23" type="uint">
+      <!-- Note that this differs from ISP_RGN. -->
+      <define name="UNIT_SIZE" value="1"/>
+    </field>
+  </struct>
+
   <struct name="ISP_BGOBJDEPTH" length="1">
     <field name="value" start="0" end="31" type="uint"/>
   </struct>
index 90d7d06..a1abc09 100644 (file)
@@ -28,6 +28,10 @@ SOFTWARE.
   <define name="TILE_SIZE_PIXELS" value="32"/>
   <define name="CONTROL_STREAM_SIZE_DWORDS" value="32"/>
   <define name="ISP_VERTEX_XY_BIAS_VALUE"   value="4096"/>
+  <!-- FIXME: This is the SIMPLE_INTERNAL_PARAMETER_FORMAT variant.
+       Should we use the "condition" tag for this?
+  -->
+  <define name="ISP_VERTEX_XY_BIAS_VALUE_SIPF" value="2048"/>
 
   <enum name="COMPRESSION_FORMAT">
     <value name="UNIQUE_1" value="0"/>
@@ -61,6 +65,60 @@ SOFTWARE.
     <value name="TERM" value="3"/>
   </enum>
 
+  <!-- FIXME: This is only available with SIMPLE_INTERNAL_PARAMETER_FORMAT_V2. -->
+  <enum name="CS_CTRL_TYPE_SIPF2">
+    <value name="PRIM" value="0"/>
+    <value name="LINK" value="1"/>
+    <value name="TERM" value="3"/>
+  </enum>
+
+  <!-- FIXME: This is only available with SIMPLE_INTERNAL_PARAMETER_FORMAT. -->
+  <struct name="INDEX_DATA_WORDS_SIPF" length="2">
+    <field name="ix_triangle3_bf_flag" start="63" end="63" type="bool"/>
+    <field name="ix_triangle3_edge_flag_ca" start="62" end="62" type="bool"/>
+    <field name="ix_triangle3_index_2" start="58" end="61" type="uint"/>
+    <field name="ix_triangle3_edge_flag_bc" start="57" end="57" type="bool"/>
+    <field name="ix_triangle3_index_1" start="53" end="56" type="uint"/>
+    <field name="ix_triangle3_edge_flag_ab" start="52" end="52" type="bool"/>
+    <field name="ix_triangle3_index_0" start="48" end="51" type="uint"/>
+    <field name="ix_triangle2_bf_flag" start="47" end="47" type="bool"/>
+    <field name="ix_triangle2_edge_flag_ca" start="46" end="46" type="bool"/>
+    <field name="ix_triangle2_index_2" start="42" end="45" type="uint"/>
+    <field name="ix_triangle2_edge_flag_bc" start="41" end="41" type="bool"/>
+    <field name="ix_triangle2_index_1" start="37" end="40" type="uint"/>
+    <field name="ix_triangle2_edge_flag_ab" start="36" end="36" type="bool"/>
+    <field name="ix_triangle2_index_0" start="32" end="35" type="uint"/>
+    <field name="ix_triangle1_bf_flag" start="31" end="31" type="bool"/>
+    <field name="ix_triangle1_edge_flag_ca" start="30" end="30" type="bool"/>
+    <field name="ix_triangle1_index_2" start="26" end="29" type="uint"/>
+    <field name="ix_triangle1_edge_flag_bc" start="25" end="25" type="bool"/>
+    <field name="ix_triangle1_index_1" start="21" end="24" type="uint"/>
+    <field name="ix_triangle1_edge_flag_ab" start="20" end="20" type="bool"/>
+    <field name="ix_triangle1_index_0" start="16" end="19" type="uint"/>
+    <field name="ix_triangle0_bf_flag" start="15" end="15" type="bool"/>
+    <field name="ix_triangle0_edge_flag_ca" start="14" end="14" type="bool"/>
+    <field name="ix_triangle0_index_2" start="10" end="13" type="uint"/>
+    <field name="ix_triangle0_edge_flag_bc" start="9" end="9" type="bool"/>
+    <field name="ix_triangle0_index_1" start="5" end="8" type="uint"/>
+    <field name="ix_triangle0_edge_flag_ab" start="4" end="4" type="bool"/>
+    <field name="ix_triangle0_index_0" start="0" end="3" type="uint"/>
+  </struct>
+
+  <!-- FIXME: This is only available with SIMPLE_INTERNAL_PARAMETER_FORMAT_V2. -->
+  <struct name="VERTEX_FORMAT_WORD_SIPF2" length="2">
+    <field name="vf_isp_format_word" start="42" end="63" type="uint"/>
+    <field name="vf_isp_state_size" start="39" end="41" type="uint"/>
+    <field name="vf_tsp_vtx_raw" start="38" end="38" type="bool"/>
+    <field name="vf_isp_vtx_raw" start="37" end="37" type="bool"/>
+    <field name="vf_varying_total_16" start="30" end="36" type="uint"/>
+    <field name="vf_varying_total_32" start="23" end="29" type="uint"/>
+    <field name="vf_varying_vertex_bits" start="11" end="22" type="uint"/>
+    <field name="vf_primitive_total" start="6" end="10" type="uint"/>
+    <field name="vf_vertex_total" start="2" end="5" type="uint"/>
+    <field name="vf_prim_msaa_disable" start="1" end="1" type="bool"/>
+    <field name="vf_vertex_clipped" start="0" end="0" type="bool"/>
+  </struct>
+
   <struct name="SCISSOR_WORD_0" length="1">
     <field name="scw0_xmin" start="16" end="31" type="uint"/>
     <field name="scw0_xmax" start="0" end="15" type="uint"/>
@@ -78,6 +136,23 @@ SOFTWARE.
     </field>
   </struct>
 
+  <!-- FIXME: This is only available with SIMPLE_INTERNAL_PARAMETER_FORMAT_V2. -->
+  <struct name="CONTROL_STREAM_TERMINATE_SIPF2" length="1">
+    <field name="rsvd" start="2" end="7" type="uint"/>
+    <field name="cs_ctrl_type" start="0" end="1" type="CS_CTRL_TYPE_SIPF2" default="TERM"/>
+  </struct>
+
+  <!-- FIXME: This is only available with SIMPLE_INTERNAL_PARAMETER_FORMAT_V2. -->
+  <struct name="PRIMITIVE_HEADER_SIPF2" length="1">
+    <field name="cs_valid_tile3" start="7" end="7" type="bool"/>
+    <field name="cs_valid_tile2" start="6" end="6" type="bool"/>
+    <field name="cs_valid_tile1" start="5" end="5" type="bool"/>
+    <field name="cs_valid_tile0" start="4" end="4" type="bool"/>
+    <field name="cs_mask_num_bytes" start="2" end="3" type="uint"/>
+    <field name="cs_prim_base_size" start="1" end="1" type="bool"/>
+    <field name="cs_ctrl_type" start="0" end="0" type="CS_CTRL_TYPE_SIPF2" default="PRIM"/>
+  </struct>
+
   <struct name="PRIMITIVE_FORMAT" length="1">
     <field name="cs_type" start="30" end="31" type="CS_TYPE"/>
     <field name="cs_isp_state_read" start="29" end="29" type="bool"/>
@@ -92,6 +167,241 @@ SOFTWARE.
     <field name="cs_prim_base" start="0" end="31" shift="2" type="address"/>
   </struct>
 
+  <!-- FIXME: This is the SIMPLE_INTERNAL_PARAMETER_FORMAT_V2 variant.
+       Should we use the "condition" tag for this?
+  -->
+  <struct name="PRIMITIVE_BASE_SIPF2" length="1">
+    <field name="cs_prim_base" start="0" end="31" shift="3" type="address"/>
+  </struct>
+
+  <!-- Labeling of fields within Byte Based Mask One-Byte Word 0.
+       See ROGUE_IPF_PRIMITIVE_HEADER_SIPF2.cs_mask_num_bytes.
+  -->
+  <struct name="BYTE_BASED_MASK_ONE_BYTE_WORD_0_SIPF2" length="1">
+    <field name="cs_mask_one_byte_tile3_7" start="31" end="31" type="bool"/>
+    <field name="cs_mask_one_byte_tile3_6" start="30" end="30" type="bool"/>
+    <field name="cs_mask_one_byte_tile3_5" start="29" end="29" type="bool"/>
+    <field name="cs_mask_one_byte_tile3_4" start="28" end="28" type="bool"/>
+    <field name="cs_mask_one_byte_tile3_3" start="27" end="27" type="bool"/>
+    <field name="cs_mask_one_byte_tile3_2" start="26" end="26" type="bool"/>
+    <field name="cs_mask_one_byte_tile3_1" start="25" end="25" type="bool"/>
+    <field name="cs_mask_one_byte_tile3_0" start="24" end="24" type="bool"/>
+    <field name="cs_mask_one_byte_tile2_7" start="23" end="23" type="bool"/>
+    <field name="cs_mask_one_byte_tile2_6" start="22" end="22" type="bool"/>
+    <field name="cs_mask_one_byte_tile2_5" start="21" end="21" type="bool"/>
+    <field name="cs_mask_one_byte_tile2_4" start="20" end="20" type="bool"/>
+    <field name="cs_mask_one_byte_tile2_3" start="19" end="19" type="bool"/>
+    <field name="cs_mask_one_byte_tile2_2" start="18" end="18" type="bool"/>
+    <field name="cs_mask_one_byte_tile2_1" start="17" end="17" type="bool"/>
+    <field name="cs_mask_one_byte_tile2_0" start="16" end="16" type="bool"/>
+    <field name="cs_mask_one_byte_tile1_7" start="15" end="15" type="bool"/>
+    <field name="cs_mask_one_byte_tile1_6" start="14" end="14" type="bool"/>
+    <field name="cs_mask_one_byte_tile1_5" start="13" end="13" type="bool"/>
+    <field name="cs_mask_one_byte_tile1_4" start="12" end="12" type="bool"/>
+    <field name="cs_mask_one_byte_tile1_3" start="11" end="11" type="bool"/>
+    <field name="cs_mask_one_byte_tile1_2" start="10" end="10" type="bool"/>
+    <field name="cs_mask_one_byte_tile1_1" start="9" end="9" type="bool"/>
+    <field name="cs_mask_one_byte_tile1_0" start="8" end="8" type="bool"/>
+    <field name="cs_mask_one_byte_tile0_7" start="7" end="7" type="bool"/>
+    <field name="cs_mask_one_byte_tile0_6" start="6" end="6" type="bool"/>
+    <field name="cs_mask_one_byte_tile0_5" start="5" end="5" type="bool"/>
+    <field name="cs_mask_one_byte_tile0_4" start="4" end="4" type="bool"/>
+    <field name="cs_mask_one_byte_tile0_3" start="3" end="3" type="bool"/>
+    <field name="cs_mask_one_byte_tile0_2" start="2" end="2" type="bool"/>
+    <field name="cs_mask_one_byte_tile0_1" start="1" end="1" type="bool"/>
+    <field name="cs_mask_one_byte_tile0_0" start="0" end="0" type="bool"/>
+  </struct>
+
+  <!-- Labeling of fields within Byte Based Mask Two-Byte Word 0.
+       See ROGUE_IPF_PRIMITIVE_HEADER_SIPF2.cs_mask_num_bytes.
+  -->
+  <struct name="BYTE_BASED_MASK_TWO_BYTE_WORD_0_SIPF2" length="1">
+    <field name="cs_mask_two_byte_tile1_15" start="31" end="31" type="bool"/>
+    <field name="cs_mask_two_byte_tile1_14" start="30" end="30" type="bool"/>
+    <field name="cs_mask_two_byte_tile1_13" start="29" end="29" type="bool"/>
+    <field name="cs_mask_two_byte_tile1_12" start="28" end="28" type="bool"/>
+    <field name="cs_mask_two_byte_tile1_11" start="27" end="27" type="bool"/>
+    <field name="cs_mask_two_byte_tile1_10" start="26" end="26" type="bool"/>
+    <field name="cs_mask_two_byte_tile1_9" start="25" end="25" type="bool"/>
+    <field name="cs_mask_two_byte_tile1_8" start="24" end="24" type="bool"/>
+    <field name="cs_mask_two_byte_tile1_7" start="23" end="23" type="bool"/>
+    <field name="cs_mask_two_byte_tile1_6" start="22" end="22" type="bool"/>
+    <field name="cs_mask_two_byte_tile1_5" start="21" end="21" type="bool"/>
+    <field name="cs_mask_two_byte_tile1_4" start="20" end="20" type="bool"/>
+    <field name="cs_mask_two_byte_tile1_3" start="19" end="19" type="bool"/>
+    <field name="cs_mask_two_byte_tile1_2" start="18" end="18" type="bool"/>
+    <field name="cs_mask_two_byte_tile1_1" start="17" end="17" type="bool"/>
+    <field name="cs_mask_two_byte_tile1_0" start="16" end="16" type="bool"/>
+    <field name="cs_mask_two_byte_tile0_15" start="15" end="15" type="bool"/>
+    <field name="cs_mask_two_byte_tile0_14" start="14" end="14" type="bool"/>
+    <field name="cs_mask_two_byte_tile0_13" start="13" end="13" type="bool"/>
+    <field name="cs_mask_two_byte_tile0_12" start="12" end="12" type="bool"/>
+    <field name="cs_mask_two_byte_tile0_11" start="11" end="11" type="bool"/>
+    <field name="cs_mask_two_byte_tile0_10" start="10" end="10" type="bool"/>
+    <field name="cs_mask_two_byte_tile0_9" start="9" end="9" type="bool"/>
+    <field name="cs_mask_two_byte_tile0_8" start="8" end="8" type="bool"/>
+    <field name="cs_mask_two_byte_tile0_7" start="7" end="7" type="bool"/>
+    <field name="cs_mask_two_byte_tile0_6" start="6" end="6" type="bool"/>
+    <field name="cs_mask_two_byte_tile0_5" start="5" end="5" type="bool"/>
+    <field name="cs_mask_two_byte_tile0_4" start="4" end="4" type="bool"/>
+    <field name="cs_mask_two_byte_tile0_3" start="3" end="3" type="bool"/>
+    <field name="cs_mask_two_byte_tile0_2" start="2" end="2" type="bool"/>
+    <field name="cs_mask_two_byte_tile0_1" start="1" end="1" type="bool"/>
+    <field name="cs_mask_two_byte_tile0_0" start="0" end="0" type="bool"/>
+  </struct>
+
+  <!-- Labeling of fields within Byte Based Mask Two-Byte Word 1.
+       See ROGUE_IPF_PRIMITIVE_HEADER_SIPF2.cs_mask_num_bytes.
+  -->
+  <struct name="BYTE_BASED_MASK_TWO_BYTE_WORD_1_SIPF2" length="1">
+    <field name="cs_mask_two_byte_tile3_15" start="31" end="31" type="bool"/>
+    <field name="cs_mask_two_byte_tile3_14" start="30" end="30" type="bool"/>
+    <field name="cs_mask_two_byte_tile3_13" start="29" end="29" type="bool"/>
+    <field name="cs_mask_two_byte_tile3_12" start="28" end="28" type="bool"/>
+    <field name="cs_mask_two_byte_tile3_11" start="27" end="27" type="bool"/>
+    <field name="cs_mask_two_byte_tile3_10" start="26" end="26" type="bool"/>
+    <field name="cs_mask_two_byte_tile3_9" start="25" end="25" type="bool"/>
+    <field name="cs_mask_two_byte_tile3_8" start="24" end="24" type="bool"/>
+    <field name="cs_mask_two_byte_tile3_7" start="23" end="23" type="bool"/>
+    <field name="cs_mask_two_byte_tile3_6" start="22" end="22" type="bool"/>
+    <field name="cs_mask_two_byte_tile3_5" start="21" end="21" type="bool"/>
+    <field name="cs_mask_two_byte_tile3_4" start="20" end="20" type="bool"/>
+    <field name="cs_mask_two_byte_tile3_3" start="19" end="19" type="bool"/>
+    <field name="cs_mask_two_byte_tile3_2" start="18" end="18" type="bool"/>
+    <field name="cs_mask_two_byte_tile3_1" start="17" end="17" type="bool"/>
+    <field name="cs_mask_two_byte_tile3_0" start="16" end="16" type="bool"/>
+    <field name="cs_mask_two_byte_tile2_15" start="15" end="15" type="bool"/>
+    <field name="cs_mask_two_byte_tile2_14" start="14" end="14" type="bool"/>
+    <field name="cs_mask_two_byte_tile2_13" start="13" end="13" type="bool"/>
+    <field name="cs_mask_two_byte_tile2_12" start="12" end="12" type="bool"/>
+    <field name="cs_mask_two_byte_tile2_11" start="11" end="11" type="bool"/>
+    <field name="cs_mask_two_byte_tile2_10" start="10" end="10" type="bool"/>
+    <field name="cs_mask_two_byte_tile2_9" start="9" end="9" type="bool"/>
+    <field name="cs_mask_two_byte_tile2_8" start="8" end="8" type="bool"/>
+    <field name="cs_mask_two_byte_tile2_7" start="7" end="7" type="bool"/>
+    <field name="cs_mask_two_byte_tile2_6" start="6" end="6" type="bool"/>
+    <field name="cs_mask_two_byte_tile2_5" start="5" end="5" type="bool"/>
+    <field name="cs_mask_two_byte_tile2_4" start="4" end="4" type="bool"/>
+    <field name="cs_mask_two_byte_tile2_3" start="3" end="3" type="bool"/>
+    <field name="cs_mask_two_byte_tile2_2" start="2" end="2" type="bool"/>
+    <field name="cs_mask_two_byte_tile2_1" start="1" end="1" type="bool"/>
+    <field name="cs_mask_two_byte_tile2_0" start="0" end="0" type="bool"/>
+  </struct>
+
+  <!-- Labeling of fields within Byte Based Mask Three-Byte Word 0.
+       See ROGUE_IPF_PRIMITIVE_HEADER_SIPF2.cs_mask_num_bytes.
+  -->
+  <struct name="BYTE_BASED_MASK_THREE_BYTE_WORD_0_SIPF2" length="1">
+    <field name="cs_mask_three_byte_tile1_7" start="31" end="31" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_6" start="30" end="30" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_5" start="29" end="29" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_4" start="28" end="28" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_3" start="27" end="27" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_2" start="26" end="26" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_1" start="25" end="25" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_0" start="24" end="24" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_23" start="23" end="23" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_22" start="22" end="22" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_21" start="21" end="21" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_20" start="20" end="20" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_19" start="19" end="19" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_18" start="18" end="18" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_17" start="17" end="17" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_16" start="16" end="16" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_15" start="15" end="15" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_14" start="14" end="14" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_13" start="13" end="13" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_12" start="12" end="12" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_11" start="11" end="11" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_10" start="10" end="10" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_9" start="9" end="9" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_8" start="8" end="8" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_7" start="7" end="7" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_6" start="6" end="6" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_5" start="5" end="5" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_4" start="4" end="4" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_3" start="3" end="3" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_2" start="2" end="2" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_1" start="1" end="1" type="bool"/>
+    <field name="cs_mask_three_byte_tile0_0" start="0" end="0" type="bool"/>
+  </struct>
+
+  <!-- Labeling of fields within Byte Based Mask Three-Byte Word 1.
+       See ROGUE_IPF_PRIMITIVE_HEADER_SIPF2.cs_mask_num_bytes.
+  -->
+  <struct name="BYTE_BASED_MASK_THREE_BYTE_WORD_1_SIPF2" length="1">
+    <field name="cs_mask_three_byte_tile2_15" start="31" end="31" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_14" start="30" end="30" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_13" start="29" end="29" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_12" start="28" end="28" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_11" start="27" end="27" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_10" start="26" end="26" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_9" start="25" end="25" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_8" start="24" end="24" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_7" start="23" end="23" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_6" start="22" end="22" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_5" start="21" end="21" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_4" start="20" end="20" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_3" start="19" end="19" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_2" start="18" end="18" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_1" start="17" end="17" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_0" start="16" end="16" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_23" start="15" end="15" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_22" start="14" end="14" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_21" start="13" end="13" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_20" start="12" end="12" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_19" start="11" end="11" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_18" start="10" end="10" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_17" start="9" end="9" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_16" start="8" end="8" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_15" start="7" end="7" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_14" start="6" end="6" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_13" start="5" end="5" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_12" start="4" end="4" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_11" start="3" end="3" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_10" start="2" end="2" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_9" start="1" end="1" type="bool"/>
+    <field name="cs_mask_three_byte_tile1_8" start="0" end="0" type="bool"/>
+  </struct>
+
+  <!-- Labeling of fields within Byte Based Mask Three-Byte Word 2.
+       See ROGUE_IPF_PRIMITIVE_HEADER_SIPF2.cs_mask_num_bytes.
+  -->
+  <struct name="BYTE_BASED_MASK_THREE_BYTE_WORD_2_SIPF2" length="1">
+    <field name="cs_mask_three_byte_tile3_23" start="31" end="31" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_22" start="30" end="30" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_21" start="29" end="29" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_20" start="28" end="28" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_19" start="27" end="27" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_18" start="26" end="26" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_17" start="25" end="25" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_16" start="24" end="24" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_15" start="23" end="23" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_14" start="22" end="22" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_13" start="21" end="21" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_12" start="20" end="20" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_11" start="19" end="19" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_10" start="18" end="18" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_9" start="17" end="17" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_8" start="16" end="16" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_7" start="15" end="15" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_6" start="14" end="14" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_5" start="13" end="13" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_4" start="12" end="12" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_3" start="11" end="11" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_2" start="10" end="10" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_1" start="9" end="9" type="bool"/>
+    <field name="cs_mask_three_byte_tile3_0" start="8" end="8" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_23" start="7" end="7" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_22" start="6" end="6" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_21" start="5" end="5" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_20" start="4" end="4" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_19" start="3" end="3" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_18" start="2" end="2" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_17" start="1" end="1" type="bool"/>
+    <field name="cs_mask_three_byte_tile2_16" start="0" end="0" type="bool"/>
+  </struct>
+
   <struct name="COMPRESSION_SIZE_WORD" length="1">
     <field name="cs_isp_comp_table_size" start="27" end="31" type="uint"/>
     <field name="cs_tsp_comp_format_size" start="21" end="26" type="uint"/>
@@ -131,12 +441,34 @@ SOFTWARE.
     <field name="ix_index0_0" start="0" end="5" type="uint"/>
   </struct>
 
+  <!-- FIXME: This should be of 24 bit length. Should we change the length to
+       be in terms of uint8_t instead of uint32_t.
+  -->
   <struct name="ISP_VERTEX_XY" length="1">
     <field name="sign" start="23" end="23" type="bool"/>
     <field name="integer" start="8" end="22" type="uint"/>
     <field name="frac" start="0" end="7" type="uint"/>
   </struct>
 
+  <!-- FIXME: This is the SIMPLE_INTERNAL_PARAMETER_FORMAT variant.
+       Should we use the "condition" tag for this?
+  -->
+  <struct name="ISP_VERTEX_XY_SIPF" length="1">
+    <field name="integer" start="4" end="16" type="uint">
+      <define name="MAX_VAL" value="0x1FFF"/>
+    </field>
+    <field name="frac" start="0" end="3" type="uint">
+      <define name="MAX_VAL" value="0xF"/>
+    </field>
+  </struct>
+
+  <!-- FIXME: This is only available with SIMPLE_INTERNAL_PARAMETER_FORMAT. -->
+  <struct name="ISP_VERTEX_WORD_SIPF" length="2">
+    <field name="z" start="34" end="63" type="uint"/>
+    <field name="y" start="17" end="33" type="uint"/>
+    <field name="x" start="0" end="16" type="uint"/>
+  </struct>
+
   <struct name="ISP_VERTEX_WORD_0" length="1">
     <field name="y0" start="24" end="31" type="uint"/>
     <field name="x0" start="0" end="23" type="uint"/>
index 44a8cf9..30effb0 100644 (file)
@@ -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 (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);
-
-      /* 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);
+      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);
+
+         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(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;
+
+         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;
+
+            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;
+
+            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);
+      }
 
-            /* 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;
+      *cs_ptr_out = cs_ptr;
+      return;
+   }
 
-            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);
+   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);
 
-      /* The last pass didn't ++. */
-      if ((num_mappings & 1U) != 0U)
-         cs_ptr++;
+         /* 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++;
+         continue;
+      }
 
-         /* 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++;
+      /* 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 = bottom >> PVRX(IPF_ISP_VERTEX_WORD_1_Y0_SHIFT);
-         }
-         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_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_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++;
+      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 (&regs->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 (&regs->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(&regs->isp_rgn, CR_ISP_RGN, isp_rgn);
+      /* clang-format on */
+   }
 
    return VK_SUCCESS;
 }