mirror of
https://github.com/elwrcl/intel-hard-graphics.git
synced 2026-10-31 10:58:03 +03:00
init
This commit is contained in:
12511 files changed
+6156641
No files matched your search
@@ -0,0 +1,380 @@
|
||||
# Copyright © 2022 Imagination Technologies Ltd.
|
||||
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
|
||||
# The above copyright notice and this permission notice (including the next
|
||||
# paragraph) shall be included in all copies or substantial portions of the
|
||||
# Software.
|
||||
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
Language: Cpp
|
||||
Standard: c++11
|
||||
|
||||
UseCRLF: false
|
||||
ColumnLimit: 80
|
||||
|
||||
DeriveLineEnding: false
|
||||
DerivePointerAlignment: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
|
||||
DisableFormat: false
|
||||
|
||||
########
|
||||
# Tabs #
|
||||
########
|
||||
UseTab: Never
|
||||
TabWidth: 3
|
||||
|
||||
ConstructorInitializerIndentWidth: 6
|
||||
ContinuationIndentWidth: 3
|
||||
|
||||
IndentWidth: 3
|
||||
#IndentCaseBlocks: true # Requires clang-11
|
||||
IndentCaseLabels: false
|
||||
#IndentExternBlock: NoIndent # Requires clang-11
|
||||
IndentGotoLabels: false
|
||||
IndentPPDirectives: AfterHash
|
||||
IndentWrappedFunctionNames: false
|
||||
AccessModifierOffset: -4 # -IndentWidth
|
||||
|
||||
NamespaceIndentation: None
|
||||
|
||||
##########
|
||||
# Braces #
|
||||
##########
|
||||
AlignAfterOpenBracket: Align
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowAllConstructorInitializersOnNextLine: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
|
||||
Cpp11BracedListStyle: false
|
||||
|
||||
########################
|
||||
# Whitespace Alignment #
|
||||
########################
|
||||
AlignConsecutiveAssignments: None
|
||||
#AlignConsecutiveBitFields: false # Requires clang-11
|
||||
AlignConsecutiveDeclarations: None
|
||||
AlignConsecutiveMacros: None
|
||||
AlignTrailingComments: false
|
||||
|
||||
AlignEscapedNewlines: Left
|
||||
|
||||
#AlignOperands: Align # Requires clang-11
|
||||
#BitFieldColonSpacing: Both # Requires clang-12
|
||||
|
||||
PointerAlignment: Right
|
||||
#SpaceAroundPointerQualifiers: Both # Requires clang-12
|
||||
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
#SpaceBeforeParens: ControlStatementsExceptForEachMacros # Requires clang-11
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceBeforeSquareBrackets: false
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesInAngles: Never
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
SpacesBeforeTrailingComments: 2
|
||||
|
||||
############################
|
||||
# Multi-line constructions #
|
||||
############################
|
||||
AllowShortBlocksOnASingleLine: Empty
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
#AllowShortEnumsOnASingleLine: false # Requires clang-11
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
# BeforeLambdaBody: false # Requires clang-11
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyNamespace: true
|
||||
SplitEmptyRecord: true
|
||||
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeTernaryOperators: true
|
||||
|
||||
BreakConstructorInitializers: AfterColon
|
||||
BreakInheritanceList: AfterColon
|
||||
|
||||
BreakStringLiterals: false
|
||||
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
|
||||
#InsertTrailingCommas: Wrapped # Requires clang-11
|
||||
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MaxEmptyLinesToKeep: 1
|
||||
|
||||
SortUsingDeclarations: true
|
||||
|
||||
############
|
||||
# Includes #
|
||||
############
|
||||
# TODO: Temporary config
|
||||
IncludeBlocks: Preserve
|
||||
SortIncludes: Never
|
||||
# TODO: This requires additional work to clean up headers & includes first
|
||||
#IncludeBlocks: Regroup
|
||||
#SortIncludes: true
|
||||
#IncludeIsMainRegex: '(_test)?$'
|
||||
##IncludeIsMainSourceRegex: <default>
|
||||
#IncludeCategories:
|
||||
# - Regex: '^"'
|
||||
# Priority: 1
|
||||
|
||||
############
|
||||
# Comments #
|
||||
############
|
||||
FixNamespaceComments: false
|
||||
|
||||
#############
|
||||
# Penalties #
|
||||
#############
|
||||
# Taken from torvalds/kernel:.clang-format
|
||||
PenaltyBreakAssignment: 10
|
||||
PenaltyBreakBeforeFirstCallParameter: 30
|
||||
PenaltyBreakComment: 10
|
||||
PenaltyBreakFirstLessLess: 0
|
||||
PenaltyBreakString: 10
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 100
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
|
||||
#######################
|
||||
# User-defined macros #
|
||||
#######################
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
|
||||
#AttributeMacros: [] # Requires clang-12
|
||||
|
||||
ForEachMacros: [
|
||||
'BITSET_FOREACH_SET',
|
||||
'foreach_instr',
|
||||
'foreach_instr_safe',
|
||||
'foreach_list_typed',
|
||||
'foreach_list_typed_from',
|
||||
'foreach_list_typed_from_reverse',
|
||||
'foreach_list_typed_reverse',
|
||||
'foreach_list_typed_reverse_safe',
|
||||
'foreach_list_typed_safe',
|
||||
'foreach_target',
|
||||
'hash_table_foreach',
|
||||
'hash_table_u64_foreach',
|
||||
'LIST_FOR_EACH_ENTRY',
|
||||
'LIST_FOR_EACH_ENTRY_FROM',
|
||||
'LIST_FOR_EACH_ENTRY_FROM_REV',
|
||||
'LIST_FOR_EACH_ENTRY_SAFE',
|
||||
'LIST_FOR_EACH_ENTRY_SAFE_REV',
|
||||
'list_for_each_entry',
|
||||
'list_for_each_entry_from',
|
||||
'list_for_each_entry_from_rev',
|
||||
'list_for_each_entry_from_safe',
|
||||
'list_for_each_entry_rev',
|
||||
'list_for_each_entry_safe',
|
||||
'list_for_each_entry_safe_rev',
|
||||
'list_pair_for_each_entry',
|
||||
'pvr_csb_emit',
|
||||
'pvr_csb_pack',
|
||||
'nir_foreach_block',
|
||||
'nir_foreach_block_safe',
|
||||
'nir_foreach_block_unstructured',
|
||||
'nir_foreach_reg_decl',
|
||||
'nir_foreach_entrypoint',
|
||||
'nir_foreach_entrypoint_safe',
|
||||
'nir_foreach_function',
|
||||
'nir_foreach_function_with_impl',
|
||||
'nir_foreach_instr',
|
||||
'nir_foreach_instr_safe',
|
||||
'nir_foreach_phi_src',
|
||||
'nir_foreach_shader_in_variable',
|
||||
'nir_foreach_shader_out_variable',
|
||||
'nir_foreach_use',
|
||||
'nir_foreach_use_safe',
|
||||
'nir_foreach_variable_with_modes',
|
||||
'nir_foreach_variable_with_modes_safe',
|
||||
'pco_foreach_block_in_func',
|
||||
'pco_foreach_block_in_func_from',
|
||||
'pco_foreach_block_in_func_from_rev',
|
||||
'pco_foreach_block_in_func_rev',
|
||||
'pco_foreach_cf_node_in_func',
|
||||
'pco_foreach_cf_node_in_func_structured',
|
||||
'pco_foreach_cf_node_in_if_else',
|
||||
'pco_foreach_cf_node_in_if_epilogue',
|
||||
'pco_foreach_cf_node_in_if_interlogue',
|
||||
'pco_foreach_cf_node_in_if_prologue',
|
||||
'pco_foreach_cf_node_in_if_then',
|
||||
'pco_foreach_cf_node_in_loop',
|
||||
'pco_foreach_cf_node_in_loop_epilogue',
|
||||
'pco_foreach_cf_node_in_loop_interlogue',
|
||||
'pco_foreach_cf_node_in_loop_prologue',
|
||||
'pco_foreach_func_in_shader',
|
||||
'pco_foreach_func_in_shader_rev',
|
||||
'pco_foreach_if_in_func',
|
||||
'pco_foreach_if_in_func_from',
|
||||
'pco_foreach_if_in_func_from_rev',
|
||||
'pco_foreach_if_in_func_rev',
|
||||
'pco_foreach_ssa_bool_if_in_func',
|
||||
'pco_foreach_ssa_if_in_func',
|
||||
'pco_foreach_igrp_in_block',
|
||||
'pco_foreach_igrp_in_func',
|
||||
'pco_foreach_instr_dest',
|
||||
'pco_foreach_instr_dest_from',
|
||||
'pco_foreach_instr_dest_hwreg',
|
||||
'pco_foreach_instr_dest_ssa',
|
||||
'pco_foreach_instr_dest_ssa_from',
|
||||
'pco_foreach_instr_dest_vreg',
|
||||
'pco_foreach_instr_dest_vreg_ssa',
|
||||
'pco_foreach_instr_in_block',
|
||||
'pco_foreach_instr_in_block_from',
|
||||
'pco_foreach_instr_in_block_from_rev',
|
||||
'pco_foreach_instr_in_block_rev',
|
||||
'pco_foreach_instr_in_block_safe',
|
||||
'pco_foreach_instr_in_block_safe_rev',
|
||||
'pco_foreach_instr_in_func',
|
||||
'pco_foreach_instr_in_func_from',
|
||||
'pco_foreach_instr_in_func_from_rev',
|
||||
'pco_foreach_instr_in_func_rev',
|
||||
'pco_foreach_instr_in_func_safe',
|
||||
'pco_foreach_instr_in_func_safe_rev',
|
||||
'pco_foreach_instr_in_igrp',
|
||||
'pco_foreach_instr_in_igrp_rev',
|
||||
'pco_foreach_instr_src',
|
||||
'pco_foreach_instr_src_from',
|
||||
'pco_foreach_instr_src_hwreg',
|
||||
'pco_foreach_instr_src_ssa',
|
||||
'pco_foreach_instr_src_ssa_from',
|
||||
'pco_foreach_instr_src_vreg',
|
||||
'pco_foreach_instr_src_vreg_ssa',
|
||||
'pco_foreach_instr_src_vtxin_reg',
|
||||
'pco_foreach_loop_in_func',
|
||||
'pco_foreach_loop_in_func_from',
|
||||
'pco_foreach_loop_in_func_from_rev',
|
||||
'pco_foreach_loop_in_func_rev',
|
||||
'pco_foreach_phase',
|
||||
'pco_foreach_phase_from',
|
||||
'pco_foreach_phase_from_rev',
|
||||
'pco_foreach_phase_in_igrp',
|
||||
'pco_foreach_phase_in_igrp_from',
|
||||
'pco_foreach_phase_in_igrp_from_rev',
|
||||
'pco_foreach_phase_in_igrp_rev',
|
||||
'pco_foreach_phase_rev',
|
||||
'pco_foreach_phi_src_in_instr',
|
||||
'pco_foreach_vreg_if_in_func',
|
||||
'pco_foreach_vreg_ssa_if_in_func',
|
||||
'pvr_foreach_supported_tex_format',
|
||||
'pvr_foreach_supported_tex_format_',
|
||||
'pvr_foreach_supported_tex_format_compressed',
|
||||
'pvr_foreach_supported_tex_format_compressed_',
|
||||
'rogue_foreach_block',
|
||||
'rogue_foreach_block_safe',
|
||||
'rogue_foreach_block_rev',
|
||||
'rogue_foreach_block_safe_rev',
|
||||
'rogue_foreach_block_use',
|
||||
'rogue_foreach_block_use_safe',
|
||||
'rogue_foreach_drc_trxn',
|
||||
'rogue_foreach_drc_trxn_safe',
|
||||
'rogue_foreach_phase_in_set',
|
||||
'rogue_foreach_phase_in_set_rev',
|
||||
'rogue_foreach_imm_use',
|
||||
'rogue_foreach_imm_use_safe',
|
||||
'rogue_foreach_instr_group_in_block',
|
||||
'rogue_foreach_instr_group_in_block_safe',
|
||||
'rogue_foreach_instr_group_in_shader',
|
||||
'rogue_foreach_instr_group_in_shader_safe',
|
||||
'rogue_foreach_instr_in_block',
|
||||
'rogue_foreach_instr_in_block_safe',
|
||||
'rogue_foreach_instr_in_block_rev',
|
||||
'rogue_foreach_instr_in_block_safe_rev',
|
||||
'rogue_foreach_instr_in_shader',
|
||||
'rogue_foreach_instr_in_shader_safe',
|
||||
'rogue_foreach_instr_in_shader_rev',
|
||||
'rogue_foreach_instr_in_shader_safe_rev',
|
||||
'rogue_foreach_mod_in_set',
|
||||
'rogue_foreach_reg',
|
||||
'rogue_foreach_reg_safe',
|
||||
'rogue_foreach_reg_use',
|
||||
'rogue_foreach_reg_use_safe',
|
||||
'rogue_foreach_reg_write',
|
||||
'rogue_foreach_reg_write_safe',
|
||||
'rogue_foreach_regarray',
|
||||
'rogue_foreach_regarray_safe',
|
||||
'rogue_foreach_regarray_use',
|
||||
'rogue_foreach_regarray_use_safe',
|
||||
'rogue_foreach_regarray_write',
|
||||
'rogue_foreach_regarray_write_safe',
|
||||
'rogue_foreach_subarray',
|
||||
'rogue_foreach_subarray_safe',
|
||||
'rb_tree_foreach',
|
||||
'rb_tree_foreach_safe',
|
||||
'u_foreach_bit',
|
||||
'u_foreach_bit64',
|
||||
'u_vector_foreach',
|
||||
'util_dynarray_foreach',
|
||||
'util_dynarray_foreach_reverse',
|
||||
'vk_foreach_struct',
|
||||
'vk_foreach_struct_const',
|
||||
# FIXME: vk_outarray_append doesn't fit here, remove
|
||||
# it when a better solution exists for it.
|
||||
'vk_outarray_append',
|
||||
'vk_outarray_append_typed'
|
||||
]
|
||||
|
||||
NamespaceMacros: [
|
||||
]
|
||||
|
||||
StatementMacros: [
|
||||
]
|
||||
|
||||
TypenameMacros: [
|
||||
]
|
||||
|
||||
#WhitespaceSensitiveMacros: [] # Requires clang-11
|
||||
@@ -0,0 +1,9 @@
|
||||
((nil . ((show-trailing-whitespace . t)))
|
||||
(prog-mode
|
||||
(indent-tabs-mode . nil)
|
||||
(tab-width . 3)
|
||||
(c-basic-offset . 3)
|
||||
(c-file-style . "linux")
|
||||
(fill-column . 80)
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,6 @@
|
||||
[*.{c,h,cpp,hpp,cc,hh}]
|
||||
max_line_length = 80
|
||||
|
||||
[*.xml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
dEQP-VK.api.buffer_view.access.suballocation.buffer_view_memory_test_complete_compute
|
||||
dEQP-VK.api.copy_and_blit.copy_commands2.blit_image.all_formats.color.1d.r32g32_uint.r32g32_uint.optimal_optimal_nearest
|
||||
dEQP-VK.api.copy_and_blit.copy_commands2.blit_image.all_formats.color.2d.etc2_r8g8b8a1_srgb_block.a8b8g8r8_srgb_pack32.optimal_general_nearest
|
||||
dEQP-VK.api.copy_and_blit.core.blit_image.all_formats.color.2d.a1r5g5b5_unorm_pack16.b10g11r11_ufloat_pack32.general_general_nearest
|
||||
dEQP-VK.api.copy_and_blit.core.blit_image.all_formats.color.2d.b4g4r4a4_unorm_pack16.b10g11r11_ufloat_pack32.optimal_optimal_nearest
|
||||
dEQP-VK.api.copy_and_blit.core.blit_image.all_formats.color.2d.eac_r11g11_unorm_block.r8g8_snorm.general_general_linear
|
||||
dEQP-VK.api.copy_and_blit.core.blit_image.all_formats.color.2d.etc2_r8g8b8_srgb_block.r8g8b8a8_srgb.optimal_general_nearest
|
||||
dEQP-VK.api.copy_and_blit.core.blit_image.all_formats.color.2d.etc2_r8g8b8a1_unorm_block.b4g4r4a4_unorm_pack16.general_optimal_nearest
|
||||
dEQP-VK.api.copy_and_blit.core.blit_image.all_formats.color.2d.r16g16_sfloat.r16g16_unorm.optimal_general_nearest
|
||||
dEQP-VK.api.copy_and_blit.core.blit_image.all_formats.color.2d.r8_unorm.r8g8_unorm.optimal_optimal_nearest
|
||||
dEQP-VK.api.copy_and_blit.core.image_to_image.all_formats.color.2d_to_2d.r16_unorm.r16_unorm.general_optimal
|
||||
dEQP-VK.api.copy_and_blit.core.image_to_image.cube.cube_to_array_whole
|
||||
dEQP-VK.api.copy_and_blit.dedicated_allocation.blit_image.simple_tests.mirror_subregions_3d.r32_sfloat_linear
|
||||
dEQP-VK.api.image_clearing.core.clear_color_image.2d.linear.single_layer.a2b10g10r10_unorm_pack32_64x11
|
||||
dEQP-VK.api.image_clearing.core.clear_color_image.2d.optimal.single_layer.a8b8g8r8_sint_pack32_1x33_multiple_subresourcerange
|
||||
dEQP-VK.api.image_clearing.dedicated_allocation.clear_color_image.1d.linear.single_layer.r8g8b8a8_uint_71x1
|
||||
dEQP-VK.binding_model.shader_access.primary_cmd_buf.bind.combined_image_sampler_immutable.no_access.multiple_descriptor_sets.multiple_contiguous_descriptors.cube_array
|
||||
dEQP-VK.binding_model.shader_access.primary_cmd_buf.bind.storage_buffer_dynamic.no_access.multiple_descriptor_sets.descriptor_array.offset_view_zero_dynamic_nonzero
|
||||
dEQP-VK.binding_model.shader_access.primary_cmd_buf.bind.with_template.uniform_buffer_dynamic.vertex_fragment.multiple_arbitrary_descriptors.offset_view_nonzero_dynamic_zero
|
||||
dEQP-VK.draw.dynamic_rendering.primary_cmd_buff.instanced.draw_indexed_indirect_vk_primitive_topology_line_list_attrib_divisor_0_multiview
|
||||
dEQP-VK.draw.dynamic_rendering.primary_cmd_buff.instanced.draw_indirect_vk_primitive_topology_triangle_list_attrib_divisor_20_multiview
|
||||
dEQP-VK.draw.renderpass.instanced.draw_indexed_indirect_vk_primitive_topology_point_list_attrib_divisor_20_multiview
|
||||
dEQP-VK.draw.renderpass.instanced.draw_indexed_indirect_vk_primitive_topology_triangle_fan_attrib_divisor_2_multiview
|
||||
dEQP-VK.draw.renderpass.instanced.draw_indirect_vk_primitive_topology_triangle_fan_khr_attrib_divisor_2_multiview
|
||||
dEQP-VK.draw.renderpass.vertex_attribute_divisor.khr.static_pipeline.draw_indexed.non_zero.0
|
||||
dEQP-VK.glsl.conversions.vector_to_vector.ivec3_to_bvec3_fragment
|
||||
dEQP-VK.glsl.matrix.mul.const.highp_mat3x2_vec3_fragment
|
||||
dEQP-VK.glsl.switch.switch_in_switch_uniform_vertex
|
||||
dEQP-VK.glsl.texture_functions.query.texturequerylevels.usampler2d_fragment
|
||||
dEQP-VK.glsl.texture_functions.query.texturesize.usampler2d_vertex
|
||||
dEQP-VK.glsl.texture_functions.texture.sampler2darrayshadow_fragment
|
||||
dEQP-VK.graphicsfuzz.cov-nested-loop-not-greater-than-increment-array-element
|
||||
dEQP-VK.graphicsfuzz.find-msb-from-lsb
|
||||
dEQP-VK.graphicsfuzz.function-with-float-comparison
|
||||
dEQP-VK.graphicsfuzz.increment-value-in-nested-for-loop
|
||||
dEQP-VK.graphicsfuzz.stable-mergesort-clamped-conditional-bit-shift
|
||||
dEQP-VK.image.atomic_operations.dec.3d.notransfer.normal_read.normal_img.r32i_intermediate_values
|
||||
dEQP-VK.image.atomic_operations.exchange.3d.transfer.normal_read.normal_img.r32ui_intermediate_values
|
||||
dEQP-VK.image.atomic_operations.xor.2d_array.notransfer.normal_read.normal_img.r32i_intermediate_values
|
||||
dEQP-VK.image.format_reinterpret.2d_array.r16_snorm_r8g8_unorm
|
||||
dEQP-VK.image.format_reinterpret.cube.r16g16b16a16_sint_r16g16b16a16_unorm
|
||||
dEQP-VK.image.format_reinterpret.cube_array.r32_sint_r32_uint
|
||||
dEQP-VK.image.mutable.2d_array.r8g8b8a8_snorm_r8g8b8a8_sint_copy_texture_format_list
|
||||
dEQP-VK.memory.pipeline_barrier.host_write_index_buffer.1048576
|
||||
dEQP-VK.memory.zero_initialize_device_memory.image_transition.r8g8_unorm_sampled_shader_frag_512x512_first_mip
|
||||
dEQP-VK.pipeline.monolithic.blend.format.r16g16b16_snorm.states.color_z_1mdc_rsub_alpha_1msa_cc_sub-color_da_1msc_min_alpha_1msc_sc_add-color_sa_sas_add_alpha_z_o_sub-color_dc_1msc_max_alpha_sa_da_sub
|
||||
dEQP-VK.pipeline.monolithic.depth.format.d32_sfloat_s8_uint_separate_layouts.compare_ops.triangle_list_equal_greater_greater_or_equal_not_equal
|
||||
dEQP-VK.pipeline.monolithic.multisample.std_sample_locations.draw.depth.samples_1.separate_renderpass_clear_attachments_same_pattern_secondary_cmd_buf
|
||||
dEQP-VK.pipeline.monolithic.render_to_image.core.1d_array.mipmap.r32g32b32a32_sfloat_d32_sfloat_s8_uint
|
||||
dEQP-VK.pipeline.monolithic.render_to_image.dedicated_allocation.1d.mipmap.r32_uint
|
||||
dEQP-VK.pipeline.monolithic.sampler.border_swizzle.r16g16b16_snorm.1gba.transparent_black.gather_3.no_swizzle_hint
|
||||
dEQP-VK.pipeline.monolithic.sampler.border_swizzle.r32g32b32_uint.rgb1.opaque_white.gather_3.with_swizzle_hint
|
||||
dEQP-VK.pipeline.monolithic.sampler.border_swizzle.r8g8_uint.r1ba.transparent_black.no_gather.no_swizzle_hint
|
||||
dEQP-VK.pipeline.monolithic.sampler.border_swizzle.r8g8b8_uint.r1ba.transparent_black.gather_3.no_swizzle_hint
|
||||
dEQP-VK.pipeline.monolithic.sampler.view_type.2d_array.format.d32_sfloat.address_modes.uvw_mode_mirrored_repeat_mode_repeat_mode_clamp_to_border
|
||||
dEQP-VK.pipeline.monolithic.stencil.format.d24_unorm_s8_uint.states.fail_decc.pass_decc.dfail_zero.comp_always.any
|
||||
dEQP-VK.pipeline.monolithic.stencil.format.d24_unorm_s8_uint.states.fail_zero.pass_keep.dfail_repl.comp_never.any
|
||||
dEQP-VK.pipeline.monolithic.stencil.format.d24_unorm_s8_uint_separate_layouts.states.fail_repl.pass_decw.dfail_zero.comp_greater.any
|
||||
dEQP-VK.pipeline.monolithic.stencil.format.d24_unorm_s8_uint_separate_layouts.states.fail_wrap.pass_incc.dfail_decc.comp_always.any
|
||||
dEQP-VK.pipeline.monolithic.stencil.format.d32_sfloat_s8_uint_separate_layouts.states.fail_decc.pass_keep.dfail_zero.comp_equal.any
|
||||
dEQP-VK.pipeline.monolithic.stencil.format.d32_sfloat_s8_uint_separate_layouts.states.fail_keep.pass_inv.dfail_decc.comp_greater.any
|
||||
dEQP-VK.pipeline.monolithic.stencil.nocolor.format.d24_unorm_s8_uint_separate_layouts.states.fail_incc.pass_wrap.dfail_keep.comp_always.any
|
||||
dEQP-VK.pipeline.monolithic.stencil.nocolor.format.d32_sfloat_s8_uint.states.fail_zero.pass_keep.dfail_inv.comp_less.any
|
||||
dEQP-VK.pipeline.monolithic.vertex_input.multiple_attributes.layout_skip.binding_one_to_one.attributes.uvec2.uvec3.mat2
|
||||
dEQP-VK.renderpasses.dynamic_rendering.primary_cmd_buff.suballocation.unused_clear_attachments.colorunused_colorused_colorunused_colorunused_stencilonly_d32s8_unused
|
||||
dEQP-VK.renderpasses.renderpass2.dedicated_allocation.formats.a2b10g10r10_uint_pack32.input.load.dont_care.clear_draw
|
||||
dEQP-VK.renderpasses.renderpass2.suballocation.attachment_allocation.roll.87
|
||||
dEQP-VK.renderpasses.renderpass2.suballocation.formats.r16_unorm.input.clear.store.self_dep_clear
|
||||
dEQP-VK.synchronization.cross_instance.dedicated.write_clear_attachments_read_copy_image.image_128x128_d32_sfloat_binary_semaphore_dma_buf
|
||||
dEQP-VK.synchronization.cross_instance.suballocated.write_ssbo_compute_read_ssbo_compute.buffer_262144_timeline_semaphore_dma_buf
|
||||
dEQP-VK.synchronization.op.multi_queue.timeline_semaphore.write_image_compute_read_copy_image_to_buffer.image_64x64x8_r32_sfloat_exclusive
|
||||
dEQP-VK.synchronization.op.single_queue.binary_semaphore.write_blit_image_read_image_compute_indirect.image_64x64x8_r32_sfloat
|
||||
dEQP-VK.synchronization.op.single_queue.binary_semaphore.write_image_compute_read_image_compute_indirect.image_128x128_r16g16b16a16_uint
|
||||
dEQP-VK.synchronization.op.single_queue.fence.write_image_compute_read_image_compute_indirect.image_128x128_r32g32b32a32_sfloat
|
||||
dEQP-VK.synchronization.signal_order.binary_semaphore.write_blit_image_read_image_compute_indirect.image_128x128_r8g8b8a8_unorm
|
||||
dEQP-VK.synchronization.signal_order.binary_semaphore.write_image_compute_indirect_read_image_compute.image_64x64x8_r32_sfloat
|
||||
dEQP-VK.synchronization.signal_order.shared_binary_semaphore.write_image_compute_indirect_read_blit_image.image_64x64x8_r32_sfloat_opaque_fd
|
||||
dEQP-VK.synchronization.signal_order.shared_binary_semaphore.write_ssbo_compute_read_ssbo_compute.buffer_262144_opaque_fd
|
||||
dEQP-VK.synchronization.signal_order.shared_timeline_semaphore.write_copy_image_read_image_compute_indirect.image_128x128_r8g8b8a8_unorm_opaque_fd
|
||||
dEQP-VK.synchronization.signal_order.shared_timeline_semaphore.write_image_compute_read_image_compute.image_128x128_r8_unorm_opaque_fd
|
||||
dEQP-VK.synchronization.signal_order.timeline_semaphore.write_image_compute_indirect_read_image_compute_indirect.image_64x64x8_r32_sfloat
|
||||
dEQP-VK.synchronization.timeline_semaphore.device_host.write_copy_image_to_buffer_read_ssbo_compute.buffer_262144
|
||||
dEQP-VK.synchronization.timeline_semaphore.one_to_n.write_image_compute_indirect_read_copy_image_to_buffer.image_64x64x8_r32_sfloat
|
||||
dEQP-VK.texture.filtering.3d.combinations.linear.nearest.clamp_to_edge.clamp_to_border.clamp_to_edge
|
||||
dEQP-VK.texture.filtering.3d.combinations.linear_mipmap_nearest.linear.mirror_clamp_to_edge.mirrored_repeat.clamp_to_edge
|
||||
dEQP-VK.ubo.instance_array_basic_type.std140.column_major_mat4x3.both
|
||||
dEQP-VK.ubo.single_basic_type.std430.mediump.mat3.vertex
|
||||
dEQP-VK.ycbcr.conversion.g8_b8_r8_3plane_420_unorm.color_conversion.ycbcr_2020_itu_full_tiling_optimal_cosited
|
||||
@@ -0,0 +1,7 @@
|
||||
# Timeout
|
||||
dEQP-VK.api.object_management.max_concurrent.compute_pipeline
|
||||
dEQP-VK.api.object_management.max_concurrent.graphics_pipeline
|
||||
dEQP-VK.memory.mapping.dedicated_alloc.buffer.full.variable.implicit_unmap
|
||||
dEQP-VK.memory.mapping.dedicated_alloc.buffer.full.variable.implicit_unmap_map2
|
||||
dEQP-VK.memory.mapping.dedicated_alloc.image.full.variable.implicit_unmap
|
||||
dEQP-VK.memory.mapping.dedicated_alloc.image.full.variable.implicit_unmap_map2
|
||||
@@ -0,0 +1,6 @@
|
||||
# Basic test set
|
||||
[[deqp]]
|
||||
deqp = "/deqp-vk/external/vulkancts/modules/vulkan/deqp-vk"
|
||||
caselists = ["/deqp-vk/mustpass/vk-main.txt"]
|
||||
renderer_check = "PowerVR"
|
||||
tests_per_group = 10000
|
||||
@@ -0,0 +1,59 @@
|
||||
.imagination-rules:
|
||||
stage: imagination
|
||||
rules:
|
||||
- !reference [.test, rules]
|
||||
- !reference [.imagination-farm-rules, rules]
|
||||
- !reference [.vulkan-rules, rules]
|
||||
- changes: &imagination_file_list
|
||||
- src/imagination/*
|
||||
- src/imagination/ci/gitlab-ci.yml
|
||||
- src/imagination/ci/gitlab-ci-inc.yml
|
||||
- src/imagination/ci/deqp-$DEQP_SUITE.toml
|
||||
- src/imagination/ci/$GPU_VERSION-fails.txt
|
||||
- src/imagination/ci/$GPU_VERSION-flakes.txt
|
||||
- src/imagination/ci/$GPU_VERSION-skips.txt
|
||||
- src/imagination/common/**/*
|
||||
- src/imagination/csbgen/**/*
|
||||
- src/imagination/include/**/*
|
||||
- src/imagination/pco/**/*
|
||||
- src/imagination/vulkan/**/*
|
||||
when: on_success
|
||||
|
||||
.imagination-manual-rules:
|
||||
stage: imagination-nightly
|
||||
extends: .no-auto-retry
|
||||
rules:
|
||||
- !reference [.test, rules]
|
||||
- !reference [.imagination-farm-manual-rules, rules]
|
||||
- !reference [.vulkan-manual-rules, rules]
|
||||
- changes:
|
||||
*imagination_file_list
|
||||
when: manual
|
||||
|
||||
.imagination-ci-tron:
|
||||
extends:
|
||||
- .ci-tron-b2c-diskless-v1
|
||||
variables:
|
||||
RUNNER_FARM_LOCATION: imagination
|
||||
CI_TRON_TIMEOUT__FIRST_CONSOLE_ACTIVITY__MINUTES: 0.5
|
||||
CI_TRON_TIMEOUT__FIRST_CONSOLE_ACTIVITY__RETRIES: 3
|
||||
CI_TRON_DUT_SETUP_TAGS: $GPU_VENDOR_TAG,$GPU_MODEL_TAG
|
||||
tags:
|
||||
- ci-tron:priority:$CI_TRON_JOB_PRIORITY
|
||||
- $GPU_VENDOR_TAG
|
||||
- $GPU_MODEL_TAG
|
||||
|
||||
# 12 devices
|
||||
.imagination-ti-am68-sk:arm64:
|
||||
extends:
|
||||
- .imagination-ci-tron
|
||||
parallel: 12
|
||||
variables:
|
||||
B2C_VERSION: v0.9.18
|
||||
CI_TRON_DTB__0__URL: 'https://gitlab.freedesktop.org/gfx-ci/boot2container/-/releases/$B2C_VERSION/downloads/linux-arm64.dtbs.cpio.xz'
|
||||
CI_TRON_DTB__0__FORMAT__0__ARCHIVE__MATCH: boot/dtbs/ti/k3-am68-sk-base-board.dtb
|
||||
CI_TRON__B2C_DISKLESS_IMAGESTORE_PLATFORM: linux/arm64/v8
|
||||
GPU_VENDOR_TAG: dt_gpu:vendor:ti
|
||||
GPU_MODEL_TAG: dt_gpu:model:j721s2-gpu
|
||||
GPU_VERSION: bxs-4-64
|
||||
FDO_CI_CONCURRENT: 3
|
||||
@@ -0,0 +1,15 @@
|
||||
include:
|
||||
- local: 'src/imagination/ci/gitlab-ci-inc.yml'
|
||||
|
||||
bxs-4-64-vk:
|
||||
extends:
|
||||
- .ci-tron-arm64-test-vk
|
||||
- .imagination-ti-am68-sk:arm64
|
||||
- .imagination-manual-rules
|
||||
timeout: 50m
|
||||
variables:
|
||||
CI_TRON_TIMEOUT__OVERALL__MINUTES: 45
|
||||
DEQP_SUITE: pvr-vk
|
||||
VK_DRIVER: powervr_mesa
|
||||
MESA_VK_IGNORE_CONFORMANCE_WARNING: 1
|
||||
PVR_I_WANT_A_BROKEN_VULKAN_DRIVER: 1
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright © 2023 Imagination Technologies Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef AXE_1_16M_H
|
||||
#define AXE_1_16M_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "pvr_device_info.h"
|
||||
|
||||
#define PVR_DEVICE_IDENT_33_V_11_3 \
|
||||
.device_id = 0x33011003, .series_name = "A-Series", \
|
||||
.public_name = "AXE-1-16M", .arch = PVR_DEVICE_ARCH_ROGUE
|
||||
|
||||
|
||||
static const struct pvr_device_features pvr_device_features_33_V_11_3 = {
|
||||
.has_common_store_size_in_dwords = true,
|
||||
.has_compute = true,
|
||||
.has_ipf_creq_pf = true,
|
||||
.has_isp_max_tiles_in_flight = true,
|
||||
.has_isp_samples_per_pixel = true,
|
||||
.has_max_instances_per_pds_task = true,
|
||||
.has_max_multisample = true,
|
||||
.has_max_partitions = true,
|
||||
.has_max_usc_tasks = true,
|
||||
.has_num_clusters = true,
|
||||
.has_num_raster_pipes = true,
|
||||
.has_pbe2_in_xe = true,
|
||||
.has_pbe_filterable_f16 = true,
|
||||
.has_pbe_yuv = true,
|
||||
.has_roguexe = true,
|
||||
.has_screen_size8K = true,
|
||||
.has_simple_internal_parameter_format = true,
|
||||
.has_simple_internal_parameter_format_v2 = true,
|
||||
.has_simple_parameter_format_version = true,
|
||||
.has_slc_cache_line_size_bits = true,
|
||||
.has_tile_size_16x16 = true,
|
||||
.has_tile_size_x = true,
|
||||
.has_tile_size_y = true,
|
||||
.has_tpu_border_colour_enhanced = true,
|
||||
.has_tpu_extended_integer_lookup = true,
|
||||
.has_tpu_image_state_v2 = true,
|
||||
.has_tpu_parallel_instances = true,
|
||||
.has_unified_store_depth = true,
|
||||
.has_usc_f16sop_u8 = true,
|
||||
.has_usc_itr_parallel_instances = true,
|
||||
.has_usc_min_output_registers_per_pix = true,
|
||||
.has_usc_pixel_partition_mask = true,
|
||||
.has_usc_slots = true,
|
||||
.has_uvs_banks = true,
|
||||
.has_uvs_pba_entries = true,
|
||||
.has_uvs_vtx_entries = true,
|
||||
.has_vdm_cam_size = true,
|
||||
.has_vdm_degenerate_culling = true,
|
||||
|
||||
.common_store_size_in_dwords = 512U * 4U * 4U,
|
||||
.isp_max_tiles_in_flight = 1U,
|
||||
.isp_samples_per_pixel = 1U,
|
||||
.max_instances_per_pds_task = 32U,
|
||||
.max_multisample = 4U,
|
||||
.max_partitions = 4U,
|
||||
.max_usc_tasks = 24U,
|
||||
.num_clusters = 1U,
|
||||
.num_raster_pipes = 1U,
|
||||
.simple_parameter_format_version = 2U,
|
||||
.slc_cache_line_size_bits = 512U,
|
||||
.tile_size_x = 16U,
|
||||
.tile_size_y = 16U,
|
||||
.tpu_parallel_instances = 1U,
|
||||
.unified_store_depth = 64U,
|
||||
.usc_itr_parallel_instances = 4U,
|
||||
.usc_min_output_registers_per_pix = 1U,
|
||||
.usc_slots = 14U,
|
||||
.uvs_banks = 2U,
|
||||
.uvs_pba_entries = 320U,
|
||||
.uvs_vtx_entries = 288U,
|
||||
.vdm_cam_size = 32U,
|
||||
|
||||
.has_s8xe = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_enhancements pvr_device_enhancements_33_15_11_3 = {
|
||||
.has_ern35421 = true,
|
||||
.has_ern38748 = true,
|
||||
.has_ern42307 = true,
|
||||
.has_ern45493 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_quirks pvr_device_quirks_33_15_11_3 = {
|
||||
.has_brn70165 = true,
|
||||
.has_brn74056 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_info pvr_device_info_33_15_11_3 = {
|
||||
.ident = {
|
||||
PVR_DEVICE_IDENT_33_V_11_3,
|
||||
.b = 33,
|
||||
.v = 15,
|
||||
.n = 11,
|
||||
.c = 3,
|
||||
},
|
||||
.features = pvr_device_features_33_V_11_3,
|
||||
.enhancements = pvr_device_enhancements_33_15_11_3,
|
||||
.quirks = pvr_device_quirks_33_15_11_3,
|
||||
};
|
||||
|
||||
#endif /* AXE_1_16M_H */
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright © 2025 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef BXE_2_32_H
|
||||
#define BXE_2_32_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "pvr_device_info.h"
|
||||
|
||||
#define PVR_DEVICE_IDENT_36_V_52_182 \
|
||||
.device_id = 0x36052182, .series_name = "B-Series", \
|
||||
.public_name = "BXE-2-32", .arch = PVR_DEVICE_ARCH_ROGUE
|
||||
|
||||
static const struct pvr_device_features pvr_device_features_36_V_52_182 = {
|
||||
.has_astc = true,
|
||||
.has_common_store_size_in_dwords = true,
|
||||
.has_compute = true,
|
||||
.has_compute_overlap = true,
|
||||
.has_fbcdc_algorithm = true,
|
||||
.has_gpu_multicore_support = true,
|
||||
/* .has_gs_rta_support = true, */
|
||||
.has_ipf_creq_pf = true,
|
||||
.has_isp_max_tiles_in_flight = true,
|
||||
.has_isp_samples_per_pixel = true,
|
||||
.has_max_instances_per_pds_task = true,
|
||||
.has_max_multisample = true,
|
||||
.has_max_partitions = true,
|
||||
.has_max_usc_tasks = true,
|
||||
.has_num_clusters = true,
|
||||
.has_num_raster_pipes = true,
|
||||
.has_paired_tiles = true,
|
||||
.has_pbe2_in_xe = true,
|
||||
.has_pbe_filterable_f16 = true,
|
||||
.has_pbe_yuv = true,
|
||||
.has_pds_ddmadt = true,
|
||||
.has_roguexe = true,
|
||||
.has_screen_size8K = true,
|
||||
.has_simple_internal_parameter_format = true,
|
||||
.has_simple_internal_parameter_format_v2 = true,
|
||||
.has_simple_parameter_format_version = true,
|
||||
.has_slc_cache_line_size_bits = true,
|
||||
.has_tile_size_16x16 = true,
|
||||
.has_tile_size_x = true,
|
||||
.has_tile_size_y = true,
|
||||
.has_tpu_border_colour_enhanced = true,
|
||||
.has_tpu_extended_integer_lookup = true,
|
||||
.has_tpu_image_state_v2 = true,
|
||||
.has_tpu_parallel_instances = true,
|
||||
.has_unified_store_depth = true,
|
||||
.has_usc_alu_roundingmode_rne = true,
|
||||
.has_usc_f16sop_u8 = true,
|
||||
.has_usc_itrsmp = true,
|
||||
.has_usc_itrsmp_enhanced = true,
|
||||
.has_usc_itr_parallel_instances = true,
|
||||
|
||||
.has_usc_min_output_registers_per_pix = true,
|
||||
.has_usc_pixel_partition_mask = true,
|
||||
.has_usc_slots = true,
|
||||
.has_uvs_banks = true,
|
||||
.has_uvs_pba_entries = true,
|
||||
.has_uvs_vtx_entries = true,
|
||||
.has_vdm_cam_size = true,
|
||||
.has_xpu_max_slaves = true,
|
||||
|
||||
.common_store_size_in_dwords = 832U * 4U * 4U,
|
||||
.fbcdc_algorithm = 50U,
|
||||
.isp_max_tiles_in_flight = 2U,
|
||||
.isp_samples_per_pixel = 1U,
|
||||
.max_instances_per_pds_task = 32U,
|
||||
.max_multisample = 4U,
|
||||
.max_partitions = 8U,
|
||||
.max_usc_tasks = 72U,
|
||||
.num_clusters = 1U,
|
||||
.num_raster_pipes = 1U,
|
||||
.simple_parameter_format_version = 2U,
|
||||
.slc_cache_line_size_bits = 512U,
|
||||
.tile_size_x = 16U,
|
||||
.tile_size_y = 16U,
|
||||
.tpu_parallel_instances = 2U,
|
||||
.unified_store_depth = 128U,
|
||||
.usc_itr_parallel_instances = 8U,
|
||||
.usc_min_output_registers_per_pix = 2U,
|
||||
.usc_slots = 32U,
|
||||
.uvs_banks = 4U,
|
||||
.uvs_pba_entries = 320U,
|
||||
.uvs_vtx_entries = 288U,
|
||||
.vdm_cam_size = 64U,
|
||||
.xpu_max_slaves = 3U,
|
||||
|
||||
.has_s8xe = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_enhancements
|
||||
pvr_device_enhancements_36_29_52_182 = {
|
||||
.has_ern35421 = true,
|
||||
.has_ern38748 = true,
|
||||
.has_ern42307 = true,
|
||||
.has_ern45493 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_quirks pvr_device_quirks_36_29_52_182 = {
|
||||
.has_brn70165 = true,
|
||||
.has_brn72168 = true,
|
||||
.has_brn72463 = true,
|
||||
.has_brn74056 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_info pvr_device_info_36_29_52_182 = {
|
||||
.ident = {
|
||||
PVR_DEVICE_IDENT_36_V_52_182,
|
||||
.b = 36,
|
||||
.v = 29,
|
||||
.n = 52,
|
||||
.c = 182,
|
||||
},
|
||||
.features = pvr_device_features_36_V_52_182,
|
||||
.enhancements = pvr_device_enhancements_36_29_52_182,
|
||||
.quirks = pvr_device_quirks_36_29_52_182,
|
||||
};
|
||||
|
||||
#endif /* BXE_2_32_H */
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright © 2025 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef BXE_4_32_H
|
||||
#define BXE_4_32_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "pvr_device_info.h"
|
||||
|
||||
#define PVR_DEVICE_IDENT_36_V_54_182 \
|
||||
.device_id = 0x36054182, .series_name = "B-Series", \
|
||||
.public_name = "BXE-4-32", .arch = PVR_DEVICE_ARCH_ROGUE
|
||||
|
||||
static const struct pvr_device_features pvr_device_features_36_V_54_182 = {
|
||||
.has_astc = true,
|
||||
.has_common_store_size_in_dwords = true,
|
||||
.has_compute = true,
|
||||
.has_compute_overlap = true,
|
||||
.has_fbcdc_algorithm = true,
|
||||
.has_gpu_multicore_support = true,
|
||||
/* .has_gs_rta_support = true, */
|
||||
.has_ipf_creq_pf = true,
|
||||
.has_isp_max_tiles_in_flight = true,
|
||||
.has_isp_samples_per_pixel = true,
|
||||
.has_max_instances_per_pds_task = true,
|
||||
.has_max_multisample = true,
|
||||
.has_max_partitions = true,
|
||||
.has_max_usc_tasks = true,
|
||||
.has_num_clusters = true,
|
||||
.has_num_raster_pipes = true,
|
||||
.has_paired_tiles = true,
|
||||
.has_pbe2_in_xe = true,
|
||||
.has_pbe_filterable_f16 = true,
|
||||
.has_pbe_yuv = true,
|
||||
.has_pds_ddmadt = true,
|
||||
.has_roguexe = true,
|
||||
.has_screen_size8K = true,
|
||||
.has_simple_internal_parameter_format = true,
|
||||
.has_simple_internal_parameter_format_v2 = true,
|
||||
.has_simple_parameter_format_version = true,
|
||||
.has_slc_cache_line_size_bits = true,
|
||||
.has_tile_size_16x16 = true,
|
||||
.has_tile_size_x = true,
|
||||
.has_tile_size_y = true,
|
||||
.has_tpu_border_colour_enhanced = true,
|
||||
.has_tpu_dm_global_registers = true,
|
||||
.has_tpu_extended_integer_lookup = true,
|
||||
.has_tpu_image_state_v2 = true,
|
||||
.has_tpu_parallel_instances = true,
|
||||
.has_unified_store_depth = true,
|
||||
.has_usc_alu_roundingmode_rne = true,
|
||||
.has_usc_itrsmp = true,
|
||||
.has_usc_itrsmp_enhanced = true,
|
||||
.has_usc_f16sop_u8 = true,
|
||||
.has_usc_itr_parallel_instances = true,
|
||||
.has_usc_min_output_registers_per_pix = true,
|
||||
.has_usc_pixel_partition_mask = true,
|
||||
.has_usc_slots = true,
|
||||
.has_uvs_banks = true,
|
||||
.has_uvs_pba_entries = true,
|
||||
.has_uvs_vtx_entries = true,
|
||||
.has_vdm_cam_size = true,
|
||||
.has_xpu_max_slaves = true,
|
||||
|
||||
.common_store_size_in_dwords = 1024U * 4U * 4U,
|
||||
.fbcdc_algorithm = 50U,
|
||||
.isp_max_tiles_in_flight = 4U,
|
||||
.isp_samples_per_pixel = 1U,
|
||||
.max_instances_per_pds_task = 32U,
|
||||
.max_multisample = 4U,
|
||||
.max_partitions = 10U,
|
||||
.max_usc_tasks = 104U,
|
||||
.num_clusters = 1U,
|
||||
.num_raster_pipes = 1U,
|
||||
.simple_parameter_format_version = 2U,
|
||||
.slc_cache_line_size_bits = 512U,
|
||||
.tile_size_x = 16U,
|
||||
.tile_size_y = 16U,
|
||||
.tpu_parallel_instances = 4U,
|
||||
.unified_store_depth = 208U,
|
||||
.usc_itr_parallel_instances = 16U,
|
||||
.usc_min_output_registers_per_pix = 2U,
|
||||
.usc_slots = 64U,
|
||||
.uvs_banks = 8U,
|
||||
.uvs_pba_entries = 160U,
|
||||
.uvs_vtx_entries = 144U,
|
||||
.vdm_cam_size = 64U,
|
||||
.xpu_max_slaves = 3U,
|
||||
|
||||
.has_s8xe = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_enhancements
|
||||
pvr_device_enhancements_36_50_54_182 = {
|
||||
.has_ern35421 = true,
|
||||
.has_ern38748 = true,
|
||||
.has_ern42307 = true,
|
||||
.has_ern45493 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_quirks pvr_device_quirks_36_50_54_182 = {
|
||||
.has_brn70165 = true,
|
||||
.has_brn72168 = true,
|
||||
.has_brn72463 = true,
|
||||
.has_brn74056 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_info pvr_device_info_36_50_54_182 = {
|
||||
.ident = {
|
||||
PVR_DEVICE_IDENT_36_V_54_182,
|
||||
.b = 36,
|
||||
.v = 50,
|
||||
.n = 54,
|
||||
.c = 182,
|
||||
},
|
||||
.features = pvr_device_features_36_V_54_182,
|
||||
.enhancements = pvr_device_enhancements_36_50_54_182,
|
||||
.quirks = pvr_device_quirks_36_50_54_182,
|
||||
};
|
||||
|
||||
#endif /* BXE_4_32_H */
|
||||
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Copyright © 2025 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef BXM_4_64_H
|
||||
#define BXM_4_64_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "pvr_device_info.h"
|
||||
|
||||
#define PVR_DEVICE_IDENT_36_V_104_182 \
|
||||
.device_id = 0x36104182, .series_name = "B-Series", \
|
||||
.public_name = "BXM-4-64", .arch = PVR_DEVICE_ARCH_ROGUE
|
||||
|
||||
static const struct pvr_device_features pvr_device_features_36_V_104_182 = {
|
||||
.has_astc = true,
|
||||
.has_common_store_size_in_dwords = true,
|
||||
.has_compute = true,
|
||||
.has_compute_overlap = true,
|
||||
.has_fbcdc_algorithm = true,
|
||||
.has_gpu_multicore_support = true,
|
||||
/* .has_gs_rta_support = true, */
|
||||
.has_ipf_creq_pf = true,
|
||||
.has_isp_max_tiles_in_flight = true,
|
||||
.has_isp_samples_per_pixel = true,
|
||||
.has_max_instances_per_pds_task = true,
|
||||
.has_max_multisample = true,
|
||||
.has_max_partitions = true,
|
||||
.has_max_usc_tasks = true,
|
||||
.has_num_clusters = true,
|
||||
.has_num_raster_pipes = true,
|
||||
.has_paired_tiles = true,
|
||||
.has_pbe2_in_xe = true,
|
||||
.has_pbe_filterable_f16 = true,
|
||||
.has_pbe_yuv = true,
|
||||
.has_pds_ddmadt = true,
|
||||
.has_roguexe = true,
|
||||
.has_screen_size8K = true,
|
||||
.has_simple_internal_parameter_format = true,
|
||||
.has_simple_internal_parameter_format_v2 = true,
|
||||
.has_simple_parameter_format_version = true,
|
||||
.has_slc_cache_line_size_bits = true,
|
||||
.has_tile_size_16x16 = true,
|
||||
.has_tile_size_x = true,
|
||||
.has_tile_size_y = true,
|
||||
.has_tpu_border_colour_enhanced = true,
|
||||
.has_tpu_dm_global_registers = true,
|
||||
.has_tpu_extended_integer_lookup = true,
|
||||
.has_tpu_image_state_v2 = true,
|
||||
.has_tpu_parallel_instances = true,
|
||||
.has_unified_store_depth = true,
|
||||
.has_usc_alu_roundingmode_rne = true,
|
||||
.has_usc_f16sop_u8 = true,
|
||||
.has_usc_itrsmp = true,
|
||||
.has_usc_itrsmp_enhanced = true,
|
||||
.has_usc_itr_parallel_instances = true,
|
||||
.has_usc_min_output_registers_per_pix = true,
|
||||
.has_usc_pixel_partition_mask = true,
|
||||
.has_usc_slots = true,
|
||||
.has_uvs_banks = true,
|
||||
.has_uvs_pba_entries = true,
|
||||
.has_uvs_vtx_entries = true,
|
||||
.has_vdm_cam_size = true,
|
||||
.has_xpu_max_slaves = true,
|
||||
|
||||
.common_store_size_in_dwords = 1216U * 4U * 4U,
|
||||
.fbcdc_algorithm = 50U,
|
||||
.isp_max_tiles_in_flight = 6U,
|
||||
.isp_samples_per_pixel = 1U,
|
||||
.max_instances_per_pds_task = 32U,
|
||||
.max_multisample = 4U,
|
||||
.max_partitions = 12U,
|
||||
.max_usc_tasks = 156U,
|
||||
.num_clusters = 1U,
|
||||
.num_raster_pipes = 1U,
|
||||
.simple_parameter_format_version = 2U,
|
||||
.slc_cache_line_size_bits = 512U,
|
||||
.tile_size_x = 16U,
|
||||
.tile_size_y = 16U,
|
||||
.tpu_parallel_instances = 4U,
|
||||
.unified_store_depth = 256U,
|
||||
.usc_itr_parallel_instances = 16U,
|
||||
.usc_min_output_registers_per_pix = 2U,
|
||||
.usc_slots = 64U,
|
||||
.uvs_banks = 8U,
|
||||
.uvs_pba_entries = 160U,
|
||||
.uvs_vtx_entries = 144U,
|
||||
.vdm_cam_size = 64U,
|
||||
.xpu_max_slaves = 3U,
|
||||
|
||||
/* Derived features. */
|
||||
.has_s8xe = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_enhancements
|
||||
pvr_device_enhancements_36_52_104_182 = {
|
||||
.has_ern35421 = true,
|
||||
.has_ern38748 = true,
|
||||
.has_ern42307 = true,
|
||||
.has_ern45493 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_quirks pvr_device_quirks_36_52_104_182 = {
|
||||
.has_brn44079 = true,
|
||||
.has_brn70165 = true,
|
||||
.has_brn72168 = true,
|
||||
.has_brn72463 = true,
|
||||
.has_brn74056 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_info pvr_device_info_36_52_104_182 = {
|
||||
.ident = {
|
||||
PVR_DEVICE_IDENT_36_V_104_182,
|
||||
.b = 36,
|
||||
.v = 52,
|
||||
.n = 104,
|
||||
.c = 182,
|
||||
},
|
||||
.features = pvr_device_features_36_V_104_182,
|
||||
.enhancements = pvr_device_enhancements_36_52_104_182,
|
||||
.quirks = pvr_device_quirks_36_52_104_182,
|
||||
};
|
||||
|
||||
#define PVR_DEVICE_IDENT_36_V_104_183 \
|
||||
.device_id = 0x36104183, .series_name = "B-Series", .public_name = "BXM-4-64"
|
||||
|
||||
static const struct pvr_device_features pvr_device_features_36_V_104_183 = {
|
||||
.has_astc = true,
|
||||
.has_common_store_size_in_dwords = true,
|
||||
.has_compute = true,
|
||||
.has_compute_overlap = true,
|
||||
.has_fbcdc_algorithm = true,
|
||||
.has_gpu_multicore_support = true,
|
||||
/* .has_gs_rta_support = true, */
|
||||
.has_ipf_creq_pf = true,
|
||||
.has_isp_max_tiles_in_flight = true,
|
||||
.has_isp_samples_per_pixel = true,
|
||||
.has_max_instances_per_pds_task = true,
|
||||
.has_max_multisample = true,
|
||||
.has_max_partitions = true,
|
||||
.has_max_usc_tasks = true,
|
||||
.has_num_clusters = true,
|
||||
.has_num_raster_pipes = true,
|
||||
.has_paired_tiles = true,
|
||||
.has_pbe2_in_xe = true,
|
||||
.has_pbe_filterable_f16 = true,
|
||||
.has_pbe_yuv = true,
|
||||
.has_pds_ddmadt = true,
|
||||
.has_roguexe = true,
|
||||
.has_screen_size8K = true,
|
||||
.has_simple_internal_parameter_format = true,
|
||||
.has_simple_internal_parameter_format_v2 = true,
|
||||
.has_simple_parameter_format_version = true,
|
||||
.has_slc_cache_line_size_bits = true,
|
||||
.has_tile_size_16x16 = true,
|
||||
.has_tile_size_x = true,
|
||||
.has_tile_size_y = true,
|
||||
.has_tpu_border_colour_enhanced = true,
|
||||
.has_tpu_dm_global_registers = true,
|
||||
.has_tpu_extended_integer_lookup = true,
|
||||
.has_tpu_image_state_v2 = true,
|
||||
.has_tpu_parallel_instances = true,
|
||||
.has_unified_store_depth = true,
|
||||
.has_usc_alu_roundingmode_rne = true,
|
||||
.has_usc_f16sop_u8 = true,
|
||||
.has_usc_itrsmp = true,
|
||||
.has_usc_itrsmp_enhanced = true,
|
||||
.has_usc_min_output_registers_per_pix = true,
|
||||
.has_usc_pixel_partition_mask = true,
|
||||
.has_usc_slots = true,
|
||||
.has_uvs_banks = true,
|
||||
.has_uvs_pba_entries = true,
|
||||
.has_uvs_vtx_entries = true,
|
||||
.has_vdm_cam_size = true,
|
||||
.has_xpu_max_slaves = true,
|
||||
|
||||
.common_store_size_in_dwords = 1216U * 4U * 4U,
|
||||
.fbcdc_algorithm = 50U,
|
||||
.isp_max_tiles_in_flight = 6U,
|
||||
.isp_samples_per_pixel = 1U,
|
||||
.max_instances_per_pds_task = 32U,
|
||||
.max_multisample = 4U,
|
||||
.max_partitions = 12U,
|
||||
.max_usc_tasks = 156U,
|
||||
.num_clusters = 1U,
|
||||
.num_raster_pipes = 1U,
|
||||
.simple_parameter_format_version = 2U,
|
||||
.slc_cache_line_size_bits = 512U,
|
||||
.tile_size_x = 16U,
|
||||
.tile_size_y = 16U,
|
||||
.tpu_parallel_instances = 4U,
|
||||
.unified_store_depth = 256U,
|
||||
.usc_min_output_registers_per_pix = 2U,
|
||||
.usc_slots = 64U,
|
||||
.uvs_banks = 8U,
|
||||
.uvs_pba_entries = 160U,
|
||||
.uvs_vtx_entries = 144U,
|
||||
.vdm_cam_size = 64U,
|
||||
.xpu_max_slaves = 3U,
|
||||
|
||||
/* Derived features. */
|
||||
.has_s8xe = true,
|
||||
.has_usc_itr_parallel_instances = true,
|
||||
|
||||
.usc_itr_parallel_instances = 16U,
|
||||
};
|
||||
|
||||
static const struct pvr_device_enhancements
|
||||
pvr_device_enhancements_36_56_104_183 = {
|
||||
.has_ern35421 = true,
|
||||
.has_ern38748 = true,
|
||||
.has_ern42307 = true,
|
||||
.has_ern45493 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_quirks pvr_device_quirks_36_56_104_183 = {
|
||||
.has_brn44079 = true,
|
||||
.has_brn70165 = true,
|
||||
.has_brn72168 = true,
|
||||
.has_brn72463 = true,
|
||||
.has_brn74056 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_info pvr_device_info_36_56_104_183 = {
|
||||
.ident = {
|
||||
PVR_DEVICE_IDENT_36_V_104_183,
|
||||
.b = 36,
|
||||
.v = 56,
|
||||
.n = 104,
|
||||
.c = 183,
|
||||
},
|
||||
.features = pvr_device_features_36_V_104_183,
|
||||
.enhancements = pvr_device_enhancements_36_56_104_183,
|
||||
.quirks = pvr_device_quirks_36_56_104_183,
|
||||
};
|
||||
|
||||
#endif /* BXM_4_64_H */
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright © 2023 Imagination Technologies Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef BXS_4_64_H
|
||||
#define BXS_4_64_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "pvr_device_info.h"
|
||||
|
||||
#define PVR_DEVICE_IDENT_36_V_104_796 \
|
||||
.device_id = 0x36104796, .series_name = "B-Series", \
|
||||
.public_name = "BXS-4-64", .arch = PVR_DEVICE_ARCH_ROGUE
|
||||
|
||||
static const struct pvr_device_features pvr_device_features_36_V_104_796 = {
|
||||
.has_astc = true,
|
||||
.has_common_store_size_in_dwords = true,
|
||||
.has_compute = true,
|
||||
.has_compute_overlap = true,
|
||||
.has_fbcdc_algorithm = true,
|
||||
.has_gpu_multicore_support = true,
|
||||
/* .has_gs_rta_support = true, */
|
||||
.has_ipf_creq_pf = true,
|
||||
.has_isp_max_tiles_in_flight = true,
|
||||
.has_isp_samples_per_pixel = true,
|
||||
.has_max_instances_per_pds_task = true,
|
||||
.has_max_multisample = true,
|
||||
.has_max_partitions = true,
|
||||
.has_max_usc_tasks = true,
|
||||
.has_num_clusters = true,
|
||||
.has_num_raster_pipes = true,
|
||||
.has_paired_tiles = true,
|
||||
.has_pbe2_in_xe = true,
|
||||
.has_pbe_filterable_f16 = true,
|
||||
.has_pbe_yuv = true,
|
||||
.has_pds_ddmadt = true,
|
||||
.has_roguexe = true,
|
||||
.has_screen_size8K = true,
|
||||
.has_simple_internal_parameter_format = true,
|
||||
.has_simple_internal_parameter_format_v2 = true,
|
||||
.has_simple_parameter_format_version = true,
|
||||
.has_slc_cache_line_size_bits = true,
|
||||
.has_tile_size_16x16 = true,
|
||||
.has_tile_size_x = true,
|
||||
.has_tile_size_y = true,
|
||||
.has_tpu_border_colour_enhanced = true,
|
||||
.has_tpu_dm_global_registers = true,
|
||||
.has_tpu_extended_integer_lookup = true,
|
||||
.has_tpu_image_state_v2 = true,
|
||||
.has_tpu_parallel_instances = true,
|
||||
.has_unified_store_depth = true,
|
||||
.has_usc_alu_roundingmode_rne = true,
|
||||
.has_usc_f16sop_u8 = true,
|
||||
.has_usc_itrsmp = true,
|
||||
.has_usc_itrsmp_enhanced = true,
|
||||
.has_usc_itr_parallel_instances = true,
|
||||
.has_usc_min_output_registers_per_pix = true,
|
||||
.has_usc_pixel_partition_mask = true,
|
||||
.has_usc_slots = true,
|
||||
.has_uvs_banks = true,
|
||||
.has_uvs_pba_entries = true,
|
||||
.has_uvs_vtx_entries = true,
|
||||
.has_vdm_cam_size = true,
|
||||
.has_vdm_degenerate_culling = true,
|
||||
.has_xpu_max_slaves = true,
|
||||
|
||||
.common_store_size_in_dwords = 1344U * 4U * 4U,
|
||||
.fbcdc_algorithm = 50U,
|
||||
.isp_max_tiles_in_flight = 6U,
|
||||
.isp_samples_per_pixel = 4U,
|
||||
.max_instances_per_pds_task = 32U,
|
||||
.max_multisample = 4U,
|
||||
.max_partitions = 16U,
|
||||
.max_usc_tasks = 156U,
|
||||
.num_clusters = 1U,
|
||||
.num_raster_pipes = 1U,
|
||||
.simple_parameter_format_version = 2U,
|
||||
.slc_cache_line_size_bits = 512U,
|
||||
.tile_size_x = 16U,
|
||||
.tile_size_y = 16U,
|
||||
.tpu_parallel_instances = 4U,
|
||||
.unified_store_depth = 256U,
|
||||
.usc_itr_parallel_instances = 16U,
|
||||
.usc_min_output_registers_per_pix = 2U,
|
||||
.usc_slots = 64U,
|
||||
.uvs_banks = 8U,
|
||||
.uvs_pba_entries = 160U,
|
||||
.uvs_vtx_entries = 144U,
|
||||
.vdm_cam_size = 64U,
|
||||
.xpu_max_slaves = 3U,
|
||||
|
||||
.has_s8xe = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_enhancements
|
||||
pvr_device_enhancements_36_53_104_796 = {
|
||||
.has_ern35421 = true,
|
||||
.has_ern38748 = true,
|
||||
.has_ern42307 = true,
|
||||
.has_ern45493 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_quirks pvr_device_quirks_36_53_104_796 = {
|
||||
.has_brn44079 = true,
|
||||
.has_brn70165 = true,
|
||||
.has_brn72168 = true,
|
||||
.has_brn72463 = true,
|
||||
.has_brn74056 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_info pvr_device_info_36_53_104_796 = {
|
||||
.ident = {
|
||||
PVR_DEVICE_IDENT_36_V_104_796,
|
||||
.b = 36,
|
||||
.v = 53,
|
||||
.n = 104,
|
||||
.c = 796,
|
||||
},
|
||||
.features = pvr_device_features_36_V_104_796,
|
||||
.enhancements = pvr_device_enhancements_36_53_104_796,
|
||||
.quirks = pvr_device_quirks_36_53_104_796,
|
||||
};
|
||||
|
||||
#endif /* BXS_4_64_H */
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright © 2025 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef G6110_H
|
||||
#define G6110_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "pvr_device_info.h"
|
||||
|
||||
#define PVR_DEVICE_IDENT_5_V_1_46 \
|
||||
.device_id = 0x6110, .series_name = "Rogue", \
|
||||
.public_name = "GX6110", .arch = PVR_DEVICE_ARCH_ROGUE
|
||||
|
||||
static const struct pvr_device_features pvr_device_features_5_V_1_46 = {
|
||||
.has_common_store_size_in_dwords = true,
|
||||
.has_compute = true,
|
||||
.has_fbcdc_algorithm = true,
|
||||
/* .has_gs_rta_support = true, */
|
||||
.has_isp_max_tiles_in_flight = true,
|
||||
.has_isp_samples_per_pixel = true,
|
||||
.has_max_instances_per_pds_task = true,
|
||||
.has_max_multisample = true,
|
||||
.has_max_partitions = true,
|
||||
.has_max_usc_tasks = true,
|
||||
.has_num_clusters = true,
|
||||
.has_num_raster_pipes = true,
|
||||
.has_pbe_filterable_f16 = true,
|
||||
.has_roguexe = true,
|
||||
.has_slc_cache_line_size_bits = true,
|
||||
.has_tile_size_x = true,
|
||||
.has_tile_size_y = true,
|
||||
.has_tpu_parallel_instances = true,
|
||||
.has_unified_store_depth = true,
|
||||
.has_usc_itr_parallel_instances = true,
|
||||
.has_usc_min_output_registers_per_pix = true,
|
||||
.has_usc_slots = true,
|
||||
.has_uvs_banks = true,
|
||||
.has_uvs_pba_entries = true,
|
||||
.has_uvs_vtx_entries = true,
|
||||
.has_vdm_cam_size = true,
|
||||
|
||||
.common_store_size_in_dwords = 1344U * 4U * 4U,
|
||||
.fbcdc_algorithm = 2U,
|
||||
.isp_max_tiles_in_flight = 1U,
|
||||
.isp_samples_per_pixel = 2U,
|
||||
.max_instances_per_pds_task = 32U,
|
||||
.max_multisample = 4U,
|
||||
.max_partitions = 12U,
|
||||
.max_usc_tasks = 96U,
|
||||
.num_clusters = 1U,
|
||||
.num_raster_pipes = 1U,
|
||||
.slc_cache_line_size_bits = 512U,
|
||||
.tile_size_x = 32U,
|
||||
.tile_size_y = 32U,
|
||||
.tpu_parallel_instances = 4U,
|
||||
.unified_store_depth = 208U,
|
||||
.usc_itr_parallel_instances = 16U,
|
||||
.usc_min_output_registers_per_pix = 2U,
|
||||
.usc_slots = 56U,
|
||||
.uvs_banks = 8U,
|
||||
.uvs_pba_entries = 160U,
|
||||
.uvs_vtx_entries = 144U,
|
||||
.vdm_cam_size = 64U,
|
||||
|
||||
.has_requires_fb_cdc_zls_setup = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_enhancements pvr_device_enhancements_5_9_1_46 = {
|
||||
.has_ern35421 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_quirks pvr_device_quirks_5_9_1_46 = {
|
||||
.has_brn44079 = true,
|
||||
.has_brn47727 = true,
|
||||
.has_brn48492 = true,
|
||||
.has_brn48545 = true,
|
||||
.has_brn49032 = true,
|
||||
.has_brn49927 = true,
|
||||
.has_brn51025 = true,
|
||||
.has_brn51210 = true,
|
||||
.has_brn52942 = true,
|
||||
.has_brn58839 = true,
|
||||
.has_brn62269 = true,
|
||||
.has_brn66011 = true,
|
||||
.has_brn70165 = true,
|
||||
.has_brn74056 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_info pvr_device_info_5_9_1_46 = {
|
||||
.ident = {
|
||||
PVR_DEVICE_IDENT_5_V_1_46,
|
||||
.b = 5,
|
||||
.v = 9,
|
||||
.n = 1,
|
||||
.c = 46,
|
||||
},
|
||||
.features = pvr_device_features_5_V_1_46,
|
||||
.enhancements = pvr_device_enhancements_5_9_1_46,
|
||||
.quirks = pvr_device_quirks_5_9_1_46,
|
||||
};
|
||||
|
||||
#endif /* G6110_H */
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright © 2025 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef GE7800_H
|
||||
#define GE7800_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "pvr_device_info.h"
|
||||
|
||||
#define PVR_DEVICE_IDENT_15_V_1_64 \
|
||||
.device_id = 0x15001064, .series_name = "Rogue", \
|
||||
.public_name = "GE7800", .arch = PVR_DEVICE_ARCH_ROGUE
|
||||
|
||||
static const struct pvr_device_features pvr_device_features_15_V_1_64 = {
|
||||
.has_astc = true,
|
||||
.has_common_store_size_in_dwords = true,
|
||||
.has_compute = true,
|
||||
.has_fbcdc_algorithm = true,
|
||||
/* .has_gs_rta_support = true, */
|
||||
.has_isp_max_tiles_in_flight = true,
|
||||
.has_isp_samples_per_pixel = true,
|
||||
.has_max_instances_per_pds_task = true,
|
||||
.has_max_multisample = true,
|
||||
.has_max_partitions = true,
|
||||
.has_max_usc_tasks = true,
|
||||
.has_num_clusters = true,
|
||||
.has_num_raster_pipes = true,
|
||||
.has_pbe_filterable_f16 = true,
|
||||
.has_roguexe = true,
|
||||
.has_slc_cache_line_size_bits = true,
|
||||
.has_tile_size_x = true,
|
||||
.has_tile_size_y = true,
|
||||
.has_tpu_parallel_instances = true,
|
||||
.has_unified_store_depth = true,
|
||||
.has_usc_f16sop_u8 = true,
|
||||
.has_usc_itr_parallel_instances = true,
|
||||
.has_usc_min_output_registers_per_pix = true,
|
||||
.has_usc_slots = true,
|
||||
.has_uvs_banks = true,
|
||||
.has_uvs_pba_entries = true,
|
||||
.has_uvs_vtx_entries = true,
|
||||
.has_vdm_cam_size = true,
|
||||
|
||||
.common_store_size_in_dwords = 1344U * 4U * 4U,
|
||||
.fbcdc_algorithm = 2U,
|
||||
.isp_max_tiles_in_flight = 2U,
|
||||
.isp_samples_per_pixel = 2U,
|
||||
.max_instances_per_pds_task = 32U,
|
||||
.max_multisample = 4U,
|
||||
.max_partitions = 12U,
|
||||
.max_usc_tasks = 96U,
|
||||
.num_clusters = 1U,
|
||||
.num_raster_pipes = 1U,
|
||||
.slc_cache_line_size_bits = 512U,
|
||||
.tile_size_x = 32U,
|
||||
.tile_size_y = 32U,
|
||||
.tpu_parallel_instances = 4U,
|
||||
.unified_store_depth = 208U,
|
||||
.usc_itr_parallel_instances = 16U,
|
||||
.usc_min_output_registers_per_pix = 2U,
|
||||
.usc_slots = 56U,
|
||||
.uvs_banks = 8U,
|
||||
.uvs_pba_entries = 320U,
|
||||
.uvs_vtx_entries = 288U,
|
||||
.vdm_cam_size = 128U,
|
||||
|
||||
.has_requires_fb_cdc_zls_setup = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_enhancements
|
||||
pvr_device_enhancements_15_5_1_64 = {
|
||||
.has_ern35421 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_quirks pvr_device_quirks_15_5_1_64 = {
|
||||
.has_brn44079 = true,
|
||||
.has_brn48492 = true,
|
||||
.has_brn49032 = true,
|
||||
.has_brn49927 = true,
|
||||
.has_brn52942 = true,
|
||||
.has_brn58839 = true,
|
||||
.has_brn62269 = true,
|
||||
.has_brn66011 = true,
|
||||
.has_brn70165 = true,
|
||||
.has_brn74056 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_info pvr_device_info_15_5_1_64 = {
|
||||
.ident = {
|
||||
PVR_DEVICE_IDENT_15_V_1_64,
|
||||
.b = 15,
|
||||
.v = 5,
|
||||
.n = 1,
|
||||
.c = 64,
|
||||
},
|
||||
.features = pvr_device_features_15_V_1_64,
|
||||
.enhancements = pvr_device_enhancements_15_5_1_64,
|
||||
.quirks = pvr_device_quirks_15_5_1_64,
|
||||
};
|
||||
|
||||
#endif /* GE7800_H */
|
||||
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright © 2025 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef GE8300_H
|
||||
#define GE8300_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "pvr_device_info.h"
|
||||
|
||||
#define PVR_DEVICE_IDENT_22_V_54_30 \
|
||||
.device_id = 0x22054030, .series_name = "Rogue", \
|
||||
.public_name = "GE8300", .arch = PVR_DEVICE_ARCH_ROGUE
|
||||
|
||||
static const struct pvr_device_features pvr_device_features_22_V_54_30 = {
|
||||
.has_astc = true,
|
||||
.has_common_store_size_in_dwords = true,
|
||||
.has_compute = true,
|
||||
.has_compute_overlap = true,
|
||||
/* .has_gs_rta_support = true, */
|
||||
.has_ipf_creq_pf = true,
|
||||
.has_isp_max_tiles_in_flight = true,
|
||||
.has_isp_samples_per_pixel = true,
|
||||
.has_max_instances_per_pds_task = true,
|
||||
.has_max_multisample = true,
|
||||
.has_max_partitions = true,
|
||||
.has_max_usc_tasks = true,
|
||||
.has_num_clusters = true,
|
||||
.has_num_raster_pipes = true,
|
||||
.has_pbe2_in_xe = true,
|
||||
.has_pbe_filterable_f16 = true,
|
||||
.has_pbe_yuv = true,
|
||||
.has_roguexe = true,
|
||||
.has_simple_internal_parameter_format = true,
|
||||
.has_simple_internal_parameter_format_v1 = true,
|
||||
.has_simple_parameter_format_version = true,
|
||||
.has_slc_cache_line_size_bits = true,
|
||||
.has_tile_size_16x16 = true,
|
||||
.has_tile_size_x = true,
|
||||
.has_tile_size_y = true,
|
||||
.has_tpu_parallel_instances = true,
|
||||
.has_unified_store_depth = true,
|
||||
.has_usc_f16sop_u8 = true,
|
||||
.has_usc_itrsmp = true,
|
||||
.has_usc_itrsmp_enhanced = true,
|
||||
.has_usc_itr_parallel_instances = true,
|
||||
.has_usc_min_output_registers_per_pix = true,
|
||||
.has_usc_slots = true,
|
||||
.has_uvs_banks = true,
|
||||
.has_uvs_pba_entries = true,
|
||||
.has_uvs_vtx_entries = true,
|
||||
.has_vdm_cam_size = true,
|
||||
|
||||
.common_store_size_in_dwords = 1024U * 4U * 4U,
|
||||
.isp_max_tiles_in_flight = 4U,
|
||||
.isp_samples_per_pixel = 1U,
|
||||
.max_instances_per_pds_task = 32U,
|
||||
.max_multisample = 4U,
|
||||
.max_partitions = 10U,
|
||||
.max_usc_tasks = 104U,
|
||||
.num_clusters = 1U,
|
||||
.num_raster_pipes = 1U,
|
||||
.simple_parameter_format_version = 1U,
|
||||
.slc_cache_line_size_bits = 512U,
|
||||
.tile_size_x = 16U,
|
||||
.tile_size_y = 16U,
|
||||
.tpu_parallel_instances = 4U,
|
||||
.unified_store_depth = 208U,
|
||||
.usc_itr_parallel_instances = 16U,
|
||||
.usc_min_output_registers_per_pix = 2U,
|
||||
.usc_slots = 64U,
|
||||
.uvs_banks = 4U,
|
||||
.uvs_pba_entries = 320U,
|
||||
.uvs_vtx_entries = 288U,
|
||||
.vdm_cam_size = 64U,
|
||||
|
||||
.has_s8xe = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_enhancements
|
||||
pvr_device_enhancements_22_67_54_30 = {
|
||||
.has_ern35421 = true,
|
||||
.has_ern38748 = true,
|
||||
.has_ern42307 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_quirks pvr_device_quirks_22_67_54_30 = {
|
||||
.has_brn49927 = true,
|
||||
.has_brn66011 = true,
|
||||
.has_brn70165 = true,
|
||||
.has_brn74056 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_info pvr_device_info_22_67_54_30 = {
|
||||
.ident = {
|
||||
PVR_DEVICE_IDENT_22_V_54_30,
|
||||
.b = 22,
|
||||
.v = 67,
|
||||
.n = 54,
|
||||
.c = 30,
|
||||
},
|
||||
.features = pvr_device_features_22_V_54_30,
|
||||
.enhancements = pvr_device_enhancements_22_67_54_30,
|
||||
.quirks = pvr_device_quirks_22_67_54_30,
|
||||
};
|
||||
|
||||
static const struct pvr_device_enhancements
|
||||
pvr_device_enhancements_22_68_54_30 = {
|
||||
.has_ern35421 = true,
|
||||
.has_ern38748 = true,
|
||||
.has_ern42307 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_quirks pvr_device_quirks_22_68_54_30 = {
|
||||
.has_brn49927 = true,
|
||||
.has_brn66011 = true,
|
||||
.has_brn70165 = true,
|
||||
.has_brn74056 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_info pvr_device_info_22_68_54_30 = {
|
||||
.ident = {
|
||||
PVR_DEVICE_IDENT_22_V_54_30,
|
||||
.b = 22,
|
||||
.v = 68,
|
||||
.n = 54,
|
||||
.c = 30,
|
||||
},
|
||||
.features = pvr_device_features_22_V_54_30,
|
||||
.enhancements = pvr_device_enhancements_22_68_54_30,
|
||||
.quirks = pvr_device_quirks_22_68_54_30,
|
||||
};
|
||||
|
||||
#define PVR_DEVICE_IDENT_22_V_54_38 \
|
||||
.device_id = 0x22054038, .series_name = "Rogue", .public_name = "GE8300"
|
||||
|
||||
static const struct pvr_device_features pvr_device_features_22_V_54_38 = {
|
||||
.has_astc = true,
|
||||
.has_common_store_size_in_dwords = true,
|
||||
.has_compute = true,
|
||||
.has_compute_overlap = true,
|
||||
/* .has_gs_rta_support = true, */
|
||||
.has_ipf_creq_pf = true,
|
||||
.has_isp_max_tiles_in_flight = true,
|
||||
.has_isp_samples_per_pixel = true,
|
||||
.has_max_instances_per_pds_task = true,
|
||||
.has_max_multisample = true,
|
||||
.has_max_partitions = true,
|
||||
.has_max_usc_tasks = true,
|
||||
.has_num_clusters = true,
|
||||
.has_num_raster_pipes = true,
|
||||
.has_pbe2_in_xe = true,
|
||||
.has_pbe_filterable_f16 = true,
|
||||
.has_pbe_yuv = true,
|
||||
.has_roguexe = true,
|
||||
.has_simple_internal_parameter_format = true,
|
||||
.has_simple_internal_parameter_format_v1 = true,
|
||||
.has_simple_parameter_format_version = true,
|
||||
.has_slc_cache_line_size_bits = true,
|
||||
.has_tile_size_16x16 = true,
|
||||
.has_tile_size_x = true,
|
||||
.has_tile_size_y = true,
|
||||
.has_tpu_parallel_instances = true,
|
||||
.has_unified_store_depth = true,
|
||||
.has_usc_f16sop_u8 = true,
|
||||
.has_usc_itrsmp = true,
|
||||
.has_usc_itrsmp_enhanced = true,
|
||||
.has_usc_min_output_registers_per_pix = true,
|
||||
.has_usc_slots = true,
|
||||
.has_uvs_banks = true,
|
||||
.has_uvs_pba_entries = true,
|
||||
.has_uvs_vtx_entries = true,
|
||||
.has_vdm_cam_size = true,
|
||||
|
||||
.common_store_size_in_dwords = 1024U * 4U * 4U,
|
||||
.isp_max_tiles_in_flight = 4U,
|
||||
.isp_samples_per_pixel = 1U,
|
||||
.max_instances_per_pds_task = 32U,
|
||||
.max_multisample = 4U,
|
||||
.max_partitions = 10U,
|
||||
.max_usc_tasks = 104U,
|
||||
.num_clusters = 1U,
|
||||
.num_raster_pipes = 1U,
|
||||
.simple_parameter_format_version = 1U,
|
||||
.slc_cache_line_size_bits = 512U,
|
||||
.tile_size_x = 16U,
|
||||
.tile_size_y = 16U,
|
||||
.tpu_parallel_instances = 4U,
|
||||
.unified_store_depth = 208U,
|
||||
.usc_min_output_registers_per_pix = 2U,
|
||||
.usc_slots = 64U,
|
||||
.uvs_banks = 4U,
|
||||
.uvs_pba_entries = 320U,
|
||||
.uvs_vtx_entries = 288U,
|
||||
.vdm_cam_size = 64U,
|
||||
|
||||
.has_s8xe = true,
|
||||
.has_usc_itr_parallel_instances = true,
|
||||
|
||||
.usc_itr_parallel_instances = 16U,
|
||||
};
|
||||
|
||||
static const struct pvr_device_enhancements
|
||||
pvr_device_enhancements_22_102_54_38 = {
|
||||
.has_ern35421 = true,
|
||||
.has_ern38748 = true,
|
||||
.has_ern42307 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_quirks pvr_device_quirks_22_102_54_38 = {
|
||||
.has_brn49927 = true,
|
||||
.has_brn66011 = true,
|
||||
.has_brn70165 = true,
|
||||
.has_brn74056 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_info pvr_device_info_22_102_54_38 = {
|
||||
.ident = {
|
||||
PVR_DEVICE_IDENT_22_V_54_38,
|
||||
.b = 22,
|
||||
.v = 102,
|
||||
.n = 54,
|
||||
.c = 38,
|
||||
},
|
||||
.features = pvr_device_features_22_V_54_38,
|
||||
.enhancements = pvr_device_enhancements_22_102_54_38,
|
||||
.quirks = pvr_device_quirks_22_102_54_38,
|
||||
};
|
||||
|
||||
#endif /* GE8300_H */
|
||||
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Copyright © 2023 Imagination Technologies Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef GX6250_H
|
||||
#define GX6250_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "pvr_device_info.h"
|
||||
|
||||
#define PVR_DEVICE_IDENT_4_V_2_51 \
|
||||
.device_id = 0x6250, .series_name = "Rogue", \
|
||||
.public_name = "GX6250", .arch = PVR_DEVICE_ARCH_ROGUE
|
||||
|
||||
static const struct pvr_device_features pvr_device_features_4_V_2_51 = {
|
||||
.has_astc = true,
|
||||
.has_cluster_grouping = true,
|
||||
.has_common_store_size_in_dwords = true,
|
||||
.has_compute = true,
|
||||
.has_compute_morton_capable = true,
|
||||
.has_compute_overlap = true,
|
||||
.has_eight_output_registers = true,
|
||||
.has_fbcdc_algorithm = true,
|
||||
/* .has_gs_rta_support = true, */
|
||||
.has_isp_max_tiles_in_flight = true,
|
||||
.has_isp_samples_per_pixel = true,
|
||||
.has_max_instances_per_pds_task = true,
|
||||
.has_max_multisample = true,
|
||||
.has_max_partitions = true,
|
||||
.has_max_usc_tasks = true,
|
||||
.has_num_clusters = true,
|
||||
.has_num_raster_pipes = true,
|
||||
.has_pbe_filterable_f16 = true,
|
||||
.has_pbe_yuv = true,
|
||||
.has_slc_cache_line_size_bits = true,
|
||||
.has_slc_mcu_cache_controls = true,
|
||||
.has_tf_bicubic_filter = true,
|
||||
.has_tile_size_x = true,
|
||||
.has_tile_size_y = true,
|
||||
.has_tpu_array_textures = true,
|
||||
.has_tpu_extended_integer_lookup = true,
|
||||
.has_tpu_image_state_v2 = true,
|
||||
.has_tpu_parallel_instances = true,
|
||||
.has_unified_store_depth = true,
|
||||
.has_usc_f16sop_u8 = true,
|
||||
.has_usc_itrsmp = true,
|
||||
.has_usc_itr_parallel_instances = true,
|
||||
.has_usc_min_output_registers_per_pix = true,
|
||||
.has_usc_slots = true,
|
||||
.has_uvs_banks = true,
|
||||
.has_uvs_pba_entries = true,
|
||||
.has_uvs_vtx_entries = true,
|
||||
.has_vdm_cam_size = true,
|
||||
.has_xt_top_infrastructure = true,
|
||||
.has_zls_subtile = true,
|
||||
|
||||
.common_store_size_in_dwords = 1280U * 4U * 4U,
|
||||
.fbcdc_algorithm = 2,
|
||||
.isp_max_tiles_in_flight = 4U,
|
||||
.isp_samples_per_pixel = 2U,
|
||||
.max_instances_per_pds_task = 32U,
|
||||
.max_multisample = 8U,
|
||||
.max_partitions = 8U,
|
||||
.max_usc_tasks = 56U,
|
||||
.num_clusters = 2U,
|
||||
.num_raster_pipes = 1U,
|
||||
.slc_cache_line_size_bits = 512U,
|
||||
.tile_size_x = 32U,
|
||||
.tile_size_y = 32U,
|
||||
.tpu_parallel_instances = 4U,
|
||||
.unified_store_depth = 256U,
|
||||
.usc_itr_parallel_instances = 8U,
|
||||
.usc_min_output_registers_per_pix = 2U,
|
||||
.usc_slots = 32U,
|
||||
.uvs_banks = 8U,
|
||||
.uvs_pba_entries = 320U,
|
||||
.uvs_vtx_entries = 288U,
|
||||
.vdm_cam_size = 256U,
|
||||
|
||||
.has_requires_fb_cdc_zls_setup = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_enhancements pvr_device_enhancements_4_40_2_51 = {
|
||||
.has_ern35421 = true,
|
||||
.has_ern38020 = true,
|
||||
.has_ern38748 = true,
|
||||
.has_ern42064 = true,
|
||||
.has_ern42307 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_quirks pvr_device_quirks_4_40_2_51 = {
|
||||
.has_brn44079 = true,
|
||||
.has_brn47727 = true,
|
||||
.has_brn48492 = true,
|
||||
.has_brn48545 = true,
|
||||
.has_brn49032 = true,
|
||||
.has_brn49927 = true,
|
||||
.has_brn51025 = true,
|
||||
.has_brn51210 = true,
|
||||
.has_brn51764 = true,
|
||||
.has_brn52354 = true,
|
||||
.has_brn52942 = true,
|
||||
.has_brn58839 = true,
|
||||
.has_brn62269 = true,
|
||||
.has_brn66011 = true,
|
||||
.has_brn70165 = true,
|
||||
.has_brn74056 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_info pvr_device_info_4_40_2_51 = {
|
||||
.ident = {
|
||||
PVR_DEVICE_IDENT_4_V_2_51,
|
||||
.b = 4,
|
||||
.v = 40,
|
||||
.n = 2,
|
||||
.c = 51,
|
||||
},
|
||||
.features = pvr_device_features_4_V_2_51,
|
||||
.enhancements = pvr_device_enhancements_4_40_2_51,
|
||||
.quirks = pvr_device_quirks_4_40_2_51,
|
||||
};
|
||||
|
||||
#define PVR_DEVICE_IDENT_4_V_2_58 \
|
||||
.device_id = 0x6250, .series_name = "Rogue", .public_name = "GX6250"
|
||||
|
||||
static const struct pvr_device_features pvr_device_features_4_V_2_58 = {
|
||||
.has_astc = true,
|
||||
.has_cluster_grouping = true,
|
||||
.has_common_store_size_in_dwords = true,
|
||||
.has_compute = true,
|
||||
.has_compute_morton_capable = true,
|
||||
.has_compute_overlap = true,
|
||||
.has_eight_output_registers = true,
|
||||
.has_fbcdc_algorithm = true,
|
||||
/* .has_gs_rta_support = true, */
|
||||
.has_isp_max_tiles_in_flight = true,
|
||||
.has_isp_samples_per_pixel = true,
|
||||
.has_max_instances_per_pds_task = true,
|
||||
.has_max_multisample = true,
|
||||
.has_max_partitions = true,
|
||||
.has_max_usc_tasks = true,
|
||||
.has_num_clusters = true,
|
||||
.has_num_raster_pipes = true,
|
||||
.has_pbe_filterable_f16 = true,
|
||||
.has_pbe_yuv = true,
|
||||
.has_slc_cache_line_size_bits = true,
|
||||
.has_slc_mcu_cache_controls = true,
|
||||
.has_tf_bicubic_filter = true,
|
||||
.has_tile_size_x = true,
|
||||
.has_tile_size_y = true,
|
||||
.has_tpu_array_textures = true,
|
||||
.has_tpu_extended_integer_lookup = true,
|
||||
.has_tpu_image_state_v2 = true,
|
||||
.has_tpu_parallel_instances = true,
|
||||
.has_unified_store_depth = true,
|
||||
.has_usc_f16sop_u8 = true,
|
||||
.has_usc_itrsmp = true,
|
||||
.has_usc_itr_parallel_instances = true,
|
||||
.has_usc_min_output_registers_per_pix = true,
|
||||
.has_usc_slots = true,
|
||||
.has_uvs_banks = true,
|
||||
.has_uvs_pba_entries = true,
|
||||
.has_uvs_vtx_entries = true,
|
||||
.has_vdm_cam_size = true,
|
||||
.has_xt_top_infrastructure = true,
|
||||
.has_zls_subtile = true,
|
||||
|
||||
.common_store_size_in_dwords = 1536U * 4U * 4U,
|
||||
.fbcdc_algorithm = 2,
|
||||
.isp_max_tiles_in_flight = 4U,
|
||||
.isp_samples_per_pixel = 2U,
|
||||
.max_instances_per_pds_task = 32U,
|
||||
.max_multisample = 8U,
|
||||
.max_partitions = 8U,
|
||||
.max_usc_tasks = 56U,
|
||||
.num_clusters = 2U,
|
||||
.num_raster_pipes = 1U,
|
||||
.slc_cache_line_size_bits = 512U,
|
||||
.tile_size_x = 32U,
|
||||
.tile_size_y = 32U,
|
||||
.tpu_parallel_instances = 4U,
|
||||
.unified_store_depth = 256U,
|
||||
.usc_itr_parallel_instances = 8U,
|
||||
.usc_min_output_registers_per_pix = 2U,
|
||||
.usc_slots = 32U,
|
||||
.uvs_banks = 8U,
|
||||
.uvs_pba_entries = 320U,
|
||||
.uvs_vtx_entries = 288U,
|
||||
.vdm_cam_size = 256U,
|
||||
|
||||
.has_requires_fb_cdc_zls_setup = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_enhancements pvr_device_enhancements_4_45_2_58 = {
|
||||
.has_ern35421 = true,
|
||||
.has_ern38020 = true,
|
||||
.has_ern38748 = true,
|
||||
.has_ern42064 = true,
|
||||
.has_ern42307 = true,
|
||||
.has_ern45493 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_quirks pvr_device_quirks_4_45_2_58 = {
|
||||
.has_brn44079 = true,
|
||||
.has_brn49927 = true,
|
||||
.has_brn51025 = true,
|
||||
.has_brn51210 = true,
|
||||
.has_brn51764 = true,
|
||||
.has_brn52354 = true,
|
||||
.has_brn52942 = true,
|
||||
.has_brn58839 = true,
|
||||
.has_brn62269 = true,
|
||||
.has_brn66011 = true,
|
||||
.has_brn70165 = true,
|
||||
.has_brn74056 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_info pvr_device_info_4_45_2_58 = {
|
||||
.ident = {
|
||||
PVR_DEVICE_IDENT_4_V_2_58,
|
||||
.b = 4,
|
||||
.v = 45,
|
||||
.n = 2,
|
||||
.c = 58,
|
||||
},
|
||||
.features = pvr_device_features_4_V_2_58,
|
||||
.enhancements = pvr_device_enhancements_4_45_2_58,
|
||||
.quirks = pvr_device_quirks_4_45_2_58,
|
||||
};
|
||||
|
||||
#endif /* GX6250_H */
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright © 2025 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef GX6650_H
|
||||
#define GX6650_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "pvr_device_info.h"
|
||||
|
||||
#define PVR_DEVICE_IDENT_4_V_6_62 \
|
||||
.device_id = 0x6650, .series_name = "Rogue", \
|
||||
.public_name = "GX6650", .arch = PVR_DEVICE_ARCH_ROGUE
|
||||
|
||||
static const struct pvr_device_features pvr_device_features_4_V_6_62 = {
|
||||
.has_astc = true,
|
||||
.has_cluster_grouping = true,
|
||||
.has_common_store_size_in_dwords = true,
|
||||
.has_compute = true,
|
||||
.has_compute_morton_capable = true,
|
||||
.has_compute_overlap = true,
|
||||
.has_eight_output_registers = true,
|
||||
.has_fbcdc_algorithm = true,
|
||||
/* .has_gs_rta_support = true, */
|
||||
.has_isp_max_tiles_in_flight = true,
|
||||
.has_isp_samples_per_pixel = true,
|
||||
.has_max_instances_per_pds_task = true,
|
||||
.has_max_multisample = true,
|
||||
.has_max_partitions = true,
|
||||
.has_max_usc_tasks = true,
|
||||
.has_num_clusters = true,
|
||||
.has_num_raster_pipes = true,
|
||||
.has_pbe_filterable_f16 = true,
|
||||
.has_pbe_yuv = true,
|
||||
.has_slc_cache_line_size_bits = true,
|
||||
.has_slc_mcu_cache_controls = true,
|
||||
.has_tf_bicubic_filter = true,
|
||||
.has_tile_size_x = true,
|
||||
.has_tile_size_y = true,
|
||||
.has_tpu_array_textures = true,
|
||||
.has_tpu_extended_integer_lookup = true,
|
||||
.has_tpu_image_state_v2 = true,
|
||||
.has_tpu_parallel_instances = true,
|
||||
.has_unified_store_depth = true,
|
||||
.has_usc_f16sop_u8 = true,
|
||||
.has_usc_itrsmp = true,
|
||||
.has_usc_itr_parallel_instances = true,
|
||||
.has_usc_min_output_registers_per_pix = true,
|
||||
.has_usc_slots = true,
|
||||
.has_uvs_banks = true,
|
||||
.has_uvs_pba_entries = true,
|
||||
.has_uvs_vtx_entries = true,
|
||||
.has_vdm_cam_size = true,
|
||||
.has_xt_top_infrastructure = true,
|
||||
.has_zls_subtile = true,
|
||||
|
||||
.common_store_size_in_dwords = 1280U * 4U * 4U,
|
||||
.fbcdc_algorithm = 2U,
|
||||
.isp_max_tiles_in_flight = 8U,
|
||||
.isp_samples_per_pixel = 2U,
|
||||
.max_instances_per_pds_task = 32U,
|
||||
.max_multisample = 8U,
|
||||
.max_partitions = 8U,
|
||||
.max_usc_tasks = 56U,
|
||||
.num_clusters = 6U,
|
||||
.num_raster_pipes = 2U,
|
||||
.slc_cache_line_size_bits = 512U,
|
||||
.tile_size_x = 32U,
|
||||
.tile_size_y = 32U,
|
||||
.tpu_parallel_instances = 4U,
|
||||
.unified_store_depth = 256U,
|
||||
.usc_itr_parallel_instances = 8U,
|
||||
.usc_min_output_registers_per_pix = 2U,
|
||||
.usc_slots = 32U,
|
||||
.uvs_banks = 8U,
|
||||
.uvs_pba_entries = 320U,
|
||||
.uvs_vtx_entries = 288U,
|
||||
.vdm_cam_size = 256U,
|
||||
|
||||
.has_requires_fb_cdc_zls_setup = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_enhancements pvr_device_enhancements_4_46_6_62 = {
|
||||
.has_ern35421 = true,
|
||||
.has_ern38020 = true,
|
||||
.has_ern38748 = true,
|
||||
.has_ern42064 = true,
|
||||
.has_ern42307 = true,
|
||||
.has_ern45493 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_quirks pvr_device_quirks_4_46_6_62 = {
|
||||
.has_brn44079 = true,
|
||||
.has_brn49927 = true,
|
||||
.has_brn51025 = true,
|
||||
.has_brn51210 = true,
|
||||
.has_brn51764 = true,
|
||||
.has_brn52354 = true,
|
||||
.has_brn52942 = true,
|
||||
.has_brn58839 = true,
|
||||
.has_brn62269 = true,
|
||||
.has_brn66011 = true,
|
||||
.has_brn70165 = true,
|
||||
.has_brn74056 = true,
|
||||
};
|
||||
|
||||
static const struct pvr_device_info pvr_device_info_4_46_6_62 = {
|
||||
.ident = {
|
||||
PVR_DEVICE_IDENT_4_V_6_62,
|
||||
.b = 4,
|
||||
.v = 46,
|
||||
.n = 6,
|
||||
.c = 62,
|
||||
},
|
||||
.features = pvr_device_features_4_V_6_62,
|
||||
.enhancements = pvr_device_enhancements_4_46_6_62,
|
||||
.quirks = pvr_device_quirks_4_46_6_62,
|
||||
};
|
||||
|
||||
#endif /* GX6650_H */
|
||||
@@ -0,0 +1,24 @@
|
||||
# Copyright © 2022 Imagination Technologies Ltd.
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
pvr_device_info_dir = join_paths(meson.current_source_dir(), 'device_info')
|
||||
|
||||
libpowervr_common = static_library(
|
||||
'powervr_common',
|
||||
[
|
||||
'pvr_debug.c',
|
||||
'pvr_device_info.c',
|
||||
'pvr_dump.c',
|
||||
'pvr_dump_info.c',
|
||||
'pvr_util.c',
|
||||
'pvr_ycbcr.c',
|
||||
sha1_h,
|
||||
],
|
||||
include_directories : [
|
||||
inc_include,
|
||||
inc_src,
|
||||
inc_imagination,
|
||||
],
|
||||
c_args : [imagination_c_args, no_override_init_args],
|
||||
gnu_symbol_visibility : 'hidden',
|
||||
)
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright © 2022 Imagination Technologies Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util/u_debug.h"
|
||||
#include "pvr_debug.h"
|
||||
|
||||
uint32_t PVR_DEBUG = 0;
|
||||
|
||||
/* clang-format off */
|
||||
static const struct debug_named_value debug_control[] = {
|
||||
{ "cs", PVR_DEBUG_DUMP_CONTROL_STREAM,
|
||||
"Dump the contents of the control stream buffer on every job submit." },
|
||||
{ "bo_track", PVR_DEBUG_TRACK_BOS,
|
||||
"Track all buffer objects with at least one reference." },
|
||||
{ "vk_desc", PVR_DEBUG_VK_DUMP_DESCRIPTOR_SET_LAYOUT,
|
||||
"Dump descriptor set and pipeline layouts." },
|
||||
{ "info", PVR_DEBUG_INFO,
|
||||
"Display information about the driver and device." },
|
||||
DEBUG_NAMED_VALUE_END
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
DEBUG_GET_ONCE_FLAGS_OPTION(pvr_debug, "PVR_DEBUG", debug_control, 0)
|
||||
|
||||
#define PVR_DEBUG_SET(x) PVR_DEBUG |= (PVR_DEBUG_##x)
|
||||
|
||||
void pvr_process_debug_variable(void)
|
||||
{
|
||||
PVR_DEBUG = debug_get_option_pvr_debug();
|
||||
|
||||
/* Perform any automatic selections. For example, if one debug option
|
||||
* implies another it should be set here.
|
||||
*/
|
||||
|
||||
if (PVR_IS_DEBUG_SET(DUMP_CONTROL_STREAM))
|
||||
PVR_DEBUG_SET(TRACK_BOS);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright © 2022 Imagination Technologies Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PVR_DEBUG_H
|
||||
#define PVR_DEBUG_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util/macros.h"
|
||||
|
||||
extern uint32_t PVR_DEBUG;
|
||||
|
||||
/* clang-format off */
|
||||
#define PVR_IS_DEBUG_SET(x) unlikely(PVR_DEBUG & PVR_DEBUG_##x)
|
||||
/* clang-format on */
|
||||
|
||||
#define PVR_DEBUG_DUMP_CONTROL_STREAM BITFIELD_BIT(0)
|
||||
#define PVR_DEBUG_TRACK_BOS BITFIELD_BIT(1)
|
||||
#define PVR_DEBUG_VK_DUMP_DESCRIPTOR_SET_LAYOUT BITFIELD_BIT(2)
|
||||
#define PVR_DEBUG_INFO BITFIELD_BIT(3)
|
||||
|
||||
void pvr_process_debug_variable(void);
|
||||
|
||||
#endif /* PVR_DEBUG_H */
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright © 2022 Imagination Technologies Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* TODO: This file is currently hand-maintained. However, the intention is to
|
||||
* auto-generate it in the future based on the hwdefs.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "pvr_device_info.h"
|
||||
|
||||
#include "device_info/g6110.h"
|
||||
#include "device_info/gx6250.h"
|
||||
#include "device_info/gx6650.h"
|
||||
#include "device_info/ge7800.h"
|
||||
#include "device_info/ge8300.h"
|
||||
#include "device_info/axe-1-16m.h"
|
||||
#include "device_info/bxe-2-32.h"
|
||||
#include "device_info/bxe-4-32.h"
|
||||
#include "device_info/bxm-4-64.h"
|
||||
#include "device_info/bxs-4-64.h"
|
||||
|
||||
#include "util/u_string.h"
|
||||
|
||||
static const struct pvr_device_info *device_infos[] = {
|
||||
/* clang-format off */
|
||||
&pvr_device_info_4_40_2_51,
|
||||
&pvr_device_info_4_45_2_58,
|
||||
&pvr_device_info_4_46_6_62,
|
||||
&pvr_device_info_5_9_1_46,
|
||||
&pvr_device_info_15_5_1_64,
|
||||
&pvr_device_info_22_67_54_30,
|
||||
&pvr_device_info_22_68_54_30,
|
||||
&pvr_device_info_22_102_54_38,
|
||||
&pvr_device_info_33_15_11_3,
|
||||
&pvr_device_info_36_29_52_182,
|
||||
&pvr_device_info_36_50_54_182,
|
||||
&pvr_device_info_36_52_104_182,
|
||||
&pvr_device_info_36_53_104_796,
|
||||
&pvr_device_info_36_56_104_183,
|
||||
/* clang-format on */
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize PowerVR device information.
|
||||
*
|
||||
* \param info Device info structure to initialize.
|
||||
* \param bvnc Packed BVNC.
|
||||
* \return
|
||||
* * 0 on success, or
|
||||
* * -%ENODEV if the device is not supported.
|
||||
*/
|
||||
int pvr_device_info_init(struct pvr_device_info *info, uint64_t bvnc)
|
||||
{
|
||||
#define CASE_PACKED_BVNC_DEVICE_INFO(_b, _v, _n, _c) \
|
||||
case PVR_BVNC_PACK(_b, _v, _n, _c): \
|
||||
*info = pvr_device_info_##_b##_##_v##_##_n##_##_c; \
|
||||
return 0
|
||||
|
||||
switch (bvnc) {
|
||||
CASE_PACKED_BVNC_DEVICE_INFO(4, 40, 2, 51);
|
||||
CASE_PACKED_BVNC_DEVICE_INFO(4, 45, 2, 58);
|
||||
CASE_PACKED_BVNC_DEVICE_INFO(4, 46, 6, 62);
|
||||
CASE_PACKED_BVNC_DEVICE_INFO(5, 9, 1, 46);
|
||||
CASE_PACKED_BVNC_DEVICE_INFO(15, 5, 1, 64);
|
||||
CASE_PACKED_BVNC_DEVICE_INFO(22, 67, 54, 30);
|
||||
CASE_PACKED_BVNC_DEVICE_INFO(22, 68, 54, 30);
|
||||
CASE_PACKED_BVNC_DEVICE_INFO(22, 102, 54, 38);
|
||||
CASE_PACKED_BVNC_DEVICE_INFO(33, 15, 11, 3);
|
||||
CASE_PACKED_BVNC_DEVICE_INFO(36, 29, 52, 182);
|
||||
CASE_PACKED_BVNC_DEVICE_INFO(36, 50, 54, 182);
|
||||
CASE_PACKED_BVNC_DEVICE_INFO(36, 52, 104, 182);
|
||||
CASE_PACKED_BVNC_DEVICE_INFO(36, 53, 104, 796);
|
||||
CASE_PACKED_BVNC_DEVICE_INFO(36, 56, 104, 183);
|
||||
}
|
||||
|
||||
#undef CASE_PACKED_BVNC_DEVICE_INFO
|
||||
|
||||
assert(!"Unsupported Device");
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize PowerVR device information from a public name.
|
||||
*
|
||||
* \param info Device info structure to initialize.
|
||||
* \param public_name Device public name.
|
||||
* \return True if successful.
|
||||
*/
|
||||
bool pvr_device_info_init_public_name(struct pvr_device_info *info,
|
||||
const char *public_name)
|
||||
{
|
||||
for (unsigned d = 0; d < ARRAY_SIZE(device_infos); ++d) {
|
||||
if (strcasecmp(public_name, device_infos[d]->ident.public_name))
|
||||
continue;
|
||||
|
||||
memcpy(info, device_infos[d], sizeof(*info));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,431 @@
|
||||
/*
|
||||
* Copyright © 2022 Imagination Technologies Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PVR_DEVICE_INFO_H
|
||||
#define PVR_DEVICE_INFO_H
|
||||
|
||||
/* TODO: This file is currently hand-maintained. However, the intention is to
|
||||
* auto-generate it in the future based on the hwdefs.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util/log.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
#define PVR_BVNC_PACK_SHIFT_B 48
|
||||
#define PVR_BVNC_PACK_SHIFT_V 32
|
||||
#define PVR_BVNC_PACK_SHIFT_N 16
|
||||
#define PVR_BVNC_PACK_SHIFT_C 0
|
||||
|
||||
#define PVR_BVNC_PACK_MASK_B UINT64_C(0xFFFF000000000000)
|
||||
#define PVR_BVNC_PACK_MASK_V UINT64_C(0x0000FFFF00000000)
|
||||
#define PVR_BVNC_PACK_MASK_N UINT64_C(0x00000000FFFF0000)
|
||||
#define PVR_BVNC_PACK_MASK_C UINT64_C(0x000000000000FFFF)
|
||||
|
||||
enum pvr_device_arch {
|
||||
PVR_DEVICE_ARCH_ROGUE,
|
||||
};
|
||||
|
||||
/**
|
||||
* Packs B, V, N and C values into a 64-bit unsigned integer.
|
||||
*
|
||||
* The packed layout is as follows:
|
||||
*
|
||||
* \verbatim
|
||||
* +--------+--------+--------+-------+
|
||||
* | 63..48 | 47..32 | 31..16 | 15..0 |
|
||||
* +========+========+========+=======+
|
||||
* | B | V | N | C |
|
||||
* +--------+--------+--------+-------+
|
||||
* \endverbatim
|
||||
*
|
||||
* #pvr_get_packed_bvnc() should be used instead of this macro when a
|
||||
* #pvr_device_information is available in order to ensure proper type checking.
|
||||
*
|
||||
* \param b Branch ID.
|
||||
* \param v Version ID.
|
||||
* \param n Number of scalable units.
|
||||
* \param c Config ID.
|
||||
* \return Packed BVNC.
|
||||
*
|
||||
* \sa #pvr_get_packed_bvnc(), #PVR_BVNC_UNPACK_B(), #PVR_BVNC_UNPACK_V(),
|
||||
* #PVR_BVNC_UNPACK_N() and #PVR_BVNC_UNPACK_C()
|
||||
*/
|
||||
#define PVR_BVNC_PACK(b, v, n, c) \
|
||||
((((uint64_t)(b) << PVR_BVNC_PACK_SHIFT_B) & PVR_BVNC_PACK_MASK_B) | \
|
||||
(((uint64_t)(v) << PVR_BVNC_PACK_SHIFT_V) & PVR_BVNC_PACK_MASK_V) | \
|
||||
(((uint64_t)(n) << PVR_BVNC_PACK_SHIFT_N) & PVR_BVNC_PACK_MASK_N) | \
|
||||
(((uint64_t)(c) << PVR_BVNC_PACK_SHIFT_C) & PVR_BVNC_PACK_MASK_C))
|
||||
|
||||
/**
|
||||
* Unpacks B value (branch ID) from packed BVNC.
|
||||
*
|
||||
* \param bvnc Packed BVNC.
|
||||
* \return Branch ID.
|
||||
*
|
||||
* \sa #PVR_BVNC_UNPACK_V(), #PVR_BVNC_UNPACK_N(), #PVR_BVNC_UNPACK_C(),
|
||||
* #pvr_get_packed_bvnc() and #PVR_BVNC_PACK()
|
||||
*/
|
||||
#define PVR_BVNC_UNPACK_B(bvnc) \
|
||||
((uint16_t)(((bvnc) & PVR_BVNC_PACK_MASK_B) >> PVR_BVNC_PACK_SHIFT_B))
|
||||
|
||||
/**
|
||||
* Unpacks V value (version ID) from packed BVNC.
|
||||
*
|
||||
* \param bvnc Packed BVNC.
|
||||
* \return Version ID.
|
||||
*
|
||||
* \sa #PVR_BVNC_UNPACK_B(), #PVR_BVNC_UNPACK_N(), #PVR_BVNC_UNPACK_C(),
|
||||
* #pvr_get_packed_bvnc() and #PVR_BVNC_PACK()
|
||||
*/
|
||||
#define PVR_BVNC_UNPACK_V(bvnc) \
|
||||
((uint16_t)(((bvnc) & PVR_BVNC_PACK_MASK_V) >> PVR_BVNC_PACK_SHIFT_V))
|
||||
|
||||
/**
|
||||
* Unpacks N value (number of scalable units) from packed BVNC.
|
||||
*
|
||||
* \param bvnc Packed BVNC.
|
||||
* \return Number of scalable units.
|
||||
*
|
||||
* \sa #PVR_BVNC_UNPACK_B(), #PVR_BVNC_UNPACK_V(), #PVR_BVNC_UNPACK_C(),
|
||||
* #pvr_get_packed_bvnc() and #PVR_BVNC_PACK()
|
||||
*/
|
||||
#define PVR_BVNC_UNPACK_N(bvnc) \
|
||||
((uint16_t)(((bvnc) & PVR_BVNC_PACK_MASK_N) >> PVR_BVNC_PACK_SHIFT_N))
|
||||
|
||||
/**
|
||||
* Unpacks C value (config ID) from packed BVNC.
|
||||
*
|
||||
* \param bvnc Packed BVNC.
|
||||
* \return Config ID.
|
||||
*
|
||||
* \sa #PVR_BVNC_UNPACK_B(), #PVR_BVNC_UNPACK_V(), #PVR_BVNC_UNPACK_N(),
|
||||
* #pvr_get_packed_bvnc() and #PVR_BVNC_PACK()
|
||||
*/
|
||||
#define PVR_BVNC_UNPACK_C(bvnc) \
|
||||
((uint16_t)(((bvnc) & PVR_BVNC_PACK_MASK_C) >> PVR_BVNC_PACK_SHIFT_C))
|
||||
|
||||
/**
|
||||
* Tests whether a physical device has a given feature.
|
||||
*
|
||||
* Feature names are derived from those found in #pvr_device_features by
|
||||
* dropping the 'has_' prefix, which is applied by this macro.
|
||||
*
|
||||
* \param dev_info #pvr_device_info object associated with the target physical
|
||||
* device.
|
||||
* \param feature Device feature name.
|
||||
*
|
||||
* \return
|
||||
* * true if the named feature is present in the hardware.
|
||||
* * false if the named feature is not present in the hardware.
|
||||
*
|
||||
* \sa #PVR_FEATURE_VALUE() and #PVR_GET_FEATURE_VALUE()
|
||||
*/
|
||||
#define PVR_HAS_FEATURE(dev_info, feature) ((dev_info)->features.has_##feature)
|
||||
|
||||
/**
|
||||
* Gets a physical device feature value if feature is supported.
|
||||
*
|
||||
* Feature names are derived from those found in #pvr_device_features by
|
||||
* dropping the 'has_' prefix.
|
||||
*
|
||||
* This macro should be used in preference to #PVR_GET_FEATURE_VALUE() as it has
|
||||
* proper error handling.
|
||||
*
|
||||
* \param dev_info #pvr_device_info object associated with the target physical
|
||||
* device.
|
||||
* \param feature Feature name.
|
||||
* \param value_out Feature value.
|
||||
*
|
||||
* \return
|
||||
* * 0 on success, or
|
||||
* * -%EINVAL if the named feature is not present in the hardware.
|
||||
*
|
||||
* \sa #PVR_HAS_FEATURE() and #PVR_GET_FEATURE_VALUE()
|
||||
*/
|
||||
#define PVR_FEATURE_VALUE(dev_info, feature, value_out) \
|
||||
({ \
|
||||
const struct pvr_device_info *__dev_info = dev_info; \
|
||||
int __ret = -EINVAL; \
|
||||
if (__dev_info->features.has_##feature) { \
|
||||
*(value_out) = __dev_info->features.feature; \
|
||||
__ret = 0; \
|
||||
} \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
/**
|
||||
* Gets a physical device feature value if supported, but otherwise returns a
|
||||
* default value.
|
||||
*
|
||||
* Feature names are derived from those found in #pvr_device_features by
|
||||
* dropping the 'has_' prefix.
|
||||
*
|
||||
* #PVR_FEATURE_VALUE() should be used in preference to this macro when errors
|
||||
* can be returned by the caller. This macro is intended for cases where errors
|
||||
* can't be returned.
|
||||
*
|
||||
* \param dev_info #pvr_device_info object associated with the target
|
||||
* physical device.
|
||||
* \param feature Feature name.
|
||||
* \param default_value Default feature value.
|
||||
*
|
||||
* \return Feature value.
|
||||
*
|
||||
* \sa #PVR_HAS_FEATURE() and #PVR_FEATURE_VALUE()
|
||||
*/
|
||||
#define PVR_GET_FEATURE_VALUE(dev_info, feature, default_value) \
|
||||
({ \
|
||||
const struct pvr_device_info *__dev_info = dev_info; \
|
||||
__typeof__(default_value) __ret = default_value; \
|
||||
if (__dev_info->features.has_##feature) { \
|
||||
__ret = __dev_info->features.feature; \
|
||||
} else { \
|
||||
mesa_logw("Missing " #feature \
|
||||
" feature (defaulting to: " #default_value ")"); \
|
||||
assert(0); \
|
||||
} \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
/**
|
||||
* Tests whether a physical device has a given enhancement.
|
||||
*
|
||||
* Enhancement numbers are derived from those found in #pvr_device_enhancements
|
||||
* by dropping the 'has_ern' prefix, which is applied by this macro.
|
||||
*
|
||||
* \param dev_info #pvr_device_info object associated with the target physical
|
||||
* device.
|
||||
* \param number Enhancement number.
|
||||
*
|
||||
* \return
|
||||
* * true if the enhancement is present in the hardware.
|
||||
* * false if the enhancement is not present in the hardware.
|
||||
*/
|
||||
#define PVR_HAS_ENHANCEMENT(dev_info, number) \
|
||||
((dev_info)->enhancements.has_ern##number)
|
||||
|
||||
/**
|
||||
* Tests whether a physical device has a given quirk.
|
||||
*
|
||||
* Quirk numbers are derived from those found in #pvr_device_quirks by
|
||||
* dropping the 'has_brn' prefix, which is applied by this macro.
|
||||
*
|
||||
* \param dev_info #pvr_device_info object associated with the target physical
|
||||
* device.
|
||||
* \param number Quirk number.
|
||||
*
|
||||
* \return
|
||||
* * true if the quirk is present in the hardware.
|
||||
* * false if the quirk is not present in the hardware.
|
||||
*/
|
||||
#define PVR_HAS_QUIRK(dev_info, number) ((dev_info)->quirks.has_brn##number)
|
||||
|
||||
struct pvr_device_ident {
|
||||
enum pvr_device_arch arch;
|
||||
uint16_t b, v, n, c;
|
||||
uint32_t device_id;
|
||||
const char *series_name;
|
||||
const char *public_name;
|
||||
};
|
||||
|
||||
struct pvr_device_features {
|
||||
bool has_astc : 1;
|
||||
bool has_cluster_grouping : 1;
|
||||
bool has_common_store_size_in_dwords : 1;
|
||||
bool has_compute : 1;
|
||||
bool has_compute_morton_capable : 1;
|
||||
bool has_compute_overlap : 1;
|
||||
bool has_eight_output_registers : 1;
|
||||
bool has_fb_cdc_v4 : 1;
|
||||
bool has_fbcdc_algorithm : 1;
|
||||
bool has_gpu_multicore_support : 1;
|
||||
bool has_gs_rta_support : 1;
|
||||
bool has_ipf_creq_pf : 1;
|
||||
bool has_isp_max_tiles_in_flight : 1;
|
||||
bool has_isp_samples_per_pixel : 1;
|
||||
bool has_max_instances_per_pds_task : 1;
|
||||
bool has_max_multisample : 1;
|
||||
bool has_max_partitions : 1;
|
||||
bool has_max_usc_tasks : 1;
|
||||
bool has_num_clusters : 1;
|
||||
bool has_num_raster_pipes : 1;
|
||||
bool has_paired_tiles : 1;
|
||||
bool has_pbe2_in_xe : 1;
|
||||
bool has_pbe_filterable_f16 : 1;
|
||||
bool has_pbe_stride_align_1pixel : 1;
|
||||
bool has_pbe_yuv : 1;
|
||||
bool has_pds_ddmadt : 1;
|
||||
bool has_roguexe : 1;
|
||||
bool has_screen_size8K : 1;
|
||||
bool has_simple_internal_parameter_format : 1;
|
||||
bool has_simple_internal_parameter_format_v1 : 1;
|
||||
bool has_simple_internal_parameter_format_v2 : 1;
|
||||
bool has_simple_parameter_format_version : 1;
|
||||
bool has_slc_cache_line_size_bits : 1;
|
||||
bool has_slc_mcu_cache_controls : 1;
|
||||
bool has_tf_bicubic_filter : 1;
|
||||
bool has_tile_per_usc : 1;
|
||||
bool has_tile_size_16x16 : 1;
|
||||
bool has_tile_size_x : 1;
|
||||
bool has_tile_size_y : 1;
|
||||
bool has_tpu_array_textures : 1;
|
||||
bool has_tpu_border_colour_enhanced : 1;
|
||||
bool has_tpu_dm_global_registers : 1;
|
||||
bool has_tpu_extended_integer_lookup : 1;
|
||||
bool has_tpu_image_state_v2 : 1;
|
||||
bool has_tpu_parallel_instances : 1;
|
||||
bool has_unified_store_depth : 1;
|
||||
bool has_usc_alu_roundingmode_rne : 1;
|
||||
bool has_usc_f16sop_u8 : 1;
|
||||
bool has_usc_itrsmp : 1;
|
||||
bool has_usc_itrsmp_enhanced : 1;
|
||||
bool has_usc_itr_parallel_instances : 1;
|
||||
bool has_usc_min_output_registers_per_pix : 1;
|
||||
bool has_usc_pixel_partition_mask : 1;
|
||||
bool has_usc_slots : 1;
|
||||
bool has_uvs_banks : 1;
|
||||
bool has_uvs_pba_entries : 1;
|
||||
bool has_uvs_vtx_entries : 1;
|
||||
bool has_vdm_cam_size : 1;
|
||||
bool has_vdm_degenerate_culling : 1;
|
||||
bool has_xpu_max_slaves : 1;
|
||||
bool has_xt_top_infrastructure : 1;
|
||||
bool has_zls_subtile : 1;
|
||||
|
||||
uint32_t common_store_size_in_dwords;
|
||||
uint32_t fbcdc_algorithm;
|
||||
uint32_t isp_max_tiles_in_flight;
|
||||
uint32_t isp_samples_per_pixel;
|
||||
uint32_t max_instances_per_pds_task;
|
||||
uint32_t max_multisample;
|
||||
uint32_t max_partitions;
|
||||
uint32_t max_usc_tasks;
|
||||
uint32_t num_clusters;
|
||||
uint32_t num_raster_pipes;
|
||||
uint32_t simple_parameter_format_version;
|
||||
uint32_t slc_cache_line_size_bits;
|
||||
uint32_t tile_size_x;
|
||||
uint32_t tile_size_y;
|
||||
uint32_t tpu_parallel_instances;
|
||||
uint32_t unified_store_depth;
|
||||
uint32_t usc_itr_parallel_instances;
|
||||
uint32_t usc_min_output_registers_per_pix;
|
||||
uint32_t usc_slots;
|
||||
uint32_t uvs_banks;
|
||||
uint32_t uvs_pba_entries;
|
||||
uint32_t uvs_vtx_entries;
|
||||
uint32_t vdm_cam_size;
|
||||
uint32_t xpu_max_slaves;
|
||||
|
||||
/* Derived features. */
|
||||
bool has_requires_fb_cdc_zls_setup : 1;
|
||||
bool has_s8xe : 1;
|
||||
};
|
||||
|
||||
struct pvr_device_enhancements {
|
||||
bool has_ern35421 : 1;
|
||||
bool has_ern38020 : 1;
|
||||
bool has_ern38748 : 1;
|
||||
bool has_ern42064 : 1;
|
||||
bool has_ern42307 : 1;
|
||||
bool has_ern45493 : 1;
|
||||
};
|
||||
|
||||
struct pvr_device_quirks {
|
||||
bool has_brn44079 : 1;
|
||||
bool has_brn47727 : 1;
|
||||
bool has_brn48492 : 1;
|
||||
bool has_brn48545 : 1;
|
||||
bool has_brn49032 : 1;
|
||||
bool has_brn49927 : 1;
|
||||
bool has_brn51025 : 1;
|
||||
bool has_brn51210 : 1;
|
||||
bool has_brn51764 : 1;
|
||||
bool has_brn52354 : 1;
|
||||
bool has_brn52942 : 1;
|
||||
bool has_brn58839 : 1;
|
||||
bool has_brn62269 : 1;
|
||||
bool has_brn66011 : 1;
|
||||
bool has_brn70165 : 1;
|
||||
bool has_brn72168 : 1;
|
||||
bool has_brn72463 : 1;
|
||||
bool has_brn74056 : 1;
|
||||
};
|
||||
|
||||
struct pvr_device_info {
|
||||
struct pvr_device_ident ident;
|
||||
struct pvr_device_features features;
|
||||
struct pvr_device_enhancements enhancements;
|
||||
struct pvr_device_quirks quirks;
|
||||
};
|
||||
|
||||
struct pvr_device_runtime_info {
|
||||
uint64_t min_free_list_size;
|
||||
uint64_t max_free_list_size;
|
||||
uint64_t reserved_shared_size;
|
||||
uint64_t total_reserved_partition_size;
|
||||
uint64_t num_phantoms;
|
||||
uint64_t max_coeffs;
|
||||
uint64_t cdm_max_local_mem_size_regs;
|
||||
uint32_t core_count;
|
||||
};
|
||||
|
||||
/**
|
||||
* Packs B, V, N and C values into a 64-bit unsigned integer.
|
||||
*
|
||||
* The packed layout is as follows:
|
||||
*
|
||||
* \verbatim
|
||||
* +--------+--------+--------+-------+
|
||||
* | 63..48 | 47..32 | 31..16 | 15..0 |
|
||||
* +========+========+========+=======+
|
||||
* | B | V | N | C |
|
||||
* +--------+--------+--------+-------+
|
||||
* \endverbatim
|
||||
*
|
||||
* This should be used in preference to #PVR_BVNC_PACK() when a
|
||||
* #pvr_device_info is available in order to ensure proper type checking.
|
||||
*
|
||||
* \param dev_info Device information.
|
||||
* \return Packed BVNC.
|
||||
*/
|
||||
static ALWAYS_INLINE uint64_t
|
||||
pvr_get_packed_bvnc(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
return PVR_BVNC_PACK(dev_info->ident.b,
|
||||
dev_info->ident.v,
|
||||
dev_info->ident.n,
|
||||
dev_info->ident.c);
|
||||
}
|
||||
|
||||
int pvr_device_info_init(struct pvr_device_info *info, uint64_t bvnc);
|
||||
|
||||
bool pvr_device_info_init_public_name(struct pvr_device_info *info,
|
||||
const char *public_name);
|
||||
|
||||
#endif /* PVR_DEVICE_INFO_H */
|
||||
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Copyright © 2022 Imagination Technologies Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "pvr_dump.h"
|
||||
#include "pvr_util.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
const struct pvr_dump_ctx __pvr_dump_ctx_invalid = {
|
||||
.active_child = &__pvr_dump_ctx_invalid,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
Hex dumps
|
||||
*****************************************************************************/
|
||||
|
||||
#define HEX_WORD_SIZE ((unsigned)sizeof(uint32_t))
|
||||
#define HEX_BYTE_FMT "%02" PRIx8
|
||||
|
||||
/* This must be even, and should probably always be a power of 2. */
|
||||
#define HEX_LINE_SIZE (HEX_WORD_SIZE * 8)
|
||||
|
||||
struct pvr_dump_hex_ctx {
|
||||
struct pvr_dump_ctx base;
|
||||
|
||||
const uint8_t *start_ptr;
|
||||
const uint8_t *end_ptr;
|
||||
uint64_t nr_bytes;
|
||||
uint32_t offset_digits;
|
||||
|
||||
/* User-modifiable values */
|
||||
const uint8_t *line_ptr;
|
||||
|
||||
uint32_t prev_non_zero_trailing_zero_bytes;
|
||||
uint64_t prev_non_zero_leading_zero_lines;
|
||||
const uint8_t *prev_non_zero_line;
|
||||
uint64_t zero_lines;
|
||||
};
|
||||
|
||||
static bool pvr_dump_hex_ctx_push(struct pvr_dump_hex_ctx *const ctx,
|
||||
struct pvr_dump_buffer_ctx *const parent_ctx,
|
||||
const uint64_t nr_bytes)
|
||||
{
|
||||
const uint64_t real_nr_bytes = nr_bytes ? nr_bytes
|
||||
: parent_ctx->remaining_size;
|
||||
bool ret;
|
||||
|
||||
if (parent_ctx->remaining_size < nr_bytes)
|
||||
return false;
|
||||
|
||||
ret = pvr_dump_ctx_push(&ctx->base, &parent_ctx->base);
|
||||
if (!ret)
|
||||
return false;
|
||||
|
||||
ctx->start_ptr = parent_ctx->ptr;
|
||||
ctx->end_ptr = ctx->start_ptr + real_nr_bytes;
|
||||
ctx->nr_bytes = real_nr_bytes;
|
||||
ctx->offset_digits = u64_hex_digits(real_nr_bytes);
|
||||
|
||||
ctx->line_ptr = ctx->start_ptr;
|
||||
|
||||
ctx->prev_non_zero_trailing_zero_bytes = 0;
|
||||
ctx->prev_non_zero_leading_zero_lines = 0;
|
||||
ctx->prev_non_zero_line = NULL;
|
||||
ctx->zero_lines = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct pvr_dump_buffer_ctx *
|
||||
pvr_dump_hex_ctx_pop(struct pvr_dump_hex_ctx *const ctx)
|
||||
{
|
||||
struct pvr_dump_buffer_ctx *parent;
|
||||
struct pvr_dump_ctx *parent_base;
|
||||
|
||||
if (ctx->line_ptr != ctx->end_ptr) {
|
||||
ctx->base.ok = false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
parent_base = pvr_dump_ctx_pop(&ctx->base);
|
||||
if (!parent_base)
|
||||
return NULL;
|
||||
|
||||
parent = container_of(parent_base, struct pvr_dump_buffer_ctx, base);
|
||||
|
||||
pvr_dump_buffer_advance(parent, ctx->nr_bytes);
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
static inline void pvr_dump_hex_print_prefix(const struct pvr_dump_hex_ctx *ctx,
|
||||
const uint64_t offset)
|
||||
{
|
||||
pvr_dump_printf(&ctx->base,
|
||||
PVR_DUMP_OFFSET_PREFIX,
|
||||
ctx->offset_digits,
|
||||
offset);
|
||||
}
|
||||
|
||||
#define pvr_dump_hex_println(ctx, offset, format, args...) \
|
||||
pvr_dump_println(&(ctx)->base, \
|
||||
PVR_DUMP_OFFSET_PREFIX format, \
|
||||
(ctx)->offset_digits, \
|
||||
offset, \
|
||||
##args)
|
||||
|
||||
#define pvr_dump_hex_println_no_prefix(ctx, format, args...) \
|
||||
pvr_dump_println(&(ctx)->base, \
|
||||
"%*c" format, \
|
||||
(ctx)->offset_digits + 3, \
|
||||
' ', \
|
||||
##args)
|
||||
|
||||
static void pvr_dump_hex_print_line(const struct pvr_dump_hex_ctx *ctx,
|
||||
const uint8_t *const line_ptr,
|
||||
const uint32_t truncate)
|
||||
{
|
||||
const uint32_t nr_bytes =
|
||||
MIN2(HEX_LINE_SIZE - truncate, ctx->end_ptr - line_ptr);
|
||||
|
||||
pvr_dump_hex_print_prefix(ctx, line_ptr - ctx->start_ptr);
|
||||
|
||||
for (uint32_t i = 0; i < nr_bytes; i++) {
|
||||
if (i == HEX_LINE_SIZE / 2)
|
||||
pvr_dump_printf_cont(&ctx->base, " ");
|
||||
|
||||
if (i % HEX_WORD_SIZE == 0)
|
||||
pvr_dump_printf_cont(&ctx->base, " ");
|
||||
|
||||
if (line_ptr[i])
|
||||
pvr_dump_printf_cont(&ctx->base, HEX_BYTE_FMT, line_ptr[i]);
|
||||
else
|
||||
pvr_dump_printf_cont(&ctx->base, "..");
|
||||
}
|
||||
|
||||
pvr_dump_print_eol(&ctx->base);
|
||||
}
|
||||
|
||||
static void
|
||||
pvr_dump_hex_print_zero_lines(const struct pvr_dump_hex_ctx *const ctx,
|
||||
const uint64_t zero_lines)
|
||||
{
|
||||
const uint64_t zero_bytes = zero_lines * HEX_LINE_SIZE;
|
||||
|
||||
if (!zero_lines)
|
||||
return;
|
||||
|
||||
/* If we've only buffered a single zero line, print it normally. We don't
|
||||
* save any space by folding it, and it's more readable this way.
|
||||
*/
|
||||
if (zero_lines == 1) {
|
||||
pvr_dump_hex_print_line(ctx, ctx->prev_non_zero_line + HEX_LINE_SIZE, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
pvr_dump_hex_println_no_prefix(ctx,
|
||||
" + %" PRIu64 " zero line%s (%" PRIu64
|
||||
"/0x%" PRIx64 " bytes)",
|
||||
zero_lines,
|
||||
zero_lines == 1 ? "" : "s",
|
||||
zero_bytes,
|
||||
zero_bytes);
|
||||
}
|
||||
|
||||
static void
|
||||
pvr_dump_hex_print_trailing_zeroes(const struct pvr_dump_hex_ctx *const ctx)
|
||||
{
|
||||
const uint64_t zero_bytes =
|
||||
ctx->zero_lines * HEX_LINE_SIZE + ctx->prev_non_zero_trailing_zero_bytes;
|
||||
|
||||
if (!ctx->prev_non_zero_trailing_zero_bytes)
|
||||
return pvr_dump_hex_print_zero_lines(ctx, ctx->zero_lines);
|
||||
|
||||
if (!ctx->zero_lines)
|
||||
return;
|
||||
|
||||
pvr_dump_hex_println_no_prefix(ctx,
|
||||
" + %" PRIu64 "+%" PRIu32
|
||||
" zero lines (%" PRIu64 "/0x%" PRIx64
|
||||
" bytes)",
|
||||
ctx->zero_lines,
|
||||
ctx->prev_non_zero_trailing_zero_bytes,
|
||||
zero_bytes,
|
||||
zero_bytes);
|
||||
}
|
||||
|
||||
static void pvr_dump_hex_process_line(struct pvr_dump_hex_ctx *const ctx,
|
||||
uint32_t truncate)
|
||||
{
|
||||
const uint32_t max_bytes = HEX_LINE_SIZE - truncate;
|
||||
|
||||
uint32_t trailing_zero_bytes = max_bytes;
|
||||
|
||||
for (uint32_t i = max_bytes; i > 0; i--) {
|
||||
if (ctx->line_ptr[i - 1]) {
|
||||
trailing_zero_bytes = HEX_LINE_SIZE - i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (trailing_zero_bytes == max_bytes) {
|
||||
/* No non-zero words were found in this line; mark it and move on. */
|
||||
ctx->zero_lines++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* We have at least one non-zero word in this line. If we have a previous
|
||||
* non-zero line stored, collapse and print any leading zero-only lines
|
||||
* before it then print the stored line.
|
||||
*/
|
||||
if (ctx->prev_non_zero_line) {
|
||||
pvr_dump_hex_print_zero_lines(ctx, ctx->prev_non_zero_leading_zero_lines);
|
||||
pvr_dump_hex_print_line(ctx, ctx->prev_non_zero_line, truncate);
|
||||
}
|
||||
|
||||
/* Now we store the current non-zero line for printing later. This way we
|
||||
* can treat the last non-zero line specially.
|
||||
*/
|
||||
ctx->prev_non_zero_line = ctx->line_ptr;
|
||||
ctx->prev_non_zero_leading_zero_lines = ctx->zero_lines;
|
||||
ctx->prev_non_zero_trailing_zero_bytes = trailing_zero_bytes;
|
||||
ctx->zero_lines = 0;
|
||||
}
|
||||
|
||||
static void pvr_dump_hex(struct pvr_dump_hex_ctx *const ctx)
|
||||
{
|
||||
while (ctx->line_ptr < (ctx->end_ptr - HEX_LINE_SIZE)) {
|
||||
pvr_dump_hex_process_line(ctx, 0);
|
||||
ctx->line_ptr += HEX_LINE_SIZE;
|
||||
}
|
||||
|
||||
pvr_dump_hex_process_line(ctx,
|
||||
HEX_LINE_SIZE - (ctx->end_ptr - ctx->line_ptr));
|
||||
ctx->line_ptr = ctx->end_ptr;
|
||||
|
||||
if (ctx->prev_non_zero_line) {
|
||||
/* If we don't have any zero lines to collapse, print the trailing zeroes
|
||||
* on the last line.
|
||||
*/
|
||||
if (!ctx->zero_lines) {
|
||||
pvr_dump_hex_print_line(ctx, ctx->prev_non_zero_line, 0);
|
||||
} else {
|
||||
pvr_dump_hex_print_zero_lines(ctx,
|
||||
ctx->prev_non_zero_leading_zero_lines);
|
||||
|
||||
pvr_dump_hex_print_line(ctx,
|
||||
ctx->prev_non_zero_line,
|
||||
ctx->prev_non_zero_trailing_zero_bytes);
|
||||
|
||||
/* Collapse and print any trailing zeroes. */
|
||||
pvr_dump_hex_print_trailing_zeroes(ctx);
|
||||
}
|
||||
} else {
|
||||
/* We made it to the end of the buffer without ever encountering a
|
||||
* non-zero word. Make this known.
|
||||
*/
|
||||
pvr_dump_hex_println(ctx, UINT64_C(0), " <empty buffer>");
|
||||
}
|
||||
|
||||
pvr_dump_hex_println(ctx, ctx->nr_bytes, " <end of buffer>");
|
||||
}
|
||||
|
||||
bool pvr_dump_buffer_hex(struct pvr_dump_buffer_ctx *const ctx,
|
||||
const uint64_t nr_bytes)
|
||||
{
|
||||
struct pvr_dump_hex_ctx hex_ctx;
|
||||
|
||||
if (!pvr_dump_hex_ctx_push(&hex_ctx, ctx, nr_bytes))
|
||||
return false;
|
||||
|
||||
pvr_dump_hex(&hex_ctx);
|
||||
|
||||
return !!pvr_dump_hex_ctx_pop(&hex_ctx);
|
||||
}
|
||||
@@ -0,0 +1,739 @@
|
||||
/*
|
||||
* Copyright © 2022 Imagination Technologies Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PVR_DUMP_H
|
||||
#define PVR_DUMP_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pvr_types.h"
|
||||
#include "pvr_util.h"
|
||||
#include "util/macros.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
/** BASIC PRINTING **/
|
||||
|
||||
#define PVR_DUMP_OFFSET_PREFIX "[%0*" PRIx64 "] "
|
||||
|
||||
/** CONTEXTS **/
|
||||
|
||||
#define PVR_DUMP_INDENT_SIZE 2U
|
||||
#define PVR_DUMP_FIELD_COLUMN_WIDTH 36U
|
||||
|
||||
/* This is an invalid context used to permanently mark popped contexts as
|
||||
* unusable. All operations on a context check that it's the "top" context
|
||||
* by ensuring it has no active child. The only way to remove the active child
|
||||
* of a context is by popping the active child directly. Assigning an invalid
|
||||
* context as the active child of a context therefore makes it impossible to
|
||||
* use.
|
||||
*/
|
||||
extern const struct pvr_dump_ctx __pvr_dump_ctx_invalid;
|
||||
|
||||
struct pvr_dump_ctx {
|
||||
/* This is const because only the "top" context should ever be modified. It's
|
||||
* fine to extract information from the parent context, but not to modify it.
|
||||
* There is *one* exception: pvr_dump_ctx_pop() must cast away the const to
|
||||
* return the parent context as the new "top" context. This is considered
|
||||
* sound because the parent context was not const when assigned here in
|
||||
* pvr_dump_ctx_push().
|
||||
*/
|
||||
const struct pvr_dump_ctx *parent;
|
||||
|
||||
/* This is const because it's not meant to be used for access - it's just a
|
||||
* way of checking if this context is the "top" context (see the comment on
|
||||
* __pvr_dump_ctx_invalid for more details). Unlike parent, the const
|
||||
* qualifier here should never be cast away.
|
||||
*/
|
||||
const struct pvr_dump_ctx *active_child;
|
||||
|
||||
FILE *file;
|
||||
const char *name;
|
||||
|
||||
uint32_t allowed_child_depth;
|
||||
uint32_t parent_indent;
|
||||
|
||||
/* User-modifiable values */
|
||||
uint32_t indent;
|
||||
bool ok;
|
||||
};
|
||||
|
||||
static inline uint32_t
|
||||
__pvr_dump_ctx_get_indent(const struct pvr_dump_ctx *const ctx)
|
||||
{
|
||||
return (ctx->parent_indent + ctx->indent) * PVR_DUMP_INDENT_SIZE;
|
||||
}
|
||||
|
||||
struct pvr_dump_buffer_ctx {
|
||||
struct pvr_dump_ctx base;
|
||||
|
||||
const void *initial_ptr;
|
||||
uint64_t capacity;
|
||||
|
||||
/* User-modifiable values */
|
||||
const void *ptr;
|
||||
uint64_t remaining_size;
|
||||
};
|
||||
|
||||
#define pvr_dump_printf(ctx, format, args...) \
|
||||
pvr_dump_printf_cont(ctx, \
|
||||
"%*s" format, \
|
||||
__pvr_dump_ctx_get_indent(ctx), \
|
||||
"", \
|
||||
##args)
|
||||
|
||||
/* Same as pvr_dump_printf(), but with no indent.
|
||||
* Intended for continuation lines.
|
||||
*/
|
||||
#define pvr_dump_printf_cont(ctx, format, args...) \
|
||||
fprintf((ctx)->file, format, ##args)
|
||||
|
||||
#define pvr_dump_println(ctx, format, args...) \
|
||||
pvr_dump_printf(ctx, format "\n", ##args)
|
||||
|
||||
#define pvr_dump_println_cont(ctx, format, args...) \
|
||||
pvr_dump_printf_cont(ctx, format "\n", ##args)
|
||||
|
||||
#define pvr_dump_print_eol(ctx) fprintf((ctx)->file, "\n")
|
||||
|
||||
#define pvr_dump_mark_section(ctx, format, args...) \
|
||||
do { \
|
||||
pvr_dump_print_eol(ctx); \
|
||||
pvr_dump_println(ctx, "------- " format " -------", ##args); \
|
||||
} while (0)
|
||||
|
||||
#define pvr_dump_buffer_print_header_prefix(ctx) \
|
||||
do { \
|
||||
struct pvr_dump_buffer_ctx *_prefix_ctx = (ctx); \
|
||||
pvr_dump_printf(&_prefix_ctx->base, \
|
||||
PVR_DUMP_OFFSET_PREFIX, \
|
||||
u64_dec_digits(_prefix_ctx->capacity), \
|
||||
_prefix_ctx->capacity - _prefix_ctx->remaining_size); \
|
||||
} while (0)
|
||||
|
||||
#define pvr_dump_buffer_print_header_line(ctx, format, args...) \
|
||||
do { \
|
||||
struct pvr_dump_buffer_ctx *_ctx = (ctx); \
|
||||
pvr_dump_buffer_print_header_prefix(_ctx); \
|
||||
pvr_dump_printf_cont(&_ctx->base, format "\n", ##args); \
|
||||
} while (0)
|
||||
|
||||
#define pvr_dump_msg(ctx, prefix, ret, format, args...) \
|
||||
({ \
|
||||
bool _ret = (ret); \
|
||||
struct pvr_dump_ctx *_ctx = (ctx); \
|
||||
pvr_dump_println(_ctx, "<!" prefix "! " format ">", ##args); \
|
||||
if (!_ret) \
|
||||
_ctx->ok = _ret; \
|
||||
_ret; \
|
||||
})
|
||||
|
||||
#define pvr_dump_error(ctx, format, args...) \
|
||||
pvr_dump_msg(ctx, "ERROR", false, format, ##args)
|
||||
|
||||
#define pvr_dump_warn(ctx, format, args...) \
|
||||
pvr_dump_msg(ctx, "WARN", true, format, ##args)
|
||||
|
||||
static inline bool pvr_dump_ctx_require_top(struct pvr_dump_ctx *const ctx)
|
||||
{
|
||||
if (ctx->active_child != NULL)
|
||||
return pvr_dump_error(ctx, "use of non-top context");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void pvr_dump_indent(struct pvr_dump_ctx *const ctx)
|
||||
{
|
||||
ctx->indent++;
|
||||
}
|
||||
|
||||
static inline void pvr_dump_dedent(struct pvr_dump_ctx *const ctx)
|
||||
{
|
||||
if (ctx->indent)
|
||||
ctx->indent--;
|
||||
}
|
||||
|
||||
static inline void __pvr_dump_ctx_init(struct pvr_dump_ctx *const ctx,
|
||||
const struct pvr_dump_ctx *const parent,
|
||||
FILE *const file,
|
||||
const char *const name,
|
||||
const uint32_t allowed_child_depth,
|
||||
const uint32_t parent_indent)
|
||||
{
|
||||
ctx->parent = parent;
|
||||
ctx->active_child = NULL;
|
||||
|
||||
ctx->file = file;
|
||||
ctx->name = name;
|
||||
|
||||
ctx->allowed_child_depth = allowed_child_depth;
|
||||
ctx->parent_indent = parent_indent;
|
||||
ctx->indent = 0;
|
||||
ctx->ok = true;
|
||||
}
|
||||
|
||||
static inline void __pvr_dump_ctx_mark_popped(struct pvr_dump_ctx *const ctx)
|
||||
{
|
||||
ctx->active_child = &__pvr_dump_ctx_invalid;
|
||||
}
|
||||
|
||||
static inline void pvr_dump_begin(struct pvr_dump_ctx *const root_ctx,
|
||||
FILE *const file,
|
||||
const char *const name,
|
||||
const uint32_t max_depth)
|
||||
{
|
||||
__pvr_dump_ctx_init(root_ctx, NULL, file, name, max_depth, 0);
|
||||
|
||||
flockfile(file);
|
||||
pvr_dump_println(root_ctx, "======= BEGIN %s =======", name);
|
||||
}
|
||||
|
||||
static inline bool pvr_dump_end(struct pvr_dump_ctx *const root_ctx)
|
||||
{
|
||||
/* In order to end a dump, we must be in a root context (no parent) and have
|
||||
* no active child context.
|
||||
*/
|
||||
if (!pvr_dump_ctx_require_top(root_ctx))
|
||||
return false;
|
||||
|
||||
if (root_ctx->parent)
|
||||
return pvr_dump_error(root_ctx, "ending non-root context");
|
||||
|
||||
pvr_dump_println(root_ctx, "======= END %s =======", root_ctx->name);
|
||||
funlockfile(root_ctx->file);
|
||||
|
||||
__pvr_dump_ctx_mark_popped(root_ctx);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool pvr_dump_ctx_push(struct pvr_dump_ctx *const ctx,
|
||||
struct pvr_dump_ctx *const parent_ctx)
|
||||
{
|
||||
if (!parent_ctx->ok)
|
||||
return false;
|
||||
|
||||
if (!parent_ctx->allowed_child_depth)
|
||||
return pvr_dump_error(parent_ctx, "context stack depth limit reached");
|
||||
|
||||
__pvr_dump_ctx_init(ctx,
|
||||
parent_ctx,
|
||||
parent_ctx->file,
|
||||
parent_ctx->name,
|
||||
parent_ctx->allowed_child_depth - 1,
|
||||
parent_ctx->parent_indent + parent_ctx->indent);
|
||||
|
||||
parent_ctx->active_child = ctx;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline struct pvr_dump_ctx *
|
||||
pvr_dump_ctx_pop(struct pvr_dump_ctx *const ctx)
|
||||
{
|
||||
struct pvr_dump_ctx *const parent = (struct pvr_dump_ctx *)ctx->parent;
|
||||
|
||||
if (!pvr_dump_ctx_require_top(ctx))
|
||||
return NULL;
|
||||
|
||||
if (!parent) {
|
||||
pvr_dump_error(ctx, "popped root context");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
parent->active_child = NULL;
|
||||
|
||||
__pvr_dump_ctx_mark_popped(ctx);
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
pvr_dump_buffer_ctx_push(struct pvr_dump_buffer_ctx *const ctx,
|
||||
struct pvr_dump_ctx *const parent_ctx,
|
||||
const void *const initial_ptr,
|
||||
const uint64_t size)
|
||||
{
|
||||
if (!pvr_dump_ctx_push(&ctx->base, parent_ctx))
|
||||
return false;
|
||||
|
||||
ctx->initial_ptr = initial_ptr;
|
||||
ctx->capacity = size;
|
||||
|
||||
ctx->ptr = initial_ptr;
|
||||
ctx->remaining_size = size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline struct pvr_dump_ctx *
|
||||
pvr_dump_buffer_ctx_pop(struct pvr_dump_buffer_ctx *const ctx)
|
||||
{
|
||||
return pvr_dump_ctx_pop(&ctx->base);
|
||||
}
|
||||
|
||||
bool pvr_dump_buffer_hex(struct pvr_dump_buffer_ctx *ctx, uint64_t nr_bytes);
|
||||
|
||||
static inline void __pvr_dump_buffer_advance(struct pvr_dump_buffer_ctx *ctx,
|
||||
const uint64_t nr_bytes)
|
||||
{
|
||||
ctx->ptr = (uint8_t *)ctx->ptr + nr_bytes;
|
||||
ctx->remaining_size -= nr_bytes;
|
||||
}
|
||||
|
||||
static inline bool pvr_dump_buffer_advance(struct pvr_dump_buffer_ctx *ctx,
|
||||
const uint64_t nr_bytes)
|
||||
{
|
||||
if (!ctx->base.ok || !pvr_dump_ctx_require_top(&ctx->base))
|
||||
return false;
|
||||
|
||||
if (nr_bytes > ctx->remaining_size)
|
||||
return pvr_dump_error(&ctx->base, "advanced past end of context buffer");
|
||||
|
||||
__pvr_dump_buffer_advance(ctx, nr_bytes);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void __pvr_dump_buffer_rewind(struct pvr_dump_buffer_ctx *ctx,
|
||||
const uint32_t nr_bytes)
|
||||
{
|
||||
ctx->ptr = (uint8_t *)ctx->ptr - nr_bytes;
|
||||
ctx->remaining_size += nr_bytes;
|
||||
}
|
||||
|
||||
static inline bool pvr_dump_buffer_rewind(struct pvr_dump_buffer_ctx *ctx,
|
||||
const uint32_t nr_bytes)
|
||||
{
|
||||
if (!ctx->base.ok || !pvr_dump_ctx_require_top(&ctx->base))
|
||||
return false;
|
||||
|
||||
if (nr_bytes > ctx->capacity - ctx->remaining_size)
|
||||
return pvr_dump_error(&ctx->base, "rewound past start of context buffer");
|
||||
|
||||
__pvr_dump_buffer_rewind(ctx, nr_bytes);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool pvr_dump_buffer_truncate(struct pvr_dump_buffer_ctx *ctx,
|
||||
const uint64_t remaining_size)
|
||||
{
|
||||
if (!ctx->base.ok || !pvr_dump_ctx_require_top(&ctx->base))
|
||||
return false;
|
||||
|
||||
if (remaining_size > ctx->remaining_size)
|
||||
return pvr_dump_error(&ctx->base, "truncated to larger size");
|
||||
|
||||
ctx->remaining_size = remaining_size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline const void *restrict pvr_dump_buffer_peek(
|
||||
struct pvr_dump_buffer_ctx *const restrict ctx,
|
||||
const uint64_t nr_bytes)
|
||||
{
|
||||
if (!ctx->base.ok || !pvr_dump_ctx_require_top(&ctx->base))
|
||||
return NULL;
|
||||
|
||||
if (nr_bytes > ctx->remaining_size) {
|
||||
pvr_dump_error(&ctx->base, "peeked past end of context buffer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ctx->ptr;
|
||||
}
|
||||
|
||||
static inline const void *restrict pvr_dump_buffer_take(
|
||||
struct pvr_dump_buffer_ctx *const restrict ctx,
|
||||
const uint64_t nr_bytes)
|
||||
{
|
||||
const void *const ptr = pvr_dump_buffer_peek(ctx, nr_bytes);
|
||||
|
||||
if (ptr)
|
||||
__pvr_dump_buffer_advance(ctx, nr_bytes);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static inline void
|
||||
pvr_dump_buffer_restart(struct pvr_dump_buffer_ctx *const ctx)
|
||||
{
|
||||
ctx->ptr = ctx->initial_ptr;
|
||||
ctx->remaining_size = ctx->capacity;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
Field printers
|
||||
*****************************************************************************/
|
||||
|
||||
#define pvr_dump_field(ctx, name, format, args...) \
|
||||
pvr_dump_println(ctx, \
|
||||
"%-*s : " format, \
|
||||
PVR_DUMP_FIELD_COLUMN_WIDTH - \
|
||||
__pvr_dump_ctx_get_indent(ctx), \
|
||||
name, \
|
||||
##args)
|
||||
|
||||
#define pvr_dump_field_computed(ctx, name, format, raw_format, args...) \
|
||||
pvr_dump_field(ctx, name, format " (" raw_format ")", ##args)
|
||||
|
||||
#define pvr_dump_field_error(ctx, format, args...) \
|
||||
({ \
|
||||
struct pvr_dump_ctx *_ctx = (ctx); \
|
||||
pvr_dump_field(_ctx, "<!ERROR!>", "<" format ">", ##args); \
|
||||
_ctx->ok = false; \
|
||||
false; \
|
||||
})
|
||||
|
||||
/*****************************************************************************
|
||||
Field printers: integers
|
||||
*****************************************************************************/
|
||||
|
||||
static inline void pvr_dump_field_u32(struct pvr_dump_ctx *const ctx,
|
||||
const char *const name,
|
||||
const uint32_t value)
|
||||
{
|
||||
pvr_dump_field(ctx, name, "%" PRIu32, value);
|
||||
}
|
||||
|
||||
static inline void pvr_dump_field_u32_units(struct pvr_dump_ctx *const ctx,
|
||||
const char *const name,
|
||||
const uint32_t value,
|
||||
const char *const units)
|
||||
{
|
||||
pvr_dump_field(ctx, name, "%" PRIu32 " %s", value, units);
|
||||
}
|
||||
|
||||
static inline void pvr_dump_field_u32_offset(struct pvr_dump_ctx *const ctx,
|
||||
const char *const name,
|
||||
const uint32_t value,
|
||||
const uint32_t offset)
|
||||
{
|
||||
pvr_dump_field_computed(ctx,
|
||||
name,
|
||||
"%" PRIu32,
|
||||
"%" PRIu32 " + %" PRIu32,
|
||||
value + offset,
|
||||
value,
|
||||
offset);
|
||||
}
|
||||
|
||||
static inline void pvr_dump_field_u32_scaled(struct pvr_dump_ctx *const ctx,
|
||||
const char *const name,
|
||||
const uint32_t value,
|
||||
const uint32_t scale)
|
||||
{
|
||||
pvr_dump_field_computed(ctx,
|
||||
name,
|
||||
"%" PRIu32,
|
||||
"%" PRIu32 " x %" PRIu32,
|
||||
value * scale,
|
||||
value,
|
||||
scale);
|
||||
}
|
||||
|
||||
static inline void
|
||||
pvr_dump_field_u32_scaled_units(struct pvr_dump_ctx *const ctx,
|
||||
const char *const name,
|
||||
const uint32_t value,
|
||||
const uint32_t scale,
|
||||
const char *const units)
|
||||
{
|
||||
pvr_dump_field_computed(ctx,
|
||||
name,
|
||||
"%" PRIu32 " %s",
|
||||
"%" PRIu32 " x %" PRIu32 " %s",
|
||||
value * scale,
|
||||
units,
|
||||
value,
|
||||
scale,
|
||||
units);
|
||||
}
|
||||
|
||||
static inline void pvr_dump_field_u32_zero(struct pvr_dump_ctx *const ctx,
|
||||
const char *const name,
|
||||
const uint32_t value,
|
||||
const uint32_t zero_value)
|
||||
{
|
||||
if (value)
|
||||
pvr_dump_field_u32(ctx, name, value);
|
||||
else
|
||||
pvr_dump_field_computed(ctx, name, "%" PRIu32, "0", zero_value);
|
||||
}
|
||||
|
||||
static inline void pvr_dump_field_x32(struct pvr_dump_ctx *const ctx,
|
||||
const char *const name,
|
||||
const uint32_t value,
|
||||
const uint32_t chars)
|
||||
{
|
||||
pvr_dump_field(ctx,
|
||||
name,
|
||||
"0x%0*" PRIx32,
|
||||
chars,
|
||||
value & BITFIELD_MASK(chars * 4));
|
||||
}
|
||||
|
||||
static inline void pvr_dump_field_u64(struct pvr_dump_ctx *const ctx,
|
||||
const char *const name,
|
||||
const uint64_t value)
|
||||
{
|
||||
pvr_dump_field(ctx, name, "%" PRIu64, value);
|
||||
}
|
||||
|
||||
static inline void pvr_dump_field_u64_units(struct pvr_dump_ctx *const ctx,
|
||||
const char *const name,
|
||||
const uint64_t value,
|
||||
const char *const units)
|
||||
{
|
||||
pvr_dump_field(ctx, name, "%" PRIu64 " %s", value, units);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
Field printers: floating point
|
||||
*****************************************************************************/
|
||||
|
||||
static inline void pvr_dump_field_f32(struct pvr_dump_ctx *const ctx,
|
||||
const char *const name,
|
||||
const float value)
|
||||
{
|
||||
pvr_dump_field_computed(ctx, name, "%f", "0x%08" PRIx32, value, fui(value));
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
Field printers: fixed point
|
||||
*****************************************************************************/
|
||||
|
||||
/* clang-format off */
|
||||
static const char *const __fixed_frac_str_table_4[1 << 4] = {
|
||||
"0", "0625", "125", "1875", "25", "3125", "375", "4375",
|
||||
"5", "5625", "625", "6875", "75", "8125", "875", "9375",
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
static inline void pvr_dump_field_uq4_4(struct pvr_dump_ctx *const ctx,
|
||||
const char *const name,
|
||||
const uint32_t raw_value)
|
||||
{
|
||||
const uint32_t int_part = (raw_value & BITFIELD_RANGE(4, 4)) >> 4;
|
||||
const uint32_t frac_part = raw_value & BITFIELD_MASK(4);
|
||||
|
||||
pvr_dump_field_computed(ctx,
|
||||
name,
|
||||
"%" PRIu32 ".%s",
|
||||
"0x%02" PRIx32, /* Or %0*x where *=(nr_bits+3)/4 */
|
||||
int_part,
|
||||
__fixed_frac_str_table_4[frac_part],
|
||||
raw_value & BITFIELD_MASK(8));
|
||||
}
|
||||
|
||||
static inline void pvr_dump_field_uq4_4_offset(struct pvr_dump_ctx *const ctx,
|
||||
const char *const name,
|
||||
const uint32_t raw_value,
|
||||
const uint32_t raw_offset)
|
||||
{
|
||||
const uint32_t raw_offset_value = raw_value + raw_offset;
|
||||
|
||||
const uint32_t int_part = (raw_offset_value & BITFIELD_RANGE(4, 4)) >> 4;
|
||||
const uint32_t frac_part = raw_offset_value & BITFIELD_MASK(4);
|
||||
|
||||
pvr_dump_field_computed(ctx,
|
||||
name,
|
||||
"%" PRIu32 ".%s",
|
||||
"0x%02" PRIx32 " + 0x%02" PRIx32,
|
||||
int_part,
|
||||
__fixed_frac_str_table_4[frac_part],
|
||||
raw_value & BITFIELD_MASK(8),
|
||||
raw_offset);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
Field printers: device address
|
||||
*****************************************************************************/
|
||||
|
||||
static inline void pvr_dump_field_addr_non_null(struct pvr_dump_ctx *const ctx,
|
||||
const char *const name,
|
||||
const pvr_dev_addr_t value)
|
||||
{
|
||||
pvr_dump_field(ctx, name, PVR_DEV_ADDR_FMT, value.addr);
|
||||
}
|
||||
|
||||
static inline void pvr_dump_field_addr(struct pvr_dump_ctx *const ctx,
|
||||
const char *const name,
|
||||
const pvr_dev_addr_t value)
|
||||
{
|
||||
if (value.addr)
|
||||
pvr_dump_field_addr_non_null(ctx, name, value);
|
||||
else
|
||||
pvr_dump_field(ctx, name, "<null>");
|
||||
}
|
||||
|
||||
static inline void pvr_dump_field_addr_split(struct pvr_dump_ctx *const ctx,
|
||||
const char *const name,
|
||||
const pvr_dev_addr_t msb,
|
||||
const pvr_dev_addr_t lsb)
|
||||
{
|
||||
pvr_dump_field_addr(ctx, name, PVR_DEV_ADDR(msb.addr | lsb.addr));
|
||||
|
||||
pvr_dump_indent(ctx);
|
||||
pvr_dump_field_addr_non_null(ctx, "msb", msb);
|
||||
pvr_dump_field_addr_non_null(ctx, "lsb", lsb);
|
||||
pvr_dump_dedent(ctx);
|
||||
}
|
||||
|
||||
static inline void pvr_dump_field_addr_offset(struct pvr_dump_ctx *const ctx,
|
||||
const char *const name,
|
||||
const pvr_dev_addr_t value,
|
||||
const pvr_dev_addr_t base)
|
||||
{
|
||||
pvr_dump_field_computed(ctx,
|
||||
name,
|
||||
PVR_DEV_ADDR_FMT,
|
||||
PVR_DEV_ADDR_FMT " + " PVR_DEV_ADDR_FMT,
|
||||
PVR_DEV_ADDR_OFFSET(base, value.addr).addr,
|
||||
base.addr,
|
||||
value.addr);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
Field printers: enums
|
||||
*****************************************************************************/
|
||||
|
||||
#define pvr_dump_field_enum(ctx, name, value, to_str) \
|
||||
do { \
|
||||
__typeof__(value) _value = (value); \
|
||||
const char *_str = to_str(_value); \
|
||||
if (!_str) \
|
||||
_str = "<unknown>"; \
|
||||
pvr_dump_field_computed(ctx, name, "%s", "%u", _str, _value); \
|
||||
} while (0)
|
||||
|
||||
static inline const char *__bool_to_str(const bool b)
|
||||
{
|
||||
return b ? "yes" : "no";
|
||||
}
|
||||
|
||||
/* A bool is just an enum with two values. */
|
||||
static inline void pvr_dump_field_bool(struct pvr_dump_ctx *const ctx,
|
||||
const char *const name,
|
||||
const bool value)
|
||||
{
|
||||
pvr_dump_field_enum(ctx, name, value, __bool_to_str);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
Field printers: string
|
||||
*****************************************************************************/
|
||||
|
||||
static inline void pvr_dump_field_string(struct pvr_dump_ctx *const ctx,
|
||||
const char *const name,
|
||||
const char *const value)
|
||||
{
|
||||
pvr_dump_field(ctx, name, "%s", value);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
Field printers: not present
|
||||
*****************************************************************************/
|
||||
|
||||
static inline void pvr_dump_field_no_fields(struct pvr_dump_ctx *const ctx)
|
||||
{
|
||||
pvr_dump_println(ctx, "<no fields>");
|
||||
}
|
||||
|
||||
static inline void pvr_dump_field_not_present(struct pvr_dump_ctx *const ctx,
|
||||
const char *const name)
|
||||
{
|
||||
pvr_dump_field(ctx, name, "<not present>");
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
Field printers: helpers for members
|
||||
*****************************************************************************/
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
#define pvr_dump_field_member_u32(ctx, compound, member) \
|
||||
pvr_dump_field_u32(ctx, #member, (compound)->member)
|
||||
|
||||
#define pvr_dump_field_member_u32_units(ctx, compound, member, units) \
|
||||
pvr_dump_field_u32_units(ctx, #member, (compound)->member, units)
|
||||
|
||||
#define pvr_dump_field_member_u32_offset(ctx, compound, member, offset) \
|
||||
pvr_dump_field_u32_offset(ctx, #member, (compound)->member, offset)
|
||||
|
||||
#define pvr_dump_field_member_u32_scaled(ctx, compound, member, scale) \
|
||||
pvr_dump_field_u32_scaled(ctx, #member, (compound)->member, scale)
|
||||
|
||||
#define pvr_dump_field_member_u32_scaled_units(ctx, compound, member, scale, units) \
|
||||
pvr_dump_field_u32_scaled_units(ctx, #member, (compound)->member, scale, units)
|
||||
|
||||
#define pvr_dump_field_member_u32_zero(ctx, compound, member, zero_value) \
|
||||
pvr_dump_field_u32_zero(ctx, #member, (compound)->member, zero_value)
|
||||
|
||||
#define pvr_dump_field_member_x32(ctx, compound, member, chars) \
|
||||
pvr_dump_field_x32(ctx, #member, (compound)->member, chars)
|
||||
|
||||
#define pvr_dump_field_member_u64(ctx, compound, member) \
|
||||
pvr_dump_field_u64(ctx, #member, (compound)->member)
|
||||
|
||||
#define pvr_dump_field_member_u64_units(ctx, compound, member, units) \
|
||||
pvr_dump_field_u64_units(ctx, #member, (compound)->member, units)
|
||||
|
||||
#define pvr_dump_field_member_f32(ctx, compound, member) \
|
||||
pvr_dump_field_f32(ctx, #member, (compound)->member)
|
||||
|
||||
#define pvr_dump_field_member_uq4_4(ctx, compound, member) \
|
||||
pvr_dump_field_uq4_4(ctx, #member, (compound)->member)
|
||||
|
||||
#define pvr_dump_field_member_uq4_4_offset(ctx, compound, member, raw_offset) \
|
||||
pvr_dump_field_uq4_4_offset(ctx, #member, (compound)->member, raw_offset)
|
||||
|
||||
#define pvr_dump_field_member_addr(ctx, compound, member) \
|
||||
pvr_dump_field_addr(ctx, #member, (compound)->member)
|
||||
|
||||
#define pvr_dump_field_member_addr_offset(ctx, compound, member, base) \
|
||||
pvr_dump_field_addr_offset(ctx, #member, (compound)->member, base)
|
||||
|
||||
#define pvr_dump_field_member_enum(ctx, compound, member, to_str) \
|
||||
pvr_dump_field_enum(ctx, #member, (compound)->member, to_str)
|
||||
|
||||
#define pvr_dump_field_member_bool(ctx, compound, member) \
|
||||
pvr_dump_field_bool(ctx, #member, (compound)->member)
|
||||
|
||||
#define pvr_dump_field_member_string(ctx, compound, member) \
|
||||
pvr_dump_field_string(ctx, #member, (compound)->member)
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
#define pvr_dump_field_member_not_present(ctx, compound, member) \
|
||||
do { \
|
||||
(void)&(compound)->member; \
|
||||
pvr_dump_field_not_present(ctx, #member); \
|
||||
} while (0)
|
||||
|
||||
#endif /* PVR_DUMP_H */
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright © 2023 Imagination Technologies Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "git_sha1.h"
|
||||
#include "pvr_dump_info.h"
|
||||
#include "pvr_dump.h"
|
||||
|
||||
static inline void pvr_dump_field_bvnc(struct pvr_dump_ctx *ctx,
|
||||
const char *const name,
|
||||
const struct pvr_device_info *info)
|
||||
{
|
||||
pvr_dump_field_computed(ctx,
|
||||
name,
|
||||
"%" PRIu16 ".%" PRIu16 ".%" PRIu16 ".%" PRIu16,
|
||||
"0x%08" PRIx64,
|
||||
info->ident.b,
|
||||
info->ident.v,
|
||||
info->ident.n,
|
||||
info->ident.c,
|
||||
pvr_get_packed_bvnc(info));
|
||||
}
|
||||
|
||||
static inline void pvr_dump_field_drm_version(struct pvr_dump_ctx *ctx,
|
||||
const char *const name,
|
||||
const char *const drm_name,
|
||||
int drm_version_major,
|
||||
int drm_version_minor,
|
||||
int drm_version_patchlevel,
|
||||
const char *const drm_date)
|
||||
{
|
||||
pvr_dump_field(ctx,
|
||||
name,
|
||||
"%s %d.%d.%d (%s)",
|
||||
drm_name,
|
||||
drm_version_major,
|
||||
drm_version_minor,
|
||||
drm_version_patchlevel,
|
||||
drm_date);
|
||||
}
|
||||
|
||||
static inline void pvr_dump_field_compatible_strings(struct pvr_dump_ctx *ctx,
|
||||
char *const *comp)
|
||||
{
|
||||
char *const *temp_comp = comp;
|
||||
uint32_t count_log10;
|
||||
uint32_t index = 0;
|
||||
|
||||
if (!*comp) {
|
||||
pvr_dump_println(ctx, "<empty>");
|
||||
return;
|
||||
}
|
||||
|
||||
while (*temp_comp++)
|
||||
index++;
|
||||
|
||||
count_log10 = u32_dec_digits(index);
|
||||
index = 0;
|
||||
|
||||
while (*comp)
|
||||
pvr_dump_println(ctx, "[%0*" PRIu32 "] %s", count_log10, index++, *comp++);
|
||||
}
|
||||
|
||||
void pvr_dump_physical_device_info(const struct pvr_device_dump_info *dump_info)
|
||||
{
|
||||
const struct pvr_device_runtime_info *run_info =
|
||||
dump_info->device_runtime_info;
|
||||
const struct pvr_device_info *dev_info = dump_info->device_info;
|
||||
struct pvr_dump_ctx ctx;
|
||||
|
||||
pvr_dump_begin(&ctx, stderr, "DEBUG INFORMATION", 1);
|
||||
|
||||
pvr_dump_mark_section(&ctx, "General Info");
|
||||
pvr_dump_indent(&ctx);
|
||||
pvr_dump_field_string(&ctx, "Public Name", dev_info->ident.public_name);
|
||||
pvr_dump_field_string(&ctx, "Series Name", dev_info->ident.series_name);
|
||||
pvr_dump_field_bvnc(&ctx, "BVNC", dev_info);
|
||||
pvr_dump_field_drm_version(&ctx,
|
||||
"DRM Display Driver Version",
|
||||
dump_info->drm_display.name,
|
||||
dump_info->drm_display.major,
|
||||
dump_info->drm_display.minor,
|
||||
dump_info->drm_display.patchlevel,
|
||||
dump_info->drm_display.date);
|
||||
pvr_dump_field_drm_version(&ctx,
|
||||
"DRM Render Driver Version",
|
||||
dump_info->drm_render.name,
|
||||
dump_info->drm_render.major,
|
||||
dump_info->drm_render.minor,
|
||||
dump_info->drm_render.patchlevel,
|
||||
dump_info->drm_render.date);
|
||||
pvr_dump_field_string(&ctx, "MESA ", PACKAGE_VERSION MESA_GIT_SHA1);
|
||||
pvr_dump_dedent(&ctx);
|
||||
|
||||
if (dump_info->drm_display.comp) {
|
||||
pvr_dump_mark_section(&ctx, "Display Platform Compatible Strings");
|
||||
pvr_dump_indent(&ctx);
|
||||
pvr_dump_field_compatible_strings(&ctx, dump_info->drm_display.comp);
|
||||
pvr_dump_dedent(&ctx);
|
||||
}
|
||||
|
||||
pvr_dump_mark_section(&ctx, "Render Platform Compatible Strings");
|
||||
pvr_dump_indent(&ctx);
|
||||
pvr_dump_field_compatible_strings(&ctx, dump_info->drm_render.comp);
|
||||
pvr_dump_dedent(&ctx);
|
||||
pvr_dump_print_eol(&ctx);
|
||||
|
||||
pvr_dump_mark_section(&ctx, "Runtime Info");
|
||||
pvr_dump_indent(&ctx);
|
||||
pvr_dump_field_member_u64(&ctx, run_info, cdm_max_local_mem_size_regs);
|
||||
pvr_dump_field_member_u64_units(&ctx, run_info, max_free_list_size, "bytes");
|
||||
pvr_dump_field_member_u64_units(&ctx, run_info, min_free_list_size, "bytes");
|
||||
pvr_dump_field_member_u64_units(&ctx,
|
||||
run_info,
|
||||
reserved_shared_size,
|
||||
"bytes");
|
||||
pvr_dump_field_member_u64_units(&ctx,
|
||||
run_info,
|
||||
total_reserved_partition_size,
|
||||
"bytes");
|
||||
pvr_dump_field_member_u32(&ctx, run_info, core_count);
|
||||
pvr_dump_field_member_u64(&ctx, run_info, max_coeffs);
|
||||
pvr_dump_field_member_u64(&ctx, run_info, num_phantoms);
|
||||
pvr_dump_dedent(&ctx);
|
||||
pvr_dump_print_eol(&ctx);
|
||||
|
||||
pvr_dump_end(&ctx);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright © 2023 Imagination Technologies Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PVR_DUMP_INFO_H
|
||||
#define PVR_DUMP_INFO_H
|
||||
|
||||
#include "pvr_device_info.h"
|
||||
|
||||
struct pvr_device_dump_info {
|
||||
const struct pvr_device_info *device_info;
|
||||
const struct pvr_device_runtime_info *device_runtime_info;
|
||||
struct {
|
||||
int patchlevel;
|
||||
int major;
|
||||
int minor;
|
||||
const char *name;
|
||||
const char *date;
|
||||
char *const *comp;
|
||||
} drm_display, drm_render;
|
||||
};
|
||||
|
||||
void pvr_dump_physical_device_info(const struct pvr_device_dump_info *dump_info);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright © 2025 Imagination Technologies Ltd.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef PVR_IFACE_H
|
||||
#define PVR_IFACE_H
|
||||
|
||||
/**
|
||||
* \file pvr_iface.h
|
||||
*
|
||||
* \brief USC program interface.
|
||||
*/
|
||||
|
||||
/** Query availability shader data; shared registers. */
|
||||
enum pvr_query_availability_data {
|
||||
PVR_QUERY_AVAILABILITY_DATA_INDEX_COUNT,
|
||||
|
||||
PVR_QUERY_AVAILABILITY_DATA_INDEX_BO_LO,
|
||||
PVR_QUERY_AVAILABILITY_DATA_INDEX_BO_HI,
|
||||
|
||||
PVR_QUERY_AVAILABILITY_DATA_BO_LO,
|
||||
PVR_QUERY_AVAILABILITY_DATA_BO_HI,
|
||||
|
||||
_PVR_QUERY_AVAILABILITY_DATA_COUNT,
|
||||
};
|
||||
|
||||
/** Query copy shader data; shared registers. */
|
||||
enum pvr_query_copy_data {
|
||||
PVR_QUERY_COPY_DATA_INDEX_COUNT,
|
||||
|
||||
PVR_QUERY_COPY_DATA_DEST_BO_LO,
|
||||
PVR_QUERY_COPY_DATA_DEST_BO_HI,
|
||||
|
||||
PVR_QUERY_COPY_DATA_AVAILABILITY_BO_LO,
|
||||
PVR_QUERY_COPY_DATA_AVAILABILITY_BO_HI,
|
||||
|
||||
PVR_QUERY_COPY_DATA_RESULT_BO_LO,
|
||||
PVR_QUERY_COPY_DATA_RESULT_BO_HI,
|
||||
|
||||
PVR_QUERY_COPY_DATA_DEST_STRIDE,
|
||||
|
||||
PVR_QUERY_COPY_DATA_FLAGS,
|
||||
|
||||
_PVR_QUERY_COPY_DATA_COUNT,
|
||||
};
|
||||
|
||||
/** Query reset shader data; shared registers. */
|
||||
enum pvr_query_reset_data {
|
||||
PVR_QUERY_RESET_DATA_INDEX_COUNT,
|
||||
|
||||
PVR_QUERY_RESET_DATA_RESULT_BO_LO,
|
||||
PVR_QUERY_RESET_DATA_RESULT_BO_HI,
|
||||
|
||||
PVR_QUERY_RESET_DATA_AVAILABILITY_BO_LO,
|
||||
PVR_QUERY_RESET_DATA_AVAILABILITY_BO_HI,
|
||||
|
||||
_PVR_QUERY_RESET_DATA_COUNT,
|
||||
};
|
||||
|
||||
/** Clear attachment shader data; shared registers. */
|
||||
enum pvr_clear_attach_data {
|
||||
PVR_CLEAR_ATTACH_DATA_DWORD0,
|
||||
PVR_CLEAR_ATTACH_DATA_DWORD1,
|
||||
PVR_CLEAR_ATTACH_DATA_DWORD2,
|
||||
PVR_CLEAR_ATTACH_DATA_DWORD3,
|
||||
|
||||
PVR_CLEAR_ATTACH_DATA_TILE_ADDR_LO,
|
||||
PVR_CLEAR_ATTACH_DATA_TILE_ADDR_HI,
|
||||
|
||||
_PVR_CLEAR_ATTACH_DATA_COUNT,
|
||||
};
|
||||
|
||||
/** SPM load shader data; shared registers. */
|
||||
enum pvr_spm_load_data {
|
||||
PVR_SPM_LOAD_DATA_SMP = 0,
|
||||
|
||||
PVR_SPM_LOAD_DATA_REG_TEX = 4,
|
||||
|
||||
PVR_SPM_LOAD_DATA_BUF_TEX_0 = 8,
|
||||
PVR_SPM_LOAD_DATA_BUF_ADDR_0 = 12,
|
||||
|
||||
PVR_SPM_LOAD_DATA_BUF_ADDR_1 = 14,
|
||||
PVR_SPM_LOAD_DATA_BUF_TEX_1 = 16,
|
||||
|
||||
PVR_SPM_LOAD_DATA_BUF_TEX_2 = 20,
|
||||
PVR_SPM_LOAD_DATA_BUF_ADDR_2 = 24,
|
||||
|
||||
PVR_SPM_LOAD_DATA_BUF_ADDR_3 = 26,
|
||||
PVR_SPM_LOAD_DATA_BUF_TEX_3 = 28,
|
||||
|
||||
PVR_SPM_LOAD_DATA_BUF_TEX_4 = 32,
|
||||
PVR_SPM_LOAD_DATA_BUF_ADDR_4 = 36,
|
||||
|
||||
PVR_SPM_LOAD_DATA_BUF_ADDR_5 = 38,
|
||||
PVR_SPM_LOAD_DATA_BUF_TEX_5 = 40,
|
||||
|
||||
PVR_SPM_LOAD_DATA_BUF_TEX_6 = 44,
|
||||
PVR_SPM_LOAD_DATA_BUF_ADDR_6 = 48,
|
||||
|
||||
_PVR_SPM_LOAD_DATA_COUNT = 50,
|
||||
};
|
||||
|
||||
/** Load/store sr shader data; vertex input registers. */
|
||||
enum pvr_load_store_sr_data {
|
||||
PVR_LOAD_STORE_SR_DATA_SIZE_ADDR_LO,
|
||||
PVR_LOAD_STORE_SR_DATA_SIZE_ADDR_HI,
|
||||
|
||||
PVR_LOAD_STORE_SR_DATA_STORE_ADDR_LO,
|
||||
PVR_LOAD_STORE_SR_DATA_STORE_ADDR_HI,
|
||||
|
||||
_PVR_LOAD_STORE_SR_DATA_COUNT,
|
||||
};
|
||||
|
||||
/** IDFWDF shader data; shared registers. */
|
||||
enum pvr_idfwdf_sr_data {
|
||||
PVR_IDFWDF_DATA_TEX = 0,
|
||||
PVR_IDFWDF_DATA_SMP = 4,
|
||||
|
||||
PVR_IDFWDF_DATA_ADDR_LO,
|
||||
PVR_IDFWDF_DATA_ADDR_HI,
|
||||
|
||||
_PVR_IDFWDF_DATA_COUNT,
|
||||
};
|
||||
|
||||
#define PVR_IDFWDF_TEX_FORMAT VK_FORMAT_R32G32B32A32_SFLOAT
|
||||
#define PVR_IDFWDF_TEX_WIDTH 4U
|
||||
#define PVR_IDFWDF_TEX_HEIGHT 2U
|
||||
#define PVR_IDFWDF_TEX_STRIDE 4U
|
||||
|
||||
/** pck_info and pck_format bitfield helpers. */
|
||||
#define PVR_PCK_FORMAT_INVALID 0b11111U
|
||||
#define PVR_PCK_INFO_FORMAT_LENGTH 5U
|
||||
#define PVR_PCK_INFO_FORMAT_OFFSET 0U
|
||||
#define PVR_PCK_INFO_SPLIT_OFFSET 5U
|
||||
#define PVR_PCK_INFO_SCALE_OFFSET 6U
|
||||
#define PVR_PCK_INFO_ROUNDZERO_OFFSET 7U
|
||||
#define PVR_PCK_INFO_UNORM_OFFSET 8U
|
||||
#define PVR_PCK_INFO_SPLIT_BIT BITFIELD_BIT(PVR_PCK_INFO_SPLIT_OFFSET)
|
||||
#define PVR_PCK_INFO_SCALE_BIT BITFIELD_BIT(PVR_PCK_INFO_SCALE_OFFSET)
|
||||
#define PVR_PCK_INFO_ROUNDZERO_BIT BITFIELD_BIT(PVR_PCK_INFO_ROUNDZERO_OFFSET)
|
||||
#define PVR_PCK_INFO_UNORM_BIT BITFIELD_BIT(PVR_PCK_INFO_UNORM_OFFSET)
|
||||
|
||||
#endif /* PVR_IFACE_H */
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright © 2022 Imagination Technologies Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constants for VkPhysicalDeviceLimits.
|
||||
*/
|
||||
|
||||
#ifndef PVR_LIMITS_H
|
||||
#define PVR_LIMITS_H
|
||||
|
||||
#include "hwdef/rogue_hw_defs.h"
|
||||
#include "pvr_device_info.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
#define PVR_MAX_COLOR_ATTACHMENTS PVR_NUM_PBE_EMIT_REGS
|
||||
#define PVR_MAX_QUEUES 2U
|
||||
#define PVR_MAX_VIEWPORTS 1U
|
||||
#define PVR_MAX_NEG_OFFSCREEN_OFFSET 4096U
|
||||
#define PVR_MAX_MULTIVIEW 6U
|
||||
|
||||
#define PVR_MAX_PUSH_CONSTANTS_SIZE 128U
|
||||
|
||||
#define PVR_LINE_WIDTH_MIN (1.0f / 16.0f)
|
||||
#define PVR_LINE_WIDTH_MAX 16.0f
|
||||
#define PVR_LINE_WIDTH_GRANULARITY (1.0f / 16.0f)
|
||||
|
||||
#define PVR_POINT_SIZE_RANGE_MIN 1.0f
|
||||
#define PVR_POINT_SIZE_RANGE_MAX 511.0f
|
||||
#define PVR_POINT_SIZE_GRANULARITY 0.0625f
|
||||
|
||||
#define PVR_TEX_FORMAT_COUNT \
|
||||
(ROGUE_TEXSTATE_IMAGE_WORD0_TEXFORMAT_MAX_SIZE + 1U)
|
||||
|
||||
#define PVR_MAX_ARRAY_LAYERS (ROGUE_TEXSTATE_IMAGE_WORD1_DEPTH_MAX_SIZE + 1U)
|
||||
|
||||
#define PVR_MAX_DESCRIPTOR_SETS 4U
|
||||
#define PVR_MAX_DESCRIPTOR_SET_UNIFORM_DYNAMIC_BUFFERS 8U
|
||||
#define PVR_MAX_DESCRIPTOR_SET_STORAGE_DYNAMIC_BUFFERS 8U
|
||||
|
||||
#define PVR_MAX_DESCRIPTORS_PER_SET 1024U
|
||||
|
||||
#define PVR_MAX_FRAMEBUFFER_LAYERS PVR_MAX_ARRAY_LAYERS
|
||||
|
||||
/* The limit is somewhat arbitrary, it just translates into more pds code
|
||||
* and larger arrays, 32 appears to be the popular (and highest choice) across
|
||||
* other implementations.
|
||||
*/
|
||||
#define PVR_MAX_VERTEX_INPUT_BINDINGS 16U
|
||||
|
||||
#define PVR_TEXEL_BUFFER_OFFSET_ALIGNMENT 16U
|
||||
#define PVR_UNIFORM_BUFFER_OFFSET_ALIGNMENT 4U
|
||||
#define PVR_STORAGE_BUFFER_OFFSET_ALIGNMENT 4U
|
||||
|
||||
#define PVR_MAX_USER_PLANES 8U
|
||||
|
||||
/* We need one RenderTarget per supported MSAA mode as each render target
|
||||
* contains state that is dependent on the sample count of the render that is
|
||||
* rendering to it.
|
||||
*
|
||||
* As we do not know the sample count until we know the renderpass framebuffer
|
||||
* combination being used, we create one per supported sample mode.
|
||||
*/
|
||||
#define PVR_RENDER_TARGETS_PER_FRAMEBUFFER(dev_info) \
|
||||
({ \
|
||||
uint32_t __ret = PVR_GET_FEATURE_VALUE(dev_info, max_multisample, 4U); \
|
||||
util_logbase2(__ret) + 1; \
|
||||
})
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright © 2022 Imagination Technologies Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "pvr_util.h"
|
||||
|
||||
/* Generated by floor(n/log2(10)). This is a compact representation of a
|
||||
* log10(2**n) estimation. Estimations of log2(n) +1/-0 are very fast on modern
|
||||
* CPUs with clz (or equivalent) instructions, which makes this log2-indexed
|
||||
* lookup both compact and fast. Assuming an input of log2(x) +1/-0; this lut
|
||||
* should produce an output of ceil(log10(x)) +0/-1.
|
||||
*/
|
||||
const uint8_t est_log10_from_log2[64 + 1] = {
|
||||
0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
|
||||
5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9,
|
||||
10, 10, 10, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15,
|
||||
15, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 18, 19,
|
||||
};
|
||||
|
||||
/* Generated by 10**n with one exception: we make the first power of ten 0
|
||||
* (instead of 1) to ensure a 0-input produces a single digit (instead of no
|
||||
* digits).
|
||||
*/
|
||||
const uint32_t u32_powers_of_ten[10] = {
|
||||
UINT32_C(0), UINT32_C(10), UINT32_C(100),
|
||||
UINT32_C(1000), UINT32_C(10000), UINT32_C(100000),
|
||||
UINT32_C(1000000), UINT32_C(10000000), UINT32_C(100000000),
|
||||
UINT32_C(1000000000),
|
||||
};
|
||||
|
||||
/* This is an extension of u32_powers_of_ten to include all possible 64-bit
|
||||
* values.
|
||||
*/
|
||||
const uint64_t u64_powers_of_ten[20] = {
|
||||
UINT64_C(0),
|
||||
UINT64_C(10),
|
||||
UINT64_C(100),
|
||||
UINT64_C(1000),
|
||||
UINT64_C(10000),
|
||||
UINT64_C(100000),
|
||||
UINT64_C(1000000),
|
||||
UINT64_C(10000000),
|
||||
UINT64_C(100000000),
|
||||
UINT64_C(1000000000),
|
||||
UINT64_C(10000000000),
|
||||
UINT64_C(100000000000),
|
||||
UINT64_C(1000000000000),
|
||||
UINT64_C(10000000000000),
|
||||
UINT64_C(100000000000000),
|
||||
UINT64_C(1000000000000000),
|
||||
UINT64_C(10000000000000000),
|
||||
UINT64_C(100000000000000000),
|
||||
UINT64_C(1000000000000000000),
|
||||
UINT64_C(10000000000000000000),
|
||||
};
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright © 2022 Imagination Technologies Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PVR_UTIL_H
|
||||
#define PVR_UTIL_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "pvr_types.h"
|
||||
|
||||
#include "util/bitscan.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
static inline bool pvr_dev_addr_is_aligned(pvr_dev_addr_t addr,
|
||||
const uint32_t alignment)
|
||||
{
|
||||
return util_is_aligned(addr.addr, alignment);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
Math functions
|
||||
*****************************************************************************/
|
||||
|
||||
static inline uint32_t u32_bin_digits(uint32_t x)
|
||||
{
|
||||
return x == 0 ? 1 : util_last_bit(x);
|
||||
}
|
||||
|
||||
static inline uint32_t u64_bin_digits(uint64_t x)
|
||||
{
|
||||
return x == 0 ? 1 : util_last_bit64(x);
|
||||
}
|
||||
|
||||
extern const uint8_t est_log10_from_log2[64 + 1];
|
||||
extern const uint32_t u32_powers_of_ten[10];
|
||||
extern const uint64_t u64_powers_of_ten[20];
|
||||
|
||||
/*
|
||||
* This function includes parts of a public-domain log10 algorithm from
|
||||
* "Bit Twiddling Hacks", an aggregate collection which is:
|
||||
*
|
||||
* © 1997-2005 Sean Eron Anderson.
|
||||
*
|
||||
* https://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
|
||||
*/
|
||||
static inline uint32_t u32_dec_digits(uint32_t x)
|
||||
{
|
||||
/* The value of nr_digits is an estimation of ceil(log10(x)) with variance
|
||||
* +0/-1 (as per the comment on the estimation lut).
|
||||
*/
|
||||
const uint32_t nr_digits = est_log10_from_log2[util_last_bit(x)];
|
||||
|
||||
/* We then convert this approximation to a real value by adding 1 iff
|
||||
* x >= 10**nr_digits using another lut to quickly compute the
|
||||
* exponentiation. See the comment on u32_powers_of_ten for details of this.
|
||||
*/
|
||||
return nr_digits + (x >= u32_powers_of_ten[nr_digits]);
|
||||
}
|
||||
|
||||
/* This function is an extended form of u32_dec_digits(); see the comments on
|
||||
* that function for details.
|
||||
*/
|
||||
static inline uint32_t u64_dec_digits(uint64_t x)
|
||||
{
|
||||
const uint32_t nr_digits = est_log10_from_log2[util_last_bit64(x)];
|
||||
return nr_digits + (x >= u64_powers_of_ten[nr_digits]);
|
||||
}
|
||||
|
||||
static inline uint32_t u32_hex_digits(uint32_t x)
|
||||
{
|
||||
const uint32_t binary_digits = u32_bin_digits(x);
|
||||
return (binary_digits >> 2) + !!(binary_digits & 3);
|
||||
}
|
||||
|
||||
static inline uint32_t u64_hex_digits(uint64_t x)
|
||||
{
|
||||
const uint32_t binary_digits = u64_bin_digits(x);
|
||||
return (binary_digits >> 2) + !!(binary_digits & 3);
|
||||
}
|
||||
|
||||
#endif /* PVR_UTIL_H */
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright © 2026 Imagination Technologies Ltd.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#include "pvr_ycbcr.h"
|
||||
|
||||
#include "util/macros.h"
|
||||
|
||||
/* number of slots occupied */
|
||||
#define PVR_YCBCR_SLOTS 9
|
||||
|
||||
struct pvr_ycbcr_csc_table_entry {
|
||||
uint16_t value[32];
|
||||
} PACKED;
|
||||
|
||||
struct pvr_ycbcr_csc_table {
|
||||
struct pvr_ycbcr_csc_table_entry slots[PVR_YCBCR_SLOTS];
|
||||
} PACKED;
|
||||
|
||||
/* clang-format off */
|
||||
static const uint16_t RGB_IDENTITY[] = {
|
||||
0x0000, 0x1ffc, 0x0000,
|
||||
0x0000, 0x0000, 0x1ffc,
|
||||
0x1ffc, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000,
|
||||
};
|
||||
|
||||
static const uint16_t YCBCR_IDENTITY_FULL[] = {
|
||||
0x0000, 0x1ffc, 0x0000,
|
||||
0x0000, 0x0000, 0x1ffc,
|
||||
0x1ffc, 0x0000, 0x0000,
|
||||
0xfff0, 0x0000, 0xfff0,
|
||||
};
|
||||
|
||||
static const uint16_t YCBCR_IDENTITY[] = {
|
||||
0x0000, 0x253e, 0x0000,
|
||||
0x0000, 0x0000, 0x2469,
|
||||
0x2469, 0x0000, 0x0000,
|
||||
0xfdb9, 0xfdac, 0xfdb9,
|
||||
};
|
||||
|
||||
static const uint16_t YCBCR_709_FULL[] = {
|
||||
0x1ffc, 0x1ffc, 0x1ffc,
|
||||
0x0000, 0xfa02, 0x3b5a,
|
||||
0x325e, 0xf107, 0x0000,
|
||||
0xe6d1, 0x0a7b, 0xe253,
|
||||
};
|
||||
|
||||
static const uint16_t YCBCR_709[] = {
|
||||
0x253e, 0x253e, 0x253e,
|
||||
0x0000, 0xf92e, 0x4390,
|
||||
0x3957, 0xeef5, 0x0000,
|
||||
0xe101, 0x099b, 0xdbe4,
|
||||
};
|
||||
|
||||
static const uint16_t YCBCR_601_FULL[] = {
|
||||
0x1ffc, 0x1ffc, 0x1ffc,
|
||||
0x0000, 0xf4fe, 0x38ad,
|
||||
0x2cd8, 0xe929, 0x0000,
|
||||
0xe994, 0x10ed, 0xe3a9,
|
||||
};
|
||||
|
||||
static const uint16_t YCBCR_601[] = {
|
||||
0x253e, 0x253e, 0x253e,
|
||||
0x0000, 0xf378, 0x4085,
|
||||
0x330c, 0xe5ff, 0x0000,
|
||||
0xe426, 0x10f0, 0xdd6a,
|
||||
};
|
||||
|
||||
static const uint16_t YCBCR_2020_FULL[] = {
|
||||
0x1ffc, 0x1ffc, 0x1ffc,
|
||||
0x0000, 0xfabd, 0x3c2d,
|
||||
0x2f2a, 0xedba, 0x0000,
|
||||
0xe86b, 0x0bc5, 0xe1ea,
|
||||
};
|
||||
|
||||
static const uint16_t YCBCR_2020[] = {
|
||||
0x253e, 0x253e, 0x253e,
|
||||
0x0000, 0xfa02, 0x4481,
|
||||
0x35b1, 0xeb32, 0x0000,
|
||||
0xe2d4, 0x0b12, 0xdb6c,
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
#define fill_slot(table, entry) \
|
||||
memcpy(&table->slots[PVR_YCBCR_SLOT_##entry].value, entry, sizeof(entry))
|
||||
|
||||
void pvr_setup_static_yuv_csc_table(uint8_t *map, uint64_t offset)
|
||||
{
|
||||
struct pvr_ycbcr_csc_table *table =
|
||||
(struct pvr_ycbcr_csc_table *)(&map[offset]);
|
||||
fill_slot(table, RGB_IDENTITY);
|
||||
fill_slot(table, YCBCR_IDENTITY_FULL);
|
||||
fill_slot(table, YCBCR_IDENTITY);
|
||||
fill_slot(table, YCBCR_709_FULL);
|
||||
fill_slot(table, YCBCR_709);
|
||||
fill_slot(table, YCBCR_601_FULL);
|
||||
fill_slot(table, YCBCR_601);
|
||||
fill_slot(table, YCBCR_2020_FULL);
|
||||
fill_slot(table, YCBCR_2020);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright © 2026 Imagination Technologies Ltd.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#ifndef PVR_YCBCR_H
|
||||
#define PVR_YCBCR_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void pvr_setup_static_yuv_csc_table(uint8_t *const heap_ptr,
|
||||
uint64_t yuv_table_offset_in_bytes);
|
||||
|
||||
#define PVR_YCBCR_SLOT_RGB_IDENTITY 0
|
||||
#define PVR_YCBCR_SLOT_YCBCR_IDENTITY_FULL 1
|
||||
#define PVR_YCBCR_SLOT_YCBCR_IDENTITY 2
|
||||
#define PVR_YCBCR_SLOT_YCBCR_709_FULL 3
|
||||
#define PVR_YCBCR_SLOT_YCBCR_709 4
|
||||
#define PVR_YCBCR_SLOT_YCBCR_601_FULL 5
|
||||
#define PVR_YCBCR_SLOT_YCBCR_601 6
|
||||
#define PVR_YCBCR_SLOT_YCBCR_2020_FULL 7
|
||||
#define PVR_YCBCR_SLOT_YCBCR_2020 8
|
||||
|
||||
#endif /* PVR_YCBCR_H */
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,8 @@
|
||||
# Copyright © 2022 Imagination Technologies Ltd.
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
pvr_xml_pack = []
|
||||
subdir('rogue')
|
||||
subdir('volcanic')
|
||||
|
||||
dep_csbgen = declare_dependency(sources : [pvr_xml_pack])
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright © 2022 Imagination Technologies Ltd.
|
||||
*
|
||||
* based in part on anv driver which is:
|
||||
* Copyright © 2016 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PVR_PACKET_HELPERS_H
|
||||
#define PVR_PACKET_HELPERS_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef __pvr_validate_value
|
||||
# define __pvr_validate_value(x)
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
# define NDEBUG_UNUSED __attribute__((unused))
|
||||
#else
|
||||
# define NDEBUG_UNUSED
|
||||
#endif
|
||||
|
||||
#ifndef __pvr_address_type
|
||||
# error #define __pvr_address_type before including this file
|
||||
#endif
|
||||
|
||||
#ifndef __pvr_get_address
|
||||
# error #define __pvr_get_address before including this file
|
||||
#endif
|
||||
|
||||
#ifndef __pvr_make_address
|
||||
# error #define __pvr_make_address before including this file
|
||||
#endif
|
||||
|
||||
union __pvr_value {
|
||||
float f;
|
||||
uint32_t dw;
|
||||
};
|
||||
|
||||
static inline __attribute__((always_inline)) uint64_t __pvr_mbo(uint32_t start,
|
||||
uint32_t end)
|
||||
{
|
||||
return (~UINT64_C(0) >> (64 - (end - start + 1))) << start;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) uint64_t
|
||||
__pvr_uint(uint64_t v, uint32_t start, NDEBUG_UNUSED uint32_t end)
|
||||
{
|
||||
__pvr_validate_value(v);
|
||||
|
||||
#ifndef NDEBUG
|
||||
const int width = end - start + 1;
|
||||
if (width < 64) {
|
||||
const uint64_t max = (UINT64_C(1) << width) - 1;
|
||||
assert(v <= max);
|
||||
}
|
||||
#endif
|
||||
|
||||
return v << start;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) uint64_t
|
||||
__pvr_uint_unpack(uint64_t packed, uint32_t start, uint32_t end)
|
||||
{
|
||||
const int width = end - start + 1;
|
||||
const uint64_t mask = ~UINT64_C(0) >> (64 - width);
|
||||
|
||||
return (packed >> start) & mask;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) uint64_t
|
||||
__pvr_sint(int64_t v, uint32_t start, uint32_t end)
|
||||
{
|
||||
const int width = end - start + 1;
|
||||
|
||||
__pvr_validate_value(v);
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (width < 64) {
|
||||
const int64_t max = (1ll << (width - 1)) - 1;
|
||||
const int64_t min = -(1ll << (width - 1));
|
||||
assert(min <= v && v <= max);
|
||||
}
|
||||
#endif
|
||||
|
||||
const uint64_t mask = ~UINT64_C(0) >> (64 - width);
|
||||
|
||||
return (v & mask) << start;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) int64_t
|
||||
__pvr_sint_unpack(uint64_t packed, uint32_t start, uint32_t end)
|
||||
{
|
||||
const int width = end - start + 1;
|
||||
const uint64_t mask = ~UINT64_C(0) >> (64 - width);
|
||||
|
||||
return (int64_t)((packed >> start) & mask);
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) uint64_t
|
||||
__pvr_offset(uint64_t v,
|
||||
NDEBUG_UNUSED uint32_t start,
|
||||
NDEBUG_UNUSED uint32_t end)
|
||||
{
|
||||
__pvr_validate_value(v);
|
||||
#ifndef NDEBUG
|
||||
uint64_t mask = (~UINT64_C(0) >> (64 - (end - start + 1))) << start;
|
||||
|
||||
assert((v & ~mask) == 0);
|
||||
#endif
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) uint64_t
|
||||
__pvr_offset_unpack(uint64_t packed,
|
||||
NDEBUG_UNUSED uint32_t start,
|
||||
NDEBUG_UNUSED uint32_t end)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
uint64_t mask = (~UINT64_C(0) >> (64 - (end - start + 1))) << start;
|
||||
|
||||
assert((packed & ~mask) == 0);
|
||||
#endif
|
||||
|
||||
return packed;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) uint64_t
|
||||
__pvr_address(__pvr_address_type address,
|
||||
uint32_t shift,
|
||||
uint32_t start,
|
||||
uint32_t end)
|
||||
{
|
||||
uint64_t addr_u64 = __pvr_get_address(address);
|
||||
uint64_t mask = (~UINT64_C(0) >> (64 - (end - start + 1))) << start;
|
||||
|
||||
return ((addr_u64 >> shift) << start) & mask;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) __pvr_address_type
|
||||
__pvr_address_unpack(uint64_t packed,
|
||||
uint32_t shift,
|
||||
uint32_t start,
|
||||
uint32_t end)
|
||||
{
|
||||
uint64_t mask = (~UINT64_C(0) >> (64 - (end - start + 1))) << start;
|
||||
uint64_t addr_u64 = ((packed & mask) >> start) << shift;
|
||||
|
||||
return __pvr_make_address(addr_u64);
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) uint32_t __pvr_float(float v)
|
||||
{
|
||||
__pvr_validate_value(v);
|
||||
return ((union __pvr_value){ .f = (v) }).dw;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) float
|
||||
__pvr_float_unpack(uint32_t packed)
|
||||
{
|
||||
return ((union __pvr_value){ .dw = (packed) }).f;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) uint64_t
|
||||
__pvr_sfixed(float v, uint32_t start, uint32_t end, uint32_t fract_bits)
|
||||
{
|
||||
__pvr_validate_value(v);
|
||||
|
||||
const float factor = (1 << fract_bits);
|
||||
|
||||
#ifndef NDEBUG
|
||||
const float max = ((1 << (end - start)) - 1) / factor;
|
||||
const float min = -(1 << (end - start)) / factor;
|
||||
assert(min <= v && v <= max);
|
||||
#endif
|
||||
|
||||
const int64_t int_val = llroundf(v * factor);
|
||||
const uint64_t mask = ~UINT64_C(0) >> (64 - (end - start + 1));
|
||||
|
||||
return (int_val & mask) << start;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) uint64_t
|
||||
__pvr_ufixed(float v,
|
||||
uint32_t start,
|
||||
NDEBUG_UNUSED uint32_t end,
|
||||
uint32_t fract_bits)
|
||||
{
|
||||
__pvr_validate_value(v);
|
||||
|
||||
const float factor = (1 << fract_bits);
|
||||
|
||||
#ifndef NDEBUG
|
||||
const float max = ((1 << (end - start + 1)) - 1) / factor;
|
||||
const float min = 0.0f;
|
||||
assert(min <= v && v <= max);
|
||||
#endif
|
||||
|
||||
const uint64_t uint_val = llroundf(v * factor);
|
||||
|
||||
return uint_val << start;
|
||||
}
|
||||
|
||||
#undef NDEBUG_UNUSED
|
||||
|
||||
#endif /* PVR_PACKET_HELPERS_H */
|
||||
@@ -0,0 +1,134 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<!--
|
||||
Copyright © 2022 Imagination Technologies Ltd.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
-->
|
||||
|
||||
<csbgen name="ROGUE" prefix="CDMCTRL">
|
||||
|
||||
<define name="GUARD_SIZE_DEFAULT" value="64"/>
|
||||
|
||||
<enum name="BLOCK_TYPE">
|
||||
<value name="COMPUTE_KERNEL" value="0"/>
|
||||
<value name="STREAM_LINK" value="1"/>
|
||||
<value name="STREAM_TERMINATE" value="2"/>
|
||||
</enum>
|
||||
|
||||
<enum name="USC_TARGET">
|
||||
<value name="ALL" value="0"/>
|
||||
<value name="ANY" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="SD_TYPE">
|
||||
<value name="NONE" value="0"/>
|
||||
<value name="PDS" value="1"/>
|
||||
<value name="USC" value="2"/>
|
||||
</enum>
|
||||
|
||||
<struct name="KERNEL0" length="1">
|
||||
<field name="block_type" start="30" end="31" type="BLOCK_TYPE" default="COMPUTE_KERNEL"/>
|
||||
<field name="indirect_present" start="29" end="29" type="bool"/>
|
||||
<field name="global_offsets_present" start="28" end="28" type="bool"/>
|
||||
<field name="event_object_present" start="27" end="27" type="bool"/>
|
||||
<field name="usc_common_size" start="18" end="26" type="uint">
|
||||
<define name="UNIT_SIZE" value="64"/>
|
||||
<define name="MAX_SIZE" value="256"/>
|
||||
</field>
|
||||
<field name="usc_unified_size" start="12" end="17" type="uint">
|
||||
<define name="UNIT_SIZE" value="16"/>
|
||||
</field>
|
||||
<field name="pds_temp_size" start="8" end="11" type="uint">
|
||||
<define name="UNIT_SIZE" value="16"/>
|
||||
</field>
|
||||
<field name="pds_data_size" start="2" end="7" type="uint">
|
||||
<define name="UNIT_SIZE" value="16"/>
|
||||
</field>
|
||||
<field name="usc_target" start="1" end="1" type="USC_TARGET"/>
|
||||
<field name="fence" start="0" end="0" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL1" length="1">
|
||||
<field name="data_addr" start="4" end="31" shift="4" type="address"/>
|
||||
<field name="sd_type" start="2" end="3" type="SD_TYPE"/>
|
||||
<field name="usc_common_shared" start="1" end="1" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL2" length="1">
|
||||
<field name="code_addr" start="4" end="31" shift="4" type="address"/>
|
||||
<field name="one_wg_per_task" start="0" end="0" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL3" length="1">
|
||||
<field name="workgroup_x" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL4" length="1">
|
||||
<field name="workgroup_y" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL5" length="1">
|
||||
<field name="workgroup_z" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL6" length="1">
|
||||
<field name="indirect_addrmsb" start="0" end="7" shift="32" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL7" length="1">
|
||||
<field name="indirect_addrlsb" start="2" end="31" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL8" length="1">
|
||||
<field name="max_instances" start="27" end="31" type="uint">
|
||||
<define name="MAX_SIZE" value="31"/>
|
||||
</field>
|
||||
<field name="workgroup_size_x" start="18" end="26" type="uint"/>
|
||||
<field name="workgroup_size_y" start="9" end="17" type="uint"/>
|
||||
<field name="workgroup_size_z" start="0" end="8" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL9" length="1">
|
||||
<field name="global_offset_x" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL10" length="1">
|
||||
<field name="global_offset_y" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL11" length="1">
|
||||
<field name="global_offset_z" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STREAM_LINK0" length="1">
|
||||
<field name="block_type" start="30" end="31" type="BLOCK_TYPE" default="STREAM_LINK"/>
|
||||
<field name="link_addrmsb" start="0" end="7" shift="32" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STREAM_LINK1" length="1">
|
||||
<field name="link_addrlsb" start="2" end="31" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STREAM_TERMINATE" length="1">
|
||||
<field name="block_type" start="30" end="31" type="BLOCK_TYPE" default="STREAM_TERMINATE"/>
|
||||
</struct>
|
||||
|
||||
</csbgen>
|
||||
@@ -0,0 +1,701 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<!--
|
||||
Copyright © 2022 Imagination Technologies Ltd.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
-->
|
||||
|
||||
<csbgen name="ROGUE" prefix="CR">
|
||||
|
||||
<define name="PM_VHEAP_TABLE_SIZE" value="0x180" />
|
||||
|
||||
<enum name="COMP_IADDR_TYPE">
|
||||
<value name="INDIRECT_1TILE" value="0"/>
|
||||
<value name="INDIRECT_4TILE" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="COMPRESS_SIZE">
|
||||
<value name="BLOCK_8X8" value="0"/>
|
||||
<value name="BLOCK_16X4" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="DIR_TYPE">
|
||||
<value name="TL2BR" value="0"/>
|
||||
<value name="TR2BL" value="1"/>
|
||||
<value name="BL2TR" value="2"/>
|
||||
<value name="BR2TL" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="ISP_AA_MODE_TYPE">
|
||||
<value name="AA_NONE" value="0"/>
|
||||
<value name="AA_2X" value="1"/>
|
||||
<value name="AA_4X" value="2"/>
|
||||
<value name="AA_8X" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="ISP_RENDER_MODE_TYPE">
|
||||
<value name="NORM" value="0"/>
|
||||
<value name="FAST_2D" value="2"/>
|
||||
<value name="FAST_SCALE" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="MEMLAYOUT">
|
||||
<value name="LINEAR" value="0"/>
|
||||
<value name="TWIDDLE_2D" value="1"/>
|
||||
<value name="TWIDDLE_3D" value="2"/>
|
||||
<value name="TILED" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="MODE_TYPE">
|
||||
<value name="DX9" value="0"/>
|
||||
<value name="DX10" value="1"/>
|
||||
<value name="OGL" value="2"/>
|
||||
</enum>
|
||||
|
||||
<enum name="PIPE_NUM">
|
||||
<value name="PIPE_ONE" value="0"/>
|
||||
<value name="PIPE_TWO" value="1"/>
|
||||
<value name="PIPE_THREE" value="2"/>
|
||||
<value name="PIPE_FOUR" value="3"/>
|
||||
<value name="PIPE_FIVE" value="4"/>
|
||||
<value name="PIPE_SIX" value="5"/>
|
||||
<value name="PIPE_SEVEN" value="6"/>
|
||||
<value name="PIPE_EIGHT" value="7"/>
|
||||
<value name="PIPE_NINE" value="8"/>
|
||||
<value name="PIPE_TEN" value="9"/>
|
||||
<value name="PIPE_ELEVEN" value="10"/>
|
||||
<value name="PIPE_TWELVE" value="11"/>
|
||||
<value name="PIPE_THIRTEEN" value="12"/>
|
||||
<value name="PIPE_FOURTEEN" value="13"/>
|
||||
<value name="PIPE_FIFTEEN" value="14"/>
|
||||
<value name="PIPE_SIXTEEN" value="15"/>
|
||||
</enum>
|
||||
|
||||
<enum name="PIXEL_WIDTH">
|
||||
<value name="2REGISTERS" value="0"/>
|
||||
<value name="4REGISTERS" value="1"/>
|
||||
<value name="8REGISTERS" value="2"/>
|
||||
<value name="1REGISTER" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="ROTATION_TYPE">
|
||||
<value name="0_DEG" value="0"/>
|
||||
<value name="90_DEG" value="1"/>
|
||||
<value name="180_DEG" value="2"/>
|
||||
<value name="270_DEG" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="SIZE">
|
||||
<value name="1_PIXEL" value="0"/>
|
||||
<value name="2_PIXEL" value="1"/>
|
||||
<value name="4_PIXEL" value="2"/>
|
||||
<value name="8_PIXEL" value="3"/>
|
||||
<value name="16_PIXEL" value="4"/>
|
||||
<value name="32_PIXEL" value="5"/>
|
||||
<value name="64_PIXEL" value="6"/>
|
||||
<value name="128_PIXEL" value="7"/>
|
||||
<value name="256_PIXEL" value="8"/>
|
||||
<value name="512_PIXEL" value="9"/>
|
||||
<value name="1K_PIXEL" value="10"/>
|
||||
<value name="2K_PIXEL" value="11"/>
|
||||
<value name="4K_PIXEL" value="12"/>
|
||||
<value name="8K_PIXEL" value="13"/>
|
||||
<value name="16K_PIXEL" value="14"/>
|
||||
</enum>
|
||||
|
||||
<enum name="SWIZ">
|
||||
<value name="SOURCE_CHAN0" value="0"/>
|
||||
<value name="SOURCE_CHAN1" value="1"/>
|
||||
<value name="SOURCE_CHAN2" value="2"/>
|
||||
<value name="SOURCE_CHAN3" value="3"/>
|
||||
<value name="ONE" value="4"/>
|
||||
<value name="ZERO" value="5"/>
|
||||
</enum>
|
||||
|
||||
<enum name="TFBC_LOSSY">
|
||||
<value name="LOSSLESS" value="0"/>
|
||||
<value name="LOSSY_75" value="1"/>
|
||||
<value name="LOSSY_50" value="2"/>
|
||||
<value name="LOSSY_25" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="TWOCOMP_GAMMA">
|
||||
<value name="GAMMA_BOTTOM_CHANNEL" value="0"/>
|
||||
<value name="GAMMA_BOTH_CHANNELS" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="ZLS_FORMAT_TYPE">
|
||||
<!-- Separate depth and stencil -->
|
||||
<value name="F32Z" value="0"/>
|
||||
<!-- Packed depth and stencil -->
|
||||
<value name="24BITINT" value="1"/>
|
||||
<!-- Separate depth and stencil -->
|
||||
<value name="16BITINT" value="2"/>
|
||||
<!-- Packed depth and stencil -->
|
||||
<value name="F64Z" value="3"/>
|
||||
</enum>
|
||||
|
||||
<struct name="PM_MTILE_ARRAY" length="2">
|
||||
<field name="base_addr" start="4" end="39" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="PM_VHEAP_TABLE" length="2">
|
||||
<field name="base_addr" start="4" end="39" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="PM_MLIST0_BASE" length="2">
|
||||
<field name="addr" start="4" end="39" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="VDM_CTRL_STREAM_BASE" length="2">
|
||||
<field name="addr" start="2" end="39" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="VDM_CALL_STACK_POINTER" length="2">
|
||||
<field name="addr" start="3" end="39" shift="3" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="VDM_CONTEXT_STATE_BASE" length="2">
|
||||
<field name="addr" start="4" end="39" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="VDM_CONTEXT_STORE_TASK0" length="2">
|
||||
<field name="pds_state1" start="32" end="63" type="uint"/>
|
||||
<field name="pds_state0" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="VDM_CONTEXT_STORE_TASK1" length="1">
|
||||
<field name="pds_state2" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="VDM_CONTEXT_STORE_TASK2" length="2">
|
||||
<field name="stream_out2" start="32" end="63" type="uint"/>
|
||||
<field name="stream_out1" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="VDM_CONTEXT_RESUME_TASK0" length="2">
|
||||
<field name="pds_state1" start="32" end="63" type="uint"/>
|
||||
<field name="pds_state0" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="VDM_CONTEXT_RESUME_TASK1" length="1">
|
||||
<field name="pds_state2" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="VDM_CONTEXT_RESUME_TASK2" length="2">
|
||||
<field name="stream_out2" start="32" end="63" type="uint"/>
|
||||
<field name="stream_out1" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="CDM_CONTEXT_STATE_BASE" length="2">
|
||||
<field name="addr" start="4" end="39" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="CDM_CONTEXT_PDS0" length="2">
|
||||
<field name="data_addr" start="36" end="63" shift="4" type="address"/>
|
||||
<field name="code_addr" start="4" end="31" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="CDM_CTRL_STREAM_BASE" length="2">
|
||||
<field name="addr" start="2" end="39" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="CDM_CONTEXT_PDS1" length="1">
|
||||
<field name="pds_seq_dep" start="29" end="29" type="bool"/>
|
||||
<field name="usc_seq_dep" start="28" end="28" type="bool"/>
|
||||
<!-- false=All, true=Any -->
|
||||
<field name="target" start="27" end="27" type="bool"/>
|
||||
<field name="unified_size" start="21" end="26" type="uint"/>
|
||||
<field name="common_shared" start="20" end="20" type="bool"/>
|
||||
<field name="common_size" start="11" end="19" type="uint">
|
||||
<define name="UNIT_SIZE" value="64"/>
|
||||
</field>
|
||||
<field name="temp_size" start="7" end="10" type="uint"/>
|
||||
<field name="data_size" start="1" end="6" type="uint">
|
||||
<define name="UNIT_SIZE" value="16"/>
|
||||
</field>
|
||||
<field name="fence" start="0" end="0" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<struct name="CDM_TERMINATE_PDS" length="2">
|
||||
<field name="data_addr" start="36" end="63" shift="4" type="address"/>
|
||||
<field name="code_addr" start="4" end="31" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="CDM_TERMINATE_PDS1" length="1">
|
||||
<field name="pds_seq_dep" start="29" end="29" type="bool"/>
|
||||
<field name="usc_seq_dep" start="28" end="28" type="bool"/>
|
||||
<field name="target" start="27" end="27" type="bool"/>
|
||||
<field name="unified_size" start="21" end="26" type="uint"/>
|
||||
<field name="common_shared" start="20" end="20" type="bool"/>
|
||||
<field name="common_size" start="11" end="19" type="uint"/>
|
||||
<field name="temp_size" start="7" end="10" type="uint"/>
|
||||
<field name="data_size" start="1" end="6" type="uint"/>
|
||||
<field name="fence" start="0" end="0" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<struct name="CDM_CONTEXT_LOAD_PDS0" length="2">
|
||||
<field name="data_addr" start="36" end="63" shift="4" type="address"/>
|
||||
<field name="code_addr" start="4" end="31" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="COMPUTE_CLUSTER" length="1">
|
||||
<field name="mask" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="CDM_ITEM" length="1">
|
||||
<field name="mode" start="0" end="1" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="PDS_CTRL0" length="1">
|
||||
<condition type="if" check="ROGUEXE"/>
|
||||
<condition type="if" check="COMPUTE"/>
|
||||
<field name="roguexe_max_num_cdm_tasks" start="24" end="31" type="uint"/>
|
||||
<condition type="endif" check="COMPUTE"/>
|
||||
<condition type="if" check="NUM_RASTER_PIPES > 0"/>
|
||||
<field name="roguexe_max_num_pdm_tasks" start="16" end="23" type="uint"/>
|
||||
<condition type="endif" check="NUM_RASTER_PIPES > 0"/>
|
||||
<condition type="if" check="NUM_TA > 0"/>
|
||||
<field name="roguexe_max_num_vdm_tasks" start="8" end="15" type="uint"/>
|
||||
<condition type="endif" check="NUM_TA > 0"/>
|
||||
<condition type="else" check="ROGUEXE"/>
|
||||
<condition type="if" check="COMPUTE"/>
|
||||
<field name="max_num_cdm_tasks" start="24" end="30" type="uint"/>
|
||||
<condition type="endif" check="COMPUTE"/>
|
||||
<field name="max_num_pdm_tasks" start="16" end="22" type="uint"/>
|
||||
<field name="max_num_vdm_tasks" start="8" end="14" type="uint"/>
|
||||
<condition type="endif" check="ROGUEXE"/>
|
||||
</struct>
|
||||
|
||||
<struct name="PDS_CTRL1" length="1">
|
||||
<field name="sm_overlap_enable" start="23" end="23" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<struct name="EVENT_PIXEL_PDS_CODE" length="1">
|
||||
<field name="addr" start="4" end="31" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="EVENT_PIXEL_PDS_DATA" length="1">
|
||||
<!-- This is an offset actually. Note for when we auto-generate the xmls. -->
|
||||
<field name="addr" start="4" end="31" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="EVENT_PIXEL_PDS_INFO" length="1">
|
||||
<field name="usc_sr_size" start="9" end="14" type="uint">
|
||||
<define name="UNIT_SIZE" value="16"/>
|
||||
</field>
|
||||
<field name="temp_stride" start="5" end="8" type="uint">
|
||||
<define name="UNIT_SIZE" value="4"/>
|
||||
</field>
|
||||
<field name="const_size" start="0" end="4" type="uint">
|
||||
<define name="UNIT_SIZE" value="4"/>
|
||||
</field>
|
||||
</struct>
|
||||
|
||||
<struct name="PDS_BGRND0_BASE" length="2">
|
||||
<!-- This is an offset actually. Note for when we auto-generate the xmls. -->
|
||||
<field name="texunicode_addr" start="36" end="63" shift="4" type="address"/>
|
||||
<!-- This is an offset actually. Note for when we auto-generate the xmls. -->
|
||||
<field name="shader_addr" start="4" end="31" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="PDS_BGRND1_BASE" length="2">
|
||||
<!-- This is an offset actually. Note for when we auto-generate the xmls. -->
|
||||
<field name="texturedata_addr" start="36" end="63" shift="4" type="address"/>
|
||||
<!-- Unused in the Vulkan driver. -->
|
||||
<field name="varying_addr" start="4" end="31" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="PDS_BGRND2_BASE" length="2">
|
||||
<!-- This is an offset actually. Note for when we auto-generate the xmls. -->
|
||||
<field name="uniformdata_addr" start="4" end="31" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="PDS_BGRND3_SIZEINFO" length="2">
|
||||
<field name="usc_sharedsize" start="55" end="63" type="uint">
|
||||
<define name="UNIT_SIZE" value="16"/>
|
||||
</field>
|
||||
<field name="pds_batchnum" start="32" end="45" type="uint"/>
|
||||
<field name="pds_uniformsize" start="23" end="31" type="uint">
|
||||
<define name="UNIT_SIZE" value="4"/>
|
||||
</field>
|
||||
<field name="pds_texturestatesize" start="16" end="22" type="uint">
|
||||
<define name="UNIT_SIZE" value="4"/>
|
||||
</field>
|
||||
<field name="pds_varyingsize" start="10" end="15" type="uint">
|
||||
<define name="UNIT_SIZE" value="4"/>
|
||||
</field>
|
||||
<field name="usc_varyingsize" start="4" end="9" type="uint">
|
||||
<define name="UNIT_SIZE" value="16"/>
|
||||
</field>
|
||||
<field name="pds_tempsize" start="0" end="3" type="uint">
|
||||
<define name="UNIT_SIZE" value="4"/>
|
||||
</field>
|
||||
</struct>
|
||||
|
||||
<struct name="TE_AA" length="1">
|
||||
<condition type="if" check="SIMPLE_INTERNAL_PARAMETER_FORMAT && ISP_SAMPLES_PER_PIXEL > 2"/>
|
||||
<field name="y2" start="3" end="3" type="bool"/>
|
||||
<condition type="endif" check="SIMPLE_INTERNAL_PARAMETER_FORMAT && ISP_SAMPLES_PER_PIXEL > 2"/>
|
||||
<field name="y" start="2" end="2" type="bool"/>
|
||||
<field name="x" start="1" end="1" type="bool"/>
|
||||
<field name="x2" start="0" end="0" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<struct name="TE_MTILE1" length="1">
|
||||
<field name="x1" start="18" end="26" type="uint"/>
|
||||
<field name="x2" start="9" end="17" type="uint"/>
|
||||
<field name="x3" start="0" end="8" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="TE_MTILE2" length="1">
|
||||
<field name="y1" start="18" end="26" type="uint"/>
|
||||
<field name="y2" start="9" end="17" type="uint"/>
|
||||
<field name="y3" start="0" end="8" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="TE_SCREEN" length="1">
|
||||
<field name="ymax" start="12" end="20" type="uint"/>
|
||||
<field name="xmax" start="0" end="8" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="TE_PSG" length="1">
|
||||
<condition type="if" check="ROGUEXE"/>
|
||||
<condition type="if" check="TILE_REGION_PROTECTION"/>
|
||||
<field name="force_protect" start="22" end="22" type="uint"/>
|
||||
<condition type="endif" check="TILE_REGION_PROTECTION"/>
|
||||
<field name="cs_size" start="21" end="21" type="uint"/>
|
||||
<field name="enable_pwr_gate_state" start="20" end="20" type="bool"/>
|
||||
<condition type="endif" check="ROGUEXE"/>
|
||||
<field name="enable_context_state_restore" start="19" end="19" type="bool"/>
|
||||
<field name="zonlyrender" start="18" end="18" type="bool"/>
|
||||
<field name="completeonterminate" start="17" end="17" type="bool"/>
|
||||
<field name="cache_bypass" start="14" end="14" type="bool"/>
|
||||
<field name="forcenewstate" start="13" end="13" type="bool"/>
|
||||
<field name="region_stride" start="0" end="10" type="uint">
|
||||
<define name="UNIT_SIZE" value="4096"/>
|
||||
</field>
|
||||
</struct>
|
||||
|
||||
<!-- FIXME: This is only a partial definition as (at the time of writing)
|
||||
csbgen doesn't support multiple address fields within structure.
|
||||
-->
|
||||
<!-- FIXME: When csbgen supports conditional structs, make this
|
||||
conditional on NUM_TA > 0.
|
||||
-->
|
||||
<struct name="TE_PSGREGION_ADDR" length="2">
|
||||
<field name="base" start="6" end="33" shift="6" type="address"/>
|
||||
</struct>
|
||||
|
||||
<!-- FIXME: This is only a partial definition as (at the time of writing)
|
||||
csbgen doesn't support multiple address fields within structure.
|
||||
-->
|
||||
<struct name="TE_TPC_ADDR" length="2">
|
||||
<field name="base" start="6" end="33" shift="6" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="PPP_MULTISAMPLECTL" length="2">
|
||||
<condition type="if" check="MAX_MULTISAMPLE == 8"/>
|
||||
<field name="msaa_y7" start="60" end="63" type="uint"/>
|
||||
<field name="msaa_x7" start="56" end="59" type="uint"/>
|
||||
<field name="msaa_y6" start="52" end="55" type="uint"/>
|
||||
<field name="msaa_x6" start="48" end="51" type="uint"/>
|
||||
<field name="msaa_y5" start="44" end="47" type="uint"/>
|
||||
<field name="msaa_x5" start="40" end="43" type="uint"/>
|
||||
<field name="msaa_y4" start="36" end="39" type="uint"/>
|
||||
<field name="msaa_x4" start="32" end="35" type="uint"/>
|
||||
<condition type="endif" check="MAX_MULTISAMPLE == 8"/>
|
||||
<field name="msaa_y3" start="28" end="31" type="uint"/>
|
||||
<field name="msaa_x3" start="24" end="27" type="uint"/>
|
||||
<field name="msaa_y2" start="20" end="23" type="uint"/>
|
||||
<field name="msaa_x2" start="16" end="19" type="uint"/>
|
||||
<field name="msaa_y1" start="12" end="15" type="uint"/>
|
||||
<field name="msaa_x1" start="8" end="11" type="uint"/>
|
||||
<field name="msaa_y0" start="4" end="7" type="uint"/>
|
||||
<field name="msaa_x0" start="0" end="3" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="PPP_CTRL" length="1">
|
||||
<field name="vpt_scissor" start="12" end="12" type="bool"/>
|
||||
<field name="flush_mode" start="11" end="11" type="uint"/>
|
||||
<field name="bfcull_restrict_clip" start="10" end="10" type="bool"/>
|
||||
<field name="fixed_point_format" start="9" end="9" type="uint"/>
|
||||
<field name="default_point_size" start="8" end="8" type="bool"/>
|
||||
<field name="bfcull1_disable" start="7" end="7" type="bool"/>
|
||||
<field name="bfcull2_disable" start="6" end="6" type="bool"/>
|
||||
<field name="fccull_disable" start="5" end="5" type="bool"/>
|
||||
<field name="oscull_disable" start="4" end="4" type="bool"/>
|
||||
<field name="socull_disable" start="2" end="2" type="bool"/>
|
||||
<field name="wclampen" start="1" end="1" type="bool"/>
|
||||
<field name="opengl" start="0" end="0" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<struct name="PPP_SCREEN" length="1">
|
||||
<field name="pixymax" start="16" end="30" type="uint"/>
|
||||
<field name="pixxmax" start="0" end="14" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<!-- FIXME: This is only a partial definition as (at the time of writing)
|
||||
csbgen doesn't support multiple address fields within structure.
|
||||
-->
|
||||
<struct name="TA_RTC_ADDR" length="2">
|
||||
<field name="base" start="6" end="33" shift="6" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="TA_CONTEXT_STATE_BASE" length="2">
|
||||
<field name="addr" start="4" end="39" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_RENDER" length="1">
|
||||
<field name="disable_eomt" start="5" end="5" type="bool"/>
|
||||
<field name="resume" start="4" end="4" type="bool"/>
|
||||
<field name="dir_type" start="2" end="3" type="DIR_TYPE"/>
|
||||
<field name="mode_type" start="0" end="1" type="ISP_RENDER_MODE_TYPE"/>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_RENDER_ORIGIN" length="1">
|
||||
<field name="x" start="16" end="25" type="uint"/>
|
||||
<field name="y" start="0" end="9" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_MTILE_BASE" length="2">
|
||||
<field name="addr" start="2" end="39" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_MTILE_SIZE" length="1">
|
||||
<field name="x" start="16" end="25" type="uint"/>
|
||||
<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">
|
||||
<define name="MAX" value="31"/>
|
||||
</field>
|
||||
<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>
|
||||
|
||||
<struct name="ISP_BGOBJVALS" length="1">
|
||||
<field name="enablebgtag" start="9" end="9" type="bool"/>
|
||||
<field name="mask" start="8" end="8" type="bool"/>
|
||||
<field name="stencil" start="0" end="7" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_AA" length="1">
|
||||
<field name="mode" start="0" end="1" type="ISP_AA_MODE_TYPE" default="AA_NONE"/>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_CTL" length="1">
|
||||
<field name="skip_init_hdrs" start="31" end="31" type="bool"/>
|
||||
<field name="line_style" start="30" end="30" type="bool"/>
|
||||
<field name="line_style_pix" start="29" end="29" type="bool"/>
|
||||
<field name="pair_tiles_vert" start="28" end="28" type="bool"/>
|
||||
<field name="pair_tiles" start="27" end="27" type="bool"/>
|
||||
<field name="creq_buf_en" start="26" end="26" type="bool"/>
|
||||
<field name="tile_age_en" start="25" end="25" type="bool"/>
|
||||
<field name="isp_sample_pos_mode" start="23" end="24" type="MODE_TYPE"/>
|
||||
<field name="num_tiles_per_usc" start="21" end="22" type="uint"/>
|
||||
<field name="dbias_is_int" start="20" end="20" type="bool"/>
|
||||
<field name="overlap_check_mode" start="19" end="19" type="bool"/>
|
||||
<field name="pt_upfront_depth_disable" start="18" end="18" type="bool"/>
|
||||
<field name="process_empty_tiles" start="17" end="17" type="bool"/>
|
||||
<field name="sample_pos" start="16" end="16" type="bool"/>
|
||||
<field name="pipe_enable" start="12" end="15" type="PIPE_NUM"/>
|
||||
<field name="valid_id" start="4" end="9" type="uint"/>
|
||||
<field name="upass_start" start="0" end="3" type="uint">
|
||||
<define name="SIZE_MAX" value="15"/>
|
||||
</field>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_ZLSCTL" length="2">
|
||||
<field name="zlsextent_y_s" start="48" end="57" type="uint"/>
|
||||
<field name="zlsextent_x_s" start="38" end="47" type="uint"/>
|
||||
<field name="stencil_extent_enable" start="37" end="37" type="bool"/>
|
||||
<field name="zlsextent_y_z" start="27" end="36" type="uint"/>
|
||||
<field name="zstoreformat" start="25" end="26" type="ZLS_FORMAT_TYPE"/>
|
||||
<field name="zloadformat" start="23" end="24" type="ZLS_FORMAT_TYPE"/>
|
||||
<field name="fb_storeen" start="22" end="22" type="bool"/>
|
||||
<field name="fb_loaden" start="21" end="21" type="bool"/>
|
||||
<field name="mstoreen" start="20" end="20" type="bool"/>
|
||||
<field name="zstoreen" start="19" end="19" type="bool"/>
|
||||
<field name="sstoreen" start="18" end="18" type="bool"/>
|
||||
<field name="storetwiddled" start="17" end="17" type="bool"/>
|
||||
<field name="mloaden" start="16" end="16" type="bool"/>
|
||||
<field name="zloaden" start="15" end="15" type="bool"/>
|
||||
<field name="sloaden" start="14" end="14" type="bool"/>
|
||||
<field name="loadtwiddled" start="13" end="13" type="bool"/>
|
||||
<field name="zlsextent_x_z" start="3" end="12" type="uint"/>
|
||||
<field name="forcezstore" start="2" end="2" type="bool"/>
|
||||
<field name="forcezload" start="1" end="1" type="bool"/>
|
||||
<field name="zonlyrender" start="0" end="0" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_ZLOAD_BASE" length="2">
|
||||
<field name="addr" start="4" end="39" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_STENCIL_LOAD_BASE" length="2">
|
||||
<field name="addr" start="4" end="39" shift="4" type="address"/>
|
||||
<field name="enable" start="0" end="0" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_SCISSOR_BASE" length="2">
|
||||
<field name="addr" start="2" end="39" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_DBIAS_BASE" length="2">
|
||||
<field name="addr" start="2" end="39" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_OCLQRY_BASE" length="2">
|
||||
<field name="addr" start="4" end="39" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_ZLS_PIXELS" length="1">
|
||||
<field name="y" start="15" end="29" type="uint"/>
|
||||
<field name="x" start="0" end="14" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="PBE_WORD0_MRT0" length="2">
|
||||
<condition type="if" check="TFBC"/>
|
||||
<field name="tfbc_lossy" start="62" end="63" type="TFBC_LOSSY"/>
|
||||
<condition type="endif" check="TFBC"/>
|
||||
<field name="x_rsrvd" start="63" end="63" type="bool"/>
|
||||
<field name="pair_tiles" start="60" end="60" type="uint"/>
|
||||
<field name="comp_iaddr_mode" start="60" end="60" type="COMP_IADDR_TYPE"/>
|
||||
<field name="x_rsrvd2" start="59" end="59" type="bool"/>
|
||||
<field name="comp_cor_enable" start="59" end="59" type="bool"/>
|
||||
<field name="dither" start="58" end="58" type="bool"/>
|
||||
<field name="tilerelative" start="57" end="57" type="bool"/>
|
||||
<field name="downscale" start="56" end="56" type="bool"/>
|
||||
<field name="size_z" start="52" end="55" type="SIZE"/>
|
||||
<field name="rotation" start="50" end="51" type="ROTATION_TYPE"/>
|
||||
<field name="linestride" start="34" end="49" type="uint">
|
||||
<define name="ALIGNMENT" value="2"/>
|
||||
</field>
|
||||
<field name="memlayout" start="32" end="33" type="MEMLAYOUT"/>
|
||||
<field name="swiz_chan3" start="29" end="31" type="SWIZ"/>
|
||||
<field name="swiz_chan2" start="26" end="28" type="SWIZ"/>
|
||||
<field name="swiz_chan1" start="23" end="25" type="SWIZ"/>
|
||||
<field name="swiz_chan0" start="20" end="22" type="SWIZ"/>
|
||||
<field name="minclip_x" start="6" end="19" type="uint"/>
|
||||
<field name="twocomp_gamma" start="5" end="5" type="TWOCOMP_GAMMA"/>
|
||||
<field name="gamma" start="4" end="4" type="bool"/>
|
||||
<field name="compression" start="3" end="3" type="bool"/>
|
||||
<field name="compress_size" start="2" end="2" type="COMPRESS_SIZE"/>
|
||||
<field name="comp_indirect_table" start="1" end="1" type="bool"/>
|
||||
<condition type="if" check="PBE_YFLIP"/>
|
||||
<field name="y_flip" start="0" end="0" type="bool"/>
|
||||
<condition type="endif" check="PBE_YFLIP"/>
|
||||
</struct>
|
||||
|
||||
<struct name="FRAG_SCREEN" length="1">
|
||||
<field name="ymax" start="16" end="30" type="uint"/>
|
||||
<field name="xmax" start="0" end="14" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="TPU" length="1">
|
||||
<condition type="if" check="PDSL0SIZE > 0"/>
|
||||
<field name="mcu_pds_l0_off" start="8" end="8" type="bool"/>
|
||||
<condition type="endif" check="PDSL0SIZE > 0"/>
|
||||
<condition type="if" check="TPU_CEM_DATAMASTER_GLOBAL_REGISTERS"/>
|
||||
<field name="tag_cem_64_face_packing" start="7" end="7" type="bool"/>
|
||||
<condition type="endif" check="TPU_CEM_DATAMASTER_GLOBAL_REGISTERS"/>
|
||||
<field name="tag_enable_mmu_prefetch" start="6" end="6" type="bool"/>
|
||||
<field name="tag_cem_4k_face_packing" start="5" end="5" type="bool"/>
|
||||
<field name="madd_config_l0off" start="4" end="4" type="bool"/>
|
||||
<field name="tag_cem_face_packing" start="3" end="3" type="bool"/>
|
||||
<field name="tag_cemedge_dontfilter" start="2" end="2" type="bool"/>
|
||||
<condition type="if" check="TPU_CEM_USG_NORMALISATION"/>
|
||||
<field name="tag_cemgrad_dontnegate" start="1" end="1" type="bool"/>
|
||||
<condition type="endif" check="TPU_CEM_USG_NORMALISATION"/>
|
||||
<field name="madd_config_dxt35_transovr" start="0" end="0" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<struct name="TPU_BORDER_COLOUR_TABLE_PDM" length="2">
|
||||
<field name="border_colour_table_address" start="0" end="37" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="TPU_BORDER_COLOUR_TABLE_VDM" length="2">
|
||||
<field name="border_colour_table_address" start="0" end="37" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="TPU_BORDER_COLOUR_TABLE_CDM" length="2">
|
||||
<field name="border_colour_table_address" start="0" end="37" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<!-- FIXME: This register depends on TPU_DM_GLOBAL_REGISTERS. -->
|
||||
<struct name="TPU_TAG_CDM_CTRL" length="1">
|
||||
<field name="af_ratio_truncate_to_integer" start="3" end="3" type="bool"/>
|
||||
<field name="af_ratio_truncate_to_half" start="2" end="2" type="bool"/>
|
||||
<field name="af_filtering_mode" start="1" end="1" type="bool"/>
|
||||
<field name="yuv_cam_invalidate" start="0" end="0" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<struct name="USC_PIXEL_OUTPUT_CTRL" length="1">
|
||||
<field name="partition_mask" start="3" end="20" type="uint"/>
|
||||
<field name="enable_4th_partition" start="2" end="2" type="bool"/>
|
||||
<field name="width" start="0" end="1" type="PIXEL_WIDTH"/>
|
||||
</struct>
|
||||
|
||||
<struct name="USC_CLEAR_REGISTER" length="1">
|
||||
<field name="val" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<!-- FIXME: When csbgen supports conditional structs, make this conditional
|
||||
on FB_CDC.
|
||||
-->
|
||||
<struct name="FB_CDC_ZLS" length="2">
|
||||
<condition type="if" check="!ROGUEXE"/>
|
||||
<field name="fbc_iaddr_mode" start="42" end="42" type="bool"/>
|
||||
<field name="fbdc_iaddr_mode" start="41" end="41" type="bool"/>
|
||||
<condition type="endif" check="!ROGUEXE"/>
|
||||
<!-- FIXME: should be dependent on !ROGUEXE || (ROGUEXE && FB_CDC_V4) -->
|
||||
<field name="fbdc_stencil_fmt" start="34" end="40" type="uint"/>
|
||||
<!-- FIXME: should be dependent on !ROGUEXE || (ROGUEXE && FB_CDC_V4) -->
|
||||
<field name="fbdc_depth_fmt" start="27" end="33" type="uint"/>
|
||||
<field name="fbc_num_tiles" start="4" end="26" type="uint"/>
|
||||
<field name="fbc_iaddr" start="1" end="1" type="bool"/>
|
||||
<field name="fbdc_iaddr" start="0" end="0" type="bool"/>
|
||||
</struct>
|
||||
|
||||
</csbgen>
|
||||
@@ -0,0 +1,510 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<!--
|
||||
Copyright © 2022 Imagination Technologies Ltd.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
-->
|
||||
|
||||
<csbgen name="ROGUE" prefix="IPF">
|
||||
|
||||
<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"/>
|
||||
<value name="ORIGIN_1_DELTA_1" value="1"/>
|
||||
<value name="ORIGIN_1_DELTA_2" value="2"/>
|
||||
<value name="ORIGIN_1_DELTA_3" value="3"/>
|
||||
<value name="ORIGIN_1_DELTA_4" value="4"/>
|
||||
<value name="ORIGIN_1_DELTA_5" value="5"/>
|
||||
<value name="ORIGIN_1_DELTA_6" value="6"/>
|
||||
<value name="ORIGIN_1_DELTA_7" value="7"/>
|
||||
<value name="RAW_BYTE" value="8"/>
|
||||
<value name="UNIQUE_2" value="9"/>
|
||||
<value name="ORIGIN_2_DELTA_1" value="10"/>
|
||||
<value name="ORIGIN_2_DELTA_2" value="11"/>
|
||||
<value name="ORIGIN_2_DELTA_3" value="12"/>
|
||||
<value name="ORIGIN_2_DELTA_4" value="13"/>
|
||||
<value name="ORIGIN_2_DELTA_5" value="14"/>
|
||||
<value name="ORIGIN_2_DELTA_6" value="15"/>
|
||||
</enum>
|
||||
|
||||
<enum name="CS_MASK_FMT">
|
||||
<value name="INDEX" value="0"/>
|
||||
<value name="BYTE" value="1"/>
|
||||
<value name="BIT" value="2"/>
|
||||
<value name="FULL" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="CS_TYPE">
|
||||
<value name="PRIM" value="0"/>
|
||||
<value name="LINK" value="2"/>
|
||||
<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"/>
|
||||
</struct>
|
||||
|
||||
<struct name="SCISSOR_WORD_1" length="1">
|
||||
<field name="scw1_ymin" start="16" end="31" type="uint"/>
|
||||
<field name="scw1_ymax" start="0" end="15" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="CONTROL_STREAM" length="1">
|
||||
<field name="cs_type" start="30" end="31" type="CS_TYPE"/>
|
||||
<field name="cs_link" start="3" end="29" shift="7" type="address">
|
||||
<define name="UNIT_SIZE" value="128"/>
|
||||
</field>
|
||||
</struct>
|
||||
|
||||
<!-- FIXME: This is only available with SIMPLE_INTERNAL_PARAMETER_FORMAT_V2. -->
|
||||
<struct name="CONTROL_STREAM_LINK_SIPF2" length="1">
|
||||
<field name="cs_link" start="2" end="31" shift="6" type="address">
|
||||
<define name="UNIT_SIZE" value="64"/>
|
||||
</field>
|
||||
<field name="cs_ctrl_type" start="0" end="1" type="CS_CTRL_TYPE_SIPF2" default="LINK"/>
|
||||
</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"/>
|
||||
<field name="cs_isp_state_size" start="26" end="28" type="uint"/>
|
||||
<field name="cs_prim_total" start="19" end="25" type="uint"/>
|
||||
<field name="cs_mask_fmt" start="17" end="18" type="CS_MASK_FMT"/>
|
||||
<field name="cs_prim_base_pres" start="16" end="16" type="bool"/>
|
||||
<field name="cs_prim_base_offset" start="0" end="15" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="PRIMITIVE_BASE" length="1">
|
||||
<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"/>
|
||||
<field name="cs_tsp_comp_table_size" start="9" end="18" type="uint"/>
|
||||
<field name="cs_tsp_comp_vertex_size" start="0" end="8" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_COMPRESSION_WORD_0" length="1">
|
||||
<field name="cf_isp_comp_fmt_z1" start="28" end="31" type="COMPRESSION_FORMAT"/>
|
||||
<field name="cf_isp_comp_fmt_z0" start="24" end="27" type="COMPRESSION_FORMAT"/>
|
||||
<field name="cf_isp_comp_fmt_y2" start="20" end="23" type="COMPRESSION_FORMAT"/>
|
||||
<field name="cf_isp_comp_fmt_y1" start="16" end="19" type="COMPRESSION_FORMAT"/>
|
||||
<field name="cf_isp_comp_fmt_y0" start="12" end="15" type="COMPRESSION_FORMAT"/>
|
||||
<field name="cf_isp_comp_fmt_x2" start="8" end="11" type="COMPRESSION_FORMAT"/>
|
||||
<field name="cf_isp_comp_fmt_x1" start="4" end="7" type="COMPRESSION_FORMAT"/>
|
||||
<field name="cf_isp_comp_fmt_x0" start="0" end="3" type="COMPRESSION_FORMAT"/>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_COMPRESSION_WORD_1" length="1">
|
||||
<field name="vf_prim_msaa" start="16" end="16" type="bool"/>
|
||||
<field name="vf_prim_id_pres" start="15" end="15" type="bool"/>
|
||||
<field name="vf_vertex_clipped" start="14" end="14" type="bool"/>
|
||||
<field name="vf_vertex_total" start="8" end="13" type="uint"/>
|
||||
<field name="cf_isp_comp_fmt_z3" start="4" end="7" type="COMPRESSION_FORMAT"/>
|
||||
<field name="cf_isp_comp_fmt_z2" start="0" end="3" type="COMPRESSION_FORMAT"/>
|
||||
</struct>
|
||||
|
||||
<struct name="INDEX_DATA" length="1">
|
||||
<field name="ix_edge_flag1_ab" start="30" end="30" type="bool"/>
|
||||
<field name="ix_index1_0" start="24" end="29" type="uint"/>
|
||||
<field name="ix_bf_flag0" start="23" end="23" type="bool"/>
|
||||
<field name="ix_edge_flag0_ca" start="22" end="22" type="bool"/>
|
||||
<field name="ix_index0_2" start="16" end="21" type="uint"/>
|
||||
<field name="ix_edge_flag0_bc" start="14" end="14" type="bool"/>
|
||||
<field name="ix_index0_1" start="8" end="13" type="uint"/>
|
||||
<field name="ix_edge_flag0_ab" start="6" end="6" type="bool"/>
|
||||
<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"/>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_VERTEX_WORD_1" length="1">
|
||||
<field name="z0" start="16" end="31" type="uint"/>
|
||||
<field name="y0" start="0" end="15" type="uint">
|
||||
<define name="SHIFT" value="8"/>
|
||||
</field>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_VERTEX_WORD_2" length="1">
|
||||
<field name="x1" start="16" end="31" type="uint"/>
|
||||
<field name="z0" start="0" end="15" type="uint">
|
||||
<define name="SHIFT" value="16"/>
|
||||
</field>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_VERTEX_WORD_3" length="1">
|
||||
<field name="y1" start="8" end="31" type="uint"/>
|
||||
<field name="x1" start="0" end="7" type="uint">
|
||||
<define name="SHIFT" value="16"/>
|
||||
</field>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_VERTEX_WORD_4" length="1">
|
||||
<field name="z1" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
</csbgen>
|
||||
@@ -0,0 +1,286 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<!--
|
||||
Copyright © 2022 Imagination Technologies Ltd.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
-->
|
||||
|
||||
<!--
|
||||
These definitions are based on the ones for the firmware streams found
|
||||
in the fwif header (pvr_rogue_fwif_stream.h).
|
||||
|
||||
TODO: Once the kernel driver is merged upstream, check to see if this comment
|
||||
needs updating.
|
||||
-->
|
||||
|
||||
<!--
|
||||
This file is structured as follows:
|
||||
- defines
|
||||
- enums
|
||||
- structs
|
||||
- streams
|
||||
|
||||
Elements in each section are ordered alphabetically.
|
||||
-->
|
||||
|
||||
<!--
|
||||
TODO: Currently the sizes for fields are in bits. Those should be changed to
|
||||
bytes. Might want to do this in conjunction with csbgen being changed from
|
||||
dword to bytes granular.
|
||||
-->
|
||||
<!--
|
||||
TODO: Allow embedding of struct definitions withing stream elements. And for
|
||||
structs that might be shared between multiple streams, allow for the field
|
||||
type to be set to a struct.
|
||||
-->
|
||||
<csbgen name="ROGUE" prefix="KMD_STREAM">
|
||||
|
||||
<define name="EXTHDR_DATA_MASK" value="0xFFFFFFF"/>
|
||||
|
||||
<!--
|
||||
Note: this does not depend on
|
||||
\ref pvr_device_features.has_eight_output_registers .
|
||||
It's always 8 catering for the largest size.
|
||||
-->
|
||||
<!--
|
||||
TODO: Instead of defining this, see if we can use something like anvil's
|
||||
"group" where a field is repeated n times. That would allow us to get the
|
||||
total length of the whole group instead of the driver calculating it by
|
||||
multiplying this with the size of the usc reg.
|
||||
-->
|
||||
<!--
|
||||
TODO: This should only be defined for `CMD_FRAG`. Allow the definition of
|
||||
`define` elements within structs and streams.
|
||||
-->
|
||||
<define name="USC_CLEAR_REGISTER_COUNT" value="8"/>
|
||||
|
||||
<enum name="EXTHDR_TYPE_COMPUTE">
|
||||
<value name="0" value="0"/>
|
||||
</enum>
|
||||
|
||||
<enum name="EXTHDR_TYPE_FRAG">
|
||||
<value name="0" value="0"/>
|
||||
</enum>
|
||||
|
||||
<enum name="EXTHDR_TYPE_GEOM">
|
||||
<value name="0" value="0"/>
|
||||
</enum>
|
||||
|
||||
<enum name="PIXEL_PHANTOM_STATE">
|
||||
<value name="DISABLED" value="0x0"/>
|
||||
<value name="ENABLED" value="0xF"/>
|
||||
</enum>
|
||||
|
||||
<struct name="EXTHDR_COMPUTE0" length="1">
|
||||
<field name="type" start="29" end="31" type="EXTHDR_TYPE_COMPUTE" default="0"/>
|
||||
<field name="continuation" start="28" end="28" type="bool"/>
|
||||
<field name="has_brn49927" start="0" end="0" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<struct name="EXTHDR_FRAG0" length="1">
|
||||
<field name="type" start="29" end="31" type="EXTHDR_TYPE_FRAG" default="0"/>
|
||||
<field name="continuation" start="28" end="28" type="bool"/>
|
||||
<field name="has_brn49927" start="1" end="1" type="bool"/>
|
||||
<field name="has_brn47217" start="0" end="0" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<struct name="EXTHDR_GEOM0" length="1">
|
||||
<field name="type" start="29" end="31" type="EXTHDR_TYPE_GEOM" default="0"/>
|
||||
<field name="continuation" start="28" end="28" type="bool"/>
|
||||
<field name="has_brn49927" start="0" end="0" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<struct name="HDR" length="2">
|
||||
<field name="length" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<!--
|
||||
Note: if there's an attempt to disable all phantoms, they will all be set
|
||||
to their default states (i.e. all enabled).
|
||||
-->
|
||||
<struct name="PIXEL_PHANTOM" length="1">
|
||||
<field name="phantom_1" start="4" end="7" type="PIXEL_PHANTOM_STATE"/>
|
||||
<field name="phantom_0" start="0" end="3" type="PIXEL_PHANTOM_STATE"/>
|
||||
</struct>
|
||||
|
||||
<struct name="VIEW_IDX" length="1">
|
||||
<field name="idx" start="0" end="7" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<stream name="CMD_COMPUTE" length="18">
|
||||
<field name="tpu_border_colour_table" size="64" type="uint"/>
|
||||
<!-- Only present if PVR_FEATURE_CDM_USER_MODE_QUEUE supported on the current device -->
|
||||
<field name="cdm_cb_queue" size="64" type="uint" feature="PVR_FEATURE_CDM_USER_MODE_QUEUE"/>
|
||||
<!-- Only present if PVR_FEATURE_CDM_USER_MODE_QUEUE supported on the current device -->
|
||||
<field name="cbm_cb_base" size="64" type="address" shift="0" feature="PVR_FEATURE_CDM_USER_MODE_QUEUE"/>
|
||||
<!-- Only present if PVR_FEATURE_CDM_USER_MODE_QUEUE supported on the current device -->
|
||||
<field name="cdm_cb" size="64" type="uint" feature="PVR_FEATURE_CDM_USER_MODE_QUEUE"/>
|
||||
<!-- Only present if PVR_FEATURE_CDM_USER_MODE_QUEUE supported on the current device -->
|
||||
<field name="cdm_ctrl_stream_base" size="64" type="address" shift="0" feature="PVR_FEATURE_CDM_USER_MODE_QUEUE"/>
|
||||
<field name="cdm_context_state_base_addr" size="64" type="address" shift="0"/>
|
||||
<field name="cdm_resume_pds1" size="32" type="uint"/>
|
||||
<!-- Only present if PVR_FEATURE_COMPUTE_MORTON_CAPABLE supported on the current device -->
|
||||
<field name="cdm_item" size="32" type="uint" feature="PVR_FEATURE_COMPUTE_MORTON_CAPABLE"/>
|
||||
<!-- Only present if PVR_FEATURE_CLUSTER_GROUPING supported on the current device -->
|
||||
<field name="compute_cluster" size="32" type="uint" feature="PVR_FEATURE_CLUSTER_GROUPING"/>
|
||||
<!-- Only present if PVR_FEATURE_TPU_DM_GLOBAL_REGISTERS supported on the current device -->
|
||||
<field name="tpu_tag_cdm_ctrl" size="32" type="uint" feature="PVR_FEATURE_TPU_DM_GLOBAL_REGISTERS"/>
|
||||
<!-- Only present if PVR_FEATURE_CDM_USER_MODE_QUEUE supported on the current device -->
|
||||
<field name="stream_start_offset" size="32" type="uint" feature="PVR_FEATURE_CDM_USER_MODE_QUEUE"/>
|
||||
<!-- Only present if PVR_FEATURE_GPU_MULTICORE_SUPPORT supported on the current device -->
|
||||
<field name="execute_count" size="32" type="uint" feature="PVR_FEATURE_GPU_MULTICORE_SUPPORT"/>
|
||||
</stream>
|
||||
|
||||
<stream name="CMD_COMPUTE_EXT_BRN49927" length="1">
|
||||
<field name="tpu" size="32" type="uint"/>
|
||||
</stream>
|
||||
|
||||
<stream name="CMD_FRAG" length="100">
|
||||
<field name="isp_scissor_base" size="64" type="address" shift="0"/>
|
||||
<field name="isp_dbias_base" size="64" type="address" shift="0"/>
|
||||
<field name="isp_oclqry_base" size="64" type="address" shift="0"/>
|
||||
<field name="isp_zlsctl" size="64" type="address" shift="0"/>
|
||||
<field name="isp_zload_store_base" size="64" type="address" shift="0"/>
|
||||
<field name="isp_stencil_load_store_base" size="64" type="address" shift="0"/>
|
||||
<!-- Only present if PVR_FEATURE_REQUIRES_FB_CDC_ZLS_SETUP supported on the current device -->
|
||||
<field name="fb_cdc_zls" size="64" type="uint" feature="PVR_FEATURE_REQUIRES_FB_CDC_ZLS_SETUP"/>
|
||||
<field name="pbe_word" size="1536" type="uint_array"/>
|
||||
<field name="tpu_border_colour_table" size="64" type="uint"/>
|
||||
<field name="pds_bgnd" size="192" type="uint_array"/>
|
||||
<field name="pds_pr_bgnd" size="192" type="uint_array"/>
|
||||
<field name="usc_clear_register" size="256" type="uint_array"/>
|
||||
<field name="usc_pixel_output_ctrl" size="32" type="uint"/>
|
||||
<field name="isp_bgobjdepth" size="32" type="uint"/>
|
||||
<field name="isp_bgobjvals" size="32" type="uint"/>
|
||||
<field name="isp_aa" size="32" type="uint"/>
|
||||
<!-- Only present if PVR_FEATURE_S7_TOP_INFRASTRUCTURE supported on the current device -->
|
||||
<field name="isp_xtp_pipe_enable" size="32" type="uint" feature="PVR_FEATURE_S7_TOP_INFRASTRUCTURE"/>
|
||||
<field name="isp_ctl" size="32" type="uint"/>
|
||||
<field name="event_pixel_pds_info" size="32" type="uint"/>
|
||||
<!-- Only present if PVR_FEATURE_CLUSTER_GROUPING supported on the current device -->
|
||||
<field name="pixel_phantom" size="32" type="uint" feature="PVR_FEATURE_CLUSTER_GROUPING"/>
|
||||
<field name="view_idx" size="32" type="uint"/>
|
||||
<field name="event_pixel_pds_data" size="32" type="uint"/>
|
||||
<!-- Only present if PVR_FEATURE_GPU_MULTICORE_SUPPORT supported on the current device -->
|
||||
<field name="isp_oclqry_stride" size="32" type="uint" feature="PVR_FEATURE_GPU_MULTICORE_SUPPORT"/>
|
||||
<!-- Only present if PVR_FEATURE_ZLS_SUBTILE supported on the current device -->
|
||||
<field name="isp_zls_pixels" size="32" type="uint" feature="PVR_FEATURE_ZLS_SUBTILE"/>
|
||||
<!-- Only present if PVR_FEATURE_ISP_ZLS_D24_S8_PACKING_OGL_MODE supported on the current device -->
|
||||
<field name="rgx_cr_blackpearl_fix" size="32" type="uint" feature="PVR_FEATURE_ISP_ZLS_D24_S8_PACKING_OGL_MODE"/>
|
||||
<field name="zls_stride" size="32" type="uint"/>
|
||||
<field name="sls_stride" size="32" type="uint"/>
|
||||
<!-- Only present if PVR_FEATURE_GPU_MULTICORE_SUPPORT supported on the current device -->
|
||||
<field name="execute_count" size="32" type="uint" feature="PVR_FEATURE_GPU_MULTICORE_SUPPORT"/>
|
||||
</stream>
|
||||
|
||||
<stream name="CMD_FRAG_EXT_BRN47217" length="1">
|
||||
<field name="isp_oclqry_stride" size="32" type="uint"/>
|
||||
</stream>
|
||||
|
||||
<stream name="CMD_FRAG_EXT_BRN49927" length="1">
|
||||
<field name="tpu" size="32" type="uint"/>
|
||||
</stream>
|
||||
|
||||
<stream name="CMD_GEOM" length="13">
|
||||
<field name="vdm_ctrl_stream_base" size="64" type="address" shift="0"/>
|
||||
<field name="tpu_border_colour_table" size="64" type="uint"/>
|
||||
<!-- Only present if PVR_FEATURE_VDM_DRAWINDIRECT supported on the current device -->
|
||||
<field name="vdm_draw_indirect0" size="64" type="uint" feature="PVR_FEATURE_VDM_DRAWINDIRECT"/>
|
||||
<!-- Only present if PVR_FEATURE_VDM_DRAWINDIRECT supported on the current device -->
|
||||
<field name="vdm_draw_indirect1" size="32" type="uint" feature="PVR_FEATURE_VDM_DRAWINDIRECT"/>
|
||||
<field name="ppp_ctrl" size="32" type="uint"/>
|
||||
<field name="te_psg" size="32" type="uint"/>
|
||||
<field name="vdm_context_resume_task0_size" size="32" type="uint"/>
|
||||
<!-- Only present if PVR_FEATURE_VDM_OBJECT_LEVEL_LLS supported on the current device -->
|
||||
<field name="vdm_context_resume_task3_size" size="32" type="uint" feature="PVR_FEATURE_VDM_OBJECT_LEVEL_LLS"/>
|
||||
<field name="view_idx" size="32" type="uint"/>
|
||||
<!-- Only present if PVR_FEATURE_TESSELLATION supported on the current device -->
|
||||
<field name="pds_coeff_free_prog" size="32" type="uint" feature="PVR_FEATURE_TESSELLATION"/>
|
||||
</stream>
|
||||
|
||||
<stream name="CMD_GEOM_EXT_BRN49927" length="1">
|
||||
<field name="tpu" size="32" type="uint"/>
|
||||
</stream>
|
||||
|
||||
<stream name="CMD_TRANSFER" length="43">
|
||||
<field name="pds_bgnd0_base" size="64" type="address" shift="0"/>
|
||||
<field name="pds_bgnd1_base" size="64" type="address" shift="0"/>
|
||||
<field name="pds_bgnd3_sizeinfo" size="64" type="uint"/>
|
||||
<field name="isp_mtile_base" size="64" type="address" shift="0"/>
|
||||
<field name="pbr_wordx_mrty" size="576" type="uint_array"/>
|
||||
<field name="isp_bgobjvals" size="32" type="uint"/>
|
||||
<field name="usc_pixel_output_ctrl" size="32" type="uint"/>
|
||||
<field name="usc_clear_register0" size="32" type="uint"/>
|
||||
<field name="usc_clear_register1" size="32" type="uint"/>
|
||||
<field name="usc_clear_register2" size="32" type="uint"/>
|
||||
<field name="usc_clear_register3" size="32" type="uint"/>
|
||||
<field name="isp_mtile_size" size="32" type="uint"/>
|
||||
<field name="isp_render_origin" size="32" type="uint"/>
|
||||
<field name="isp_ctl" size="32" type="uint"/>
|
||||
<field name="isp_aa" size="32" type="uint"/>
|
||||
<field name="event_pixel_pds_info" size="32" type="uint"/>
|
||||
<field name="event_pixel_pds_code" size="32" type="uint"/>
|
||||
<field name="event_pixel_pds_data" size="32" type="uint"/>
|
||||
<field name="isp_render" size="32" type="uint"/>
|
||||
<field name="isp_rgn" size="32" type="uint"/>
|
||||
<!-- Only present if PVR_FEATURE_S7_TOP_INFRASTRUCTURE supported on the current device -->
|
||||
<field name="isp_xtp_pipe_enable" size="32" type="uint" feature="PVR_FEATURE_S7_TOP_INFRASTRUCTURE"/>
|
||||
<!-- Only present if PVR_FEATURE_GPU_MULTICORE_SUPPORT supported on the current device -->
|
||||
<field name="frag_screen" size="32" type="uint" feature="PVR_FEATURE_GPU_MULTICORE_SUPPORT"/>
|
||||
</stream>
|
||||
|
||||
<stream name="STATIC_COMPUTE_CONTEXT_STATE" length="14">
|
||||
<field name="cdm_reg_context_pds0" size="64" type="uint"/>
|
||||
<field name="cdm_reg_context_pds1" size="64" type="uint"/>
|
||||
<field name="cdm_reg_terminate_pds0" size="64" type="uint"/>
|
||||
<field name="cdm_reg_terminate_pds1" size="64" type="uint"/>
|
||||
<field name="cdm_reg_resume_pds0" size="64" type="uint"/>
|
||||
<field name="cdm_reg_context_pds0_b" size="64" type="uint"/>
|
||||
<field name="cdm_reg_resume_pds0_b" size="64" type="uint"/>
|
||||
</stream>
|
||||
|
||||
<stream name="STATIC_RENDER_CONTEXT_STATE" length="46">
|
||||
<field name="geom_reg_vdm_context_state_base_addr" size="64" type="address" shift="0"/>
|
||||
<field name="geom_reg_vdm_context_state_resume_addr" size="64" type="address" shift="0"/>
|
||||
<field name="geom_reg_ta_context_state_base_addr" size="64" type="address" shift="0"/>
|
||||
<field name="geom_state0_geom_reg_vdm_context_store_task0" size="64" type="uint"/>
|
||||
<field name="geom_state0_geom_reg_vdm_context_store_task1" size="64" type="uint"/>
|
||||
<field name="geom_state0_geom_reg_vdm_context_store_task2" size="64" type="uint"/>
|
||||
<field name="geom_state0_geom_reg_vdm_context_store_task3" size="64" type="uint"/>
|
||||
<field name="geom_state0_geom_reg_vdm_context_store_task4" size="64" type="uint"/>
|
||||
<field name="geom_state0_geom_reg_vdm_context_resume_task0" size="64" type="uint"/>
|
||||
<field name="geom_state0_geom_reg_vdm_context_resume_task1" size="64" type="uint"/>
|
||||
<field name="geom_state0_geom_reg_vdm_context_resume_task2" size="64" type="uint"/>
|
||||
<field name="geom_state0_geom_reg_vdm_context_resume_task3" size="64" type="uint"/>
|
||||
<field name="geom_state0_geom_reg_vdm_context_resume_task4" size="64" type="uint"/>
|
||||
<field name="geom_state1_geom_reg_vdm_context_store_task0" size="64" type="uint"/>
|
||||
<field name="geom_state1_geom_reg_vdm_context_store_task1" size="64" type="uint"/>
|
||||
<field name="geom_state1_geom_reg_vdm_context_store_task2" size="64" type="uint"/>
|
||||
<field name="geom_state1_geom_reg_vdm_context_store_task3" size="64" type="uint"/>
|
||||
<field name="geom_state1_geom_reg_vdm_context_store_task4" size="64" type="uint"/>
|
||||
<field name="geom_state1_geom_reg_vdm_context_resume_task0" size="64" type="uint"/>
|
||||
<field name="geom_state1_geom_reg_vdm_context_resume_task1" size="64" type="uint"/>
|
||||
<field name="geom_state1_geom_reg_vdm_context_resume_task2" size="64" type="uint"/>
|
||||
<field name="geom_state1_geom_reg_vdm_context_resume_task3" size="64" type="uint"/>
|
||||
<field name="geom_state1_geom_reg_vdm_context_resume_task4" size="64" type="uint"/>
|
||||
</stream>
|
||||
|
||||
</csbgen>
|
||||
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<!--
|
||||
Copyright © 2022 Imagination Technologies Ltd.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
-->
|
||||
|
||||
<csbgen name="ROGUE" prefix="LLS">
|
||||
|
||||
<!-- Size of the CDM's context state buffer in bytes. -->
|
||||
<define name="CDM_CONTEXT_RESUME_BUFFER_SIZE" value="72"/>
|
||||
<define name="CDM_CONTEXT_RESUME_BUFFER_ALIGNMENT" value="16"/>
|
||||
|
||||
<!-- Size of the PDS's persistent-temporary register context state buffer in bytes. -->
|
||||
<define name="PDS_PERSISTENT_TEMPS_BUFFER_ALIGNMENT" value="16"/>
|
||||
<define name="PDS_PERSISTENT_TEMPS_BUFFER_SIZE" value="128"/>
|
||||
|
||||
<!-- Size of the TA's context state buffer in bytes. -->
|
||||
<define name="TA_STATE_BUFFER_ALIGNMENT" value="16"/>
|
||||
<define name="TA_STATE_BUFFER_SIZE" value="484"/>
|
||||
|
||||
<!-- Size of the USC's shared register context state buffer in bytes. -->
|
||||
<define name="USC_SHARED_REGS_BUFFER_ALIGNMENT" value="16"/>
|
||||
<define name="USC_SHARED_REGS_BUFFER_SIZE" value="16384"/>
|
||||
|
||||
<!-- Size of the VDM's context resume control stream buffer in bytes. -->
|
||||
<define name="VDM_CONTEXT_RESUME_BUFFER_ALIGNMENT" value="16"/>
|
||||
<define name="VDM_CONTEXT_RESUME_BUFFER_SIZE" value="92"/>
|
||||
|
||||
</csbgen>
|
||||
@@ -0,0 +1,26 @@
|
||||
# Copyright © 2022 Imagination Technologies Ltd.
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
pvr_xml_files = [
|
||||
'cdm.xml',
|
||||
'cr.xml',
|
||||
'ipf.xml',
|
||||
'kmd_stream.xml',
|
||||
'lls.xml',
|
||||
'pbestate.xml',
|
||||
'pds.xml',
|
||||
'ppp.xml',
|
||||
'texstate.xml',
|
||||
'vdm.xml',
|
||||
]
|
||||
|
||||
foreach f : pvr_xml_files
|
||||
_name = '@[email protected]'.format(f.split('.')[0])
|
||||
pvr_xml_pack += custom_target(
|
||||
_name,
|
||||
input : ['../gen_pack_header.py', f],
|
||||
output : _name,
|
||||
command : [prog_python, '@INPUT@'],
|
||||
capture : true,
|
||||
)
|
||||
endforeach
|
||||
@@ -0,0 +1,293 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<!--
|
||||
Copyright © 2022 Imagination Technologies Ltd.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
-->
|
||||
|
||||
<csbgen name="ROGUE" prefix="PBESTATE">
|
||||
|
||||
<enum name="COMP_IADDR_TYPE">
|
||||
<value name="INDIRECT_1TILE" value="0"/>
|
||||
<value name="INDIRECT_4TILE" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="COMPRESS_SIZE">
|
||||
<value name="BLOCK_8X8" value="0"/>
|
||||
<value name="BLOCK_16X4" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="COMPRESS_SIZE_EXT">
|
||||
<value name="BLOCK_8X8_16X4" value="0"/>
|
||||
<value name="BLOCK_32X2_RSRVD" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="COMPRESSION">
|
||||
<value name="DISABLED" value="0"/>
|
||||
<value name="ENABLED" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="LOSSY">
|
||||
<value name="DISABLED" value="0"/>
|
||||
<value name="ENABLED" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="MEMLAYOUT">
|
||||
<value name="LINEAR" value="0"/>
|
||||
<value name="TWIDDLE_2D" value="1"/>
|
||||
<value name="TWIDDLE_3D" value="2"/>
|
||||
<value name="TILED" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="PACKMODE">
|
||||
<value name="U8U8U8U8" value="0x0"/>
|
||||
<value name="S8S8S8S8" value="0x1"/>
|
||||
<value name="X8U8S8S8" value="0x2"/>
|
||||
<value name="X8S8S8U8" value="0x3"/>
|
||||
<value name="A1R5G5B5" value="0x4"/>
|
||||
<value name="R5G5B5A1" value="0x5"/>
|
||||
<value name="A4R4G4B4" value="0x6"/>
|
||||
<value name="A8R3G3B2" value="0x7"/>
|
||||
<value name="U16U16U16U16" value="0x8"/>
|
||||
<value name="S16S16S16S16" value="0x9"/>
|
||||
<value name="F16F16F16F16" value="0xa"/>
|
||||
<value name="U32U32U32U32" value="0xb"/>
|
||||
<value name="S32S32S32S32" value="0xc"/>
|
||||
<value name="F32F32F32F32" value="0xd"/>
|
||||
<value name="A2R10B10G10" value="0xe"/>
|
||||
<value name="R10B10G10A2" value="0xf"/>
|
||||
<value name="A2F10F10F10" value="0x10"/>
|
||||
<value name="F10F10F10A2" value="0x11"/>
|
||||
<value name="U8U8U8" value="0x12"/>
|
||||
<value name="S8S8S8" value="0x13"/>
|
||||
<value name="R5G6B5" value="0x14"/>
|
||||
<value name="R5SG5SB6" value="0x15"/>
|
||||
<value name="B6G5SR5S" value="0x16"/>
|
||||
<value name="U16U16U16" value="0x17"/>
|
||||
<value name="S16S16S16" value="0x18"/>
|
||||
<value name="F16F16F16" value="0x19"/>
|
||||
<value name="U32U32U32" value="0x1a"/>
|
||||
<value name="S32S32S32" value="0x1b"/>
|
||||
<value name="F11F11F10" value="0x1c"/>
|
||||
<value name="F10F11F11" value="0x1d"/>
|
||||
<value name="SE9995" value="0x1e"/>
|
||||
<value name="F32F32F32" value="0x1f"/>
|
||||
<value name="X24U8F32" value="0x20"/>
|
||||
<value name="X24X8F32" value="0x21"/>
|
||||
<value name="X24G8X32" value="0x22"/>
|
||||
<value name="U8U8" value="0x23"/>
|
||||
<value name="S8S8" value="0x24"/>
|
||||
<value name="U16U16" value="0x25"/>
|
||||
<value name="S16S16" value="0x26"/>
|
||||
<value name="F16F16" value="0x27"/>
|
||||
<value name="U32U32" value="0x28"/>
|
||||
<value name="S32S32" value="0x29"/>
|
||||
<value name="F32F32" value="0x2a"/>
|
||||
<value name="U24ST8" value="0x2b"/>
|
||||
<value name="ST8U24" value="0x2c"/>
|
||||
<value name="X8U24" value="0x2d"/>
|
||||
<value name="U8X24" value="0x2e"/>
|
||||
<value name="U8" value="0x2f"/>
|
||||
<value name="S8" value="0x30"/>
|
||||
<value name="U16" value="0x31"/>
|
||||
<value name="S16" value="0x32"/>
|
||||
<value name="F16" value="0x33"/>
|
||||
<value name="U32" value="0x34"/>
|
||||
<value name="S32" value="0x35"/>
|
||||
<value name="F32" value="0x36"/>
|
||||
<value name="PBYTE" value="0x37"/>
|
||||
<value name="PWORD" value="0x38"/>
|
||||
<value name="ARGBV16_XR10" value="0x39"/>
|
||||
<value name="A2_XRBIAS_U10U10U10" value="0x3a"/>
|
||||
<value name="YUV" value="0x3b"/>
|
||||
<value name="U10U10U10_XRBIAS_A2" value="0x3c"/>
|
||||
<value name="INVALID" value="0xFFFFFFFF"/>
|
||||
</enum>
|
||||
|
||||
<enum name="PAIR_TILES">
|
||||
<value name="DISABLED" value="0"/>
|
||||
<value name="ENABLED" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="ROTATION_TYPE">
|
||||
<value name="0_DEG" value="0"/>
|
||||
<value name="90_DEG" value="1"/>
|
||||
<value name="180_DEG" value="2"/>
|
||||
<value name="270_DEG" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="SIZE">
|
||||
<value name="1_PIXEL" value="0"/>
|
||||
<value name="2_PIXEL" value="1"/>
|
||||
<value name="4_PIXEL" value="2"/>
|
||||
<value name="8_PIXEL" value="3"/>
|
||||
<value name="16_PIXEL" value="4"/>
|
||||
<value name="32_PIXEL" value="5"/>
|
||||
<value name="64_PIXEL" value="6"/>
|
||||
<value name="128_PIXEL" value="7"/>
|
||||
<value name="256_PIXEL" value="8"/>
|
||||
<value name="512_PIXEL" value="9"/>
|
||||
<value name="1K_PIXEL" value="10"/>
|
||||
<value name="2K_PIXEL" value="11"/>
|
||||
<value name="4K_PIXEL" value="12"/>
|
||||
<value name="8K_PIXEL" value="13"/>
|
||||
<value name="16K_PIXEL" value="14"/>
|
||||
</enum>
|
||||
|
||||
<enum name="SOURCE_FORMAT">
|
||||
<value name="F16_PER_CHANNEL" value="0"/>
|
||||
<value name="8_PER_CHANNEL" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="SOURCE_POS">
|
||||
<value name="START_BIT0" value="0"/>
|
||||
<value name="START_BIT32" value="1"/>
|
||||
<value name="START_BIT64" value="2"/>
|
||||
<value name="START_BIT96" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="SWIZ">
|
||||
<value name="SOURCE_CHAN0" value="0"/>
|
||||
<value name="SOURCE_CHAN1" value="1"/>
|
||||
<value name="SOURCE_CHAN2" value="2"/>
|
||||
<value name="SOURCE_CHAN3" value="3"/>
|
||||
<value name="ONE" value="4"/>
|
||||
<value name="ZERO" value="5"/>
|
||||
</enum>
|
||||
|
||||
<enum name="TFBC_LOSSY">
|
||||
<value name="LOSSLESS" value="0"/>
|
||||
<value name="LOSSY75" value="1"/>
|
||||
<value name="LOSSY50" value="2"/>
|
||||
<value name="LOSSY25" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="TWOCOMP_GAMMA">
|
||||
<value name="GAMMA_BOTTOM_CHANNEL" value="0"/>
|
||||
<value name="GAMMA_BOTH_CHANNELS" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="Y_FLIP">
|
||||
<value name="DISABLED" value="0"/>
|
||||
<value name="ENABLED" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="YUV_DOWNSCALE">
|
||||
<value name="NO_DOWNSCALING" value="0"/>
|
||||
<value name="ONE_SAMPLE_LEFT" value="1"/>
|
||||
<value name="EMPTY" value="2"/>
|
||||
<value name="TWO_SAMPLES" value="3"/>
|
||||
<value name="FOUR_SAMPLES" value="4"/>
|
||||
<value name="ONE_SAMPLE_RIGHT" value="5"/>
|
||||
</enum>
|
||||
|
||||
<enum name="YUV_PMODE">
|
||||
<value name="UV8_420_2PLANE" value="0"/>
|
||||
<value name="U8_420_3PLANE" value="1"/>
|
||||
<value name="V8_420_3PLANE" value="2"/>
|
||||
<value name="YUV8_422_1PLANE" value="3"/>
|
||||
<value name="UV8_422_2PLANE" value="4"/>
|
||||
<value name="UV8_444_2PLANE" value="5"/>
|
||||
<value name="Y8_23PLANE" value="6"/>
|
||||
<value name="U8_444_3PLANE" value="7"/>
|
||||
<value name="V8_444_3PLANE" value="8"/>
|
||||
<value name="YUV10_444_1PLANE" value="9"/>
|
||||
<value name="RESERVED_YUV1" value="10"/>
|
||||
<value name="RESERVED_YUV2" value="11"/>
|
||||
<value name="YUV10_422_1PLANE" value="12"/>
|
||||
<value name="UV10_420_2PLANE" value="13"/>
|
||||
<value name="Y10_23PLANE" value="14"/>
|
||||
<value name="UV16_420_2PLANE" value="15"/>
|
||||
<value name="UV16_422_2PLANE" value="16"/>
|
||||
<value name="UV16_444_2PLANE" value="17"/>
|
||||
<value name="Y16_23PLANE" value="18"/>
|
||||
<value name="U16_444_3PLANE" value="19"/>
|
||||
<value name="V16_444_3PLANE" value="20"/>
|
||||
</enum>
|
||||
|
||||
<struct name="STATE_WORD0" length="1">
|
||||
<field name="address_low" start="0" end="31" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_WORD1" length="1">
|
||||
<condition type="if" check="8_OUTPUT_REGISTERS"/>
|
||||
<field name="source_pos_offset_128" start="28" end="28" type="bool"/>
|
||||
<condition type="endif" check="8_OUTPUT_REGISTERS"/>
|
||||
<field name="yuv_pmode" start="23" end="27" type="YUV_PMODE"/>
|
||||
<field name="yuv_downscale" start="20" end="22" type="YUV_DOWNSCALE"/>
|
||||
<field name="source_format" start="19" end="19" type="SOURCE_FORMAT"/>
|
||||
<field name="mrt_index" start="16" end="18" type="uint"/>
|
||||
<field name="source_pos" start="14" end="15" type="SOURCE_POS"/>
|
||||
<field name="norm" start="13" end="13" type="bool"/>
|
||||
<field name="packmode" start="7" end="12" type="PACKMODE"/>
|
||||
<field name="emptytile" start="6" end="6" type="bool"/>
|
||||
<field name="address_high" start="0" end="5" shift="34" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="REG_WORD0" length="2">
|
||||
<field name="tfbc_lossy" start="62" end="63" type="TFBC_LOSSY">
|
||||
<define name="LOSSY37_75_TFBC_LOSSY_37_PERCENT_ENABLED" value="1"/>
|
||||
</field>
|
||||
<field name="lossy" start="62" end="62" type="LOSSY"/>
|
||||
<field name="compress_size_ext" start="61" end="61" type="COMPRESS_SIZE_EXT"/>
|
||||
<field name="comp_iaddr_mode" start="60" end="60" type="COMP_IADDR_TYPE"/>
|
||||
<field name="comp_cor_enable" start="59" end="59" type="bool"/>
|
||||
<field name="dither" start="58" end="58" type="bool"/>
|
||||
<field name="tilerelative" start="57" end="57" type="bool"/>
|
||||
<field name="downscale" start="56" end="56" type="bool"/>
|
||||
<field name="size_z" start="52" end="55" type="SIZE"/>
|
||||
<field name="rotation" start="50" end="51" type="ROTATION_TYPE"/>
|
||||
<field name="linestride" start="34" end="49" type="uint">
|
||||
<define name="UNIT_SIZE" value="2"/>
|
||||
</field>
|
||||
<field name="memlayout" start="32" end="33" type="MEMLAYOUT"/>
|
||||
<field name="swiz_chan3" start="29" end="31" type="SWIZ"/>
|
||||
<field name="swiz_chan2" start="26" end="28" type="SWIZ"/>
|
||||
<field name="swiz_chan1" start="23" end="25" type="SWIZ"/>
|
||||
<field name="swiz_chan0" start="20" end="22" type="SWIZ"/>
|
||||
<field name="minclip_x" start="6" end="19" type="uint"/>
|
||||
<field name="twocomp_gamma" start="5" end="5" type="TWOCOMP_GAMMA"/>
|
||||
<field name="gamma" start="4" end="4" type="bool"/>
|
||||
<field name="compression" start="3" end="3" type="COMPRESSION"/>
|
||||
<field name="compress_size" start="2" end="2" type="COMPRESS_SIZE"/>
|
||||
<field name="comp_indirect_table" start="1" end="1" type="bool"/>
|
||||
<field name="y_flip" start="0" end="0" type="Y_FLIP"/>
|
||||
</struct>
|
||||
|
||||
<struct name="REG_WORD1" length="2">
|
||||
<field name="size_x" start="60" end="63" type="SIZE"/>
|
||||
<field name="minclip_y" start="46" end="59" type="uint"/>
|
||||
<field name="maxclip_x" start="32" end="45" type="uint"/>
|
||||
<field name="size_y" start="28" end="31" type="SIZE"/>
|
||||
<field name="zslice" start="14" end="27" type="uint"/>
|
||||
<field name="maxclip_y" start="0" end="13" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="REG_WORD2" length="2">
|
||||
<field name="pair_tiles" start="46" end="46" type="PAIR_TILES">
|
||||
<!-- TODO: Do we need this? -->
|
||||
<define name="SHIFT" value="46"/>
|
||||
</field>
|
||||
<field name="surface_y_size" start="32" end="45" type="uint"/>
|
||||
<field name="sw_bytemask" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
</csbgen>
|
||||
@@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<!--
|
||||
Copyright © 2022 Imagination Technologies Ltd.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
-->
|
||||
|
||||
<csbgen name="ROGUE" prefix="PDSINST">
|
||||
|
||||
<enum name="CMODE_LD">
|
||||
<value name="CACHED" value="0"/>
|
||||
<value name="BYPASS" value="1"/>
|
||||
<value name="FORCE_LINE_FILL" value="2"/>
|
||||
</enum>
|
||||
|
||||
<enum name="DOUTD_DEST">
|
||||
<value name="UNIFIED_STORE" value="0"/>
|
||||
<value name="COMMON_STORE" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="DEST">
|
||||
<value name="UNIFIED_STORE" value="0"/>
|
||||
<value name="COMMON_STORE" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="DOUTI_SHADEMODEL">
|
||||
<value name="FLAT_VERTEX0" value="0"/>
|
||||
<value name="FLAT_VERTEX1" value="1"/>
|
||||
<value name="FLAT_VERTEX2" value="2"/>
|
||||
<value name="GOURUAD" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="DOUTI_SIZE">
|
||||
<value name="1D" value="0"/>
|
||||
<value name="2D" value="1"/>
|
||||
<value name="3D" value="2"/>
|
||||
<value name="4D" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="DOUTU_SAMPLE_RATE">
|
||||
<value name="INSTANCE" value="0"/>
|
||||
<value name="SELECTIVE" value="1"/>
|
||||
<value name="FULL" value="2"/>
|
||||
</enum>
|
||||
|
||||
<enum name="SLC_MODE_LD">
|
||||
<value name="BYPASS" value="0"/>
|
||||
<value name="CACHED" value="1"/>
|
||||
<value name="CACHED_RD_NA" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="WORDSIZE">
|
||||
<value name="ONE" value="0"/>
|
||||
<value name="TWO" value="1"/>
|
||||
<value name="THREE" value="2"/>
|
||||
<value name="FOUR" value="3"/>
|
||||
</enum>
|
||||
|
||||
<struct name="DDMAD_FIELDS_SRC3" length="2">
|
||||
<condition type="if" check="PDS_DDMADT"/>
|
||||
<field name="msize" start="33" end="63" type="uint"/>
|
||||
<field name="test" start="32" end="32" type="bool"/>
|
||||
<condition type="endif" check="PDS_DDMADT"/>
|
||||
<field name="last" start="31" end="31" type="bool"/>
|
||||
<field name="wordsize" start="29" end="30" type="WORDSIZE"/>
|
||||
<field name="dest" start="28" end="28" type="DEST"/>
|
||||
<field name="cmode" start="26" end="27" type="CMODE_LD"/>
|
||||
<field name="a0" start="13" end="25" type="uint"/>
|
||||
<field name="repeat" start="12" end="12" type="bool"/>
|
||||
<field name="bsize" start="0" end="11" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="DOUTU_SRC0" length="2">
|
||||
<field name="dual_phase" start="41" end ="41" type="bool"/>
|
||||
<field name="temps" start="35" end="40" type="uint">
|
||||
<define name="UNIT_SIZE" value="2"/>
|
||||
</field>
|
||||
<field name="sample_rate" start="33" end="34" type="DOUTU_SAMPLE_RATE"/>
|
||||
<field name="exe_off" start="2" end="31" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="DOUT_FIELDS_DOUTD_SRC0" length="2">
|
||||
<condition type="if" check="SLC_MCU_CACHE_CONTROLS"/>
|
||||
<field name="slcmode" start="60" end="61" type="SLC_MODE_LD"/>
|
||||
<condition type="endif" check="SLC_MCU_CACHE_CONTROLS"/>
|
||||
<field name="doffset" start="40" end="52" type="uint"/>
|
||||
<field name="sbase" start="0" end="39" shift="0" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="DOUT_FIELDS_DOUTD_SRC1" length="1">
|
||||
<field name="last" start="31" end="31" type="bool"/>
|
||||
<field name="wordsize" start="29" end="30" type="WORDSIZE"/>
|
||||
<field name="dest" start="28" end="28" type="DOUTD_DEST"/>
|
||||
<field name="cmode" start="26" end="27" type="CMODE_LD"/>
|
||||
<field name="a0" start="13" end="25" type="uint">
|
||||
<define name="UNIT_SIZE" value="4"/>
|
||||
</field>
|
||||
<field name="repeat" start="12" end="12" type="bool"/>
|
||||
<field name="bsize" start="0" end="11" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="DOUT_FIELDS_DOUTI_SRC" length="1">
|
||||
<field name="depthbias" start="27" end="27" type="bool"/>
|
||||
<field name="primitiveid" start="26" end="26" type="bool"/>
|
||||
<field name="shademodel" start="24" end="25" type="DOUTI_SHADEMODEL"/>
|
||||
<field name="pointsprite" start="23" end="23" type="bool"/>
|
||||
<field name="wraps" start="22" end="22" type="bool"/>
|
||||
<field name="wrapv" start="21" end="21" type="bool"/>
|
||||
<field name="wrapu" start="20" end="20" type="bool"/>
|
||||
<field name="size" start="18" end="19" type="DOUTI_SIZE"/>
|
||||
<field name="f16" start="17" end="17" type="bool"/>
|
||||
<field name="perspective" start="16" end="16" type="bool"/>
|
||||
<field name="f32_offset" start="8" end="15" type="uint"/>
|
||||
<field name="f16_offset" start="0" end="7" type="uint"/>
|
||||
</struct>
|
||||
|
||||
</csbgen>
|
||||
@@ -0,0 +1,343 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<!--
|
||||
Copyright © 2022 Imagination Technologies Ltd.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
-->
|
||||
|
||||
<csbgen name="ROGUE" prefix="TA">
|
||||
|
||||
<enum name="CLIP_MODE">
|
||||
<value name="NO_FRONT_OR_REAR" value="0"/>
|
||||
<value name="FRONT_REAR" value="1"/>
|
||||
<value name="FRONT_REAR_DEPTH" value="2"/>
|
||||
</enum>
|
||||
|
||||
<enum name="CMPMODE">
|
||||
<value name="NEVER" value="0"/>
|
||||
<value name="LESS" value="1"/>
|
||||
<value name="EQUAL" value="2"/>
|
||||
<value name="LESS_OR_EQUAL" value="3"/>
|
||||
<value name="GREATER" value="4"/>
|
||||
<value name="NOT_EQUAL" value="5"/>
|
||||
<value name="GREATER_OR_EQUAL" value="6"/>
|
||||
<value name="ALWAYS" value="7"/>
|
||||
</enum>
|
||||
|
||||
<enum name="CULLMODE">
|
||||
<value name="NO_CULLING" value="0"/>
|
||||
<value name="CULL_CW" value="1"/>
|
||||
<value name="CULL_CCW" value="2"/>
|
||||
</enum>
|
||||
|
||||
<enum name="FLATSHADE">
|
||||
<value name="VTX_VERTEX_0" value="1"/>
|
||||
<value name="VTX_VERTEX_1" value="2"/>
|
||||
<value name="VTX_VERTEX_2" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="GS_OUTPUT_TOPOLOGY">
|
||||
<value name="POINT_LIST" value="0"/>
|
||||
<value name="LINE_STRIP" value="1"/>
|
||||
<value name="TRI_STRIP" value="2"/>
|
||||
</enum>
|
||||
|
||||
<enum name="ISPB_STENCILOP">
|
||||
<value name="KEEP" value="0"/>
|
||||
<value name="ZERO" value="1"/>
|
||||
<value name="REPLACE" value="2"/>
|
||||
<value name="INCREMENT_SATURATE" value="3"/>
|
||||
<value name="DECREMENT_SATURATE" value="4"/>
|
||||
<value name="INVERT" value="5"/>
|
||||
<value name="INCREMENT" value="6"/>
|
||||
<value name="DECREMENT" value="7"/>
|
||||
</enum>
|
||||
|
||||
<enum name="OBJTYPE">
|
||||
<value name="TRIANGLE" value="0"/>
|
||||
<value name="LINE" value="1"/>
|
||||
<value name="SPRITE_10UV" value="2"/>
|
||||
<value name="SPRITE_UV" value="3"/>
|
||||
<value name="SPRITE_01UV" value="4"/>
|
||||
<value name="LINE_FILLED_TRIANGLE" value="5"/>
|
||||
<value name="POINT_FILLED_TRIANGLE" value="6"/>
|
||||
<value name="TESSELLATED_OBJECT_NO_GS" value="7"/>
|
||||
<value name="TESSELLATED_OBJECT_WITH_GS" value="8"/>
|
||||
</enum>
|
||||
|
||||
<!--
|
||||
TODO: Add support for "ifs" in csbgen root element.
|
||||
-->
|
||||
<enum name="PASSTYPE">
|
||||
<value name="OPAQUE" value="0"/>
|
||||
<value name="TRANSLUCENT" value="1"/>
|
||||
<value name="PUNCH_THROUGH" value="2"/>
|
||||
<value name="VIEWPORT_OBJECT" value="3"/>
|
||||
<value name="FAST_PUNCH_THROUGH" value="4"/>
|
||||
<value name="DEPTH_FEEDBACK" value="5"/>
|
||||
<value name="ANTI_ALIASED" value="6"/>
|
||||
</enum>
|
||||
|
||||
<enum name="REGION_CLIP_MODE">
|
||||
<value name="NONE" value="0"/>
|
||||
<value name="OUTSIDE" value="1"/>
|
||||
</enum>
|
||||
|
||||
<struct name="STATE_HEADER" length="1">
|
||||
<field name="not_final_term" start="26" end="26" type="bool"/>
|
||||
<field name="pres_terminate" start="25" end="25" type="bool"/>
|
||||
<field name="context_switch" start="24" end="24" type="bool"/>
|
||||
<field name="pres_stream_out_program" start="23" end="23" type="bool"/>
|
||||
<field name="pres_stream_out_size" start="22" end="22" type="bool"/>
|
||||
<field name="pres_ppp_ctrl" start="21" end="21" type="bool"/>
|
||||
<field name="pres_varying_word2" start="20" end="20" type="bool"/>
|
||||
<field name="pres_varying_word1" start="19" end="19" type="bool"/>
|
||||
<field name="pres_varying_word0" start="18" end="18" type="bool"/>
|
||||
<field name="pres_outselects" start="17" end="17" type="bool"/>
|
||||
<field name="pres_wclamp" start="16" end="16" type="bool"/>
|
||||
<field name="view_port_count" start="12" end="15" type="uint"/>
|
||||
<field name="pres_viewport" start="11" end="11" type="bool"/>
|
||||
<field name="pres_region_clip" start="10" end="10" type="bool"/>
|
||||
<field name="pres_pds_state_ptr3" start="9" end="9" type="bool"/>
|
||||
<field name="pres_pds_state_ptr2" start="8" end="8" type="bool"/>
|
||||
<field name="pres_pds_state_ptr1" start="7" end="7" type="bool"/>
|
||||
<field name="pres_pds_state_ptr0" start="6" end="6" type="bool"/>
|
||||
<field name="pres_ispctl_dbsc" start="5" end="5" type="bool"/>
|
||||
<field name="pres_ispctl_bb" start="4" end="4" type="bool"/>
|
||||
<field name="pres_ispctl_ba" start="3" end="3" type="bool"/>
|
||||
<field name="pres_ispctl_fb" start="2" end="2" type="bool"/>
|
||||
<field name="pres_ispctl_fa" start="1" end="1" type="bool"/>
|
||||
<field name="pres_ispctl" start="0" end="0" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_ISPCTL" length="1">
|
||||
<field name="validid" start="26" end="31" type="uint"/>
|
||||
<field name="upass" start="22" end="25" type="uint"/>
|
||||
<field name="tagwritedisable" start="21" end="21" type="bool"/>
|
||||
<field name="ovgmtestdisable" start="20" end="20" type="bool"/>
|
||||
<field name="two_sided" start="19" end="19" type="bool"/>
|
||||
<field name="bpres" start="18" end="18" type="bool"/>
|
||||
<field name="dbenable" start="17" end="17" type="bool"/>
|
||||
<field name="scenable" start="16" end="16" type="bool"/>
|
||||
<field name="vistest" start="15" end="15" type="bool"/>
|
||||
<field name="visbool" start="14" end="14" type="bool"/>
|
||||
<field name="visreg" start="0" end="13" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_ISPA" length="1">
|
||||
<field name="objtype" start="28" end="31" type="OBJTYPE"/>
|
||||
<field name="passtype" start="24" end="26" type="PASSTYPE"/>
|
||||
<field name="ovgvispassmaskop" start="23" end="23" type="bool"/>
|
||||
<field name="maskval" start="22" end="22" type="bool"/>
|
||||
<field name="dwritedisable" start="21" end="21" type="bool"/>
|
||||
<field name="dfbztestenable" start="20" end="20" type="bool"/>
|
||||
<field name="dcmpmode" start="17" end="19" type="CMPMODE"/>
|
||||
<field name="linefilllastpixel" start="16" end="16" type="bool"/>
|
||||
<field name="pointlinewidth" start="8" end="15" type="uint">
|
||||
<define name="SIZE_MAX" value="255"/>
|
||||
</field>
|
||||
<field name="sref" start="0" end="7" type="uint">
|
||||
<define name="SIZE_MAX" value="255"/>
|
||||
</field>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_ISPB" length="1">
|
||||
<field name="scmpmode" start="25" end="27" type="CMPMODE"/>
|
||||
<field name="sop1" start="22" end="24" type="ISPB_STENCILOP"/>
|
||||
<field name="sop2" start="19" end="21" type="ISPB_STENCILOP"/>
|
||||
<field name="sop3" start="16" end="18" type="ISPB_STENCILOP"/>
|
||||
<field name="scmpmask" start="8" end="15" type="uint"/>
|
||||
<field name="swmask" start="0" end="7" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<!-- `REGION_CLIP{0,1}` `left`,`right`,`top`,`bottom`, are all 9 bits. -->
|
||||
<define name="REGION_CLIP_MAX" value="0x1FF"/>
|
||||
|
||||
<struct name="REGION_CLIP0" length="1">
|
||||
<field name="mode" start="31" end="31" type="REGION_CLIP_MODE"/>
|
||||
<field name="left" start="16" end="24" type="uint"/>
|
||||
<field name="right" start="0" end="8" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="REGION_CLIP1" length="1">
|
||||
<field name="top" start="16" end="24" type="uint"/>
|
||||
<field name="bottom" start="0" end="8" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="WCLAMP" length="1">
|
||||
<field name="val" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_ISPDBSC" length="1">
|
||||
<field name="dbindex" start="16" end="31" type="uint"/>
|
||||
<field name="scindex" start="0" end="15" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="OUTPUT_SEL" length="1">
|
||||
<field name="vtxsize" start="24" end="31" type="uint"/>
|
||||
<field name="tsp_unclamped_z_pres" start="21" end="21" type="bool"/>
|
||||
<field name="render_tgt_pres" start="20" end="20" type="bool"/>
|
||||
<field name="vpt_tgt_pres" start="19" end="19" type="bool"/>
|
||||
<field name="psprite_size_pres" start="18" end="18" type="bool"/>
|
||||
<field name="isp_position_depth_clamp_z" start="17" end="17" type="bool"/>
|
||||
<field name="rhw_pres" start="16" end="16" type="bool"/>
|
||||
<field name="cullplane7" start="15" end="15" type="bool"/>
|
||||
<field name="cullplane6" start="14" end="14" type="bool"/>
|
||||
<field name="cullplane5" start="13" end="13" type="bool"/>
|
||||
<field name="cullplane4" start="12" end="12" type="bool"/>
|
||||
<field name="cullplane3" start="11" end="11" type="bool"/>
|
||||
<field name="cullplane2" start="10" end="10" type="bool"/>
|
||||
<field name="cullplane1" start="9" end="9" type="bool"/>
|
||||
<field name="cullplane0" start="8" end="8" type="bool"/>
|
||||
<field name="plane7" start="7" end="7" type="bool"/>
|
||||
<field name="plane6" start="6" end="6" type="bool"/>
|
||||
<field name="plane5" start="5" end="5" type="bool"/>
|
||||
<field name="plane4" start="4" end="4" type="bool"/>
|
||||
<field name="plane3" start="3" end="3" type="bool"/>
|
||||
<field name="plane2" start="2" end="2" type="bool"/>
|
||||
<field name="plane1" start="1" end="1" type="bool"/>
|
||||
<field name="plane0" start="0" end="0" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_VARYING0" length="1">
|
||||
<field name="f32_npc" start="16" end="23" type="uint"/>
|
||||
<field name="f32_flat" start="8" end="15" type="uint"/>
|
||||
<field name="f32_linear" start="0" end="7" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_VARYING1" length="1">
|
||||
<field name="f16_npc" start="24" end="31" type="uint"/>
|
||||
<field name="f16_flat" start="16" end="23" type="uint"/>
|
||||
<field name="f16_linear" start="8" end="15" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_VARYING2" length="1">
|
||||
<field name="output_clip_planes" start="16" end="19" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_TERMINATE0" length="1">
|
||||
<field name="clip_right" start="18" end="26" type="uint">
|
||||
<define name="BLOCK_SIZE_IN_PIXELS" value="32"/>
|
||||
</field>
|
||||
<field name="clip_top" start="9" end="17" type="uint">
|
||||
<define name="BLOCK_SIZE_IN_PIXELS" value="32"/>
|
||||
</field>
|
||||
<field name="clip_bottom" start="0" end="8" type="uint">
|
||||
<define name="BLOCK_SIZE_IN_PIXELS" value="32"/>
|
||||
</field>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_TERMINATE1" length="1">
|
||||
<field name="clip_left" start="23" end="31" type="uint">
|
||||
<define name="BLOCK_SIZE_IN_PIXELS" value="32"/>
|
||||
</field>
|
||||
<field name="render_target" start="0" end="10" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_STREAM_OUT0" length="1">
|
||||
<field name="stream3_size" start="24" end="31" type="uint"/>
|
||||
<field name="stream2_size" start="16" end="23" type="uint"/>
|
||||
<field name="stream1_size" start="8" end="15" type="uint"/>
|
||||
<field name="stream0_mem_output" start="1" end="1" type="bool"/>
|
||||
<field name="stream0_ta_output" start="0" end="0" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_STREAM_OUT1" length="1">
|
||||
<field name="sync" start="10" end="10" type="bool"/>
|
||||
<field name="pds_data_size" start="4" end="9" type="uint">
|
||||
<define name="UNIT_SIZE" value="16"/>
|
||||
</field>
|
||||
<field name="pds_temp_size" start="0" end="3" type="uint">
|
||||
<define name="UNIT_SIZE" value="16"/>
|
||||
</field>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_STREAM_OUT2" length="1">
|
||||
<!-- This is an offset actually. Note for when we auto-generate the xmls. -->
|
||||
<field name="pds_data_addr" start="4" end="31" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_PDS_SHADERBASE" length="1">
|
||||
<!-- This is an offset actually. Note for when we auto-generate the xmls. -->
|
||||
<field name="addr" start="4" end="31" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_PDS_TEXUNICODEBASE" length="1">
|
||||
<field name="addr" start="4" end="31" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_PDS_VARYINGBASE" length="1">
|
||||
<!-- This is an offset actually. Note for when we auto-generate the xmls. -->
|
||||
<field name="addr" start="4" end="31" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_PDS_TEXTUREDATABASE" length="1">
|
||||
<field name="addr" start="4" end="31" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_PDS_UNIFORMDATABASE" length="1">
|
||||
<!-- This is an offset actually. Note for when we auto-generate the xmls. -->
|
||||
<field name="addr" start="4" end="31" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_PDS_SIZEINFO1" length="1">
|
||||
<field name="pds_uniformsize" start="23" end="31" type="uint">
|
||||
<define name="UNIT_SIZE" value="4"/>
|
||||
</field>
|
||||
<field name="pds_texturestatesize" start="16" end="22" type="uint">
|
||||
<define name="UNIT_SIZE" value="4"/>
|
||||
</field>
|
||||
<field name="pds_varyingsize" start="10" end="15" type="uint">
|
||||
<define name="UNIT_SIZE" value="4"/>
|
||||
</field>
|
||||
<field name="usc_varyingsize" start="4" end="9" type="uint">
|
||||
<define name="UNIT_SIZE" value="16"/>
|
||||
<define name="MAX_SIZE" value="63"/>
|
||||
</field>
|
||||
<field name="pds_tempsize" start="0" end="3" type="uint">
|
||||
<define name="UNIT_SIZE" value="4"/>
|
||||
</field>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_PDS_SIZEINFO2" length="1">
|
||||
<field name="usc_sharedsize" start="23" end="31" type="uint">
|
||||
<define name="UNIT_SIZE" value="16"/>
|
||||
</field>
|
||||
<field name="pds_tri_merge_disable" start="14" end="14" type="bool"/>
|
||||
<field name="pds_batchnum" start="0" end="13" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STATE_PPP_CTRL" length="1">
|
||||
<field name="prim_msaa" start="15" end="15" type="bool"/>
|
||||
<field name="gs_output_topology" start="13" end="14" type="GS_OUTPUT_TOPOLOGY"/>
|
||||
<field name="pres_prim_id" start="12" end="12" type="bool"/>
|
||||
<field name="clip_mode" start="10" end="11" type="CLIP_MODE"/>
|
||||
<field name="drawclippededges" start="9" end="9" type="bool"/>
|
||||
<field name="flatshade_vtx" start="7" end="8" type="FLATSHADE"/>
|
||||
<field name="pretransform" start="6" end="6" type="bool"/>
|
||||
<field name="wclampen" start="5" end="5" type="bool"/>
|
||||
<field name="wbuffen" start="4" end="4" type="bool"/>
|
||||
<field name="resetbbox" start="3" end="3" type="bool"/>
|
||||
<field name="updatebbox" start="2" end="2" type="bool"/>
|
||||
<field name="cullmode" start="0" end="1" type="CULLMODE"/>
|
||||
</struct>
|
||||
|
||||
</csbgen>
|
||||
@@ -0,0 +1,369 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<!--
|
||||
Copyright © 2022 Imagination Technologies Ltd.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
-->
|
||||
|
||||
<csbgen name="ROGUE" prefix="TEXSTATE">
|
||||
|
||||
<enum name="ADDRMODE">
|
||||
<value name="REPEAT" value="0"/>
|
||||
<value name="FLIP" value="1"/>
|
||||
<value name="CLAMP_TO_EDGE" value="2"/>
|
||||
<value name="FLIP_ONCE_THEN_CLAMP" value="3"/>
|
||||
<value name="CLAMP_TO_BORDER" value="4"/>
|
||||
<value name="OGL_CLAMP" value="5"/>
|
||||
</enum>
|
||||
|
||||
<enum name="ANISOCTL">
|
||||
<value name="DISABLED" value="0"/>
|
||||
<value name="X2" value="1"/>
|
||||
<value name="X4" value="2"/>
|
||||
<value name="X8" value="3"/>
|
||||
<value name="X16" value="4"/>
|
||||
</enum>
|
||||
|
||||
<enum name="CLAMP">
|
||||
<value name="MIN" value="0"/>
|
||||
<value name="MAX" value="959"/>
|
||||
<value name="INTEGER_BITS" value="4"/>
|
||||
<value name="FRACTIONAL_BITS" value="6"/>
|
||||
</enum>
|
||||
|
||||
<enum name="CMP_MODE">
|
||||
<value name="NEVER" value="0"/>
|
||||
<value name="LESS" value="1"/>
|
||||
<value name="EQUAL" value="2"/>
|
||||
<value name="LESSEQUAL" value="3"/>
|
||||
<value name="GREATER" value="4"/>
|
||||
<value name="NOTEQUAL" value="5"/>
|
||||
<value name="GREATEREQUAL" value="6"/>
|
||||
<value name="ALWAYS" value="7"/>
|
||||
</enum>
|
||||
|
||||
<enum name="COMPRESSION_LEVEL">
|
||||
<value name="LOSSLESS" value="0"/>
|
||||
<value name="LOSSY_75" value="1"/>
|
||||
<value name="LOSSY_50" value="2"/>
|
||||
<value name="LOSSY_25" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="COMPRESSION_MODE">
|
||||
<value name="NONE" value="0"/>
|
||||
<value name="TPU" value="1"/>
|
||||
<value name="FB_DIRECT_8X8" value="2"/>
|
||||
<value name="FB_DIRECT_16X4" value="3"/>
|
||||
<value name="FB_INDIRECT_1TILE_8X8" value="4"/>
|
||||
<value name="FB_INDIRECT_1TILE_16X4" value="5"/>
|
||||
<value name="FB_INDIRECT_4TILE_8X8" value="6"/>
|
||||
<value name="FB_INDIRECT_4TILE_16X4" value="7"/>
|
||||
</enum>
|
||||
|
||||
<enum name="DADJUST">
|
||||
<value name="MIN_UINT" value="0"/>
|
||||
<value name="ZERO_UINT" value="4095"/>
|
||||
<value name="MAX_UINT" value="8191"/>
|
||||
<value name="INTEGER_BITS" value="5"/>
|
||||
<value name="FRACTIONAL_BITS" value="8"/>
|
||||
</enum>
|
||||
|
||||
<enum name="FILTER">
|
||||
<value name="POINT" value="0"/>
|
||||
<value name="LINEAR" value="1"/>
|
||||
<value name="BICUBIC" value="2"/>
|
||||
</enum>
|
||||
|
||||
<enum name="FORMAT">
|
||||
<value name="U8" value="0"/>
|
||||
<value name="S8" value="1"/>
|
||||
<value name="A4R4G4B4" value="2"/>
|
||||
<value name="A8R3G3B2" value="3"/>
|
||||
<value name="A1R5G5B5" value="4"/>
|
||||
<value name="R5G6B5" value="5"/>
|
||||
<value name="R5sG5sB6" value="6"/>
|
||||
<value name="U8U8" value="7"/>
|
||||
<value name="S8S8" value="8"/>
|
||||
<value name="U16" value="9"/>
|
||||
<value name="S16" value="10"/>
|
||||
<value name="F16" value="11"/>
|
||||
<value name="U8U8U8U8" value="12"/>
|
||||
<value name="S8S8S8S8" value="13"/>
|
||||
<value name="A2R10B10G10" value="14"/>
|
||||
<value name="U16U16" value="15"/>
|
||||
<value name="S16S16" value="16"/>
|
||||
<value name="F16F16" value="17"/>
|
||||
<value name="F32" value="18"/>
|
||||
<value name="F32_SIGNMASK" value="19"/>
|
||||
<value name="X8U8S8S8" value="20"/>
|
||||
<value name="X8U24" value="21"/>
|
||||
<value name="ST8U24" value="22"/>
|
||||
<value name="U8X24" value="23"/>
|
||||
<value name="U32" value="24"/>
|
||||
<value name="S32" value="25"/>
|
||||
<value name="SE9995" value="26"/>
|
||||
<value name="F11F11F10" value="27"/>
|
||||
<value name="F16F16F16F16" value="28"/>
|
||||
<value name="U16U16U16U16" value="29"/>
|
||||
<value name="S16S16S16S16" value="30"/>
|
||||
<value name="F16F16F16" value="31"/>
|
||||
<value name="U16U16U16" value="32"/>
|
||||
<value name="S16S16S16" value="33"/>
|
||||
<value name="F32F32" value="34"/>
|
||||
<value name="U32U32" value="35"/>
|
||||
<value name="S32S32" value="36"/>
|
||||
<value name="X24U8F32" value="37"/>
|
||||
<value name="X24X8F32" value="38"/>
|
||||
<value name="X24G8X32" value="39"/>
|
||||
<value name="YUV420_2PLANE" value="54"/>
|
||||
<value name="YVU420_2PLANE" value="55"/>
|
||||
<value name="YUV420_3PLANE" value="56"/>
|
||||
<value name="YVU420_3PLANE" value="57"/>
|
||||
<value name="U8U8U8" value="58"/>
|
||||
<value name="S8S8S8" value="59"/>
|
||||
<value name="A2F10F10F10" value="60"/>
|
||||
<value name="F32F32F32F32" value="61"/>
|
||||
<value name="U32U32U32U32" value="62"/>
|
||||
<value name="S32S32S32S32" value="63"/>
|
||||
<value name="F32F32F32" value="64"/>
|
||||
<value name="U32U32U32" value="65"/>
|
||||
<value name="S32S32S32" value="66"/>
|
||||
<value name="A2_XRBIAS_U10U10U10" value="67"/>
|
||||
<value name="O8" value="81"/>
|
||||
<value name="O8O8" value="82"/>
|
||||
<value name="R5G5B5A1" value="83"/>
|
||||
<value name="B6G5sR5s" value="84"/>
|
||||
<value name="R10B10G10A2" value="85"/>
|
||||
<value name="X8S8S8U8" value="86"/>
|
||||
<value name="U24ST8" value="87"/>
|
||||
<value name="F10F11F11" value="88"/>
|
||||
<value name="VYUY" value="89"/>
|
||||
<value name="UYVY" value="90"/>
|
||||
<value name="YVYU" value="91"/>
|
||||
<value name="YUYV" value="92"/>
|
||||
<value name="F10F10F10A2" value="93"/>
|
||||
<value name="YUV420_2PLANE_MACRO_BLOCK" value="94"/>
|
||||
<value name="YVU420_2PLANE_MACRO_BLOCK" value="95"/>
|
||||
<value name="ARGBV16_XR10" value="96"/>
|
||||
<value name="YVU8_422_2PLANE_PACK8" value="97"/>
|
||||
<value name="YVU8_444_2PLANE_PACK8" value="98"/>
|
||||
<value name="YVU10_444_1PLANE_PACK10" value="99"/>
|
||||
<value name="YVU10_422_2PLANE_PACK16" value="100"/>
|
||||
<value name="YVU10_420_2PLANE_PACK16" value="101"/>
|
||||
<value name="YVU10_444_2PLANE_PACK16" value="102"/>
|
||||
<value name="YUV8_422_2PLANE_PACK8" value="103"/>
|
||||
<value name="YUV8_444_3PLANE_PACK8" value="104"/>
|
||||
<value name="YUV10_444_3PLANE_PACK16" value="105"/>
|
||||
<value name="YVU10_420_2PLANE_PACK10" value="106"/>
|
||||
<value name="YUV10_420_2PLANE_PACK10" value="107"/>
|
||||
<value name="YVU10_422_2PLANE_PACK10" value="108"/>
|
||||
<value name="YUV10_422_2PLANE_PACK10" value="109"/>
|
||||
<value name="YUV10_444_3PLANE_PACK10" value="110"/>
|
||||
<value name="R8G8_B8G8" value="111"/>
|
||||
<value name="G8R8_G8B8" value="112"/>
|
||||
<value name="YVYU_IMPLIED_CSC" value="113"/>
|
||||
<value name="VYUY_IMPLIED_CSC" value="114"/>
|
||||
<value name="YUV10_420_2PLANE_PACK10_R" value="115"/>
|
||||
<value name="YVU10_420_2PLANE_PACK10_R" value="116"/>
|
||||
<value name="YUV10_420_2PLANE_PACK10_T" value="117"/>
|
||||
<value name="YVU10_420_2PLANE_PACK10_T" value="118"/>
|
||||
<value name="YUV8_420_2PLANE_PACK8_P" value="119"/>
|
||||
<value name="YVU8_420_2PLANE_PACK8_P" value="120"/>
|
||||
<value name="YUV8_420_2PLANE_PACK8_F" value="121"/>
|
||||
<value name="YVU8_420_2PLANE_PACK8_F" value="122"/>
|
||||
<value name="INVALID" value="0xFFFFFFFF"/>
|
||||
</enum>
|
||||
|
||||
<enum name="FORMAT_COMPRESSED">
|
||||
<value name="ASTC_4x4" value="0"/>
|
||||
<value name="ASTC_5x4" value="1"/>
|
||||
<value name="ASTC_5x5" value="2"/>
|
||||
<value name="ASTC_6x5" value="3"/>
|
||||
<value name="ASTC_6x6" value="4"/>
|
||||
<value name="ASTC_8x5" value="5"/>
|
||||
<value name="ASTC_8x6" value="6"/>
|
||||
<value name="ASTC_8x8" value="7"/>
|
||||
<value name="ASTC_10x5" value="8"/>
|
||||
<value name="ASTC_10x6" value="9"/>
|
||||
<value name="ASTC_10x8" value="10"/>
|
||||
<value name="ASTC_10x10" value="11"/>
|
||||
<value name="ASTC_12x10" value="12"/>
|
||||
<value name="ASTC_12x12" value="13"/>
|
||||
<value name="PVRT2BPP" value="40"/>
|
||||
<value name="PVRT4BPP" value="41"/>
|
||||
<value name="PVRTII2BPP" value="42"/>
|
||||
<value name="PVRTII4BPP" value="43"/>
|
||||
<value name="UBC1" value="44"/>
|
||||
<value name="UBC2" value="45"/>
|
||||
<value name="UBC3" value="46"/>
|
||||
<value name="UBC4" value="47"/>
|
||||
<value name="SBC4" value="48"/>
|
||||
<value name="UBC5" value="49"/>
|
||||
<value name="SBC5" value="50"/>
|
||||
<value name="UBC6" value="51"/>
|
||||
<value name="SBC6" value="52"/>
|
||||
<value name="UBC7" value="53"/>
|
||||
<value name="ETC2_RGB" value="68"/>
|
||||
<value name="ETC2A_RGBA" value="69"/>
|
||||
<value name="ETC2_PUNCHTHROUGHA" value="70"/>
|
||||
<value name="EAC_R11_UNSIGNED" value="71"/>
|
||||
<value name="EAC_R11_SIGNED" value="72"/>
|
||||
<value name="EAC_RG11_UNSIGNED" value="73"/>
|
||||
<value name="EAC_RG11_SIGNED" value="74"/>
|
||||
<value name="INVALID" value="0xFFFFFFFF"/>
|
||||
</enum>
|
||||
|
||||
<enum name="GAMMA">
|
||||
<value name="OFF" value="0"/>
|
||||
<value name="ON" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="SWIZ">
|
||||
<value name="SRCCHAN_0" value="0"/>
|
||||
<value name="SRCCHAN_1" value="1"/>
|
||||
<value name="SRCCHAN_2" value="2"/>
|
||||
<value name="SRCCHAN_3" value="3"/>
|
||||
<value name="SRC_ONE" value="4"/>
|
||||
<value name="SRC_ZERO" value="5"/>
|
||||
</enum>
|
||||
|
||||
<enum name="TEXTYPE">
|
||||
<value name="1D" value="0"/>
|
||||
<value name="2D" value="1"/>
|
||||
<value name="3D" value="2"/>
|
||||
<value name="CUBE" value="3"/>
|
||||
<value name="STRIDE" value="4"/>
|
||||
<value name="PAGETILE" value="5"/>
|
||||
<value name="BUFFER_LOOKUP" value="6"/>
|
||||
</enum>
|
||||
|
||||
<enum name="TWOCOMP_GAMMA">
|
||||
<value name="OFF" value="0"/>
|
||||
<value name="R" value="1"/>
|
||||
<value name="RG" value="3"/>
|
||||
</enum>
|
||||
|
||||
<!-- FIXME: This is the definition for hardware with TPU_IMAGE_STATE_V2.
|
||||
Add V1 definition when condition tags can be nested in enum tags.
|
||||
-->
|
||||
<enum name="CHROMAINTERP">
|
||||
<value name="ZERO" value="0"/>
|
||||
<value name="ENABLED" value="1"/>
|
||||
</enum>
|
||||
|
||||
<struct name="IMAGE_WORD0" length="2">
|
||||
<field name="smpcnt" start="62" end="63" type="uint"/>
|
||||
<field name="height" start="48" end="61" type="uint"/>
|
||||
<field name="width" start="34" end="47" type="uint">
|
||||
<define name="MAX_SIZE" value="16383"/>
|
||||
</field>
|
||||
<field name="texformat" start="27" end="33" type="FORMAT">
|
||||
<define name="MAX_SIZE" value="127"/>
|
||||
</field>
|
||||
<field name="texformat_compressed" start="27" end="33" type="FORMAT_COMPRESSED"/>
|
||||
<field name="minlod" start="17" end="26" type="uint"/>
|
||||
<field name="swiz0" start="14" end="16" type="SWIZ"/>
|
||||
<field name="swiz1" start="11" end="13" type="SWIZ"/>
|
||||
<field name="swiz2" start="8" end="10" type="SWIZ"/>
|
||||
<field name="swiz3" start="5" end="7" type="SWIZ"/>
|
||||
<field name="twocomp_gamma" start="3" end="4" type="TWOCOMP_GAMMA"/>
|
||||
<field name="gamma" start="3" end="3" type="GAMMA"/>
|
||||
<field name="textype" start="0" end="2" type="TEXTYPE"/>
|
||||
</struct>
|
||||
|
||||
<struct name="IMAGE_WORD1" length="2">
|
||||
<field name="baselevel" start="60" end="63" type="uint"/>
|
||||
<field name="alpha_msb" start="59" end="59" type="bool"/>
|
||||
<field name="border" start="58" end="58" type="bool"/>
|
||||
<condition type="if" check="TPU_IMAGE_STATE_V2"/>
|
||||
<condition type="if" check="TFBC"/>
|
||||
<field name="lossy_compression_mode" start="56" end="57" type="COMPRESSION_LEVEL"/>
|
||||
<condition type="endif" check="TFBC"/>
|
||||
<field name="tpu_image_state_v2_compression_mode" start="54" end="56" type="COMPRESSION_MODE"/>
|
||||
<condition type="else" check="TPU_IMAGE_STATE_V2"/>
|
||||
<field name="tile_size" start="57" end="57" type="bool"/>
|
||||
<field name="index_lookup" start="56" end="56" type="bool"/>
|
||||
<field name="frame_buffer_compression" start="55" end="55" type="bool"/>
|
||||
<field name="frame_buffer_compression_addressing_mode" start="54" end="54" type="bool"/>
|
||||
<condition type="endif" check="TPU_IMAGE_STATE_V2"/>
|
||||
<field name="texaddr" start="16" end="53" shift="2" type="address"/>
|
||||
<field name="mipmaps_present" start="15" end="15" type="bool"/>
|
||||
<field name="depth" start="4" end="14" type="uint">
|
||||
<define name="MAX_SIZE" value="2047"/>
|
||||
</field>
|
||||
<field name="num_mip_levels" start="0" end="3" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STRIDE_IMAGE_WORD1" length="2">
|
||||
<field name="num_mip_levels" start="60" end="63" type="uint"/>
|
||||
<field name="alpha_msb" start="59" end="59" type="bool"/>
|
||||
<condition type="if" check="TPU_IMAGE_STATE_V2"/>
|
||||
<condition type="if" check="TFBC"/>
|
||||
<field name="lossy_compression_mode" start="56" end="57" type="COMPRESSION_LEVEL"/>
|
||||
<condition type="endif" check="TFBC"/>
|
||||
<field name="tpu_image_state_v2_compression_mode" start="54" end="56" type="COMPRESSION_MODE"/>
|
||||
<condition type="else" check="TPU_IMAGE_STATE_V2"/>
|
||||
<field name="tile_size" start="57" end="57" type="bool"/>
|
||||
<field name="index_lookup" start="56" end="56" type="bool"/>
|
||||
<field name="frame_buffer_compression" start="55" end="55" type="bool"/>
|
||||
<field name="frame_buffer_compression_addressing_mode" start="54" end="54" type="bool"/>
|
||||
<condition type="endif" check="TPU_IMAGE_STATE_V2"/>
|
||||
<field name="texaddr" start="16" end="53" shift="2" type="address"/>
|
||||
<field name="mipmaps_present" start="15" end="15" type="bool"/>
|
||||
<field name="stride" start="0" end="14" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="YUV_IMAGE_WORD1" length="2">
|
||||
<field name="csc_coeff_index" start="60" end="63" type="uint"/>
|
||||
<field name="chroma_interpolation_v" start="59" end="59" type="CHROMAINTERP"/>
|
||||
<field name="chroma_interpolation_u" start="53" end="53" type="CHROMAINTERP"/>
|
||||
<field name="stride" start="38" end="52" type="uint"/>
|
||||
<field name="texaddr" start="0" end="37" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="SAMPLER_WORD0" length="2">
|
||||
<field name="texaddr_plane2_lo" start="50" end="63" shift="2" type="address"/>
|
||||
<field name="cmp_mode" start="59" end="61" type="CMP_MODE"/>
|
||||
<field name="addrmode_w" start="56" end="58" type="ADDRMODE"/>
|
||||
<field name="bordercolor_index" start="50" end="55" type="uint">
|
||||
<define name="MAX_SIZE" value="63"/>
|
||||
</field>
|
||||
<field name="non_normalized_coords" start="49" end="49" type="bool"/>
|
||||
<field name="lumakey_alphamult" start="48" end="48" type="bool"/>
|
||||
<field name="lumakey" start="47" end="47" type="bool"/>
|
||||
<field name="addrmode_v" start="44" end="46" type="ADDRMODE"/>
|
||||
<field name="addrmode_u" start="41" end="43" type="ADDRMODE"/>
|
||||
<field name="mipfilter" start="40" end="40" type="bool"/>
|
||||
<field name="minfilter" start="38" end="39" type="FILTER"/>
|
||||
<field name="magfilter" start="36" end="37" type="FILTER"/>
|
||||
<field name="anisoctl" start="33" end="35" type="ANISOCTL"/>
|
||||
<field name="maxlod" start="23" end="32" type="CLAMP"/>
|
||||
<field name="minlod" start="13" end="22" type="CLAMP"/>
|
||||
<field name="dadjust" start="0" end="12" type="DADJUST"/>
|
||||
</struct>
|
||||
|
||||
<struct name="SAMPLER_WORD1" length="2">
|
||||
<field name="cemedge_dontfilter" start="63" end="63" type="bool"/>
|
||||
<field name="texaddr_plane3" start="24" end="61" shift="2" type="address"/>
|
||||
<field name="texaddr_plane2_hi" start="0" end="23" shift="16" type="address"/>
|
||||
</struct>
|
||||
|
||||
</csbgen>
|
||||
@@ -0,0 +1,258 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<!--
|
||||
Copyright © 2022 Imagination Technologies Ltd.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
-->
|
||||
|
||||
<csbgen name="ROGUE" prefix="VDMCTRL">
|
||||
|
||||
<define name="GUARD_SIZE_DEFAULT" value="64"/>
|
||||
|
||||
<enum name="BLOCK_TYPE">
|
||||
<value name="PPP_STATE_UPDATE" value="0"/>
|
||||
<value name="PDS_STATE_UPDATE" value="1"/>
|
||||
<value name="VDM_STATE_UPDATE" value="2"/>
|
||||
<value name="INDEX_LIST" value="3"/>
|
||||
<value name="STREAM_LINK" value="4"/>
|
||||
<value name="STREAM_RETURN" value="5"/>
|
||||
<value name="STREAM_TERMINATE" value="6"/>
|
||||
<value name="CONTROL" value="7"/>
|
||||
</enum>
|
||||
|
||||
<enum name="DM_TARGET">
|
||||
<value name="VDM" value="0"/>
|
||||
<value name="DDM" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="FLATSHADE_CONTROL">
|
||||
<value name="VERTEX_0" value="0"/>
|
||||
<value name="VERTEX_1" value="1"/>
|
||||
<value name="VERTEX_2" value="2"/>
|
||||
</enum>
|
||||
|
||||
<enum name="INDEX_SIZE">
|
||||
<value name="B8" value="0"/>
|
||||
<value name="B16" value="1"/>
|
||||
<value name="B32" value="2"/>
|
||||
</enum>
|
||||
|
||||
<enum name="PRIMITIVE_TOPOLOGY">
|
||||
<value name="POINT_LIST" value="0"/>
|
||||
<value name="LINE_LIST" value="1"/>
|
||||
<value name="LINE_LIST_ADJ" value="2"/>
|
||||
<value name="LINE_STRIP" value="3"/>
|
||||
<value name="LINE_STRIP_ADJ" value="4"/>
|
||||
<value name="LINE_LOOP" value="5"/>
|
||||
<value name="TRI_LIST" value="6"/>
|
||||
<value name="TRI_LIST_ADJ" value="7"/>
|
||||
<value name="TRI_LIST_EDGE" value="8"/>
|
||||
<value name="TRI_STRIP" value="9"/>
|
||||
<value name="TRI_STRIP_ADJ" value="10"/>
|
||||
<value name="TRI_FAN" value="11"/>
|
||||
<value name="PATCH_LIST" value="12"/>
|
||||
</enum>
|
||||
|
||||
<enum name="SD_TYPE">
|
||||
<value name="NONE" value="0"/>
|
||||
<value name="PDS" value="1"/>
|
||||
<value name="USC" value="2"/>
|
||||
</enum>
|
||||
|
||||
<enum name="USC_TARGET">
|
||||
<value name="ALL" value="0"/>
|
||||
<value name="ANY" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="UVS_SCRATCH_SIZE_SELECT">
|
||||
<value name="FIVE" value="0"/>
|
||||
<value name="ONE" value="1"/>
|
||||
</enum>
|
||||
|
||||
<struct name="PPP_STATE0" length="1">
|
||||
<field name="block_type" start="29" end="31" type="BLOCK_TYPE" default="PPP_STATE_UPDATE"/>
|
||||
<field name="word_count" start="8" end="15" type="uint"/>
|
||||
<field name="addrmsb" start="0" end="7" shift="32" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="PPP_STATE1" length="1">
|
||||
<field name="addrlsb" start="2" end="31" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="PDS_STATE0" length="1">
|
||||
<field name="block_type" start="29" end="31" type="BLOCK_TYPE" default="PDS_STATE_UPDATE"/>
|
||||
<field name="dm_target" start="28" end="28" type="DM_TARGET"/>
|
||||
<field name="usc_target" start="25" end="25" type="USC_TARGET"/>
|
||||
<field name="usc_common_size" start="16" end="24" type="uint">
|
||||
<define name="UNIT_SIZE" value="64"/>
|
||||
</field>
|
||||
<field name="usc_unified_size" start="10" end="15" type="uint">
|
||||
<define name="UNIT_SIZE" value="16"/>
|
||||
</field>
|
||||
<field name="pds_temp_size" start="6" end="9" type="uint">
|
||||
<define name="UNIT_SIZE" value="16"/>
|
||||
</field>
|
||||
<field name="pds_data_size" start="0" end="5" type="uint">
|
||||
<define name="UNIT_SIZE" value="16"/>
|
||||
</field>
|
||||
</struct>
|
||||
|
||||
<struct name="PDS_STATE1" length="1">
|
||||
<!-- This is an offset actually. Note for when we auto-generate the xmls. -->
|
||||
<field name="pds_data_addr" start="4" end="31" shift="4" type="address"/>
|
||||
<field name="sd_type" start="2" end="3" type="SD_TYPE"/>
|
||||
<field name="sd_next_type" start="0" end="1" type="SD_TYPE"/>
|
||||
</struct>
|
||||
|
||||
<struct name="PDS_STATE2" length="1">
|
||||
<!-- This is an offset actually. Note for when we auto-generate the xmls. -->
|
||||
<field name="pds_code_addr" start="4" end="31" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STREAM_LINK0" length="1">
|
||||
<field name="block_type" start="29" end="31" type="BLOCK_TYPE" default="STREAM_LINK"/>
|
||||
<field name="with_return" start="28" end="28" type="bool"/>
|
||||
<field name="compare_present" start="27" end="27" type="bool"/>
|
||||
<field name="compare_mode" start="24" end="26" type="uint"/>
|
||||
<field name="compare_data" start="8" end="23" type="uint"/>
|
||||
<field name="link_addrmsb" start="0" end="7" shift="32" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STREAM_LINK1" length="1">
|
||||
<field name="link_addrlsb" start="2" end="31" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STREAM_RETURN" length="1">
|
||||
<field name="block_type" start="29" end="31" type="BLOCK_TYPE" default="STREAM_RETURN"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STREAM_TERMINATE" length="1">
|
||||
<field name="block_type" start="29" end="31" type="BLOCK_TYPE" default="STREAM_TERMINATE"/>
|
||||
<field name="context" start="0" end="0" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<struct name="VDM_STATE0" length="1">
|
||||
<field name="block_type" start="29" end="31" type="BLOCK_TYPE" default="VDM_STATE_UPDATE"/>
|
||||
<field name="cut_index_present" start="28" end="28" type="bool"/>
|
||||
<field name="vs_data_addr_present" start="27" end="27" type="bool"/>
|
||||
<field name="vs_other_present" start="26" end="26" type="bool"/>
|
||||
<field name="ds_present" start="24" end="24" type="bool"/>
|
||||
<field name="gs_present" start="23" end="23" type="bool"/>
|
||||
<field name="hs_present" start="22" end="22" type="bool"/>
|
||||
<field name="cam_size" start="7" end="14" type="uint"/>
|
||||
<field name="uvs_scratch_size_select" start="6" end="6" type="UVS_SCRATCH_SIZE_SELECT"/>
|
||||
<field name="cut_index_enable" start="5" end="5" type="bool"/>
|
||||
<field name="tess_enable" start="4" end="4" type="bool"/>
|
||||
<field name="gs_enable" start="3" end="3" type="bool"/>
|
||||
<field name="flatshade_control" start="1" end="2" type="FLATSHADE_CONTROL"/>
|
||||
<field name="generate_primitive_id" start="0" end="0" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<struct name="VDM_STATE1" length="1">
|
||||
<field name="cut_index" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="VDM_STATE2" length="1">
|
||||
<field name="vs_pds_data_base_addr" start="4" end="31" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="VDM_STATE3" length="1">
|
||||
<field name="vs_pds_code_base_addr" start="4" end="31" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="VDM_STATE4" length="1">
|
||||
<field name="vs_output_size" start="0" end="7" type="uint">
|
||||
<define name="UNIT_SIZE" value="4"/>
|
||||
</field>
|
||||
</struct>
|
||||
|
||||
<struct name="VDM_STATE5" length="1">
|
||||
<field name="vs_max_instances_ext" start="31" end="31" type="bool"/>
|
||||
<field name="vs_max_instances" start="25" end="29" type="uint"/>
|
||||
<field name="vs_usc_common_size" start="16" end="24" type="uint">
|
||||
<define name="UNIT_SIZE" value="64"/>
|
||||
</field>
|
||||
<field name="vs_usc_unified_size" start="10" end="15" type="uint">
|
||||
<define name="UNIT_SIZE" value="16"/>
|
||||
</field>
|
||||
<field name="vs_pds_temp_size" start="6" end="9" type="uint">
|
||||
<define name="UNIT_SIZE" value="16"/>
|
||||
</field>
|
||||
<field name="vs_pds_data_size" start="0" end="5" type="uint">
|
||||
<define name="UNIT_SIZE" value="16"/>
|
||||
</field>
|
||||
</struct>
|
||||
|
||||
<struct name="INDEX_LIST0" length="1">
|
||||
<field name="block_type" start="29" end="31" type="BLOCK_TYPE" default="INDEX_LIST"/>
|
||||
<field name="index_addr_present" start="28" end="28" type="bool"/>
|
||||
<field name="index_count_present" start="27" end="27" type="bool"/>
|
||||
<field name="index_instance_count_present" start="26" end="26" type="bool"/>
|
||||
<field name="index_offset_present" start="25" end="25" type="bool"/>
|
||||
<field name="start_present" start="24" end="24" type="bool"/>
|
||||
<field name="indirect_addr_present" start="23" end="23" type="bool"/>
|
||||
<field name="split_count_present" start="22" end="22" type="bool"/>
|
||||
<condition type="if" check="VDM_DEGENERATE_CULLING"/>
|
||||
<field name="degen_cull_enable" start="19" end="19" type="bool"/>
|
||||
<condition type="endif" check="VDM_DEGENERATE_CULLING"/>
|
||||
<field name="index_size" start="17" end="18" type="INDEX_SIZE"/>
|
||||
<field name="patch_count" start="12" end="16" type="uint"/>
|
||||
<field name="primitive_topology" start="8" end="11" type="PRIMITIVE_TOPOLOGY"/>
|
||||
<field name="index_base_addrmsb" start="0" end="7" shift="32" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="INDEX_LIST1" length="1">
|
||||
<field name="index_base_addrlsb" start="0" end="31" shift="0" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="INDEX_LIST2" length="1">
|
||||
<field name="index_count" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="INDEX_LIST3" length="1">
|
||||
<field name="instance_count" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="INDEX_LIST4" length="1">
|
||||
<field name="index_offset" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="INDEX_LIST5" length="1">
|
||||
<field name="start_index" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="INDEX_LIST6" length="1">
|
||||
<field name="start_instance" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="INDEX_LIST7" length="1">
|
||||
<field name="indirect_base_addrmsb" start="0" end="7" shift="32" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="INDEX_LIST8" length="1">
|
||||
<field name="indirect_base_addrlsb" start="2" end="31" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="INDEX_LIST9" length="1">
|
||||
<field name="split_count" start="0" end="15" type="uint"/>
|
||||
</struct>
|
||||
|
||||
</csbgen>
|
||||
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<!--
|
||||
Copyright © 2025 Imagination Technologies Ltd.
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
-->
|
||||
|
||||
<csbgen name="VOLCANIC" prefix="CDMCTRL">
|
||||
|
||||
<define name="GUARD_SIZE_DEFAULT" value="64"/>
|
||||
|
||||
<enum name="BLOCK_TYPE">
|
||||
<value name="COMPUTE_KERNEL" value="0"/>
|
||||
<value name="STREAM_LINK" value="1"/>
|
||||
<value name="STREAM_TERMINATE" value="2"/>
|
||||
</enum>
|
||||
|
||||
<enum name="USC_TARGET">
|
||||
<value name="ALL" value="0"/>
|
||||
<value name="ANY" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="SD_TYPE">
|
||||
<value name="NONE" value="0"/>
|
||||
<value name="PDS" value="1"/>
|
||||
<value name="USC" value="2"/>
|
||||
</enum>
|
||||
|
||||
<struct name="KERNEL0" length="1">
|
||||
<field name="block_type" start="30" end="31" type="BLOCK_TYPE" default="COMPUTE_KERNEL"/>
|
||||
<field name="indirect_present" start="29" end="29" type="bool"/>
|
||||
|
||||
<field name="usc_unified_size" start="12" end="18" type="uint"/>
|
||||
<field name="pds_temp_size" start="7" end="11" type="uint"/>
|
||||
<field name="pds_data_size" start="1" end="6" type="uint"/>
|
||||
|
||||
<field name="usc_target" start="0" end="0" type="USC_TARGET"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL1" length="1">
|
||||
<field name="data_addr" start="4" end="31" shift="4" type="address"/>
|
||||
<field name="sd_type" start="2" end="3" type="SD_TYPE"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL2" length="1">
|
||||
<field name="code_addr" start="4" end="31" shift="4" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL3" length="1">
|
||||
<field name="workgroup_x" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL4" length="1">
|
||||
<field name="workgroup_y" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL5" length="1">
|
||||
<field name="workgroup_z" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL6" length="1">
|
||||
<field name="indirect_addrmsb" start="0" end="15" shift="32" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL7" length="1">
|
||||
<field name="indirect_addrlsb" start="2" end="31" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL8" length="1">
|
||||
<field name="max_instances" start="25" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL9" length="1">
|
||||
<field name="workgroup_size_x" start="20" end="29" type="uint"/>
|
||||
<field name="workgroup_size_y" start="10" end="19" type="uint"/>
|
||||
<field name="workgroup_size_z" start="0" end="9" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL10" length="1">
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL11" length="1">
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL12" length="1">
|
||||
</struct>
|
||||
|
||||
<struct name="KERNEL13" length="1">
|
||||
</struct>
|
||||
|
||||
<struct name="STREAM_LINK0" length="1">
|
||||
<field name="block_type" start="30" end="31" type="BLOCK_TYPE" default="STREAM_LINK"/>
|
||||
<field name="link_addrmsb" start="0" end="15" shift="32" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STREAM_LINK1" length="1">
|
||||
<field name="link_addrlsb" start="2" end="31" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STREAM_TERMINATE" length="1">
|
||||
<field name="block_type" start="30" end="31" type="BLOCK_TYPE" default="STREAM_TERMINATE"/>
|
||||
</struct>
|
||||
|
||||
</csbgen>
|
||||
@@ -0,0 +1,139 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<!--
|
||||
Copyright © 2025 Imagination Technologies Ltd.
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
-->
|
||||
|
||||
<csbgen name="VOLCANIC" prefix="IPF">
|
||||
|
||||
<define name="TILE_SIZE_PIXELS" value="32"/>
|
||||
<define name="CONTROL_STREAM_SIZE_DWORDS" value="32"/>
|
||||
<define name="ISP_VERTEX_XY_BIAS_VALUE" value="4096"/>
|
||||
|
||||
<enum name="COMPRESSION_FORMAT">
|
||||
<value name="UNIQUE_1" value="0"/>
|
||||
<value name="ORIGIN_1_DELTA_1" value="1"/>
|
||||
<value name="ORIGIN_1_DELTA_2" value="2"/>
|
||||
<value name="ORIGIN_1_DELTA_3" value="3"/>
|
||||
<value name="ORIGIN_1_DELTA_4" value="4"/>
|
||||
<value name="ORIGIN_1_DELTA_5" value="5"/>
|
||||
<value name="ORIGIN_1_DELTA_6" value="6"/>
|
||||
<value name="ORIGIN_1_DELTA_7" value="7"/>
|
||||
<value name="RAW_BYTE" value="8"/>
|
||||
<value name="UNIQUE_2" value="9"/>
|
||||
<value name="ORIGIN_2_DELTA_1" value="10"/>
|
||||
<value name="ORIGIN_2_DELTA_2" value="11"/>
|
||||
<value name="ORIGIN_2_DELTA_3" value="12"/>
|
||||
<value name="ORIGIN_2_DELTA_4" value="13"/>
|
||||
<value name="ORIGIN_2_DELTA_5" value="14"/>
|
||||
<value name="ORIGIN_2_DELTA_6" value="15"/>
|
||||
</enum>
|
||||
|
||||
<enum name="CS_MASK_FMT">
|
||||
<value name="INDEX" value="0"/>
|
||||
<value name="BYTE" value="1"/>
|
||||
<value name="BIT" value="2"/>
|
||||
<value name="FULL" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="CS_TYPE">
|
||||
<value name="PRIM" value="0"/>
|
||||
<value name="LINK" value="2"/>
|
||||
<value name="TERM" value="3"/>
|
||||
</enum>
|
||||
|
||||
<struct name="CONTROL_STREAM" length="1">
|
||||
<field name="cs_type" start="30" end="31" type="CS_TYPE"/>
|
||||
<field name="cs_link" start="3" end="29" shift="7" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="PRIMITIVE_FORMAT" length="1">
|
||||
<field name="cs_type" start="30" end="31" type="CS_TYPE"/>
|
||||
<field name="cs_isp_state_size" start="26" end="28" type="uint"/>
|
||||
<field name="cs_prim_total" start="19" end="25" type="uint"/>
|
||||
<field name="cs_mask_fmt" start="17" end="18" type="CS_MASK_FMT"/>
|
||||
<field name="cs_prim_base_pres" start="16" end="16" type="bool"/>
|
||||
<field name="cs_prim_base_offset" start="0" end="15" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="PRIMITIVE_BASE" length="1">
|
||||
<field name="cs_prim_base" start="0" end="31" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="COMPRESSION_SIZE_WORD" length="1">
|
||||
<field name="cs_tsp_comp_format_size" start="22" end="27" type="uint"/>
|
||||
<field name="cs_tsp_comp_table_size" start="12" end="21" type="uint"/>
|
||||
<field name="cs_tsp_comp_vertex_size" start="0" end="11" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_COMPRESSION_WORD_0" length="1">
|
||||
<field name="cf_isp_comp_fmt_z1" start="28" end="31" type="COMPRESSION_FORMAT"/>
|
||||
<field name="cf_isp_comp_fmt_z0" start="24" end="27" type="COMPRESSION_FORMAT"/>
|
||||
<field name="cf_isp_comp_fmt_y2" start="20" end="23" type="COMPRESSION_FORMAT"/>
|
||||
<field name="cf_isp_comp_fmt_y1" start="16" end="19" type="COMPRESSION_FORMAT"/>
|
||||
<field name="cf_isp_comp_fmt_y0" start="12" end="15" type="COMPRESSION_FORMAT"/>
|
||||
<field name="cf_isp_comp_fmt_x2" start="8" end="11" type="COMPRESSION_FORMAT"/>
|
||||
<field name="cf_isp_comp_fmt_x1" start="4" end="7" type="COMPRESSION_FORMAT"/>
|
||||
<field name="cf_isp_comp_fmt_x0" start="0" end="3" type="COMPRESSION_FORMAT"/>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_COMPRESSION_WORD_1" length="1">
|
||||
<field name="vf_prim_msaa" start="16" end="16" type="bool"/>
|
||||
<field name="vf_prim_id_pres" start="15" end="15" type="bool"/>
|
||||
<field name="vf_vertex_clipped" start="14" end="14" type="bool"/>
|
||||
<field name="vf_vertex_total" start="8" end="13" type="uint"/>
|
||||
<field name="cf_isp_comp_fmt_z3" start="4" end="7" type="COMPRESSION_FORMAT"/>
|
||||
<field name="cf_isp_comp_fmt_z2" start="0" end="3" type="COMPRESSION_FORMAT"/>
|
||||
</struct>
|
||||
|
||||
<struct name="INDEX_DATA" length="1">
|
||||
<field name="ix_edge_flag1_ab" start="30" end="30" type="bool"/>
|
||||
<field name="ix_index1_0" start="24" end="29" type="uint"/>
|
||||
<field name="ix_bf_flag0" start="23" end="23" type="bool"/>
|
||||
<field name="ix_edge_flag0_ca" start="22" end="22" type="bool"/>
|
||||
<field name="ix_index0_2" start="16" end="21" type="uint"/>
|
||||
<field name="ix_edge_flag0_bc" start="14" end="14" type="bool"/>
|
||||
<field name="ix_index0_1" start="8" end="13" type="uint"/>
|
||||
<field name="ix_edge_flag0_ab" start="6" end="6" type="bool"/>
|
||||
<field name="ix_index0_0" start="0" end="5" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<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>
|
||||
|
||||
<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"/>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_VERTEX_WORD_1" length="1">
|
||||
<field name="z0" start="16" end="31" type="uint"/>
|
||||
<field name="y0" start="0" end="15" type="uint">
|
||||
<define name="SHIFT" value="8"/>
|
||||
</field>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_VERTEX_WORD_2" length="1">
|
||||
<field name="x1" start="16" end="31" type="uint"/>
|
||||
<field name="z0" start="0" end="15" type="uint">
|
||||
<define name="SHIFT" value="16"/>
|
||||
</field>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_VERTEX_WORD_3" length="1">
|
||||
<field name="y1" start="8" end="31" type="uint"/>
|
||||
<field name="x1" start="0" end="7" type="uint">
|
||||
<define name="SHIFT" value="16"/>
|
||||
</field>
|
||||
</struct>
|
||||
|
||||
<struct name="ISP_VERTEX_WORD_4" length="1">
|
||||
<field name="z1" start="0" end="31" type="uint"/>
|
||||
</struct>
|
||||
|
||||
</csbgen>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<!--
|
||||
Copyright © 2025 Imagination Technologies Ltd.
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
-->
|
||||
|
||||
<csbgen name="VOLCANIC" prefix="LLS">
|
||||
|
||||
<define name="CDM_CONTEXT_RESUME_BUFFER_SIZE" value="72"/>
|
||||
<define name="CDM_CONTEXT_RESUME_BUFFER_ALIGNMENT" value="32"/>
|
||||
|
||||
<define name="TA_STATE_BUFFER_SIZE" value="468"/>
|
||||
<define name="TA_STATE_BUFFER_ALIGNMENT" value="32"/>
|
||||
|
||||
<define name="USC_SHARED_REGS_BUFFER_SIZE" value="16384"/>
|
||||
<define name="USC_SHARED_REGS_BUFFER_ALIGNMENT" value="32"/>
|
||||
|
||||
</csbgen>
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright © 2025 Imagination Technologies Ltd.
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
pvr_xml_files = [
|
||||
'cdm.xml',
|
||||
'ipf.xml',
|
||||
'lls.xml',
|
||||
'pbestate.xml',
|
||||
'pds.xml',
|
||||
'texstate.xml',
|
||||
]
|
||||
|
||||
foreach f : pvr_xml_files
|
||||
_name = '@[email protected]'.format(f.split('.')[0])
|
||||
pvr_xml_pack += custom_target(
|
||||
_name,
|
||||
input : ['../gen_pack_header.py', f],
|
||||
output : _name,
|
||||
command : [prog_python, '@INPUT@'],
|
||||
capture : true,
|
||||
)
|
||||
endforeach
|
||||
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<!--
|
||||
Copyright © 2025 Imagination Technologies Ltd.
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
-->
|
||||
|
||||
<csbgen name="VOLCANIC" prefix="PBESTATE">
|
||||
|
||||
<enum name="PACKMODE">
|
||||
<value name="U8U8U8U8" value="0x0"/>
|
||||
<value name="S8S8S8S8" value="0x1"/>
|
||||
<value name="A1R5G5B5" value="0x2"/>
|
||||
<value name="R5G5B5A1" value="0x3"/>
|
||||
<value name="A4R4G4B4" value="0x4"/>
|
||||
<value name="A8R3G3B2" value="0x5"/>
|
||||
<value name="U16U16U16U16" value="0x6"/>
|
||||
<value name="S16S16S16S16" value="0x7"/>
|
||||
<value name="F16F16F16F16" value="0x8"/>
|
||||
<value name="U32U32U32U32" value="0x9"/>
|
||||
<value name="S32S32S32S32" value="0xa"/>
|
||||
<value name="F32F32F32F32" value="0xb"/>
|
||||
<value name="A2R10B10G10" value="0xc"/>
|
||||
<value name="R10B10G10A2" value="0xd"/>
|
||||
<value name="A2F10F10F10" value="0xe"/>
|
||||
<value name="F10F10F10A2" value="0xf"/>
|
||||
<value name="U8U8U8" value="0x10"/>
|
||||
<value name="S8S8S8" value="0x11"/>
|
||||
<value name="R5G6B5" value="0x12"/>
|
||||
<value name="R5SG5SB6" value="0x13"/>
|
||||
<value name="B6G5SR5S" value="0x14"/>
|
||||
<value name="U16U16U16" value="0x15"/>
|
||||
<value name="S16S16S16" value="0x16"/>
|
||||
<value name="F16F16F16" value="0x17"/>
|
||||
<value name="U32U32U32" value="0x18"/>
|
||||
<value name="S32S32S32" value="0x19"/>
|
||||
<value name="F11F11F10" value="0x1a"/>
|
||||
<value name="F10F11F11" value="0x1b"/>
|
||||
<value name="F32F32F32" value="0x1d"/>
|
||||
<value name="U8U8" value="0x1e"/>
|
||||
<value name="S8S8" value="0x1f"/>
|
||||
<value name="U16U16" value="0x20"/>
|
||||
<value name="S16S16" value="0x21"/>
|
||||
<value name="F16F16" value="0x22"/>
|
||||
<value name="U32U32" value="0x23"/>
|
||||
<value name="S32S32" value="0x24"/>
|
||||
<value name="F32F32" value="0x25"/>
|
||||
<value name="U24ST8" value="0x26"/>
|
||||
<value name="ST8U24" value="0x27"/>
|
||||
<value name="U8" value="0x28"/>
|
||||
<value name="S8" value="0x29"/>
|
||||
<value name="U16" value="0x2a"/>
|
||||
<value name="S16" value="0x2b"/>
|
||||
<value name="F16" value="0x2c"/>
|
||||
<value name="U32" value="0x2d"/>
|
||||
<value name="S32" value="0x2e"/>
|
||||
<value name="F32" value="0x2f"/>
|
||||
<value name="ARGBV16_XR10" value="0x30"/>
|
||||
<value name="A2_XRBIAS_U10U10U10" value="0x31"/>
|
||||
<value name="U10U10U10_XRBIAS_A2" value="0x32"/>
|
||||
</enum>
|
||||
|
||||
<enum name="SOURCE_FORMAT">
|
||||
<value name="F16_PER_CHANNEL" value="0"/>
|
||||
<value name="8_OR_RAW_PER_CHANNEL" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="SOURCE_POS">
|
||||
<value name="START_BIT0" value="0"/>
|
||||
<value name="START_BIT32" value="1"/>
|
||||
<value name="START_BIT64" value="2"/>
|
||||
<value name="START_BIT96" value="3"/>
|
||||
</enum>
|
||||
|
||||
<struct name="STATE_WORD0" length="1">
|
||||
<field name="address_low" start="0" end="31" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
</csbgen>
|
||||
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<!--
|
||||
Copyright © 2025 Imagination Technologies Ltd.
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
-->
|
||||
|
||||
<csbgen name="VOLCANIC" prefix="PDSINST">
|
||||
|
||||
<enum name="DOUTI_SHADEMODEL">
|
||||
<value name="FLAT_VERTEX0" value="0"/>
|
||||
<value name="FLAT_VERTEX1" value="1"/>
|
||||
<value name="FLAT_VERTEX2" value="2"/>
|
||||
<value name="GOURUAD" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="DOUTI_SIZE">
|
||||
<value name="1D" value="0"/>
|
||||
<value name="2D" value="1"/>
|
||||
<value name="3D" value="2"/>
|
||||
<value name="4D" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="DOUTU_SAMPLE_RATE">
|
||||
<value name="INSTANCE" value="0"/>
|
||||
<value name="SELECTIVE" value="1"/>
|
||||
<value name="FULL" value="2"/>
|
||||
</enum>
|
||||
|
||||
<struct name="DOUT_FIELDS_DOUTD_SRC0" length="1">
|
||||
<field name="doffset" start="48" end="60" type="uint"/>
|
||||
<field name="sbase" start="0" end="47" shift="0" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="DOUT_FIELDS_DOUTD_SRC1" length="1">
|
||||
<field name="last" start="31" end="31" type="bool"/>
|
||||
<field name="dest" start="28" end="30" type="uint"/>
|
||||
<field name="bsize" start="0" end="11" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="DOUT_FIELDS_DOUTI_SRC" length="1">
|
||||
<field name="depthbias" start="27" end="27" type="bool"/>
|
||||
<field name="primitiveid" start="26" end="26" type="bool"/>
|
||||
<field name="shademodel" start="24" end="25" type="DOUTI_SHADEMODEL"/>
|
||||
<field name="pointsprite" start="23" end="23" type="bool"/>
|
||||
<field name="wraps" start="22" end="22" type="bool"/>
|
||||
<field name="wrapv" start="21" end="21" type="bool"/>
|
||||
<field name="wrapu" start="20" end="20" type="bool"/>
|
||||
<field name="size" start="18" end="19" type="DOUTI_SIZE"/>
|
||||
<field name="f16" start="17" end="17" type="bool"/>
|
||||
<field name="perspective" start="16" end="16" type="bool"/>
|
||||
<field name="f32_offset" start="8" end="15" type="uint"/>
|
||||
<field name="f16_offset" start="0" end="7" type="uint"/>
|
||||
</struct>
|
||||
|
||||
</csbgen>
|
||||
@@ -0,0 +1,260 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<!--
|
||||
Copyright © 2025 Imagination Technologies Ltd.
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
-->
|
||||
|
||||
<csbgen name="VOLCANIC" prefix="TEXSTATE">
|
||||
|
||||
<enum name="ADDRMODE">
|
||||
<value name="REPEAT" value="0"/>
|
||||
<value name="FLIP" value="1"/>
|
||||
<value name="CLAMP_TO_EDGE" value="2"/>
|
||||
<value name="FLIP_ONCE_THEN_CLAMP" value="3"/>
|
||||
<value name="CLAMP_TO_BORDER" value="4"/>
|
||||
<value name="OGL_CLAMP" value="5"/>
|
||||
</enum>
|
||||
|
||||
<enum name="ANISOCTL">
|
||||
<value name="DISABLED" value="0"/>
|
||||
<value name="X2" value="1"/>
|
||||
<value name="X4" value="2"/>
|
||||
<value name="X8" value="3"/>
|
||||
<value name="X16" value="4"/>
|
||||
</enum>
|
||||
|
||||
<enum name="CLAMP">
|
||||
<value name="INTEGER_BITS" value="4"/>
|
||||
<value name="FRACTIONAL_BITS" value="8"/>
|
||||
</enum>
|
||||
|
||||
<enum name="CMP_MODE">
|
||||
<value name="NEVER" value="0"/>
|
||||
<value name="LESS" value="1"/>
|
||||
<value name="EQUAL" value="2"/>
|
||||
<value name="LESSEQUAL" value="3"/>
|
||||
<value name="GREATER" value="4"/>
|
||||
<value name="NOTEQUAL" value="5"/>
|
||||
<value name="GREATEREQUAL" value="6"/>
|
||||
<value name="ALWAYS" value="7"/>
|
||||
</enum>
|
||||
|
||||
<enum name="DADJUST">
|
||||
<value name="MIN_UINT" value="0"/>
|
||||
<value name="ZERO_UINT" value="4095"/>
|
||||
<value name="MAX_UINT" value="8191"/>
|
||||
<value name="INTEGER_BITS" value="5"/>
|
||||
<value name="FRACTIONAL_BITS" value="8"/>
|
||||
</enum>
|
||||
|
||||
<enum name="FILTER">
|
||||
<value name="POINT" value="0"/>
|
||||
<value name="LINEAR" value="1"/>
|
||||
<value name="BICUBIC" value="2"/>
|
||||
</enum>
|
||||
|
||||
<enum name="FORMAT">
|
||||
<value name="U8" value="0"/>
|
||||
<value name="S8" value="1"/>
|
||||
<value name="A4R4G4B4" value="2"/>
|
||||
<value name="A8R3G3B2" value="3"/>
|
||||
<value name="A1R5G5B5" value="4"/>
|
||||
<value name="R5G6B5" value="5"/>
|
||||
<value name="R5sG5sB6" value="6"/>
|
||||
<value name="U8U8" value="7"/>
|
||||
<value name="S8S8" value="8"/>
|
||||
<value name="U16" value="9"/>
|
||||
<value name="S16" value="10"/>
|
||||
<value name="F16" value="11"/>
|
||||
<value name="U8U8U8U8" value="12"/>
|
||||
<value name="S8S8S8S8" value="13"/>
|
||||
<value name="A2R10B10G10" value="14"/>
|
||||
<value name="U16U16" value="15"/>
|
||||
<value name="S16S16" value="16"/>
|
||||
<value name="F16F16" value="17"/>
|
||||
<value name="F32" value="18"/>
|
||||
<!-- 19 -->
|
||||
<value name="X8U8S8S8" value="20"/>
|
||||
<value name="X8U24" value="21"/>
|
||||
<value name="ST8U24" value="22"/>
|
||||
<value name="U8X24" value="23"/>
|
||||
<value name="U32" value="24"/>
|
||||
<value name="S32" value="25"/>
|
||||
<value name="SE9995" value="26"/>
|
||||
<value name="F11F11F10" value="27"/>
|
||||
<value name="F16F16F16F16" value="28"/>
|
||||
<value name="U16U16U16U16" value="29"/>
|
||||
<value name="S16S16S16S16" value="30"/>
|
||||
<value name="F16F16F16" value="31"/>
|
||||
<value name="U16U16U16" value="32"/>
|
||||
<value name="S16S16S16" value="33"/>
|
||||
<value name="F32F32" value="34"/>
|
||||
<value name="U32U32" value="35"/>
|
||||
<value name="S32S32" value="36"/>
|
||||
<value name="X24U8F32" value="37"/>
|
||||
<value name="X24X8F32" value="38"/>
|
||||
<value name="X24G8X32" value="39"/>
|
||||
<value name="YUV420_2PLANE" value="40"/>
|
||||
<value name="YVU420_2PLANE" value="41"/>
|
||||
<value name="YUV420_3PLANE" value="42"/>
|
||||
<value name="YVU420_3PLANE" value="43"/>
|
||||
<value name="U8U8U8" value="44"/>
|
||||
<value name="S8S8S8" value="45"/>
|
||||
<value name="A2F10F10F10" value="46"/>
|
||||
<value name="F32F32F32F32" value="47"/>
|
||||
<value name="U32U32U32U32" value="48"/>
|
||||
<value name="S32S32S32S32" value="49"/>
|
||||
<value name="F32F32F32" value="50"/>
|
||||
<value name="U32U32U32" value="51"/>
|
||||
<value name="S32S32S32" value="52"/>
|
||||
<value name="R5G5B5A1" value="53"/>
|
||||
<value name="B6G5sR5s" value="54"/>
|
||||
<value name="R10B10G10A2" value="55"/>
|
||||
<value name="X8S8S8U8" value="56"/>
|
||||
<value name="U24ST8" value="57"/>
|
||||
<value name="F10F11F11" value="58"/>
|
||||
<value name="VYUY" value="59"/>
|
||||
<value name="UYVY" value="60"/>
|
||||
<value name="YVYU" value="61"/>
|
||||
<value name="YUYV" value="62"/>
|
||||
<value name="F10F10F10A2" value="63"/>
|
||||
<value name="YUV420_2PLANE_MACRO_BLOCK" value="64"/>
|
||||
<value name="YVU420_2PLANE_MACRO_BLOCK" value="65"/>
|
||||
<value name="YVU8_422_2PLANE_PACK8" value="66"/>
|
||||
<value name="YVU8_444_2PLANE_PACK8" value="67"/>
|
||||
<value name="YVU10_444_1PLANE_PACK10" value="68"/>
|
||||
<value name="YVU10_422_2PLANE_PACK16" value="69"/>
|
||||
<value name="YVU10_420_2PLANE_PACK16" value="70"/>
|
||||
<value name="YVU10_444_2PLANE_PACK16" value="71"/>
|
||||
<value name="YUV8_422_2PLANE_PACK8" value="72"/>
|
||||
<value name="YUV8_444_3PLANE_PACK8" value="73"/>
|
||||
<value name="YUV10_444_3PLANE_PACK16" value="74"/>
|
||||
<value name="YVU10_420_2PLANE_PACK10" value="75"/>
|
||||
<value name="YUV10_420_2PLANE_PACK10" value="76"/>
|
||||
<value name="YVU10_422_2PLANE_PACK10" value="77"/>
|
||||
<value name="YUV10_422_2PLANE_PACK10" value="78"/>
|
||||
<value name="YUV10_444_3PLANE_PACK10" value="79"/>
|
||||
<value name="R8G8_B8G8" value="80"/>
|
||||
<value name="G8R8_G8B8" value="81"/>
|
||||
<value name="YVYU_IMPLIED_CSC" value="82"/>
|
||||
<value name="VYUY_IMPLIED_CSC" value="83"/>
|
||||
<!-- 84..85 -->
|
||||
<value name="YUV10_420_2PLANE_PACK10_T" value="86"/>
|
||||
<value name="YVU10_420_2PLANE_PACK10_T" value="87"/>
|
||||
<value name="YUV8_420_2PLANE_PACK8_P" value="88"/>
|
||||
<value name="YVU8_420_2PLANE_PACK8_P" value="89"/>
|
||||
<value name="YUV8_420_2PLANE_PACK8_F" value="90"/>
|
||||
<value name="YVU8_420_2PLANE_PACK8_F" value="91"/>
|
||||
<!-- 92..93 -->
|
||||
<value name="ASTC_4x4" value="94"/>
|
||||
<value name="ASTC_5x4" value="95"/>
|
||||
<value name="ASTC_5x5" value="96"/>
|
||||
<value name="ASTC_6x5" value="97"/>
|
||||
<value name="ASTC_6x6" value="98"/>
|
||||
<value name="ASTC_8x5" value="99"/>
|
||||
<value name="ASTC_8x6" value="100"/>
|
||||
<value name="ASTC_8x8" value="101"/>
|
||||
<value name="ASTC_10x5" value="102"/>
|
||||
<value name="ASTC_10x6" value="103"/>
|
||||
<value name="ASTC_10x8" value="104"/>
|
||||
<value name="ASTC_10x10" value="105"/>
|
||||
<value name="ASTC_12x10" value="106"/>
|
||||
<value name="ASTC_12x12" value="107"/>
|
||||
<value name="UBC1" value="108"/>
|
||||
<value name="UBC2" value="109"/>
|
||||
<value name="UBC3" value="110"/>
|
||||
<value name="UBC4" value="111"/>
|
||||
<value name="SBC4" value="112"/>
|
||||
<value name="UBC5" value="113"/>
|
||||
<value name="SBC5" value="114"/>
|
||||
<value name="UBC6" value="115"/>
|
||||
<value name="SBC6" value="116"/>
|
||||
<value name="UBC7" value="117"/>
|
||||
<value name="ETC2_RGB" value="118"/>
|
||||
<value name="ETC2A_RGBA" value="119"/>
|
||||
<value name="ETC2_PUNCHTHROUGHA" value="120"/>
|
||||
<value name="EAC_R11_UNSIGNED" value="121"/>
|
||||
<value name="EAC_R11_SIGNED" value="122"/>
|
||||
<value name="EAC_RG11_UNSIGNED" value="123"/>
|
||||
<value name="EAC_RG11_SIGNED" value="124"/>
|
||||
<!-- 125..138 -->
|
||||
</enum>
|
||||
|
||||
<enum name="SWIZ">
|
||||
<value name="SRCCHAN_0" value="0"/>
|
||||
<value name="SRCCHAN_1" value="1"/>
|
||||
<value name="SRCCHAN_2" value="2"/>
|
||||
<value name="SRCCHAN_3" value="3"/>
|
||||
<value name="SRC_ONE" value="4"/>
|
||||
<value name="SRC_ZERO" value="5"/>
|
||||
</enum>
|
||||
|
||||
<enum name="TEXTYPE">
|
||||
<value name="1D" value="0"/>
|
||||
<value name="2D" value="1"/>
|
||||
<value name="3D" value="2"/>
|
||||
<value name="CUBE" value="3"/>
|
||||
<value name="STRIDE" value="4"/>
|
||||
<value name="BUFFER_LOOKUP" value="5"/>
|
||||
</enum>
|
||||
|
||||
<enum name="TWOCOMP_GAMMA">
|
||||
<value name="OFF" value="0"/>
|
||||
<value name="R" value="1"/>
|
||||
<value name="RG" value="3"/>
|
||||
</enum>
|
||||
|
||||
<struct name="IMAGE_WORD0" length="2">
|
||||
<field name="height" start="49" end="62" type="uint"/>
|
||||
<field name="width" start="35" end="48" type="uint"/>
|
||||
<field name="texformat" start="15" end="22" type="FORMAT"/>
|
||||
<field name="minlod" start="23" end="34" type="uint"/>
|
||||
<field name="swiz0" start="12" end="14" type="SWIZ"/>
|
||||
<field name="swiz1" start="9" end="11" type="SWIZ"/>
|
||||
<field name="swiz2" start="6" end="8" type="SWIZ"/>
|
||||
<field name="swiz3" start="3" end="5" type="SWIZ"/>
|
||||
<field name="textype" start="0" end="2" type="TEXTYPE"/>
|
||||
</struct>
|
||||
|
||||
<struct name="IMAGE_WORD1" length="2">
|
||||
<field name="alpha_msb" start="62" end="62" type="bool"/>
|
||||
<field name="mipmaps_present" start="61" end="61" type="bool"/>
|
||||
<field name="depth" start="48" end="58" type="uint"/>
|
||||
<field name="border" start="46" end="46" type="bool"/>
|
||||
<field name="texaddr" start="0" end="45" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="IMAGE_WORD2" length="2">
|
||||
<field name="num_mip_levels" start="10" end="13" type="uint"/>
|
||||
<field name="twocomp_gamma" start="4" end="5" type="TWOCOMP_GAMMA"/>
|
||||
<field name="baselevel" start="0" end="3" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="STRIDE_IMAGE_WORD1" length="2">
|
||||
<field name="alpha_msb" start="62" end="62" type="bool"/>
|
||||
<field name="mipmaps_present" start="61" end="61" type="bool"/>
|
||||
<field name="stride" start="46" end="60" type="uint"/>
|
||||
<field name="texaddr" start="0" end="45" shift="2" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="SAMPLER_WORD0" length="2">
|
||||
<field name="cemedge_dontfilter" start="63" end="63" type="bool"/>
|
||||
<field name="cmp_mode" start="57" end="59" type="CMP_MODE"/>
|
||||
<field name="non_normalized_coords" start="56" end="56" type="bool"/>
|
||||
<field name="lumakey_alphamult" start="55" end="55" type="bool"/>
|
||||
<field name="lumakey" start="54" end="54" type="bool"/>
|
||||
<field name="addrmode_w" start="51" end="53" type="ADDRMODE"/>
|
||||
<field name="addrmode_v" start="48" end="50" type="ADDRMODE"/>
|
||||
<field name="addrmode_u" start="45" end="47" type="ADDRMODE"/>
|
||||
<field name="mipfilter" start="44" end="44" type="bool"/>
|
||||
<field name="minfilter" start="42" end="43" type="FILTER"/>
|
||||
<field name="magfilter" start="40" end="41" type="FILTER"/>
|
||||
<field name="anisoctl" start="37" end="39" type="ANISOCTL"/>
|
||||
<field name="maxlod" start="25" end="36" type="CLAMP"/>
|
||||
<field name="minlod" start="13" end="24" type="CLAMP"/>
|
||||
<field name="dadjust" start="0" end="12" type="DADJUST"/>
|
||||
</struct>
|
||||
|
||||
</csbgen>
|
||||
@@ -0,0 +1,13 @@
|
||||
# Copyright © 2026 Imagination Technologies Ltd.
|
||||
# Copyright 2019 Broadcom
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
libpowervr_noop_drm_shim = shared_library(
|
||||
'powervr_noop_drm_shim',
|
||||
'pvr_noop.c',
|
||||
link_with : [libpowervr_common],
|
||||
include_directories: [inc_imagination, inc_include, inc_src],
|
||||
dependencies: [dep_drm_shim, dep_valgrind, dep_csbgen],
|
||||
gnu_symbol_visibility : 'hidden',
|
||||
install : true,
|
||||
)
|
||||
@@ -0,0 +1,567 @@
|
||||
/*
|
||||
* Copyright © 2026 Imagination Technologies Ltd.
|
||||
* Copyright 2018 Broadcom
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "common/pvr_device_info.h"
|
||||
#include "drm-shim/drm_shim.h"
|
||||
#include "drm-uapi/pvr_drm.h"
|
||||
#include "hwdef/rogue_hw_utils.h"
|
||||
#include "util/macros.h"
|
||||
#include "util/u_debug.h"
|
||||
|
||||
bool drm_shim_driver_prefers_first_render_node = true;
|
||||
|
||||
|
||||
#define DEFAULT_DEVICE_BVNC PVR_BVNC_PACK(36, 53, 104, 796)
|
||||
static struct pvr_device_info device_info;
|
||||
|
||||
static bool musthave_quirks = false;
|
||||
static unsigned num_quirks = 0;
|
||||
static uint32_t *quirks = NULL;
|
||||
|
||||
static unsigned num_enhancements = 0;
|
||||
static uint32_t *enhancements = NULL;
|
||||
|
||||
static int
|
||||
pvr_ioctl_noop(UNUSED int fd, UNUSED unsigned long request, UNUSED void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_num_phantoms(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
return DIV_ROUND_UP(PVR_GET_FEATURE_VALUE(&device_info, num_clusters, 1U),
|
||||
4U);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_common_store_partition_space_size(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
const uint32_t max_partitions =
|
||||
PVR_GET_FEATURE_VALUE(dev_info, max_partitions, 0U);
|
||||
const uint32_t tile_size_x =
|
||||
PVR_GET_FEATURE_VALUE(dev_info, tile_size_x, 0U);
|
||||
const uint32_t tile_size_y =
|
||||
PVR_GET_FEATURE_VALUE(dev_info, tile_size_y, 0U);
|
||||
|
||||
if (tile_size_x == 16U && tile_size_y == 16U) {
|
||||
uint32_t usc_min_output_registers_per_pix =
|
||||
PVR_GET_FEATURE_VALUE(dev_info, usc_min_output_registers_per_pix, 0U);
|
||||
|
||||
return tile_size_x * tile_size_y * max_partitions *
|
||||
usc_min_output_registers_per_pix;
|
||||
}
|
||||
|
||||
return max_partitions * 1024U;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_common_store_alloc_region_size(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
uint32_t alloc_region_size;
|
||||
|
||||
const uint32_t common_store_size_in_dwords =
|
||||
PVR_GET_FEATURE_VALUE(dev_info,
|
||||
common_store_size_in_dwords,
|
||||
512U * 4U * 4U);
|
||||
|
||||
alloc_region_size = common_store_size_in_dwords - (256U * 4U) -
|
||||
rogue_common_store_partition_space_size(dev_info);
|
||||
|
||||
if (PVR_HAS_QUIRK(dev_info, 44079)) {
|
||||
uint32_t common_store_split_point = (768U * 4U * 4U);
|
||||
|
||||
return MIN2(common_store_split_point - (256U * 4U), alloc_region_size);
|
||||
}
|
||||
|
||||
return alloc_region_size;
|
||||
}
|
||||
|
||||
static inline uint32_t rogue_max_coeffs(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
uint32_t max_coeff_additional_portion = ROGUE_MAX_VERTEX_SHARED_REGISTERS;
|
||||
uint32_t pending_allocation_shared_regs = 2U * 1024U;
|
||||
uint32_t pending_allocation_coeff_regs = 0U;
|
||||
uint32_t num_phantoms = rogue_num_phantoms(dev_info);
|
||||
uint32_t tiles_in_flight =
|
||||
PVR_GET_FEATURE_VALUE(dev_info, isp_max_tiles_in_flight, 0U);
|
||||
uint32_t max_coeff_pixel_portion =
|
||||
DIV_ROUND_UP(tiles_in_flight, num_phantoms);
|
||||
max_coeff_pixel_portion *= ROGUE_MAX_PIXEL_SHARED_REGISTERS;
|
||||
|
||||
/*
|
||||
* Compute tasks on cores with BRN48492 and without compute overlap may lock
|
||||
* up without two additional lines of coeffs.
|
||||
*/
|
||||
if (PVR_HAS_QUIRK(dev_info, 48492) &&
|
||||
!PVR_HAS_FEATURE(dev_info, compute_overlap))
|
||||
pending_allocation_coeff_regs = 2U * 1024U;
|
||||
|
||||
if (PVR_HAS_ENHANCEMENT(dev_info, 38748))
|
||||
pending_allocation_shared_regs = 0;
|
||||
|
||||
if (PVR_HAS_ENHANCEMENT(dev_info, 38020))
|
||||
max_coeff_additional_portion += ROGUE_MAX_COMPUTE_SHARED_REGISTERS;
|
||||
|
||||
return rogue_common_store_alloc_region_size(dev_info) +
|
||||
pending_allocation_coeff_regs -
|
||||
(max_coeff_pixel_portion + max_coeff_additional_portion +
|
||||
pending_allocation_shared_regs);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_cdm_max_local_mem_size_regs(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
uint32_t available_coeffs_in_dwords = rogue_max_coeffs(dev_info);
|
||||
|
||||
if (PVR_HAS_QUIRK(dev_info, 48492) && PVR_HAS_FEATURE(dev_info, roguexe) &&
|
||||
!PVR_HAS_FEATURE(dev_info, compute_overlap)) {
|
||||
/* Driver must not use the 2 reserved lines. */
|
||||
available_coeffs_in_dwords -= ROGUE_CSRM_LINE_SIZE_IN_DWORDS * 2U;
|
||||
}
|
||||
|
||||
/*
|
||||
* The maximum amount of local memory available to a kernel is the minimum
|
||||
* of the total number of coefficient registers available and the max common
|
||||
* store allocation size which can be made by the CDM.
|
||||
*
|
||||
* If any coeff lines are reserved for tessellation or pixel then we need to
|
||||
* subtract those too.
|
||||
*/
|
||||
return MIN2(available_coeffs_in_dwords,
|
||||
ROGUE_MAX_PER_KERNEL_LOCAL_MEM_SIZE_REGS);
|
||||
}
|
||||
|
||||
static int pvr_dev_query_gpu_info_get(struct drm_pvr_ioctl_dev_query_args *args)
|
||||
{
|
||||
struct drm_pvr_dev_query_gpu_info *gpu_info =
|
||||
(struct drm_pvr_dev_query_gpu_info *)args->pointer;
|
||||
|
||||
if (!gpu_info)
|
||||
goto dev_query_gpu_info_set_size;
|
||||
|
||||
gpu_info->gpu_id = pvr_get_packed_bvnc(&device_info);
|
||||
gpu_info->num_phantoms = rogue_num_phantoms(&device_info);
|
||||
|
||||
dev_query_gpu_info_set_size:
|
||||
args->size = sizeof(*gpu_info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pvr_dev_query_runtime_info_get(struct drm_pvr_ioctl_dev_query_args *args)
|
||||
{
|
||||
struct drm_pvr_dev_query_runtime_info *runtime_info =
|
||||
(struct drm_pvr_dev_query_runtime_info *)args->pointer;
|
||||
|
||||
if (!runtime_info)
|
||||
goto dev_query_runtime_info_set_size;
|
||||
|
||||
if (PVR_HAS_FEATURE(&device_info, roguexe)) {
|
||||
if (PVR_HAS_QUIRK(&device_info, 66011))
|
||||
runtime_info->free_list_min_pages = 40;
|
||||
else
|
||||
runtime_info->free_list_min_pages = 25;
|
||||
} else {
|
||||
runtime_info->free_list_min_pages = 50;
|
||||
}
|
||||
|
||||
runtime_info->free_list_max_pages = 0x80000;
|
||||
|
||||
runtime_info->common_store_alloc_region_size =
|
||||
rogue_common_store_alloc_region_size(&device_info);
|
||||
|
||||
runtime_info->common_store_partition_space_size =
|
||||
rogue_common_store_partition_space_size(&device_info);
|
||||
|
||||
runtime_info->max_coeffs = rogue_max_coeffs(&device_info);
|
||||
|
||||
runtime_info->cdm_max_local_mem_size_regs =
|
||||
rogue_cdm_max_local_mem_size_regs(&device_info);
|
||||
|
||||
dev_query_runtime_info_set_size:
|
||||
args->size = sizeof(*runtime_info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pvr_dev_query_quirks_get(struct drm_pvr_ioctl_dev_query_args *args)
|
||||
{
|
||||
struct drm_pvr_dev_query_quirks *query_quirks =
|
||||
(struct drm_pvr_dev_query_quirks *)args->pointer;
|
||||
|
||||
if (!query_quirks)
|
||||
goto dev_query_quirks_set_size;
|
||||
|
||||
if (!query_quirks->quirks) {
|
||||
query_quirks->count = num_quirks;
|
||||
query_quirks->musthave_count = musthave_quirks ? num_quirks : 0;
|
||||
goto dev_query_quirks_set_size;
|
||||
}
|
||||
|
||||
if (query_quirks->count > num_quirks)
|
||||
query_quirks->count = num_quirks;
|
||||
|
||||
memcpy((void *)query_quirks->quirks,
|
||||
quirks,
|
||||
sizeof(*quirks) * query_quirks->count);
|
||||
|
||||
dev_query_quirks_set_size:
|
||||
args->size = sizeof(*query_quirks);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pvr_dev_query_enhancements_get(struct drm_pvr_ioctl_dev_query_args *args)
|
||||
{
|
||||
struct drm_pvr_dev_query_enhancements *query_enhancements =
|
||||
(struct drm_pvr_dev_query_enhancements *)args->pointer;
|
||||
|
||||
if (!query_enhancements)
|
||||
goto dev_query_enhancements_set_size;
|
||||
|
||||
if (!query_enhancements->enhancements) {
|
||||
query_enhancements->count = num_enhancements;
|
||||
goto dev_query_enhancements_set_size;
|
||||
}
|
||||
|
||||
if (query_enhancements->count > num_enhancements)
|
||||
query_enhancements->count = num_enhancements;
|
||||
|
||||
memcpy((void *)query_enhancements->enhancements,
|
||||
enhancements,
|
||||
sizeof(*enhancements) * query_enhancements->count);
|
||||
|
||||
dev_query_enhancements_set_size:
|
||||
args->size = sizeof(*query_enhancements);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_pvr_heap pvr_heaps[DRM_PVR_HEAP_COUNT] = {
|
||||
[DRM_PVR_HEAP_GENERAL] = {
|
||||
.base = UINT64_C(0x8000000000),
|
||||
.size = UINT64_C(0x2000000000),
|
||||
.flags = 0,
|
||||
.page_size_log2 = 12,
|
||||
},
|
||||
[DRM_PVR_HEAP_PDS_CODE_DATA] = {
|
||||
.base = UINT64_C(0xda00000000),
|
||||
.size = UINT64_C(0x100000000),
|
||||
.flags = 0,
|
||||
.page_size_log2 = 12,
|
||||
},
|
||||
[DRM_PVR_HEAP_USC_CODE] = {
|
||||
.base = UINT64_C(0xe000000000),
|
||||
.size = UINT64_C(0x100000000),
|
||||
.flags = 0,
|
||||
.page_size_log2 = 12,
|
||||
},
|
||||
[DRM_PVR_HEAP_RGNHDR] = {
|
||||
.base = UINT64_C(0xdbf0000000),
|
||||
.size = 0x10000000,
|
||||
.flags = 0,
|
||||
.page_size_log2 = 12,
|
||||
},
|
||||
[DRM_PVR_HEAP_VIS_TEST] = {
|
||||
.base = UINT64_C(0xf200000000),
|
||||
.size = 0x00200000,
|
||||
.flags = 0,
|
||||
.page_size_log2 = 12,
|
||||
},
|
||||
[DRM_PVR_HEAP_TRANSFER_FRAG] = {
|
||||
.base = UINT64_C(0xe400000000),
|
||||
.size = UINT64_C(0x400000000),
|
||||
.flags = 0,
|
||||
.page_size_log2 = 12,
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
pvr_dev_query_heap_info_get(struct drm_pvr_ioctl_dev_query_args *args)
|
||||
{
|
||||
struct drm_pvr_dev_query_heap_info *heap_info =
|
||||
(struct drm_pvr_dev_query_heap_info *)args->pointer;
|
||||
|
||||
if (!heap_info)
|
||||
goto dev_query_heap_info_set_size;
|
||||
|
||||
if (!heap_info->heaps.array) {
|
||||
heap_info->heaps.count = ARRAY_SIZE(pvr_heaps);
|
||||
heap_info->heaps.stride = sizeof(struct drm_pvr_heap);
|
||||
goto dev_query_heap_info_set_size;
|
||||
}
|
||||
|
||||
if (heap_info->heaps.count > ARRAY_SIZE(pvr_heaps))
|
||||
heap_info->heaps.count = ARRAY_SIZE(pvr_heaps);
|
||||
|
||||
memcpy((void *)heap_info->heaps.array,
|
||||
pvr_heaps,
|
||||
heap_info->heaps.stride * heap_info->heaps.count);
|
||||
|
||||
dev_query_heap_info_set_size:
|
||||
args->size = sizeof(*heap_info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_pvr_static_data_area pvr_static_data_areas[] = {
|
||||
{
|
||||
.area_usage = DRM_PVR_STATIC_DATA_AREA_FENCE,
|
||||
.location_heap_id = DRM_PVR_HEAP_GENERAL,
|
||||
.offset = 0,
|
||||
.size = 128,
|
||||
},
|
||||
{
|
||||
.area_usage = DRM_PVR_STATIC_DATA_AREA_YUV_CSC,
|
||||
.location_heap_id = DRM_PVR_HEAP_GENERAL,
|
||||
.offset = 128,
|
||||
.size = 1024,
|
||||
},
|
||||
{
|
||||
.area_usage = DRM_PVR_STATIC_DATA_AREA_VDM_SYNC,
|
||||
.location_heap_id = DRM_PVR_HEAP_PDS_CODE_DATA,
|
||||
.offset = 0,
|
||||
.size = 128,
|
||||
},
|
||||
{
|
||||
.area_usage = DRM_PVR_STATIC_DATA_AREA_EOT,
|
||||
.location_heap_id = DRM_PVR_HEAP_PDS_CODE_DATA,
|
||||
.offset = 128,
|
||||
.size = 128,
|
||||
},
|
||||
{
|
||||
.area_usage = DRM_PVR_STATIC_DATA_AREA_VDM_SYNC,
|
||||
.location_heap_id = DRM_PVR_HEAP_USC_CODE,
|
||||
.offset = 0,
|
||||
.size = 128,
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
pvr_dev_query_static_data_areas_get(struct drm_pvr_ioctl_dev_query_args *args)
|
||||
{
|
||||
struct drm_pvr_dev_query_static_data_areas *static_data_areas =
|
||||
(struct drm_pvr_dev_query_static_data_areas *)args->pointer;
|
||||
|
||||
if (!static_data_areas)
|
||||
goto dev_query_static_data_areas_set_size;
|
||||
|
||||
if (!static_data_areas->static_data_areas.array) {
|
||||
static_data_areas->static_data_areas.count =
|
||||
ARRAY_SIZE(pvr_static_data_areas);
|
||||
static_data_areas->static_data_areas.stride =
|
||||
sizeof(struct drm_pvr_static_data_area);
|
||||
goto dev_query_static_data_areas_set_size;
|
||||
}
|
||||
|
||||
if (static_data_areas->static_data_areas.count >
|
||||
ARRAY_SIZE(pvr_static_data_areas)) {
|
||||
static_data_areas->static_data_areas.count =
|
||||
ARRAY_SIZE(pvr_static_data_areas);
|
||||
}
|
||||
|
||||
memcpy((void *)static_data_areas->static_data_areas.array,
|
||||
pvr_static_data_areas,
|
||||
static_data_areas->static_data_areas.stride *
|
||||
static_data_areas->static_data_areas.count);
|
||||
|
||||
dev_query_static_data_areas_set_size:
|
||||
args->size = sizeof(*static_data_areas);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pvr_ioctl_dev_query(UNUSED int fd, UNUSED unsigned long request, void *arg)
|
||||
{
|
||||
struct drm_pvr_ioctl_dev_query_args *args = arg;
|
||||
|
||||
switch ((enum drm_pvr_dev_query)args->type) {
|
||||
case DRM_PVR_DEV_QUERY_GPU_INFO_GET:
|
||||
return pvr_dev_query_gpu_info_get(args);
|
||||
|
||||
case DRM_PVR_DEV_QUERY_RUNTIME_INFO_GET:
|
||||
return pvr_dev_query_runtime_info_get(args);
|
||||
|
||||
case DRM_PVR_DEV_QUERY_QUIRKS_GET:
|
||||
return pvr_dev_query_quirks_get(args);
|
||||
|
||||
case DRM_PVR_DEV_QUERY_ENHANCEMENTS_GET:
|
||||
return pvr_dev_query_enhancements_get(args);
|
||||
|
||||
case DRM_PVR_DEV_QUERY_HEAP_INFO_GET:
|
||||
return pvr_dev_query_heap_info_get(args);
|
||||
|
||||
case DRM_PVR_DEV_QUERY_STATIC_DATA_AREAS_GET:
|
||||
return pvr_dev_query_static_data_areas_get(args);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int pvr_ioctl_create_bo(int fd, UNUSED unsigned long request, void *arg)
|
||||
{
|
||||
struct drm_pvr_ioctl_create_bo_args *args = arg;
|
||||
|
||||
struct shim_fd *shim_fd = drm_shim_fd_lookup(fd);
|
||||
struct shim_bo *bo = calloc(1, sizeof(*bo));
|
||||
|
||||
drm_shim_bo_init(bo, args->size);
|
||||
|
||||
args->handle = drm_shim_bo_get_handle(shim_fd, bo);
|
||||
|
||||
drm_shim_bo_put(bo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pvr_ioctl_get_bo_mmap_offset(int fd, UNUSED unsigned long request, void *arg)
|
||||
{
|
||||
struct drm_pvr_ioctl_get_bo_mmap_offset_args *args = arg;
|
||||
|
||||
struct shim_fd *shim_fd = drm_shim_fd_lookup(fd);
|
||||
struct shim_bo *bo = drm_shim_bo_lookup(shim_fd, args->handle);
|
||||
|
||||
args->offset = drm_shim_bo_get_mmap_offset(shim_fd, bo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PVR_IOC_NR(_name) (_IOC_NR(DRM_IOCTL_PVR_##_name) - DRM_COMMAND_BASE)
|
||||
|
||||
static ioctl_fn_t driver_ioctls[] = {
|
||||
[PVR_IOC_NR(DEV_QUERY)] = pvr_ioctl_dev_query,
|
||||
[PVR_IOC_NR(CREATE_BO)] = pvr_ioctl_create_bo,
|
||||
[PVR_IOC_NR(GET_BO_MMAP_OFFSET)] = pvr_ioctl_get_bo_mmap_offset,
|
||||
[PVR_IOC_NR(CREATE_VM_CONTEXT)] = pvr_ioctl_noop,
|
||||
[PVR_IOC_NR(DESTROY_VM_CONTEXT)] = pvr_ioctl_noop,
|
||||
[PVR_IOC_NR(VM_MAP)] = pvr_ioctl_noop,
|
||||
[PVR_IOC_NR(VM_UNMAP)] = pvr_ioctl_noop,
|
||||
[PVR_IOC_NR(CREATE_CONTEXT)] = pvr_ioctl_noop,
|
||||
[PVR_IOC_NR(DESTROY_CONTEXT)] = pvr_ioctl_noop,
|
||||
[PVR_IOC_NR(CREATE_FREE_LIST)] = pvr_ioctl_noop,
|
||||
[PVR_IOC_NR(DESTROY_FREE_LIST)] = pvr_ioctl_noop,
|
||||
[PVR_IOC_NR(CREATE_HWRT_DATASET)] = pvr_ioctl_noop,
|
||||
[PVR_IOC_NR(DESTROY_HWRT_DATASET)] = pvr_ioctl_noop,
|
||||
[PVR_IOC_NR(SUBMIT_JOBS)] = pvr_ioctl_noop,
|
||||
};
|
||||
|
||||
static unsigned count_elems(const char *str, const char *delims)
|
||||
{
|
||||
if (!str || !strlen(str))
|
||||
return 0;
|
||||
|
||||
unsigned count = 1;
|
||||
for (unsigned u = 0; u < strlen(str); ++u) {
|
||||
for (unsigned d = 0; d < strlen(delims); ++d) {
|
||||
if (str[u] == delims[d]) {
|
||||
++count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static void u32_str_list_to_array(const char *str_list,
|
||||
const char *delims,
|
||||
unsigned num_elems,
|
||||
uint32_t *array)
|
||||
{
|
||||
for (unsigned u = 0; u < num_elems; ++u) {
|
||||
array[u] = strtol(str_list, NULL, 10);
|
||||
str_list += strcspn(str_list, delims) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void init_overrides(void)
|
||||
{
|
||||
const char *device_bvnc = debug_get_option("PVR_SHIM_DEVICE_BVNC", NULL);
|
||||
static const char *delims = ",;";
|
||||
unsigned b, v, n, c;
|
||||
uint64_t bvnc = DEFAULT_DEVICE_BVNC;
|
||||
int ret;
|
||||
|
||||
if (device_bvnc) {
|
||||
ret = sscanf(device_bvnc, "%u.%u.%u.%u", &b, &v, &n, &c);
|
||||
if (ret != 4) {
|
||||
fprintf(stderr,
|
||||
"pvr-drm-shim: Warning: Invalid device BVNC format \"%s\"; "
|
||||
"reverting to default device BVNC.\n",
|
||||
device_bvnc);
|
||||
|
||||
bvnc = DEFAULT_DEVICE_BVNC;
|
||||
} else {
|
||||
bvnc = PVR_BVNC_PACK(b, v, n, c);
|
||||
}
|
||||
}
|
||||
|
||||
ret = pvr_device_info_init(&device_info, bvnc);
|
||||
if (ret) {
|
||||
fprintf(stderr,
|
||||
"pvr-drm-shim: Warning: Device BVNC provided \"%s\" not found; "
|
||||
"reverting to default device BVNC.\n",
|
||||
device_bvnc);
|
||||
|
||||
ret = pvr_device_info_init(&device_info, DEFAULT_DEVICE_BVNC);
|
||||
assert(!ret);
|
||||
}
|
||||
|
||||
musthave_quirks = debug_get_bool_option("PVR_SHIM_MUSTHAVE_QUIRKS", false);
|
||||
const char *quirk_list = debug_get_option("PVR_SHIM_QUIRKS", NULL);
|
||||
if (quirk_list) {
|
||||
num_quirks = count_elems(quirk_list, delims);
|
||||
quirks = malloc(num_quirks * sizeof(*quirks));
|
||||
u32_str_list_to_array(quirk_list, delims, num_quirks, quirks);
|
||||
}
|
||||
|
||||
const char *enhancement_list =
|
||||
debug_get_option("PVR_SHIM_ENHANCEMENTS", NULL);
|
||||
if (enhancement_list) {
|
||||
num_enhancements = count_elems(enhancement_list, delims);
|
||||
enhancements = malloc(num_enhancements * sizeof(*enhancements));
|
||||
u32_str_list_to_array(enhancement_list,
|
||||
delims,
|
||||
num_enhancements,
|
||||
enhancements);
|
||||
}
|
||||
}
|
||||
|
||||
static void drm_shim_driver_fini(void)
|
||||
{
|
||||
free(enhancements);
|
||||
free(quirks);
|
||||
}
|
||||
|
||||
void drm_shim_driver_init(void)
|
||||
{
|
||||
init_overrides();
|
||||
|
||||
shim_device.bus_type = DRM_BUS_PLATFORM;
|
||||
shim_device.driver_name = "powervr";
|
||||
shim_device.driver_ioctls = driver_ioctls;
|
||||
shim_device.driver_ioctl_count = ARRAY_SIZE(driver_ioctls);
|
||||
|
||||
shim_device.version_major = 1;
|
||||
shim_device.version_minor = 0;
|
||||
shim_device.version_patchlevel = 0;
|
||||
|
||||
drm_shim_override_file("DRIVER=powervr\n"
|
||||
"OF_FULLNAME=/soc/pvr\n"
|
||||
"OF_COMPATIBLE_0=img,img-rogue\n"
|
||||
"OF_COMPATIBLE_N=1\n",
|
||||
"/sys/dev/char/%d:%d/device/uevent",
|
||||
DRM_MAJOR,
|
||||
render_node_minor);
|
||||
|
||||
atexit(drm_shim_driver_fini);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright © 2022 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef PVR_HW_UTILS_H
|
||||
#define PVR_HW_UTILS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "util/macros.h"
|
||||
|
||||
#include "pvr_device_info.h"
|
||||
|
||||
static inline uint32_t
|
||||
pvr_get_slc_cache_line_size(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
return PVR_GET_FEATURE_VALUE(dev_info, slc_cache_line_size_bits, 8U) / 8U;
|
||||
}
|
||||
|
||||
static inline uint32_t pvr_get_max_user_vertex_output_components(
|
||||
const struct pvr_device_info *dev_info)
|
||||
{
|
||||
/* Default value based on the minimum value found in all existing cores. */
|
||||
const uint32_t uvs_pba_entries =
|
||||
PVR_GET_FEATURE_VALUE(dev_info, uvs_pba_entries, 160U);
|
||||
|
||||
/* Default value based on the minimum value found in all existing cores. */
|
||||
const uint32_t uvs_banks = PVR_GET_FEATURE_VALUE(dev_info, uvs_banks, 2U);
|
||||
|
||||
if (uvs_banks <= 8U && uvs_pba_entries == 160U) {
|
||||
ASSERTED const uint32_t tpu_parallel_instances =
|
||||
PVR_GET_FEATURE_VALUE(dev_info, tpu_parallel_instances, 1U);
|
||||
|
||||
/* Cores with > 2 ppc support vertex sizes of >= 128 dwords */
|
||||
assert(tpu_parallel_instances <= 2 ||
|
||||
(dev_info->ident.b <= 36 || dev_info->ident.b == 46));
|
||||
|
||||
return 64U;
|
||||
}
|
||||
|
||||
return 128U;
|
||||
}
|
||||
|
||||
#endif /* PVR_HW_UTILS_H */
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright © 2022 Imagination Technologies Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* This file is based on rgxdefs.h and should only contain object-like macros.
|
||||
* Any function-like macros or inline functions should instead appear in
|
||||
* rogue_hw_utils.h.
|
||||
*/
|
||||
|
||||
#ifndef ROGUE_HW_DEFS_H
|
||||
#define ROGUE_HW_DEFS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util/macros.h"
|
||||
|
||||
#define ROGUE_BIF_PM_PHYSICAL_PAGE_SHIFT 12U
|
||||
#define ROGUE_BIF_PM_PHYSICAL_PAGE_SIZE \
|
||||
BITFIELD_BIT(ROGUE_BIF_PM_PHYSICAL_PAGE_SHIFT)
|
||||
|
||||
/* ISP triangle merging constants. */
|
||||
/* tan(15) (0x3E8930A3) */
|
||||
#define ROGUE_ISP_MERGE_LOWER_LIMIT_NUMERATOR 0.267949f
|
||||
/* tan(60) (0x3FDDB3D7) */
|
||||
#define ROGUE_ISP_MERGE_UPPER_LIMIT_NUMERATOR 1.732051f
|
||||
#define ROGUE_ISP_MERGE_SCALE_FACTOR 16.0f
|
||||
|
||||
#define ROGUE_MAX_INSTR_BYTES 32U
|
||||
|
||||
#define ROGUE_ICACHE_ALIGN 8U
|
||||
|
||||
#define ROGUE_OQUERY_ALIGN 16U
|
||||
|
||||
#define ROGUE_MAX_ALU_INPUTS 6U
|
||||
#define ROGUE_ALU_INPUT_GROUP_SIZE (ROGUE_MAX_ALU_INPUTS / 2)
|
||||
#define ROGUE_MAX_ALU_OUTPUTS 2U
|
||||
#define ROGUE_MAX_ALU_INTERNAL_SOURCES 6U
|
||||
|
||||
/* MList entry stride in bytes */
|
||||
#define ROGUE_MLIST_ENTRY_STRIDE 4U
|
||||
|
||||
/* VCE & TE share virtual space and Alist. */
|
||||
#define ROGUE_NUM_PM_ADDRESS_SPACES 2U
|
||||
|
||||
/* PM Maximum addressable limit (as determined by the size field of the
|
||||
* PM_*_FSTACK registers).
|
||||
*/
|
||||
#define ROGUE_PM_MAX_PB_VIRT_ADDR_SPACE UINT64_C(0x400000000)
|
||||
|
||||
/* Vheap entry size in bytes. */
|
||||
#define ROGUE_PM_VHEAP_ENTRY_SIZE 4U
|
||||
|
||||
#define ROGUE_RTC_SIZE_IN_BYTES 256U
|
||||
|
||||
#define ROGUE_NUM_VCE 1U
|
||||
|
||||
#define ROGUE_NUM_TEAC 1U
|
||||
|
||||
#define ROGUE_NUM_TE 1U
|
||||
|
||||
/* Tail pointer size in bytes. */
|
||||
#define ROGUE_TAIL_POINTER_SIZE 8U
|
||||
|
||||
/* Tail pointer cache line size. */
|
||||
#define ROGUE_TE_TPC_CACHE_LINE_SIZE 64U
|
||||
|
||||
#define ROGUE_MAX_VERTEX_SHARED_REGISTERS 1024U
|
||||
|
||||
#define ROGUE_MAX_PIXEL_SHARED_REGISTERS 1024U
|
||||
|
||||
#define ROGUE_MAX_COMPUTE_SHARED_REGISTERS (2U * 1024U)
|
||||
|
||||
/* Number of CR_PDS_BGRND values that need setting up. */
|
||||
#define ROGUE_NUM_CR_PDS_BGRND_WORDS 3U
|
||||
|
||||
/* Number of PBESTATE_REG_WORD values that need setting up. */
|
||||
#define ROGUE_NUM_PBESTATE_REG_WORDS 3U
|
||||
|
||||
/* Number of PBESTATE_REG_WORD used in transfer.
|
||||
* The last word is not used.
|
||||
*/
|
||||
#define ROGUE_NUM_PBESTATE_REG_WORDS_FOR_TRANSFER 2U
|
||||
|
||||
/* Number of PBESTATE_STATE_WORD values that need setting up. */
|
||||
#define ROGUE_NUM_PBESTATE_STATE_WORDS 2U
|
||||
|
||||
/* Number of TEXSTATE_IMAGE_WORD values that need setting up. */
|
||||
#define ROGUE_NUM_TEXSTATE_IMAGE_WORDS 2U
|
||||
|
||||
/* Number of TEXSTATE_SAMPLER state words that need setting up. */
|
||||
#define ROGUE_NUM_TEXSTATE_SAMPLER_WORDS 2U
|
||||
|
||||
#define ROGUE_NUM_TEXSTATE_DWORDS 4U
|
||||
|
||||
/* 12 dwords reserved for shared register management. The first dword is the
|
||||
* number of shared register blocks to reload. Should be a multiple of 4 dwords,
|
||||
* size in bytes.
|
||||
*/
|
||||
#define ROGUE_LLS_SHARED_REGS_RESERVE_SIZE 48U
|
||||
|
||||
#define ROGUE_CSRM_LINE_SIZE_IN_DWORDS (64U * 4U * 4U)
|
||||
|
||||
/* The maximum amount of local memory which can be allocated by a single kernel
|
||||
* (in dwords/32-bit registers).
|
||||
*
|
||||
* ROGUE_CDMCTRL_USC_COMMON_SIZE_UNIT_SIZE is in bytes so we divide by four.
|
||||
*/
|
||||
#define ROGUE_MAX_PER_KERNEL_LOCAL_MEM_SIZE_REGS \
|
||||
((ROGUE_CDMCTRL_KERNEL0_USC_COMMON_SIZE_UNIT_SIZE * \
|
||||
ROGUE_CDMCTRL_KERNEL0_USC_COMMON_SIZE_MAX_SIZE) >> \
|
||||
2)
|
||||
|
||||
#define ROGUE_MAX_INSTANCES_PER_TASK \
|
||||
(ROGUE_CDMCTRL_KERNEL8_MAX_INSTANCES_MAX_SIZE + 1U)
|
||||
|
||||
/* Optimal number for packing work groups into a slot. */
|
||||
#define ROGUE_CDM_MAX_PACKED_WORKGROUPS_PER_TASK 8U
|
||||
|
||||
/* The maximum number of pixel task instances which might be running overlapped
|
||||
* with compute. Once we have 8 pixel task instances we have a complete set and
|
||||
* task will be able to run and allocations will be freed.
|
||||
*/
|
||||
#define ROGUE_MAX_OVERLAPPED_PIXEL_TASK_INSTANCES 7U
|
||||
|
||||
/* Size of the image state in 64-bit units. */
|
||||
#define ROGUE_MAXIMUM_IMAGE_STATE_SIZE_IN_ULONGLONGS 2U
|
||||
|
||||
/* Size of the image state in dwords. The last 64-bit word is optional for
|
||||
* non-YUV textures.
|
||||
*/
|
||||
#define ROGUE_MAXIMUM_IMAGE_STATE_SIZE \
|
||||
(ROGUE_MAXIMUM_IMAGE_STATE_SIZE_IN_ULONGLONGS * \
|
||||
(sizeof(uint64_t) / sizeof(uint32_t)))
|
||||
|
||||
#define PVR_NUM_PBE_EMIT_REGS 8U
|
||||
|
||||
#define ROGUE_USRM_GRANULARITY_IN_REGISTERS 4U
|
||||
|
||||
#define ROGUE_RESERVED_USRM_LINES 2U
|
||||
|
||||
#define ROGUE_USC_NUM_UNIFIED_STORE_BANKS 8U
|
||||
|
||||
#define ROGUE_PDS_US_REGISTER_ALLOCATION_GRANULARITY 8U
|
||||
|
||||
#define ROGUE_PDS_US_TEMP_ALLOCATION_GRANULARITY \
|
||||
ROGUE_PDS_US_REGISTER_ALLOCATION_GRANULARITY
|
||||
|
||||
#define ROGUE_USRM_LINE_SIZE 16U
|
||||
|
||||
#define ROGUE_USRM_LINE_SIZE_PER_INSTANCE \
|
||||
(ROGUE_PDS_US_TEMP_ALLOCATION_GRANULARITY * ROGUE_USRM_LINE_SIZE)
|
||||
|
||||
enum {
|
||||
ROGUE_USC_COEFFICIENT_SET_A = 0,
|
||||
ROGUE_USC_COEFFICIENT_SET_B,
|
||||
ROGUE_USC_COEFFICIENT_SET_C,
|
||||
ROGUE_USC_COEFFICIENT_SET_PAD,
|
||||
ROGUE_USC_COEFFICIENT_SET_SIZE,
|
||||
};
|
||||
|
||||
enum {
|
||||
ROGUE_SMP_COEFF_UFRAC = 0,
|
||||
ROGUE_SMP_COEFF_VFRAC,
|
||||
ROGUE_SMP_COEFF_SFRAC,
|
||||
ROGUE_SMP_COEFF_LOD_DVAL_POST_CLAMP,
|
||||
ROGUE_SMP_COEFF_LOD_DVAL_PRE_CLAMP,
|
||||
ROGUE_SMP_COEFF_TFRAC_POST_CLAMP,
|
||||
ROGUE_SMP_COEFF_TFRAC_PRE_CLAMP,
|
||||
ROGUE_SMP_COEFF_COUNT,
|
||||
};
|
||||
|
||||
#define ROGUE_SMP_MAX_DATA_WORDS 18U
|
||||
|
||||
#define ROGUE_SMP_LOOKUP_MS_NUM_START 16U
|
||||
#define ROGUE_SMP_LOOKUP_MS_NUM_BITS 3U
|
||||
|
||||
#define ROGUE_SMP_LOOKUP_W_OFF_START 12U
|
||||
#define ROGUE_SMP_LOOKUP_W_OFF_BITS 4U
|
||||
|
||||
#define ROGUE_SMP_LOOKUP_V_OFF_START 6U
|
||||
#define ROGUE_SMP_LOOKUP_V_OFF_BITS 6U
|
||||
|
||||
#define ROGUE_SMP_LOOKUP_U_OFF_START 0U
|
||||
#define ROGUE_SMP_LOOKUP_U_OFF_BITS 6U
|
||||
|
||||
#define ROGUE_REG_SIZE_BYTES 4U
|
||||
|
||||
#endif /* ROGUE_HW_DEFS_H */
|
||||
@@ -0,0 +1,517 @@
|
||||
/*
|
||||
* Copyright © 2022 Imagination Technologies Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* This file is based on rgxdefs.h and should only contain function-like macros
|
||||
* and inline functions. Any object-like macros should instead appear in
|
||||
* rogue_hw_defs.h.
|
||||
*/
|
||||
|
||||
#ifndef ROGUE_HW_UTILS_H
|
||||
#define ROGUE_HW_UTILS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "pvr_types.h"
|
||||
|
||||
#define __pvr_address_type pvr_dev_addr_t
|
||||
#define __pvr_get_address(pvr_dev_addr) (pvr_dev_addr).addr
|
||||
/* clang-format off */
|
||||
#define __pvr_make_address(addr_u64) PVR_DEV_ADDR(addr_u64)
|
||||
/* clang-format on */
|
||||
|
||||
#include "csbgen/rogue/cdm.h"
|
||||
#include "csbgen/rogue/lls.h"
|
||||
|
||||
#undef __pvr_make_address
|
||||
#undef __pvr_get_address
|
||||
#undef __pvr_address_type
|
||||
|
||||
#include "rogue_hw_defs.h"
|
||||
#include "pvr_device_info.h"
|
||||
#include "util/compiler.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
#include "pvr_hw_utils.h"
|
||||
|
||||
static inline void
|
||||
rogue_get_isp_samples_per_tile_xy(const struct pvr_device_info *dev_info,
|
||||
uint32_t samples,
|
||||
uint32_t *const x_out,
|
||||
uint32_t *const y_out)
|
||||
{
|
||||
const uint32_t tile_size_x =
|
||||
PVR_GET_FEATURE_VALUE(dev_info, tile_size_x, 0U);
|
||||
const uint32_t tile_size_y =
|
||||
PVR_GET_FEATURE_VALUE(dev_info, tile_size_y, 0U);
|
||||
const uint32_t samples_per_pixel =
|
||||
PVR_GET_FEATURE_VALUE(dev_info, isp_samples_per_pixel, 0U);
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
switch (samples_per_pixel) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
break;
|
||||
default:
|
||||
assert(!"Unsupported ISP samples per pixel");
|
||||
}
|
||||
#endif
|
||||
|
||||
*x_out = tile_size_x;
|
||||
*y_out = tile_size_y;
|
||||
|
||||
switch (samples) {
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
if (samples_per_pixel == 2 || samples_per_pixel == 4)
|
||||
*y_out *= 2;
|
||||
|
||||
break;
|
||||
case 4:
|
||||
if (samples_per_pixel == 2 || samples_per_pixel == 4)
|
||||
*x_out *= 2;
|
||||
|
||||
if (samples_per_pixel == 4)
|
||||
*y_out *= 2;
|
||||
|
||||
break;
|
||||
case 8:
|
||||
if (samples_per_pixel == 2)
|
||||
*y_out *= 2;
|
||||
break;
|
||||
default:
|
||||
assert(!"Unsupported number of samples");
|
||||
}
|
||||
}
|
||||
|
||||
static void rogue_get_isp_scale_xy_from_samples(const uint32_t samples,
|
||||
uint32_t *const x_scale_out,
|
||||
uint32_t *const y_scale_out)
|
||||
{
|
||||
switch (samples) {
|
||||
case 1:
|
||||
*x_scale_out = 1;
|
||||
*y_scale_out = 1;
|
||||
break;
|
||||
case 2:
|
||||
*x_scale_out = 1;
|
||||
*y_scale_out = 2;
|
||||
break;
|
||||
case 4:
|
||||
*x_scale_out = 2;
|
||||
*y_scale_out = 2;
|
||||
break;
|
||||
case 8:
|
||||
*x_scale_out = 2;
|
||||
*y_scale_out = 4;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE("Unsupported number of samples");
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
rogue_get_isp_num_tiles_xy(const struct pvr_device_info *dev_info,
|
||||
uint32_t samples,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t *const x_out,
|
||||
uint32_t *const y_out)
|
||||
{
|
||||
uint32_t tile_samples_x;
|
||||
uint32_t tile_samples_y;
|
||||
uint32_t scale_x;
|
||||
uint32_t scale_y;
|
||||
|
||||
rogue_get_isp_samples_per_tile_xy(dev_info,
|
||||
samples,
|
||||
&tile_samples_x,
|
||||
&tile_samples_y);
|
||||
|
||||
rogue_get_isp_scale_xy_from_samples(samples, &scale_x, &scale_y);
|
||||
|
||||
*x_out = DIV_ROUND_UP(width * scale_x, tile_samples_x);
|
||||
*y_out = DIV_ROUND_UP(height * scale_y, tile_samples_y);
|
||||
|
||||
if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format)) {
|
||||
assert(PVR_GET_FEATURE_VALUE(dev_info,
|
||||
simple_parameter_format_version,
|
||||
0U) == 2U);
|
||||
/* Align to a 2x2 tile block. */
|
||||
*x_out = ALIGN_POT(*x_out, 2);
|
||||
*y_out = ALIGN_POT(*y_out, 2);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
rogue_get_zls_tile_size_xy(const struct pvr_device_info *dev_info,
|
||||
uint32_t *const x_out,
|
||||
uint32_t *const y_out)
|
||||
{
|
||||
uint32_t version = 0;
|
||||
bool has_version;
|
||||
|
||||
has_version =
|
||||
!PVR_FEATURE_VALUE(dev_info, simple_parameter_format_version, &version);
|
||||
|
||||
*x_out = PVR_GET_FEATURE_VALUE(dev_info, tile_size_x, 0U);
|
||||
*y_out = PVR_GET_FEATURE_VALUE(dev_info, tile_size_y, 0U);
|
||||
|
||||
if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format) &&
|
||||
has_version && version == 2) {
|
||||
*x_out *= 2;
|
||||
*y_out *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_get_max_output_regs_per_pixel(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
if (PVR_HAS_FEATURE(dev_info, eight_output_registers))
|
||||
return 8U;
|
||||
|
||||
return 4U;
|
||||
}
|
||||
|
||||
static inline void
|
||||
rogue_get_num_macrotiles_xy(const struct pvr_device_info *dev_info,
|
||||
uint32_t *const x_out,
|
||||
uint32_t *const y_out)
|
||||
{
|
||||
uint32_t version;
|
||||
|
||||
if (PVR_FEATURE_VALUE(dev_info, simple_parameter_format_version, &version))
|
||||
version = 0;
|
||||
|
||||
if (!PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format) ||
|
||||
version == 2) {
|
||||
*x_out = 4;
|
||||
*y_out = 4;
|
||||
} else {
|
||||
*x_out = 1;
|
||||
*y_out = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_get_macrotile_array_size(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
uint32_t num_macrotiles_x;
|
||||
uint32_t num_macrotiles_y;
|
||||
|
||||
if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format))
|
||||
return 0;
|
||||
|
||||
rogue_get_num_macrotiles_xy(dev_info, &num_macrotiles_x, &num_macrotiles_y);
|
||||
|
||||
return num_macrotiles_x * num_macrotiles_y * 8U;
|
||||
}
|
||||
|
||||
/* Region header size in bytes. */
|
||||
static inline uint32_t
|
||||
rogue_get_region_header_size(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
uint32_t version;
|
||||
|
||||
if (PVR_FEATURE_VALUE(dev_info, simple_parameter_format_version, &version))
|
||||
version = 0;
|
||||
|
||||
if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format) &&
|
||||
version == 2) {
|
||||
return 6;
|
||||
}
|
||||
|
||||
return 5;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_get_render_size_max(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
if (PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format))
|
||||
if (!PVR_HAS_FEATURE(dev_info, screen_size8K))
|
||||
return 4096U;
|
||||
|
||||
return 8192U;
|
||||
}
|
||||
|
||||
#define rogue_get_render_size_max_x(dev_info) \
|
||||
rogue_get_render_size_max(dev_info)
|
||||
|
||||
#define rogue_get_render_size_max_y(dev_info) \
|
||||
rogue_get_render_size_max(dev_info)
|
||||
|
||||
static inline uint32_t
|
||||
rogue_get_render_size_max_z(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
switch (dev_info->ident.arch) {
|
||||
case PVR_DEVICE_ARCH_ROGUE:
|
||||
return 2048;
|
||||
default:
|
||||
UNREACHABLE("unexpected arch");
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_get_texture_extent_max(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
switch (dev_info->ident.arch) {
|
||||
case PVR_DEVICE_ARCH_ROGUE:
|
||||
return 16384;
|
||||
default:
|
||||
UNREACHABLE("unexpected arch");
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_max_compute_shared_registers(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
if (PVR_HAS_FEATURE(dev_info, compute))
|
||||
return 1024U;
|
||||
|
||||
return 0U;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_get_max_num_cores(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
if (PVR_HAS_FEATURE(dev_info, gpu_multicore_support) &&
|
||||
PVR_HAS_FEATURE(dev_info, xpu_max_slaves)) {
|
||||
return PVR_GET_FEATURE_VALUE(dev_info, xpu_max_slaves, 0U) + 1U;
|
||||
}
|
||||
|
||||
return 1U;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_get_cdm_context_resume_buffer_size(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
if (PVR_HAS_FEATURE(dev_info, gpu_multicore_support)) {
|
||||
const uint32_t max_num_cores = rogue_get_max_num_cores(dev_info);
|
||||
const uint32_t cache_line_size = pvr_get_slc_cache_line_size(dev_info);
|
||||
const uint32_t cdm_context_resume_buffer_stride =
|
||||
ALIGN_POT(ROGUE_LLS_CDM_CONTEXT_RESUME_BUFFER_SIZE, cache_line_size);
|
||||
|
||||
/*
|
||||
* TODO: Optimise buffer size based on the core_count,
|
||||
* not max_num_cores
|
||||
*/
|
||||
return cdm_context_resume_buffer_stride * max_num_cores;
|
||||
}
|
||||
|
||||
return ROGUE_LLS_CDM_CONTEXT_RESUME_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
static inline uint32_t rogue_get_cdm_context_resume_buffer_alignment(
|
||||
const struct pvr_device_info *dev_info)
|
||||
{
|
||||
if (PVR_HAS_FEATURE(dev_info, gpu_multicore_support))
|
||||
return pvr_get_slc_cache_line_size(dev_info);
|
||||
|
||||
return ROGUE_LLS_CDM_CONTEXT_RESUME_BUFFER_ALIGNMENT;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_get_compute_max_work_group_size(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
/* The number of tasks which can be executed per USC - Limited to 16U by the
|
||||
* CDM.
|
||||
*/
|
||||
const uint32_t max_tasks_per_usc = 16U;
|
||||
|
||||
if (!PVR_HAS_ENHANCEMENT(dev_info, 35421)) {
|
||||
/* Barriers on work-groups > 32 instances aren't supported. */
|
||||
return ROGUE_MAX_INSTANCES_PER_TASK;
|
||||
}
|
||||
|
||||
return ROGUE_MAX_INSTANCES_PER_TASK * max_tasks_per_usc;
|
||||
}
|
||||
|
||||
/* Don't use this directly. Use the x and y define macros. */
|
||||
static inline uint32_t
|
||||
__rogue_get_param_vf_max(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
return (rogue_get_render_size_max(dev_info) * 3 / 2) - 1;
|
||||
}
|
||||
|
||||
#define rogue_get_param_vf_max_x(dev_info) __rogue_get_param_vf_max(dev_info)
|
||||
#define rogue_get_param_vf_max_y(dev_info) __rogue_get_param_vf_max(dev_info)
|
||||
|
||||
static inline uint32_t
|
||||
rogue_get_max_total_instances(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
const uint32_t usc_slots = PVR_GET_FEATURE_VALUE(dev_info, usc_slots, 0U);
|
||||
assert(usc_slots);
|
||||
|
||||
return usc_slots * ROGUE_MAX_INSTANCES_PER_TASK;
|
||||
}
|
||||
|
||||
static inline uint32_t rogue_get_unified_store_size_per_instance(
|
||||
const struct pvr_device_info *dev_info)
|
||||
{
|
||||
const uint32_t unified_store_depth =
|
||||
PVR_GET_FEATURE_VALUE(dev_info, unified_store_depth, 0U);
|
||||
assert(unified_store_depth);
|
||||
|
||||
return unified_store_depth * ROGUE_USC_NUM_UNIFIED_STORE_BANKS;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_get_min_attr_in_usrm_lines(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
const uint32_t unified_store_size_per_instance =
|
||||
rogue_get_unified_store_size_per_instance(dev_info);
|
||||
assert(unified_store_size_per_instance);
|
||||
|
||||
return (unified_store_size_per_instance /
|
||||
ROGUE_USRM_LINE_SIZE_PER_INSTANCE) -
|
||||
ROGUE_RESERVED_USRM_LINES;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_get_parallel_instances(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
return ROGUE_MAX_INSTANCES_PER_TASK / 2;
|
||||
}
|
||||
|
||||
static inline uint32_t rogue_get_unified_store_temps_per_instance(
|
||||
const struct pvr_device_info *dev_info)
|
||||
{
|
||||
return rogue_get_min_attr_in_usrm_lines(dev_info) *
|
||||
ROGUE_USRM_LINE_SIZE_PER_INSTANCE;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_get_unified_store_total_temps(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
return rogue_get_unified_store_temps_per_instance(dev_info) *
|
||||
rogue_get_parallel_instances(dev_info);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_get_instance_groups_per_slot(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
return ROGUE_MAX_INSTANCES_PER_TASK / rogue_get_parallel_instances(dev_info);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_get_optimal_temps(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
const uint32_t usc_slots = PVR_GET_FEATURE_VALUE(dev_info, usc_slots, 0U);
|
||||
assert(usc_slots);
|
||||
|
||||
uint32_t max_temps_full_slot_use =
|
||||
rogue_get_unified_store_temps_per_instance(dev_info) /
|
||||
(rogue_get_instance_groups_per_slot(dev_info) * usc_slots);
|
||||
|
||||
max_temps_full_slot_use &= ~(ROGUE_PDS_US_TEMP_ALLOCATION_GRANULARITY - 1);
|
||||
|
||||
return MAX2(max_temps_full_slot_use, 24U);
|
||||
}
|
||||
|
||||
static inline uint32_t rogue_get_temps(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
uint32_t temps = rogue_get_unified_store_temps_per_instance(dev_info) / 2;
|
||||
|
||||
return MIN2(temps, 248U);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_max_wg_temps(const struct pvr_device_info *dev_info,
|
||||
unsigned temps,
|
||||
unsigned wg_size,
|
||||
bool has_barrier)
|
||||
{
|
||||
assert(wg_size <= rogue_get_max_total_instances(dev_info));
|
||||
if (!wg_size)
|
||||
wg_size = rogue_get_compute_max_work_group_size(dev_info);
|
||||
|
||||
if (wg_size > ROGUE_MAX_INSTANCES_PER_TASK && has_barrier) {
|
||||
/* Number of slots allocated for each workgroup. */
|
||||
unsigned slots_per_wg =
|
||||
DIV_ROUND_UP(wg_size, ROGUE_MAX_INSTANCES_PER_TASK);
|
||||
|
||||
/* Lines of USRM lines available for each slot
|
||||
* (+1 for fragmentation / coarse checking).
|
||||
*/
|
||||
unsigned lines_per_slot =
|
||||
rogue_get_min_attr_in_usrm_lines(dev_info) / (slots_per_wg + 1);
|
||||
|
||||
unsigned max_allocs;
|
||||
if (lines_per_slot != 0) {
|
||||
/* Convert lines to USRM allocs. */
|
||||
max_allocs = lines_per_slot * ROGUE_USRM_LINE_SIZE;
|
||||
} else {
|
||||
max_allocs = (rogue_get_min_attr_in_usrm_lines(dev_info) *
|
||||
ROGUE_USRM_LINE_SIZE) /
|
||||
(slots_per_wg + 1);
|
||||
}
|
||||
|
||||
/* Convert USRM allocs to temporary registers. */
|
||||
unsigned max_temps_for_barrier =
|
||||
max_allocs * ROGUE_USRM_GRANULARITY_IN_REGISTERS;
|
||||
|
||||
/* Clamp to provided limit */
|
||||
temps = MIN2(temps, max_temps_for_barrier);
|
||||
}
|
||||
|
||||
return temps;
|
||||
}
|
||||
|
||||
static inline uint32_t rogue_get_vtxins(void)
|
||||
{
|
||||
/* TODO: use highest safe number of vertex input registers. */
|
||||
return 12;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_num_uscs_per_tile(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
if (PVR_HAS_FEATURE(dev_info, tile_per_usc) ||
|
||||
PVR_HAS_FEATURE(dev_info, pbe2_in_xe))
|
||||
return 1;
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
static inline uint32_t rogue_usc_indexed_pixel_output_index_scale(
|
||||
const struct pvr_device_info *dev_info)
|
||||
{
|
||||
if (PVR_HAS_FEATURE(dev_info, tile_per_usc))
|
||||
return 4;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_get_total_instance_count(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
/* Number of instances calculated as such:
|
||||
* USC_SLOTS * INSTANCES_PER_SLOT * MAX_NUM_CORES * NUM_CLUSTERS
|
||||
*/
|
||||
/* TODO: Optimise tile buffer size to use core_count, not max_num_cores. */
|
||||
return rogue_get_max_total_instances(dev_info) *
|
||||
rogue_get_max_num_cores(dev_info) *
|
||||
PVR_GET_FEATURE_VALUE(dev_info, num_clusters, 1);
|
||||
}
|
||||
#endif /* ROGUE_HW_UTILS_H */
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright © 2022 Imagination Technologies Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* This file is based on rgx_fwif_shared.h and rgx_fwif_client.h. It contains
|
||||
* information about the firmware that is needed by the driver.
|
||||
*/
|
||||
|
||||
#ifndef PVR_ROGUE_FW_H
|
||||
#define PVR_ROGUE_FW_H
|
||||
|
||||
/* FIXME: This will change based on the firmware configuration, which will vary
|
||||
* depending on the BVNC and firmware version. The powervr KM driver allows this
|
||||
* information to be queried, but the pvrsrvkm KM driver doesn't. This
|
||||
* information should really be queried from the winsys.
|
||||
*/
|
||||
/* Indicates the number of Render Target Datas in a Render Target Dataset. */
|
||||
#define ROGUE_NUM_RTDATAS 2U
|
||||
|
||||
#endif /* PVR_ROGUE_FW_H */
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright © 2022 Imagination Technologies Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PVR_TYPES_H
|
||||
#define PVR_TYPES_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* \brief Convert dwords to bytes.
|
||||
*
|
||||
* Throughout the code base we keep sizes in dwords (e.g. code_size and
|
||||
* data_size returned by the pds api) and in some cases we need to convert those
|
||||
* to be in bytes.
|
||||
*
|
||||
* This macro makes the conversion more obvious.
|
||||
*/
|
||||
/* clang-format off */
|
||||
#define PVR_DW_TO_BYTES(_value) ((_value) * 4)
|
||||
/* clang-format on */
|
||||
|
||||
/*****************************************************************************
|
||||
Device virtual addresses
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct pvr_dev_addr {
|
||||
uint64_t addr;
|
||||
} pvr_dev_addr_t;
|
||||
|
||||
#define PVR_DEV_ADDR(addr_) ((pvr_dev_addr_t){ .addr = (addr_) })
|
||||
#define PVR_DEV_ADDR_OFFSET(base, offset) PVR_DEV_ADDR((base).addr + (offset))
|
||||
#define PVR_DEV_ADDR_INVALID PVR_DEV_ADDR(0)
|
||||
|
||||
/* All currently supported devices use a 40-bit virtual address space. */
|
||||
#define PVR_DEV_ADDR_FMT "0x%010" PRIx64
|
||||
|
||||
#endif /* PVR_TYPES_H */
|
||||
@@ -0,0 +1,26 @@
|
||||
# Copyright © 2022 Imagination Technologies Ltd.
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
imagination_c_args = cc.get_supported_arguments(
|
||||
'-Werror=pointer-arith',
|
||||
)
|
||||
|
||||
inc_imagination = include_directories([
|
||||
'.',
|
||||
'common',
|
||||
'include',
|
||||
])
|
||||
|
||||
if with_imagination_vk or with_tools.contains('imagination')
|
||||
subdir('common')
|
||||
subdir('csbgen')
|
||||
subdir('pco')
|
||||
endif
|
||||
|
||||
if with_imagination_vk
|
||||
subdir('vulkan')
|
||||
|
||||
if with_tools.contains('drm-shim')
|
||||
subdir('drm-shim')
|
||||
endif
|
||||
endif
|
||||
@@ -0,0 +1,136 @@
|
||||
# Copyright © 2024 Imagination Technologies Ltd.
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
inc_powervr_compiler = include_directories(['.'])
|
||||
|
||||
libpowervr_compiler_files = files(
|
||||
'pco.c',
|
||||
'pco_binary.c',
|
||||
'pco_bool.c',
|
||||
'pco_cf.c',
|
||||
'pco_const_imms.c',
|
||||
'pco_debug.c',
|
||||
'pco_end.c',
|
||||
'pco_group_instrs.c',
|
||||
'pco_index.c',
|
||||
'pco_ir.c',
|
||||
'pco_legalize.c',
|
||||
'pco_nir.c',
|
||||
'pco_nir_compute.c',
|
||||
'pco_nir_io.c',
|
||||
'pco_nir_lower_null_descriptors.c',
|
||||
'pco_nir_pvfio.c',
|
||||
'pco_nir_sync.c',
|
||||
'pco_nir_tex.c',
|
||||
'pco_nir_vk.c',
|
||||
'pco_opt.c',
|
||||
'pco_print.c',
|
||||
'pco_ra.c',
|
||||
'pco_schedule.c',
|
||||
'pco_trans_nir.c',
|
||||
'pco_validate.c',
|
||||
)
|
||||
|
||||
pco_pygen_dep_files = files('pco_pygen_common.py', 'pco_isa.py', 'pco_ops.py', 'pco_map.py')
|
||||
|
||||
pco_builder_ops_h = custom_target(
|
||||
'pco_builder_ops.h',
|
||||
input : ['pco_builder_ops.h.py'],
|
||||
output : 'pco_builder_ops.h',
|
||||
command : [prog_python, '@INPUT@'],
|
||||
capture : true,
|
||||
depend_files : pco_pygen_dep_files,
|
||||
)
|
||||
|
||||
pco_common_h = custom_target(
|
||||
'pco_common.h',
|
||||
input : ['pco_common.h.py'],
|
||||
output : 'pco_common.h',
|
||||
command : [prog_python, '@INPUT@'],
|
||||
capture : true,
|
||||
depend_files : pco_pygen_dep_files,
|
||||
)
|
||||
|
||||
pco_info_c = custom_target(
|
||||
'pco_info.c',
|
||||
input : ['pco_info.c.py'],
|
||||
output : 'pco_info.c',
|
||||
command : [prog_python, '@INPUT@'],
|
||||
capture : true,
|
||||
depend_files : pco_pygen_dep_files,
|
||||
)
|
||||
|
||||
pco_isa_h = custom_target(
|
||||
'pco_isa.h',
|
||||
input : ['pco_isa.h.py'],
|
||||
output : 'pco_isa.h',
|
||||
command : [prog_python, '@INPUT@'],
|
||||
capture : true,
|
||||
depend_files : pco_pygen_dep_files,
|
||||
)
|
||||
|
||||
pco_map_h = custom_target(
|
||||
'pco_map.h',
|
||||
input : ['pco_map.h.py'],
|
||||
output : 'pco_map.h',
|
||||
command : [prog_python, '@INPUT@'],
|
||||
capture : true,
|
||||
depend_files : pco_pygen_dep_files,
|
||||
)
|
||||
|
||||
pco_ops_h = custom_target(
|
||||
'pco_ops.h',
|
||||
input : ['pco_ops.h.py'],
|
||||
output : 'pco_ops.h',
|
||||
command : [prog_python, '@INPUT@'],
|
||||
capture : true,
|
||||
depend_files : pco_pygen_dep_files,
|
||||
)
|
||||
|
||||
pco_pygen_sources = [
|
||||
pco_builder_ops_h,
|
||||
pco_common_h,
|
||||
pco_info_c,
|
||||
pco_isa_h,
|
||||
pco_map_h,
|
||||
pco_ops_h,
|
||||
]
|
||||
|
||||
idep_pco_pygen = declare_dependency(
|
||||
sources : pco_pygen_sources,
|
||||
include_directories : inc_powervr_compiler,
|
||||
)
|
||||
|
||||
pco_pygen_c_files = [pco_info_c]
|
||||
|
||||
subdir('usclib')
|
||||
|
||||
pco_nir_algebraic_c = custom_target(
|
||||
'pco_nir_algebraic.c',
|
||||
input : 'pco_nir_algebraic.py',
|
||||
output : 'pco_nir_algebraic.c',
|
||||
command : [
|
||||
prog_python, '@INPUT@', '-p', dir_compiler_nir,
|
||||
],
|
||||
capture : true,
|
||||
depend_files : nir_algebraic_depends,
|
||||
)
|
||||
|
||||
libpowervr_compiler = static_library(
|
||||
'powervr_compiler',
|
||||
[libpowervr_compiler_files, pco_pygen_c_files, pco_nir_algebraic_c],
|
||||
include_directories : [
|
||||
inc_imagination,
|
||||
inc_powervr_compiler,
|
||||
inc_include,
|
||||
inc_compiler,
|
||||
inc_src,
|
||||
],
|
||||
# Suppress 'parameter passing for argument of type ... changed in GCC ...' warnings.
|
||||
c_args : [imagination_c_args, no_override_init_args, '-Wno-psabi'],
|
||||
dependencies : [dep_csbgen, idep_mesautil, idep_nir, idep_pco_pygen, idep_pco_usclib],
|
||||
gnu_symbol_visibility : 'hidden',
|
||||
install : false,
|
||||
)
|
||||
|
||||
subdir('uscgen')
|
||||
@@ -0,0 +1,461 @@
|
||||
/*
|
||||
* Copyright © 2024 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file pco.c
|
||||
*
|
||||
* \brief Main compiler interface.
|
||||
*/
|
||||
|
||||
#include "compiler/glsl_types.h"
|
||||
#include "nir_serialize.h"
|
||||
#include "pco.h"
|
||||
#include "pco_internal.h"
|
||||
#include "util/blob.h"
|
||||
#include "util/hash_table.h"
|
||||
#include "util/list.h"
|
||||
#include "util/macros.h"
|
||||
#include "util/ralloc.h"
|
||||
#include "util/shader_stats.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* \brief PCO compiler context destructor.
|
||||
*
|
||||
* \param[in,out] ptr PCO compiler context pointer.
|
||||
*/
|
||||
static void pco_ctx_destructor(UNUSED void *ptr)
|
||||
{
|
||||
glsl_type_singleton_decref();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Allocates and sets up a PCO compiler context.
|
||||
*
|
||||
* \param[in] dev_info Device info.
|
||||
* \param[in] dev_runtime_info Device runtime info.
|
||||
* \param[in] mem_ctx Ralloc memory allocation context.
|
||||
* \return The PCO compiler context, or NULL on failure.
|
||||
*/
|
||||
pco_ctx *pco_ctx_create(const struct pvr_device_info *dev_info,
|
||||
const struct pvr_device_runtime_info *dev_runtime_info,
|
||||
void *mem_ctx)
|
||||
{
|
||||
pco_ctx *ctx = rzalloc_size(mem_ctx, sizeof(*ctx));
|
||||
|
||||
ctx->dev_info = dev_info;
|
||||
ctx->dev_runtime_info = dev_runtime_info;
|
||||
|
||||
pco_debug_init();
|
||||
|
||||
#ifndef NDEBUG
|
||||
/* Ensure NIR debug variables are processed. */
|
||||
nir_process_debug_variable();
|
||||
#endif /* NDEBUG */
|
||||
|
||||
glsl_type_singleton_init_or_ref();
|
||||
ralloc_set_destructor(ctx, pco_ctx_destructor);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void pco_ctx_setup_usclib(pco_ctx *ctx, const void *data, unsigned size)
|
||||
{
|
||||
struct blob_reader blob_reader;
|
||||
blob_reader_init(&blob_reader, data, size);
|
||||
ctx->usclib = nir_deserialize(ctx, pco_nir_options(), &blob_reader);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Updates the device info for a PCO compiler context.
|
||||
*
|
||||
* \param[in,out] ctx PCO compiler context.
|
||||
* \param[in] dev_info Device info.
|
||||
*/
|
||||
void pco_ctx_update_dev_info(pco_ctx *ctx,
|
||||
const struct pvr_device_info *dev_info)
|
||||
{
|
||||
ctx->dev_info = dev_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Allocates and sets up a PCO shader from a NIR shader.
|
||||
*
|
||||
* \param[in] ctx PCO compiler context.
|
||||
* \param[in] nir The NIR shader.
|
||||
* \return The PCO shader, or NULL on failure.
|
||||
*/
|
||||
pco_shader *pco_shader_create(pco_ctx *ctx, nir_shader *nir, void *mem_ctx)
|
||||
{
|
||||
pco_shader *shader = rzalloc_size(mem_ctx, sizeof(*shader));
|
||||
|
||||
shader->ctx = ctx;
|
||||
shader->nir = nir;
|
||||
shader->stage = nir->info.stage;
|
||||
shader->name = ralloc_strdup(shader, nir->info.name);
|
||||
shader->is_internal = nir->info.internal;
|
||||
shader->is_grouped = false;
|
||||
list_inithead(&shader->funcs);
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets up a PCO cf node.
|
||||
*
|
||||
* \param[in,out] cf_node PCO cf node.
|
||||
* \param[in] type CF node type.
|
||||
*/
|
||||
static inline void init_cf_node(pco_cf_node *cf_node,
|
||||
enum pco_cf_node_type type)
|
||||
{
|
||||
cf_node->type = type;
|
||||
cf_node->parent = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Allocates and sets up a PCO function.
|
||||
*
|
||||
* \param[in,out] shader PCO shader.
|
||||
* \param[in] type The function type.
|
||||
* \param[in] num_params The number of parameters.
|
||||
* \return The PCO function, or NULL on failure.
|
||||
*/
|
||||
pco_func *pco_func_create(pco_shader *shader,
|
||||
enum pco_func_type type,
|
||||
unsigned num_params)
|
||||
{
|
||||
pco_func *func = rzalloc_size(shader, sizeof(*func));
|
||||
pco_func *preamble = pco_preamble(shader);
|
||||
|
||||
/* Add the function to the shader; preamble goes first, then entrypoint.
|
||||
* The rest of the functions will get appended.
|
||||
*/
|
||||
if (type == PCO_FUNC_TYPE_PREAMBLE) {
|
||||
assert(!preamble);
|
||||
list_add(&func->link, &shader->funcs);
|
||||
} else if (type == PCO_FUNC_TYPE_ENTRYPOINT) {
|
||||
assert(!pco_entrypoint(shader));
|
||||
if (!preamble)
|
||||
list_add(&func->link, &shader->funcs);
|
||||
else
|
||||
list_add(&func->link, &preamble->link);
|
||||
} else {
|
||||
list_addtail(&func->link, &shader->funcs);
|
||||
}
|
||||
|
||||
init_cf_node(&func->cf_node, PCO_CF_NODE_TYPE_FUNC);
|
||||
func->parent_shader = shader;
|
||||
func->type = type;
|
||||
func->index = shader->next_func++;
|
||||
|
||||
list_inithead(&func->body);
|
||||
|
||||
func->num_params = num_params;
|
||||
if (num_params) {
|
||||
func->params =
|
||||
rzalloc_array_size(func, sizeof(*func->params), num_params);
|
||||
}
|
||||
|
||||
func->vec_infos = _mesa_hash_table_u64_create(func);
|
||||
|
||||
func->enc_offset = ~0U;
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Allocates and sets up a PCO block.
|
||||
*
|
||||
* \param[in,out] func Parent function.
|
||||
* \return The PCO block, or NULL on failure.
|
||||
*/
|
||||
pco_block *pco_block_create(pco_func *func)
|
||||
{
|
||||
pco_block *block = rzalloc_size(func, sizeof(*block));
|
||||
|
||||
init_cf_node(&block->cf_node, PCO_CF_NODE_TYPE_BLOCK);
|
||||
block->parent_func = func;
|
||||
list_inithead(&block->instrs);
|
||||
block->index = func->next_block++;
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Allocates and sets up a PCO if construct.
|
||||
*
|
||||
* \param[in,out] func Parent function.
|
||||
* \return The PCO if construct, or NULL on failure.
|
||||
*/
|
||||
pco_if *pco_if_create(pco_func *func)
|
||||
{
|
||||
pco_if *pif = rzalloc_size(func, sizeof(*pif));
|
||||
|
||||
init_cf_node(&pif->cf_node, PCO_CF_NODE_TYPE_IF);
|
||||
pif->parent_func = func;
|
||||
list_inithead(&pif->prologue);
|
||||
list_inithead(&pif->then_body);
|
||||
list_inithead(&pif->interlogue);
|
||||
list_inithead(&pif->else_body);
|
||||
list_inithead(&pif->epilogue);
|
||||
pif->index = func->next_if++;
|
||||
|
||||
return pif;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Allocates and sets up a PCO loop.
|
||||
*
|
||||
* \param[in,out] func Parent function.
|
||||
* \return The PCO loop, or NULL on failure.
|
||||
*/
|
||||
pco_loop *pco_loop_create(pco_func *func)
|
||||
{
|
||||
pco_loop *loop = rzalloc_size(func, sizeof(*loop));
|
||||
|
||||
init_cf_node(&loop->cf_node, PCO_CF_NODE_TYPE_LOOP);
|
||||
loop->parent_func = func;
|
||||
list_inithead(&loop->prologue);
|
||||
list_inithead(&loop->body);
|
||||
list_inithead(&loop->interlogue);
|
||||
list_inithead(&loop->epilogue);
|
||||
loop->index = func->next_loop++;
|
||||
|
||||
return loop;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Allocates and sets up a PCO instruction.
|
||||
*
|
||||
* \param[in,out] func Parent function.
|
||||
* \param[in] num_dests Number of destinations.
|
||||
* \param[in] num_srcs Number of sources.
|
||||
* \return The PCO instruction, or NULL on failure.
|
||||
*/
|
||||
pco_instr *
|
||||
pco_instr_create(pco_func *func, unsigned num_dests, unsigned num_srcs)
|
||||
{
|
||||
pco_instr *instr;
|
||||
unsigned size = sizeof(*instr);
|
||||
size += num_dests * sizeof(*instr->dest);
|
||||
size += num_srcs * sizeof(*instr->src);
|
||||
|
||||
instr = rzalloc_size(func, size);
|
||||
|
||||
instr->parent_func = func;
|
||||
|
||||
instr->num_dests = num_dests;
|
||||
instr->dest = (pco_ref *)(instr + 1);
|
||||
|
||||
instr->num_srcs = num_srcs;
|
||||
instr->src = instr->dest + num_dests;
|
||||
|
||||
list_inithead(&instr->phi_srcs);
|
||||
|
||||
instr->index = func->next_instr++;
|
||||
|
||||
return instr;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Allocates and sets up a PCO instruction group.
|
||||
*
|
||||
* \param[in,out] func Parent function.
|
||||
* \return The PCO instruction group, or NULL on failure.
|
||||
*/
|
||||
pco_igrp *pco_igrp_create(pco_func *func)
|
||||
{
|
||||
pco_igrp *igrp = rzalloc_size(func, sizeof(*igrp));
|
||||
|
||||
igrp->parent_func = func;
|
||||
igrp->index = func->next_igrp++;
|
||||
|
||||
return igrp;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Deletes a PCO instruction.
|
||||
*
|
||||
* \param[in,out] instr PCO instruction.
|
||||
*/
|
||||
void pco_instr_delete(pco_instr *instr)
|
||||
{
|
||||
list_del(&instr->link);
|
||||
ralloc_free(instr);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the shader data.
|
||||
*
|
||||
* \param[in] shader PCO shader.
|
||||
*/
|
||||
pco_data *pco_shader_data(pco_shader *shader)
|
||||
{
|
||||
return &shader->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns precompilation data for a shader.
|
||||
*
|
||||
* \param[in] shader PCO shader.
|
||||
* \return The precompilation data.
|
||||
*/
|
||||
pco_precomp_data pco_get_precomp_data(pco_shader *shader)
|
||||
{
|
||||
assert(pco_shader_binary_size(shader));
|
||||
|
||||
unsigned size_dwords = pco_shader_binary_size(shader) / sizeof(uint32_t);
|
||||
assert(size_dwords <= UINT16_MAX);
|
||||
|
||||
return (pco_precomp_data){
|
||||
.temps = shader->data.common.temps,
|
||||
.vtxins = shader->data.common.vtxins,
|
||||
.coeffs = shader->data.common.coeffs,
|
||||
.shareds = shader->data.common.shareds,
|
||||
.size_dwords = size_dwords,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns statistics for a shader.
|
||||
*
|
||||
* \param[in] shader PCO shader.
|
||||
* \return The shader statistics.
|
||||
*/
|
||||
struct pvr_stats pco_get_pvr_stats(pco_shader *shader)
|
||||
{
|
||||
assert(shader->is_grouped);
|
||||
|
||||
unsigned shader_size = pco_shader_binary_size(shader);
|
||||
assert(shader_size > 0);
|
||||
|
||||
unsigned loop_count = 0;
|
||||
unsigned igrp_count = 0;
|
||||
|
||||
unsigned main_count = 0;
|
||||
unsigned bitwise_count = 0;
|
||||
unsigned control_count = 0;
|
||||
|
||||
pco_foreach_func_in_shader (func, shader) {
|
||||
pco_foreach_loop_in_func (loop, func) {
|
||||
loop_count++;
|
||||
}
|
||||
pco_foreach_igrp_in_func (igrp, func) {
|
||||
igrp_count++;
|
||||
switch (igrp->hdr.alutype) {
|
||||
case PCO_ALUTYPE_MAIN:
|
||||
main_count++;
|
||||
break;
|
||||
|
||||
case PCO_ALUTYPE_BITWISE:
|
||||
bitwise_count++;
|
||||
break;
|
||||
|
||||
case PCO_ALUTYPE_CONTROL:
|
||||
control_count++;
|
||||
break;
|
||||
|
||||
default:
|
||||
UNREACHABLE("Invalid pco_alutype");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (struct pvr_stats){
|
||||
.isa = PVR_STAT_ROGUE,
|
||||
.rogue = (struct rogue_stats) {
|
||||
.code_size = shader_size,
|
||||
.scratch_size = shader->data.common.scratch,
|
||||
.spill_count = shader->data.common.spilled_temps,
|
||||
.temp_count = shader->data.common.temps,
|
||||
.vtxin_count = shader->data.common.vtxins,
|
||||
.loop_count = loop_count,
|
||||
.inst_group_count = igrp_count,
|
||||
.main_inst_group_count = main_count,
|
||||
.bitwise_inst_group_count = bitwise_count,
|
||||
.control_inst_group_count = control_count,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
enum pco_pck_format pco_pipe_to_pck_format(enum pipe_format format,
|
||||
bool *scale,
|
||||
bool *roundzero,
|
||||
bool *split)
|
||||
{
|
||||
enum pco_pck_format pck_format = ~0;
|
||||
*scale = false;
|
||||
*roundzero = false;
|
||||
*split = false;
|
||||
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_R8_UNORM:
|
||||
case PIPE_FORMAT_R8G8_UNORM:
|
||||
case PIPE_FORMAT_R8G8B8_UNORM:
|
||||
case PIPE_FORMAT_R8G8B8A8_UNORM:
|
||||
pck_format = PCO_PCK_FORMAT_U8888;
|
||||
*scale = true;
|
||||
break;
|
||||
|
||||
case PIPE_FORMAT_R8_SNORM:
|
||||
case PIPE_FORMAT_R8G8_SNORM:
|
||||
case PIPE_FORMAT_R8G8B8_SNORM:
|
||||
case PIPE_FORMAT_R8G8B8A8_SNORM:
|
||||
pck_format = PCO_PCK_FORMAT_S8888;
|
||||
*scale = true;
|
||||
break;
|
||||
|
||||
case PIPE_FORMAT_R11G11B10_FLOAT:
|
||||
pck_format = PCO_PCK_FORMAT_F111110;
|
||||
break;
|
||||
|
||||
/* TODO: better way to do the 1x2 component. */
|
||||
case PIPE_FORMAT_R10G10B10A2_UNORM:
|
||||
pck_format = PCO_PCK_FORMAT_U1010102;
|
||||
*scale = true;
|
||||
break;
|
||||
|
||||
/* TODO: better way to do the 1x2 component. */
|
||||
case PIPE_FORMAT_R10G10B10A2_SNORM:
|
||||
pck_format = PCO_PCK_FORMAT_S1010102;
|
||||
*scale = true;
|
||||
break;
|
||||
|
||||
case PIPE_FORMAT_R16_FLOAT:
|
||||
case PIPE_FORMAT_R16G16_FLOAT:
|
||||
case PIPE_FORMAT_R16G16B16_FLOAT:
|
||||
case PIPE_FORMAT_R16G16B16A16_FLOAT:
|
||||
pck_format = PCO_PCK_FORMAT_F16F16;
|
||||
*split = true;
|
||||
break;
|
||||
|
||||
case PIPE_FORMAT_R16_UNORM:
|
||||
case PIPE_FORMAT_R16G16_UNORM:
|
||||
case PIPE_FORMAT_R16G16B16_UNORM:
|
||||
case PIPE_FORMAT_R16G16B16A16_UNORM:
|
||||
pck_format = PCO_PCK_FORMAT_U1616;
|
||||
*scale = true;
|
||||
*split = true;
|
||||
break;
|
||||
|
||||
case PIPE_FORMAT_R16_SNORM:
|
||||
case PIPE_FORMAT_R16G16_SNORM:
|
||||
case PIPE_FORMAT_R16G16B16_SNORM:
|
||||
case PIPE_FORMAT_R16G16B16A16_SNORM:
|
||||
pck_format = PCO_PCK_FORMAT_S1616;
|
||||
*scale = true;
|
||||
*split = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return pck_format;
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright © 2024 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef PCO_H
|
||||
#define PCO_H
|
||||
|
||||
/**
|
||||
* \file pco.h
|
||||
*
|
||||
* \brief Main compiler interface header.
|
||||
*/
|
||||
|
||||
#include "compiler/nir/nir.h"
|
||||
|
||||
/* Defines. */
|
||||
#define PCO_REG_UNUSED (~0U)
|
||||
|
||||
/* Driver-specific forward-declarations. */
|
||||
struct pvr_device_info;
|
||||
struct pvr_device_runtime_info;
|
||||
|
||||
/* Compiler-specific forward-declarations. */
|
||||
typedef struct _pco_shader pco_shader;
|
||||
typedef struct _pco_ctx pco_ctx;
|
||||
typedef struct _pco_data pco_data;
|
||||
|
||||
pco_ctx *pco_ctx_create(const struct pvr_device_info *dev_info,
|
||||
const struct pvr_device_runtime_info *dev_runtime_info,
|
||||
void *mem_ctx);
|
||||
void pco_ctx_setup_usclib(pco_ctx *ctx, const void *data, unsigned size);
|
||||
void pco_ctx_update_dev_info(pco_ctx *ctx,
|
||||
const struct pvr_device_info *dev_info);
|
||||
const struct spirv_to_nir_options *pco_spirv_options(void);
|
||||
const nir_shader_compiler_options *pco_nir_options(void);
|
||||
|
||||
void pco_preprocess_nir(pco_ctx *ctx, nir_shader *nir);
|
||||
void pco_link_nir(pco_ctx *ctx,
|
||||
nir_shader *producer,
|
||||
nir_shader *consumer,
|
||||
pco_data *producer_data,
|
||||
pco_data *consumer_data);
|
||||
void pco_rev_link_nir(pco_ctx *ctx, nir_shader *producer, nir_shader *consumer);
|
||||
void pco_lower_nir(pco_ctx *ctx, nir_shader *nir, pco_data *data);
|
||||
void pco_postprocess_nir(pco_ctx *ctx, nir_shader *nir, pco_data *data);
|
||||
|
||||
pco_shader *
|
||||
pco_trans_nir(pco_ctx *ctx, nir_shader *nir, pco_data *data, void *mem_ctx);
|
||||
void pco_process_ir(pco_ctx *ctx, pco_shader *shader);
|
||||
void pco_encode_ir(pco_ctx *ctx, pco_shader *shader);
|
||||
|
||||
pco_data *pco_shader_data(pco_shader *shader);
|
||||
|
||||
unsigned pco_shader_binary_size(pco_shader *shader);
|
||||
const void *pco_shader_binary_data(pco_shader *shader);
|
||||
|
||||
void pco_validate_shader(pco_shader *shader, const char *when);
|
||||
|
||||
void pco_print_shader_stats(pco_shader *shader, FILE *fp);
|
||||
void pco_print_shader(pco_shader *shader, FILE *fp, const char *when);
|
||||
void pco_print_binary(pco_shader *shader, FILE *fp, const char *when);
|
||||
|
||||
#include "compiler/nir/nir_builder.h"
|
||||
|
||||
typedef struct _pco_smp_params {
|
||||
nir_def *tex_state;
|
||||
nir_def *smp_state;
|
||||
|
||||
nir_alu_type dest_type;
|
||||
|
||||
enum glsl_sampler_dim sampler_dim;
|
||||
|
||||
bool nncoords;
|
||||
nir_def *coords;
|
||||
nir_def *array_index;
|
||||
|
||||
nir_def *proj;
|
||||
|
||||
nir_def *lod_bias;
|
||||
nir_def *lod_replace;
|
||||
nir_def *lod_ddx;
|
||||
nir_def *lod_ddy;
|
||||
|
||||
nir_def *addr_lo;
|
||||
nir_def *addr_hi;
|
||||
|
||||
nir_def *offset;
|
||||
nir_def *ms_index;
|
||||
|
||||
nir_def *write_data;
|
||||
|
||||
bool sample_coeffs;
|
||||
bool sample_raw;
|
||||
unsigned sample_components;
|
||||
|
||||
bool int_mode;
|
||||
} pco_smp_params;
|
||||
nir_intrinsic_instr *pco_emit_nir_smp(nir_builder *b, pco_smp_params *params);
|
||||
|
||||
enum pco_pck_format pco_pipe_to_pck_format(enum pipe_format format,
|
||||
bool *scale,
|
||||
bool *roundzero,
|
||||
bool *split);
|
||||
#endif /* PCO_H */
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright © 2024 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file pco_binary.c
|
||||
*
|
||||
* \brief PCO binary-specific functions.
|
||||
*/
|
||||
|
||||
#include "pco.h"
|
||||
#include "pco_internal.h"
|
||||
#include "pco_isa.h"
|
||||
#include "pco_map.h"
|
||||
#include "util/u_dynarray.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* \brief Encodes instruction group alignment.
|
||||
*
|
||||
* \param[in,out] buf Binary buffer.
|
||||
* \param[in] igrp PCO instruction group.
|
||||
*/
|
||||
static inline unsigned pco_encode_align(struct util_dynarray *buf,
|
||||
pco_igrp *igrp)
|
||||
{
|
||||
unsigned bytes_encoded = 0;
|
||||
|
||||
if (igrp->enc.len.word_padding) {
|
||||
util_dynarray_append_typed(buf, uint8_t, 0xff);
|
||||
bytes_encoded += 1;
|
||||
}
|
||||
|
||||
if (igrp->enc.len.align_padding) {
|
||||
assert(!(igrp->enc.len.align_padding % 2));
|
||||
|
||||
unsigned align_words = igrp->enc.len.align_padding / 2;
|
||||
util_dynarray_append_typed(buf, uint8_t, 0xf0 | align_words);
|
||||
bytes_encoded += 1;
|
||||
|
||||
for (unsigned u = 0; u < igrp->enc.len.align_padding - 1; ++u) {
|
||||
util_dynarray_append_typed(buf, uint8_t, 0xff);
|
||||
bytes_encoded += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return bytes_encoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Encodes a PCO instruction group into binary.
|
||||
*
|
||||
* \param[in,out] buf Binary buffer.
|
||||
* \param[in] igrp PCO instruction group.
|
||||
* \return The number of bytes encoded.
|
||||
*/
|
||||
static unsigned pco_encode_igrp(struct util_dynarray *buf, pco_igrp *igrp)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
unsigned bytes_encoded = 0;
|
||||
|
||||
/* Header. */
|
||||
ptr = util_dynarray_grow(buf, uint8_t, igrp->enc.len.hdr);
|
||||
bytes_encoded += pco_igrp_hdr_map_encode(ptr, igrp);
|
||||
|
||||
/* Instructions. */
|
||||
pco_foreach_phase_in_igrp_rev (igrp, p) {
|
||||
ptr = util_dynarray_grow(buf, uint8_t, igrp->enc.len.instrs[p]);
|
||||
bytes_encoded += pco_instr_map_encode(ptr, igrp, p);
|
||||
}
|
||||
|
||||
/* I/O. */
|
||||
if (igrp->enc.len.lower_srcs) {
|
||||
ptr = util_dynarray_grow(buf, uint8_t, igrp->enc.len.lower_srcs);
|
||||
bytes_encoded += pco_srcs_map_encode(ptr, igrp, false);
|
||||
}
|
||||
|
||||
if (igrp->enc.len.upper_srcs) {
|
||||
ptr = util_dynarray_grow(buf, uint8_t, igrp->enc.len.upper_srcs);
|
||||
bytes_encoded += pco_srcs_map_encode(ptr, igrp, true);
|
||||
}
|
||||
|
||||
if (igrp->enc.len.iss) {
|
||||
ptr = util_dynarray_grow(buf, uint8_t, igrp->enc.len.iss);
|
||||
bytes_encoded += pco_iss_map_encode(ptr, igrp);
|
||||
}
|
||||
|
||||
if (igrp->enc.len.dests) {
|
||||
ptr = util_dynarray_grow(buf, uint8_t, igrp->enc.len.dests);
|
||||
bytes_encoded += pco_dests_map_encode(ptr, igrp);
|
||||
}
|
||||
|
||||
/* Word/alignment padding. */
|
||||
bytes_encoded += pco_encode_align(buf, igrp);
|
||||
|
||||
assert(bytes_encoded == igrp->enc.len.total);
|
||||
|
||||
return bytes_encoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Encodes a PCO shader into binary.
|
||||
*
|
||||
* \param[in] ctx PCO compiler context.
|
||||
* \param[in,out] shader PCO shader.
|
||||
*/
|
||||
void pco_encode_ir(pco_ctx *ctx, pco_shader *shader)
|
||||
{
|
||||
assert(shader->is_grouped);
|
||||
|
||||
util_dynarray_init(&shader->binary, shader);
|
||||
|
||||
unsigned bytes_encoded = 0;
|
||||
pco_foreach_func_in_shader (func, shader) {
|
||||
func->enc_offset = bytes_encoded;
|
||||
pco_foreach_block_in_func (block, func) {
|
||||
pco_foreach_igrp_in_block (igrp, block) {
|
||||
bytes_encoded += pco_encode_igrp(&shader->binary, igrp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pco_should_print_binary(shader))
|
||||
pco_print_binary(shader, stdout, "after encoding");
|
||||
|
||||
if (pco_should_print_stats(shader))
|
||||
pco_print_shader_stats(shader, stdout);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the size in bytes of a PCO shader binary.
|
||||
*
|
||||
* \param[in] shader PCO shader.
|
||||
* \return The size in bytes of the PCO shader binary.
|
||||
*/
|
||||
unsigned pco_shader_binary_size(pco_shader *shader)
|
||||
{
|
||||
if (!shader)
|
||||
return 0;
|
||||
|
||||
return shader->binary.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the PCO shader binary data.
|
||||
*
|
||||
* \param[in] shader PCO shader.
|
||||
* \return The PCO shader binary data.
|
||||
*/
|
||||
const void *pco_shader_binary_data(pco_shader *shader)
|
||||
{
|
||||
if (!shader)
|
||||
return NULL;
|
||||
return shader->binary.data;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright © 2025 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file pco_bool.c
|
||||
*
|
||||
* \brief PCO bool passes.
|
||||
*/
|
||||
|
||||
#include "pco.h"
|
||||
#include "pco_builder.h"
|
||||
#include "util/bitscan.h"
|
||||
#include "util/bitset.h"
|
||||
#include "util/macros.h"
|
||||
#include "util/ralloc.h"
|
||||
#include "util/u_dynarray.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
static bool lower_bools(pco_func *func)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
/* Update to 32-bit. */
|
||||
pco_foreach_instr_in_func (instr, func) {
|
||||
pco_foreach_instr_dest_vreg_ssa (pdest, instr) {
|
||||
if (pco_ref_get_bits(*pdest) != 1)
|
||||
continue;
|
||||
|
||||
*pdest = pco_ref_bits(*pdest, 32);
|
||||
|
||||
progress = true;
|
||||
}
|
||||
|
||||
pco_foreach_instr_src_vreg_ssa (psrc, instr) {
|
||||
if (pco_ref_get_bits(*psrc) != 1)
|
||||
continue;
|
||||
|
||||
*psrc = pco_ref_bits(*psrc, 32);
|
||||
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
|
||||
pco_foreach_ssa_bool_if_in_func (pif, func) {
|
||||
pif->cond = pco_ref_bits(pif->cond, 32);
|
||||
|
||||
progress = true;
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Bool lowering pass.
|
||||
*
|
||||
* \param[in,out] shader PCO shader.
|
||||
* \return True if the pass made progress.
|
||||
*/
|
||||
bool pco_bool(pco_shader *shader)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
pco_foreach_func_in_shader (func, shader) {
|
||||
progress |= lower_bools(func);
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
@@ -0,0 +1,473 @@
|
||||
/*
|
||||
* Copyright © 2024 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef PCO_BUILDER_H
|
||||
#define PCO_BUILDER_H
|
||||
|
||||
/**
|
||||
* \\file pco_builder.h
|
||||
*
|
||||
* \\brief PCO builder header.
|
||||
*/
|
||||
|
||||
#include "pco.h"
|
||||
#include "pco_internal.h"
|
||||
#include "util/list.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/** Cursor pointer. */
|
||||
enum pco_cursor_option {
|
||||
PCO_CURSOR_BEFORE_CF_NODE,
|
||||
PCO_CURSOR_AFTER_CF_NODE,
|
||||
|
||||
PCO_CURSOR_BEFORE_INSTR,
|
||||
PCO_CURSOR_AFTER_INSTR,
|
||||
|
||||
PCO_CURSOR_BEFORE_IGRP,
|
||||
PCO_CURSOR_AFTER_IGRP,
|
||||
};
|
||||
|
||||
/** Cursor for PCO instructions/groups and basic blocks. */
|
||||
typedef struct pco_cursor {
|
||||
enum pco_cursor_option option; /** Cursor pointer option. */
|
||||
union {
|
||||
pco_cf_node *cf_node;
|
||||
pco_instr *instr;
|
||||
pco_igrp *igrp;
|
||||
};
|
||||
} pco_cursor;
|
||||
|
||||
/** PCO builder context. */
|
||||
typedef struct pco_builder {
|
||||
pco_func *func; /** Target function. */
|
||||
pco_cursor cursor; /** Current position in the function. */
|
||||
} pco_builder;
|
||||
|
||||
/* Cursor position setters. */
|
||||
/**
|
||||
* \brief Returns a cursor set to before a cf node.
|
||||
*
|
||||
* \param[in] cf_node The cf node.
|
||||
* \return The cursor.
|
||||
*/
|
||||
static inline pco_cursor pco_cursor_before_cf_node(pco_cf_node *cf_node)
|
||||
{
|
||||
return (pco_cursor){
|
||||
.option = PCO_CURSOR_BEFORE_CF_NODE,
|
||||
.cf_node = cf_node,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns a cursor set to after a cf node.
|
||||
*
|
||||
* \param[in] cf_node The cf node.
|
||||
* \return The cursor.
|
||||
*/
|
||||
static inline pco_cursor pco_cursor_after_cf_node(pco_cf_node *cf_node)
|
||||
{
|
||||
return (pco_cursor){
|
||||
.option = PCO_CURSOR_AFTER_CF_NODE,
|
||||
.cf_node = cf_node,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns a cursor set to before a block.
|
||||
*
|
||||
* \param[in] block The block.
|
||||
* \return The cursor.
|
||||
*/
|
||||
static inline pco_cursor pco_cursor_before_block(pco_block *block)
|
||||
{
|
||||
return pco_cursor_before_cf_node(&block->cf_node);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns a cursor set to after a block.
|
||||
*
|
||||
* \param[in] block The block.
|
||||
* \return The cursor.
|
||||
*/
|
||||
static inline pco_cursor pco_cursor_after_block(pco_block *block)
|
||||
{
|
||||
return pco_cursor_after_cf_node(&block->cf_node);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns a cursor set to before a list.
|
||||
*
|
||||
* \param[in] list The list.
|
||||
* \return The cursor.
|
||||
*/
|
||||
static inline pco_cursor pco_cursor_before_list(struct list_head *list)
|
||||
{
|
||||
return pco_cursor_before_cf_node(pco_cf_node_head(list));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns a cursor set to after an exec_list.
|
||||
*
|
||||
* \param[in] list The list.
|
||||
* \return The list.
|
||||
*/
|
||||
static inline pco_cursor pco_cursor_after_list(struct list_head *list)
|
||||
{
|
||||
return pco_cursor_after_cf_node(pco_cf_node_tail(list));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns a cursor set to before an instruction.
|
||||
*
|
||||
* \param[in] instr The instruction.
|
||||
* \return The cursor.
|
||||
*/
|
||||
static inline pco_cursor pco_cursor_before_instr(pco_instr *instr)
|
||||
{
|
||||
return (pco_cursor){
|
||||
.option = PCO_CURSOR_BEFORE_INSTR,
|
||||
.instr = instr,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns a cursor set to after an instruction.
|
||||
*
|
||||
* \param[in] instr The instruction.
|
||||
* \return The cursor.
|
||||
*/
|
||||
static inline pco_cursor pco_cursor_after_instr(pco_instr *instr)
|
||||
{
|
||||
return (pco_cursor){
|
||||
.option = PCO_CURSOR_AFTER_INSTR,
|
||||
.instr = instr,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns a cursor set to before an instruction group.
|
||||
*
|
||||
* \param[in] igrp The instruction group.
|
||||
* \return The cursor.
|
||||
*/
|
||||
static inline pco_cursor pco_cursor_before_igrp(pco_igrp *igrp)
|
||||
{
|
||||
return (pco_cursor){
|
||||
.option = PCO_CURSOR_BEFORE_IGRP,
|
||||
.igrp = igrp,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns a cursor set to after an instruction group.
|
||||
*
|
||||
* \param[in] igrp The instruction group.
|
||||
* \return The cursor.
|
||||
*/
|
||||
static inline pco_cursor pco_cursor_after_igrp(pco_igrp *igrp)
|
||||
{
|
||||
return (pco_cursor){
|
||||
.option = PCO_CURSOR_AFTER_IGRP,
|
||||
.igrp = igrp,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns whether a cursor is set to before a construct.
|
||||
*
|
||||
* \param[in] cursor The cursor.
|
||||
* \return True if the cursor is set to before a construct.
|
||||
*/
|
||||
static inline bool pco_cursor_is_before(pco_cursor cursor)
|
||||
{
|
||||
return cursor.option == PCO_CURSOR_BEFORE_CF_NODE ||
|
||||
cursor.option == PCO_CURSOR_BEFORE_INSTR ||
|
||||
cursor.option == PCO_CURSOR_BEFORE_IGRP;
|
||||
}
|
||||
|
||||
/* Cursor get functions. */
|
||||
/**
|
||||
* \brief Returns the function being pointed to by the cursor.
|
||||
*
|
||||
* \param[in] cursor The cursor.
|
||||
* \return The function being pointed to.
|
||||
*/
|
||||
static inline pco_func *pco_cursor_func(pco_cursor cursor)
|
||||
{
|
||||
switch (cursor.option) {
|
||||
case PCO_CURSOR_BEFORE_CF_NODE:
|
||||
case PCO_CURSOR_AFTER_CF_NODE:
|
||||
switch (cursor.cf_node->type) {
|
||||
case PCO_CF_NODE_TYPE_BLOCK:
|
||||
return pco_cf_node_as_block(cursor.cf_node)->parent_func;
|
||||
|
||||
case PCO_CF_NODE_TYPE_IF:
|
||||
return pco_cf_node_as_if(cursor.cf_node)->parent_func;
|
||||
|
||||
case PCO_CF_NODE_TYPE_LOOP:
|
||||
return pco_cf_node_as_loop(cursor.cf_node)->parent_func;
|
||||
|
||||
case PCO_CF_NODE_TYPE_FUNC:
|
||||
return pco_cf_node_as_func(cursor.cf_node);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PCO_CURSOR_BEFORE_INSTR:
|
||||
case PCO_CURSOR_AFTER_INSTR:
|
||||
return cursor.instr->parent_func;
|
||||
|
||||
case PCO_CURSOR_BEFORE_IGRP:
|
||||
case PCO_CURSOR_AFTER_IGRP:
|
||||
return cursor.igrp->parent_func;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the cf node being pointed to by the cursor.
|
||||
*
|
||||
* \param[in] cursor The cursor.
|
||||
* \return The cf node being pointed to.
|
||||
*/
|
||||
static inline pco_cf_node *pco_cursor_cf_node(pco_cursor cursor)
|
||||
{
|
||||
switch (cursor.option) {
|
||||
case PCO_CURSOR_BEFORE_CF_NODE:
|
||||
case PCO_CURSOR_AFTER_CF_NODE:
|
||||
return cursor.cf_node;
|
||||
|
||||
case PCO_CURSOR_BEFORE_INSTR:
|
||||
case PCO_CURSOR_AFTER_INSTR:
|
||||
return &cursor.instr->parent_block->cf_node;
|
||||
|
||||
case PCO_CURSOR_BEFORE_IGRP:
|
||||
case PCO_CURSOR_AFTER_IGRP:
|
||||
return &cursor.igrp->parent_block->cf_node;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the block being pointed to by the cursor.
|
||||
*
|
||||
* \param[in] cursor The cursor.
|
||||
* \return The block being pointed to.
|
||||
*/
|
||||
static inline pco_block *pco_cursor_block(pco_cursor cursor)
|
||||
{
|
||||
switch (cursor.option) {
|
||||
case PCO_CURSOR_BEFORE_CF_NODE:
|
||||
case PCO_CURSOR_AFTER_CF_NODE:
|
||||
switch (cursor.cf_node->type) {
|
||||
case PCO_CF_NODE_TYPE_BLOCK:
|
||||
return pco_cf_node_as_block(cursor.cf_node);
|
||||
|
||||
/* TODO: other cf node types? */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PCO_CURSOR_BEFORE_INSTR:
|
||||
case PCO_CURSOR_AFTER_INSTR:
|
||||
return cursor.instr->parent_block;
|
||||
|
||||
case PCO_CURSOR_BEFORE_IGRP:
|
||||
case PCO_CURSOR_AFTER_IGRP:
|
||||
return cursor.igrp->parent_block;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the instruction being pointed to by the cursor.
|
||||
*
|
||||
* \param[in] cursor The cursor.
|
||||
* \return The instruction being pointed to.
|
||||
*/
|
||||
static inline pco_instr *pco_cursor_instr(pco_cursor cursor)
|
||||
{
|
||||
bool before = pco_cursor_is_before(cursor);
|
||||
|
||||
switch (cursor.option) {
|
||||
case PCO_CURSOR_BEFORE_CF_NODE:
|
||||
case PCO_CURSOR_AFTER_CF_NODE: {
|
||||
pco_block *block = NULL;
|
||||
|
||||
switch (cursor.cf_node->type) {
|
||||
case PCO_CF_NODE_TYPE_BLOCK:
|
||||
block = pco_cf_node_as_block(cursor.cf_node);
|
||||
return before ? pco_first_instr(block) : pco_last_instr(block);
|
||||
|
||||
/* TODO: other cf node types? */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PCO_CURSOR_BEFORE_INSTR:
|
||||
case PCO_CURSOR_AFTER_INSTR:
|
||||
return cursor.instr;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the instruction group being pointed to by the cursor.
|
||||
*
|
||||
* \param[in] cursor The cursor.
|
||||
* \return The instruction group being pointed to.
|
||||
*/
|
||||
static inline pco_igrp *pco_cursor_igrp(pco_cursor cursor)
|
||||
{
|
||||
bool before = pco_cursor_is_before(cursor);
|
||||
|
||||
switch (cursor.option) {
|
||||
case PCO_CURSOR_BEFORE_CF_NODE:
|
||||
case PCO_CURSOR_AFTER_CF_NODE: {
|
||||
pco_block *block = NULL;
|
||||
|
||||
switch (cursor.cf_node->type) {
|
||||
case PCO_CF_NODE_TYPE_BLOCK:
|
||||
block = pco_cf_node_as_block(cursor.cf_node);
|
||||
/* Special case: we're in pco_group_instrs and want to go from
|
||||
* the start.
|
||||
*/
|
||||
if (!block->parent_func->parent_shader->is_grouped)
|
||||
return NULL;
|
||||
return before ? pco_first_igrp(block) : pco_last_igrp(block);
|
||||
|
||||
/* TODO: other cf node types? */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PCO_CURSOR_BEFORE_IGRP:
|
||||
case PCO_CURSOR_AFTER_IGRP:
|
||||
return cursor.igrp;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
/* Builder functions. */
|
||||
/**
|
||||
* \brief Creates a builder.
|
||||
*
|
||||
* \param[in] func The function being targeted.
|
||||
* \param[in] cursor The cursor.
|
||||
* \return The builder.
|
||||
*/
|
||||
static pco_builder pco_builder_create(pco_func *func, pco_cursor cursor)
|
||||
{
|
||||
return (pco_builder){
|
||||
.func = func,
|
||||
.cursor = cursor,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Inserts a instruction at a position specified by the builder.
|
||||
*
|
||||
* \param[in] b The builder.
|
||||
* \param[in] instr The instruction.
|
||||
*/
|
||||
static inline void pco_builder_insert_instr(pco_builder *b, pco_instr *instr)
|
||||
{
|
||||
pco_block *block = pco_cursor_block(b->cursor);
|
||||
instr->parent_block = block;
|
||||
|
||||
pco_instr *cursor_instr = pco_cursor_instr(b->cursor);
|
||||
bool before = pco_cursor_is_before(b->cursor);
|
||||
|
||||
if (cursor_instr) {
|
||||
if (before)
|
||||
list_add(&instr->link, cursor_instr->link.prev);
|
||||
else
|
||||
list_add(&instr->link, &cursor_instr->link);
|
||||
} else {
|
||||
if (before)
|
||||
list_add(&instr->link, &block->instrs);
|
||||
else
|
||||
list_addtail(&instr->link, &block->instrs);
|
||||
}
|
||||
|
||||
b->cursor = pco_cursor_after_instr(instr);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Inserts a instruction group at a position specified by the builder.
|
||||
*
|
||||
* \param[in] b The builder.
|
||||
* \param[in] igrp The instruction group.
|
||||
*/
|
||||
static inline void pco_builder_insert_igrp(pco_builder *b, pco_igrp *igrp)
|
||||
{
|
||||
pco_block *block = pco_cursor_block(b->cursor);
|
||||
igrp->parent_block = block;
|
||||
|
||||
pco_igrp *cursor_igrp = pco_cursor_igrp(b->cursor);
|
||||
bool before = pco_cursor_is_before(b->cursor);
|
||||
|
||||
if (cursor_igrp) {
|
||||
if (before)
|
||||
list_add(&igrp->link, cursor_igrp->link.prev);
|
||||
else
|
||||
list_add(&igrp->link, &cursor_igrp->link);
|
||||
} else {
|
||||
if (before)
|
||||
list_add(&igrp->link, &block->instrs);
|
||||
else
|
||||
list_addtail(&igrp->link, &block->instrs);
|
||||
}
|
||||
|
||||
b->cursor = pco_cursor_after_igrp(igrp);
|
||||
}
|
||||
|
||||
/* Generated op building functions. */
|
||||
#include "pco_builder_ops.h"
|
||||
|
||||
/**
|
||||
* \brief Returns whether the instruction has the default execution condition.
|
||||
*
|
||||
* \param[in] instr The instruction.
|
||||
* \return True if the instruction has the default execution condition.
|
||||
*/
|
||||
static inline bool pco_instr_has_default_exec(pco_instr *instr)
|
||||
{
|
||||
if (!pco_instr_has_exec_cnd(instr))
|
||||
return true;
|
||||
|
||||
return pco_instr_get_exec_cnd(instr) == PCO_EXEC_CND_E1_ZX;
|
||||
}
|
||||
#endif /* PCO_BUILDER_H */
|
||||
@@ -0,0 +1,194 @@
|
||||
# Copyright © 2024 Imagination Technologies Ltd.
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
from mako.template import Template, exceptions
|
||||
from pco_ops import *
|
||||
|
||||
template = """/*
|
||||
* Copyright © 2024 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef PCO_BUILDER_OPS_H
|
||||
#define PCO_BUILDER_OPS_H
|
||||
|
||||
/**
|
||||
* \\file pco_builder_ops.h
|
||||
*
|
||||
* \\brief PCO op building functions.
|
||||
*/
|
||||
|
||||
#include "pco_internal.h"
|
||||
#include "pco_common.h"
|
||||
#include "pco_ops.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/** Ref mod info. */
|
||||
static inline
|
||||
bool pco_instr_dest_has_mod(const pco_instr *instr, unsigned dest, enum pco_ref_mod mod)
|
||||
{
|
||||
const struct pco_op_info *info = &pco_op_info[instr->op];
|
||||
if (info->num_dests == ~0)
|
||||
return false;
|
||||
|
||||
assert(dest < info->num_dests);
|
||||
assert(mod < _PCO_REF_MOD_COUNT);
|
||||
return (info->dest_mods[dest] & (1ULL << mod)) != 0;
|
||||
}
|
||||
|
||||
static inline
|
||||
bool pco_instr_src_has_mod(const pco_instr *instr, unsigned src, enum pco_ref_mod mod)
|
||||
{
|
||||
const struct pco_op_info *info = &pco_op_info[instr->op];
|
||||
if (info->num_srcs == ~0)
|
||||
return false;
|
||||
|
||||
assert(src < info->num_srcs);
|
||||
assert(mod < _PCO_REF_MOD_COUNT);
|
||||
return (info->src_mods[src] & (1ULL << mod)) != 0;
|
||||
}
|
||||
|
||||
% for ref_mod in ref_mods.values():
|
||||
static inline
|
||||
bool pco_instr_dest_has_${ref_mod.t.tname}(const pco_instr *instr, unsigned dest)
|
||||
{
|
||||
return pco_instr_dest_has_mod(instr, dest, ${ref_mod.cname});
|
||||
}
|
||||
|
||||
static inline
|
||||
bool pco_instr_src_has_${ref_mod.t.tname}(const pco_instr *instr, unsigned src)
|
||||
{
|
||||
return pco_instr_src_has_mod(instr, src, ${ref_mod.cname});
|
||||
}
|
||||
|
||||
% endfor
|
||||
/** Op mod getting/setting. */
|
||||
static inline
|
||||
bool pco_instr_has_mod(const pco_instr *instr, enum pco_op_mod mod)
|
||||
{
|
||||
assert(mod < _PCO_OP_MOD_COUNT);
|
||||
return (pco_op_info[instr->op].mods & (1ULL << mod)) != 0;
|
||||
}
|
||||
|
||||
static inline
|
||||
void pco_instr_set_mod(pco_instr *instr, enum pco_op_mod mod, uint32_t val)
|
||||
{
|
||||
assert(mod < _PCO_OP_MOD_COUNT);
|
||||
unsigned mod_index = pco_op_info[instr->op].mod_map[mod];
|
||||
assert(mod_index > 0);
|
||||
instr->mod[mod_index - 1] = val;
|
||||
}
|
||||
|
||||
static inline
|
||||
uint32_t pco_instr_get_mod(const pco_instr *instr, enum pco_op_mod mod)
|
||||
{
|
||||
assert(mod < _PCO_OP_MOD_COUNT);
|
||||
unsigned mod_index = pco_op_info[instr->op].mod_map[mod];
|
||||
assert(mod_index > 0);
|
||||
return instr->mod[mod_index - 1];
|
||||
}
|
||||
|
||||
static inline
|
||||
bool pco_instr_mod_is_set(const pco_instr *instr, enum pco_op_mod mod)
|
||||
{
|
||||
const struct pco_op_mod_info *info = &pco_op_mod_info[mod];
|
||||
return pco_instr_get_mod(instr, mod) != (info->nzdefault ? info->nzdefault : 0);
|
||||
}
|
||||
|
||||
% for op_mod in op_mods.values():
|
||||
static inline
|
||||
bool pco_instr_has_${op_mod.t.tname}(const pco_instr *instr)
|
||||
{
|
||||
return pco_instr_has_mod(instr, ${op_mod.cname});
|
||||
}
|
||||
|
||||
static inline
|
||||
void pco_instr_set_${op_mod.t.tname}(pco_instr *instr, ${op_mod.t.name} val)
|
||||
{
|
||||
return pco_instr_set_mod(instr, ${op_mod.cname}, val);
|
||||
}
|
||||
|
||||
static inline
|
||||
${op_mod.t.name} pco_instr_get_${op_mod.t.tname}(const pco_instr *instr)
|
||||
{
|
||||
return pco_instr_get_mod(instr, ${op_mod.cname});
|
||||
}
|
||||
|
||||
% endfor
|
||||
% for op in ops.values():
|
||||
% if bool(op.op_mods):
|
||||
struct ${op.bname}_mods {
|
||||
% for op_mod in op.op_mods:
|
||||
${op_mod.t.name} ${op_mod.t.tname};
|
||||
% endfor
|
||||
};
|
||||
|
||||
% endif
|
||||
#define ${op.bname}_(${op.builder_params[2]}${op.builder_params[4]}) _${op.bname}_(${op.builder_params[2]}${op.builder_params[5]})
|
||||
static
|
||||
pco_instr *_${op.bname}_(${op.builder_params[0]})
|
||||
{
|
||||
pco_instr *instr = pco_instr_create(func,
|
||||
${'num_dests' if op.num_dests == VARIABLE else op.num_dests},
|
||||
${'num_srcs' if op.num_srcs == VARIABLE else op.num_srcs});
|
||||
|
||||
instr->op = ${op.cname.upper()};
|
||||
|
||||
% if op.has_target_cf_node:
|
||||
instr->target_cf_node = target_cf_node;
|
||||
% endif
|
||||
% if op.num_dests == VARIABLE:
|
||||
for (unsigned d = 0; d < num_dests; ++d)
|
||||
instr->dest[d] = dest[d];
|
||||
% else:
|
||||
% for d in range(op.num_dests):
|
||||
instr->dest[${d}] = dest${d};
|
||||
% endfor
|
||||
% endif
|
||||
% if op.num_srcs == VARIABLE:
|
||||
for (unsigned s = 0; s < num_srcs; ++s)
|
||||
instr->src[s] = src[s];
|
||||
% else:
|
||||
% for s in range(op.num_srcs):
|
||||
instr->src[${s}] = src${s};
|
||||
% endfor
|
||||
% endif
|
||||
|
||||
% for op_mod in op.op_mods:
|
||||
% if op_mod.t.nzdefault is None:
|
||||
pco_instr_set_${op_mod.t.tname}(instr, mods.${op_mod.t.tname});
|
||||
% else:
|
||||
pco_instr_set_${op_mod.t.tname}(instr, !mods.${op_mod.t.tname} ? ${op_mod.t.nzdefault} : mods.${op_mod.t.tname});
|
||||
% endif
|
||||
% endfor
|
||||
|
||||
return instr;
|
||||
}
|
||||
|
||||
% if op.op_type != 'hw_direct':
|
||||
#define ${op.bname}(${op.builder_params[3]}${op.builder_params[4]}) _${op.bname}(${op.builder_params[3]}${op.builder_params[5]})
|
||||
static inline
|
||||
pco_instr *_${op.bname}(${op.builder_params[1]})
|
||||
{
|
||||
pco_func *func = pco_cursor_func(b->cursor);
|
||||
pco_instr *instr = _${op.bname}_(${op.builder_params[2]}${op.builder_params[6]});
|
||||
pco_builder_insert_instr(b, instr);
|
||||
return instr;
|
||||
}
|
||||
|
||||
% endif
|
||||
% endfor
|
||||
#endif /* PCO_BUILDER_OPS_H */"""
|
||||
|
||||
def main():
|
||||
try:
|
||||
print(Template(template).render(ops=ops, op_mods=op_mods, ref_mods=ref_mods, VARIABLE=VARIABLE))
|
||||
except:
|
||||
raise Exception(exceptions.text_error_template().render())
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,512 @@
|
||||
/*
|
||||
* Copyright © 2025 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file pco_cf.c
|
||||
*
|
||||
* \brief PCO control-flow passes.
|
||||
*/
|
||||
|
||||
#include "pco.h"
|
||||
#include "pco_builder.h"
|
||||
#include "util/bitscan.h"
|
||||
#include "util/bitset.h"
|
||||
#include "util/list.h"
|
||||
#include "util/macros.h"
|
||||
#include "util/ralloc.h"
|
||||
#include "util/u_dynarray.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
static pco_ref emc_ref(pco_func *func, pco_builder *b)
|
||||
{
|
||||
if (pco_ref_is_null(func->emc)) {
|
||||
/* Allocate and initialize the emc. */
|
||||
func->emc = pco_ref_new_vreg(func);
|
||||
|
||||
pco_cndst(b,
|
||||
pco_ref_pred(PCO_PRED_PE),
|
||||
func->emc,
|
||||
pco_zero,
|
||||
pco_ref_imm8(1),
|
||||
.exec_cnd = PCO_EXEC_CND_EX_ZX,
|
||||
.cnd = PCO_CND_ALWAYS);
|
||||
}
|
||||
|
||||
return func->emc;
|
||||
}
|
||||
|
||||
static inline pco_block *cf_section_create(pco_func *func,
|
||||
pco_cf_node *parent_cf_node,
|
||||
struct list_head *cf_node_list,
|
||||
enum pco_cf_node_flag flag)
|
||||
{
|
||||
assert(flag == PCO_CF_NODE_FLAG_PROLOGUE ||
|
||||
flag == PCO_CF_NODE_FLAG_INTERLOGUE ||
|
||||
flag == PCO_CF_NODE_FLAG_EPILOGUE);
|
||||
|
||||
pco_block *block = pco_block_create(func);
|
||||
block->cf_node.parent = parent_cf_node;
|
||||
block->cf_node.flag = flag;
|
||||
list_addtail(&block->cf_node.link, cf_node_list);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
static inline bool body_has_non_preds(struct list_head *body)
|
||||
{
|
||||
if (list_is_empty(body))
|
||||
return false;
|
||||
|
||||
pco_block *block = pco_cf_node_as_block(pco_cf_node_head(body));
|
||||
pco_instr *last_instr = NULL;
|
||||
pco_foreach_instr_in_block (instr, block) {
|
||||
/* Make sure there are no instructions that read/write predicates. */
|
||||
pco_foreach_instr_src (psrc, instr) {
|
||||
if (pco_ref_is_pred(*psrc))
|
||||
return true;
|
||||
}
|
||||
|
||||
pco_foreach_instr_dest (pdest, instr) {
|
||||
if (pco_ref_is_pred(*pdest))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!pco_instr_has_exec_cnd(instr))
|
||||
return true;
|
||||
|
||||
if (!pco_instr_has_default_exec(instr))
|
||||
return true;
|
||||
|
||||
last_instr = instr;
|
||||
}
|
||||
|
||||
assert(last_instr);
|
||||
return last_instr->op == PCO_OP_BR;
|
||||
}
|
||||
|
||||
static inline bool can_pred_exec(pco_if *pif)
|
||||
{
|
||||
if (PCO_DEBUG(NO_PRED_CF))
|
||||
return false;
|
||||
|
||||
/* Skip if there is any nesting. */
|
||||
if (list_length(&pif->then_body) > 1 || list_length(&pif->else_body) > 1)
|
||||
return false;
|
||||
|
||||
/* Skip if then/else blocks end with a branch, or contain non-predicatable
|
||||
* instructions.
|
||||
* Note: WDFs can't be predicated and won't be inserted until the scheduling
|
||||
* pass which comes after this one, but we don't have to worry about it as if
|
||||
* there are no outstanding data fences it'll simply NOP.
|
||||
*/
|
||||
if (body_has_non_preds(&pif->then_body) ||
|
||||
body_has_non_preds(&pif->else_body))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void set_body_exec_cnd(struct list_head *body,
|
||||
enum pco_exec_cnd exec_cnd)
|
||||
{
|
||||
assert(!list_is_empty(body));
|
||||
|
||||
pco_block *block = pco_cf_node_as_block(pco_cf_node_head(body));
|
||||
pco_foreach_instr_in_block (instr, block) {
|
||||
pco_instr_set_exec_cnd(instr, exec_cnd);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
lower_if_pred_exec(pco_if *pif, pco_func *func, bool has_else, bool invert_cond)
|
||||
{
|
||||
pco_block *prologue = cf_section_create(func,
|
||||
&pif->cf_node,
|
||||
&pif->prologue,
|
||||
PCO_CF_NODE_FLAG_PROLOGUE);
|
||||
|
||||
/* Setup the prologue. */
|
||||
pco_builder b = pco_builder_create(func, pco_cursor_after_block(prologue));
|
||||
|
||||
/* TODO: see if the cond producer can set p0 directly. */
|
||||
pco_tstz(&b,
|
||||
pco_ref_null(),
|
||||
pco_ref_pred(PCO_PRED_P0),
|
||||
pif->cond,
|
||||
.tst_type_main = PCO_TST_TYPE_MAIN_U32);
|
||||
|
||||
set_body_exec_cnd(&pif->then_body,
|
||||
invert_cond ? PCO_EXEC_CND_E1_Z1 : PCO_EXEC_CND_E1_Z0);
|
||||
|
||||
if (has_else) {
|
||||
set_body_exec_cnd(&pif->else_body,
|
||||
invert_cond ? PCO_EXEC_CND_E1_Z0 : PCO_EXEC_CND_E1_Z1);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
lower_if_cond_exec(pco_if *pif, pco_func *func, bool has_else, bool invert_cond)
|
||||
{
|
||||
pco_block *prologue = cf_section_create(func,
|
||||
&pif->cf_node,
|
||||
&pif->prologue,
|
||||
PCO_CF_NODE_FLAG_PROLOGUE);
|
||||
|
||||
pco_block *interlogue = has_else
|
||||
? cf_section_create(func,
|
||||
&pif->cf_node,
|
||||
&pif->interlogue,
|
||||
PCO_CF_NODE_FLAG_INTERLOGUE)
|
||||
: NULL;
|
||||
|
||||
pco_block *epilogue = cf_section_create(func,
|
||||
&pif->cf_node,
|
||||
&pif->epilogue,
|
||||
PCO_CF_NODE_FLAG_EPILOGUE);
|
||||
|
||||
/* Setup the prologue. */
|
||||
pco_builder b = pco_builder_create(func, pco_cursor_after_block(prologue));
|
||||
pco_ref emc = emc_ref(func, &b);
|
||||
|
||||
/* TODO: see if the cond producer can set p0 directly. */
|
||||
pco_tstz(&b,
|
||||
pco_ref_null(),
|
||||
pco_ref_pred(PCO_PRED_P0),
|
||||
pif->cond,
|
||||
.tst_type_main = PCO_TST_TYPE_MAIN_U32);
|
||||
|
||||
pco_cndst(&b,
|
||||
pco_ref_pred(PCO_PRED_PE),
|
||||
emc,
|
||||
emc,
|
||||
pco_ref_imm8(1),
|
||||
.exec_cnd = PCO_EXEC_CND_EX_ZX,
|
||||
.cnd = invert_cond ? PCO_CND_P0_TRUE : PCO_CND_P0_FALSE);
|
||||
|
||||
pco_br(&b,
|
||||
has_else ? &interlogue->cf_node : &epilogue->cf_node,
|
||||
.branch_cnd = PCO_BRANCH_CND_ALLINST);
|
||||
|
||||
/* Setup the interlogue (if needed). */
|
||||
if (has_else) {
|
||||
b.cursor = pco_cursor_after_block(interlogue);
|
||||
|
||||
pco_cndef(&b,
|
||||
pco_ref_pred(PCO_PRED_PE),
|
||||
emc,
|
||||
emc,
|
||||
pco_ref_imm8(1),
|
||||
.exec_cnd = PCO_EXEC_CND_EX_ZX,
|
||||
.cnd = PCO_CND_ALWAYS);
|
||||
|
||||
pco_br(&b, &epilogue->cf_node, .branch_cnd = PCO_BRANCH_CND_ALLINST);
|
||||
}
|
||||
|
||||
/* Setup the epilogue. */
|
||||
b.cursor = pco_cursor_after_block(epilogue);
|
||||
|
||||
pco_cndend(&b,
|
||||
pco_ref_pred(PCO_PRED_PE),
|
||||
emc,
|
||||
emc,
|
||||
pco_ref_imm8(1),
|
||||
.exec_cnd = PCO_EXEC_CND_EX_ZX);
|
||||
}
|
||||
|
||||
static inline void lower_if(pco_if *pif, pco_func *func)
|
||||
{
|
||||
assert(!pco_ref_is_null(pif->cond));
|
||||
assert(list_is_empty(&pif->prologue));
|
||||
assert(list_is_empty(&pif->interlogue));
|
||||
assert(list_is_empty(&pif->epilogue));
|
||||
|
||||
bool has_then = !list_is_empty(&pif->then_body);
|
||||
bool has_else = !list_is_empty(&pif->else_body);
|
||||
assert(has_then || has_else);
|
||||
|
||||
/* If we only have an else body, invert the condition and bodies. */
|
||||
bool invert_cond = false;
|
||||
if (!has_then && has_else) {
|
||||
struct list_head temp;
|
||||
memcpy(&temp, &pif->then_body, sizeof(pif->then_body));
|
||||
memcpy(&pif->then_body, &pif->else_body, sizeof(pif->else_body));
|
||||
memcpy(&pif->else_body, &pif->then_body, sizeof(pif->then_body));
|
||||
invert_cond = true;
|
||||
|
||||
has_then = true;
|
||||
has_else = false;
|
||||
}
|
||||
|
||||
assert(has_then);
|
||||
|
||||
if (pif->pred_exec)
|
||||
lower_if_pred_exec(pif, func, has_else, invert_cond);
|
||||
else
|
||||
lower_if_cond_exec(pif, func, has_else, invert_cond);
|
||||
|
||||
pif->cond = pco_ref_null();
|
||||
}
|
||||
|
||||
static inline void lower_loop(pco_loop *loop, pco_func *func)
|
||||
{
|
||||
assert(list_is_empty(&loop->prologue));
|
||||
assert(list_is_empty(&loop->interlogue));
|
||||
assert(list_is_empty(&loop->epilogue));
|
||||
|
||||
pco_block *prologue = cf_section_create(func,
|
||||
&loop->cf_node,
|
||||
&loop->prologue,
|
||||
PCO_CF_NODE_FLAG_PROLOGUE);
|
||||
|
||||
pco_block *interlogue = cf_section_create(func,
|
||||
&loop->cf_node,
|
||||
&loop->interlogue,
|
||||
PCO_CF_NODE_FLAG_INTERLOGUE);
|
||||
|
||||
pco_block *epilogue = cf_section_create(func,
|
||||
&loop->cf_node,
|
||||
&loop->epilogue,
|
||||
PCO_CF_NODE_FLAG_EPILOGUE);
|
||||
|
||||
/* Setup the prologue. */
|
||||
pco_builder b = pco_builder_create(func, pco_cursor_after_block(prologue));
|
||||
pco_ref emc = emc_ref(func, &b);
|
||||
|
||||
pco_cndst(&b,
|
||||
pco_ref_pred(PCO_PRED_PE),
|
||||
emc,
|
||||
emc,
|
||||
pco_ref_imm8(2), /* TODO: make this a define */
|
||||
.exec_cnd = PCO_EXEC_CND_EX_ZX,
|
||||
.cnd = PCO_CND_ALWAYS);
|
||||
|
||||
pco_br(&b, &epilogue->cf_node, .branch_cnd = PCO_BRANCH_CND_ALLINST);
|
||||
|
||||
/* Setup the interlogue. */
|
||||
b.cursor = pco_cursor_after_block(interlogue);
|
||||
|
||||
pco_cndend(&b,
|
||||
pco_ref_pred(PCO_PRED_PE),
|
||||
emc,
|
||||
emc,
|
||||
pco_ref_imm8(1), /* TODO: make this a define */
|
||||
.exec_cnd = PCO_EXEC_CND_EX_ZX);
|
||||
|
||||
pco_cndst(&b,
|
||||
pco_ref_pred(PCO_PRED_PE),
|
||||
emc,
|
||||
emc,
|
||||
pco_ref_imm8(1), /* TODO: make this a define */
|
||||
.exec_cnd = PCO_EXEC_CND_EX_ZX,
|
||||
.cnd = PCO_CND_ALWAYS);
|
||||
|
||||
/* Setup the epilogue. */
|
||||
b.cursor = pco_cursor_after_block(epilogue);
|
||||
|
||||
pco_cndlt(&b,
|
||||
pco_ref_pred(PCO_PRED_PE),
|
||||
emc,
|
||||
pco_ref_pred(PCO_PRED_P0),
|
||||
emc,
|
||||
pco_ref_imm8(2), /* TODO: make this a define */
|
||||
.exec_cnd = PCO_EXEC_CND_EX_ZX,
|
||||
.cnd = PCO_CND_ALWAYS);
|
||||
|
||||
pco_br(&b,
|
||||
pco_cf_node_head(&loop->body),
|
||||
.exec_cnd = PCO_EXEC_CND_E1_Z1,
|
||||
.branch_cnd = PCO_BRANCH_CND_EXEC_COND);
|
||||
}
|
||||
|
||||
static inline void lower_break_continue(pco_instr *instr,
|
||||
pco_func *func,
|
||||
pco_if *pif,
|
||||
pco_loop *loop,
|
||||
unsigned loop_nestings,
|
||||
bool is_continue)
|
||||
{
|
||||
pco_builder b = pco_builder_create(func, pco_cursor_before_instr(instr));
|
||||
pco_ref emc = emc_ref(func, &b);
|
||||
enum pco_exec_cnd exec_cnd = pco_instr_get_exec_cnd(instr);
|
||||
|
||||
pco_ref val = pco_ref_new_ssa32(func);
|
||||
pco_movi32(&b,
|
||||
val,
|
||||
pco_ref_imm32(loop_nestings + (is_continue ? 1 : 2)),
|
||||
.exec_cnd = exec_cnd);
|
||||
|
||||
enum pco_cnd cnd;
|
||||
switch (exec_cnd) {
|
||||
case PCO_CC_E1_ZX:
|
||||
assert(!pif || !pif->pred_exec);
|
||||
cnd = PCO_CND_ALWAYS;
|
||||
break;
|
||||
|
||||
case PCO_CC_E1_Z1:
|
||||
assert(!pif || pif->pred_exec);
|
||||
cnd = PCO_CND_P0_TRUE;
|
||||
break;
|
||||
|
||||
case PCO_CC_E1_Z0:
|
||||
assert(!pif || pif->pred_exec);
|
||||
cnd = PCO_CND_P0_FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
pco_cndsm(&b,
|
||||
pco_ref_pred(PCO_PRED_PE),
|
||||
emc,
|
||||
emc,
|
||||
val,
|
||||
.exec_cnd = PCO_EXEC_CND_EX_ZX,
|
||||
.cnd = cnd);
|
||||
|
||||
pco_instr_delete(instr);
|
||||
}
|
||||
|
||||
static inline bool pco_lower_cf(pco_func *func)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
void *mem_ctx = ralloc_context(NULL);
|
||||
unsigned loop_nestings = 0;
|
||||
struct util_dynarray loop_nestings_stack;
|
||||
struct util_dynarray pif_stack;
|
||||
struct util_dynarray loop_stack;
|
||||
|
||||
util_dynarray_init(&loop_nestings_stack, mem_ctx);
|
||||
util_dynarray_init(&pif_stack, mem_ctx);
|
||||
util_dynarray_init(&loop_stack, mem_ctx);
|
||||
|
||||
pco_foreach_cf_node_in_func_structured (cf_node, cf_node_completed, func) {
|
||||
/* Handle the end of an if/loop. */
|
||||
if (cf_node_completed) {
|
||||
switch (cf_node_completed->type) {
|
||||
case PCO_CF_NODE_TYPE_IF: {
|
||||
pco_if *pif = pco_cf_node_as_if(cf_node_completed);
|
||||
|
||||
ASSERTED pco_if *last_pif = util_dynarray_pop(&pif_stack, pco_if *);
|
||||
assert(pif == last_pif);
|
||||
|
||||
if (!pif->pred_exec)
|
||||
--loop_nestings;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PCO_CF_NODE_TYPE_LOOP: {
|
||||
ASSERTED pco_loop *loop = pco_cf_node_as_loop(cf_node_completed);
|
||||
ASSERTED pco_loop *last_loop =
|
||||
util_dynarray_pop(&loop_stack, pco_loop *);
|
||||
assert(loop == last_loop);
|
||||
|
||||
assert(loop_nestings == 0);
|
||||
loop_nestings = util_dynarray_pop(&loop_nestings_stack, unsigned);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle the start of an if/loop, or lower break/continue for blocks. */
|
||||
switch (cf_node->type) {
|
||||
case PCO_CF_NODE_TYPE_IF: {
|
||||
pco_if *pif = pco_cf_node_as_if(cf_node);
|
||||
pif->pred_exec = can_pred_exec(pif);
|
||||
util_dynarray_append(&pif_stack, pif);
|
||||
|
||||
if (!pif->pred_exec)
|
||||
++loop_nestings;
|
||||
|
||||
lower_if(pif, func);
|
||||
progress = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PCO_CF_NODE_TYPE_LOOP: {
|
||||
util_dynarray_append(&loop_nestings_stack, loop_nestings);
|
||||
loop_nestings = 0;
|
||||
|
||||
pco_loop *loop = pco_cf_node_as_loop(cf_node);
|
||||
util_dynarray_append(&loop_stack, loop);
|
||||
|
||||
lower_loop(loop, func);
|
||||
progress = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PCO_CF_NODE_TYPE_BLOCK: {
|
||||
pco_block *block = pco_cf_node_as_block(cf_node);
|
||||
pco_foreach_instr_in_block_safe (instr, block) {
|
||||
if (instr->op != PCO_OP_BREAK && instr->op != PCO_OP_CONTINUE)
|
||||
continue;
|
||||
|
||||
/* This has to be the last instruction in the block. */
|
||||
assert(instr == pco_last_instr(block));
|
||||
|
||||
pco_if *current_pif = NULL;
|
||||
if (instr->parent_block->cf_node.parent->type ==
|
||||
PCO_CF_NODE_TYPE_IF) {
|
||||
current_pif = util_dynarray_top(&pif_stack, pco_if *);
|
||||
assert(current_pif ==
|
||||
pco_cf_node_as_if(instr->parent_block->cf_node.parent));
|
||||
}
|
||||
|
||||
pco_loop *current_loop = util_dynarray_top(&loop_stack, pco_loop *);
|
||||
|
||||
lower_break_continue(instr,
|
||||
func,
|
||||
current_pif,
|
||||
current_loop,
|
||||
loop_nestings,
|
||||
instr->op == PCO_OP_CONTINUE);
|
||||
|
||||
progress = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(!util_dynarray_num_elements(&loop_stack, pco_loop *));
|
||||
assert(!util_dynarray_num_elements(&pif_stack, pco_if *));
|
||||
assert(!util_dynarray_num_elements(&loop_nestings_stack, unsigned));
|
||||
assert(loop_nestings == 0);
|
||||
|
||||
ralloc_free(mem_ctx);
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Control-flow pass.
|
||||
*
|
||||
* \param[in,out] shader PCO shader.
|
||||
* \return True if the pass made progress.
|
||||
*/
|
||||
bool pco_cf(pco_shader *shader)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
pco_foreach_func_in_shader (func, shader) {
|
||||
progress |= pco_lower_cf(func);
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
# Copyright © 2024 Imagination Technologies Ltd.
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
from mako.template import Template, exceptions
|
||||
from pco_pygen_common import *
|
||||
from pco_ops import *
|
||||
from pco_isa import *
|
||||
from pco_map import *
|
||||
|
||||
template = """/*
|
||||
* Copyright © 2024 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef PCO_COMMON_H
|
||||
#define PCO_COMMON_H
|
||||
|
||||
/**
|
||||
* \\file pco_common.h
|
||||
*
|
||||
* \\brief PCO common definitions.
|
||||
*/
|
||||
|
||||
#include "util/macros.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef __OPENCL_VERSION__
|
||||
#define __constant
|
||||
#endif
|
||||
|
||||
/** Enums. */
|
||||
% for enum in [enum for enum in enums.values() if enum.parent is None]:
|
||||
#define _${enum.name.upper()}_COUNT ${enum.unique_count}U
|
||||
enum ${enum.name} {
|
||||
% for elem in enum.elems.values():
|
||||
${elem.cname} = ${hex(elem.value) if enum.is_bitset else elem.value},
|
||||
% endfor
|
||||
};
|
||||
|
||||
static inline
|
||||
__constant const char *${enum.name}_str(uint64_t val) {
|
||||
switch (val) {
|
||||
% for elem in enum.elems.values():
|
||||
% if elem.string is not None:
|
||||
case ${elem.cname}:
|
||||
return "${elem.string}";
|
||||
% endif
|
||||
% endfor
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
% endfor
|
||||
/** Enum validation. */
|
||||
% for enum in enums.values():
|
||||
static bool ${enum.name}_valid(uint64_t val)
|
||||
{
|
||||
% if enum.is_bitset:
|
||||
return !(val & ~(${enum.valid}ULL));
|
||||
% else:
|
||||
return ${' || '.join([f'val == {val}' for val in enum.valid])};
|
||||
% endif
|
||||
}
|
||||
|
||||
% endfor
|
||||
/** Bit set variants. */
|
||||
% for bit_set in bit_sets.values():
|
||||
#define _${bit_set.name.upper()}_VARIANT_COUNT ${len(bit_set.variants) + 1}U
|
||||
enum ${bit_set.name}_variant {
|
||||
${bit_set.name.upper()}_NONE,
|
||||
% for variant in bit_set.variants:
|
||||
${variant.cname},
|
||||
% endfor
|
||||
};
|
||||
|
||||
% endfor
|
||||
#endif /* PCO_COMMON_H */"""
|
||||
|
||||
def main():
|
||||
try:
|
||||
print(Template(template).render(enums=enums, bit_sets=bit_sets))
|
||||
except:
|
||||
raise Exception(exceptions.text_error_template().render())
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright © 2024 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file pco_const_imms.c
|
||||
*
|
||||
* \brief PCO constant immediates lowering pass.
|
||||
*/
|
||||
|
||||
#include "pco.h"
|
||||
#include "pco_builder.h"
|
||||
#include "pco_internal.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** Mapping of constant register values and their indices. */
|
||||
struct const_reg_def {
|
||||
uint32_t val;
|
||||
uint8_t idx;
|
||||
bool flr : 1;
|
||||
bool neg : 1;
|
||||
};
|
||||
|
||||
/** Constant register values (sorted for bsearch). */
|
||||
static const struct const_reg_def const_reg_defs[] = {
|
||||
{ 0x00000000, 0, false, false }, /* */
|
||||
{ 0x00000001, 1, false, false }, /* */
|
||||
{ 0x00000002, 2, false, false }, /* */
|
||||
{ 0x00000003, 3, false, false }, /* */
|
||||
{ 0x00000004, 4, false, false }, /* */
|
||||
{ 0x00000005, 5, false, false }, /* */
|
||||
{ 0x00000006, 6, false, false }, /* */
|
||||
{ 0x00000007, 7, false, false }, /* */
|
||||
{ 0x00000008, 8, false, false }, /* */
|
||||
{ 0x00000009, 9, false, false }, /* */
|
||||
{ 0x0000000a, 10, false, false }, /* */
|
||||
{ 0x0000000b, 11, false, false }, /* */
|
||||
{ 0x0000000c, 12, false, false }, /* */
|
||||
{ 0x0000000d, 13, false, false }, /* */
|
||||
{ 0x0000000e, 14, false, false }, /* */
|
||||
{ 0x0000000f, 15, false, false }, /* */
|
||||
{ 0x00000010, 16, false, false }, /* */
|
||||
{ 0x00000011, 17, false, false }, /* */
|
||||
{ 0x00000012, 18, false, false }, /* */
|
||||
{ 0x00000013, 19, false, false }, /* */
|
||||
{ 0x00000014, 20, false, false }, /* */
|
||||
{ 0x00000015, 21, false, false }, /* */
|
||||
{ 0x00000016, 22, false, false }, /* */
|
||||
{ 0x00000017, 23, false, false }, /* */
|
||||
{ 0x00000018, 24, false, false }, /* */
|
||||
{ 0x00000019, 25, false, false }, /* */
|
||||
{ 0x0000001a, 26, false, false }, /* */
|
||||
{ 0x0000001b, 27, false, false }, /* */
|
||||
{ 0x0000001c, 28, false, false }, /* */
|
||||
{ 0x0000001d, 29, false, false }, /* */
|
||||
{ 0x0000001e, 30, false, false }, /* */
|
||||
{ 0x0000001f, 31, false, false }, /* */
|
||||
{ 0x0000007f, 147, false, false }, /* */
|
||||
{ 0x37800000, 134, false, false }, /* */
|
||||
{ 0x38000000, 135, false, false }, /* */
|
||||
{ 0x38800000, 88, false, false }, /* */
|
||||
{ 0x39000000, 87, false, false }, /* */
|
||||
{ 0x39800000, 86, false, false }, /* */
|
||||
{ 0x3a000000, 85, false, false }, /* */
|
||||
{ 0x3a800000, 84, false, false }, /* */
|
||||
{ 0x3b000000, 83, false, false }, /* */
|
||||
{ 0x3b4d2e1c, 136, false, false }, /* */
|
||||
{ 0x3b800000, 82, false, false }, /* */
|
||||
{ 0x3c000000, 81, false, false }, /* */
|
||||
{ 0x3c800000, 80, false, false }, /* */
|
||||
{ 0x3d000000, 79, false, false }, /* */
|
||||
{ 0x3d25aee6, 156, false, false }, /* */
|
||||
{ 0x3d6147ae, 140, false, false }, /* */
|
||||
{ 0x3d800000, 78, false, false }, /* */
|
||||
{ 0x3d9e8391, 157, false, false }, /* */
|
||||
{ 0x3e000000, 77, false, false }, /* */
|
||||
{ 0x3e2aaaab, 153, false, false }, /* */
|
||||
{ 0x3e800000, 76, false, false }, /* */
|
||||
{ 0x3e9a209b, 145, false, false }, /* */
|
||||
{ 0x3ea2f983, 128, false, false }, /* */
|
||||
{ 0x3eaaaaab, 152, false, false }, /* */
|
||||
{ 0x3ebc5ab2, 90, false, false }, /* */
|
||||
{ 0x3ed55555, 138, false, false }, /* */
|
||||
{ 0x3f000000, 75, false, false }, /* */
|
||||
{ 0x3f22f983, 129, false, false }, /* */
|
||||
{ 0x3f317218, 146, false, false }, /* */
|
||||
{ 0x3f3504f3, 92, false, false }, /* */
|
||||
{ 0x3f490fdb, 93, false, false }, /* */
|
||||
{ 0x3f72a76f, 158, false, false }, /* */
|
||||
{ 0x3f800000, 64, false, false }, /* */
|
||||
{ 0x3f860a92, 151, false, false }, /* */
|
||||
{ 0x3f870a3d, 139, false, false }, /* */
|
||||
{ 0x3fa2f983, 130, false, false }, /* */
|
||||
{ 0x3fb504f3, 91, false, false }, /* */
|
||||
{ 0x3fb8aa3b, 155, false, false }, /* */
|
||||
{ 0x3fc90fdb, 94, false, false }, /* */
|
||||
{ 0x40000000, 65, false, false }, /* */
|
||||
{ 0x4019999a, 159, false, false }, /* */
|
||||
{ 0x402df854, 89, false, false }, /* */
|
||||
{ 0x40490fdb, 95, false, false }, /* */
|
||||
{ 0x40549a78, 154, false, false }, /* */
|
||||
{ 0x40800000, 66, false, false }, /* */
|
||||
{ 0x40c90fdb, 131, false, false }, /* */
|
||||
{ 0x41000000, 67, false, false }, /* */
|
||||
{ 0x41490fdb, 132, false, false }, /* */
|
||||
{ 0x414eb852, 137, false, false }, /* */
|
||||
{ 0x41800000, 68, false, false }, /* */
|
||||
{ 0x41c90fdb, 133, false, false }, /* */
|
||||
{ 0x42000000, 69, false, false }, /* */
|
||||
{ 0x42800000, 70, false, false }, /* */
|
||||
{ 0x43000000, 71, false, false }, /* */
|
||||
{ 0x43800000, 72, false, false }, /* */
|
||||
{ 0x44000000, 73, false, false }, /* */
|
||||
{ 0x44800000, 74, false, false }, /* */
|
||||
{ 0x4b000000, 149, false, false }, /* */
|
||||
{ 0x4b800000, 150, false, false }, /* */
|
||||
{ 0x7f7fffff, 148, false, false }, /* */
|
||||
{ 0x7f800000, 142, false, false }, /* */
|
||||
{ 0x7fff7fff, 144, false, false }, /* */
|
||||
{ 0x80000000, 141, false, false }, /* */
|
||||
{ 0xffffffff, 143, false, false }, /* */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Comparison function for bsearch() to support rogue_const_reg_def.
|
||||
*
|
||||
* \param[in] lhs The left hand side of the comparison.
|
||||
* \param[in] rhs The right hand side of the comparison.
|
||||
* \return 0 if (lhs == rhs), -1 if (lhs < rhs), 1 if (lhs > rhs).
|
||||
*/
|
||||
static int constreg_cmp(const void *lhs, const void *rhs)
|
||||
{
|
||||
const struct const_reg_def *l = lhs;
|
||||
const struct const_reg_def *r = rhs;
|
||||
|
||||
if (l->val < r->val)
|
||||
return -1;
|
||||
else if (l->val > r->val)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Looks up an immediate in constant registers.
|
||||
*
|
||||
* \param[in] imm The immediate to lookup.
|
||||
* \return A pointer to the constant register definition,
|
||||
* or NULL if no constant register was found.
|
||||
*/
|
||||
inline static const struct const_reg_def *constreg_lookup(uint32_t imm)
|
||||
{
|
||||
return bsearch(&(struct const_reg_def){ .val = imm },
|
||||
const_reg_defs,
|
||||
ARRAY_SIZE(const_reg_defs),
|
||||
sizeof(*const_reg_defs),
|
||||
constreg_cmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Converts immediates into constant register lookups where possible.
|
||||
*
|
||||
* \param[in,out] shader PCO shader.
|
||||
* \return True if the pass made progress.
|
||||
*/
|
||||
bool pco_const_imms(pco_shader *shader)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
pco_foreach_func_in_shader (func, shader) {
|
||||
pco_foreach_instr_in_func_safe (instr, func) {
|
||||
if (instr->op != PCO_OP_MOVI32)
|
||||
continue;
|
||||
|
||||
const struct const_reg_def *const_reg_def =
|
||||
constreg_lookup(pco_ref_get_imm(instr->src[0]));
|
||||
|
||||
if (!const_reg_def)
|
||||
continue;
|
||||
|
||||
pco_builder b =
|
||||
pco_builder_create(func, pco_cursor_before_instr(instr));
|
||||
|
||||
pco_ref dest = instr->dest[0];
|
||||
pco_ref const_reg =
|
||||
pco_ref_hwreg(const_reg_def->idx, PCO_REG_CLASS_CONST);
|
||||
|
||||
if (!const_reg_def->flr && !const_reg_def->neg) {
|
||||
pco_mov(&b, dest, const_reg);
|
||||
} else if (!const_reg_def->flr && const_reg_def->neg) {
|
||||
pco_fneg(&b, dest, const_reg);
|
||||
} else if (const_reg_def->flr && !const_reg_def->neg) {
|
||||
pco_fflr(&b, dest, const_reg);
|
||||
} else {
|
||||
/* TODO: use floor and neg mods when support for > 1 is added. */
|
||||
const_reg = pco_ref_flr(const_reg);
|
||||
const_reg = pco_ref_neg(const_reg);
|
||||
|
||||
pco_fadd(&b, dest, const_reg, pco_zero);
|
||||
}
|
||||
|
||||
pco_instr_delete(instr);
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Copyright © 2024 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef PCO_DATA_H
|
||||
#define PCO_DATA_H
|
||||
|
||||
/**
|
||||
* \file pco_data.h
|
||||
*
|
||||
* \brief PCO shader-specific data/compiler-driver interface.
|
||||
*/
|
||||
|
||||
#include "common/pvr_limits.h"
|
||||
#include "compiler/shader_enums.h"
|
||||
#include "nir/nir_lower_blend.h"
|
||||
#include "util/format/u_format.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define PCO_POINT_SAMPLER 0xffff
|
||||
#define PCO_IA_SAMPLER 0xfffe
|
||||
|
||||
/* Compiler-specific forward-declarations. */
|
||||
typedef struct _pco_shader pco_shader;
|
||||
|
||||
/** Generic range struct. */
|
||||
typedef struct _pco_range {
|
||||
unsigned start;
|
||||
unsigned count;
|
||||
union {
|
||||
unsigned stride;
|
||||
unsigned offset;
|
||||
};
|
||||
} pco_range;
|
||||
|
||||
/** PCO vertex shader-specific data. */
|
||||
typedef struct _pco_vs_data {
|
||||
/** Attributes/input mappings. */
|
||||
pco_range attribs[VERT_ATTRIB_MAX];
|
||||
|
||||
enum pipe_format attrib_formats[VERT_ATTRIB_MAX];
|
||||
|
||||
/** Varyings/output mappings. */
|
||||
pco_range varyings[VARYING_SLOT_MAX];
|
||||
|
||||
unsigned clip_count;
|
||||
unsigned cull_count;
|
||||
|
||||
unsigned f32_smooth; /** Number of F32 linear varyings. */
|
||||
unsigned f32_flat; /** Number of F32 flat varyings. */
|
||||
unsigned f32_npc; /** Number of F32 NPC varyings. */
|
||||
|
||||
unsigned f16_smooth; /** Number of F16 linear varyings. */
|
||||
unsigned f16_flat; /** Number of F16 flat varyings. */
|
||||
unsigned f16_npc; /** Number of F16 NPC varyings. */
|
||||
|
||||
unsigned vtxouts; /** How many vertex outputs are written to. */
|
||||
} pco_vs_data;
|
||||
|
||||
enum pco_front_face_op {
|
||||
PCO_FRONT_FACE_OP_NOP,
|
||||
PCO_FRONT_FACE_OP_SWAP,
|
||||
PCO_FRONT_FACE_OP_TRUE,
|
||||
};
|
||||
|
||||
/** PCO fragment shader-specific data. */
|
||||
typedef struct _pco_fs_data {
|
||||
/** Varyings/input mappings. */
|
||||
pco_range varyings[VARYING_SLOT_MAX];
|
||||
|
||||
/** Results/output mappings. */
|
||||
pco_range outputs[FRAG_RESULT_MAX];
|
||||
|
||||
/** If outputs are to be placed in tile buffers. */
|
||||
uint8_t output_tile_buffers;
|
||||
|
||||
/** Fragment output formats. */
|
||||
enum pipe_format output_formats[FRAG_RESULT_MAX];
|
||||
|
||||
/** On-chip input attachment mappings. */
|
||||
pco_range ias_onchip[8];
|
||||
|
||||
/** On-chip input attachment formats. */
|
||||
enum pipe_format ia_formats[8];
|
||||
|
||||
uint8_t ia_tile_buffers;
|
||||
uint8_t ia_has_stencil;
|
||||
|
||||
unsigned num_tile_buffers;
|
||||
|
||||
pco_range meta;
|
||||
|
||||
gl_frag_result z_replicate;
|
||||
|
||||
/* Blend options. */
|
||||
nir_lower_blend_options blend_opts;
|
||||
pco_range blend_consts;
|
||||
uint8_t blend_consts_needed;
|
||||
|
||||
uint16_t rasterization_samples;
|
||||
|
||||
pco_range tile_buffers;
|
||||
|
||||
pco_range sample_locations;
|
||||
|
||||
gl_varying_slot view_index_slot;
|
||||
|
||||
struct {
|
||||
bool w; /** Whether the shader uses pos.w. */
|
||||
bool z; /** Whether the shader uses pos.z */
|
||||
bool pntc; /** Whether the shader uses point coord. */
|
||||
bool phase_change; /** Whether the shader does a phase change. */
|
||||
bool fbfetch; /** Whether the shader fetches from the framebuffer. */
|
||||
bool depth_feedback;
|
||||
bool discard;
|
||||
bool early_frag;
|
||||
bool sample_shading;
|
||||
bool sample_locations;
|
||||
bool alpha_to_coverage;
|
||||
bool olchk_skip;
|
||||
} uses;
|
||||
|
||||
struct {
|
||||
bool color_write_enable;
|
||||
} meta_present;
|
||||
} pco_fs_data;
|
||||
|
||||
/** PCO compute shader-specific data. */
|
||||
typedef struct _pco_cs_data {
|
||||
unsigned workgroup_size[3]; /** Workgroup size. */
|
||||
|
||||
pco_range shmem;
|
||||
bool zero_shmem;
|
||||
bool global_shmem;
|
||||
} pco_cs_data;
|
||||
|
||||
/** PCO image descriptor metadata. */
|
||||
enum pco_image_meta {
|
||||
PCO_IMAGE_META_LAYER_SIZE,
|
||||
PCO_IMAGE_META_BUFFER_ELEMS,
|
||||
PCO_IMAGE_META_Z_SLICE,
|
||||
PCO_IMAGE_META_PCK_INFO,
|
||||
|
||||
PCO_IMAGE_META_COUNT,
|
||||
};
|
||||
|
||||
/** PCO sampler descriptor metadata. */
|
||||
enum pco_sampler_meta {
|
||||
PCO_SAMPLER_META_COMPARE_OP,
|
||||
PCO_SAMPLER_META_RSVD0,
|
||||
PCO_SAMPLER_META_RSVD1,
|
||||
PCO_SAMPLER_META_RSVD2,
|
||||
|
||||
PCO_SAMPLER_META_COUNT,
|
||||
};
|
||||
|
||||
/** PCO descriptor binding data. */
|
||||
typedef struct _pco_binding_data {
|
||||
pco_range range; /** Descriptor location range. */
|
||||
bool used; /** Whether the descriptor binding is used by the shader. */
|
||||
|
||||
/** Whether the descriptor binding is a combined image sampler. */
|
||||
bool is_img_smp;
|
||||
} pco_binding_data;
|
||||
|
||||
/** PCO descriptor set data. */
|
||||
typedef struct _pco_descriptor_set_data {
|
||||
pco_range range; /** Descriptor location range. */
|
||||
pco_range dynamic_range; /** Dynamic descriptor location range. */
|
||||
|
||||
unsigned binding_count; /** Number of bindings. */
|
||||
pco_binding_data *bindings; /** Descriptor set bindings. */
|
||||
|
||||
bool used; /** Whether the descriptor set is used by the shader. */
|
||||
} pco_descriptor_set_data;
|
||||
|
||||
/** PCO push constant data. */
|
||||
typedef struct _pco_push_const_data {
|
||||
pco_range range; /** Push constant range. */
|
||||
|
||||
unsigned used;
|
||||
} pco_push_const_data;
|
||||
|
||||
/** PCO common data. */
|
||||
typedef struct _pco_common_data {
|
||||
/** System value mappings. */
|
||||
pco_range sys_vals[SYSTEM_VALUE_MAX];
|
||||
|
||||
/** Descriptor set data. */
|
||||
pco_descriptor_set_data desc_sets[PVR_MAX_DESCRIPTOR_SETS];
|
||||
|
||||
/** Push constant data. */
|
||||
pco_push_const_data push_consts;
|
||||
|
||||
pco_range point_sampler;
|
||||
pco_range ia_sampler;
|
||||
|
||||
unsigned temps; /** Number of allocated temp registers. */
|
||||
unsigned vtxins; /** Number of allocated vertex input registers. */
|
||||
unsigned interns; /** Number of allocated internal registers. */
|
||||
|
||||
unsigned spilled_temps;
|
||||
pco_range spill_info; /* addr_lo, addr_hi, block_size */
|
||||
|
||||
unsigned scratch;
|
||||
pco_range scratch_info; /* addr_lo, addr_hi, block_size */
|
||||
|
||||
unsigned coeffs; /** Number of allocated coefficient registers. */
|
||||
unsigned shareds; /** Number of allocated shared registers. */
|
||||
|
||||
unsigned entry_offset; /** Offset of the shader entrypoint. */
|
||||
|
||||
struct {
|
||||
bool atomics; /** Whether the shader uses atomics. */
|
||||
bool barriers; /** Whether the shader uses barriers. */
|
||||
bool side_effects; /** Whether the shader has side effects. */
|
||||
bool empty; /** Whether the shader is empty. */
|
||||
bool point_sampler; /** Whether the shader uses a point sampler. */
|
||||
bool ia_sampler; /** Does the shader use an input attachment sampler? */
|
||||
bool usclib; /** Does the shader use usclib functions? */
|
||||
} uses;
|
||||
|
||||
bool robust_buffer_access;
|
||||
bool null_descriptor;
|
||||
bool image_2d_view_of_3d;
|
||||
bool multiview;
|
||||
} pco_common_data;
|
||||
|
||||
/** PCO shader data. */
|
||||
typedef struct _pco_data {
|
||||
union {
|
||||
pco_vs_data vs;
|
||||
pco_fs_data fs;
|
||||
pco_cs_data cs;
|
||||
};
|
||||
|
||||
pco_common_data common;
|
||||
} pco_data;
|
||||
|
||||
/** PCO precompiled shader data. */
|
||||
typedef struct PACKED _pco_precomp_data {
|
||||
uint8_t temps;
|
||||
uint8_t vtxins;
|
||||
|
||||
uint16_t coeffs : 12;
|
||||
uint16_t shareds : 12;
|
||||
|
||||
uint16_t size_dwords;
|
||||
|
||||
uint8_t pad[1];
|
||||
|
||||
uint32_t binary[];
|
||||
} pco_precomp_data;
|
||||
static_assert(sizeof(pco_precomp_data) == 8, "sizeof(pco_precomp_data) != 8");
|
||||
|
||||
pco_precomp_data pco_get_precomp_data(pco_shader *shader);
|
||||
|
||||
struct pvr_stats pco_get_pvr_stats(pco_shader *shader);
|
||||
#endif /* PCO_DATA_H */
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright © 2024 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file pco_debug.c
|
||||
*
|
||||
* \brief Debug-related functions.
|
||||
*/
|
||||
|
||||
#include "pco.h"
|
||||
#include "pco_internal.h"
|
||||
#include "util/macros.h"
|
||||
#include "util/u_call_once.h"
|
||||
#include "util/u_debug.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static const struct debug_named_value pco_debug_options[] = {
|
||||
{ "val_skip", PCO_DEBUG_VAL_SKIP, "Skip IR validation." },
|
||||
{ "reindex", PCO_DEBUG_REINDEX, "Reindex IR at the end of each pass." },
|
||||
{ "no_pred_cf", PCO_DEBUG_NO_PRED_CF, "No predicated execution in CF." },
|
||||
{ "alloc_extra_vtxins",
|
||||
PCO_DEBUG_ALLOC_EXTRA_VTXINS,
|
||||
"Allocates additional vertex input registers." },
|
||||
{ "int_smp",
|
||||
PCO_DEBUG_INT_SMP,
|
||||
"Enable integer coordinate support for sampler instructions." },
|
||||
{ "global_shmem",
|
||||
PCO_DEBUG_GLOBAL_SHMEM,
|
||||
"Force spill shared memory to global memory." },
|
||||
DEBUG_NAMED_VALUE_END,
|
||||
};
|
||||
|
||||
static const struct debug_named_value pco_debug_print_options[] = {
|
||||
{ "vs", PCO_DEBUG_PRINT_VS, "Print the IR for vertex shaders." },
|
||||
{ "fs", PCO_DEBUG_PRINT_FS, "Print the IR for fragment shaders." },
|
||||
{ "cs", PCO_DEBUG_PRINT_CS, "Print the IR for compute shaders." },
|
||||
{ "all", PCO_DEBUG_PRINT_ALL, "Print the IR for all shaders." },
|
||||
{ "internal",
|
||||
PCO_DEBUG_PRINT_INTERNAL,
|
||||
"Print the IR for internal shader types." },
|
||||
{ "passes", PCO_DEBUG_PRINT_PASSES, "Print the IR after each pass." },
|
||||
{ "nir", PCO_DEBUG_PRINT_NIR, "Print the resulting NIR." },
|
||||
{ "binary", PCO_DEBUG_PRINT_BINARY, "Print the resulting binary." },
|
||||
{ "verbose", PCO_DEBUG_PRINT_VERBOSE, "Print verbose IR." },
|
||||
{ "ra", PCO_DEBUG_PRINT_RA, "Print register alloc info." },
|
||||
{ "stats", PCO_DEBUG_PRINT_STATS, "Print shader stats." },
|
||||
DEBUG_NAMED_VALUE_END,
|
||||
};
|
||||
|
||||
DEBUG_GET_ONCE_FLAGS_OPTION(pco_debug, "PCO_DEBUG", pco_debug_options, 0U)
|
||||
uint64_t pco_debug = 0U;
|
||||
|
||||
DEBUG_GET_ONCE_FLAGS_OPTION(pco_debug_print,
|
||||
"PCO_DEBUG_PRINT",
|
||||
pco_debug_print_options,
|
||||
0U)
|
||||
uint64_t pco_debug_print = 0U;
|
||||
|
||||
DEBUG_GET_ONCE_OPTION(pco_skip_passes, "PCO_SKIP_PASSES", "")
|
||||
const char *pco_skip_passes = "";
|
||||
|
||||
DEBUG_GET_ONCE_OPTION(pco_color, "PCO_COLOR", NULL)
|
||||
bool pco_color = false;
|
||||
|
||||
static void pco_debug_init_once(void)
|
||||
{
|
||||
/* Get debug flags. */
|
||||
pco_debug = debug_get_option_pco_debug();
|
||||
pco_debug_print = debug_get_option_pco_debug_print();
|
||||
pco_skip_passes = debug_get_option_pco_skip_passes();
|
||||
|
||||
/* Get/parse color option. */
|
||||
const char *color_opt = debug_get_option_pco_color();
|
||||
if (!color_opt || !strcmp(color_opt, "auto") || !strcmp(color_opt, "a"))
|
||||
pco_color = isatty(fileno(stdout));
|
||||
else if (!strcmp(color_opt, "on") || !strcmp(color_opt, "1"))
|
||||
pco_color = true;
|
||||
else if (!strcmp(color_opt, "off") || !strcmp(color_opt, "0"))
|
||||
pco_color = false;
|
||||
}
|
||||
|
||||
void pco_debug_init(void)
|
||||
{
|
||||
static util_once_flag flag = UTIL_ONCE_FLAG_INIT;
|
||||
util_call_once(&flag, pco_debug_init_once);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright © 2024 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file pco_end.c
|
||||
*
|
||||
* \brief PCO shader ending pass.
|
||||
*/
|
||||
|
||||
#include "pco.h"
|
||||
#include "pco_builder.h"
|
||||
#include "pco_internal.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* \brief Processes end of shader instruction(s).
|
||||
*
|
||||
* \param[in,out] shader PCO shader.
|
||||
* \return True if the pass made progress.
|
||||
*/
|
||||
bool pco_end(pco_shader *shader)
|
||||
{
|
||||
/* TODO: Support for multiple end points. */
|
||||
pco_func *entry = pco_entrypoint(shader);
|
||||
pco_block *last_block = pco_func_last_block(entry);
|
||||
pco_instr *last_instr = pco_last_instr(last_block);
|
||||
|
||||
pco_builder b =
|
||||
pco_builder_create(entry, pco_cursor_after_block(last_block));
|
||||
|
||||
if (shader->stage == MESA_SHADER_VERTEX) {
|
||||
if (last_instr && last_instr->op == PCO_OP_UVSW_WRITE &&
|
||||
pco_instr_has_default_exec(last_instr) &&
|
||||
pco_instr_get_rpt(last_instr) == 1) {
|
||||
pco_instr *new_last_instr =
|
||||
pco_uvsw_write_emit_endtask(&b,
|
||||
last_instr->src[0],
|
||||
last_instr->src[1]);
|
||||
pco_instr_delete(last_instr);
|
||||
last_instr = new_last_instr;
|
||||
} else {
|
||||
last_instr = pco_uvsw_emit_endtask(&b);
|
||||
}
|
||||
}
|
||||
|
||||
if (last_instr && pco_instr_has_end(last_instr)) {
|
||||
pco_instr_set_end(last_instr, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
pco_nop(&b, .end = true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright © 2024 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file pco_group_instrs.c
|
||||
*
|
||||
* \brief PCO instruction grouping pass.
|
||||
*/
|
||||
|
||||
#include "hwdef/rogue_hw_defs.h"
|
||||
#include "pco.h"
|
||||
#include "pco_builder.h"
|
||||
#include "pco_map.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* \brief Calculates the decode-assist value for an instruction group.
|
||||
*
|
||||
* \param[in] igrp PCO instruction group.
|
||||
* \return The decode-assist value.
|
||||
*/
|
||||
static inline unsigned calc_da(pco_igrp *igrp)
|
||||
{
|
||||
unsigned da = igrp->enc.len.hdr;
|
||||
bool no_srcs_dests = !igrp->enc.len.lower_srcs &&
|
||||
!igrp->enc.len.upper_srcs && !igrp->enc.len.dests;
|
||||
|
||||
switch (igrp->hdr.alutype) {
|
||||
case PCO_ALUTYPE_MAIN:
|
||||
case PCO_ALUTYPE_BITWISE: {
|
||||
pco_foreach_phase_rev (p) {
|
||||
if (igrp->hdr.alutype == PCO_ALUTYPE_BITWISE || p > PCO_OP_PHASE_1)
|
||||
da += igrp->enc.len.instrs[p];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PCO_ALUTYPE_CONTROL:
|
||||
if (no_srcs_dests)
|
||||
return 0;
|
||||
|
||||
da += igrp->enc.len.instrs[PCO_OP_PHASE_CTRL];
|
||||
break;
|
||||
|
||||
default:
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
return da;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Calculates the lengths for an instruction group.
|
||||
*
|
||||
* \param[in,out] igrp PCO instruction group.
|
||||
* \param[in,out] offset_bytes The cumulative shader offset (in bytes).
|
||||
*/
|
||||
static inline void calc_lengths(pco_igrp *igrp, unsigned *offset_bytes)
|
||||
{
|
||||
unsigned total_length = 0;
|
||||
|
||||
igrp->enc.len.hdr = pco_igrp_hdr_bytes(igrp->variant.hdr);
|
||||
total_length += igrp->enc.len.hdr;
|
||||
|
||||
igrp->enc.len.lower_srcs = pco_src_bytes(igrp->variant.lower_src);
|
||||
total_length += igrp->enc.len.lower_srcs;
|
||||
|
||||
igrp->enc.len.upper_srcs = pco_src_bytes(igrp->variant.upper_src);
|
||||
total_length += igrp->enc.len.upper_srcs;
|
||||
|
||||
igrp->enc.len.iss = pco_iss_bytes(igrp->variant.iss);
|
||||
total_length += igrp->enc.len.iss;
|
||||
|
||||
igrp->enc.len.dests = pco_dst_bytes(igrp->variant.dest);
|
||||
total_length += igrp->enc.len.dests;
|
||||
|
||||
pco_foreach_phase_in_igrp (igrp, phase) {
|
||||
switch (igrp->hdr.alutype) {
|
||||
case PCO_ALUTYPE_MAIN:
|
||||
if (phase == PCO_OP_PHASE_BACKEND) {
|
||||
igrp->enc.len.instrs[phase] =
|
||||
pco_backend_bytes(igrp->variant.instr[phase].backend);
|
||||
} else {
|
||||
igrp->enc.len.instrs[phase] =
|
||||
pco_main_bytes(igrp->variant.instr[phase].main);
|
||||
}
|
||||
break;
|
||||
|
||||
case PCO_ALUTYPE_BITWISE:
|
||||
igrp->enc.len.instrs[phase] =
|
||||
pco_bitwise_bytes(igrp->variant.instr[phase].bitwise);
|
||||
break;
|
||||
|
||||
case PCO_ALUTYPE_CONTROL:
|
||||
igrp->enc.len.instrs[phase] =
|
||||
pco_ctrl_bytes(igrp->variant.instr[phase].control);
|
||||
break;
|
||||
|
||||
default:
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
total_length += igrp->enc.len.instrs[phase];
|
||||
}
|
||||
|
||||
igrp->enc.len.word_padding = total_length % 2;
|
||||
total_length += igrp->enc.len.word_padding;
|
||||
|
||||
igrp->enc.len.total = total_length;
|
||||
|
||||
/* Set igrp header length and decode-assist. */
|
||||
igrp->hdr.length = igrp->enc.len.total / 2;
|
||||
igrp->hdr.da = calc_da(igrp);
|
||||
|
||||
/* Set offset and update running offset byte count. */
|
||||
igrp->enc.offset = *offset_bytes;
|
||||
*offset_bytes += igrp->enc.len.total;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Calculates the alignment padding to be applied to
|
||||
* the last instruction group in the shader.
|
||||
*
|
||||
* \param[in,out] last_igrp The last instruction group.
|
||||
* \param[in,out] offset_bytes The cumulative shader offset (in bytes).
|
||||
*/
|
||||
static inline void calc_align_padding(pco_igrp *last_igrp,
|
||||
unsigned *offset_bytes)
|
||||
{
|
||||
/* We should never end up with a completely empty shader. */
|
||||
assert(last_igrp);
|
||||
|
||||
unsigned total_align = last_igrp->enc.len.total % ROGUE_ICACHE_ALIGN;
|
||||
unsigned offset_align = last_igrp->enc.offset % ROGUE_ICACHE_ALIGN;
|
||||
|
||||
if (total_align) {
|
||||
unsigned padding = ROGUE_ICACHE_ALIGN - total_align;
|
||||
*offset_bytes += padding;
|
||||
|
||||
/* Pad the size of the last igrp. */
|
||||
last_igrp->enc.len.align_padding += padding;
|
||||
last_igrp->enc.len.total += padding;
|
||||
|
||||
/* Update the last igrp header length. */
|
||||
last_igrp->hdr.length = last_igrp->enc.len.total / 2;
|
||||
}
|
||||
|
||||
if (offset_align) {
|
||||
unsigned padding = ROGUE_ICACHE_ALIGN - offset_align;
|
||||
*offset_bytes += padding;
|
||||
|
||||
/* Pad the size of the penultimate igrp. */
|
||||
pco_igrp *penultimate_igrp = pco_prev_igrp(last_igrp);
|
||||
|
||||
/* If we only have one igrp then its offset will be zero. */
|
||||
assert(penultimate_igrp);
|
||||
|
||||
penultimate_igrp->enc.len.align_padding += padding;
|
||||
penultimate_igrp->enc.len.total += padding;
|
||||
|
||||
/* Update the penultimate igrp header length. */
|
||||
penultimate_igrp->hdr.length = penultimate_igrp->enc.len.total / 2;
|
||||
|
||||
/* Update the offset of the last igrp. */
|
||||
last_igrp->enc.offset += padding;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Converts a PCO instruction to an instruction group.
|
||||
*
|
||||
* \param[in] b PCO builder.
|
||||
* \param[in] instr PCO instruction.
|
||||
* \param[out] igrp PCO instruction group.
|
||||
* \param[in,out] offset_bytes The cumulative shader offset (in bytes).
|
||||
*/
|
||||
static void pco_instr_to_igrp(pco_builder *b,
|
||||
pco_instr *instr,
|
||||
pco_igrp *igrp,
|
||||
unsigned *offset_bytes)
|
||||
{
|
||||
pco_map_igrp(igrp, instr);
|
||||
calc_lengths(igrp, offset_bytes);
|
||||
pco_builder_insert_igrp(b, igrp);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Groups PCO instructions into instruction groups.
|
||||
*
|
||||
* \param[in,out] shader PCO shader.
|
||||
* \return True if the pass made progress.
|
||||
*/
|
||||
bool pco_group_instrs(pco_shader *shader)
|
||||
{
|
||||
pco_builder b;
|
||||
pco_igrp *igrp = NULL;
|
||||
unsigned offset_bytes = 0;
|
||||
|
||||
assert(!shader->is_grouped);
|
||||
|
||||
pco_foreach_func_in_shader (func, shader) {
|
||||
/* TODO: double check that *start* alignment is satisfied by
|
||||
* calc_align_padding when having multiple functions?
|
||||
*/
|
||||
pco_foreach_block_in_func (block, func) {
|
||||
b = pco_builder_create(func, pco_cursor_before_block(block));
|
||||
pco_foreach_instr_in_block_safe (instr, block) {
|
||||
igrp = pco_igrp_create(func);
|
||||
pco_instr_to_igrp(&b, instr, igrp, &offset_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure the final instruction group has a total size and offset
|
||||
* that are a multiple of the icache alignment.
|
||||
*/
|
||||
calc_align_padding(igrp, &offset_bytes);
|
||||
}
|
||||
|
||||
shader->is_grouped = true;
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright © 2024 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file pco_index.c
|
||||
*
|
||||
* \brief PCO indexing pass.
|
||||
*/
|
||||
|
||||
#include "pco.h"
|
||||
#include "pco_internal.h"
|
||||
#include "util/hash_table.h"
|
||||
#include "util/macros.h"
|
||||
#include "util/ralloc.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* \brief Indexes all shader child structures.
|
||||
*
|
||||
* \param[in,out] shader PCO shader.
|
||||
* \param[in] skip_ssa Whether to skip SSA indexing.
|
||||
* \return True if the pass made progress.
|
||||
*/
|
||||
bool pco_index(pco_shader *shader, bool skip_ssa)
|
||||
{
|
||||
/* TODO */
|
||||
if (shader->is_grouped)
|
||||
return false;
|
||||
|
||||
shader->next_func = 0;
|
||||
pco_foreach_func_in_shader (func, shader) {
|
||||
unsigned *ssa_idx_map = NULL;
|
||||
if (!skip_ssa) {
|
||||
ssa_idx_map =
|
||||
rzalloc_array_size(NULL, sizeof(*ssa_idx_map), func->next_ssa);
|
||||
}
|
||||
|
||||
func->index = shader->next_func++;
|
||||
func->next_instr = 0;
|
||||
func->next_block = 0;
|
||||
|
||||
struct hash_table_u64 *vec_infos = NULL;
|
||||
if (!skip_ssa) {
|
||||
func->next_ssa = 0;
|
||||
vec_infos = _mesa_hash_table_u64_create(func);
|
||||
}
|
||||
|
||||
pco_foreach_block_in_func (block, func) {
|
||||
block->index = func->next_block++;
|
||||
pco_foreach_instr_in_block (instr, block) {
|
||||
instr->index = func->next_instr++;
|
||||
if (!skip_ssa) {
|
||||
pco_foreach_instr_dest_ssa (pdest, instr) {
|
||||
ssa_idx_map[pdest->val] = func->next_ssa++;
|
||||
if (instr->op == PCO_OP_VEC) {
|
||||
pco_vec_info *vec_info =
|
||||
_mesa_hash_table_u64_search(func->vec_infos,
|
||||
pdest->val);
|
||||
|
||||
ralloc_steal(vec_infos, vec_info);
|
||||
|
||||
_mesa_hash_table_u64_insert(vec_infos,
|
||||
ssa_idx_map[pdest->val],
|
||||
vec_info);
|
||||
}
|
||||
pdest->val = ssa_idx_map[pdest->val];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!skip_ssa) {
|
||||
pco_foreach_instr_in_func (instr, func) {
|
||||
pco_foreach_instr_src_ssa (psrc, instr) {
|
||||
psrc->val = ssa_idx_map[psrc->val];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func->next_if = 0;
|
||||
pco_foreach_if_in_func (pif, func) {
|
||||
pif->index = func->next_if++;
|
||||
|
||||
if (!skip_ssa) {
|
||||
if (!pco_ref_is_ssa(pif->cond))
|
||||
continue;
|
||||
|
||||
pif->cond.val = ssa_idx_map[pif->cond.val];
|
||||
}
|
||||
}
|
||||
|
||||
func->next_loop = 0;
|
||||
pco_foreach_loop_in_func (loop, func) {
|
||||
loop->index = func->next_loop++;
|
||||
}
|
||||
|
||||
if (!skip_ssa) {
|
||||
_mesa_hash_table_u64_destroy(func->vec_infos);
|
||||
func->vec_infos = vec_infos;
|
||||
ralloc_free(ssa_idx_map);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
# Copyright © 2024 Imagination Technologies Ltd.
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
from mako.template import Template, exceptions
|
||||
from pco_ops import *
|
||||
from pco_map import *
|
||||
|
||||
template = """/*
|
||||
* Copyright © 2024 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* \\file pco_info.c
|
||||
*
|
||||
* \\brief PCO info structures.
|
||||
*/
|
||||
|
||||
#include "pco_common.h"
|
||||
#include "pco_internal.h"
|
||||
#include "pco_isa.h"
|
||||
#include "pco_ops.h"
|
||||
|
||||
const struct pco_op_info pco_op_info[_PCO_OP_COUNT] = {
|
||||
% for op in ops.values():
|
||||
[${op.cname.upper()}] = {
|
||||
.str = "${op.name}",
|
||||
.num_dests = ${op.num_dests},
|
||||
.num_srcs = ${op.num_srcs},
|
||||
.mods = ${op.cop_mods},
|
||||
.mod_map = {
|
||||
% for mod, index in op.op_mod_map.items():
|
||||
[${mod}] = ${index},
|
||||
% endfor
|
||||
},
|
||||
.dest_mods = {
|
||||
% for index, cdest_mods in op.cdest_mods.items():
|
||||
[${index}] = ${cdest_mods},
|
||||
% endfor
|
||||
},
|
||||
.src_mods = {
|
||||
% for index, csrc_mods in op.csrc_mods.items():
|
||||
[${index}] = ${csrc_mods},
|
||||
% endfor
|
||||
},
|
||||
.type = PCO_OP_TYPE_${op.op_type.upper()},
|
||||
.has_target_cf_node = ${str(op.has_target_cf_node).lower()},
|
||||
% if op.bname in group_maps:
|
||||
.dest_intrn_map = {
|
||||
% for index, val in group_maps[op.bname].dest_intrn_map:
|
||||
[${index}] = ${val},
|
||||
% endfor
|
||||
},
|
||||
.src_intrn_map = {
|
||||
% for index, val in group_maps[op.bname].src_intrn_map:
|
||||
[${index}] = ${val},
|
||||
% endfor
|
||||
},
|
||||
% endif
|
||||
#ifndef NDEBUG
|
||||
% if op.bname in encode_maps:
|
||||
.grp_dest_maps = {
|
||||
% for phase, dests, _ in encode_maps[op.bname].op_ref_maps:
|
||||
[${phase}] = {
|
||||
% for dest in dests:
|
||||
[${loop.index}] = ${dest},
|
||||
% endfor
|
||||
},
|
||||
% endfor
|
||||
},
|
||||
.grp_src_maps = {
|
||||
% for phase, _, srcs in encode_maps[op.bname].op_ref_maps:
|
||||
[${phase}] = {
|
||||
% for src in srcs:
|
||||
[${loop.index}] = ${src},
|
||||
% endfor
|
||||
},
|
||||
% endfor
|
||||
},
|
||||
% endif
|
||||
#endif /* NDEBUG */
|
||||
},
|
||||
% endfor
|
||||
};
|
||||
|
||||
const struct pco_op_mod_info pco_op_mod_info[_PCO_OP_MOD_COUNT] = {
|
||||
% for name, op_mod in op_mods.items():
|
||||
[${op_mod.cname}] = {
|
||||
.print_early = ${str(op_mod.t.print_early).lower()},
|
||||
.type = ${op_mod.ctype},
|
||||
% if op_mod.t.base_type == BaseType.enum:
|
||||
.is_bitset = ${str(op_mod.t.enum.is_bitset).lower()},
|
||||
.strs = (const char * []){
|
||||
% for elem in op_mod.t.enum.elems.values():
|
||||
[${elem.cname}] = "${elem.string}",
|
||||
% endfor
|
||||
},
|
||||
% else:
|
||||
.str = "${name}",
|
||||
% endif
|
||||
% if op_mod.t.nzdefault is not None:
|
||||
.nzdefault = ${op_mod.t.nzdefault},
|
||||
% endif
|
||||
},
|
||||
% endfor
|
||||
};
|
||||
|
||||
const struct pco_ref_mod_info pco_ref_mod_info[_PCO_REF_MOD_COUNT] = {
|
||||
% for name, ref_mod in ref_mods.items():
|
||||
[${ref_mod.cname}] = {
|
||||
.type = ${ref_mod.ctype},
|
||||
% if ref_mod.t.base_type == BaseType.enum:
|
||||
.is_bitset = ${str(ref_mod.t.enum.is_bitset).lower()},
|
||||
.strs = (const char * []){
|
||||
% for elem in ref_mod.t.enum.elems.values():
|
||||
[${elem.cname}] = "${elem.string}",
|
||||
% endfor
|
||||
},
|
||||
% else:
|
||||
.str = "${name}",
|
||||
% endif
|
||||
},
|
||||
% endfor
|
||||
};"""
|
||||
|
||||
def main():
|
||||
try:
|
||||
print(Template(template).render(BaseType=BaseType, ops=ops, op_mods=op_mods, ref_mods=ref_mods, group_maps=group_maps, encode_maps=encode_maps))
|
||||
except:
|
||||
raise Exception(exceptions.text_error_template().render())
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright © 2024 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file pco_ir.c
|
||||
*
|
||||
* \brief PCO IR-specific functions.
|
||||
*/
|
||||
|
||||
#include "pco.h"
|
||||
#include "pco_internal.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* \brief Runs passes on a PCO shader.
|
||||
*
|
||||
* \param[in] ctx PCO compiler context.
|
||||
* \param[in,out] shader PCO shader.
|
||||
*/
|
||||
void pco_process_ir(pco_ctx *ctx, pco_shader *shader)
|
||||
{
|
||||
pco_validate_shader(shader, "before passes");
|
||||
|
||||
PCO_PASS(_, shader, pco_const_imms);
|
||||
PCO_PASS(_, shader, pco_opt);
|
||||
|
||||
bool progress;
|
||||
do {
|
||||
progress = false;
|
||||
PCO_PASS(progress, shader, pco_dce);
|
||||
} while (progress);
|
||||
|
||||
PCO_PASS(_, shader, pco_bool);
|
||||
PCO_PASS(_, shader, pco_cf);
|
||||
|
||||
PCO_PASS(_, shader, pco_shrink_vecs);
|
||||
|
||||
PCO_PASS(_, shader, pco_const_imms);
|
||||
PCO_PASS(_, shader, pco_opt_comp_only_vecs);
|
||||
PCO_PASS(_, shader, pco_opt);
|
||||
|
||||
do {
|
||||
progress = false;
|
||||
PCO_PASS(progress, shader, pco_dce);
|
||||
} while (progress);
|
||||
|
||||
/* TODO: schedule after RA instead as e.g. vecs may no longer be the first
|
||||
* time a drc result is used.
|
||||
*/
|
||||
PCO_PASS(_, shader, pco_schedule);
|
||||
PCO_PASS(_, shader, pco_pre_ra_legalize);
|
||||
PCO_PASS(_, shader, pco_ra);
|
||||
PCO_PASS(_, shader, pco_post_ra_legalize);
|
||||
PCO_PASS(_, shader, pco_end);
|
||||
PCO_PASS(_, shader, pco_group_instrs);
|
||||
|
||||
pco_validate_shader(shader, "after passes");
|
||||
|
||||
if (pco_should_print_shader(shader))
|
||||
pco_print_shader(shader, stdout, "after passes");
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
# Copyright © 2024 Imagination Technologies Ltd.
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
from mako.template import Template, exceptions
|
||||
from pco_isa import *
|
||||
|
||||
template = """/*
|
||||
* Copyright © 2024 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef PCO_ISA_H
|
||||
#define PCO_ISA_H
|
||||
|
||||
/**
|
||||
* \\file pco_isa.h
|
||||
*
|
||||
* \\brief PCO ISA definitions.
|
||||
*/
|
||||
|
||||
#include "pco_common.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
% for _bit_set_name, bit_set in bit_sets.items():
|
||||
/** ${_bit_set_name} */
|
||||
enum ${bit_set.name}_field {
|
||||
% for field in bit_set.fields.values():
|
||||
${field.cname},
|
||||
% endfor
|
||||
};
|
||||
|
||||
static unsigned ${bit_set.name}_bytes(enum ${bit_set.name}_variant variant)
|
||||
{
|
||||
switch (variant) {
|
||||
case ${bit_set.name.upper()}_NONE: return 0;
|
||||
% for variant in bit_set.variants:
|
||||
case ${variant.cname}: return ${variant.bytes};
|
||||
% endfor
|
||||
default: break;
|
||||
}
|
||||
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
static unsigned ${bit_set.name}_encode_field(uint8_t *bin, enum ${bit_set.name}_field field, uint64_t val)
|
||||
{
|
||||
uint64_t enc_val;
|
||||
|
||||
switch (field) {
|
||||
% for field in bit_set.fields.values():
|
||||
case ${field.cname}:
|
||||
% if field.field_type.check is not None:
|
||||
assert(${field.field_type.check.format('val')});
|
||||
% endif
|
||||
% if field.reserved is not None:
|
||||
assert(val == ${field.reserved});
|
||||
% endif
|
||||
enc_val = ${field.field_type.encode.format('val') if field.field_type.encode is not None else 'val'};
|
||||
assert(${field.validate.format('enc_val')});
|
||||
% for encoding in field.encoding:
|
||||
${encoding.clear.format('bin')};
|
||||
${encoding.set.format('bin', 'enc_val')};
|
||||
% endfor
|
||||
return ${field.encoded_bits};
|
||||
|
||||
% endfor
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
% for bit_struct in bit_set.bit_structs.values():
|
||||
% if len(bit_struct.struct_fields) > 0:
|
||||
struct ${bit_struct.name} {
|
||||
% for struct_field in bit_struct.struct_fields.values():
|
||||
${struct_field.type.name} ${struct_field.field} : ${struct_field.bits};
|
||||
% endfor
|
||||
};
|
||||
% endif
|
||||
|
||||
% if len(bit_struct.struct_fields) > 0:
|
||||
#define ${bit_struct.name}_encode(bin, ...) _${bit_struct.name}_encode(bin, (const struct ${bit_struct.name}){0, ##__VA_ARGS__})
|
||||
static unsigned _${bit_struct.name}_encode(uint8_t *bin, const struct ${bit_struct.name} s)
|
||||
% else:
|
||||
static unsigned ${bit_struct.name}_encode(uint8_t *bin)
|
||||
% endif
|
||||
{
|
||||
unsigned bits_encoded = 0;
|
||||
|
||||
% for encode_field in bit_struct.encode_fields:
|
||||
bits_encoded += ${bit_set.name}_encode_field(bin, ${encode_field.name}, ${encode_field.value});
|
||||
% endfor
|
||||
|
||||
assert(!(bits_encoded % 8));
|
||||
return bits_encoded / 8;
|
||||
}
|
||||
|
||||
% endfor
|
||||
% endfor
|
||||
#endif /* PCO_ISA_H */"""
|
||||
|
||||
def main():
|
||||
try:
|
||||
print(Template(template).render(bit_sets=bit_sets))
|
||||
except:
|
||||
raise Exception(exceptions.text_error_template().render())
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,517 @@
|
||||
/*
|
||||
* Copyright © 2025 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file pco_legalize.c
|
||||
*
|
||||
* \brief PCO legalizing pass.
|
||||
*/
|
||||
|
||||
#include "pco.h"
|
||||
#include "pco_builder.h"
|
||||
#include "pco_internal.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
static inline bool ref_needs_olchk(pco_ref ref)
|
||||
{
|
||||
if (!pco_ref_is_reg(ref))
|
||||
return false;
|
||||
|
||||
switch (pco_ref_get_reg_class(ref)) {
|
||||
case PCO_REG_CLASS_PIXOUT:
|
||||
return true;
|
||||
|
||||
case PCO_REG_CLASS_SPEC:
|
||||
return ref.val == PCO_SR_OUTPUT_PART ||
|
||||
(ref.val >= PCO_SR_TILED_LD_COMP0 &&
|
||||
ref.val <= PCO_SR_TILED_ST_COMP3) ||
|
||||
(ref.val >= PCO_SR_TILED_LD_COMP4 &&
|
||||
ref.val <= PCO_SR_TILED_ST_COMP7);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Insert a mov to legalize how a hardware register is referenced.
|
||||
*
|
||||
* \param[in,out] instr PCO instr.
|
||||
* \param[in,out] ref Reference to be legalized.
|
||||
* \param[in] needs_s124 Whether the mapping needs to use S{1,2,4}
|
||||
* rather than S{0,2,3}.
|
||||
* \return True if progress was made.
|
||||
*/
|
||||
static void insert_mov_ref(pco_instr *instr, pco_ref *ref, bool needs_s124)
|
||||
{
|
||||
if (instr->op == PCO_OP_MBYP && needs_s124 && !pco_ref_has_mods_set(*ref)) {
|
||||
instr->op = PCO_OP_MOVS1;
|
||||
return;
|
||||
} else if (instr->op == PCO_OP_MOVS1 && !needs_s124) {
|
||||
instr->op = PCO_OP_MBYP;
|
||||
return;
|
||||
}
|
||||
|
||||
assert(pco_ref_is_scalar(*ref));
|
||||
pco_ref new_ref = pco_ref_new_ssa(instr->parent_func,
|
||||
pco_ref_get_bits(*ref),
|
||||
pco_ref_get_chans(*ref));
|
||||
|
||||
pco_ref_xfer_mods(&new_ref, ref, true);
|
||||
|
||||
pco_builder b =
|
||||
pco_builder_create(instr->parent_func, pco_cursor_before_instr(instr));
|
||||
|
||||
enum pco_exec_cnd exec_cnd = pco_instr_get_exec_cnd(instr);
|
||||
pco_instr *mov_instr;
|
||||
if (needs_s124)
|
||||
mov_instr = pco_movs1(&b, new_ref, *ref, .exec_cnd = exec_cnd);
|
||||
else
|
||||
mov_instr = pco_mbyp(&b, new_ref, *ref, .exec_cnd = exec_cnd);
|
||||
|
||||
if (pco_instr_has_olchk(instr) && pco_instr_get_olchk(instr) &&
|
||||
ref_needs_olchk(*ref)) {
|
||||
assert(pco_instr_has_olchk(mov_instr));
|
||||
pco_instr_set_olchk(mov_instr, true);
|
||||
pco_instr_set_olchk(instr, false);
|
||||
}
|
||||
|
||||
*ref = new_ref;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Try to legalize an instruction's hardware source mappings.
|
||||
*
|
||||
* \param[in,out] instr PCO instr.
|
||||
* \param[in] info PCO op info.
|
||||
* \return True if progress was made.
|
||||
*/
|
||||
static bool try_legalize_src_mappings(pco_instr *instr,
|
||||
const struct pco_op_info *info)
|
||||
{
|
||||
bool progress = false;
|
||||
bool needs_s124;
|
||||
|
||||
/* Check dests. */
|
||||
pco_foreach_instr_dest (pdest, instr) {
|
||||
unsigned dest_index = pdest - instr->dest;
|
||||
if (!info->dest_intrn_map[dest_index])
|
||||
continue;
|
||||
|
||||
enum pco_io mapped_src = PCO_IO_S0 + info->dest_intrn_map[dest_index] - 1;
|
||||
|
||||
if (ref_src_map_valid(*pdest, mapped_src, &needs_s124))
|
||||
continue;
|
||||
|
||||
insert_mov_ref(instr, pdest, needs_s124);
|
||||
progress = true;
|
||||
}
|
||||
|
||||
/* Check srcs. */
|
||||
pco_foreach_instr_src (psrc, instr) {
|
||||
unsigned src_index = psrc - instr->src;
|
||||
if (!info->src_intrn_map[src_index])
|
||||
continue;
|
||||
|
||||
enum pco_io mapped_src = PCO_IO_S0 + info->src_intrn_map[src_index] - 1;
|
||||
|
||||
if (ref_src_map_valid(*psrc, mapped_src, &needs_s124))
|
||||
continue;
|
||||
|
||||
insert_mov_ref(instr, psrc, needs_s124);
|
||||
progress = true;
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
static inline bool xfer_op_mods(pco_instr *dest, pco_instr *src)
|
||||
{
|
||||
bool all_xfered = true;
|
||||
|
||||
for (enum pco_op_mod mod = PCO_OP_MOD_NONE + 1; mod < _PCO_OP_MOD_COUNT;
|
||||
++mod) {
|
||||
bool dest_has_mod = pco_instr_has_mod(dest, mod);
|
||||
bool src_has_mod = pco_instr_has_mod(src, mod);
|
||||
|
||||
if (!dest_has_mod && !src_has_mod)
|
||||
continue;
|
||||
|
||||
if (dest_has_mod != src_has_mod) {
|
||||
all_xfered = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
pco_instr_set_mod(dest, mod, pco_instr_get_mod(src, mod));
|
||||
}
|
||||
|
||||
return all_xfered;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Legalize fence pseudo instruction.
|
||||
*
|
||||
* \param[in,out] instr PCO instr.
|
||||
* \return True if progress was made.
|
||||
*/
|
||||
static bool legalize_fence(pco_instr *instr)
|
||||
{
|
||||
pco_builder b =
|
||||
pco_builder_create(instr->parent_func, pco_cursor_before_instr(instr));
|
||||
|
||||
pco_flush_p0(&b);
|
||||
pco_br_next(&b, .exec_cnd = PCO_EXEC_CND_E1_Z1);
|
||||
pco_br_next(&b, .exec_cnd = PCO_EXEC_CND_E1_Z0);
|
||||
|
||||
pco_instr_delete(instr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool legalize_pseudo(pco_instr *instr)
|
||||
{
|
||||
switch (instr->op) {
|
||||
case PCO_OP_FENCE:
|
||||
return legalize_fence(instr);
|
||||
|
||||
case PCO_OP_MOV:
|
||||
if (pco_ref_is_reg(instr->src[0]) &&
|
||||
pco_ref_get_reg_class(instr->src[0]) == PCO_REG_CLASS_SPEC)
|
||||
instr->op = PCO_OP_MOVS1;
|
||||
else
|
||||
instr->op = PCO_OP_MBYP;
|
||||
|
||||
return true;
|
||||
|
||||
case PCO_OP_MOV_OFFSET: {
|
||||
pco_builder b =
|
||||
pco_builder_create(instr->parent_func, pco_cursor_before_instr(instr));
|
||||
|
||||
pco_ref dest = instr->dest[0];
|
||||
pco_ref src = instr->src[0];
|
||||
pco_ref offset = instr->src[1];
|
||||
|
||||
unsigned idx_reg_num = 0;
|
||||
pco_ref idx_reg =
|
||||
pco_ref_hwreg_idx(idx_reg_num, idx_reg_num, PCO_REG_CLASS_INDEX);
|
||||
|
||||
pco_mbyp(&b, idx_reg, offset, .exec_cnd = pco_instr_get_exec_cnd(instr));
|
||||
|
||||
if (pco_instr_get_offset_sd(instr) == PCO_OFFSET_SD_SRC)
|
||||
src = pco_ref_hwreg_idx_from(idx_reg_num, src);
|
||||
else
|
||||
dest = pco_ref_hwreg_idx_from(idx_reg_num, dest);
|
||||
|
||||
pco_instr *mbyp = pco_mbyp(&b, dest, src);
|
||||
xfer_op_mods(mbyp, instr);
|
||||
|
||||
pco_instr_delete(instr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
case PCO_OP_OP_ATOMIC_OFFSET: {
|
||||
pco_builder b =
|
||||
pco_builder_create(instr->parent_func, pco_cursor_before_instr(instr));
|
||||
|
||||
pco_ref dest = instr->dest[0];
|
||||
pco_ref shmem_dest = instr->dest[1];
|
||||
|
||||
pco_ref shmem_src = instr->src[0];
|
||||
pco_ref value = instr->src[1];
|
||||
pco_ref value_swap = instr->src[2];
|
||||
pco_ref offset = instr->src[3];
|
||||
|
||||
unsigned idx_reg_num = 0;
|
||||
pco_ref idx_reg =
|
||||
pco_ref_hwreg_idx(idx_reg_num, idx_reg_num, PCO_REG_CLASS_INDEX);
|
||||
|
||||
pco_mbyp(&b, idx_reg, offset, .exec_cnd = pco_instr_get_exec_cnd(instr));
|
||||
|
||||
shmem_dest = pco_ref_hwreg_idx_from(idx_reg_num, shmem_dest);
|
||||
shmem_src = pco_ref_hwreg_idx_from(idx_reg_num, shmem_src);
|
||||
|
||||
pco_instr *repl;
|
||||
enum pco_atom_op atom_op = pco_instr_get_atom_op(instr);
|
||||
switch (atom_op) {
|
||||
case PCO_ATOM_OP_ADD:
|
||||
assert(pco_ref_is_null(value_swap));
|
||||
repl = pco_iadd32_atomic(&b,
|
||||
dest,
|
||||
shmem_dest,
|
||||
shmem_src,
|
||||
value,
|
||||
pco_ref_null(),
|
||||
.s = true);
|
||||
break;
|
||||
|
||||
case PCO_ATOM_OP_XCHG:
|
||||
assert(pco_ref_is_null(value_swap));
|
||||
repl = pco_xchg_atomic(&b, dest, shmem_dest, shmem_src, value);
|
||||
break;
|
||||
|
||||
case PCO_ATOM_OP_CMPXCHG:
|
||||
assert(!pco_ref_is_null(value_swap));
|
||||
repl = pco_cmpxchg_atomic(&b,
|
||||
dest,
|
||||
shmem_dest,
|
||||
shmem_src,
|
||||
value,
|
||||
value_swap,
|
||||
.tst_type_main = PCO_TST_TYPE_MAIN_U32);
|
||||
break;
|
||||
|
||||
case PCO_ATOM_OP_UMIN:
|
||||
assert(pco_ref_is_null(value_swap));
|
||||
repl = pco_min_atomic(&b,
|
||||
dest,
|
||||
shmem_dest,
|
||||
shmem_src,
|
||||
value,
|
||||
.tst_type_main = PCO_TST_TYPE_MAIN_U32);
|
||||
break;
|
||||
|
||||
case PCO_ATOM_OP_IMIN:
|
||||
assert(pco_ref_is_null(value_swap));
|
||||
repl = pco_min_atomic(&b,
|
||||
dest,
|
||||
shmem_dest,
|
||||
shmem_src,
|
||||
value,
|
||||
.tst_type_main = PCO_TST_TYPE_MAIN_S32);
|
||||
break;
|
||||
|
||||
case PCO_ATOM_OP_UMAX:
|
||||
assert(pco_ref_is_null(value_swap));
|
||||
repl = pco_max_atomic(&b,
|
||||
dest,
|
||||
shmem_dest,
|
||||
shmem_src,
|
||||
value,
|
||||
.tst_type_main = PCO_TST_TYPE_MAIN_U32);
|
||||
break;
|
||||
|
||||
case PCO_ATOM_OP_IMAX:
|
||||
assert(pco_ref_is_null(value_swap));
|
||||
repl = pco_max_atomic(&b,
|
||||
dest,
|
||||
shmem_dest,
|
||||
shmem_src,
|
||||
value,
|
||||
.tst_type_main = PCO_TST_TYPE_MAIN_S32);
|
||||
break;
|
||||
|
||||
case PCO_ATOM_OP_AND:
|
||||
assert(pco_ref_is_null(value_swap));
|
||||
repl = pco_logical_atomic(&b,
|
||||
dest,
|
||||
shmem_dest,
|
||||
shmem_src,
|
||||
value,
|
||||
.logiop = PCO_LOGIOP_AND);
|
||||
break;
|
||||
|
||||
case PCO_ATOM_OP_OR:
|
||||
assert(pco_ref_is_null(value_swap));
|
||||
repl = pco_logical_atomic(&b,
|
||||
dest,
|
||||
shmem_dest,
|
||||
shmem_src,
|
||||
value,
|
||||
.logiop = PCO_LOGIOP_OR);
|
||||
break;
|
||||
|
||||
case PCO_ATOM_OP_XOR:
|
||||
assert(pco_ref_is_null(value_swap));
|
||||
repl = pco_logical_atomic(&b,
|
||||
dest,
|
||||
shmem_dest,
|
||||
shmem_src,
|
||||
value,
|
||||
.logiop = PCO_LOGIOP_XOR);
|
||||
break;
|
||||
|
||||
default:
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
xfer_op_mods(repl, instr);
|
||||
|
||||
pco_instr_delete(instr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool try_legalize_large_hwreg_offsets(pco_instr *instr,
|
||||
const struct pco_op_info *info)
|
||||
{
|
||||
unsigned large_hwreg_count = 0;
|
||||
pco_ref *large_hwregs[_PCO_OP_MAX_SRCS + _PCO_OP_MAX_DESTS] = { 0 };
|
||||
|
||||
enum pco_reg_class hwreg_class = ~0;
|
||||
unsigned min_large_offset = ~0;
|
||||
ASSERTED unsigned max_large_offset = 0;
|
||||
|
||||
/* Check dests. */
|
||||
pco_foreach_instr_dest_hwreg (pdest, instr) {
|
||||
if (pco_ref_get_reg_index(*pdest) < 256)
|
||||
continue;
|
||||
|
||||
large_hwregs[large_hwreg_count++] = pdest;
|
||||
assert(hwreg_class == ~0 || hwreg_class == pco_ref_get_reg_class(*pdest));
|
||||
hwreg_class = pco_ref_get_reg_class(*pdest);
|
||||
|
||||
min_large_offset = MIN2(min_large_offset, pco_ref_get_reg_index(*pdest));
|
||||
max_large_offset = MAX2(max_large_offset, pco_ref_get_reg_index(*pdest));
|
||||
}
|
||||
|
||||
/* Check srcs. */
|
||||
pco_foreach_instr_src_hwreg (psrc, instr) {
|
||||
if (pco_ref_get_reg_index(*psrc) < 256)
|
||||
continue;
|
||||
|
||||
large_hwregs[large_hwreg_count++] = psrc;
|
||||
assert(hwreg_class == ~0 || hwreg_class == pco_ref_get_reg_class(*psrc));
|
||||
hwreg_class = pco_ref_get_reg_class(*psrc);
|
||||
|
||||
min_large_offset = MIN2(min_large_offset, pco_ref_get_reg_index(*psrc));
|
||||
max_large_offset = MAX2(max_large_offset, pco_ref_get_reg_index(*psrc));
|
||||
}
|
||||
|
||||
if (!large_hwreg_count)
|
||||
return false;
|
||||
|
||||
/* We'd need more than one indexed register to support this. */
|
||||
assert((max_large_offset - min_large_offset) < 256);
|
||||
|
||||
pco_builder b =
|
||||
pco_builder_create(instr->parent_func, pco_cursor_before_instr(instr));
|
||||
|
||||
unsigned idx_reg_num = 0;
|
||||
pco_ref idx_reg =
|
||||
pco_ref_hwreg_idx(idx_reg_num, idx_reg_num, PCO_REG_CLASS_INDEX);
|
||||
|
||||
pco_ref imm = pco_ref_imm32(min_large_offset);
|
||||
pco_movi32(&b, idx_reg, imm, .exec_cnd = pco_instr_get_exec_cnd(instr));
|
||||
|
||||
/* Remap the offset for each large hwreg and replace it with the indexed
|
||||
* register.
|
||||
*/
|
||||
for (unsigned u = 0; u < large_hwreg_count; ++u) {
|
||||
*large_hwregs[u] = pco_ref_offset(*large_hwregs[u], -min_large_offset);
|
||||
*large_hwregs[u] = pco_ref_hwreg_idx_from(idx_reg_num, *large_hwregs[u]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Insert pseudo fences around DITR and DITRP instructions.
|
||||
*
|
||||
* \param[in,out] instr PCO instr.
|
||||
* \return True if progress was made.
|
||||
*/
|
||||
static bool try_legalize_ditr_fence(pco_instr *instr)
|
||||
{
|
||||
if (instr->op != PCO_OP_DITR && instr->op != PCO_OP_DITRP)
|
||||
return false;
|
||||
|
||||
pco_builder b =
|
||||
pco_builder_create(instr->parent_func, pco_cursor_before_instr(instr));
|
||||
pco_fence(&b);
|
||||
|
||||
b.cursor = pco_cursor_after_instr(instr);
|
||||
pco_fence(&b);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Try to legalizes an instruction.
|
||||
*
|
||||
* \param[in,out] instr PCO instr.
|
||||
* \return True if progress was made.
|
||||
*/
|
||||
static bool try_legalize(pco_instr *instr)
|
||||
{
|
||||
const struct pco_op_info *info = &pco_op_info[instr->op];
|
||||
bool progress = false;
|
||||
|
||||
progress |= try_legalize_large_hwreg_offsets(instr, info);
|
||||
progress |= try_legalize_ditr_fence(instr);
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Legalizes instructions where additional restrictions apply.
|
||||
* This should be run after register allocation.
|
||||
*
|
||||
* \param[in,out] shader PCO shader.
|
||||
* \return True if the pass made progress.
|
||||
*/
|
||||
bool pco_pre_ra_legalize(pco_shader *shader)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
assert(!shader->is_grouped);
|
||||
assert(!shader->is_legalized);
|
||||
|
||||
const struct pco_op_info *info;
|
||||
|
||||
pco_foreach_func_in_shader (func, shader) {
|
||||
pco_foreach_instr_in_func_safe (instr, func) {
|
||||
info = &pco_op_info[instr->op];
|
||||
if (info->type != PCO_OP_TYPE_PSEUDO)
|
||||
progress |= try_legalize_src_mappings(instr, info);
|
||||
}
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Post-RA legalization pass.
|
||||
*
|
||||
* \param[in,out] shader PCO shader.
|
||||
* \return True if the pass made progress.
|
||||
*/
|
||||
bool pco_post_ra_legalize(pco_shader *shader)
|
||||
{
|
||||
assert(!shader->is_grouped);
|
||||
|
||||
bool progress = false;
|
||||
|
||||
pco_foreach_func_in_shader (func, shader) {
|
||||
pco_foreach_instr_in_func_safe (instr, func) {
|
||||
progress |= try_legalize(instr);
|
||||
}
|
||||
}
|
||||
|
||||
const struct pco_op_info *info;
|
||||
|
||||
pco_foreach_func_in_shader (func, shader) {
|
||||
pco_foreach_instr_in_func_safe (instr, func) {
|
||||
info = &pco_op_info[instr->op];
|
||||
if (info->type == PCO_OP_TYPE_PSEUDO)
|
||||
progress |= legalize_pseudo(instr);
|
||||
}
|
||||
}
|
||||
|
||||
shader->is_legalized = true;
|
||||
return progress;
|
||||
}
|
||||
@@ -0,0 +1,553 @@
|
||||
# Copyright © 2024 Imagination Technologies Ltd.
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
from mako.template import Template, exceptions
|
||||
from pco_map import *
|
||||
|
||||
template = """/*
|
||||
* Copyright © 2024 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef PCO_MAP_H
|
||||
#define PCO_MAP_H
|
||||
|
||||
/**
|
||||
* \\file pco_map.h
|
||||
*
|
||||
* \\brief PCO mapping definitions.
|
||||
*/
|
||||
|
||||
#include "pco_builder.h"
|
||||
#include "pco_common.h"
|
||||
#include "pco_internal.h"
|
||||
#include "pco_isa.h"
|
||||
#include "pco_ops.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/* Enum mappings. */
|
||||
% for enum_map in enum_maps.values():
|
||||
static inline
|
||||
${enum_map.type_to} ${enum_map.name}(${enum_map.type_from} val)
|
||||
{
|
||||
uint64_t to = 0;
|
||||
|
||||
% if enum_map.pass_zero_val is not None:
|
||||
if (!val)
|
||||
return ${enum_map.pass_zero_val};
|
||||
|
||||
% endif
|
||||
% if enum_map.both_bitsets:
|
||||
u_foreach_bit64 (b, val) {
|
||||
switch (b) {
|
||||
% for elem_from, elem_to in enum_map.mappings:
|
||||
case ${elem_from}:
|
||||
to |= ${elem_to};
|
||||
break;
|
||||
|
||||
% endfor
|
||||
default:
|
||||
UNREACHABLE("");
|
||||
}
|
||||
}
|
||||
% else:
|
||||
switch (val) {
|
||||
% for elem_from, elem_to in enum_map.mappings:
|
||||
case ${elem_from}:
|
||||
to = ${elem_to};
|
||||
break;
|
||||
|
||||
% endfor
|
||||
default:
|
||||
UNREACHABLE("");
|
||||
}
|
||||
% endif
|
||||
|
||||
return to;
|
||||
}
|
||||
|
||||
% endfor
|
||||
static inline
|
||||
enum pco_regbank pco_map_reg_bank(pco_ref ref)
|
||||
{
|
||||
if (pco_ref_is_idx_reg(ref)) {
|
||||
return PCO_REGBANK_IDX0 + ref.idx_reg.num;
|
||||
}
|
||||
|
||||
return pco_map_reg_class_to_regbank(pco_ref_get_reg_class(ref));
|
||||
}
|
||||
|
||||
static inline
|
||||
unsigned pco_map_reg_bank_bits(pco_ref ref)
|
||||
{
|
||||
return util_last_bit(pco_map_reg_bank(ref));
|
||||
}
|
||||
|
||||
static inline
|
||||
enum pco_idxbank pco_map_idx_bank(pco_ref ref)
|
||||
{
|
||||
assert(pco_ref_is_idx_reg(ref));
|
||||
return pco_map_reg_class_to_idxbank(ref.reg_class);
|
||||
}
|
||||
|
||||
static inline unsigned pco_map_reg_index(pco_ref ref)
|
||||
{
|
||||
if (pco_ref_is_reg(ref)) {
|
||||
switch (ref.reg_class) {
|
||||
case PCO_REG_CLASS_TEMP:
|
||||
case PCO_REG_CLASS_VTXIN:
|
||||
case PCO_REG_CLASS_COEFF:
|
||||
case PCO_REG_CLASS_SHARED:
|
||||
case PCO_REG_CLASS_SPEC:
|
||||
case PCO_REG_CLASS_CONST:
|
||||
return ref.val;
|
||||
|
||||
case PCO_REG_CLASS_INTERN:
|
||||
return ref.val + PCO_SR_INTL0;
|
||||
|
||||
case PCO_REG_CLASS_PIXOUT:
|
||||
if (ref.val >= 4)
|
||||
return ref.val + PCO_SR_PIXOUT4 - 4;
|
||||
else
|
||||
return ref.val + PCO_SR_PIXOUT0;
|
||||
|
||||
case PCO_REG_CLASS_GLOBAL:
|
||||
return ref.val + PCO_SR_GLOBAL0;
|
||||
|
||||
case PCO_REG_CLASS_SLOT:
|
||||
return (7 - ref.val) + PCO_SR_SLOT7;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (pco_ref_is_idx_reg(ref)) {
|
||||
return pco_map_idx_bank(ref) | (ref.idx_reg.offset << 3);
|
||||
}
|
||||
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
static inline unsigned pco_map_reg_index_bits(pco_ref ref)
|
||||
{
|
||||
if (pco_ref_is_reg(ref))
|
||||
return util_last_bit(pco_map_reg_index(ref));
|
||||
else if (pco_ref_is_idx_reg(ref))
|
||||
return 11;
|
||||
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
static inline
|
||||
enum pco_igrp_hdr_variant pco_igrp_hdr_variant(pco_igrp *igrp)
|
||||
{
|
||||
if (igrp->hdr.alutype == PCO_ALUTYPE_BITWISE)
|
||||
return PCO_IGRP_HDR_BITWISE;
|
||||
else if (igrp->hdr.alutype == PCO_ALUTYPE_CONTROL)
|
||||
return PCO_IGRP_HDR_CONTROL;
|
||||
else
|
||||
assert(igrp->hdr.alutype == PCO_ALUTYPE_MAIN);
|
||||
|
||||
if (!igrp->hdr.end && !igrp->hdr.atom && !igrp->hdr.rpt && !igrp->hdr.cc)
|
||||
return PCO_IGRP_HDR_MAIN_BRIEF;
|
||||
|
||||
return PCO_IGRP_HDR_MAIN;
|
||||
}
|
||||
|
||||
static inline
|
||||
enum pco_src_variant pco_igrp_src_variant(const pco_igrp *igrp,
|
||||
bool is_upper)
|
||||
{
|
||||
unsigned offset = is_upper ? ROGUE_ALU_INPUT_GROUP_SIZE : 0;
|
||||
|
||||
pco_ref sA = igrp->srcs.s[0 + offset];
|
||||
pco_ref sB = igrp->srcs.s[1 + offset];
|
||||
pco_ref sC = igrp->srcs.s[2 + offset];
|
||||
pco_ref mux = is_upper ? pco_ref_null() : igrp->iss.is[0];
|
||||
|
||||
bool sA_set = !pco_ref_is_null(sA);
|
||||
bool sB_set = !pco_ref_is_null(sB);
|
||||
bool sC_set = !pco_ref_is_null(sC);
|
||||
bool mux_set = !pco_ref_is_null(mux);
|
||||
|
||||
int sbA_bits = sA_set ? pco_map_reg_bank_bits(sA) : -1;
|
||||
int sA_bits = sA_set ? pco_map_reg_index_bits(sA) : -1;
|
||||
|
||||
int sbB_bits = sB_set ? pco_map_reg_bank_bits(sB) : -1;
|
||||
int sB_bits = sB_set ? pco_map_reg_index_bits(sB) : -1;
|
||||
|
||||
int sbC_bits = sC_set ? pco_map_reg_bank_bits(sC) : -1;
|
||||
int sC_bits = sC_set ? pco_map_reg_index_bits(sC) : -1;
|
||||
|
||||
int mux_bits = mux_set ? util_last_bit(pco_map_io_to_is0_sel(pco_ref_get_io(mux))) : -1;
|
||||
|
||||
bool is_ctrl = igrp->hdr.alutype == PCO_ALUTYPE_CONTROL;
|
||||
bool no_srcs_set = !sA_set && !sB_set && !sC_set && !mux_set;
|
||||
if (is_ctrl && no_srcs_set)
|
||||
return PCO_SRC_NONE;
|
||||
|
||||
% for variant, spec in [(bs.name.upper(), bs.data) for bs in I_SRC.bit_structs.values()]:
|
||||
${'else ' if not loop.first else ''}if (${'!' if not spec.is_upper else ''}is_upper &&
|
||||
sbA_bits ${'==' if spec.sbA_bits == -1 else '<='} ${spec.sbA_bits} && sA_bits ${'==' if spec.sA_bits == -1 else '<='} ${spec.sA_bits} &&
|
||||
sbB_bits ${'==' if spec.sbB_bits == -1 else '<='} ${spec.sbB_bits} && sB_bits ${'==' if spec.sB_bits == -1 else '<='} ${spec.sB_bits} &&
|
||||
sbC_bits ${'==' if spec.sbC_bits == -1 else '<='} ${spec.sbC_bits} && sC_bits ${'==' if spec.sC_bits == -1 else '<='} ${spec.sC_bits} &&
|
||||
mux_bits ${'==' if spec.mux_bits == -1 else '<='} ${spec.mux_bits}) {
|
||||
return ${variant};
|
||||
}
|
||||
% endfor
|
||||
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
static inline
|
||||
enum pco_iss_variant pco_igrp_iss_variant(const pco_igrp *igrp)
|
||||
{
|
||||
if (igrp->hdr.alutype == PCO_ALUTYPE_MAIN)
|
||||
return PCO_ISS_ISS;
|
||||
|
||||
return PCO_ISS_NONE;
|
||||
}
|
||||
|
||||
static inline
|
||||
enum pco_dst_variant pco_igrp_dest_variant(pco_igrp *igrp)
|
||||
{
|
||||
pco_ref w0 = igrp->dests.w[0];
|
||||
pco_ref w1 = igrp->dests.w[1];
|
||||
|
||||
bool w0_set = !pco_ref_is_null(w0);
|
||||
bool w1_set = !pco_ref_is_null(w1);
|
||||
|
||||
bool no_dsts = !w0_set && !w1_set;
|
||||
bool one_dest = w0_set != w1_set;
|
||||
bool dual_dsts = w0_set && w1_set;
|
||||
|
||||
if (no_dsts)
|
||||
return PCO_DST_NONE;
|
||||
|
||||
int db0_bits = w0_set ? pco_map_reg_bank_bits(w0) : -1;
|
||||
int d0_bits = w0_set ? pco_map_reg_index_bits(w0) : -1;
|
||||
|
||||
int db1_bits = w1_set ? pco_map_reg_bank_bits(w1) : -1;
|
||||
int d1_bits = w1_set ? pco_map_reg_index_bits(w1) : -1;
|
||||
|
||||
int dbN_bits = w0_set ? db0_bits : db1_bits;
|
||||
int dN_bits = w0_set ? d0_bits : d1_bits;
|
||||
|
||||
if (one_dest) {
|
||||
db0_bits = dbN_bits;
|
||||
d0_bits = dN_bits;
|
||||
|
||||
db1_bits = -1;
|
||||
d1_bits = -1;
|
||||
}
|
||||
|
||||
% for variant, spec in [(bs.name.upper(), bs.data) for bs in I_DST.bit_structs.values()]:
|
||||
${'else ' if not loop.first else ''}if (${'!' if not spec.dual_dsts else ''}dual_dsts &&
|
||||
db0_bits ${'==' if spec.db0_bits == -1 else '<='} ${spec.db0_bits} && d0_bits ${'==' if spec.d0_bits == -1 else '<='} ${spec.d0_bits} &&
|
||||
db1_bits ${'==' if spec.db1_bits == -1 else '<='} ${spec.db1_bits} && d1_bits ${'==' if spec.d1_bits == -1 else '<='} ${spec.d1_bits}) {
|
||||
return ${variant};
|
||||
}
|
||||
% endfor
|
||||
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
% for encode_map in encode_maps.values():
|
||||
static inline
|
||||
unsigned ${encode_map.name}_variant(pco_instr *instr)
|
||||
{
|
||||
% if len(encode_map.variants) > 1:
|
||||
% for variant, _, conds in encode_map.variants[1:]:
|
||||
${conds.format('bin', 'instr', 'variant')}
|
||||
return ${variant};
|
||||
% endfor
|
||||
|
||||
% endif
|
||||
return ${encode_map.variants[0][0]};
|
||||
}
|
||||
|
||||
% endfor
|
||||
/* Instruction group mappings. */
|
||||
% for group_map in group_maps.values():
|
||||
static inline
|
||||
void ${group_map.name}_map_igrp(pco_igrp *igrp, pco_instr *instr)
|
||||
{
|
||||
% for mapping_set in group_map.mapping_sets:
|
||||
% for mapping in mapping_set:
|
||||
${mapping.format('igrp', 'instr')}
|
||||
% endfor
|
||||
|
||||
% endfor
|
||||
igrp->variant.hdr = pco_igrp_hdr_variant(igrp);
|
||||
igrp->variant.lower_src = pco_igrp_src_variant(igrp, false);
|
||||
igrp->variant.upper_src = pco_igrp_src_variant(igrp, true);
|
||||
igrp->variant.iss = pco_igrp_iss_variant(igrp);
|
||||
igrp->variant.dest = pco_igrp_dest_variant(igrp);
|
||||
}
|
||||
|
||||
% endfor
|
||||
static inline
|
||||
void pco_map_igrp(pco_igrp *igrp, pco_instr *instr)
|
||||
{
|
||||
switch (instr->op) {
|
||||
% for group_map in group_maps.values():
|
||||
case ${group_map.cop_name}:
|
||||
return ${group_map.name}_map_igrp(igrp, instr);
|
||||
|
||||
% endfor
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const struct pco_op_info *info = &pco_op_info[instr->op];
|
||||
printf("Instruction group mapping not defined for %s op '%s'.\\n",
|
||||
info->type == PCO_OP_TYPE_PSEUDO ? "pseudo" : "hardware",
|
||||
info->str);
|
||||
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
static inline unsigned pco_igrp_hdr_map_encode(uint8_t *bin, pco_igrp *igrp)
|
||||
{
|
||||
switch (igrp->variant.hdr) {
|
||||
case PCO_IGRP_HDR_MAIN_BRIEF:
|
||||
return pco_igrp_hdr_main_brief_encode(bin,
|
||||
.da = igrp->hdr.da,
|
||||
.length = igrp->hdr.length,
|
||||
.oporg = igrp->hdr.oporg,
|
||||
.olchk = igrp->hdr.olchk,
|
||||
.w1p = igrp->hdr.w1p,
|
||||
.w0p = igrp->hdr.w0p,
|
||||
.cc = igrp->hdr.cc);
|
||||
|
||||
case PCO_IGRP_HDR_MAIN:
|
||||
return pco_igrp_hdr_main_encode(bin,
|
||||
.da = igrp->hdr.da,
|
||||
.length = igrp->hdr.length,
|
||||
.oporg = igrp->hdr.oporg,
|
||||
.olchk = igrp->hdr.olchk,
|
||||
.w1p = igrp->hdr.w1p,
|
||||
.w0p = igrp->hdr.w0p,
|
||||
.cc = igrp->hdr.cc,
|
||||
.end = igrp->hdr.end,
|
||||
.atom = igrp->hdr.atom,
|
||||
.rpt = igrp->hdr.rpt);
|
||||
|
||||
case PCO_IGRP_HDR_BITWISE:
|
||||
return pco_igrp_hdr_bitwise_encode(bin,
|
||||
.da = igrp->hdr.da,
|
||||
.length = igrp->hdr.length,
|
||||
.opcnt = igrp->hdr.opcnt,
|
||||
.olchk = igrp->hdr.olchk,
|
||||
.w1p = igrp->hdr.w1p,
|
||||
.w0p = igrp->hdr.w0p,
|
||||
.cc = igrp->hdr.cc,
|
||||
.end = igrp->hdr.end,
|
||||
.atom = igrp->hdr.atom,
|
||||
.rpt = igrp->hdr.rpt);
|
||||
|
||||
case PCO_IGRP_HDR_CONTROL:
|
||||
return pco_igrp_hdr_control_encode(bin,
|
||||
.da = igrp->hdr.da,
|
||||
.length = igrp->hdr.length,
|
||||
.olchk = igrp->hdr.olchk,
|
||||
.w1p = igrp->hdr.w1p,
|
||||
.w0p = igrp->hdr.w0p,
|
||||
.cc = igrp->hdr.cc,
|
||||
.miscctl = igrp->hdr.miscctl,
|
||||
.ctrlop = igrp->hdr.ctrlop);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
% for encode_map in encode_maps.values():
|
||||
static inline
|
||||
% if len(encode_map.variants) > 1:
|
||||
unsigned ${encode_map.name}_map_encode(uint8_t *bin, pco_instr *instr, unsigned variant)
|
||||
{
|
||||
switch (variant) {
|
||||
% for variant, mapping, _ in encode_map.variants:
|
||||
case ${variant}:
|
||||
return ${mapping.format('bin', 'instr', 'variant')};
|
||||
|
||||
% endfor
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UNREACHABLE("");
|
||||
}
|
||||
% else:
|
||||
unsigned ${encode_map.name}_map_encode(uint8_t *bin, pco_instr *instr)
|
||||
{
|
||||
return ${encode_map.variants[0][1].format('bin', 'instr', 'variant')};
|
||||
}
|
||||
% endif
|
||||
|
||||
% endfor
|
||||
static inline
|
||||
unsigned pco_instr_map_encode(uint8_t *bin, pco_igrp *igrp, enum pco_op_phase phase)
|
||||
{
|
||||
pco_instr *instr = igrp->instrs[phase];
|
||||
switch (instr->op) {
|
||||
% for encode_map in encode_maps.values():
|
||||
case ${encode_map.cop_name}:
|
||||
% if len(encode_map.variants) > 1:
|
||||
return ${encode_map.name}_map_encode(bin, instr, pco_igrp_variant(igrp, phase));
|
||||
% else:
|
||||
return ${encode_map.name}_map_encode(bin, instr);
|
||||
% endif
|
||||
|
||||
% endfor
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
static inline
|
||||
unsigned pco_srcs_map_encode(uint8_t *bin, pco_igrp *igrp, bool is_upper)
|
||||
{
|
||||
unsigned offset = is_upper ? ROGUE_ALU_INPUT_GROUP_SIZE : 0;
|
||||
|
||||
pco_ref _sA = igrp->srcs.s[0 + offset];
|
||||
pco_ref _sB = igrp->srcs.s[1 + offset];
|
||||
pco_ref _sC = igrp->srcs.s[2 + offset];
|
||||
pco_ref _mux = is_upper ? pco_ref_null() : igrp->iss.is[0];
|
||||
|
||||
bool sA_set = !pco_ref_is_null(_sA);
|
||||
bool sB_set = !pco_ref_is_null(_sB);
|
||||
bool sC_set = !pco_ref_is_null(_sC);
|
||||
bool mux_set = !pco_ref_is_null(_mux);
|
||||
|
||||
unsigned sbA = sA_set ? pco_map_reg_bank(_sA) : 0;
|
||||
unsigned sA = sA_set ? pco_map_reg_index(_sA) : 0;
|
||||
|
||||
unsigned sbB = sB_set ? pco_map_reg_bank(_sB) : 0;
|
||||
unsigned sB = sB_set ? pco_map_reg_index(_sB) : 0;
|
||||
|
||||
unsigned sbC = sC_set ? pco_map_reg_bank(_sC) : 0;
|
||||
unsigned sC = sC_set ? pco_map_reg_index(_sC) : 0;
|
||||
|
||||
unsigned mux = mux_set ? pco_map_io_to_is0_sel(pco_ref_get_io(_mux)) : 0;
|
||||
|
||||
enum pco_src_variant variant = is_upper ? igrp->variant.upper_src : igrp->variant.lower_src;
|
||||
switch (variant) {
|
||||
% for variant, encode_func, spec, offset in [(bs.name.upper(), f'{bs.name}_encode', bs.data, 3 if bs.data.is_upper else 0) for bs in I_SRC.bit_structs.values()]:
|
||||
case ${variant}:
|
||||
return ${encode_func}(bin,
|
||||
% if spec.sbA_bits != -1:
|
||||
.s${offset + 0} = sA,
|
||||
.sb${offset + 0} = sbA,
|
||||
% endif
|
||||
% if spec.sbB_bits != -1:
|
||||
.s${offset + 1} = sB,
|
||||
.sb${offset + 1} = sbB,
|
||||
% endif
|
||||
% if spec.sbC_bits != -1:
|
||||
.s${offset + 2} = sC,
|
||||
.sb${offset + 2} = sbC,
|
||||
% endif
|
||||
% if spec.mux_bits != -1:
|
||||
.is0 = mux,
|
||||
% endif
|
||||
);
|
||||
|
||||
% endfor
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
static inline
|
||||
unsigned pco_iss_map_encode(uint8_t *bin, pco_igrp *igrp)
|
||||
{
|
||||
bool is5_set = !pco_ref_is_null(igrp->iss.is[5]);
|
||||
bool is4_set = !pco_ref_is_null(igrp->iss.is[4]);
|
||||
bool is3_set = !pco_ref_is_null(igrp->iss.is[3]);
|
||||
bool is2_set = !pco_ref_is_null(igrp->iss.is[2]);
|
||||
bool is1_set = !pco_ref_is_null(igrp->iss.is[1]);
|
||||
|
||||
unsigned is5 = is5_set ? pco_map_io_to_is5_sel(pco_ref_get_io(igrp->iss.is[5])) : 0;
|
||||
unsigned is4 = is4_set ? pco_map_io_to_is4_sel(pco_ref_get_io(igrp->iss.is[4])) : 0;
|
||||
unsigned is3 = is3_set ? pco_map_io_to_is3_sel(pco_ref_get_io(igrp->iss.is[3])) : 0;
|
||||
unsigned is2 = is2_set ? pco_map_io_to_is2_sel(pco_ref_get_io(igrp->iss.is[2])) : 0;
|
||||
unsigned is1 = is1_set ? pco_map_io_to_is1_sel(pco_ref_get_io(igrp->iss.is[1])) : 0;
|
||||
|
||||
assert(igrp->variant.iss == PCO_ISS_ISS);
|
||||
return pco_iss_iss_encode(bin, .is5 = is5, .is4 = is4, .is3 = is3, .is2 = is2, .is1 = is1);
|
||||
}
|
||||
|
||||
static inline
|
||||
unsigned pco_dests_map_encode(uint8_t *bin, pco_igrp *igrp)
|
||||
{
|
||||
pco_ref w0 = igrp->dests.w[0];
|
||||
pco_ref w1 = igrp->dests.w[1];
|
||||
|
||||
bool w0_set = !pco_ref_is_null(w0);
|
||||
bool w1_set = !pco_ref_is_null(w1);
|
||||
|
||||
bool one_dest = w0_set != w1_set;
|
||||
|
||||
int db0 = w0_set ? pco_map_reg_bank(w0) : 0;
|
||||
int d0 = w0_set ? pco_map_reg_index(w0) : 0;
|
||||
|
||||
int db1 = w1_set ? pco_map_reg_bank(w1) : 0;
|
||||
int d1 = w1_set ? pco_map_reg_index(w1) : 0;
|
||||
|
||||
int dbN = w0_set ? db0 : db1;
|
||||
int dN = w0_set ? d0 : d1;
|
||||
|
||||
if (one_dest) {
|
||||
db0 = dbN;
|
||||
d0 = dN;
|
||||
|
||||
db1 = 0;
|
||||
d1 = 0;
|
||||
}
|
||||
|
||||
switch (igrp->variant.dest) {
|
||||
% for variant, encode_func, spec in [(bs.name.upper(), f'{bs.name}_encode', bs.data) for bs in I_DST.bit_structs.values()]:
|
||||
case ${variant}:
|
||||
return ${encode_func}(bin,
|
||||
% if spec.db0_bits != -1:
|
||||
% if spec.dual_dsts:
|
||||
.d0 = d0,
|
||||
.db0 = db0,
|
||||
% else:
|
||||
.dN = d0,
|
||||
.dbN = db0,
|
||||
% endif
|
||||
% endif
|
||||
% if spec.db1_bits != -1:
|
||||
.d1 = d1,
|
||||
.db1 = db1,
|
||||
% endif
|
||||
);
|
||||
|
||||
% endfor
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UNREACHABLE("");
|
||||
}
|
||||
#endif /* PCO_MAP_H */"""
|
||||
|
||||
def main():
|
||||
try:
|
||||
print(Template(template).render(enum_maps=enum_maps, group_maps=group_maps, encode_maps=encode_maps, I_SRC=I_SRC, I_DST=I_DST))
|
||||
except:
|
||||
raise Exception(exceptions.text_error_template().render())
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,88 @@
|
||||
# Copyright © 2025 Imagination Technologies Ltd.
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import math
|
||||
|
||||
a = 'a'
|
||||
b = 'b'
|
||||
|
||||
lower_algebraic = []
|
||||
lower_algebraic_late = []
|
||||
|
||||
def lowered_fround_even(src):
|
||||
abs_src = ('fabs', src)
|
||||
ffloor_temp = ('ffloor', abs_src)
|
||||
ffract_temp = ('ffract', abs_src)
|
||||
|
||||
ceil_temp = ('fadd', ffloor_temp, 1.0)
|
||||
even_temp = ('fmul', ffloor_temp, 0.5)
|
||||
|
||||
even_ffract_temp = ('ffract', even_temp)
|
||||
|
||||
ishalf_temp = ('feq', ffract_temp, 0.5)
|
||||
ffract_temp = ('bcsel', ishalf_temp, even_ffract_temp, ffract_temp)
|
||||
|
||||
lesshalf_temp = ('flt', ffract_temp, 0.5)
|
||||
result_temp = ('bcsel', lesshalf_temp, ffloor_temp, ceil_temp)
|
||||
|
||||
res = ('fcopysign_pco', result_temp, src)
|
||||
return res
|
||||
|
||||
lower_algebraic.append((('fround_even', a), lowered_fround_even(a)))
|
||||
|
||||
lower_insert_extract = [
|
||||
(('insert_u8', 'a@32', b), ('bitfield_insert', 0, a, ('imul', b, 8), 8)),
|
||||
(('insert_u16', 'a@32', b), ('bitfield_insert', 0, a, ('imul', b, 16), 16)),
|
||||
|
||||
(('extract_u8', 'a@32', b), ('ubitfield_extract', a, ('imul', b, 8), 8)),
|
||||
(('extract_i8', 'a@32', b), ('ibitfield_extract', a, ('imul', b, 8), 8)),
|
||||
|
||||
(('extract_u16', 'a@32', b), ('ubitfield_extract', a, ('imul', b, 16), 16)),
|
||||
(('extract_i16', 'a@32', b), ('ibitfield_extract', a, ('imul', b, 16), 16)),
|
||||
]
|
||||
|
||||
lower_algebraic_late.extend(lower_insert_extract)
|
||||
|
||||
lower_b2b = [
|
||||
(('b2b32', a), ('ineg', ('b2i32', a))),
|
||||
(('b2b1', a), ('ine', a, 0)),
|
||||
]
|
||||
|
||||
lower_algebraic.extend(lower_b2b)
|
||||
|
||||
lower_scmp = [
|
||||
# Float comparisons + bool conversions.
|
||||
(('b2f32', ('flt', a, b)), ('slt', a, 'b@32'), '!options->lower_scmp'),
|
||||
(('b2f32', ('fge', a, b)), ('sge', a, 'b@32'), '!options->lower_scmp'),
|
||||
(('b2f32', ('feq', a, b)), ('seq', a, 'b@32'), '!options->lower_scmp'),
|
||||
(('b2f32', ('fneu', a, b)), ('sne', a, 'b@32'), '!options->lower_scmp'),
|
||||
|
||||
# Float comparisons + bool conversions via bcsel.
|
||||
(('bcsel@32', ('flt', a, b), 1.0, 0.0), ('slt', a, 'b@32'), '!options->lower_scmp'),
|
||||
(('bcsel@32', ('fge', a, b), 1.0, 0.0), ('sge', a, 'b@32'), '!options->lower_scmp'),
|
||||
(('bcsel@32', ('feq', a, b), 1.0, 0.0), ('seq', a, 'b@32'), '!options->lower_scmp'),
|
||||
(('bcsel@32', ('fneu', a, b), 1.0, 0.0), ('sne', a, 'b@32'), '!options->lower_scmp'),
|
||||
]
|
||||
|
||||
lower_algebraic_late.extend(lower_scmp)
|
||||
|
||||
# TODO: core-specific info.
|
||||
params=[]
|
||||
|
||||
def run():
|
||||
import nir_algebraic # pylint: disable=import-error
|
||||
print('#include "pco_internal.h"')
|
||||
print(nir_algebraic.AlgebraicPass('pco_nir_lower_algebraic', lower_algebraic, params=params).render())
|
||||
print(nir_algebraic.AlgebraicPass('pco_nir_lower_algebraic_late', lower_algebraic_late, params=params).render())
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-p', '--import-path', required=True)
|
||||
args = parser.parse_args()
|
||||
sys.path.insert(0, args.import_path)
|
||||
run()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright © 2025 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file pco_nir_compute.c
|
||||
*
|
||||
* \brief PCO NIR compute-specific passes.
|
||||
*/
|
||||
|
||||
#include "nir.h"
|
||||
#include "nir_builder.h"
|
||||
#include "pco.h"
|
||||
#include "pco_builder.h"
|
||||
#include "pco_internal.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* \brief Inserts the instance check.
|
||||
*
|
||||
* \param[in,out] entrypoint NIR shader entrypoint.
|
||||
* \return The cursor position for where to re-insert the entrypoint.
|
||||
*/
|
||||
static nir_cursor insert_instance_check(nir_function_impl *entrypoint)
|
||||
{
|
||||
nir_builder b = nir_builder_at(nir_before_impl(entrypoint));
|
||||
nir_cursor cursor;
|
||||
|
||||
/* If the current instance index is greater than the total workgroup size,
|
||||
* we don't execute.
|
||||
*/
|
||||
nir_def *local_size = nir_load_workgroup_size(&b);
|
||||
nir_def *size_x = nir_channel(&b, local_size, 0);
|
||||
nir_def *size_y = nir_channel(&b, local_size, 1);
|
||||
nir_def *size_z = nir_channel(&b, local_size, 2);
|
||||
nir_def *flat_size = nir_imul(&b, nir_imul(&b, size_x, size_y), size_z);
|
||||
|
||||
nir_def *flat_id = nir_load_local_invocation_index(&b);
|
||||
|
||||
nir_def *cond_inst_valid = nir_ilt(&b, flat_id, flat_size);
|
||||
nir_if *nif = nir_push_if(&b, cond_inst_valid);
|
||||
{
|
||||
cursor = b.cursor;
|
||||
}
|
||||
nir_pop_if(&b, nif);
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Inserts an instance check for compute shaders.
|
||||
*
|
||||
* \param[in,out] shader NIR shader.
|
||||
* \return True if the pass made progress.
|
||||
*/
|
||||
bool pco_nir_compute_instance_check(nir_shader *shader)
|
||||
{
|
||||
assert(shader->info.stage == MESA_SHADER_COMPUTE);
|
||||
|
||||
if (shader->info.internal)
|
||||
return false;
|
||||
|
||||
nir_function_impl *entrypoint = nir_shader_get_entrypoint(shader);
|
||||
|
||||
if (nir_cf_list_is_empty_block(&entrypoint->body))
|
||||
return false;
|
||||
|
||||
/* Extract the entire entrypoint. */
|
||||
nir_cf_list cf_list;
|
||||
nir_cf_extract(&cf_list,
|
||||
nir_before_impl(entrypoint),
|
||||
nir_after_impl(entrypoint));
|
||||
|
||||
nir_cursor cursor = insert_instance_check(entrypoint);
|
||||
|
||||
/* Re-insert the entrypoint inside the instance check. */
|
||||
nir_cf_reinsert(&cf_list, cursor);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright © 2025 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file pco_nir_io.c
|
||||
*
|
||||
* \brief PCO NIR I/O lowering pass.
|
||||
*/
|
||||
|
||||
#include "nir.h"
|
||||
#include "nir_builder.h"
|
||||
#include "pco.h"
|
||||
#include "pco_builder.h"
|
||||
#include "pco_internal.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* \brief Lowers an I/O instruction.
|
||||
*
|
||||
* \param[in] b NIR builder.
|
||||
* \param[in] intr NIR intrinsic instruction.
|
||||
* \param[in] cb_data User callback data.
|
||||
* \return True if progress was made.
|
||||
*/
|
||||
static bool
|
||||
lower_io(nir_builder *b, nir_intrinsic_instr *intr, UNUSED void *cb_data)
|
||||
{
|
||||
b->cursor = nir_before_instr(&intr->instr);
|
||||
|
||||
switch (intr->intrinsic) {
|
||||
case nir_intrinsic_load_push_constant:
|
||||
case nir_intrinsic_load_shared:
|
||||
case nir_intrinsic_shared_atomic:
|
||||
case nir_intrinsic_shared_atomic_swap:
|
||||
case nir_intrinsic_store_shared:
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
nir_src *offset_src = nir_get_io_offset_src(intr);
|
||||
|
||||
ASSERTED unsigned base = nir_intrinsic_base(intr);
|
||||
assert(!base);
|
||||
|
||||
/* Byte offset to DWORD offset. */
|
||||
nir_src_rewrite(offset_src, nir_ushr_imm(b, offset_src->ssa, 2));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief I/O lowering pass.
|
||||
*
|
||||
* \param[in,out] shader NIR shader.
|
||||
* \return True if the pass made progress.
|
||||
*/
|
||||
bool pco_nir_lower_io(nir_shader *shader)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
progress |= nir_shader_intrinsics_pass(shader,
|
||||
lower_io,
|
||||
nir_metadata_control_flow,
|
||||
NULL);
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
static bool lower_shared_io_to_global(nir_builder *b,
|
||||
nir_intrinsic_instr *intr,
|
||||
void *cb_data)
|
||||
{
|
||||
switch (intr->intrinsic) {
|
||||
case nir_intrinsic_load_shared:
|
||||
case nir_intrinsic_store_shared:
|
||||
case nir_intrinsic_shared_atomic:
|
||||
case nir_intrinsic_shared_atomic_swap:
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
struct shader_info *info = &b->shader->info;
|
||||
unsigned local_size = info->workgroup_size[0] *
|
||||
info->workgroup_size[1] *
|
||||
info->workgroup_size[2];
|
||||
|
||||
unsigned usc_slots = *((unsigned *)cb_data);
|
||||
assert(usc_slots);
|
||||
|
||||
b->cursor = nir_before_instr(&intr->instr);
|
||||
|
||||
/* If each wg fits inside a slot, then we run one wg per _slot_, so:
|
||||
*
|
||||
* wg_idx = (cluster_num * slots_per_cluster) + slot_num
|
||||
*
|
||||
* otherwise if > 1 slot is required, we run one wg per _cluster_:
|
||||
*
|
||||
* wg_idx = cluster_num
|
||||
*/
|
||||
nir_def *wg_idx = nir_load_cluster_num_pco(b);
|
||||
if (local_size <= ROGUE_MAX_INSTANCES_PER_TASK) {
|
||||
wg_idx = nir_imul_imm(b, wg_idx, usc_slots);
|
||||
wg_idx = nir_iadd(b, wg_idx, nir_load_slot_num_pco(b));
|
||||
}
|
||||
|
||||
nir_src *offset_src = nir_get_io_offset_src(intr);
|
||||
nir_def *shmem_buf_offset = nir_imul_imm(b, wg_idx, info->shared_size);
|
||||
nir_def *offset = nir_iadd(b, offset_src->ssa, shmem_buf_offset);
|
||||
|
||||
nir_def *shared_base_ptr = nir_load_shared_base_ptr(b, 2, 32);
|
||||
nir_def *shared_base_ptr_lo = nir_channel(b, shared_base_ptr, 0);
|
||||
nir_def *shared_base_ptr_hi = nir_channel(b, shared_base_ptr, 1);
|
||||
nir_def *addr =
|
||||
nir_uadd64_32(b, shared_base_ptr_lo, shared_base_ptr_hi, offset);
|
||||
|
||||
switch (intr->intrinsic) {
|
||||
case nir_intrinsic_load_shared: {
|
||||
nir_def *repl =
|
||||
nir_load_global_2x32(b,
|
||||
intr->def.num_components,
|
||||
intr->def.bit_size,
|
||||
addr,
|
||||
.align_mul = nir_intrinsic_align_mul(intr),
|
||||
.align_offset = nir_intrinsic_align_offset(intr));
|
||||
|
||||
nir_def_replace(&intr->def, repl);
|
||||
nir_instr_free(&intr->instr);
|
||||
break;
|
||||
}
|
||||
|
||||
case nir_intrinsic_store_shared: {
|
||||
nir_def *value = intr->src[0].ssa;
|
||||
nir_store_global_2x32(b,
|
||||
value,
|
||||
addr,
|
||||
.write_mask = nir_intrinsic_write_mask(intr),
|
||||
.align_mul = nir_intrinsic_align_mul(intr),
|
||||
.align_offset = nir_intrinsic_align_offset(intr));
|
||||
|
||||
nir_instr_remove(&intr->instr);
|
||||
break;
|
||||
}
|
||||
|
||||
case nir_intrinsic_shared_atomic: {
|
||||
nir_def *data = intr->src[1].ssa;
|
||||
nir_def *repl =
|
||||
nir_global_atomic_2x32(b,
|
||||
intr->def.bit_size,
|
||||
addr,
|
||||
data,
|
||||
.atomic_op = nir_intrinsic_atomic_op(intr));
|
||||
|
||||
nir_def_replace(&intr->def, repl);
|
||||
nir_instr_free(&intr->instr);
|
||||
break;
|
||||
}
|
||||
|
||||
case nir_intrinsic_shared_atomic_swap: {
|
||||
nir_def *data = intr->src[1].ssa;
|
||||
nir_def *data2 = intr->src[2].ssa;
|
||||
nir_def *repl =
|
||||
nir_global_atomic_swap_2x32(b,
|
||||
intr->def.bit_size,
|
||||
addr,
|
||||
data,
|
||||
data2,
|
||||
.atomic_op = nir_intrinsic_atomic_op(intr));
|
||||
|
||||
nir_def_replace(&intr->def, repl);
|
||||
nir_instr_free(&intr->instr);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
UNREACHABLE("Unexpected intrinsic.");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pco_nir_lower_shared_io_to_global(nir_shader *shader, unsigned usc_slots)
|
||||
{
|
||||
return nir_shader_intrinsics_pass(shader,
|
||||
lower_shared_io_to_global,
|
||||
nir_metadata_control_flow,
|
||||
&usc_slots);
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright © 2025 Imagination Technologies Ltd.
|
||||
* Copyright (C) 2020-2021 Collabora, Ltd.
|
||||
* Copyright © 2020 Valve Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "compiler/nir/nir.h"
|
||||
#include "compiler/nir/nir_builder.h"
|
||||
#include "pco_internal.h"
|
||||
|
||||
static nir_def *get_is_null(nir_builder *b,
|
||||
nir_instr *instr,
|
||||
nir_def **def,
|
||||
pco_nir_lower_null_descriptor_options options)
|
||||
{
|
||||
bool is_deref = false;
|
||||
*def = NULL;
|
||||
|
||||
if (instr->type == nir_instr_type_intrinsic) {
|
||||
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
|
||||
switch (intr->intrinsic) {
|
||||
case nir_intrinsic_image_deref_size:
|
||||
case nir_intrinsic_image_deref_levels:
|
||||
case nir_intrinsic_image_deref_samples:
|
||||
case nir_intrinsic_image_deref_load:
|
||||
case nir_intrinsic_image_deref_store:
|
||||
case nir_intrinsic_image_deref_atomic:
|
||||
case nir_intrinsic_image_deref_atomic_swap:
|
||||
if (!(options & pco_nir_lower_null_descriptor_image))
|
||||
return NULL;
|
||||
|
||||
is_deref = true;
|
||||
break;
|
||||
|
||||
case nir_intrinsic_get_ubo_size:
|
||||
case nir_intrinsic_load_ubo:
|
||||
if (!(options & pco_nir_lower_null_descriptor_ubo))
|
||||
return NULL;
|
||||
|
||||
break;
|
||||
|
||||
case nir_intrinsic_get_ssbo_size:
|
||||
case nir_intrinsic_load_ssbo:
|
||||
case nir_intrinsic_ssbo_atomic:
|
||||
case nir_intrinsic_ssbo_atomic_swap:
|
||||
case nir_intrinsic_store_ssbo:
|
||||
if (!(options & pco_nir_lower_null_descriptor_ssbo))
|
||||
return NULL;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nir_src *index = nir_get_io_index_src(intr);
|
||||
assert(index || is_deref);
|
||||
|
||||
if (nir_intrinsic_infos[intr->intrinsic].has_dest)
|
||||
*def = &intr->def;
|
||||
|
||||
return nir_is_null_descriptor(b,
|
||||
is_deref ? intr->src[0].ssa : index->ssa);
|
||||
}
|
||||
|
||||
if (instr->type == nir_instr_type_tex) {
|
||||
if (!(options & pco_nir_lower_null_descriptor_texture))
|
||||
return NULL;
|
||||
|
||||
nir_tex_instr *tex = nir_instr_as_tex(instr);
|
||||
nir_def *deref_def = nir_get_tex_src(tex, nir_tex_src_texture_deref);
|
||||
if (!deref_def)
|
||||
return NULL;
|
||||
|
||||
*def = &tex->def;
|
||||
return nir_is_null_descriptor(b, deref_def);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool lower(nir_builder *b, nir_instr *instr, void *data)
|
||||
{
|
||||
pco_nir_lower_null_descriptor_options *options = data;
|
||||
b->cursor = nir_before_instr(instr);
|
||||
|
||||
nir_def *def;
|
||||
nir_def *is_null = get_is_null(b, instr, &def, *options);
|
||||
|
||||
if (!is_null)
|
||||
return false;
|
||||
|
||||
nir_def *zero = NULL;
|
||||
nir_if *nif = nir_push_if(b, nir_inot(b, is_null));
|
||||
nir_instr_remove(instr);
|
||||
nir_builder_instr_insert(b, instr);
|
||||
if (def) {
|
||||
nir_push_else(b, nif);
|
||||
zero = nir_imm_zero(b, def->num_components, def->bit_size);
|
||||
}
|
||||
nir_pop_if(b, nif);
|
||||
|
||||
if (def) {
|
||||
nir_def *phi = nir_if_phi(b, def, zero);
|
||||
|
||||
/* We can't use nir_def_rewrite_uses_after on phis, so use the global
|
||||
* version and fixup the phi manually
|
||||
*/
|
||||
nir_def_rewrite_uses(def, phi);
|
||||
|
||||
nir_instr *phi_instr = nir_def_instr(phi);
|
||||
nir_phi_instr *phi_as_phi = nir_instr_as_phi(phi_instr);
|
||||
nir_phi_src *phi_src =
|
||||
nir_phi_get_src_from_block(phi_as_phi, instr->block);
|
||||
nir_src_rewrite(&phi_src->src, def);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pco_nir_lower_null_descriptors(
|
||||
nir_shader *shader,
|
||||
pco_nir_lower_null_descriptor_options options)
|
||||
{
|
||||
return nir_shader_instructions_pass(shader,
|
||||
lower,
|
||||
nir_metadata_none,
|
||||
&options);
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright © 2025 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file pco_nir_sync.c
|
||||
*
|
||||
* \brief PCO NIR sync-related passes.
|
||||
*/
|
||||
|
||||
#include "hwdef/rogue_hw_defs.h"
|
||||
#include "nir.h"
|
||||
#include "nir_builder.h"
|
||||
#include "nir_builtin_builder.h"
|
||||
#include "pco.h"
|
||||
#include "pco_builder.h"
|
||||
#include "pco_internal.h"
|
||||
#include "pco_usclib.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* \brief Lowers a barrier instruction.
|
||||
*
|
||||
* \param[in] b NIR builder.
|
||||
* \param[in] intr NIR intrinsic instruction.
|
||||
* \param[in] cb_data User callback data.
|
||||
* \return True if progress was made.
|
||||
*/
|
||||
static bool
|
||||
lower_barrier(nir_builder *b, nir_intrinsic_instr *intr, void *cb_data)
|
||||
{
|
||||
if (intr->intrinsic != nir_intrinsic_barrier)
|
||||
return false;
|
||||
|
||||
struct shader_info *info = &b->shader->info;
|
||||
bool *uses_usclib = cb_data;
|
||||
|
||||
mesa_scope exec_scope = nir_intrinsic_execution_scope(intr);
|
||||
|
||||
unsigned wg_size = info->workgroup_size[0] * info->workgroup_size[1] *
|
||||
info->workgroup_size[2];
|
||||
|
||||
if (wg_size <= ROGUE_MAX_INSTANCES_PER_TASK || exec_scope == SCOPE_NONE ||
|
||||
exec_scope == SCOPE_SUBGROUP) {
|
||||
nir_instr_remove(&intr->instr);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* TODO: We might be able to re-use barrier counters. */
|
||||
unsigned counter_offset = info->shared_size;
|
||||
info->shared_size += sizeof(uint32_t);
|
||||
info->zero_initialize_shared_memory = true;
|
||||
|
||||
*uses_usclib = true;
|
||||
|
||||
unsigned num_slots = DIV_ROUND_UP(wg_size, ROGUE_MAX_INSTANCES_PER_TASK);
|
||||
|
||||
b->cursor = nir_before_instr(&intr->instr);
|
||||
usclib_barrier(b, nir_imm_int(b, num_slots), nir_imm_int(b, counter_offset));
|
||||
nir_instr_remove(&intr->instr);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Barrier lowering pass.
|
||||
*
|
||||
* \param[in,out] shader NIR shader.
|
||||
* \return True if the pass made progress.
|
||||
*/
|
||||
bool pco_nir_lower_barriers(nir_shader *shader, pco_data *data)
|
||||
{
|
||||
bool progress = nir_shader_intrinsics_pass(shader,
|
||||
lower_barrier,
|
||||
nir_metadata_none,
|
||||
&data->common.uses.usclib);
|
||||
|
||||
data->common.uses.barriers |= progress;
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
static bool
|
||||
lower_usclib_atomic(nir_builder *b, nir_intrinsic_instr *intr, void *cb_data)
|
||||
{
|
||||
if (intr->intrinsic != nir_intrinsic_ssbo_atomic_swap &&
|
||||
intr->intrinsic != nir_intrinsic_global_atomic_swap_pco)
|
||||
return false;
|
||||
|
||||
bool *uses_usclib = cb_data;
|
||||
|
||||
b->cursor = nir_before_instr(&intr->instr);
|
||||
|
||||
if (intr->intrinsic == nir_intrinsic_ssbo_atomic_swap) {
|
||||
nir_def *buffer = intr->src[0].ssa;
|
||||
nir_def *offset = intr->src[1].ssa;
|
||||
nir_def *value = intr->src[2].ssa;
|
||||
nir_def *value_swap = intr->src[3].ssa;
|
||||
|
||||
ASSERTED enum gl_access_qualifier access = nir_intrinsic_access(intr);
|
||||
ASSERTED unsigned num_components = intr->def.num_components;
|
||||
ASSERTED unsigned bit_size = intr->def.bit_size;
|
||||
assert(access == ACCESS_COHERENT);
|
||||
assert(num_components == 1 && bit_size == 32);
|
||||
|
||||
*uses_usclib = true;
|
||||
nir_def *emulated =
|
||||
usclib_emu_ssbo_atomic_comp_swap(b, buffer, offset, value, value_swap);
|
||||
nir_def_rewrite_uses(&intr->def, emulated);
|
||||
nir_instr_remove(&intr->instr);
|
||||
return true;
|
||||
}
|
||||
|
||||
nir_def *addr_data = intr->src[0].ssa;
|
||||
nir_def *addr = nir_channels(b, addr_data, BITFIELD_RANGE(0, 2));
|
||||
nir_def *value = nir_channel(b, addr_data, 2);
|
||||
nir_def *value_swap = nir_channel(b, addr_data, 3);
|
||||
|
||||
ASSERTED unsigned num_components = intr->def.num_components;
|
||||
ASSERTED unsigned bit_size = intr->def.bit_size;
|
||||
assert(num_components == 1 && bit_size == 32);
|
||||
|
||||
*uses_usclib = true;
|
||||
|
||||
nir_def *emulated =
|
||||
usclib_emu_global_atomic_comp_swap(b, addr, value, value_swap);
|
||||
nir_def_rewrite_uses(&intr->def, emulated);
|
||||
nir_instr_remove(&intr->instr);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool lower_global_atomic_intrinsic(nir_builder *b,
|
||||
nir_intrinsic_instr *intrin,
|
||||
UNUSED void *data)
|
||||
{
|
||||
nir_intrinsic_op op;
|
||||
bool is_swap = false;
|
||||
switch (intrin->intrinsic) {
|
||||
case nir_intrinsic_global_atomic_2x32:
|
||||
op = nir_intrinsic_global_atomic_pco;
|
||||
break;
|
||||
case nir_intrinsic_global_atomic_swap_2x32:
|
||||
op = nir_intrinsic_global_atomic_swap_pco;
|
||||
is_swap = true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
nir_src *addr_src = &intrin->src[0];
|
||||
nir_src *data_src = &intrin->src[1];
|
||||
nir_src *data2_src;
|
||||
if (is_swap)
|
||||
data2_src = &intrin->src[2];
|
||||
|
||||
b->cursor = nir_before_instr(&intrin->instr);
|
||||
|
||||
nir_def *new_src = nir_pad_vector(b, addr_src->ssa, is_swap ? 4 : 3);
|
||||
new_src = nir_vector_insert_imm(b, new_src, data_src->ssa, 2);
|
||||
if (is_swap)
|
||||
new_src = nir_vector_insert_imm(b, new_src, data2_src->ssa, 3);
|
||||
|
||||
nir_intrinsic_instr *new_intrin = nir_intrinsic_instr_create(b->shader, op);
|
||||
new_intrin->num_components = intrin->num_components;
|
||||
nir_def_init(&new_intrin->instr,
|
||||
&new_intrin->def,
|
||||
intrin->def.num_components,
|
||||
intrin->def.bit_size);
|
||||
new_intrin->src[0] = nir_src_for_ssa(new_src);
|
||||
assert(nir_intrinsic_has_atomic_op(intrin));
|
||||
nir_intrinsic_set_atomic_op(new_intrin, nir_intrinsic_atomic_op(intrin));
|
||||
|
||||
nir_builder_instr_insert(b, &new_intrin->instr);
|
||||
nir_def_rewrite_uses(&intrin->def, &new_intrin->def);
|
||||
nir_instr_remove(&intrin->instr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Atomics lowering pass.
|
||||
*
|
||||
* \param[in,out] shader NIR shader.
|
||||
* \return True if the pass made progress.
|
||||
*/
|
||||
bool pco_nir_lower_atomics(nir_shader *shader, pco_data *data)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
progress |= nir_shader_intrinsics_pass(shader,
|
||||
lower_global_atomic_intrinsic,
|
||||
nir_metadata_none,
|
||||
NULL);
|
||||
progress |= nir_shader_intrinsics_pass(shader,
|
||||
lower_usclib_atomic,
|
||||
nir_metadata_none,
|
||||
&data->common.uses.usclib);
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
static bool lower_subgroup_intrinsic(nir_builder *b,
|
||||
nir_intrinsic_instr *intr,
|
||||
void *cb_data)
|
||||
{
|
||||
nir_def *new_def;
|
||||
|
||||
b->cursor = nir_before_instr(&intr->instr);
|
||||
|
||||
switch (intr->intrinsic) {
|
||||
case nir_intrinsic_load_subgroup_size:
|
||||
new_def = nir_imm_int(b, 1);
|
||||
break;
|
||||
|
||||
case nir_intrinsic_load_subgroup_invocation:
|
||||
new_def = nir_imm_int(b, 0);
|
||||
break;
|
||||
|
||||
case nir_intrinsic_load_num_subgroups:
|
||||
new_def = nir_imm_int(b,
|
||||
b->shader->info.workgroup_size[0] *
|
||||
b->shader->info.workgroup_size[1] *
|
||||
b->shader->info.workgroup_size[2]);
|
||||
break;
|
||||
|
||||
case nir_intrinsic_load_subgroup_id:
|
||||
new_def = nir_load_local_invocation_index(b);
|
||||
break;
|
||||
|
||||
case nir_intrinsic_first_invocation:
|
||||
new_def = nir_imm_int(b, 0);
|
||||
break;
|
||||
|
||||
case nir_intrinsic_elect:
|
||||
new_def = nir_imm_true(b);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
nir_def_rewrite_uses(&intr->def, new_def);
|
||||
nir_instr_remove(&intr->instr);
|
||||
assert(intr->def.num_components == 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pco_nir_lower_subgroups(nir_shader *shader)
|
||||
{
|
||||
shader->info.api_subgroup_size = 1;
|
||||
shader->info.min_subgroup_size = 1;
|
||||
shader->info.max_subgroup_size = 1;
|
||||
|
||||
return nir_shader_intrinsics_pass(shader,
|
||||
lower_subgroup_intrinsic,
|
||||
nir_metadata_control_flow,
|
||||
NULL);
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
* Copyright © 2025 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file pco_nir_vk.c
|
||||
*
|
||||
* \brief PCO NIR Vulkan lowering pass.
|
||||
*/
|
||||
|
||||
#include "nir.h"
|
||||
#include "nir_builder.h"
|
||||
#include "pco.h"
|
||||
#include "pco_builder.h"
|
||||
#include "pco_internal.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void
|
||||
set_resource_used(pco_common_data *common, unsigned desc_set, unsigned binding)
|
||||
{
|
||||
assert(desc_set < ARRAY_SIZE(common->desc_sets));
|
||||
pco_descriptor_set_data *desc_set_data = &common->desc_sets[desc_set];
|
||||
desc_set_data->used = true;
|
||||
|
||||
assert(desc_set_data->bindings && binding < desc_set_data->binding_count);
|
||||
pco_binding_data *binding_data = &desc_set_data->bindings[binding];
|
||||
binding_data->used = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Lowers load_vulkan_descriptor.
|
||||
*
|
||||
* Packs the descriptor set, binding, and array element.
|
||||
*
|
||||
* \param[in] b NIR builder.
|
||||
* \param[in] intr NIR intrinsic instruction.
|
||||
* \param[in] common Shader common data.
|
||||
* \return True if progress was made.
|
||||
*/
|
||||
static bool lower_load_vulkan_descriptor(nir_builder *b,
|
||||
nir_intrinsic_instr *intr,
|
||||
pco_common_data *common)
|
||||
{
|
||||
nir_intrinsic_instr *vk_res_idx = nir_src_as_intrinsic(intr->src[0]);
|
||||
assert(vk_res_idx->intrinsic == nir_intrinsic_vulkan_resource_index);
|
||||
|
||||
assert(nir_intrinsic_desc_type(intr) == nir_intrinsic_desc_type(vk_res_idx));
|
||||
|
||||
unsigned desc_set = nir_intrinsic_desc_set(vk_res_idx);
|
||||
unsigned binding = nir_intrinsic_binding(vk_res_idx);
|
||||
unsigned elem = nir_src_as_uint(vk_res_idx->src[0]);
|
||||
|
||||
set_resource_used(common, desc_set, binding);
|
||||
|
||||
b->cursor = nir_before_instr(&intr->instr);
|
||||
|
||||
uint32_t desc_set_binding = pco_pack_desc(desc_set, binding);
|
||||
nir_def *desc_ref = nir_imm_ivec3(b, desc_set_binding, elem, 0);
|
||||
nir_def_rewrite_uses(&intr->def, desc_ref);
|
||||
nir_instr_remove(&intr->instr);
|
||||
return true;
|
||||
}
|
||||
|
||||
static nir_def *array_elem_from_deref(nir_builder *b, nir_deref_instr *deref)
|
||||
{
|
||||
unsigned array_elem = 0;
|
||||
if (deref->deref_type != nir_deref_type_var) {
|
||||
assert(deref->deref_type == nir_deref_type_array);
|
||||
|
||||
array_elem = nir_src_as_uint(deref->arr.index);
|
||||
|
||||
deref = nir_deref_instr_parent(deref);
|
||||
}
|
||||
|
||||
assert(deref->deref_type == nir_deref_type_var);
|
||||
return nir_imm_int(b, array_elem);
|
||||
}
|
||||
|
||||
static inline bool is_comb_img_smp(unsigned desc_set,
|
||||
unsigned binding,
|
||||
const pco_common_data *common)
|
||||
{
|
||||
const pco_descriptor_set_data *desc_set_data = &common->desc_sets[desc_set];
|
||||
assert(desc_set_data->bindings && binding < desc_set_data->binding_count);
|
||||
|
||||
const pco_binding_data *binding_data = &desc_set_data->bindings[binding];
|
||||
return binding_data->is_img_smp;
|
||||
}
|
||||
|
||||
static bool lower_tex_deref_to_binding(nir_builder *b,
|
||||
nir_tex_instr *tex,
|
||||
unsigned deref_index,
|
||||
pco_common_data *common)
|
||||
{
|
||||
nir_tex_src *deref_src = &tex->src[deref_index];
|
||||
nir_deref_instr *deref = nir_def_as_deref(deref_src->src.ssa);
|
||||
|
||||
b->cursor = nir_before_instr(&tex->instr);
|
||||
|
||||
nir_variable *var = nir_deref_instr_get_variable(deref);
|
||||
assert(var);
|
||||
unsigned desc_set = var->data.descriptor_set;
|
||||
unsigned binding = var->data.binding;
|
||||
nir_def *elem = array_elem_from_deref(b, deref);
|
||||
|
||||
set_resource_used(common, desc_set, binding);
|
||||
|
||||
uint32_t desc_set_binding = pco_pack_desc(desc_set, binding);
|
||||
if (deref_src->src_type == nir_tex_src_texture_deref) {
|
||||
tex->texture_index = desc_set_binding;
|
||||
deref_src->src_type = nir_tex_src_backend1;
|
||||
} else {
|
||||
tex->sampler_index = desc_set_binding;
|
||||
deref_src->src_type = nir_tex_src_backend2;
|
||||
}
|
||||
|
||||
nir_src_rewrite(&deref_src->src, elem);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
add_txf_sampler(nir_builder *b, nir_tex_instr *tex, pco_common_data *common)
|
||||
{
|
||||
int deref_index = nir_tex_instr_src_index(tex, nir_tex_src_backend1);
|
||||
assert(deref_index >= 0);
|
||||
nir_tex_src *deref_src = &tex->src[deref_index];
|
||||
|
||||
unsigned desc_set;
|
||||
unsigned binding;
|
||||
pco_unpack_desc(tex->texture_index, &desc_set, &binding);
|
||||
nir_def *elem = deref_src->src.ssa;
|
||||
|
||||
/* If it's not a combined image/sampler, use the point sampler. */
|
||||
if (!is_comb_img_smp(desc_set, binding, common)) {
|
||||
desc_set = PCO_POINT_SAMPLER;
|
||||
binding = PCO_POINT_SAMPLER;
|
||||
elem = nir_imm_int(b, 0);
|
||||
|
||||
common->uses.point_sampler = true;
|
||||
}
|
||||
|
||||
tex->sampler_index = pco_pack_desc(desc_set, binding);
|
||||
nir_tex_instr_add_src(tex, nir_tex_src_backend2, elem);
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
lower_tex_derefs(nir_builder *b, nir_tex_instr *tex, pco_common_data *common)
|
||||
{
|
||||
int deref_index;
|
||||
bool progress = false;
|
||||
|
||||
deref_index = nir_tex_instr_src_index(tex, nir_tex_src_texture_deref);
|
||||
if (deref_index >= 0)
|
||||
progress |= lower_tex_deref_to_binding(b, tex, deref_index, common);
|
||||
|
||||
deref_index = nir_tex_instr_src_index(tex, nir_tex_src_sampler_deref);
|
||||
if (deref_index >= 0)
|
||||
progress |= lower_tex_deref_to_binding(b, tex, deref_index, common);
|
||||
else if (tex->op == nir_texop_txf || tex->op == nir_texop_txf_ms)
|
||||
progress |= add_txf_sampler(b, tex, common);
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
static bool
|
||||
lower_image_derefs(nir_builder *b, nir_intrinsic_instr *intr, pco_data *data)
|
||||
{
|
||||
nir_src *deref_src = &intr->src[0];
|
||||
nir_deref_instr *deref = nir_src_as_deref(*deref_src);
|
||||
b->cursor = nir_before_instr(&intr->instr);
|
||||
|
||||
nir_variable *var = nir_deref_instr_get_variable(deref);
|
||||
assert(var);
|
||||
|
||||
unsigned desc_set = var->data.descriptor_set;
|
||||
unsigned binding = var->data.binding;
|
||||
set_resource_used(&data->common, desc_set, binding);
|
||||
|
||||
if (nir_intrinsic_format(intr) == PIPE_FORMAT_NONE)
|
||||
nir_intrinsic_set_format(intr, var->data.image.format);
|
||||
|
||||
enum glsl_sampler_dim image_dim = nir_intrinsic_image_dim(intr);
|
||||
bool ia = image_dim == GLSL_SAMPLER_DIM_SUBPASS ||
|
||||
image_dim == GLSL_SAMPLER_DIM_SUBPASS_MS;
|
||||
|
||||
if (ia) {
|
||||
unsigned ia_idx = var->data.index;
|
||||
bool onchip = data->fs.ia_formats[ia_idx] != PIPE_FORMAT_NONE;
|
||||
|
||||
bool is_stencil = data->fs.ia_has_stencil & BITFIELD_BIT(ia_idx);
|
||||
is_stencil &= glsl_get_sampler_result_type(glsl_without_array_or_matrix(
|
||||
var->type)) != GLSL_TYPE_FLOAT;
|
||||
onchip &= !is_stencil;
|
||||
|
||||
if (onchip) {
|
||||
nir_def *elem = array_elem_from_deref(b, deref);
|
||||
nir_def *index = nir_vec4(b,
|
||||
nir_imm_int(b, desc_set),
|
||||
nir_imm_int(b, binding),
|
||||
elem,
|
||||
nir_imm_int(b, ia_idx));
|
||||
|
||||
nir_src_rewrite(deref_src, index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Sampler not needed for on-chip input attachments. */
|
||||
data->common.uses.ia_sampler = true;
|
||||
} else if (intr->intrinsic == nir_intrinsic_image_deref_load ||
|
||||
intr->intrinsic == nir_intrinsic_image_deref_store) {
|
||||
/* Sampler not needed for other types of image accesses. */
|
||||
data->common.uses.point_sampler = true;
|
||||
}
|
||||
|
||||
nir_def *elem = array_elem_from_deref(b, deref);
|
||||
nir_def *index =
|
||||
nir_vec3(b, nir_imm_int(b, desc_set), nir_imm_int(b, binding), elem);
|
||||
|
||||
nir_src_rewrite(deref_src, index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool lower_is_null_descriptor(nir_builder *b, nir_intrinsic_instr *intr)
|
||||
{
|
||||
nir_src *deref_src = &intr->src[0];
|
||||
nir_deref_instr *deref = nir_src_as_deref(*deref_src);
|
||||
|
||||
/* Will be taken care of by lower_load_vulkan_descriptor. */
|
||||
if (!deref)
|
||||
return false;
|
||||
|
||||
b->cursor = nir_before_instr(&intr->instr);
|
||||
|
||||
nir_variable *var = nir_deref_instr_get_variable(deref);
|
||||
assert(var);
|
||||
unsigned desc_set = var->data.descriptor_set;
|
||||
unsigned binding = var->data.binding;
|
||||
nir_def *elem = array_elem_from_deref(b, deref);
|
||||
|
||||
uint32_t desc_set_binding = pco_pack_desc(desc_set, binding);
|
||||
nir_def *index = nir_vec2(b, nir_imm_int(b, desc_set_binding), elem);
|
||||
|
||||
nir_src_rewrite(deref_src, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Lowers a Vulkan-related texture instruction.
|
||||
*
|
||||
* \param[in] b NIR builder.
|
||||
* \param[in] tex NIR texture instruction.
|
||||
* \param[in] cb_data User callback data.
|
||||
* \return True if progress was made.
|
||||
*/
|
||||
static bool lower_vk_tex(nir_builder *b, nir_tex_instr *tex, void *cb_data)
|
||||
{
|
||||
pco_data *data = cb_data;
|
||||
pco_common_data *common = &data->common;
|
||||
if (nir_tex_instr_src_index(tex, nir_tex_src_texture_deref) >= 0 ||
|
||||
nir_tex_instr_src_index(tex, nir_tex_src_sampler_deref) >= 0) {
|
||||
return lower_tex_derefs(b, tex, common);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Lowers a Vulkan-related intrinsic instruction.
|
||||
*
|
||||
* \param[in] b NIR builder.
|
||||
* \param[in] intr NIR intrinsic instruction.
|
||||
* \param[in] cb_data User callback data.
|
||||
* \return True if progress was made.
|
||||
*/
|
||||
static bool
|
||||
lower_vk_intr(nir_builder *b, nir_intrinsic_instr *intr, void *cb_data)
|
||||
{
|
||||
pco_data *data = cb_data;
|
||||
pco_common_data *common = &data->common;
|
||||
|
||||
b->cursor = nir_before_instr(&intr->instr);
|
||||
|
||||
switch (intr->intrinsic) {
|
||||
case nir_intrinsic_load_vulkan_descriptor:
|
||||
return lower_load_vulkan_descriptor(b, intr, common);
|
||||
|
||||
case nir_intrinsic_image_deref_load:
|
||||
case nir_intrinsic_image_deref_store:
|
||||
case nir_intrinsic_image_deref_atomic:
|
||||
case nir_intrinsic_image_deref_atomic_swap:
|
||||
case nir_intrinsic_image_deref_size:
|
||||
return lower_image_derefs(b, intr, data);
|
||||
|
||||
case nir_intrinsic_is_null_descriptor:
|
||||
return lower_is_null_descriptor(b, intr);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Vulkan lowering pass.
|
||||
*
|
||||
* \param[in,out] shader NIR shader.
|
||||
* \param[in,out] data Shader data.
|
||||
* \return True if the pass made progress.
|
||||
*/
|
||||
bool pco_nir_lower_vk(nir_shader *shader, pco_data *data)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
progress |= nir_shader_intrinsics_pass(shader,
|
||||
lower_vk_intr,
|
||||
nir_metadata_control_flow,
|
||||
data);
|
||||
progress |= nir_shader_tex_pass(shader,
|
||||
lower_vk_tex,
|
||||
nir_metadata_control_flow,
|
||||
data);
|
||||
|
||||
return progress;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
# Copyright © 2024 Imagination Technologies Ltd.
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
from mako.template import Template, exceptions
|
||||
from pco_ops import *
|
||||
|
||||
template = """/*
|
||||
* Copyright © 2024 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef PCO_OPS_H
|
||||
#define PCO_OPS_H
|
||||
|
||||
/**
|
||||
* \\file pco_ops.h
|
||||
*
|
||||
* \\brief PCO op definitions and functions.
|
||||
*/
|
||||
|
||||
#include "util/macros.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define _PCO_OP_MAX_DESTS ${max([op.num_dests for op in ops.values()])}U
|
||||
#define _PCO_OP_MAX_SRCS ${max([op.num_srcs for op in ops.values()])}U
|
||||
#define _PCO_OP_MAX_MODS ${max([len(op.op_mods) for op in ops.values()])}U
|
||||
|
||||
/** Ops. */
|
||||
#define _PCO_OP_COUNT ${len(ops) + 1}U
|
||||
enum pco_op {
|
||||
PCO_OP_NONE,
|
||||
% for op in ops.values():
|
||||
${op.cname.upper()},
|
||||
% endfor
|
||||
};
|
||||
|
||||
/** Op mods. */
|
||||
#define _PCO_OP_MOD_COUNT ${len(op_mods) + 1}U
|
||||
enum pco_op_mod {
|
||||
PCO_OP_MOD_NONE,
|
||||
% for op_mod in op_mods.values():
|
||||
${op_mod.cname},
|
||||
% endfor
|
||||
};
|
||||
|
||||
/** Ref mods. */
|
||||
#define _PCO_REF_MOD_COUNT ${len(ref_mods) + 1}U
|
||||
enum pco_ref_mod {
|
||||
PCO_REF_MOD_NONE,
|
||||
% for ref_mod in ref_mods.values():
|
||||
${ref_mod.cname},
|
||||
% endfor
|
||||
};
|
||||
#endif /* PCO_OPS_H */"""
|
||||
|
||||
def main():
|
||||
try:
|
||||
print(Template(template).render(ops=ops, op_mods=op_mods, ref_mods=ref_mods))
|
||||
except:
|
||||
raise Exception(exceptions.text_error_template().render())
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,529 @@
|
||||
# Copyright © 2024 Imagination Technologies Ltd.
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
from pco_pygen_common import *
|
||||
|
||||
OP_TYPE = enum_type('op_type', [
|
||||
'pseudo',
|
||||
'hw',
|
||||
'hw_direct',
|
||||
])
|
||||
|
||||
MOD_TYPE = enum_type('mod_type', [
|
||||
'bool',
|
||||
'uint',
|
||||
'enum',
|
||||
])
|
||||
|
||||
REF_TYPE = enum_type('ref_type', [
|
||||
('null', '_'),
|
||||
('ssa', '%'),
|
||||
('reg', ''),
|
||||
('idx_reg', ''),
|
||||
('imm', ''),
|
||||
('io', ''),
|
||||
('pred', ''),
|
||||
('drc', 'drc'),
|
||||
])
|
||||
|
||||
FUNC_TYPE = enum_type('func_type', [
|
||||
'callable',
|
||||
'preamble',
|
||||
'entrypoint',
|
||||
'phase_change',
|
||||
])
|
||||
|
||||
DTYPE = enum_type('dtype', [
|
||||
('any', ''),
|
||||
('unsigned', 'u'),
|
||||
('signed', 'i'),
|
||||
('float', 'f'),
|
||||
])
|
||||
|
||||
BITS = enum_type('bits', [
|
||||
('1', '1'),
|
||||
('8', '8'),
|
||||
('16', '16'),
|
||||
('32', '32'),
|
||||
('64', '64'),
|
||||
])
|
||||
|
||||
REG_CLASS = enum_type('reg_class', [
|
||||
('virt', '$'),
|
||||
('temp', 'r'),
|
||||
('vtxin', 'vi'),
|
||||
('coeff', 'cf'),
|
||||
('shared', 'sh'),
|
||||
('index', 'idx'),
|
||||
('spec', 'sr'),
|
||||
('intern', 'i'),
|
||||
('const', 'sc'),
|
||||
('pixout', 'po'),
|
||||
('global', 'g'),
|
||||
('slot', 'sl'),
|
||||
])
|
||||
|
||||
IO = enum_type('io', [
|
||||
('s0', 's0'),
|
||||
('s1', 's1'),
|
||||
('s2', 's2'),
|
||||
|
||||
('s3', 's3'),
|
||||
('s4', 's4'),
|
||||
('s5', 's5'),
|
||||
|
||||
('w0', 'w0'),
|
||||
('w1', 'w1'),
|
||||
|
||||
('is0', 'is0'),
|
||||
('is1', 'is1'),
|
||||
('is2', 'is2'),
|
||||
('is3', 'is3'),
|
||||
('is4', 'is4'),
|
||||
('is5', 'is5'),
|
||||
|
||||
('ft0', 'ft0'),
|
||||
('ft1', 'ft1'),
|
||||
('ft2', 'ft2'),
|
||||
('fte', 'fte'),
|
||||
|
||||
('ft1_invert', '~ft1'),
|
||||
('ft3', 'ft3'),
|
||||
('ft4', 'ft4'),
|
||||
('ft5', 'ft5'),
|
||||
|
||||
('ftt', 'ftt'),
|
||||
|
||||
('cout', 'cout'),
|
||||
])
|
||||
|
||||
PRED = enum_type('pred', [
|
||||
('pe', 'pe'),
|
||||
('p0', 'p0'),
|
||||
|
||||
('always', 'if(1)'),
|
||||
('p0_true', 'if(p0)'),
|
||||
('never', 'if(0)'),
|
||||
('p0_false', 'if(!p0)'),
|
||||
])
|
||||
|
||||
DRC = enum_type('drc', [
|
||||
('0', '0'),
|
||||
('1', '1'),
|
||||
('pending', '?'),
|
||||
])
|
||||
|
||||
MUTEX_ID = enum_type('mutex_id', [
|
||||
'atomic_emu',
|
||||
'barrier',
|
||||
'rsvd_2',
|
||||
'rsvd_3',
|
||||
'rsvd_4',
|
||||
'rsvd_5',
|
||||
'rsvd_6',
|
||||
'rsvd_7',
|
||||
'rsvd_8',
|
||||
'rsvd_9',
|
||||
'rsvd_a',
|
||||
'rsvd_b',
|
||||
'rsvd_c',
|
||||
'rsvd_d',
|
||||
'rsvd_e',
|
||||
'rsvd_f'
|
||||
])
|
||||
|
||||
# Ref mods.
|
||||
RM_ONEMINUS = ref_mod('oneminus', BaseType.bool)
|
||||
RM_CLAMP = ref_mod('clamp', BaseType.bool)
|
||||
RM_ABS = ref_mod('abs', BaseType.bool)
|
||||
RM_NEG = ref_mod('neg', BaseType.bool)
|
||||
RM_FLR = ref_mod('flr', BaseType.bool)
|
||||
|
||||
RM_ELEM = ref_mod_enum('elem', [
|
||||
'e0',
|
||||
'e1',
|
||||
'e2',
|
||||
'e3',
|
||||
], is_bitset=True)
|
||||
|
||||
# Op mods.
|
||||
OM_EXEC_CND = op_mod_enum('exec_cnd', [
|
||||
('e1_zx', ''),
|
||||
('e1_z1', 'if(p0)'),
|
||||
('ex_zx', '(ignorepe)'),
|
||||
('e1_z0', 'if(!p0)'),
|
||||
], print_early=True, unset=True)
|
||||
OM_RPT = op_mod('rpt', BaseType.uint, print_early=True, nzdefault=1, unset=True)
|
||||
OM_SAT = op_mod('sat', BaseType.bool)
|
||||
OM_LP = op_mod('lp', BaseType.bool)
|
||||
OM_SCALE = op_mod('scale', BaseType.bool)
|
||||
OM_ROUNDZERO = op_mod('roundzero', BaseType.bool)
|
||||
OM_S = op_mod('s', BaseType.bool)
|
||||
OM_TST_TYPE_MAIN = op_mod_enum('tst_type_main', [
|
||||
'f32',
|
||||
'u16',
|
||||
's16',
|
||||
'u8',
|
||||
's8',
|
||||
'u32',
|
||||
's32',
|
||||
])
|
||||
OM_TST_OP_MAIN = op_mod_enum('tst_op_main', [
|
||||
('zero', 'z'),
|
||||
('gzero', 'gz'),
|
||||
('gezero', 'gez'),
|
||||
('carry', 'c'),
|
||||
('equal', 'e'),
|
||||
('greater', 'g'),
|
||||
('gequal', 'ge'),
|
||||
('notequal', 'ne'),
|
||||
('less', 'l'),
|
||||
('lequal', 'le'),
|
||||
])
|
||||
OM_TST_OP_BITWISE = op_mod_enum('tst_op_bitwise', [
|
||||
('zero', 'z'),
|
||||
('nonzero', 'nz'),
|
||||
])
|
||||
OM_SIGNPOS = op_mod_enum('signpos', [
|
||||
'twb',
|
||||
'pwb',
|
||||
'mtb',
|
||||
'ftb',
|
||||
])
|
||||
OM_DIM = op_mod_enum('dim', [
|
||||
'1d',
|
||||
'2d',
|
||||
'3d',
|
||||
])
|
||||
OM_PROJ = op_mod('proj', BaseType.bool)
|
||||
OM_FCNORM = op_mod('fcnorm', BaseType.bool)
|
||||
OM_NNCOORDS = op_mod('nncoords', BaseType.bool)
|
||||
OM_LOD_MODE = op_mod_enum('lod_mode', [
|
||||
('normal', ''),
|
||||
('bias', 'bias'),
|
||||
('replace', 'replace'),
|
||||
('gradients', 'gradients'),
|
||||
])
|
||||
OM_PPLOD = op_mod('pplod', BaseType.bool)
|
||||
OM_TAO = op_mod('tao', BaseType.bool)
|
||||
OM_SOO = op_mod('soo', BaseType.bool)
|
||||
OM_SNO = op_mod('sno', BaseType.bool)
|
||||
OM_WRT = op_mod('wrt', BaseType.bool)
|
||||
OM_SB_MODE = op_mod_enum('sb_mode', [
|
||||
('none', ''),
|
||||
('rawdata', 'rawdata'),
|
||||
('coeffs', 'coeffs'),
|
||||
('both', 'both'),
|
||||
])
|
||||
OM_ARRAY = op_mod('array', BaseType.bool)
|
||||
OM_INTEGER = op_mod('integer', BaseType.bool)
|
||||
OM_SCHEDSWAP = op_mod_enum('schedswap', [
|
||||
('none', ''),
|
||||
('swap', 'schedswap'),
|
||||
])
|
||||
OM_F16 = op_mod('f16', BaseType.bool)
|
||||
OM_TILED = op_mod('tiled', BaseType.bool)
|
||||
OM_FREEP = op_mod('freep', BaseType.bool)
|
||||
OM_SM = op_mod('sm', BaseType.bool)
|
||||
OM_SAVMSK_MODE = op_mod_enum('savmsk_mode', [
|
||||
'vm',
|
||||
'icm',
|
||||
'icmoc',
|
||||
'icmi',
|
||||
'caxy',
|
||||
])
|
||||
OM_ATOM_OP = op_mod_enum('atom_op', [
|
||||
'add',
|
||||
'sub',
|
||||
'xchg',
|
||||
'cmpxchg',
|
||||
'umin',
|
||||
'imin',
|
||||
'umax',
|
||||
'imax',
|
||||
'and',
|
||||
'or',
|
||||
'xor',
|
||||
])
|
||||
OM_MCU_CACHE_MODE_LD = op_mod_enum('mcu_cache_mode_ld', [
|
||||
('normal', ''),
|
||||
('bypass', 'bypass'),
|
||||
('force_line_fill', 'forcelinefill'),
|
||||
])
|
||||
OM_MCU_CACHE_MODE_ST = op_mod_enum('mcu_cache_mode_st', [
|
||||
('write_through', 'writethrough'),
|
||||
('write_back', 'writeback'),
|
||||
('lazy_write_back', 'lazywriteback'),
|
||||
])
|
||||
OM_BRANCH_CND = op_mod_enum('branch_cnd', [
|
||||
('exec_cond', ''),
|
||||
('allinst', 'allinst'),
|
||||
('anyinst', 'anyinst'),
|
||||
])
|
||||
OM_LINK = op_mod('link', BaseType.bool)
|
||||
OM_PCK_FMT = op_mod_enum('pck_fmt', [
|
||||
'u8888',
|
||||
's8888',
|
||||
'o8888',
|
||||
'u1616',
|
||||
's1616',
|
||||
'o1616',
|
||||
'u32',
|
||||
's32',
|
||||
'u1010102',
|
||||
's1010102',
|
||||
'u111110',
|
||||
's111110',
|
||||
'f111110',
|
||||
'f16f16',
|
||||
'f32',
|
||||
'cov',
|
||||
'u565u565',
|
||||
'd24s8',
|
||||
's8d24',
|
||||
'f32_mask',
|
||||
'2f10f10f10',
|
||||
's8888ogl',
|
||||
's1616ogl',
|
||||
'zero',
|
||||
'one',
|
||||
])
|
||||
OM_PHASE2END = op_mod('phase2end', BaseType.bool)
|
||||
OM_ITR_MODE = op_mod_enum('itr_mode', [
|
||||
'pixel',
|
||||
'sample',
|
||||
'centroid',
|
||||
])
|
||||
OM_SCHED = op_mod_enum('sched', [
|
||||
('none', ''),
|
||||
('swap', 'schedswap'),
|
||||
('wdf', 'schedwdf'),
|
||||
])
|
||||
OM_ATOM = op_mod('atom', BaseType.bool, unset=True)
|
||||
OM_OLCHK = op_mod('olchk', BaseType.bool, unset=True)
|
||||
OM_END = op_mod('end', BaseType.bool, unset=True)
|
||||
|
||||
OM_LOGIOP = op_mod_enum('logiop', [
|
||||
'or',
|
||||
'and',
|
||||
'xor',
|
||||
'nor',
|
||||
'nand',
|
||||
'xnor',
|
||||
])
|
||||
|
||||
OM_SHIFTOP = op_mod_enum('shiftop', [
|
||||
'lsl',
|
||||
'shr',
|
||||
'rol',
|
||||
'cps',
|
||||
'asr_twb',
|
||||
'asr_pwb',
|
||||
'asr_mtb',
|
||||
'asr_ftb',
|
||||
])
|
||||
|
||||
OM_CND = op_mod_enum('cnd', [
|
||||
('always', 'if(1)'),
|
||||
('p0_true', 'if(p0)'),
|
||||
('never', 'if(0)'),
|
||||
('p0_false', 'if(!p0)'),
|
||||
])
|
||||
|
||||
OM_FRED_TYPE = op_mod_enum('fred_type', [
|
||||
'sin',
|
||||
'cos',
|
||||
])
|
||||
|
||||
OM_FRED_PART = op_mod_enum('fred_part', [
|
||||
'a',
|
||||
'b',
|
||||
])
|
||||
|
||||
OM_MUTEX_OP = op_mod_enum('mutex_op', [
|
||||
('release', 'release'),
|
||||
('release_sleep', 'release.sleep'),
|
||||
('release_wakeup', 'release.wakeup'),
|
||||
('lock', 'lock'),
|
||||
])
|
||||
|
||||
OM_OFFSET_SD = op_mod_enum('offset_sd', [
|
||||
'src',
|
||||
'dest',
|
||||
])
|
||||
|
||||
OM_IDF = op_mod('idf', BaseType.bool)
|
||||
|
||||
# Ops.
|
||||
|
||||
OM_ALU = [OM_OLCHK, OM_EXEC_CND, OM_END, OM_ATOM, OM_RPT]
|
||||
OM_ALU_RPT1 = [OM_OLCHK, OM_EXEC_CND, OM_END, OM_ATOM]
|
||||
OM_ALU_ATOMEXT = [OM_OLCHK, OM_EXEC_CND, OM_END, OM_RPT]
|
||||
|
||||
## Main.
|
||||
O_FADD = hw_op('fadd', OM_ALU + [OM_SAT], 1, 2, [], [[RM_ABS, RM_NEG, RM_FLR], [RM_ABS]])
|
||||
O_FMUL = hw_op('fmul', OM_ALU + [OM_SAT], 1, 2, [], [[RM_ABS, RM_NEG, RM_FLR], [RM_ABS]])
|
||||
O_FMAD = hw_op('fmad', OM_ALU + [OM_SAT, OM_LP], 1, 3, [], [[RM_ABS, RM_NEG], [RM_ABS, RM_NEG], [RM_ABS, RM_NEG, RM_FLR]])
|
||||
O_FRCP = hw_op('frcp', OM_ALU, 1, 1, [], [[RM_ABS, RM_NEG]])
|
||||
O_FRSQ = hw_op('frsq', OM_ALU, 1, 1, [], [[RM_ABS, RM_NEG]])
|
||||
O_FLOG = hw_op('flog', OM_ALU, 1, 1, [], [[RM_ABS, RM_NEG]])
|
||||
O_FLOGCN = hw_op('flogcn', OM_ALU, 1, 1, [], [[RM_ABS, RM_NEG]])
|
||||
O_FEXP = hw_op('fexp', OM_ALU, 1, 1, [], [[RM_ABS, RM_NEG]])
|
||||
O_FRED = hw_op('fred', OM_ALU + [OM_FRED_TYPE, OM_FRED_PART], 3, 3, [], [[RM_ABS, RM_NEG]])
|
||||
O_FSINC = hw_op('fsinc', OM_ALU, 2, 1)
|
||||
O_MBYP = hw_op('mbyp', OM_ALU, 1, 1, [], [[RM_ABS, RM_NEG]])
|
||||
O_FDSX = hw_op('fdsx', OM_ALU, 1, 1, [], [[RM_ABS, RM_NEG]])
|
||||
O_FDSXF = hw_op('fdsxf', OM_ALU, 1, 1, [], [[RM_ABS, RM_NEG]])
|
||||
O_FDSY = hw_op('fdsy', OM_ALU, 1, 1, [], [[RM_ABS, RM_NEG]])
|
||||
O_FDSYF = hw_op('fdsyf', OM_ALU, 1, 1, [], [[RM_ABS, RM_NEG]])
|
||||
O_PCK = hw_op('pck', OM_ALU + [OM_PCK_FMT, OM_ROUNDZERO, OM_SCALE], 1, 1)
|
||||
O_PCK_PROG = hw_op('pck.prog', OM_ALU + [OM_ROUNDZERO, OM_SCALE], 1, 2)
|
||||
O_ADD64_32 = hw_op('add64_32', OM_ALU + [OM_S], 2, 4, [], [[RM_ABS, RM_NEG], [], [RM_ABS, RM_NEG]])
|
||||
O_IMADD64 = hw_op('imadd64', OM_ALU + [OM_S], 2, 5, [], [[RM_ABS, RM_NEG], [RM_ABS, RM_NEG], [RM_ABS, RM_NEG]])
|
||||
O_IMADD32 = hw_op('imadd32', OM_ALU + [OM_S], 1, 4, [], [[RM_ABS, RM_NEG], [RM_ABS, RM_NEG], [RM_ABS, RM_NEG]])
|
||||
O_UNPCK = hw_op('unpck', OM_ALU + [OM_PCK_FMT, OM_ROUNDZERO, OM_SCALE], 1, 1, [], [[RM_ELEM]])
|
||||
|
||||
O_TST = hw_direct_op('tst', [OM_TST_OP_MAIN, OM_PHASE2END, OM_TST_TYPE_MAIN], 2, 2, [], [[RM_ELEM], [RM_ELEM]])
|
||||
O_MOVC = hw_direct_op('movc', [OM_PHASE2END], 2, 5, [[RM_ELEM]])
|
||||
|
||||
O_MOVWM = hw_op('movwm', OM_ALU + [OM_PHASE2END], 1, 2, [[RM_ELEM]])
|
||||
O_MOVS1 = hw_op('movs1', OM_ALU, 1, 1)
|
||||
|
||||
# TODO
|
||||
# O_PCK_ELEM = pseudo_op('pck.elem', OM_ALU_RPT1 + [OM_PCK_FMT, OM_ROUNDZERO, OM_SCALE], 1, 2)
|
||||
|
||||
## Backend.
|
||||
O_UVSW_WRITE = hw_op('uvsw.write', [OM_EXEC_CND, OM_RPT], 0, 2)
|
||||
O_UVSW_EMIT = hw_op('uvsw.emit', [OM_EXEC_CND])
|
||||
O_UVSW_ENDTASK = hw_op('uvsw.endtask', [OM_END])
|
||||
O_UVSW_EMIT_ENDTASK = hw_op('uvsw.emit.endtask', [OM_END])
|
||||
O_UVSW_WRITE_EMIT_ENDTASK = hw_op('uvsw.write.emit.endtask', [OM_END], 0, 2)
|
||||
|
||||
O_FITR = hw_op('fitr', [OM_EXEC_CND, OM_END, OM_ITR_MODE, OM_SAT], 1, 3)
|
||||
O_FITRP = hw_op('fitrp', [OM_EXEC_CND, OM_END, OM_ITR_MODE, OM_SAT], 1, 4)
|
||||
|
||||
O_LD = hw_op('ld', OM_ALU_RPT1 + [OM_MCU_CACHE_MODE_LD], 1, 3)
|
||||
O_LD_REGBL = hw_op('ld.regbl', OM_ALU_RPT1 + [OM_MCU_CACHE_MODE_LD], 1, 3)
|
||||
|
||||
O_ST = hw_direct_op('st', [OM_MCU_CACHE_MODE_ST, OM_IDF], 0, 6)
|
||||
O_ST_REGBL = hw_direct_op('st.regbl', [OM_MCU_CACHE_MODE_ST, OM_IDF], 0, 6)
|
||||
|
||||
# { data, data size, drc, chans, addr, cov_msk}
|
||||
O_ST_TILED = hw_op('st.tiled', OM_ALU_RPT1 + [OM_MCU_CACHE_MODE_ST], 0, 6)
|
||||
|
||||
O_IDF = hw_op('idf', OM_ALU_RPT1, 0, 2)
|
||||
|
||||
O_ATOMIC = hw_op('atomic', [OM_OLCHK, OM_EXEC_CND, OM_END, OM_ATOM_OP], 1, 2)
|
||||
|
||||
O_SMP = hw_op('smp', OM_ALU_RPT1 + [OM_DIM, OM_PROJ, OM_FCNORM, OM_NNCOORDS,
|
||||
OM_LOD_MODE, OM_PPLOD, OM_TAO, OM_SOO,
|
||||
OM_SNO, OM_WRT, OM_SB_MODE, OM_MCU_CACHE_MODE_LD,
|
||||
OM_ARRAY, OM_INTEGER, OM_SCHEDSWAP, OM_F16], 1, 6)
|
||||
|
||||
O_ALPHATST = hw_op('alphatst', OM_ALU_RPT1, 1, 4)
|
||||
|
||||
O_ALPHAF = hw_op('alphaf', OM_ALU_RPT1, 1, 4)
|
||||
O_DEPTHF = hw_op('depthf', OM_ALU_RPT1, 0, 2)
|
||||
|
||||
O_SAVMSK = hw_op('savmsk', OM_ALU_RPT1 + [OM_SAVMSK_MODE], 2)
|
||||
|
||||
O_EMITPIX = hw_op('emitpix', OM_ALU_RPT1 + [OM_FREEP], 0, 2)
|
||||
|
||||
## Bitwise.
|
||||
O_MOVI32 = hw_op('movi32', OM_ALU, 1, 1)
|
||||
|
||||
O_CBS = hw_op('cbs', OM_ALU, 1, 1)
|
||||
O_FTB = hw_op('ftb', OM_ALU, 1, 1)
|
||||
O_REV = hw_op('rev', OM_ALU, 1, 1)
|
||||
O_SHUFFLE = hw_op('shuffle', OM_ALU, 1, 2)
|
||||
O_LOGICAL = hw_op('logical', OM_ALU + [OM_LOGIOP], 1, 4)
|
||||
O_SHIFT = hw_op('shift', OM_ALU + [OM_SHIFTOP], 1, 3)
|
||||
|
||||
O_COPYSIGN = hw_op('copysign', OM_ALU, 1, 2)
|
||||
|
||||
O_IBFE = hw_op('ibfe', OM_ALU, 1, 3)
|
||||
O_UBFE = hw_op('ubfe', OM_ALU, 1, 3)
|
||||
O_BFI = hw_op('bfi', OM_ALU, 1, 4)
|
||||
|
||||
O_BBYP0BM = hw_direct_op('bbyp0bm', [], 2, 2)
|
||||
O_BBYP0BM_IMM32 = hw_direct_op('bbyp0bm_imm32', [], 2, 2)
|
||||
O_BBYP0S1 = hw_direct_op('bbyp0s1', [], 2, 1)
|
||||
O_MSK_BBYP0S1 = hw_direct_op('msk_bbyp0s1', [], 3, 3)
|
||||
O_MSK_LSL = hw_direct_op('msk_lsl', [], 3, 3)
|
||||
|
||||
## Control.
|
||||
O_WOP = hw_op('wop')
|
||||
O_WDF = hw_op('wdf', [], 0, 1)
|
||||
O_NOP = hw_op('nop', [OM_EXEC_CND, OM_END])
|
||||
|
||||
# TODO NEXT: gate usage of OM_F16!
|
||||
O_DITR = hw_op('ditr', [OM_EXEC_CND, OM_ITR_MODE, OM_SAT, OM_SCHED, OM_F16], 1, 3)
|
||||
O_DITRP = hw_op('ditrp', [OM_EXEC_CND, OM_ITR_MODE, OM_SAT, OM_SCHED, OM_F16], 1, 4)
|
||||
O_DITRP_WRITE = hw_op('ditrp.write', [OM_EXEC_CND, OM_ITR_MODE, OM_SAT, OM_SCHED, OM_F16], 1, 4)
|
||||
O_DITRP_READ = hw_op('ditrp.read', [OM_EXEC_CND, OM_ITR_MODE, OM_SAT, OM_SCHED, OM_F16], 1, 3)
|
||||
|
||||
O_CNDST = hw_op('cndst', [OM_EXEC_CND, OM_CND], 2, 2)
|
||||
O_CNDEF = hw_op('cndef', [OM_EXEC_CND, OM_CND], 2, 2)
|
||||
O_CNDSM = hw_op('cndsm', [OM_EXEC_CND, OM_CND], 2, 2)
|
||||
O_CNDLT = hw_op('cndlt', [OM_EXEC_CND, OM_CND], 3, 2)
|
||||
O_CNDEND = hw_op('cndend', [OM_EXEC_CND], 2, 2)
|
||||
|
||||
O_BR = hw_op('br', [OM_EXEC_CND, OM_BRANCH_CND, OM_LINK], has_target_cf_node=True)
|
||||
|
||||
O_BR_NEXT = hw_op('br.next', [OM_EXEC_CND])
|
||||
|
||||
O_MUTEX = hw_op('mutex', [OM_MUTEX_OP], 0, 1)
|
||||
|
||||
# Combination (> 1 instructions per group).
|
||||
O_SCMP = hw_op('scmp', OM_ALU + [OM_TST_OP_MAIN], 1, 2, [], [[RM_ABS, RM_NEG], [RM_ABS, RM_NEG]])
|
||||
O_BCMP = hw_op('bcmp', OM_ALU + [OM_TST_OP_MAIN, OM_TST_TYPE_MAIN], 1, 2, [], [[RM_ABS, RM_NEG], [RM_ABS, RM_NEG]])
|
||||
O_BCSEL = hw_op('bcsel', OM_ALU, 1, 3, [], [[], [RM_ABS, RM_NEG], [RM_ABS, RM_NEG]])
|
||||
O_CSEL = hw_op('csel', OM_ALU + [OM_TST_OP_MAIN, OM_TST_TYPE_MAIN], 1, 3, [], [[], [RM_ABS, RM_NEG], [RM_ABS, RM_NEG]])
|
||||
O_PSEL = hw_op('psel', OM_ALU, 1, 3)
|
||||
O_PSEL_TRIG = hw_op('psel_trig', OM_ALU, 1, 3)
|
||||
O_FSIGN = hw_op('fsign', OM_ALU, 1, 1)
|
||||
O_ISIGN = hw_op('isign', OM_ALU, 1, 1)
|
||||
O_FCEIL = hw_op('fceil', OM_ALU, 1, 1)
|
||||
O_MIN = hw_op('min', OM_ALU + [OM_TST_TYPE_MAIN], 1, 2, [], [[RM_ABS, RM_NEG], [RM_ABS, RM_NEG]])
|
||||
O_MAX = hw_op('max', OM_ALU + [OM_TST_TYPE_MAIN], 1, 2, [], [[RM_ABS, RM_NEG], [RM_ABS, RM_NEG]])
|
||||
O_IADD32 = hw_op('iadd32', OM_ALU + [OM_S], 1, 3, [], [[RM_ABS, RM_NEG], [RM_ABS, RM_NEG]])
|
||||
O_IMUL32 = hw_op('imul32', OM_ALU + [OM_S], 1, 3, [], [[RM_ABS, RM_NEG], [RM_ABS, RM_NEG]])
|
||||
|
||||
O_UADD_CARRY = hw_op('uadd_carry', OM_ALU, 2, 2)
|
||||
O_UADD_SAT = hw_op('uadd_sat', OM_ALU, 1, 3)
|
||||
|
||||
O_TSTZ = hw_op('tstz', OM_ALU + [OM_TST_TYPE_MAIN], 2, 1, [], [[RM_ELEM]])
|
||||
O_ST32 = hw_op('st32', OM_ALU_RPT1 + [OM_MCU_CACHE_MODE_ST, OM_IDF], 0, 5)
|
||||
O_ST32_REGBL = hw_op('st32.regbl', OM_ALU_RPT1 + [OM_MCU_CACHE_MODE_ST, OM_IDF], 0, 5)
|
||||
|
||||
# [vec3 for store], [data, offset, base_addr_lo, base_addr_hi]
|
||||
O_SPILL = hw_op('spill', OM_ALU_RPT1, 1, 4)
|
||||
|
||||
# [result], [offset, base_addr_lo, base_addr_hi]
|
||||
O_UNSPILL = hw_op('unspill', OM_ALU_RPT1, 1, 3)
|
||||
|
||||
O_IADD32_ATOMIC = hw_op('iadd32.atomic', OM_ALU_ATOMEXT + [OM_S], 2, 3, [], [[RM_ABS, RM_NEG], [RM_ABS, RM_NEG]])
|
||||
O_XCHG_ATOMIC = hw_op('xchg.atomic', OM_ALU_ATOMEXT, 2, 2, [], [[RM_ABS, RM_NEG], [RM_ABS, RM_NEG]])
|
||||
O_CMPXCHG_ATOMIC = hw_op('cmpxchg.atomic', OM_ALU_ATOMEXT + [OM_TST_TYPE_MAIN], 2, 3, [], [[RM_ABS, RM_NEG], [RM_ABS, RM_NEG]])
|
||||
O_MIN_ATOMIC = hw_op('min.atomic', OM_ALU_ATOMEXT + [OM_TST_TYPE_MAIN], 2, 2, [], [[RM_ABS, RM_NEG], [RM_ABS, RM_NEG]])
|
||||
O_MAX_ATOMIC = hw_op('max.atomic', OM_ALU_ATOMEXT + [OM_TST_TYPE_MAIN], 2, 2, [], [[RM_ABS, RM_NEG], [RM_ABS, RM_NEG]])
|
||||
O_LOGICAL_ATOMIC = hw_op('logical.atomic', OM_ALU_ATOMEXT + [OM_LOGIOP], 2, 2, [], [[RM_ABS, RM_NEG], [RM_ABS, RM_NEG]])
|
||||
|
||||
O_FLUSH_P0 = hw_op('flush.p0', [OM_EXEC_CND, OM_END])
|
||||
|
||||
O_MBYP2 = hw_op('mbyp2', OM_ALU, 2, 2, [], [[RM_ABS, RM_NEG], [RM_ABS, RM_NEG]])
|
||||
|
||||
# Pseudo-ops (unmapped).
|
||||
O_FNEG = pseudo_op('fneg', OM_ALU, 1, 1)
|
||||
O_FABS = pseudo_op('fabs', OM_ALU, 1, 1)
|
||||
O_FFLR = pseudo_op('fflr', OM_ALU, 1, 1)
|
||||
O_MOV = pseudo_op('mov', OM_ALU, 1, 1)
|
||||
O_MOV_OFFSET = pseudo_op('mov.offset', OM_ALU + [OM_OFFSET_SD], 1, 2)
|
||||
O_VEC = pseudo_op('vec', [OM_EXEC_CND], 1, VARIABLE)
|
||||
O_COMP = pseudo_op('comp', [], 1, 2)
|
||||
O_FENCE = pseudo_op('fence')
|
||||
|
||||
O_OP_ATOMIC_OFFSET = pseudo_op('op.atomic.offset', OM_ALU_ATOMEXT + [OM_ATOM_OP], 2, 4, [], [[RM_ABS, RM_NEG], [RM_ABS, RM_NEG]])
|
||||
|
||||
O_BREAK = pseudo_op('break', [OM_EXEC_CND])
|
||||
O_CONTINUE = pseudo_op('continue', [OM_EXEC_CND])
|
||||
@@ -0,0 +1,819 @@
|
||||
/*
|
||||
* Copyright © 2024 Imagination Technologies Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file pco_opt.c
|
||||
*
|
||||
* \brief PCO optimization passes.
|
||||
*/
|
||||
|
||||
#include "pco.h"
|
||||
#include "pco_builder.h"
|
||||
#include "util/bitscan.h"
|
||||
#include "util/bitset.h"
|
||||
#include "util/macros.h"
|
||||
#include "util/ralloc.h"
|
||||
#include "util/u_dynarray.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/** Source use. */
|
||||
struct pco_use {
|
||||
pco_instr *instr;
|
||||
pco_ref *psrc;
|
||||
};
|
||||
|
||||
/** Shared optimization context. */
|
||||
struct pco_opt_ctx {
|
||||
void *mem_ctx;
|
||||
struct util_dynarray mods;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Prepares modifiers and their users for propagation.
|
||||
*
|
||||
* Instructions with commutative sources may use a modifier in the source which
|
||||
* can't have said modifier applied to it, e.g. fadd can have {abs,neg,flr} set
|
||||
* in src0, but src1 only supports abs.
|
||||
*
|
||||
* \param[in,out] shader PCO shader.
|
||||
* \param[in,out] ctx Shared optimization context.
|
||||
* \return True if any instructions were modified.
|
||||
*/
|
||||
static inline bool pco_opt_prep_mods(pco_shader *shader,
|
||||
struct pco_opt_ctx *ctx)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
util_dynarray_init(&ctx->mods, ctx->mem_ctx);
|
||||
|
||||
/* TODO: support for more modifiers/ops. */
|
||||
/* TODO: support cases where > 1 modifier can be applied (e.g. .abs.neg),
|
||||
* and where modifiers might need to be applied on more than one source.
|
||||
*/
|
||||
pco_foreach_func_in_shader (func, shader) {
|
||||
pco_foreach_instr_in_func_safe (mod, func) {
|
||||
if (mod->op != PCO_OP_FNEG && mod->op != PCO_OP_FABS &&
|
||||
mod->op != PCO_OP_FFLR)
|
||||
continue;
|
||||
|
||||
pco_foreach_instr_in_func_from (instr, mod) {
|
||||
if (instr->op != PCO_OP_FADD && instr->op != PCO_OP_FMUL)
|
||||
continue;
|
||||
|
||||
pco_ref *match_src = NULL;
|
||||
pco_ref *other_src = NULL;
|
||||
pco_foreach_instr_src (psrc, instr) {
|
||||
if (!pco_ref_is_ssa(*psrc) || psrc->val != mod->dest[0].val)
|
||||
other_src = psrc;
|
||||
else
|
||||
match_src = psrc;
|
||||
}
|
||||
|
||||
/* Instruction doesn't use the mod. */
|
||||
if (!match_src)
|
||||
continue;
|
||||
|
||||
/* Mod used in *both* sources; swapping would do nothing. */
|
||||
if (!other_src)
|
||||
continue;
|
||||
|
||||
unsigned match_src_index = match_src - instr->src;
|
||||
unsigned other_src_index = other_src - instr->src;
|
||||
|
||||
bool match_has_mod = false;
|
||||
bool other_has_mod = false;
|
||||
|
||||
switch (mod->op) {
|
||||
case PCO_OP_FNEG:
|
||||
match_has_mod = pco_instr_src_has_neg(instr, match_src_index);
|
||||
other_has_mod = pco_instr_src_has_neg(instr, other_src_index);
|
||||
break;
|
||||
|
||||
case PCO_OP_FABS:
|
||||
match_has_mod = pco_instr_src_has_abs(instr, match_src_index);
|
||||
other_has_mod = pco_instr_src_has_abs(instr, other_src_index);
|
||||
break;
|
||||
|
||||
case PCO_OP_FFLR:
|
||||
match_has_mod = pco_instr_src_has_flr(instr, match_src_index);
|
||||
other_has_mod = pco_instr_src_has_flr(instr, other_src_index);
|
||||
break;
|
||||
|
||||
default:
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
/* Source can already have the mod set. */
|
||||
if (match_has_mod)
|
||||
continue;
|
||||
|
||||
/* Other source can't have the mod set either. */
|
||||
if (!other_has_mod)
|
||||
continue;
|
||||
|
||||
/* Swap the sources. */
|
||||
pco_ref tmp = *match_src;
|
||||
*match_src = *other_src;
|
||||
*other_src = tmp;
|
||||
|
||||
progress = true;
|
||||
}
|
||||
|
||||
/* Rewrite the mod op to a mov. */
|
||||
pco_ref src = mod->src[0];
|
||||
switch (mod->op) {
|
||||
case PCO_OP_FNEG:
|
||||
src = pco_ref_neg(src);
|
||||
break;
|
||||
|
||||
case PCO_OP_FABS:
|
||||
src = pco_ref_abs(src);
|
||||
break;
|
||||
|
||||
case PCO_OP_FFLR:
|
||||
src = pco_ref_flr(src);
|
||||
break;
|
||||
|
||||
default:
|
||||
UNREACHABLE("");
|
||||
}
|
||||
|
||||
pco_builder b = pco_builder_create(func, pco_cursor_before_instr(mod));
|
||||
pco_instr *mov = pco_mov(&b, mod->dest[0], src);
|
||||
util_dynarray_append(&ctx->mods, mov);
|
||||
pco_instr_delete(mod);
|
||||
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Lowers modifiers to hardware instructions.
|
||||
*
|
||||
* \param[in,out] shader PCO shader.
|
||||
* \param[in,out] ctx Shared optimization context.
|
||||
* \return True if any instructions were modified.
|
||||
*/
|
||||
static inline bool pco_opt_lower_mods(pco_shader *shader,
|
||||
struct pco_opt_ctx *ctx)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
util_dynarray_foreach (&ctx->mods, pco_instr *, pmod) {
|
||||
pco_instr *mod = *pmod;
|
||||
|
||||
pco_builder b =
|
||||
pco_builder_create(mod->parent_func, pco_cursor_before_instr(mod));
|
||||
|
||||
if (mod->src[0].flr)
|
||||
pco_fadd(&b, mod->dest[0], mod->src[0], pco_zero);
|
||||
else
|
||||
pco_mbyp(&b, mod->dest[0], mod->src[0]);
|
||||
|
||||
pco_instr_delete(mod);
|
||||
|
||||
progress = true;
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Checks if an instruction can be back-propagated.
|
||||
*
|
||||
* \param[in] to Instruction being back-propagated to.
|
||||
* \param[in] from Instruction being back-propagated from.
|
||||
* \return True if from can be back-propagated.
|
||||
*/
|
||||
static inline bool can_back_prop_instr(const pco_instr *to,
|
||||
const pco_instr *from)
|
||||
{
|
||||
const struct pco_op_info *info = &pco_op_info[from->op];
|
||||
|
||||
/* Ensure any op mods set in from can also be set in to. */
|
||||
u_foreach_bit64 (mod, info->mods) {
|
||||
if (pco_instr_has_mod(from, mod) && pco_instr_mod_is_set(from, mod) &&
|
||||
!pco_instr_has_mod(to, mod))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Transfers any op mods that have been set.
|
||||
*
|
||||
* \param[in] to Instruction receiving the op mods.
|
||||
* \param[in] from Instruction providing the op mods.
|
||||
*/
|
||||
static inline void xfer_set_op_mods(pco_instr *to, const pco_instr *from)
|
||||
{
|
||||
const struct pco_op_info *info = &pco_op_info[from->op];
|
||||
|
||||
/* Transfer set op mods. */
|
||||
u_foreach_bit64 (mod, info->mods) {
|
||||
if (pco_instr_has_mod(from, mod) && pco_instr_mod_is_set(from, mod)) {
|
||||
assert(pco_instr_has_mod(to, mod));
|
||||
pco_instr_set_mod(to, mod, pco_instr_get_mod(from, mod));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Tries to back-propagate an instruction.
|
||||
*
|
||||
* \param[in] uses Global list of uses.
|
||||
* \param[in] instr Instruction to try and back-propagate.
|
||||
* \return True if back-propagation was successful.
|
||||
*/
|
||||
static inline bool try_back_prop_instr(struct pco_use *uses, pco_instr *instr)
|
||||
{
|
||||
pco_ref *pdest_to = &instr->dest[0];
|
||||
if (instr->num_dests != 1 || !pco_ref_is_ssa(*pdest_to))
|
||||
return false;
|
||||
|
||||
struct pco_use *use = &uses[pdest_to->val];
|
||||
if (!use->instr)
|
||||
return false;
|
||||
|
||||
/* TODO: allow propagating instructions which can have their dest/op
|
||||
* modifiers set to perform the same operations as use source modifiers.
|
||||
*
|
||||
* Make sure to check in can_back_prop_instr when implementing this.
|
||||
* We're fine for now since mov has no settable dest mods.
|
||||
*/
|
||||
if (use->instr->op != PCO_OP_MOV || pco_ref_has_mods_set(*use->psrc))
|
||||
return false;
|
||||
|
||||
if (!can_back_prop_instr(instr, use->instr))
|
||||
return false;
|
||||
|
||||
pco_ref *pdest_from = &use->instr->dest[0];
|
||||
|
||||
if (pco_ref_is_idx_reg(*pdest_from))
|
||||
return false;
|
||||
|
||||
if (pco_ref_is_reg(*pdest_from) &&
|
||||
pco_ref_get_reg_class(*pdest_from) == PCO_REG_CLASS_PIXOUT) {
|
||||
return false;
|
||||
|
||||
bool has_isp_fb = false;
|
||||
|
||||
pco_foreach_instr_in_func_from_rev (rev_instr, use->instr) {
|
||||
if (rev_instr == instr)
|
||||
break;
|
||||
|
||||
if (rev_instr->op == PCO_OP_ALPHAF || rev_instr->op == PCO_OP_DEPTHF) {
|
||||
has_isp_fb = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_isp_fb)
|
||||
return false;
|
||||
|
||||
/* Don't move pixout regs into instructions that already use them. */
|
||||
pco_foreach_instr_src (psrc, instr) {
|
||||
if (pco_ref_is_reg(*psrc) &&
|
||||
pco_ref_get_reg_class(*psrc) == PCO_REG_CLASS_PIXOUT) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert(pco_ref_get_bits(*pdest_from) == pco_ref_get_bits(*pdest_to));
|
||||
assert(pco_ref_get_chans(*pdest_from) == pco_ref_get_chans(*pdest_to));
|
||||
assert(!pco_ref_has_mods_set(*pdest_from) &&
|
||||
!pco_ref_has_mods_set(*pdest_to));
|
||||
|
||||
/* Propagate the destination and the set op mods. */
|
||||
/* TODO: types? */
|
||||
*pdest_to = *pdest_from;
|
||||
xfer_set_op_mods(instr, use->instr);
|
||||
pco_instr_delete(use->instr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Instruction back-propagation pass.
|
||||
*
|
||||
* \param[in,out] shader PCO shader.
|
||||
* \return True if any back-propagations were performed.
|
||||
*/
|
||||
static inline bool pco_opt_back_prop(pco_shader *shader)
|
||||
{
|
||||
bool progress = false;
|
||||
struct pco_use *uses;
|
||||
BITSET_WORD *multi_uses;
|
||||
|
||||
pco_foreach_func_in_shader_rev (func, shader) {
|
||||
uses = rzalloc_array_size(NULL, sizeof(*uses), func->next_ssa);
|
||||
multi_uses = rzalloc_array_size(uses,
|
||||
sizeof(*multi_uses),
|
||||
BITSET_WORDS(func->next_ssa));
|
||||
|
||||
pco_foreach_instr_in_func_safe_rev (instr, func) {
|
||||
pco_foreach_instr_src_ssa (psrc, instr) {
|
||||
if (BITSET_TEST(multi_uses, psrc->val) || uses[psrc->val].instr) {
|
||||
BITSET_SET(multi_uses, psrc->val);
|
||||
uses[psrc->val].instr = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
uses[psrc->val] = (struct pco_use){
|
||||
.instr = instr,
|
||||
.psrc = psrc,
|
||||
};
|
||||
}
|
||||
|
||||
progress |= try_back_prop_instr(uses, instr);
|
||||
}
|
||||
|
||||
ralloc_free(uses);
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Checks if a source can be forward-propagated.
|
||||
*
|
||||
* \param[in] to_instr Instruction being forward-propagated to.
|
||||
* \param[in] to Source being forward-propagated to.
|
||||
* \param[in] from Source being forward-propagated from.
|
||||
* \return True if from can be forward-propagated.
|
||||
*/
|
||||
static inline bool can_fwd_prop_src(const pco_instr *to_instr,
|
||||
const pco_ref *to,
|
||||
const pco_ref *from)
|
||||
{
|
||||
/* Check sizes. */
|
||||
if (pco_ref_get_bits(*from) != pco_ref_get_bits(*to))
|
||||
return false;
|
||||
|
||||
if (pco_ref_get_chans(*from) != pco_ref_get_chans(*to))
|
||||
return false;
|
||||
|
||||
/* See if the modifiers can be propagated. */
|
||||
unsigned to_src_index = to - to_instr->src;
|
||||
if (pco_ref_has_mods_set(*from)) {
|
||||
if (from->oneminus && !pco_instr_src_has_oneminus(to_instr, to_src_index))
|
||||
return false;
|
||||
if (from->clamp && !pco_instr_src_has_clamp(to_instr, to_src_index))
|
||||
return false;
|
||||
if (from->flr && !pco_instr_src_has_flr(to_instr, to_src_index))
|
||||
return false;
|
||||
if (from->abs && !pco_instr_src_has_abs(to_instr, to_src_index))
|
||||
return false;
|
||||
if (from->neg && !pco_instr_src_has_neg(to_instr, to_src_index))
|
||||
return false;
|
||||
if (from->elem && !pco_instr_src_has_elem(to_instr, to_src_index))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* TODO: Also need to consider whether the source can be represented in the
|
||||
* propagated instruction.
|
||||
* Or, a legalize pass to insert movs; probably better since
|
||||
* feature/arch-agnostic.
|
||||
*/
|
||||
|
||||
if (pco_ref_is_reg(*from) &&
|
||||
pco_ref_get_reg_class(*from) == PCO_REG_CLASS_PIXOUT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Tries to forward-propagate an instruction.
|
||||
*
|
||||
* \param[in] writes Global list of writes.
|
||||
* \param[in] instr Instruction to try and forward-propagate.
|
||||
* \return True if forward-propagation was successful.
|
||||
*/
|
||||
static inline bool try_fwd_prop_instr(pco_instr **writes, pco_instr *instr)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
pco_foreach_instr_src_ssa (psrc, instr) {
|
||||
pco_instr *parent_instr = writes[psrc->val];
|
||||
|
||||
if (!parent_instr || parent_instr->op != PCO_OP_MOV)
|
||||
continue;
|
||||
|
||||
if (!can_fwd_prop_src(instr, psrc, &parent_instr->src[0]))
|
||||
continue;
|
||||
|
||||
/* Propagate the source. */
|
||||
pco_ref repl = parent_instr->src[0];
|
||||
if (psrc->flr)
|
||||
repl = pco_ref_flr(repl);
|
||||
else if (psrc->abs)
|
||||
repl = pco_ref_abs(repl);
|
||||
|
||||
repl.neg ^= psrc->neg;
|
||||
|
||||
/* TODO: types? */
|
||||
*psrc = repl;
|
||||
|
||||
if (pco_instr_has_olchk(parent_instr) &&
|
||||
pco_instr_get_olchk(parent_instr)) {
|
||||
assert(pco_instr_has_olchk(instr));
|
||||
pco_instr_set_olchk(instr, true);
|
||||
}
|
||||
|
||||
progress = true;
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Instruction forward-propagation pass.
|
||||
*
|
||||
* \param[in,out] shader PCO shader.
|
||||
* \return True if any forward-propagations were performed.
|
||||
*/
|
||||
static inline bool pco_opt_fwd_prop(pco_shader *shader)
|
||||
{
|
||||
bool progress = false;
|
||||
pco_instr **writes;
|
||||
|
||||
pco_foreach_func_in_shader (func, shader) {
|
||||
writes = rzalloc_array_size(NULL, sizeof(*writes), func->next_ssa);
|
||||
|
||||
pco_foreach_instr_in_func (instr, func) {
|
||||
pco_foreach_instr_dest_ssa (pdest, instr) {
|
||||
writes[pdest->val] = instr;
|
||||
}
|
||||
|
||||
progress |= try_fwd_prop_instr(writes, instr);
|
||||
}
|
||||
|
||||
ralloc_free(writes);
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Tries to propagate a comp instruction referencing hw registers.
|
||||
*
|
||||
* \param[in] src Source to match for replacement.
|
||||
* \param[in] repl Replacement hw register reference.
|
||||
* \param[in] from Instruction to try and propagate from.
|
||||
* \return True if propagation was successful.
|
||||
*/
|
||||
static inline bool try_prop_hw_comp(pco_ref src, pco_ref repl, pco_instr *from)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
pco_foreach_instr_in_func_from (instr, from) {
|
||||
pco_foreach_instr_src_ssa (psrc, instr) {
|
||||
if (psrc->val != src.val)
|
||||
continue;
|
||||
|
||||
/* Propagate the source. */
|
||||
pco_ref _repl = repl;
|
||||
if (psrc->flr)
|
||||
_repl = pco_ref_flr(_repl);
|
||||
else if (psrc->abs)
|
||||
_repl = pco_ref_abs(_repl);
|
||||
|
||||
_repl.neg ^= psrc->neg;
|
||||
|
||||
/* TODO: types? */
|
||||
*psrc = _repl;
|
||||
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Pass to propagate comp instructions referencing hw registers.
|
||||
*
|
||||
* \param[in,out] shader PCO shader.
|
||||
* \return True if any hw reg propagations were performed.
|
||||
*/
|
||||
static inline bool pco_opt_prop_hw_comps(pco_shader *shader)
|
||||
{
|
||||
bool progress = false;
|
||||
pco_foreach_func_in_shader (func, shader) {
|
||||
pco_foreach_instr_in_func_safe (instr, func) {
|
||||
if (instr->op != PCO_OP_COMP)
|
||||
continue;
|
||||
|
||||
pco_ref vec_src = instr->src[0];
|
||||
if (pco_ref_is_ssa(vec_src))
|
||||
continue;
|
||||
|
||||
pco_ref dest = instr->dest[0];
|
||||
assert(pco_ref_is_ssa(dest));
|
||||
|
||||
unsigned offset = pco_ref_get_imm(instr->src[1]);
|
||||
|
||||
/* Construct a replacement scalar reference. */
|
||||
pco_ref repl = vec_src;
|
||||
repl = pco_ref_chans(repl, 1);
|
||||
repl = pco_ref_offset(repl, offset);
|
||||
|
||||
progress |= try_prop_hw_comp(dest, repl, instr);
|
||||
|
||||
pco_instr_delete(instr);
|
||||
}
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Performs shader optimizations.
|
||||
*
|
||||
* \param[in,out] shader PCO shader.
|
||||
* \return True if the pass made progress.
|
||||
*/
|
||||
bool pco_opt(pco_shader *shader)
|
||||
{
|
||||
bool progress = false;
|
||||
struct pco_opt_ctx ctx = { .mem_ctx = ralloc_context(NULL) };
|
||||
|
||||
PCO_PASS(progress, shader, pco_opt_prep_mods, &ctx);
|
||||
PCO_PASS(progress, shader, pco_opt_back_prop);
|
||||
PCO_PASS(progress, shader, pco_opt_fwd_prop);
|
||||
/* TODO: Track whether there are any comp instructions referencing hw
|
||||
* registers resulting from the previous passes, and only run
|
||||
* pco_opt_prop_hw_comps if this is the case.
|
||||
*/
|
||||
|
||||
PCO_PASS(progress, shader, pco_opt_prop_hw_comps);
|
||||
|
||||
PCO_PASS(progress, shader, pco_opt_lower_mods, &ctx);
|
||||
ralloc_free(ctx.mem_ctx);
|
||||
return progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Checks whether an instruction has side-effects.
|
||||
*
|
||||
* \param[in] instr Instruction to check.
|
||||
* \return True if the instruction has side-effects.
|
||||
*/
|
||||
static inline bool instr_has_side_effects(pco_instr *instr)
|
||||
{
|
||||
/* Atomic instructions. */
|
||||
if (pco_instr_has_atom(instr) && pco_instr_get_atom(instr))
|
||||
return true;
|
||||
|
||||
switch (instr->op) {
|
||||
case PCO_OP_ATOMIC:
|
||||
case PCO_OP_FDSX:
|
||||
case PCO_OP_FDSY:
|
||||
|
||||
/* TODO: we don't really want to mark this as having side-effects, but
|
||||
* idfwdf does smp without using the results.
|
||||
*/
|
||||
case PCO_OP_SMP:
|
||||
|
||||
case PCO_OP_IADD32_ATOMIC:
|
||||
case PCO_OP_XCHG_ATOMIC:
|
||||
case PCO_OP_CMPXCHG_ATOMIC:
|
||||
case PCO_OP_MIN_ATOMIC:
|
||||
case PCO_OP_MAX_ATOMIC:
|
||||
case PCO_OP_LOGICAL_ATOMIC:
|
||||
|
||||
case PCO_OP_OP_ATOMIC_OFFSET:
|
||||
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO:
|
||||
* - gradient
|
||||
* - conditional
|
||||
* - sample writes (+ set the destination pointer to point to the write data)
|
||||
* - others
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Performs DCE.
|
||||
*
|
||||
* \param[in,out] shader PCO shader.
|
||||
* \return True if the pass made progress.
|
||||
*/
|
||||
bool pco_dce(pco_shader *shader)
|
||||
{
|
||||
bool progress = false;
|
||||
BITSET_WORD *ssa_used;
|
||||
BITSET_WORD *vreg_used;
|
||||
|
||||
pco_foreach_func_in_shader (func, shader) {
|
||||
ssa_used = rzalloc_array_size(NULL,
|
||||
sizeof(*ssa_used),
|
||||
BITSET_WORDS(func->next_ssa));
|
||||
|
||||
vreg_used = rzalloc_array_size(NULL,
|
||||
sizeof(*vreg_used),
|
||||
BITSET_WORDS(func->next_vreg));
|
||||
|
||||
/* Collect used SSA/vreg sources. */
|
||||
pco_foreach_instr_in_func (instr, func) {
|
||||
pco_foreach_instr_src_vreg_ssa (psrc, instr) {
|
||||
if (pco_ref_is_ssa(*psrc))
|
||||
BITSET_SET(ssa_used, psrc->val);
|
||||
else
|
||||
BITSET_SET(vreg_used, psrc->val);
|
||||
}
|
||||
}
|
||||
|
||||
pco_foreach_vreg_ssa_if_in_func (pif, func) {
|
||||
if (pco_ref_is_ssa(pif->cond))
|
||||
BITSET_SET(ssa_used, pif->cond.val);
|
||||
else
|
||||
BITSET_SET(vreg_used, pif->cond.val);
|
||||
}
|
||||
|
||||
/* Remove instructions with unused SSA/vreg destinations (if they also
|
||||
* have no side-effects).
|
||||
*/
|
||||
pco_foreach_instr_in_func_safe (instr, func) {
|
||||
bool has_dce_dests = false;
|
||||
bool dests_used = false;
|
||||
|
||||
pco_foreach_instr_dest_vreg_ssa (pdest, instr) {
|
||||
has_dce_dests = true;
|
||||
if (pco_ref_is_ssa(*pdest))
|
||||
dests_used |= BITSET_TEST(ssa_used, pdest->val);
|
||||
else
|
||||
dests_used |= BITSET_TEST(vreg_used, pdest->val);
|
||||
}
|
||||
|
||||
if (has_dce_dests && !dests_used && !instr_has_side_effects(instr)) {
|
||||
pco_instr_delete(instr);
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
|
||||
ralloc_free(vreg_used);
|
||||
ralloc_free(ssa_used);
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
static inline bool only_uncollated_elems(pco_instr *vec)
|
||||
{
|
||||
pco_foreach_instr_src (psrc, vec) {
|
||||
if (pco_ref_get_chans(*psrc) > 1)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Shrinks vectors with unused components.
|
||||
*
|
||||
* \param[in,out] shader PCO shader.
|
||||
* \return True if the pass made progress.
|
||||
*/
|
||||
bool pco_shrink_vecs(pco_shader *shader)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
pco_foreach_func_in_shader (func, shader) {
|
||||
pco_foreach_instr_in_func (vec, func) {
|
||||
if (vec->op != PCO_OP_VEC)
|
||||
continue;
|
||||
|
||||
/* Can't shrink if has collated elems. */
|
||||
if (!only_uncollated_elems(vec))
|
||||
continue;
|
||||
|
||||
pco_ref *pdest = &vec->dest[0];
|
||||
unsigned chans_used = 0;
|
||||
unsigned chans = pco_ref_get_chans(*pdest);
|
||||
pco_foreach_instr_in_func_from (instr, vec) {
|
||||
if (instr->op == PCO_OP_COMP) {
|
||||
pco_ref src = instr->src[0];
|
||||
if (!pco_ref_is_ssa(src))
|
||||
continue;
|
||||
|
||||
if (src.val != pdest->val)
|
||||
continue;
|
||||
|
||||
unsigned offset = pco_ref_get_imm(instr->src[1]);
|
||||
chans_used = MAX2(chans_used, offset);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
pco_foreach_instr_src_ssa (psrc, instr) {
|
||||
if (psrc->val == pdest->val) {
|
||||
chans_used = MAX2(chans_used, pco_ref_get_chans(*psrc) - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++chans_used;
|
||||
assert(chans_used <= chans);
|
||||
|
||||
/* Whole vec used, skip. */
|
||||
if (chans_used == chans)
|
||||
continue;
|
||||
|
||||
/* Update the vec. */
|
||||
vec->num_srcs = chans_used;
|
||||
*pdest = pco_ref_chans(*pdest, chans_used);
|
||||
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
bool pco_opt_comp_only_vecs(pco_shader *shader)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
pco_foreach_func_in_shader (func, shader) {
|
||||
pco_foreach_instr_in_func (vec, func) {
|
||||
if (vec->op != PCO_OP_VEC)
|
||||
continue;
|
||||
|
||||
bool used_by_noncomps = false;
|
||||
pco_ref dest = vec->dest[0];
|
||||
|
||||
struct util_dynarray comps = UTIL_DYNARRAY_INIT;
|
||||
|
||||
pco_foreach_instr_in_func_from (instr, vec) {
|
||||
if (instr->op == PCO_OP_COMP) {
|
||||
if (instr->src[0].val == dest.val) {
|
||||
util_dynarray_append(&comps, instr);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
pco_foreach_instr_src_ssa (psrc, instr) {
|
||||
if (psrc->val == dest.val) {
|
||||
used_by_noncomps = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (used_by_noncomps)
|
||||
break;
|
||||
}
|
||||
|
||||
if (used_by_noncomps) {
|
||||
util_dynarray_fini(&comps);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Has collated vec, skip. */
|
||||
/* TODO: support this. */
|
||||
if (vec->num_srcs != util_dynarray_num_elements(&comps, pco_instr *)) {
|
||||
util_dynarray_fini(&comps);
|
||||
continue;
|
||||
}
|
||||
|
||||
util_dynarray_foreach (&comps, pco_instr *, _comp) {
|
||||
pco_instr *comp = *_comp;
|
||||
pco_ref dest = comp->dest[0];
|
||||
assert(pco_ref_is_ssa(dest));
|
||||
|
||||
unsigned offset = pco_ref_get_imm(comp->src[1]);
|
||||
assert(offset < vec->num_srcs);
|
||||
|
||||
pco_builder b =
|
||||
pco_builder_create(func, pco_cursor_before_instr(comp));
|
||||
pco_mov(&b, comp->dest[0], vec->src[offset]);
|
||||
|
||||
pco_instr_delete(comp);
|
||||
}
|
||||
|
||||
util_dynarray_fini(&comps);
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,500 @@
|
||||
# Copyright © 2024 Imagination Technologies Ltd.
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
from enum import Enum, auto
|
||||
|
||||
_ = None
|
||||
VARIABLE = ~0
|
||||
|
||||
prefix = 'pco'
|
||||
|
||||
def val_fits_in_bits(val, num_bits):
|
||||
return val < pow(2, num_bits)
|
||||
|
||||
class BaseType(Enum):
|
||||
bool = auto()
|
||||
uint = auto()
|
||||
enum = auto()
|
||||
|
||||
class Type(object):
|
||||
def __init__(self, name, tname, base_type, num_bits, dec_bits, check, encode, nzdefault, print_early, unset, enum):
|
||||
self.name = name
|
||||
self.tname = tname
|
||||
self.base_type = base_type
|
||||
self.num_bits = num_bits
|
||||
self.dec_bits = dec_bits
|
||||
self.check = check
|
||||
self.encode = encode
|
||||
self.nzdefault = nzdefault
|
||||
self.print_early = print_early
|
||||
self.unset = unset
|
||||
self.enum = enum
|
||||
|
||||
types = {}
|
||||
|
||||
def type(name, base_type, num_bits=None, dec_bits=None, check=None, encode=None, nzdefault=None, print_early=False, unset=False, enum=None):
|
||||
assert name not in types.keys(), f'Duplicate type "{name}".'
|
||||
|
||||
if base_type == BaseType.bool:
|
||||
_name = 'bool'
|
||||
elif base_type == BaseType.uint:
|
||||
_name = 'unsigned'
|
||||
elif base_type == BaseType.enum:
|
||||
_name = f'enum {prefix}_{name}'
|
||||
else:
|
||||
assert False, f'Invalid base type for type {name}.'
|
||||
|
||||
t = Type(_name, name, base_type, num_bits, dec_bits, check, encode, nzdefault, print_early, unset, enum)
|
||||
types[name] = t
|
||||
return t
|
||||
|
||||
# Enum types.
|
||||
class EnumType(object):
|
||||
def __init__(self, name, ename, elems, valid, unique_count, is_bitset, parent):
|
||||
self.name = name
|
||||
self.ename = ename
|
||||
self.elems = elems
|
||||
self.valid = valid
|
||||
self.unique_count = unique_count
|
||||
self.is_bitset = is_bitset
|
||||
self.parent = parent
|
||||
|
||||
class EnumElem(object):
|
||||
def __init__(self, cname, value, string):
|
||||
self.cname = cname
|
||||
self.value = value
|
||||
self.string = string
|
||||
|
||||
enums = {}
|
||||
def enum_type(name, elems, is_bitset=False, num_bits=None, *args, **kwargs):
|
||||
assert name not in enums.keys(), f'Duplicate enum "{name}".'
|
||||
|
||||
_elems = {}
|
||||
_valid_vals = set()
|
||||
_valid_valmask = 0
|
||||
next_value = 0
|
||||
for e in elems:
|
||||
if isinstance(e, str):
|
||||
elem = e
|
||||
value = (1 << next_value) if is_bitset else next_value
|
||||
next_value += 1
|
||||
string = elem
|
||||
else:
|
||||
assert isinstance(e, tuple) and len(e) > 1
|
||||
elem = e[0]
|
||||
if isinstance(e[1], str) and len(e) == 2:
|
||||
value = (1 << next_value) if is_bitset else next_value
|
||||
next_value += 1
|
||||
string = e[1]
|
||||
elif isinstance(e[1], int):
|
||||
value = e[1]
|
||||
string = e[2] if len(e) == 3 else elem
|
||||
else:
|
||||
assert False, f'Invalid defintion for element "{elem}" in elem "{name}".'
|
||||
|
||||
assert isinstance(elem, str) and isinstance(value, int) and isinstance(string, str)
|
||||
|
||||
assert not num_bits or val_fits_in_bits(value, num_bits), f'Element "{elem}" in elem "{name}" with value "{value}" does not fit into {num_bits} bits.'
|
||||
# Collect valid values, ensure that elements with repeated values only have one string set.
|
||||
if is_bitset:
|
||||
if (_valid_valmask & value) != 0:
|
||||
string = None
|
||||
_valid_valmask |= value
|
||||
else:
|
||||
if value in _valid_vals:
|
||||
string = None
|
||||
_valid_vals.add(value)
|
||||
|
||||
assert elem not in _elems.keys(), f'Duplicate element "{elem}" in enum "".'
|
||||
cname = f'{prefix}_{name}_{elem}'.upper()
|
||||
_elems[elem] = EnumElem(cname, value, string)
|
||||
|
||||
_name = f'{prefix}_{name}'
|
||||
_valid = _valid_valmask if is_bitset else _valid_vals
|
||||
_unique_count = bin(_valid_valmask).count('1') if is_bitset else len(_valid_vals)
|
||||
enum = EnumType(_name, name, _elems, _valid, _unique_count, is_bitset, parent=None)
|
||||
enums[name] = enum
|
||||
|
||||
return type(name, BaseType.enum, num_bits, *args, **kwargs, enum=enum)
|
||||
|
||||
def enum_subtype(name, parent, num_bits):
|
||||
assert name not in enums.keys(), f'Duplicate enum "{name}".'
|
||||
|
||||
assert parent.enum is not None
|
||||
assert not parent.enum.is_bitset
|
||||
assert parent.num_bits is not None and parent.num_bits > num_bits
|
||||
|
||||
_name = f'{prefix}_{name}'
|
||||
# Validation of subtype - values that will fit in the smaller bit size.
|
||||
_valid = {val for val in parent.enum.valid if val_fits_in_bits(val, num_bits)}
|
||||
enum = EnumType(_name, name, None, _valid, None, False, parent)
|
||||
enums[name] = enum
|
||||
return type(name, BaseType.enum, num_bits, enum=enum)
|
||||
|
||||
# Type specializations.
|
||||
|
||||
field_types = {}
|
||||
field_enum_types = {}
|
||||
def field_type(name, *args, **kwargs):
|
||||
assert name not in field_types.keys(), f'Duplicate field type "{name}".'
|
||||
t = type(name, *args, **kwargs)
|
||||
field_types[name] = t
|
||||
return t
|
||||
|
||||
def field_enum_type(name, *args, **kwargs):
|
||||
assert name not in field_types.keys() and name not in field_enum_types.keys(), f'Duplicate field enum type "{name}".'
|
||||
t = enum_type(name, *args, **kwargs)
|
||||
field_types[name] = t
|
||||
field_enum_types[name] = enums[name]
|
||||
return t
|
||||
|
||||
def field_enum_subtype(name, *args, **kwargs):
|
||||
assert name not in field_types.keys() and name not in field_enum_types.keys(), f'Duplicate field enum (sub)type "{name}".'
|
||||
t = enum_subtype(name, *args, **kwargs)
|
||||
field_types[name] = t
|
||||
field_enum_types[name] = enums[name]
|
||||
return t
|
||||
|
||||
class OpMod(object):
|
||||
def __init__(self, t, cname, ctype):
|
||||
self.t = t
|
||||
self.cname = cname
|
||||
self.ctype = ctype
|
||||
|
||||
op_mods = {}
|
||||
op_mod_enums = {}
|
||||
def op_mod(name, *args, **kwargs):
|
||||
assert name not in op_mods.keys(), f'Duplicate op mod "{name}".'
|
||||
t = type(name, *args, **kwargs)
|
||||
cname = f'{prefix}_op_mod_{name}'.upper()
|
||||
ctype = f'{prefix}_mod_type_{t.base_type.name.upper()}'.upper()
|
||||
om = op_mods[name] = OpMod(t, cname, ctype)
|
||||
assert len(op_mods) <= 64, f'Too many op mods ({len(op_mods)})!'
|
||||
return om
|
||||
|
||||
def op_mod_enum(name, *args, **kwargs):
|
||||
assert name not in op_mods.keys() and name not in op_mod_enums.keys(), f'Duplicate op mod enum "{name}".'
|
||||
t = enum_type(name, *args, **kwargs)
|
||||
cname = f'{prefix}_op_mod_{name}'.upper()
|
||||
ctype = f'{prefix}_mod_type_{t.base_type.name.upper()}'.upper()
|
||||
om = op_mods[name] = OpMod(t, cname, ctype)
|
||||
op_mod_enums[name] = enums[name]
|
||||
assert len(op_mods) <= 64, f'Too many op mods ({len(op_mods)})!'
|
||||
return om
|
||||
|
||||
class RefMod(object):
|
||||
def __init__(self, t, cname, ctype):
|
||||
self.t = t
|
||||
self.cname = cname
|
||||
self.ctype = ctype
|
||||
|
||||
ref_mods = {}
|
||||
ref_mod_enums = {}
|
||||
def ref_mod(name, *args, **kwargs):
|
||||
assert name not in ref_mods.keys(), f'Duplicate ref mod "{name}".'
|
||||
t = type(name, *args, **kwargs)
|
||||
cname = f'{prefix}_ref_mod_{name}'.upper()
|
||||
ctype = f'{prefix}_mod_type_{t.base_type.name.upper()}'.upper()
|
||||
rm = ref_mods[name] = RefMod(t, cname, ctype)
|
||||
assert len(ref_mods) <= 64, f'Too many ref mods ({len(ref_mods)})!'
|
||||
return rm
|
||||
|
||||
def ref_mod_enum(name, *args, **kwargs):
|
||||
assert name not in ref_mods.keys() and name not in ref_mod_enums.keys(), f'Duplicate ref mod enum "{name}".'
|
||||
t = enum_type(name, *args, **kwargs)
|
||||
cname = f'{prefix}_ref_mod_{name}'.upper()
|
||||
ctype = f'{prefix}_mod_type_{t.base_type.name.upper()}'.upper()
|
||||
rm = ref_mods[name] = RefMod(t, cname, ctype)
|
||||
ref_mod_enums[name] = enums[name]
|
||||
assert len(ref_mods) <= 64, f'Too many ref mods ({len(ref_mods)})!'
|
||||
return rm
|
||||
|
||||
# Bit encoding definition helpers.
|
||||
|
||||
class BitPiece(object):
|
||||
def __init__(self, name, byte, hi_bit, lo_bit, num_bits):
|
||||
self.name = name
|
||||
self.byte = byte
|
||||
self.hi_bit = hi_bit
|
||||
self.lo_bit = lo_bit
|
||||
self.num_bits = num_bits
|
||||
|
||||
def bit_piece(name, byte, bit_range):
|
||||
assert bit_range.count(':') <= 1, f'Invalid bit range specification in bit piece {name}.'
|
||||
is_one_bit = not bit_range.count(':')
|
||||
|
||||
split_range = [bit_range, bit_range] if is_one_bit else bit_range.split(':', 1)
|
||||
(hi_bit, lo_bit) = list(map(int, split_range))
|
||||
assert hi_bit < 8 and hi_bit >= 0 and lo_bit < 8 and lo_bit >= 0 and hi_bit >= lo_bit
|
||||
|
||||
_num_bits = hi_bit - lo_bit + 1
|
||||
return BitPiece(name, byte, hi_bit, lo_bit, _num_bits)
|
||||
|
||||
class BitField(object):
|
||||
def __init__(self, name, cname, field_type, pieces, reserved, validate, encoding, encoded_bits):
|
||||
self.name = name
|
||||
self.cname = cname
|
||||
self.field_type = field_type
|
||||
self.pieces = pieces
|
||||
self.reserved = reserved
|
||||
self.validate = validate
|
||||
self.encoding = encoding
|
||||
self.encoded_bits = encoded_bits
|
||||
|
||||
class Encoding(object):
|
||||
def __init__(self, clear, set):
|
||||
self.clear = clear
|
||||
self.set = set
|
||||
|
||||
def bit_field(bit_set_name, name, bit_set_pieces, field_type, pieces, reserved=None):
|
||||
_pieces = [bit_set_pieces[p] for p in pieces]
|
||||
|
||||
total_bits = sum([p.num_bits for p in _pieces])
|
||||
assert total_bits == field_type.num_bits, f'Expected {field_type.num_bits}, got {total_bits} in bit field {name}.'
|
||||
|
||||
if reserved is not None:
|
||||
assert val_fits_in_bits(reserved, total_bits), f'Reserved value for bit field {name} is too large.'
|
||||
|
||||
cname = f'{bit_set_name}_{name}'.upper()
|
||||
if field_type.base_type == BaseType.enum:
|
||||
validate = f'{prefix}_{field_type.enum.ename}_valid({{}})'
|
||||
else:
|
||||
validate = f'{{}} < (1ULL << {field_type.num_bits})'
|
||||
|
||||
encoding = []
|
||||
bits_consumed = 0
|
||||
for i, piece in enumerate(reversed(_pieces)):
|
||||
enc_clear = f'{{}}[{piece.byte}] &= {hex((((1 << piece.num_bits) - 1) << piece.lo_bit) ^ 0xff)}'
|
||||
|
||||
enc_set = f'{{}}[{piece.byte}] |= ('
|
||||
enc_set += f'({{}} >> {bits_consumed})' if bits_consumed > 0 else '{}'
|
||||
enc_set += f' & {hex((1 << piece.num_bits) - 1)})'
|
||||
enc_set += f' << {piece.lo_bit}' if piece.lo_bit > 0 else ''
|
||||
encoding.append(Encoding(enc_clear, enc_set))
|
||||
|
||||
bits_consumed += piece.num_bits
|
||||
|
||||
return BitField(name, cname, field_type, _pieces, reserved, validate, encoding, bits_consumed)
|
||||
|
||||
class BitSet(object):
|
||||
def __init__(self, name, bsname, pieces, fields):
|
||||
self.name = name
|
||||
self.bsname = bsname
|
||||
self.pieces = pieces
|
||||
self.fields = fields
|
||||
self.bit_structs = {}
|
||||
self.variants = []
|
||||
|
||||
bit_sets = {}
|
||||
|
||||
def bit_set(name, pieces, fields):
|
||||
assert name not in bit_sets.keys(), f'Duplicate bit set "{name}".'
|
||||
_name = f'{prefix}_{name}'
|
||||
|
||||
_pieces = {}
|
||||
for (piece, spec) in pieces:
|
||||
assert piece not in _pieces.keys(), f'Duplicate bit piece "{piece}" in bit set "{name}".'
|
||||
_pieces[piece] = bit_piece(piece, *spec)
|
||||
|
||||
_fields = {}
|
||||
for (field, spec) in fields:
|
||||
assert field not in _fields.keys(), f'Duplicate bit field "{field}" in bit set "{name}".'
|
||||
_fields[field] = bit_field(_name, field, _pieces, *spec)
|
||||
|
||||
bs = BitSet(_name, name, _pieces, _fields)
|
||||
bit_sets[name] = bs
|
||||
return bs
|
||||
|
||||
class BitStruct(object):
|
||||
def __init__(self, name, bsname, struct_fields, encode_fields, num_bytes, data, bit_set):
|
||||
self.name = name
|
||||
self.bsname = bsname
|
||||
self.struct_fields = struct_fields
|
||||
self.encode_fields = encode_fields
|
||||
self.num_bytes = num_bytes
|
||||
self.data = data
|
||||
self.bit_set = bit_set
|
||||
|
||||
class StructField(object):
|
||||
def __init__(self, type, field, bits):
|
||||
self.type = type
|
||||
self.field = field
|
||||
self.bits = bits
|
||||
|
||||
class EncodeField(object):
|
||||
def __init__(self, name, value):
|
||||
self.name = name
|
||||
self.value = value
|
||||
|
||||
class Variant(object):
|
||||
def __init__(self, cname, bytes):
|
||||
self.cname = cname
|
||||
self.bytes = bytes
|
||||
|
||||
def bit_struct(name, bit_set, field_mappings, data=None):
|
||||
assert name not in bit_set.bit_structs.keys(), f'Duplicate bit struct "{name}" in bit set "{bit_set.name}".'
|
||||
|
||||
struct_fields = {}
|
||||
encode_fields = []
|
||||
all_pieces = []
|
||||
total_bits = 0
|
||||
for mapping in field_mappings:
|
||||
if isinstance(mapping, str):
|
||||
struct_field = mapping
|
||||
_field = mapping
|
||||
fixed_value = None
|
||||
else:
|
||||
assert isinstance(mapping, tuple)
|
||||
struct_field, _field, *fixed_value = mapping
|
||||
assert len(fixed_value) == 0 or len(fixed_value) == 1
|
||||
fixed_value = None if len(fixed_value) == 0 else fixed_value[0]
|
||||
|
||||
assert struct_field not in struct_fields.keys(), f'Duplicate struct field "{struct_field}" in bit struct "{name}".'
|
||||
assert _field in bit_set.fields.keys(), f'Field "{_field}" in mapping for struct field "{name}.{struct_field}" not defined in bit set "{bit_set.name}".'
|
||||
field = bit_set.fields[_field]
|
||||
field_type = field.field_type
|
||||
is_enum = field_type.base_type == BaseType.enum
|
||||
|
||||
if fixed_value is not None:
|
||||
assert field.reserved is None, f'Fixed value for field mapping "{struct_field}" using field "{_field}" cannot overwrite its reserved value.'
|
||||
|
||||
if is_enum and isinstance(fixed_value, str):
|
||||
enum = field_type.enum
|
||||
assert fixed_value in enum.elems.keys(), f'Fixed value for field mapping "{struct_field}" using field "{_field}" is not an element of enum {field_type.name}.'
|
||||
fixed_value = enum.elems[fixed_value].cname.upper()
|
||||
else:
|
||||
if isinstance(fixed_value, bool):
|
||||
fixed_value = int(fixed_value)
|
||||
|
||||
assert isinstance(fixed_value, int)
|
||||
assert val_fits_in_bits(fixed_value, field_type.num_bits), f'Fixed value for field mapping "{struct_field}" using field "{_field}" is too large.'
|
||||
|
||||
all_pieces.extend([(piece.lo_bit + (8 * piece.byte), piece.hi_bit + (8 * piece.byte), piece.name) for piece in field.pieces])
|
||||
total_bits += field_type.num_bits
|
||||
|
||||
# Describe how to encode the bit struct.
|
||||
encode_field = f'{bit_set.name}_{_field}'.upper()
|
||||
if fixed_value is not None:
|
||||
encode_value = fixed_value
|
||||
elif field.reserved is not None:
|
||||
encode_value = field.reserved
|
||||
else:
|
||||
encode_value = f's.{struct_field}'
|
||||
encode_fields.append(EncodeField(encode_field, encode_value))
|
||||
|
||||
# Describe settable fields.
|
||||
if field.reserved is None and fixed_value is None:
|
||||
# Use parent enum for struct fields.
|
||||
if is_enum and field_type.enum.parent is not None:
|
||||
field_type = field_type.enum.parent
|
||||
|
||||
struct_field_bits = field_type.dec_bits if field_type.dec_bits is not None else field_type.num_bits
|
||||
struct_fields[struct_field] = StructField(field_type, struct_field, struct_field_bits)
|
||||
|
||||
# Check for overlapping pieces.
|
||||
for p0 in all_pieces:
|
||||
for p1 in all_pieces:
|
||||
if p0 == p1:
|
||||
continue
|
||||
assert p0[1] < p1[0] or p0[0] > p1[1], f'Pieces "{p0[2]}" and "{p1[2]}" overlap in bit struct "{name}".'
|
||||
|
||||
# Check for byte-alignment.
|
||||
assert (total_bits % 8) == 0, f'Bit struct "{name}" has a non-byte-aligned number of bits ({total_bits}).'
|
||||
|
||||
_name = f'{bit_set.name}_{name}'
|
||||
total_bytes = total_bits // 8
|
||||
bs = BitStruct(_name, name, struct_fields, encode_fields, total_bytes, data, bit_set)
|
||||
bit_set.bit_structs[name] = bs
|
||||
bit_set.variants.append(Variant(f'{bit_set.name}_{name}'.upper(), total_bytes))
|
||||
|
||||
return bs
|
||||
|
||||
# Op definitions.
|
||||
class Op(object):
|
||||
def __init__(self, name, cname, bname, op_type, op_mods, cop_mods, op_mod_map, num_dests, num_srcs, dest_mods, cdest_mods, src_mods, csrc_mods, has_target_cf_node, builder_params):
|
||||
self.name = name
|
||||
self.cname = cname
|
||||
self.bname = bname
|
||||
self.op_type = op_type
|
||||
self.op_mods = op_mods
|
||||
self.cop_mods = cop_mods
|
||||
self.op_mod_map = op_mod_map
|
||||
self.num_dests = num_dests
|
||||
self.num_srcs = num_srcs
|
||||
self.dest_mods = dest_mods
|
||||
self.cdest_mods = cdest_mods
|
||||
self.src_mods = src_mods
|
||||
self.csrc_mods = csrc_mods
|
||||
self.has_target_cf_node = has_target_cf_node
|
||||
self.builder_params = builder_params
|
||||
|
||||
ops = {}
|
||||
|
||||
def op(name, op_type, op_mods, num_dests, num_srcs, dest_mods, src_mods, has_target_cf_node):
|
||||
assert name not in ops.keys(), f'Duplicate op "{name}".'
|
||||
|
||||
_name = name.replace('.', '_')
|
||||
cname = f'{prefix}_op_{_name}'
|
||||
bname = f'{prefix}_{_name}'
|
||||
cop_mods = 0 if not op_mods else ' | '.join([f'(1ULL << {op_mod.cname})' for op_mod in op_mods])
|
||||
op_mod_map = {op_mod.cname: index + 1 for index, op_mod in enumerate(op_mods)}
|
||||
cdest_mods = {i: 0 if not destn_mods else ' | '.join([f'(1ULL << {ref_mod.cname})' for ref_mod in destn_mods]) for i, destn_mods in enumerate(dest_mods)}
|
||||
csrc_mods = {i: 0 if not srcn_mods else ' | '.join([f'(1ULL << {ref_mod.cname})' for ref_mod in srcn_mods]) for i, srcn_mods in enumerate(src_mods)}
|
||||
|
||||
builder_params = ['', '', '', '', '', '', '']
|
||||
|
||||
builder_params[0] = 'pco_func *func'
|
||||
builder_params[1] = 'pco_builder *b'
|
||||
builder_params[2] = 'func'
|
||||
builder_params[3] = 'b'
|
||||
|
||||
if has_target_cf_node:
|
||||
builder_params[0] += ', pco_cf_node *target_cf_node'
|
||||
builder_params[1] += ', pco_cf_node *target_cf_node'
|
||||
builder_params[2] += ', target_cf_node'
|
||||
builder_params[3] += ', target_cf_node'
|
||||
|
||||
if num_dests == VARIABLE:
|
||||
builder_params[0] += f', unsigned num_dests, pco_ref *dest'
|
||||
builder_params[1] += f', unsigned num_dests, pco_ref *dest'
|
||||
builder_params[2] += f', num_dests, dest'
|
||||
builder_params[3] += f', num_dests, dest'
|
||||
else:
|
||||
for d in range(num_dests):
|
||||
builder_params[0] += f', pco_ref dest{d}'
|
||||
builder_params[1] += f', pco_ref dest{d}'
|
||||
builder_params[2] += f', dest{d}'
|
||||
builder_params[3] += f', dest{d}'
|
||||
|
||||
if num_srcs == VARIABLE:
|
||||
builder_params[0] += f', unsigned num_srcs, pco_ref *src'
|
||||
builder_params[1] += f', unsigned num_srcs, pco_ref *src'
|
||||
builder_params[2] += f', num_srcs, src'
|
||||
builder_params[3] += f', num_srcs, src'
|
||||
else:
|
||||
for s in range(num_srcs):
|
||||
builder_params[0] += f', pco_ref src{s}'
|
||||
builder_params[1] += f', pco_ref src{s}'
|
||||
builder_params[2] += f', src{s}'
|
||||
builder_params[3] += f', src{s}'
|
||||
|
||||
if bool(op_mods):
|
||||
builder_params[0] += f', struct {prefix}_{_name}_mods mods'
|
||||
builder_params[1] += f', struct {prefix}_{_name}_mods mods'
|
||||
builder_params[4] = ', ...'
|
||||
builder_params[5] = f', (struct {bname}_mods){{0, ##__VA_ARGS__}}'
|
||||
builder_params[6] = ', mods'
|
||||
|
||||
|
||||
op = Op(name, cname, bname, op_type, op_mods, cop_mods, op_mod_map, num_dests, num_srcs, dest_mods, cdest_mods, src_mods, csrc_mods, has_target_cf_node, builder_params)
|
||||
ops[name] = op
|
||||
return op
|
||||
|
||||
def pseudo_op(name, op_mods=[], num_dests=0, num_srcs=0, dest_mods=[], src_mods=[], has_target_cf_node=False):
|
||||
return op(name, 'pseudo', op_mods, num_dests, num_srcs, dest_mods, src_mods, has_target_cf_node)
|
||||
|
||||
def hw_op(name, op_mods=[], num_dests=0, num_srcs=0, dest_mods=[], src_mods=[], has_target_cf_node=False):
|
||||
return op(name, 'hw', op_mods, num_dests, num_srcs, dest_mods, src_mods, has_target_cf_node)
|
||||
|
||||
def hw_direct_op(name, op_mods=[], num_dests=0, num_srcs=0, dest_mods=[], src_mods=[], has_target_cf_node=False):
|
||||
return op(name, 'hw_direct', op_mods, num_dests, num_srcs, dest_mods, src_mods, has_target_cf_node)
|
||||
Loaded 100 of 12511 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user