+#if V3D_VERSION >= 41
+static void
+v3d_emit_gs_state_record(struct v3d_job *job,
+ struct v3d_compiled_shader *gs_bin,
+ struct v3d_cl_reloc gs_bin_uniforms,
+ struct v3d_compiled_shader *gs,
+ struct v3d_cl_reloc gs_render_uniforms)
+{
+ cl_emit(&job->indirect, GEOMETRY_SHADER_STATE_RECORD, shader) {
+ shader.geometry_bin_mode_shader_code_address =
+ cl_address(v3d_resource(gs_bin->resource)->bo,
+ gs_bin->offset);
+ shader.geometry_bin_mode_shader_4_way_threadable =
+ gs_bin->prog_data.gs->base.threads == 4;
+ shader.geometry_bin_mode_shader_start_in_final_thread_section =
+ gs_bin->prog_data.gs->base.single_seg;
+ shader.geometry_bin_mode_shader_propagate_nans = true;
+ shader.geometry_bin_mode_shader_uniforms_address =
+ gs_bin_uniforms;
+
+ shader.geometry_render_mode_shader_code_address =
+ cl_address(v3d_resource(gs->resource)->bo, gs->offset);
+ shader.geometry_render_mode_shader_4_way_threadable =
+ gs->prog_data.gs->base.threads == 4;
+ shader.geometry_render_mode_shader_start_in_final_thread_section =
+ gs->prog_data.gs->base.single_seg;
+ shader.geometry_render_mode_shader_propagate_nans = true;
+ shader.geometry_render_mode_shader_uniforms_address =
+ gs_render_uniforms;
+ }
+}
+
+static uint8_t
+v3d_gs_output_primitive(uint32_t prim_type)
+{
+ switch (prim_type) {
+ case GL_POINTS:
+ return GEOMETRY_SHADER_POINTS;
+ case GL_LINE_STRIP:
+ return GEOMETRY_SHADER_LINE_STRIP;
+ case GL_TRIANGLE_STRIP:
+ return GEOMETRY_SHADER_TRI_STRIP;
+ default:
+ unreachable("Unsupported primitive type");
+ }
+}
+
+static void
+v3d_emit_tes_gs_common_params(struct v3d_job *job,
+ uint8_t gs_out_prim_type)
+{
+ /* This, and v3d_emit_tes_gs_shader_params below, fill in default
+ * values for tessellation fields even though we don't support
+ * tessellation yet because our packing functions (and the simulator)
+ * complain if we don't.
+ */
+ cl_emit(&job->indirect, TESSELLATION_GEOMETRY_COMMON_PARAMS, shader) {
+ shader.tessellation_type = TESSELLATION_TYPE_TRIANGLE;
+ shader.tessellation_point_mode = false;
+ shader.tessellation_edge_spacing = TESSELLATION_EDGE_SPACING_EVEN;
+ shader.tessellation_clockwise = true;
+ shader.tessellation_invocations = 1;
+
+ shader.geometry_shader_output_format =
+ v3d_gs_output_primitive(gs_out_prim_type);
+ shader.geometry_shader_instances = 1; /* FIXME */
+ }
+}
+
+static void
+v3d_emit_tes_gs_shader_params(struct v3d_job *job,
+ struct v3d_gs_prog_data *gs)
+{
+ cl_emit(&job->indirect, TESSELLATION_GEOMETRY_SHADER_PARAMS, shader) {
+ shader.tcs_batch_flush_mode = V3D_TCS_FLUSH_MODE_FULLY_PACKED;
+ shader.per_patch_data_column_depth = 1;
+ shader.tcs_output_segment_size_in_sectors = 1;
+ shader.tcs_output_segment_pack_mode = V3D_PACK_MODE_16_WAY;
+ shader.tes_output_segment_size_in_sectors = 1;
+ shader.tes_output_segment_pack_mode = V3D_PACK_MODE_16_WAY;
+ shader.gs_output_segment_size_in_sectors =
+ gs->vpm_output_size;
+ shader.gs_output_segment_pack_mode = V3D_PACK_MODE_16_WAY; /* FIXME*/
+ shader.tbg_max_patches_per_tcs_batch = 1;
+ shader.tbg_max_extra_vertex_segs_for_patches_after_first = 0;
+ shader.tbg_min_tcs_output_segments_required_in_play = 1;
+ shader.tbg_min_per_patch_data_segments_required_in_play = 1;
+ shader.tpg_max_patches_per_tes_batch = 1;
+ shader.tpg_max_vertex_segments_per_tes_batch = 0;
+ shader.tpg_max_tcs_output_segments_per_tes_batch = 1;
+ shader.tpg_min_tes_output_segments_required_in_play = 1;
+ shader.gbg_max_tes_output_vertex_segments_per_gs_batch = 0;
+ shader.gbg_min_gs_output_segments_required_in_play = 1;
+ }
+}
+
+#endif
+