pvr: Add a Vulkan driver for Imagination Technologies PowerVR Rogue GPUs
Co-authored-by: Rajnesh Kanwal <rajnesh.kanwal@imgtec.com> Co-authored-by: Karmjit Mahil <Karmjit.Mahil@imgtec.com> Co-authored-by: Simon Perretta <simon.perretta@imgtec.com> Co-authored-by: Alexander Wasey <Alexander.Wasey@imgtec.com> Signed-off-by: Frank Binns <frank.binns@imgtec.com> Signed-off-by: Rajnesh Kanwal <rajnesh.kanwal@imgtec.com> Signed-off-by: Karmjit Mahil <Karmjit.Mahil@imgtec.com> Signed-off-by: Simon Perretta <simon.perretta@imgtec.com> Signed-off-by: Alexander Wasey <Alexander.Wasey@imgtec.com> Acked-by: Jason Ekstrand <jason.ekstrand@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15243>
This commit is contained in:
parent
5d151ddfba
commit
8991e64641
|
@ -109,6 +109,11 @@ meson.build @dbaker @eric
|
|||
# Freedreno
|
||||
/src/gallium/drivers/freedreno/ @robclark
|
||||
|
||||
# Imagination
|
||||
/include/drm-uapi/pvr_drm.h @CreativeCylon @frankbinns @rajnesh-kanwal
|
||||
/src/imagination/ @CreativeCylon @frankbinns @rajnesh-kanwal
|
||||
/src/imagination/rogue/ @simon-perretta-img
|
||||
|
||||
# Intel
|
||||
/include/drm-uapi/i915_drm.h @kwg @llandwerlin @jekstrand @idr
|
||||
/include/pci_ids/i*_pci_ids.h @kwg @llandwerlin @jekstrand @idr
|
||||
|
|
|
@ -272,6 +272,8 @@ with_swrast_vk = _vulkan_drivers.contains('swrast')
|
|||
with_virtio_vk = _vulkan_drivers.contains('virtio-experimental')
|
||||
with_freedreno_kgsl = get_option('freedreno-kgsl')
|
||||
with_broadcom_vk = _vulkan_drivers.contains('broadcom')
|
||||
with_imagination_vk = _vulkan_drivers.contains('imagination-experimental')
|
||||
with_imagination_srv = get_option('imagination-srv')
|
||||
with_any_vk = _vulkan_drivers.length() != 0
|
||||
|
||||
with_any_broadcom = with_gallium_vc4 or with_gallium_v3d or with_broadcom_vk
|
||||
|
|
|
@ -192,7 +192,7 @@ option(
|
|||
'vulkan-drivers',
|
||||
type : 'array',
|
||||
value : ['auto'],
|
||||
choices : ['auto', 'amd', 'broadcom', 'freedreno', 'intel', 'panfrost', 'swrast', 'virtio-experimental'],
|
||||
choices : ['auto', 'amd', 'broadcom', 'freedreno', 'imagination-experimental', 'intel', 'panfrost', 'swrast', 'virtio-experimental'],
|
||||
description : 'List of vulkan drivers to build. If this is set to auto all drivers applicable to the target OS/architecture will be built'
|
||||
)
|
||||
option(
|
||||
|
@ -201,6 +201,12 @@ option(
|
|||
value : false,
|
||||
description : 'use kgsl backend for freedreno vulkan driver',
|
||||
)
|
||||
option(
|
||||
'imagination-srv',
|
||||
type : 'boolean',
|
||||
value : false,
|
||||
description : 'Enable Services backend for Imagination Technologies vulkan driver',
|
||||
)
|
||||
option(
|
||||
'shader-cache',
|
||||
type : 'combo',
|
||||
|
|
|
@ -0,0 +1,247 @@
|
|||
# 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: false
|
||||
#AlignConsecutiveBitFields: false # Requires clang-11
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignConsecutiveMacros: false
|
||||
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: false
|
||||
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: false
|
||||
# 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: [
|
||||
'foreach_instr',
|
||||
'foreach_instr_safe',
|
||||
'hash_table_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_emit_merge',
|
||||
'pvr_csb_pack',
|
||||
'nir_foreach_block',
|
||||
'nir_foreach_block_safe',
|
||||
'nir_foreach_function',
|
||||
'nir_foreach_instr',
|
||||
'nir_foreach_instr_safe',
|
||||
'nir_foreach_shader_in_variable',
|
||||
'nir_foreach_shader_out_variable',
|
||||
'nir_foreach_use',
|
||||
'nir_foreach_use_safe',
|
||||
'nir_foreach_variable_with_modes',
|
||||
'u_vector_foreach',
|
||||
'util_dynarray_foreach',
|
||||
'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'
|
||||
]
|
||||
|
||||
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,2 @@
|
|||
[*.{c,h,cpp,hpp,cc,hh}]
|
||||
max_line_length = 80
|
|
@ -0,0 +1,33 @@
|
|||
# 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.
|
||||
|
||||
libpowervr_common = static_library(
|
||||
'powervr_common',
|
||||
[
|
||||
'pvr_device_info.c',
|
||||
],
|
||||
include_directories : [
|
||||
inc_include,
|
||||
inc_src,
|
||||
],
|
||||
c_args : [no_override_init_args],
|
||||
gnu_symbol_visibility : 'hidden',
|
||||
)
|
|
@ -0,0 +1,294 @@
|
|||
/*
|
||||
* 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 "pvr_device_info.h"
|
||||
|
||||
const struct pvr_device_ident pvr_device_ident_4_V_2_51 = {
|
||||
.device_id = 0x6250,
|
||||
.series_name = "Rogue",
|
||||
.public_name = "GX6250",
|
||||
};
|
||||
|
||||
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_gs_rta_support = true,
|
||||
.has_isp_max_tiles_in_flight = true,
|
||||
.has_isp_samples_per_pixel = true,
|
||||
.has_max_multisample = true,
|
||||
.has_max_partitions = true,
|
||||
.has_max_usc_tasks = true,
|
||||
.has_num_clusters = true,
|
||||
.has_num_raster_pipes = true,
|
||||
.has_num_user_clip_planes = true,
|
||||
.has_robust_buffer_access = true,
|
||||
.has_slc_cache_line_size_bits = true,
|
||||
.has_slc_mcu_cache_controls = 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_usc_f16sop_u8 = true,
|
||||
.has_usc_min_output_registers_per_pix = 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,
|
||||
.isp_max_tiles_in_flight = 4U,
|
||||
.isp_samples_per_pixel = 2U,
|
||||
.max_multisample = 8U,
|
||||
.max_partitions = 8U,
|
||||
.max_usc_tasks = 56U,
|
||||
.num_clusters = 2U,
|
||||
.num_raster_pipes = 1U,
|
||||
.num_user_clip_planes = 8U,
|
||||
.slc_cache_line_size_bits = 512U,
|
||||
.tile_size_x = 32U,
|
||||
.tile_size_y = 32U,
|
||||
.usc_min_output_registers_per_pix = 2U,
|
||||
.uvs_banks = 8U,
|
||||
.uvs_pba_entries = 320U,
|
||||
.uvs_vtx_entries = 288U,
|
||||
.vdm_cam_size = 256U,
|
||||
};
|
||||
|
||||
const struct pvr_device_enhancements pvr_device_enhancements_4_40_2_51 = {
|
||||
.has_ern35421 = true,
|
||||
.has_ern38020 = true,
|
||||
.has_ern38748 = true,
|
||||
.has_ern42307 = true,
|
||||
};
|
||||
|
||||
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_brn51210 = true,
|
||||
.has_brn51764 = true,
|
||||
.has_brn52354 = true,
|
||||
.has_brn52942 = true,
|
||||
.has_brn56279 = true,
|
||||
.has_brn58839 = true,
|
||||
.has_brn62269 = true,
|
||||
.has_brn66011 = true,
|
||||
.has_brn70165 = true,
|
||||
};
|
||||
|
||||
const struct pvr_device_ident pvr_device_ident_33_V_11_3 = {
|
||||
.device_id = 0x33011003,
|
||||
.series_name = "A-Series",
|
||||
.public_name = "AXE-1-16M",
|
||||
};
|
||||
|
||||
const struct pvr_device_features pvr_device_features_33_V_11_3 = {
|
||||
.has_common_store_size_in_dwords = true,
|
||||
.has_compute = true,
|
||||
.has_isp_max_tiles_in_flight = true,
|
||||
.has_isp_samples_per_pixel = true,
|
||||
.has_max_multisample = true,
|
||||
.has_max_partitions = true,
|
||||
.has_max_usc_tasks = true,
|
||||
.has_num_clusters = true,
|
||||
.has_num_raster_pipes = true,
|
||||
.has_num_user_clip_planes = 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_x = true,
|
||||
.has_tile_size_y = true,
|
||||
.has_tile_size_16x16 = true,
|
||||
.has_tpu_extended_integer_lookup = true,
|
||||
.has_tpu_image_state_v2 = true,
|
||||
.has_usc_f16sop_u8 = true,
|
||||
.has_usc_min_output_registers_per_pix = true,
|
||||
.has_usc_pixel_partition_mask = 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 = 512U * 4U * 4U,
|
||||
.isp_max_tiles_in_flight = 1U,
|
||||
.isp_samples_per_pixel = 1U,
|
||||
.max_multisample = 4U,
|
||||
.max_partitions = 4U,
|
||||
.max_usc_tasks = 24U,
|
||||
.num_clusters = 1U,
|
||||
.num_raster_pipes = 1U,
|
||||
.num_user_clip_planes = 8U,
|
||||
.simple_parameter_format_version = 2U,
|
||||
.slc_cache_line_size_bits = 512U,
|
||||
.tile_size_x = 16U,
|
||||
.tile_size_y = 16U,
|
||||
.usc_min_output_registers_per_pix = 1U,
|
||||
.uvs_banks = 2U,
|
||||
.uvs_pba_entries = 320U,
|
||||
.uvs_vtx_entries = 288U,
|
||||
.vdm_cam_size = 32U,
|
||||
|
||||
.has_s8xe = true,
|
||||
};
|
||||
|
||||
const struct pvr_device_enhancements pvr_device_enhancements_33_15_11_3 = {
|
||||
.has_ern35421 = true,
|
||||
.has_ern38748 = true,
|
||||
.has_ern42307 = true,
|
||||
.has_ern45493 = true,
|
||||
};
|
||||
|
||||
const struct pvr_device_quirks pvr_device_quirks_33_15_11_3 = {
|
||||
.has_brn70165 = true,
|
||||
};
|
||||
|
||||
const struct pvr_device_ident pvr_device_ident_36_V_104_796 = {
|
||||
.device_id = 0x36104796,
|
||||
.series_name = "B-Series",
|
||||
.public_name = "BXS-4-64",
|
||||
};
|
||||
|
||||
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_gpu_multicore_support = true,
|
||||
.has_gs_rta_support = true,
|
||||
.has_isp_max_tiles_in_flight = true,
|
||||
.has_isp_samples_per_pixel = true,
|
||||
.has_max_multisample = true,
|
||||
.has_max_partitions = true,
|
||||
.has_max_usc_tasks = true,
|
||||
.has_num_clusters = true,
|
||||
.has_num_raster_pipes = true,
|
||||
.has_num_user_clip_planes = true,
|
||||
.has_paired_tiles = 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_x = true,
|
||||
.has_tile_size_y = true,
|
||||
.has_tile_size_16x16 = true,
|
||||
.has_tpu_extended_integer_lookup = true,
|
||||
.has_tpu_image_state_v2 = true,
|
||||
.has_usc_f16sop_u8 = true,
|
||||
.has_usc_min_output_registers_per_pix = true,
|
||||
.has_usc_pixel_partition_mask = 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 = 1344U * 4U * 4U,
|
||||
.isp_max_tiles_in_flight = 6U,
|
||||
.isp_samples_per_pixel = 4U,
|
||||
.max_multisample = 4U,
|
||||
.max_partitions = 16U,
|
||||
.max_usc_tasks = 156U,
|
||||
.num_clusters = 1U,
|
||||
.num_raster_pipes = 1U,
|
||||
.num_user_clip_planes = 8U,
|
||||
.simple_parameter_format_version = 2U,
|
||||
.slc_cache_line_size_bits = 512U,
|
||||
.tile_size_x = 16U,
|
||||
.tile_size_y = 16U,
|
||||
.usc_min_output_registers_per_pix = 2U,
|
||||
.uvs_banks = 8U,
|
||||
.uvs_pba_entries = 160U,
|
||||
.uvs_vtx_entries = 144U,
|
||||
.vdm_cam_size = 64U,
|
||||
.xpu_max_slaves = 3U,
|
||||
|
||||
.has_s8xe = true,
|
||||
};
|
||||
|
||||
const struct pvr_device_enhancements pvr_device_enhancements_36_53_104_796 = {
|
||||
.has_ern35421 = true,
|
||||
.has_ern38748 = true,
|
||||
.has_ern42307 = true,
|
||||
.has_ern45493 = true,
|
||||
};
|
||||
|
||||
const struct pvr_device_quirks pvr_device_quirks_36_53_104_796 = {
|
||||
.has_brn44079 = true,
|
||||
.has_brn70165 = true,
|
||||
};
|
||||
|
||||
/**
|
||||
* 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->ident = pvr_device_ident_##_b##_V_##_n##_##_c; \
|
||||
info->ident.b = _b; \
|
||||
info->ident.n = _n; \
|
||||
info->ident.v = _v; \
|
||||
info->ident.c = _c; \
|
||||
info->features = pvr_device_features_##_b##_V_##_n##_##_c; \
|
||||
info->enhancements = pvr_device_enhancements_##_b##_##_v##_##_n##_##_c; \
|
||||
info->quirks = pvr_device_quirks_##_b##_##_v##_##_n##_##_c; \
|
||||
return 0
|
||||
|
||||
switch (bvnc) {
|
||||
CASE_PACKED_BVNC_DEVICE_INFO(4, 40, 2, 51);
|
||||
}
|
||||
|
||||
#undef CASE_PACKED_BVNC_DEVICE_INFO
|
||||
|
||||
assert(!"Unsupported Device");
|
||||
|
||||
return -ENODEV;
|
||||
}
|
|
@ -0,0 +1,381 @@
|
|||
/*
|
||||
* 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)
|
||||
|
||||
/**
|
||||
* 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_ERN(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 {
|
||||
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_gpu_multicore_support : 1;
|
||||
bool has_gs_rta_support : 1;
|
||||
bool has_isp_max_tiles_in_flight : 1;
|
||||
bool has_isp_samples_per_pixel : 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_num_user_clip_planes : 1;
|
||||
bool has_paired_tiles : 1;
|
||||
bool has_pds_ddmadt : 1;
|
||||
bool has_robust_buffer_access : 1;
|
||||
bool has_roguexe : 1;
|
||||
bool has_screen_size8K : 1;
|
||||
bool has_simple_internal_parameter_format : 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_tile_size_x : 1;
|
||||
bool has_tile_size_y : 1;
|
||||
bool has_tile_size_16x16 : 1;
|
||||
bool has_tpu_array_textures : 1;
|
||||
bool has_tpu_extended_integer_lookup : 1;
|
||||
bool has_tpu_image_state_v2 : 1;
|
||||
bool has_usc_f16sop_u8 : 1;
|
||||
bool has_usc_min_output_registers_per_pix : 1;
|
||||
bool has_usc_pixel_partition_mask : 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_xpu_max_slaves : 1;
|
||||
bool has_xt_top_infrastructure : 1;
|
||||
bool has_zls_subtile : 1;
|
||||
|
||||
uint32_t common_store_size_in_dwords;
|
||||
uint32_t isp_max_tiles_in_flight;
|
||||
uint32_t isp_samples_per_pixel;
|
||||
uint32_t max_multisample;
|
||||
uint32_t max_partitions;
|
||||
uint32_t max_usc_tasks;
|
||||
uint32_t num_clusters;
|
||||
uint32_t num_raster_pipes;
|
||||
uint32_t num_user_clip_planes;
|
||||
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 usc_min_output_registers_per_pix;
|
||||
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_s8xe : 1;
|
||||
};
|
||||
|
||||
struct pvr_device_enhancements {
|
||||
bool has_ern35421 : 1;
|
||||
bool has_ern38020 : 1;
|
||||
bool has_ern38748 : 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_brn51210 : 1;
|
||||
bool has_brn51764 : 1;
|
||||
bool has_brn52354 : 1;
|
||||
bool has_brn52942 : 1;
|
||||
bool has_brn56279 : 1;
|
||||
bool has_brn58839 : 1;
|
||||
bool has_brn62269 : 1;
|
||||
bool has_brn66011 : 1;
|
||||
bool has_brn70165 : 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
#endif /* PVR_DEVICE_INFO_H */
|
|
@ -0,0 +1,934 @@
|
|||
# encoding=utf-8
|
||||
|
||||
# Copyright © 2022 Imagination Technologies Ltd.
|
||||
|
||||
# based on anv driver gen_pack_header.py which is:
|
||||
# Copyright © 2016 Intel Corporation
|
||||
|
||||
# based on v3dv driver gen_pack_header.py which is:
|
||||
# Copyright (C) 2016 Broadcom
|
||||
|
||||
# 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.
|
||||
|
||||
import argparse
|
||||
import ast
|
||||
import xml.parsers.expat
|
||||
import re
|
||||
import sys
|
||||
import copy
|
||||
import os
|
||||
import textwrap
|
||||
|
||||
license = """/*
|
||||
* 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.
|
||||
*/"""
|
||||
|
||||
pack_header = """%(license)s
|
||||
|
||||
/* Enums, structures and pack functions for %(platform)s.
|
||||
*
|
||||
* This file has been generated, do not hand edit.
|
||||
*/
|
||||
|
||||
#ifndef %(guard)s
|
||||
#define %(guard)s
|
||||
|
||||
#include "csbgen/pvr_packet_helpers.h"
|
||||
|
||||
"""
|
||||
|
||||
def safe_name(name):
|
||||
if not name[0].isalpha():
|
||||
name = '_' + name
|
||||
|
||||
return name
|
||||
|
||||
def num_from_str(num_str):
|
||||
if num_str.lower().startswith('0x'):
|
||||
return int(num_str, base=16)
|
||||
|
||||
if num_str.startswith('0') and len(num_str) > 1:
|
||||
raise ValueError('Octal numbers not allowed')
|
||||
|
||||
return int(num_str)
|
||||
|
||||
class Node:
|
||||
def __init__(self, parent, name, name_is_safe = False):
|
||||
self.parent = parent
|
||||
if name_is_safe:
|
||||
self.name = name
|
||||
else:
|
||||
self.name = safe_name(name)
|
||||
|
||||
@property
|
||||
def full_name(self):
|
||||
if self.name[0] == '_':
|
||||
return self.parent.prefix + self.name.upper()
|
||||
|
||||
return self.parent.prefix + "_" + self.name.upper()
|
||||
|
||||
@property
|
||||
def prefix(self):
|
||||
return self.parent.prefix
|
||||
|
||||
class Csbgen(Node):
|
||||
def __init__(self, name, prefix, filename):
|
||||
super().__init__(None, name.upper())
|
||||
self.prefix_field = safe_name(prefix.upper())
|
||||
self.filename = filename
|
||||
|
||||
self._defines = []
|
||||
self._enums = {}
|
||||
self._structs = {}
|
||||
|
||||
@property
|
||||
def full_name(self):
|
||||
return self.name + "_" + self.prefix_field
|
||||
|
||||
@property
|
||||
def prefix(self):
|
||||
return self.full_name
|
||||
|
||||
def add(self, element):
|
||||
if isinstance(element, Enum):
|
||||
if element.name in self._enums:
|
||||
raise RuntimeError('Enum redefined. Enum: %s' % element.name)
|
||||
|
||||
self._enums[element.name] = element
|
||||
elif isinstance(element, Struct):
|
||||
if element.name in self._structs:
|
||||
raise RuntimeError('Struct redefined. Struct: %s' % element.name)
|
||||
|
||||
self._structs[element.name] = element
|
||||
elif isinstance(element, Define):
|
||||
define_names = map(lambda d: d.full_name, self._defines)
|
||||
if element.full_name in define_names:
|
||||
raise RuntimeError('Define redefined. Define: %s' % element.full_name)
|
||||
|
||||
self._defines.append(element)
|
||||
else:
|
||||
raise RuntimeError('Element "%s" cannot be nested in csbgen.' %
|
||||
type(element).__name__)
|
||||
|
||||
def _gen_guard(self):
|
||||
return os.path.basename(self.filename).replace('.xml', '_h').upper()
|
||||
|
||||
def emit(self):
|
||||
print(pack_header % {'license': license,
|
||||
'platform': self.name,
|
||||
'guard': self._gen_guard()})
|
||||
|
||||
for define in self._defines:
|
||||
define.emit(self)
|
||||
|
||||
print()
|
||||
|
||||
for enum in self._enums.values():
|
||||
enum.emit(self)
|
||||
|
||||
for struct in self._structs.values():
|
||||
struct.emit(self)
|
||||
|
||||
print('#endif /* %s */' % self._gen_guard())
|
||||
|
||||
def is_known_struct(self, struct_name):
|
||||
return struct_name in self._structs.keys()
|
||||
|
||||
def is_known_enum(self, enum_name):
|
||||
return enum_name in self._enums.keys()
|
||||
|
||||
def get_enum(self, enum_name):
|
||||
return self._enums[enum_name]
|
||||
|
||||
class Enum(Node):
|
||||
def __init__(self, parent, name):
|
||||
super().__init__(parent, name)
|
||||
|
||||
self._values = {}
|
||||
|
||||
self.parent.add(self)
|
||||
|
||||
# We override prefix so that the values will contain the enum's name too.
|
||||
@property
|
||||
def prefix(self):
|
||||
return self.full_name
|
||||
|
||||
def get_value(self, value_name):
|
||||
return self._values[value_name]
|
||||
|
||||
def add(self, element):
|
||||
if not isinstance(element, Value):
|
||||
raise RuntimeError('Element cannot be nested in enum. ' +
|
||||
'Element Type: %s, Enum: %s' %
|
||||
(type(element).__name__, self.full_name))
|
||||
|
||||
if element.name in self._values:
|
||||
raise RuntimeError('Value is being redefined. Value: "%s"' % element.name)
|
||||
|
||||
self._values[element.name] = element
|
||||
|
||||
def emit(self, root):
|
||||
# This check is invalid if tags other than Value can be nested within an enum.
|
||||
if not self._values.values():
|
||||
raise RuntimeError('Enum definition is empty. Enum: "%s"' % self.full_name)
|
||||
|
||||
print('enum %s {' % self.full_name)
|
||||
for value in self._values.values():
|
||||
value.emit()
|
||||
print('};\n')
|
||||
|
||||
class Value(Node):
|
||||
def __init__(self, parent, name, value):
|
||||
super().__init__(parent, name)
|
||||
|
||||
self.value = int(value)
|
||||
|
||||
self.parent.add(self)
|
||||
|
||||
def emit(self):
|
||||
print(' %-36s = %6d,' % (self.full_name, self.value))
|
||||
|
||||
class Struct(Node):
|
||||
def __init__(self, parent, name, length):
|
||||
super().__init__(parent, name)
|
||||
|
||||
self.length = int(length)
|
||||
self.size = self.length * 32
|
||||
|
||||
if self.length <= 0:
|
||||
raise ValueError('Struct length must be greater than 0. ' +
|
||||
'Struct: "%s".' % self.full_name)
|
||||
|
||||
self._children = {}
|
||||
|
||||
self.parent.add(self)
|
||||
|
||||
@property
|
||||
def fields(self):
|
||||
# TODO: Should we cache? See TODO in equivalent Condition getter.
|
||||
|
||||
fields = []
|
||||
for child in self._children.values():
|
||||
if isinstance(child, Condition):
|
||||
fields += child.fields
|
||||
else:
|
||||
fields.append(child)
|
||||
|
||||
return fields
|
||||
|
||||
@property
|
||||
def prefix(self):
|
||||
return self.full_name
|
||||
|
||||
def add(self, element):
|
||||
# We don't support conditions and field having the same name.
|
||||
if isinstance(element, Field):
|
||||
if element.name in self._children.keys():
|
||||
raise ValueError('Field is being redefined. ' +
|
||||
'Field: "%s", Struct: "%s"' %
|
||||
(element.name, self.full_name))
|
||||
|
||||
self._children[element.name] = element
|
||||
|
||||
elif isinstance(element, Condition):
|
||||
# We only save ifs, and ignore the rest. The rest will be linked to
|
||||
# the if condition so we just need to call emit() on the if and the
|
||||
# rest will also be emitted.
|
||||
if element.type == 'if':
|
||||
self._children[element.name] = element
|
||||
else:
|
||||
if element.name not in self._children.keys():
|
||||
raise RuntimeError('Unknown condition: "%s"' % element.name)
|
||||
|
||||
else:
|
||||
raise RuntimeError('Element cannot be nested in struct. ' +
|
||||
'Element Type: %s, Struct: %s' %
|
||||
(type(element).__name__, self.full_name))
|
||||
|
||||
def _emit_header(self, root):
|
||||
fields = filter(lambda f: hasattr(f, 'default'), self.fields)
|
||||
|
||||
default_fields = []
|
||||
for field in fields:
|
||||
if field.is_builtin_type:
|
||||
default_fields.append(" .%-35s = %6d" %
|
||||
(field.name, field.default))
|
||||
else:
|
||||
if not root.is_known_enum(field.type):
|
||||
# Default values should not apply to structures
|
||||
raise RuntimeError('Unknown type. Field: "%s" Type: "%s"' %
|
||||
(field.name, field.type))
|
||||
|
||||
enum = root.get_enum(field.type)
|
||||
|
||||
try:
|
||||
value = enum.get_value(field.default)
|
||||
except KeyError:
|
||||
raise ValueError('Unknown enum value. ' +
|
||||
'Value: "%s", Enum: "%s", Field: "%s"' %
|
||||
(field.default, enum.full_name, field.name))
|
||||
|
||||
default_fields.append(" .%-35s = %s" %
|
||||
(field.name, value.full_name))
|
||||
|
||||
print('#define %-40s\\' % (self.full_name + '_header'))
|
||||
print(", \\\n".join(default_fields))
|
||||
print('')
|
||||
|
||||
def _emit_helper_macros(self, root):
|
||||
fields_with_defines = filter(lambda f: f.defines, self.fields)
|
||||
|
||||
for field in fields_with_defines:
|
||||
print("/* Helper macros for %s */" % (field.name))
|
||||
|
||||
for define in field.defines:
|
||||
define.emit(root)
|
||||
|
||||
print()
|
||||
|
||||
def _emit_pack_function(self, root):
|
||||
print(textwrap.dedent("""\
|
||||
static inline __attribute__((always_inline)) void
|
||||
%s_pack(__attribute__((unused)) void * restrict dst,
|
||||
%s__attribute__((unused)) const struct %s * restrict values)
|
||||
{""") % (self.full_name, ' ' * len(self.full_name), self.full_name))
|
||||
|
||||
group = Group(0, 1, self.size, self.fields)
|
||||
(dwords, length) = group.collect_dwords_and_length()
|
||||
if length:
|
||||
# Cast dst to make header C++ friendly
|
||||
print(" uint32_t * restrict dw = (uint32_t * restrict) dst;")
|
||||
|
||||
group.emit_pack_function(root, dwords, length)
|
||||
|
||||
print("}\n")
|
||||
|
||||
|
||||
def emit(self, root):
|
||||
print('#define %-33s %6d' % (self.full_name + "_length", self.length))
|
||||
|
||||
self._emit_header(root)
|
||||
|
||||
self._emit_helper_macros(root)
|
||||
|
||||
print("struct %s {" % self.full_name)
|
||||
for child in self._children.values():
|
||||
child.emit(root)
|
||||
print("};\n")
|
||||
|
||||
self._emit_pack_function(root)
|
||||
|
||||
class Field(Node):
|
||||
def __init__(self, parent, name, start, end, type, default=None, shift=None):
|
||||
super().__init__(parent, name)
|
||||
|
||||
self.start = int(start)
|
||||
self.end = int(end)
|
||||
self.type = type
|
||||
|
||||
self._defines = {}
|
||||
|
||||
self.parent.add(self)
|
||||
|
||||
if self.start > self.end:
|
||||
raise ValueError('Start cannot be after end. ' +
|
||||
'Start: %d, End: %d, Field: "%s"' %
|
||||
(self.start, self.end, self.name))
|
||||
|
||||
if self.type == 'bool' and self.end != self.start:
|
||||
raise ValueError('Bool field can only be 1 bit long. ' +
|
||||
'Field "%s"' % self.name)
|
||||
|
||||
if default is not None:
|
||||
if not self.is_builtin_type:
|
||||
# Assuming it's an enum type.
|
||||
self.default = safe_name(default)
|
||||
else:
|
||||
self.default = num_from_str(default)
|
||||
|
||||
if shift is not None:
|
||||
if self.type != 'address':
|
||||
raise RuntimeError('Only address fields can have a shift ' +
|
||||
'attribute. Field: "%s"' % self.name)
|
||||
|
||||
self.shift = int(shift)
|
||||
|
||||
Define(self, "ALIGNMENT", 2 ** self.shift)
|
||||
else:
|
||||
if self.type == 'address':
|
||||
raise RuntimeError('Field of address type ' +
|
||||
'requires a shift attribute. Field "%s"' %
|
||||
self.name)
|
||||
|
||||
@property
|
||||
def defines(self):
|
||||
return self._defines.values()
|
||||
|
||||
# We override prefix so that the defines will contain the field's name too.
|
||||
@property
|
||||
def prefix(self):
|
||||
return self.full_name
|
||||
|
||||
@property
|
||||
def is_builtin_type(self):
|
||||
builtins = {'address', 'bool', 'float', 'mbo', 'offset', 'int', 'uint'}
|
||||
return self.type in builtins
|
||||
|
||||
def _get_c_type(self, root):
|
||||
if self.type == 'address':
|
||||
return '__pvr_address_type'
|
||||
elif self.type == 'bool':
|
||||
return 'bool'
|
||||
elif self.type == 'float':
|
||||
return 'float'
|
||||
elif self.type == 'offset':
|
||||
return 'uint64_t'
|
||||
elif self.type == 'int':
|
||||
return 'int32_t'
|
||||
elif self.type == 'uint':
|
||||
if self.end - self.start < 32:
|
||||
return 'uint32_t'
|
||||
elif self.end - self.self < 64:
|
||||
return 'uint64_t'
|
||||
|
||||
raise RuntimeError('No known C type found to hold %d bit sized value. ' +
|
||||
'Field: "%s"' %
|
||||
(self.end - self.start, self.name))
|
||||
elif root.is_known_struct(self.type):
|
||||
return 'struct ' + self.type
|
||||
elif root.is_known_enum(self.type):
|
||||
return 'enum ' + root.get_enum(self.type).full_name
|
||||
raise RuntimeError('Unknown type. Type: "%s", Field: "%s"' %
|
||||
(self.type, self.name))
|
||||
|
||||
def add(self, element):
|
||||
if self.type == 'mbo':
|
||||
raise RuntimeError('No element can be nested in an mbo field. ' +
|
||||
'Element Type: %s, Field: %s' %
|
||||
(type(element).__name__, self.name))
|
||||
|
||||
if isinstance(element, Define):
|
||||
if element.name in self._defines:
|
||||
raise RuntimeError('Duplicate define. Define: "%s"' %
|
||||
element.name)
|
||||
|
||||
self._defines[element.name] = element
|
||||
else:
|
||||
raise RuntimeError('Element cannot be nested in a field. ' +
|
||||
'Element Type: %s, Field: %s' %
|
||||
(type(element).__name__, self.name))
|
||||
|
||||
def emit(self, root):
|
||||
if self.type == 'mbo':
|
||||
return
|
||||
|
||||
print(" %-36s %s;" % (self._get_c_type(root), self.name))
|
||||
|
||||
class Define(Node):
|
||||
def __init__(self, parent, name, value):
|
||||
super().__init__(parent, name)
|
||||
|
||||
self.value = value
|
||||
|
||||
self.parent.add(self)
|
||||
|
||||
def emit(self, root):
|
||||
print("#define %-40s %d" % (self.full_name, self.value))
|
||||
|
||||
class Condition(Node):
|
||||
def __init__(self, parent, name, type):
|
||||
super().__init__(parent, name, name_is_safe = True)
|
||||
|
||||
self.type = type
|
||||
if not Condition._is_valid_type(self.type):
|
||||
raise RuntimeError('Unknown type: "%s"' % self.name)
|
||||
|
||||
self._children = {}
|
||||
|
||||
# This is the link to the next branch for the if statement so either
|
||||
# elif, else, or endif. They themselves will also have a link to the
|
||||
# next branch up until endif which terminates the chain.
|
||||
self._child_branch = None
|
||||
|
||||
self.parent.add(self)
|
||||
|
||||
@property
|
||||
def fields(self):
|
||||
# TODO: Should we use some kind of state to indicate the all of the
|
||||
# child nodes have been added and then cache the fields in here on the
|
||||
# first call so that we don't have to traverse them again per each call?
|
||||
# The state could be changed wither when we reach the endif and pop from
|
||||
# the context, or when we start emitting.
|
||||
|
||||
fields = []
|
||||
|
||||
for child in self._children.values():
|
||||
if isinstance(child, Condition):
|
||||
fields += child.fields
|
||||
else:
|
||||
fields.append(child)
|
||||
|
||||
if self._child_branch is not None:
|
||||
fields += self._child_branch.fields
|
||||
|
||||
return fields
|
||||
|
||||
def _is_valid_type(type):
|
||||
types = {'if', 'elif', 'else', 'endif'}
|
||||
return type in types
|
||||
|
||||
def _is_compatible_child_branch(self, branch):
|
||||
types = ['if', 'elif', 'else', 'endif']
|
||||
idx = types.index(self.type)
|
||||
return (branch.type in types[idx + 1:] or
|
||||
self.type == 'elif' and branch.type == 'elif')
|
||||
|
||||
def _add_branch(self, branch):
|
||||
if branch.type == 'elif' and branch.name == self.name:
|
||||
raise RuntimeError('Elif branch cannot have same check as previous branch. ' +
|
||||
'Check: "%s"' % (branch.name))
|
||||
|
||||
if not self._is_compatible_child_branch(branch):
|
||||
raise RuntimeError('Invalid branch. Check: "%s", Type: "%s"' %
|
||||
(branch.name, branch.type))
|
||||
|
||||
self._child_branch = branch
|
||||
|
||||
# Returns the name of the if condition. This is used for elif branches since
|
||||
# they have a different name than the if condition thus we have to traverse
|
||||
# the chain of branches.
|
||||
# This is used to discriminate nested if conditions from branches since
|
||||
# branches like 'endif' and 'else' will have the same name as the 'if' (the
|
||||
# elif is an exception) while nested conditions will have different names.
|
||||
#
|
||||
# TODO: Redo this to improve speed? Would caching this be helpful? We could
|
||||
# just save the name of the if instead of having to walk towards it whenever
|
||||
# a new condition is being added.
|
||||
def _top_branch_name(self):
|
||||
if self.type == 'if':
|
||||
return self.name
|
||||
|
||||
return self.parent._top_branch_name()
|
||||
|
||||
def add(self, element):
|
||||
if isinstance(element, Field):
|
||||
if element.name in self._children.keys():
|
||||
raise ValueError('Duplicate field. Field: "%s"' % element.name)
|
||||
|
||||
self._children[element.name] = element
|
||||
elif isinstance(element, Condition):
|
||||
if element.type == 'elif' or self._top_branch_name() == element.name:
|
||||
self._add_branch(element)
|
||||
else:
|
||||
if element.type != 'if':
|
||||
raise RuntimeError('Branch of an unopened if condition. ' +
|
||||
'Check: "%s", Type: "%s".' % (element.name, element.type))
|
||||
|
||||
# This is a nested condition and we made sure that the name
|
||||
# doesn't match _top_branch_name() so we can recognize the else
|
||||
# and endif.
|
||||
# We recognized the elif by its type however its name differs
|
||||
# from the if condition thus when we add an if condition with
|
||||
# the same name as the elif nested in it, the _top_branch_name()
|
||||
# check doesn't hold true as the name matched the elif and not
|
||||
# the if statement which the elif was a branch of, thus the
|
||||
# nested if condition is not recognized as an invalid branch of
|
||||
# the outer if statement.
|
||||
# Sample:
|
||||
# <condition type="if" check="ROGUEXE"/>
|
||||
# <condition type="elif" check="COMPUTE"/>
|
||||
# <condition type="if" check="COMPUTE"/>
|
||||
# <condition type="endif" check="COMPUTE"/>
|
||||
# <condition type="endif" check="COMPUTE"/>
|
||||
# <condition type="endif" check="ROGUEXE"/>
|
||||
#
|
||||
# We fix this by checking the if condition name against its
|
||||
# parent.
|
||||
if element.name == self.name:
|
||||
raise RuntimeError('Invalid if condition. Check: "%s"' %
|
||||
element.name)
|
||||
|
||||
self._children[element.name] = element
|
||||
else:
|
||||
raise RuntimeError('Element cannot be nested in a condition. ' +
|
||||
'Element Type: %s, Check: %s' %
|
||||
(type(element).__name__, self.name))
|
||||
|
||||
def emit(self, root):
|
||||
if self.type == "if":
|
||||
print("/* if %s is supported use: */" % (self.name))
|
||||
elif self.type == "elif":
|
||||
print("/* else if %s is supported use: */" % (self.name))
|
||||
elif self.type == "else":
|
||||
print("/* else %s is not-supported use: */" % (self.name))
|
||||
elif self.type == "endif":
|
||||
print("/* endif %s */" % (self.name))
|
||||
return
|
||||
else:
|
||||
raise RuntimeError('Unknown condition type. Implementation error.')
|
||||
|
||||
for child in self._children.values():
|
||||
child.emit(root)
|
||||
|
||||
self._child_branch.emit(root)
|
||||
|
||||
class Group(object):
|
||||
def __init__(self, start, count, size, fields):
|
||||
self.start = start
|
||||
self.count = count
|
||||
self.size = size
|
||||
self.fields = fields
|
||||
|
||||
class DWord:
|
||||
def __init__(self):
|
||||
self.size = 32
|
||||
self.fields = []
|
||||
self.addresses = []
|
||||
|
||||
def collect_dwords(self, dwords, start, dim):
|
||||
for field in self.fields:
|
||||
index = (start + field.start) // 32
|
||||
if index not in dwords:
|
||||
dwords[index] = self.DWord()
|
||||
|
||||
clone = copy.copy(field)
|
||||
clone.start = clone.start + start
|
||||
clone.end = clone.end + start
|
||||
clone.dim = dim
|
||||
dwords[index].fields.append(clone)
|
||||
|
||||
if field.type == "address":
|
||||
# assert dwords[index].address == None
|
||||
dwords[index].addresses.append(clone)
|
||||
|
||||
# Coalesce all the dwords covered by this field. The two cases we
|
||||
# handle are where multiple fields are in a 64 bit word (typically
|
||||
# and address and a few bits) or where a single struct field
|
||||
# completely covers multiple dwords.
|
||||
while index < (start + field.end) // 32:
|
||||
if index + 1 in dwords and \
|
||||
not dwords[index] == dwords[index + 1]:
|
||||
dwords[index].fields.extend(dwords[index + 1].fields)
|
||||
dwords[index].addresses.extend(dwords[index + 1].addresses)
|
||||
dwords[index].size = 64
|
||||
dwords[index + 1] = dwords[index]
|
||||
index = index + 1
|
||||
|
||||
def collect_dwords_and_length(self):
|
||||
dwords = {}
|
||||
self.collect_dwords(dwords, 0, "")
|
||||
|
||||
# Determine number of dwords in this group. If we have a size, use
|
||||
# that, since that'll account for MBZ dwords at the end of a group
|
||||
# (like dword 8 on BDW+ 3DSTATE_HS). Otherwise, use the largest dword
|
||||
# index we've seen plus one.
|
||||
if self.size > 0:
|
||||
length = self.size // 32
|
||||
elif dwords:
|
||||
length = max(dwords.keys()) + 1
|
||||
else:
|
||||
length = 0
|
||||
|
||||
return (dwords, length)
|
||||
|
||||
def emit_pack_function(self, root, dwords, length):
|
||||
for index in range(length):
|
||||
# Handle MBZ dwords
|
||||
if index not in dwords:
|
||||
print("")
|
||||
print(" dw[%d] = 0;" % index)
|
||||
continue
|
||||
|
||||
# For 64 bit dwords, we aliased the two dword entries in the dword
|
||||
# dict it occupies. Now that we're emitting the pack function,
|
||||
# skip the duplicate entries.
|
||||
dw = dwords[index]
|
||||
if index > 0 and index - 1 in dwords and dw == dwords[index - 1]:
|
||||
continue
|
||||
|
||||
# Special case: only one field and it's a struct at the beginning
|
||||
# of the dword. In this case we pack directly into the
|
||||
# destination. This is the only way we handle embedded structs
|
||||
# larger than 32 bits.
|
||||
if len(dw.fields) == 1:
|
||||
field = dw.fields[0]
|
||||
name = field.name + field.dim
|
||||
if root.is_known_struct(field.type) and field.start % 32 == 0:
|
||||
print("")
|
||||
print(" %s_pack(data, &dw[%d], &values->%s);" %
|
||||
(self.parser.gen_prefix(safe_name(field.type)),
|
||||
index, name))
|
||||
continue
|
||||
|
||||
# Pack any fields of struct type first so we have integer values
|
||||
# to the dword for those fields.
|
||||
field_index = 0
|
||||
for field in dw.fields:
|
||||
if isinstance(field, Field) and root.is_known_struct(field.type):
|
||||
name = field.name + field.dim
|
||||
print("")
|
||||
print(" uint32_t v%d_%d;" % (index, field_index))
|
||||
print(" %s_pack(data, &v%d_%d, &values->%s);" %
|
||||
(self.parser.gen_prefix(safe_name(field.type)),
|
||||
index, field_index, name))
|
||||
field_index = field_index + 1
|
||||
|
||||
print("")
|
||||
dword_start = index * 32
|
||||
address_count = len(dw.addresses);
|
||||
|
||||
if dw.size == 32 and not dw.addresses:
|
||||
v = None
|
||||
print(" dw[%d] =" % index)
|
||||
elif len(dw.fields) > address_count:
|
||||
v = "v%d" % index
|
||||
print(" const uint%d_t %s =" % (dw.size, v))
|
||||
else:
|
||||
v = "0"
|
||||
|
||||
field_index = 0
|
||||
non_address_fields = []
|
||||
for field in dw.fields:
|
||||
if field.type != "mbo":
|
||||
name = field.name + field.dim
|
||||
|
||||
if field.type == "mbo":
|
||||
non_address_fields.append("__pvr_mbo(%d, %d)" %
|
||||
(field.start - dword_start,
|
||||
field.end - dword_start))
|
||||
elif field.type == "address":
|
||||
pass
|
||||
elif field.type == "uint":
|
||||
non_address_fields.append("__pvr_uint(values->%s, %d, %d)" %
|
||||
(name, field.start - dword_start,
|
||||
field.end - dword_start))
|
||||
elif root.is_known_enum(field.type):
|
||||
non_address_fields.append("__pvr_uint(values->%s, %d, %d)" %
|
||||
(name, field.start - dword_start,
|
||||
field.end - dword_start))
|
||||
elif field.type == "int":
|
||||
non_address_fields.append("__pvr_sint(values->%s, %d, %d)" %
|
||||
(name, field.start - dword_start,
|
||||
field.end - dword_start))
|
||||
elif field.type == "bool":
|
||||
non_address_fields.append("__pvr_uint(values->%s, %d, %d)" %
|
||||
(name, field.start - dword_start,
|
||||
field.end - dword_start))
|
||||
elif field.type == "float":
|
||||
non_address_fields.append("__pvr_float(values->%s)" % name)
|
||||
elif field.type == "offset":
|
||||
non_address_fields.append(
|
||||
"__pvr_offset(values->%s,"" %d, %d)" %
|
||||
(name, field.start - dword_start,
|
||||
field.end - dword_start))
|
||||
elif field.is_struct_type():
|
||||
non_address_fields.append("__pvr_uint(v%d_%d, %d, %d)" %
|
||||
(index, field_index,
|
||||
field.start - dword_start,
|
||||
field.end - dword_start))
|
||||
field_index = field_index + 1
|
||||
else:
|
||||
non_address_fields.append("/* unhandled field %s,"
|
||||
" type %s */\n" %
|
||||
(name, field.type))
|
||||
|
||||
if non_address_fields:
|
||||
print(" |\n".join(" " + f for f in non_address_fields) +
|
||||
";")
|
||||
|
||||
if dw.size == 32:
|
||||
for i in range(address_count):
|
||||
print(" dw[%d] = __pvr_address("
|
||||
"values->%s, %d, %d, %d) | %s;" %
|
||||
(index, dw.addresses[i].name + field.dim,
|
||||
dw.addresses[i].shift, dw.addresses[i].start - dword_start,
|
||||
dw.addresses[i].end - dword_start, v))
|
||||
continue
|
||||
|
||||
v_accumulated_addr = ""
|
||||
for i in range(address_count):
|
||||
v_address = "v%d_address" % i
|
||||
v_accumulated_addr += "v%d_address" % i
|
||||
print(" const uint64_t %s =\n "
|
||||
" __pvr_address(values->%s, %d, %d, %d);" %
|
||||
(v_address, dw.addresses[i].name + field.dim, dw.addresses[i].shift,
|
||||
dw.addresses[i].start - dword_start,
|
||||
dw.addresses[i].end - dword_start))
|
||||
if i < (address_count - 1):
|
||||
v_accumulated_addr += " |\n "
|
||||
|
||||
if dw.addresses:
|
||||
if len(dw.fields) > address_count:
|
||||
print(" dw[%d] = %s | %s;" % (index, v_accumulated_addr, v))
|
||||
print(" dw[%d] = (%s >> 32) | (%s >> 32);" %
|
||||
(index + 1, v_accumulated_addr, v))
|
||||
continue
|
||||
else:
|
||||
v = v_accumulated_addr
|
||||
|
||||
print(" dw[%d] = %s;" % (index, v))
|
||||
print(" dw[%d] = %s >> 32;" % (index + 1, v))
|
||||
|
||||
class Parser(object):
|
||||
def __init__(self):
|
||||
self.parser = xml.parsers.expat.ParserCreate()
|
||||
self.parser.StartElementHandler = self.start_element
|
||||
self.parser.EndElementHandler = self.end_element
|
||||
|
||||
self.context = []
|
||||
|
||||
def start_element(self, name, attrs):
|
||||
if not name == "csbgen":
|
||||
parent = self.context[-1]
|
||||
|
||||
if name == "csbgen":
|
||||
if self.context:
|
||||
raise RuntimeError('Can only have 1 csbgen block and it has ' +
|
||||
'to contain all of the other elements.')
|
||||
|
||||
csbgen = Csbgen(attrs["name"], attrs["prefix"], self.filename)
|
||||
self.context.append(csbgen)
|
||||
|
||||
elif name == "struct":
|
||||
struct = Struct(parent , attrs["name"], attrs["length"])
|
||||
self.context.append(struct)
|
||||
|
||||
elif name == "field":
|
||||
default = None
|
||||
if "default" in attrs.keys():
|
||||
default = attrs["default"]
|
||||
|
||||
shift = None
|
||||
if "shift" in attrs.keys():
|
||||
shift = attrs["shift"]
|
||||
|
||||
field = Field(parent,
|
||||
name = attrs["name"],
|
||||
start = int(attrs["start"]),
|
||||
end = int(attrs["end"]),
|
||||
type = attrs["type"],
|
||||
default = default,
|
||||
shift = shift)
|
||||
self.context.append(field)
|
||||
|
||||
elif name == "enum":
|
||||
enum = Enum(parent, attrs["name"])
|
||||
self.context.append(enum)
|
||||
|
||||
elif name == "value":
|
||||
value = Value(parent, attrs["name"], ast.literal_eval(attrs["value"]))
|
||||
self.context.append(value)
|
||||
|
||||
elif name == "define":
|
||||
define = Define(parent, attrs["name"], ast.literal_eval(attrs["value"]))
|
||||
self.context.append(define)
|
||||
|
||||
elif name == "condition":
|
||||
condition = Condition(parent, name=attrs["check"], type=attrs["type"])
|
||||
|
||||
# Starting with the if statement we push it in the context. For each
|
||||
# branch following (elif, and else) we assign the top of stack as
|
||||
# its parent, pop() and push the new condition. So per branch we end
|
||||
# up having [..., struct, condition]. We don't push an endif since
|
||||
# it's not supposed to have any children and it's supposed to close
|
||||
# the whole if statement.
|
||||
|
||||
if condition.type != 'if':
|
||||
# Remove the parent condition from the context. We were peeking
|
||||
# before, now we pop().
|
||||
self.context.pop()
|
||||
|
||||
if condition.type == 'endif':
|
||||
if not isinstance(parent, Condition):
|
||||
raise RuntimeError('Cannot close unopened or already ' +
|
||||
'closed condition. Condition: "%s"' % condition.name)
|
||||
else:
|
||||
self.context.append(condition)
|
||||
|
||||
else:
|
||||
raise RuntimeError('Unknown tag: "%s"' % name)
|
||||
|
||||
def end_element(self, name):
|
||||
if name == 'condition':
|
||||
element = self.context[-1]
|
||||
if not isinstance(element, Condition) and not isinstance(element, Struct):
|
||||
raise RuntimeError("Expected condition or struct tag to be closed.")
|
||||
|
||||
return
|
||||
|
||||
element = self.context.pop()
|
||||
|
||||
if name == "struct":
|
||||
if not isinstance(element, Struct):
|
||||
raise RuntimeError("Expected struct tag to be closed.")
|
||||
elif name == "field":
|
||||
if not isinstance(element, Field):
|
||||
raise RuntimeError("Expected field tag to be closed.")
|
||||
elif name == "enum":
|
||||
if not isinstance(element, Enum):
|
||||
raise RuntimeError("Expected enum tag to be closed.")
|
||||
elif name == "value":
|
||||
if not isinstance(element, Value):
|
||||
raise RuntimeError("Expected value tag to be closed.")
|
||||
elif name == "define":
|
||||
if not isinstance(element, Define):
|
||||
raise RuntimeError("Expected define tag to be closed.")
|
||||
elif name == "csbgen":
|
||||
if not isinstance(element, Csbgen):
|
||||
raise RuntimeError("""Expected csbgen tag to be closed.
|
||||
Some tags may have not been closed""")
|
||||
|
||||
element.emit()
|
||||
else:
|
||||
raise RuntimeError('Unknown closing element: "%s"' % name)
|
||||
|
||||
def parse(self, filename):
|
||||
file = open(filename, "rb")
|
||||
self.filename = filename
|
||||
self.parser.ParseFile(file)
|
||||
file.close()
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print("No input xml file specified")
|
||||
sys.exit(1)
|
||||
|
||||
input_file = sys.argv[1]
|
||||
|
||||
p = Parser()
|
||||
p.parse(input_file)
|
|
@ -0,0 +1,46 @@
|
|||
# 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.
|
||||
|
||||
pvr_xml_files = [
|
||||
'rogue_cdm.xml',
|
||||
'rogue_cr.xml',
|
||||
'rogue_ipf.xml',
|
||||
'rogue_lls.xml',
|
||||
'rogue_pbestate.xml',
|
||||
'rogue_pds.xml',
|
||||
'rogue_ppp.xml',
|
||||
'rogue_texstate.xml',
|
||||
'rogue_vdm.xml',
|
||||
]
|
||||
|
||||
pvr_xml_pack = []
|
||||
foreach f : pvr_xml_files
|
||||
_name = '@0@.h'.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
|
||||
|
||||
dep_csbgen = declare_dependency(sources : [pvr_xml_pack])
|
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* 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 <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
|
||||
|
||||
union __pvr_value {
|
||||
float f;
|
||||
uint32_t dw;
|
||||
};
|
||||
|
||||
static inline __attribute__((always_inline)) uint64_t __pvr_mbo(uint32_t start,
|
||||
uint32_t end)
|
||||
{
|
||||
return (~0ull >> (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 = (1ull << width) - 1;
|
||||
assert(v <= max);
|
||||
}
|
||||
#endif
|
||||
|
||||
return v << start;
|
||||
}
|
||||
|
||||
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 = ~0ull >> (64 - width);
|
||||
|
||||
return (v & mask) << start;
|
||||
}
|
||||
|
||||
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 = (~0ull >> (64 - (end - start + 1))) << start;
|
||||
|
||||
assert((v & ~mask) == 0);
|
||||
#endif
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
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 = (~0ull >> (64 - (end - start + 1))) << start;
|
||||
|
||||
return ((addr_u64 >> shift) << start) & mask;
|
||||
}
|
||||
|
||||
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)) 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 = ~0ull >> (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,132 @@
|
|||
<?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">
|
||||
|
||||
<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,631 @@
|
|||
<?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="1"/>
|
||||
<value name="FAST_SCALE" value="2"/>
|
||||
</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="ZLOADFORMAT_TYPE">
|
||||
<value name="F32Z" value="0"/>
|
||||
<value name="24BITINT" value="1"/>
|
||||
<value name="16BITINT" value="2"/>
|
||||
<value name="F64Z" value="3"/>
|
||||
</enum>
|
||||
|
||||
<enum name="ZSTOREFORMAT_TYPE">
|
||||
<value name="F32Z" value="0"/>
|
||||
<value name="24BITINT" value="1"/>
|
||||
<value name="16BITINT" value="2"/>
|
||||
<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="PDS_CTRL" length="2">
|
||||
<field name="sm_overlap_enable" start="55" end="55" type="bool"/>
|
||||
<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="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_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_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"/>
|
||||
</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"/>
|
||||
</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="ZSTOREFORMAT_TYPE"/>
|
||||
<field name="zloadformat" start="23" end="24" type="ZLOADFORMAT_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_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"/>
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
</csbgen>
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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 ROGUE_HWDEFS_H
|
||||
#define ROGUE_HWDEFS_H
|
||||
|
||||
#include "rogue_cdm.h"
|
||||
#include "rogue_cr.h"
|
||||
#include "rogue_ipf.h"
|
||||
#include "rogue_lls.h"
|
||||
#include "rogue_pbestate.h"
|
||||
#include "rogue_pds.h"
|
||||
#include "rogue_ppp.h"
|
||||
#include "rogue_texstate.h"
|
||||
#include "rogue_vdm.h"
|
||||
|
||||
#endif /* ROGUE_HWDEFS_H */
|
|
@ -0,0 +1,40 @@
|
|||
<?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"/>
|
||||
|
||||
<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>
|
||||
|
||||
</csbgen>
|
|
@ -0,0 +1,49 @@
|
|||
<?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,300 @@
|
|||
<?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="REG_WORD0_LINESTRIDE">
|
||||
<value name="ALIGNSHIFT" value="1"/>
|
||||
<value name="ALIGNSIZE" value="2"/>
|
||||
<value name="ALIGNSHIFT_PBE_STRIDE_ALIGN_1PIXEL_ENABLED" value="0"/>
|
||||
<value name="ALIGNSIZE_PBE_STRIDE_ALIGN_1PIXEL_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,116 @@
|
|||
<?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="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="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,329 @@
|
|||
<?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"/>
|
||||
</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>
|
||||
|
||||
<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="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">
|
||||
<condition type="if" check="TEXTURE_WRAP_VARYING"/>
|
||||
<field name="f32_linear_wrap" start="24" end="31" type="uint"/>
|
||||
<condition type="endif" check="TEXTURE_WRAP_VARYING"/>
|
||||
<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"/>
|
||||
<condition type="if" check="TEXTURE_WRAP_VARYING"/>
|
||||
<field name="f32_npc_wrap" start="0" end=" 7" type="uint"/>
|
||||
<condition type="endif" check="TEXTURE_WRAP_VARYING"/>
|
||||
</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_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="trp" start="16" end="16" type="bool"/>
|
||||
<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,334 @@
|
|||
<?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="COMPRESSED_ASTC_4x4" value="0"/>
|
||||
<value name="COMPRESSED_ASTC_5x4" value="1"/>
|
||||
<value name="COMPRESSED_ASTC_5x5" value="2"/>
|
||||
<value name="COMPRESSED_ASTC_6x5" value="3"/>
|
||||
<value name="COMPRESSED_ASTC_6x6" value="4"/>
|
||||
<value name="COMPRESSED_ASTC_8x5" value="5"/>
|
||||
<value name="COMPRESSED_ASTC_8x6" value="6"/>
|
||||
<value name="COMPRESSED_ASTC_8x8" value="7"/>
|
||||
<value name="COMPRESSED_ASTC_10x5" value="8"/>
|
||||
<value name="COMPRESSED_ASTC_10x6" value="9"/>
|
||||
<value name="COMPRESSED_ASTC_10x8" value="10"/>
|
||||
<value name="COMPRESSED_ASTC_10x10" value="11"/>
|
||||
<value name="COMPRESSED_ASTC_12x10" value="12"/>
|
||||
<value name="COMPRESSED_ASTC_12x12" value="13"/>
|
||||
<value name="COMPRESSED_PVRT2BPP" value="40"/>
|
||||
<value name="COMPRESSED_PVRT4BPP" value="41"/>
|
||||
<value name="COMPRESSED_PVRTII2BPP" value="42"/>
|
||||
<value name="COMPRESSED_PVRTII4BPP" value="43"/>
|
||||
<value name="COMPRESSED_UBC1" value="44"/>
|
||||
<value name="COMPRESSED_UBC2" value="45"/>
|
||||
<value name="COMPRESSED_UBC3" value="46"/>
|
||||
<value name="COMPRESSED_UBC4" value="47"/>
|
||||
<value name="COMPRESSED_SBC4" value="48"/>
|
||||
<value name="COMPRESSED_UBC5" value="49"/>
|
||||
<value name="COMPRESSED_SBC5" value="50"/>
|
||||
<value name="COMPRESSED_UBC6" value="51"/>
|
||||
<value name="COMPRESSED_SBC6" value="52"/>
|
||||
<value name="COMPRESSED_UBC7" value="53"/>
|
||||
<value name="COMPRESSED_ETC2_RGB" value="68"/>
|
||||
<value name="COMPRESSED_ETC2A_RGBA" value="69"/>
|
||||
<value name="COMPRESSED_ETC2_PUNCHTHROUGHA" value="70"/>
|
||||
<value name="COMPRESSED_EAC_R11_UNSIGNED" value="71"/>
|
||||
<value name="COMPRESSED_EAC_R11_SIGNED" value="72"/>
|
||||
<value name="COMPRESSED_EAC_RG11_UNSIGNED" value="73"/>
|
||||
<value name="COMPRESSED_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>
|
||||
|
||||
<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"/>
|
||||
<field name="texformat" start="27" end="33" type="FORMAT"/>
|
||||
<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"/>
|
||||
<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="SAMPLER" 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"/>
|
||||
<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>
|
||||
|
||||
</csbgen>
|
|
@ -0,0 +1,256 @@
|
|||
<?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">
|
||||
|
||||
<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,127 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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_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
|
||||
|
||||
#define ROGUE_MAX_RENDER_TARGETS 2048U
|
||||
|
||||
/* 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_USC_TASK_PROGRAM_SIZE 512U
|
||||
|
||||
#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
|
||||
|
||||
#endif /* ROGUE_HW_DEFS_H */
|
|
@ -0,0 +1,379 @@
|
|||
/*
|
||||
* 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_winsys.h"
|
||||
|
||||
#define __pvr_address_type pvr_dev_addr_t
|
||||
#define __pvr_get_address(pvr_dev_addr) (pvr_dev_addr).addr
|
||||
|
||||
#include "csbgen/rogue_cdm.h"
|
||||
#include "csbgen/rogue_lls.h"
|
||||
|
||||
#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"
|
||||
|
||||
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) {
|
||||
default:
|
||||
assert(!"Unsupported number of samples");
|
||||
FALLTHROUGH;
|
||||
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 == 2)
|
||||
*y_out *= 2;
|
||||
|
||||
break;
|
||||
case 8:
|
||||
*y_out *= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
rogue_get_min_free_list_size(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
uint64_t min_num_pages;
|
||||
|
||||
if (PVR_HAS_FEATURE(dev_info, roguexe)) {
|
||||
if (PVR_HAS_QUIRK(dev_info, 66011))
|
||||
min_num_pages = 40U;
|
||||
else
|
||||
min_num_pages = 25U;
|
||||
} else {
|
||||
min_num_pages = 50U;
|
||||
}
|
||||
|
||||
return min_num_pages << ROGUE_BIF_PM_PHYSICAL_PAGE_SHIFT;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_get_max_num_vdm_pds_tasks(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
/* Default value based on the minimum value found in all existing cores. */
|
||||
uint32_t max_usc_tasks = PVR_GET_FEATURE_VALUE(dev_info, max_usc_tasks, 24U);
|
||||
|
||||
/* FIXME: Where does the 9 come from? */
|
||||
return max_usc_tasks - 9;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* To get the number of required Bernado/Phantom(s), divide the number of
|
||||
* clusters by 4 and round up.
|
||||
*/
|
||||
static inline uint32_t
|
||||
rogue_get_num_phantoms(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
return DIV_ROUND_UP(PVR_GET_FEATURE_VALUE(dev_info, num_clusters, 1U), 4U);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Return the total reserved size of partition in dwords. */
|
||||
static inline uint32_t
|
||||
rogue_get_total_reserved_partition_size(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
uint32_t tile_size_x = PVR_GET_FEATURE_VALUE(dev_info, tile_size_x, 0);
|
||||
uint32_t tile_size_y = PVR_GET_FEATURE_VALUE(dev_info, tile_size_y, 0);
|
||||
uint32_t max_partitions = PVR_GET_FEATURE_VALUE(dev_info, max_partitions, 0);
|
||||
|
||||
if (tile_size_x == 16 && tile_size_y == 16) {
|
||||
return tile_size_x * tile_size_y * max_partitions *
|
||||
PVR_GET_FEATURE_VALUE(dev_info,
|
||||
usc_min_output_registers_per_pix,
|
||||
0);
|
||||
}
|
||||
|
||||
return max_partitions * 1024U;
|
||||
}
|
||||
|
||||
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_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)
|
||||
{
|
||||
const uint32_t uvs_pba_entries =
|
||||
PVR_GET_FEATURE_VALUE(dev_info, uvs_pba_entries, 0U);
|
||||
const uint32_t uvs_banks = PVR_GET_FEATURE_VALUE(dev_info, uvs_banks, 0U);
|
||||
|
||||
if (uvs_banks <= 8U && uvs_pba_entries == 160U)
|
||||
return 64U;
|
||||
|
||||
return 128U;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_get_reserved_shared_size(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
uint32_t common_store_size_in_dwords =
|
||||
PVR_GET_FEATURE_VALUE(dev_info,
|
||||
common_store_size_in_dwords,
|
||||
512U * 4U * 4U);
|
||||
uint32_t reserved_shared_size =
|
||||
common_store_size_in_dwords - (256U * 4U) -
|
||||
rogue_get_total_reserved_partition_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), reserved_shared_size);
|
||||
}
|
||||
|
||||
return reserved_shared_size;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_max_compute_shared_registers(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
if (PVR_HAS_FEATURE(dev_info, compute))
|
||||
return 2U * 1024U;
|
||||
|
||||
return 0U;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_get_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_get_num_phantoms(dev_info);
|
||||
uint32_t tiles_in_flight =
|
||||
PVR_GET_FEATURE_VALUE(dev_info, isp_max_tiles_in_flight, 0);
|
||||
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_ERN(dev_info, 38748))
|
||||
pending_allocation_shared_regs = 0U;
|
||||
|
||||
if (PVR_HAS_ERN(dev_info, 38020)) {
|
||||
max_coeff_additional_portion +=
|
||||
rogue_max_compute_shared_registers(dev_info);
|
||||
}
|
||||
|
||||
return rogue_get_reserved_shared_size(dev_info) +
|
||||
pending_allocation_coeff_regs -
|
||||
(max_coeff_pixel_portion + max_coeff_additional_portion +
|
||||
pending_allocation_shared_regs);
|
||||
}
|
||||
|
||||
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 =
|
||||
PVR_GET_FEATURE_VALUE(dev_info, xpu_max_slaves, 0U) + 1U;
|
||||
const uint32_t cache_line_size = rogue_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);
|
||||
|
||||
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 rogue_get_slc_cache_line_size(dev_info);
|
||||
|
||||
return ROGUE_LLS_CDM_CONTEXT_RESUME_BUFFER_ALIGNMENT;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rogue_get_cdm_max_local_mem_size_regs(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
uint32_t available_coeffs_in_dwords = rogue_get_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 * 2;
|
||||
}
|
||||
|
||||
/* 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 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_ERN(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;
|
||||
}
|
||||
|
||||
#endif /* ROGUE_HW_UTILS_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.
|
||||
*/
|
||||
|
||||
/* 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
|
||||
|
||||
/**
|
||||
* Maximum PB free list size supported by RGX and Services.
|
||||
*
|
||||
* Maximum PB free list size must ensure that no PM address space can be fully
|
||||
* used, because if the full address space was used it would wrap and corrupt
|
||||
* itself. Since there are two freelists (local is always minimum sized) this
|
||||
* can be described as following three conditions being met:
|
||||
*
|
||||
* Minimum PB + Maximum PB < ALIST PM address space size (16GB)
|
||||
* Minimum PB + Maximum PB < TE PM address space size (16GB) / NUM_TE_PIPES
|
||||
* Minimum PB + Maximum PB < VCE PM address space size (16GB) / NUM_VCE_PIPES
|
||||
*
|
||||
* Since the max of NUM_TE_PIPES and NUM_VCE_PIPES is 4, we have a hard limit
|
||||
* of 4GB minus the Minimum PB. For convenience we take the smaller power-of-2
|
||||
* value of 2GB. This is far more than any normal application would request
|
||||
* or use.
|
||||
*/
|
||||
#define ROGUE_FREE_LIST_MAX_SIZE (2ULL * 1024ULL * 1024ULL * 1024ULL)
|
||||
|
||||
/* 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,33 @@
|
|||
# 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.
|
||||
|
||||
inc_imagination = include_directories([
|
||||
'.',
|
||||
'common',
|
||||
'include',
|
||||
])
|
||||
|
||||
if with_imagination_vk
|
||||
subdir('common')
|
||||
subdir('csbgen')
|
||||
subdir('rogue')
|
||||
subdir('vulkan')
|
||||
endif
|
|
@ -0,0 +1,77 @@
|
|||
# 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.
|
||||
|
||||
libpowervr_rogue_files = files(
|
||||
'nir/rogue_nir_constreg.c',
|
||||
'nir/rogue_nir_lower_io.c',
|
||||
'nir/rogue_nir_pfo.c',
|
||||
|
||||
'rogue.c',
|
||||
'rogue_build_data.c',
|
||||
'rogue_compiler.c',
|
||||
'rogue_constreg.c',
|
||||
'rogue_dump.c',
|
||||
'rogue_encode.c',
|
||||
'rogue_encoders.c',
|
||||
'rogue_instr.c',
|
||||
'rogue_nir.c',
|
||||
'rogue_operand.c',
|
||||
'rogue_regalloc.c',
|
||||
'rogue_shader.c',
|
||||
'rogue_util.c',
|
||||
'rogue_validate.c',
|
||||
)
|
||||
|
||||
libpowervr_rogue = shared_library(
|
||||
'powervr_rogue',
|
||||
libpowervr_rogue_files,
|
||||
include_directories : [
|
||||
inc_imagination,
|
||||
inc_include,
|
||||
inc_compiler,
|
||||
inc_src,
|
||||
inc_mapi,
|
||||
inc_mesa,
|
||||
inc_gallium,
|
||||
inc_gallium_aux,
|
||||
],
|
||||
c_args : [c_msvc_compat_args, no_override_init_args],
|
||||
gnu_symbol_visibility : 'hidden',
|
||||
dependencies : [idep_mesautil, idep_nir, dep_csbgen],
|
||||
install : true,
|
||||
)
|
||||
|
||||
rogue_compiler = executable(
|
||||
'rogue_compiler',
|
||||
'tools/offline_compiler.c',
|
||||
link_with : [libpowervr_rogue],
|
||||
dependencies : [idep_mesautil, idep_nir],
|
||||
include_directories : [
|
||||
inc_mesa,
|
||||
inc_include,
|
||||
inc_src,
|
||||
inc_mapi,
|
||||
inc_gallium,
|
||||
inc_gallium_aux,
|
||||
inc_compiler,
|
||||
],
|
||||
install : false,
|
||||
)
|
|
@ -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 "nir/nir.h"
|
||||
#include "nir/nir_builder.h"
|
||||
#include "nir/nir_search_helpers.h"
|
||||
#include "rogue_constreg.h"
|
||||
#include "rogue_nir.h"
|
||||
|
||||
/* TODO: optimize: if value is in const regs, replace, else, use shared regs and
|
||||
* notify driver they need to be populated?
|
||||
*/
|
||||
|
||||
/* Replaces multiple ssa uses from load_const with a single use -> a register.
|
||||
*/
|
||||
void rogue_nir_constreg(nir_shader *shader)
|
||||
{
|
||||
nir_function_impl *impl = nir_shader_get_entrypoint(shader);
|
||||
nir_builder b;
|
||||
|
||||
nir_builder_init(&b, impl);
|
||||
|
||||
/* Find load_const instructions. */
|
||||
nir_foreach_block (block, impl) {
|
||||
nir_foreach_instr_safe (instr, block) {
|
||||
if (instr->type != nir_instr_type_load_const)
|
||||
continue;
|
||||
|
||||
nir_load_const_instr *load_const = nir_instr_as_load_const(instr);
|
||||
|
||||
/* Skip values that can be pulled from constant registers. */
|
||||
uint32_t value = nir_const_value_as_uint(load_const->value[0], 32);
|
||||
size_t const_reg = rogue_constreg_lookup(value);
|
||||
if (const_reg != ROGUE_NO_CONST_REG)
|
||||
continue;
|
||||
|
||||
b.cursor = nir_after_instr(&load_const->instr);
|
||||
nir_ssa_def *mov = nir_mov(&b, &load_const->def);
|
||||
|
||||
nir_foreach_use_safe (use_src, &load_const->def) {
|
||||
if (use_src->parent_instr == mov->parent_instr)
|
||||
continue;
|
||||
|
||||
/* Skip when used as an index for intrinsics, as we want to
|
||||
* access that value directly.
|
||||
*/
|
||||
if (use_src->parent_instr->type == nir_instr_type_intrinsic)
|
||||
continue;
|
||||
|
||||
nir_instr_rewrite_src_ssa(use_src->parent_instr, use_src, mov);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "nir/nir.h"
|
||||
#include "nir/nir_builder.h"
|
||||
#include "nir/nir_search_helpers.h"
|
||||
#include "rogue_nir.h"
|
||||
#include "rogue_nir_helpers.h"
|
||||
|
||||
static void lower_vulkan_resource_index(nir_builder *b,
|
||||
nir_intrinsic_instr *intr,
|
||||
void *pipeline_layout)
|
||||
{
|
||||
unsigned desc_set = nir_intrinsic_desc_set(intr);
|
||||
unsigned binding = nir_intrinsic_binding(intr);
|
||||
|
||||
nir_ssa_def *def = nir_vec3(b,
|
||||
nir_imm_int(b, desc_set),
|
||||
nir_imm_int(b, binding),
|
||||
nir_imm_int(b, 0));
|
||||
nir_ssa_def_rewrite_uses(&intr->dest.ssa, def);
|
||||
nir_instr_remove(&intr->instr);
|
||||
}
|
||||
|
||||
static void lower_load_vulkan_descriptor(nir_builder *b,
|
||||
nir_intrinsic_instr *intr)
|
||||
{
|
||||
/* Loading the descriptor happens as part of the load/store instruction so
|
||||
* this is a no-op.
|
||||
*/
|
||||
|
||||
nir_ssa_def_rewrite_uses(&intr->dest.ssa, intr->src[0].ssa);
|
||||
nir_instr_remove(&intr->instr);
|
||||
}
|
||||
|
||||
static void lower_load_ubo_to_scalar(nir_builder *b, nir_intrinsic_instr *intr)
|
||||
{
|
||||
/* Scalarize the load_ubo. */
|
||||
b->cursor = nir_before_instr(&intr->instr);
|
||||
|
||||
assert(intr->dest.is_ssa);
|
||||
assert(intr->num_components > 1);
|
||||
|
||||
nir_ssa_def *loads[NIR_MAX_VEC_COMPONENTS];
|
||||
|
||||
for (uint8_t i = 0; i < intr->num_components; i++) {
|
||||
size_t scaled_range = nir_intrinsic_range(intr) / intr->num_components;
|
||||
nir_intrinsic_instr *chan_intr =
|
||||
nir_intrinsic_instr_create(b->shader, intr->intrinsic);
|
||||
nir_ssa_dest_init(&chan_intr->instr,
|
||||
&chan_intr->dest,
|
||||
1,
|
||||
intr->dest.ssa.bit_size,
|
||||
NULL);
|
||||
chan_intr->num_components = 1;
|
||||
|
||||
nir_intrinsic_set_access(chan_intr, nir_intrinsic_access(intr));
|
||||
nir_intrinsic_set_align_mul(chan_intr, nir_intrinsic_align_mul(intr));
|
||||
nir_intrinsic_set_align_offset(chan_intr,
|
||||
nir_intrinsic_align_offset(intr));
|
||||
nir_intrinsic_set_range_base(chan_intr,
|
||||
nir_intrinsic_range_base(intr) +
|
||||
(i * intr->num_components));
|
||||
nir_intrinsic_set_range(chan_intr, scaled_range);
|
||||
|
||||
/* Base (desc_set, binding). */
|
||||
nir_src_copy(&chan_intr->src[0], &intr->src[0]);
|
||||
|
||||
/* Offset (unused). */
|
||||
chan_intr->src[1] = nir_src_for_ssa(nir_imm_int(b, 0));
|
||||
|
||||
nir_builder_instr_insert(b, &chan_intr->instr);
|
||||
|
||||
loads[i] = &chan_intr->dest.ssa;
|
||||
}
|
||||
|
||||
nir_ssa_def_rewrite_uses(&intr->dest.ssa,
|
||||
nir_vec(b, loads, intr->num_components));
|
||||
nir_instr_remove(&intr->instr);
|
||||
}
|
||||
|
||||
static bool
|
||||
lower_intrinsic(nir_builder *b, nir_intrinsic_instr *instr, void *layout)
|
||||
{
|
||||
switch (instr->intrinsic) {
|
||||
case nir_intrinsic_load_vulkan_descriptor:
|
||||
lower_load_vulkan_descriptor(b, instr);
|
||||
return true;
|
||||
|
||||
case nir_intrinsic_vulkan_resource_index:
|
||||
lower_vulkan_resource_index(b, instr, layout);
|
||||
return true;
|
||||
|
||||
case nir_intrinsic_load_ubo:
|
||||
lower_load_ubo_to_scalar(b, instr);
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool lower_impl(nir_function_impl *impl, void *layout)
|
||||
{
|
||||
bool progress = false;
|
||||
nir_builder b;
|
||||
|
||||
nir_builder_init(&b, impl);
|
||||
|
||||
nir_foreach_block (block, impl) {
|
||||
nir_foreach_instr_safe (instr, block) {
|
||||
b.cursor = nir_before_instr(instr);
|
||||
switch (instr->type) {
|
||||
case nir_instr_type_intrinsic:
|
||||
progress |=
|
||||
lower_intrinsic(&b, nir_instr_as_intrinsic(instr), layout);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (progress)
|
||||
nir_metadata_preserve(impl, nir_metadata_none);
|
||||
else
|
||||
nir_metadata_preserve(impl, nir_metadata_all);
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
bool rogue_nir_lower_io(nir_shader *shader, void *layout)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
nir_foreach_function (function, shader) {
|
||||
if (function->impl)
|
||||
progress |= lower_impl(function->impl, layout);
|
||||
}
|
||||
|
||||
if (progress)
|
||||
nir_opt_dce(shader);
|
||||
|
||||
return progress;
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* 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 "nir/nir.h"
|
||||
#include "nir/nir_builder.h"
|
||||
#include "nir/nir_search_helpers.h"
|
||||
#include "rogue_nir.h"
|
||||
|
||||
static void insert_pfo(nir_builder *b,
|
||||
nir_intrinsic_instr *store_output,
|
||||
nir_src *output_src)
|
||||
{
|
||||
/* TODO: Support complex PFO with blending. */
|
||||
/* TODO: Verify type is vec4. */
|
||||
|
||||
/* Pack the output color components into U8888 format. */
|
||||
nir_ssa_def *new_output_src_ssa = nir_pack_unorm_4x8(b, output_src->ssa);
|
||||
nir_src new_output_src = nir_src_for_ssa(new_output_src_ssa);
|
||||
|
||||
/* Update the store_output intrinsic. */
|
||||
nir_instr_rewrite_src(&store_output->instr, output_src, new_output_src);
|
||||
nir_intrinsic_set_write_mask(store_output, 1);
|
||||
store_output->num_components = 1;
|
||||
nir_intrinsic_set_src_type(store_output, nir_type_uint32);
|
||||
}
|
||||
|
||||
void rogue_nir_pfo(nir_shader *shader)
|
||||
{
|
||||
nir_function_impl *impl = nir_shader_get_entrypoint(shader);
|
||||
nir_builder b;
|
||||
|
||||
/* Only apply to fragment shaders. */
|
||||
if (shader->info.stage != MESA_SHADER_FRAGMENT)
|
||||
return;
|
||||
|
||||
nir_builder_init(&b, impl);
|
||||
|
||||
nir_foreach_block (block, impl) {
|
||||
nir_foreach_instr_safe (instr, block) {
|
||||
if (instr->type == nir_instr_type_intrinsic) {
|
||||
/* Find the store_output intrinsic and pack the output value. */
|
||||
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
|
||||
|
||||
if (intr->intrinsic != nir_intrinsic_store_output)
|
||||
continue;
|
||||
|
||||
b.cursor = nir_before_instr(&intr->instr);
|
||||
insert_pfo(&b, intr, &intr->src[0]);
|
||||
} else if (instr->type == nir_instr_type_deref) {
|
||||
/* Find variable derefs and update their type. */
|
||||
nir_deref_instr *deref = nir_instr_as_deref(instr);
|
||||
|
||||
if (!nir_deref_mode_is(deref, nir_var_shader_out))
|
||||
continue;
|
||||
|
||||
if (deref->deref_type != nir_deref_type_var)
|
||||
continue;
|
||||
|
||||
nir_variable *out = nir_deref_instr_get_variable(deref);
|
||||
|
||||
deref->type = glsl_uintN_t_type(32);
|
||||
out->type = glsl_uintN_t_type(32);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,789 @@
|
|||
/*
|
||||
* 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 <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "compiler/shader_enums.h"
|
||||
#include "compiler/spirv/nir_spirv.h"
|
||||
#include "nir/nir.h"
|
||||
#include "rogue.h"
|
||||
#include "rogue_build_data.h"
|
||||
#include "rogue_compiler.h"
|
||||
#include "rogue_constreg.h"
|
||||
#include "rogue_encode.h"
|
||||
#include "rogue_nir.h"
|
||||
#include "rogue_nir_helpers.h"
|
||||
#include "rogue_operand.h"
|
||||
#include "rogue_regalloc.h"
|
||||
#include "rogue_shader.h"
|
||||
#include "rogue_validate.h"
|
||||
#include "util/macros.h"
|
||||
#include "util/memstream.h"
|
||||
#include "util/ralloc.h"
|
||||
|
||||
/**
|
||||
* \file rogue.c
|
||||
*
|
||||
* \brief Contains the top-level Rogue compiler interface for Vulkan driver and
|
||||
* the offline compiler.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Converts a SPIR-V shader to NIR.
|
||||
*
|
||||
* \param[in] ctx Shared multi-stage build context.
|
||||
* \param[in] stage Shader stage.
|
||||
* \param[in] spirv_size SPIR-V data length in DWORDs.
|
||||
* \param[in] spirv_data SPIR-V data.
|
||||
* \param[in] num_spec Number of SPIR-V specializations.
|
||||
* \param[in] spec SPIR-V specializations.
|
||||
* \return A nir_shader* if successful, or NULL if unsuccessful.
|
||||
*/
|
||||
nir_shader *rogue_spirv_to_nir(struct rogue_build_ctx *ctx,
|
||||
gl_shader_stage stage,
|
||||
const char *entry,
|
||||
size_t spirv_size,
|
||||
const uint32_t *spirv_data,
|
||||
unsigned num_spec,
|
||||
struct nir_spirv_specialization *spec)
|
||||
{
|
||||
nir_shader *nir;
|
||||
|
||||
nir = spirv_to_nir(spirv_data,
|
||||
spirv_size,
|
||||
spec,
|
||||
num_spec,
|
||||
stage,
|
||||
entry,
|
||||
rogue_get_spirv_options(ctx->compiler),
|
||||
rogue_get_compiler_options(ctx->compiler));
|
||||
if (!nir)
|
||||
return NULL;
|
||||
|
||||
ralloc_steal(ctx, nir);
|
||||
|
||||
/* Apply passes. */
|
||||
if (!rogue_nir_passes(ctx, nir, stage)) {
|
||||
ralloc_free(nir);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Collect I/O data to pass back to the driver. */
|
||||
if (!rogue_collect_io_data(ctx, nir)) {
|
||||
ralloc_free(nir);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return nir;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Converts a Rogue shader to binary.
|
||||
*
|
||||
* \param[in] ctx Shared multi-stage build context.
|
||||
* \param[in] shader Rogue shader.
|
||||
* \return A rogue_shader_binary* if successful, or NULL if unsuccessful.
|
||||
*/
|
||||
struct rogue_shader_binary *rogue_to_binary(struct rogue_build_ctx *ctx,
|
||||
const struct rogue_shader *shader)
|
||||
{
|
||||
struct rogue_shader_binary *binary;
|
||||
struct u_memstream mem;
|
||||
size_t buf_size;
|
||||
char *buf;
|
||||
|
||||
if (!rogue_validate_shader(shader))
|
||||
return NULL;
|
||||
|
||||
if (!u_memstream_open(&mem, &buf, &buf_size))
|
||||
return NULL;
|
||||
|
||||
if (!rogue_encode_shader(shader, u_memstream_get(&mem))) {
|
||||
u_memstream_close(&mem);
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u_memstream_close(&mem);
|
||||
|
||||
binary = rzalloc_size(ctx, sizeof(*binary) + buf_size);
|
||||
if (!binary) {
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
binary->size = buf_size;
|
||||
memcpy(binary->data, buf, buf_size);
|
||||
|
||||
free(buf);
|
||||
|
||||
return binary;
|
||||
}
|
||||
|
||||
static bool
|
||||
setup_alu_dest(struct rogue_instr *instr, size_t dest_index, nir_alu_instr *alu)
|
||||
{
|
||||
assert(dest_index == 0);
|
||||
|
||||
/* Dest validation. */
|
||||
assert(nir_dest_num_components(alu->dest.dest) == 1 ||
|
||||
nir_dest_num_components(alu->dest.dest) == 4);
|
||||
assert(nir_dest_bit_size(alu->dest.dest) == 32);
|
||||
|
||||
size_t nir_dest_reg = nir_alu_dest_regindex(alu);
|
||||
|
||||
if (nir_dest_num_components(alu->dest.dest) == 1) {
|
||||
CHECK(rogue_instr_set_operand_vreg(instr, dest_index, nir_dest_reg));
|
||||
} else {
|
||||
size_t comp = nir_alu_dest_comp(alu);
|
||||
CHECK(rogue_instr_set_operand_vreg_vec(instr,
|
||||
dest_index,
|
||||
comp,
|
||||
nir_dest_reg));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_constreg_operand(struct rogue_instr *instr,
|
||||
size_t operand_index,
|
||||
uint32_t const_value)
|
||||
{
|
||||
size_t const_reg = rogue_constreg_lookup(const_value);
|
||||
|
||||
/* Only values that can be sourced from const regs should be left from the
|
||||
* rogue_nir_constreg pass.
|
||||
*/
|
||||
assert(const_reg != ROGUE_NO_CONST_REG);
|
||||
|
||||
CHECK(rogue_instr_set_operand_reg(instr,
|
||||
operand_index,
|
||||
ROGUE_OPERAND_TYPE_REG_CONST,
|
||||
const_reg));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_nir_alu_fmax(struct rogue_shader *shader, nir_alu_instr *alu)
|
||||
{
|
||||
/* Src validation. */
|
||||
assert(nir_src_num_components(alu->src[0].src) == 1);
|
||||
assert(nir_src_bit_size(alu->src[0].src) == 32);
|
||||
|
||||
assert(nir_src_num_components(alu->src[1].src) == 1);
|
||||
assert(nir_src_bit_size(alu->src[1].src) == 32);
|
||||
|
||||
struct rogue_instr *instr = rogue_shader_insert(shader, ROGUE_OP_MAX);
|
||||
|
||||
CHECK(setup_alu_dest(instr, 0, alu));
|
||||
|
||||
for (size_t u = 0; u < nir_op_infos[nir_op_fmax].num_inputs; ++u) {
|
||||
/* Handle values that can be pulled from const regs. */
|
||||
if (nir_alu_src_is_const(alu, u)) {
|
||||
CHECK(trans_constreg_operand(instr, u + 1, nir_alu_src_const(alu, u)));
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t nir_src_reg = nir_alu_src_regindex(alu, u);
|
||||
|
||||
CHECK(rogue_instr_set_operand_vreg(instr, u + 1, nir_src_reg));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_nir_alu_fmin(struct rogue_shader *shader, nir_alu_instr *alu)
|
||||
{
|
||||
/* Src validation. */
|
||||
assert(nir_src_num_components(alu->src[0].src) == 1);
|
||||
assert(nir_src_bit_size(alu->src[0].src) == 32);
|
||||
|
||||
assert(nir_src_num_components(alu->src[1].src) == 1);
|
||||
assert(nir_src_bit_size(alu->src[1].src) == 32);
|
||||
|
||||
struct rogue_instr *instr = rogue_shader_insert(shader, ROGUE_OP_MIN);
|
||||
|
||||
CHECK(setup_alu_dest(instr, 0, alu));
|
||||
|
||||
for (size_t u = 0; u < nir_op_infos[nir_op_fmin].num_inputs; ++u) {
|
||||
/* Handle values that can be pulled from const regs. */
|
||||
if (nir_alu_src_is_const(alu, u)) {
|
||||
CHECK(trans_constreg_operand(instr, u + 1, nir_alu_src_const(alu, u)));
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t nir_src_reg = nir_alu_src_regindex(alu, u);
|
||||
|
||||
CHECK(rogue_instr_set_operand_vreg(instr, u + 1, nir_src_reg));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_nir_alu_mov_imm(struct rogue_shader *shader,
|
||||
nir_alu_instr *alu)
|
||||
{
|
||||
/* Src validation. */
|
||||
assert(nir_src_num_components(alu->src[0].src) == 1);
|
||||
assert(nir_src_bit_size(alu->src[0].src) == 32);
|
||||
|
||||
uint32_t value = nir_alu_src_const(alu, 0);
|
||||
|
||||
struct rogue_instr *instr = rogue_shader_insert(shader, ROGUE_OP_MOV_IMM);
|
||||
|
||||
CHECK(setup_alu_dest(instr, 0, alu));
|
||||
CHECK(rogue_instr_set_operand_imm(instr, 1, value));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_nir_alu_mov(struct rogue_shader *shader, nir_alu_instr *alu)
|
||||
{
|
||||
/* Constant value that isn't in constregs. */
|
||||
if (nir_alu_src_is_const(alu, 0) &&
|
||||
nir_dest_num_components(alu->dest.dest) == 1)
|
||||
return trans_nir_alu_mov_imm(shader, alu);
|
||||
|
||||
/* Src validation. */
|
||||
assert(nir_src_num_components(alu->src[0].src) == 1);
|
||||
assert(nir_src_bit_size(alu->src[0].src) == 32);
|
||||
|
||||
struct rogue_instr *instr = rogue_shader_insert(shader, ROGUE_OP_MOV);
|
||||
|
||||
CHECK(setup_alu_dest(instr, 0, alu));
|
||||
|
||||
/* Handle values that can be pulled from const regs. */
|
||||
if (nir_alu_src_is_const(alu, 0)) {
|
||||
return trans_constreg_operand(instr, 1, nir_alu_src_const(alu, 0));
|
||||
}
|
||||
|
||||
size_t nir_src_reg = nir_alu_src_regindex(alu, 0);
|
||||
CHECK(rogue_instr_set_operand_vreg(instr, 1, nir_src_reg));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_nir_alu_pack_unorm_4x8(struct rogue_shader *shader,
|
||||
nir_alu_instr *alu)
|
||||
{
|
||||
/* Src/dest validation. */
|
||||
assert(nir_dest_num_components(alu->dest.dest) == 1);
|
||||
assert(nir_dest_bit_size(alu->dest.dest) == 32);
|
||||
|
||||
assert(nir_src_num_components(alu->src[0].src) == 4);
|
||||
assert(nir_src_bit_size(alu->src[0].src) == 32);
|
||||
|
||||
size_t nir_src_reg = nir_alu_src_regindex(alu, 0);
|
||||
size_t nir_dest_reg = nir_alu_dest_regindex(alu);
|
||||
|
||||
struct rogue_instr *instr = rogue_shader_insert(shader, ROGUE_OP_PACK_U8888);
|
||||
|
||||
CHECK(rogue_instr_set_operand_vreg(instr, 0, nir_dest_reg));
|
||||
|
||||
/* Ensure all 4 components are being sourced in order. */
|
||||
for (size_t u = 0; u < nir_src_num_components(alu->src[0].src); ++u)
|
||||
assert(alu->src->swizzle[u] == u);
|
||||
|
||||
CHECK(rogue_instr_set_operand_vreg_vec(instr,
|
||||
1,
|
||||
ROGUE_COMPONENT_ALL,
|
||||
nir_src_reg));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_nir_alu_fmul(struct rogue_shader *shader, nir_alu_instr *alu)
|
||||
{
|
||||
/* Src validation. */
|
||||
assert(nir_src_num_components(alu->src[0].src) == 1);
|
||||
assert(nir_src_bit_size(alu->src[0].src) == 32);
|
||||
|
||||
assert(nir_src_num_components(alu->src[1].src) == 1);
|
||||
assert(nir_src_bit_size(alu->src[1].src) == 32);
|
||||
|
||||
size_t nir_in_reg_a = nir_alu_src_regindex(alu, 0);
|
||||
size_t nir_in_reg_b = nir_alu_src_regindex(alu, 1);
|
||||
|
||||
struct rogue_instr *instr = rogue_shader_insert(shader, ROGUE_OP_MUL);
|
||||
|
||||
CHECK(setup_alu_dest(instr, 0, alu));
|
||||
CHECK(rogue_instr_set_operand_vreg(instr, 1, nir_in_reg_a));
|
||||
CHECK(rogue_instr_set_operand_vreg(instr, 2, nir_in_reg_b));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_nir_alu_ffma(struct rogue_shader *shader, nir_alu_instr *alu)
|
||||
{
|
||||
/* Src validation. */
|
||||
assert(nir_src_num_components(alu->src[0].src) == 1);
|
||||
assert(nir_src_bit_size(alu->src[0].src) == 32);
|
||||
|
||||
assert(nir_src_num_components(alu->src[1].src) == 1);
|
||||
assert(nir_src_bit_size(alu->src[1].src) == 32);
|
||||
|
||||
assert(nir_src_num_components(alu->src[2].src) == 1);
|
||||
assert(nir_src_bit_size(alu->src[2].src) == 32);
|
||||
|
||||
size_t nir_in_reg_a = nir_alu_src_regindex(alu, 0);
|
||||
size_t nir_in_reg_b = nir_alu_src_regindex(alu, 1);
|
||||
size_t nir_in_reg_c = nir_alu_src_regindex(alu, 2);
|
||||
|
||||
struct rogue_instr *instr = rogue_shader_insert(shader, ROGUE_OP_FMA);
|
||||
|
||||
CHECK(setup_alu_dest(instr, 0, alu));
|
||||
CHECK(rogue_instr_set_operand_vreg(instr, 1, nir_in_reg_a));
|
||||
CHECK(rogue_instr_set_operand_vreg(instr, 2, nir_in_reg_b));
|
||||
CHECK(rogue_instr_set_operand_vreg(instr, 3, nir_in_reg_c));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_nir_alu(struct rogue_shader *shader, nir_alu_instr *alu)
|
||||
{
|
||||
switch (alu->op) {
|
||||
case nir_op_fmax:
|
||||
return trans_nir_alu_fmax(shader, alu);
|
||||
|
||||
case nir_op_fmin:
|
||||
return trans_nir_alu_fmin(shader, alu);
|
||||
|
||||
case nir_op_pack_unorm_4x8:
|
||||
return trans_nir_alu_pack_unorm_4x8(shader, alu);
|
||||
|
||||
case nir_op_mov:
|
||||
return trans_nir_alu_mov(shader, alu);
|
||||
|
||||
case nir_op_fmul:
|
||||
return trans_nir_alu_fmul(shader, alu);
|
||||
|
||||
case nir_op_ffma:
|
||||
return trans_nir_alu_ffma(shader, alu);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
unreachable("Unimplemented NIR ALU instruction.");
|
||||
}
|
||||
|
||||
static bool trans_nir_intrinsic_load_input_fs(struct rogue_shader *shader,
|
||||
nir_intrinsic_instr *intr)
|
||||
{
|
||||
struct rogue_fs_build_data *fs_data = &shader->ctx->stage_data.fs;
|
||||
|
||||
/* Src/dest validation. */
|
||||
assert(nir_dest_num_components(intr->dest) == 1);
|
||||
assert(nir_dest_bit_size(intr->dest) == 32);
|
||||
|
||||
assert(nir_src_num_components(intr->src[0]) == 1);
|
||||
assert(nir_src_bit_size(intr->src[0]) == 32);
|
||||
assert(nir_intr_src_is_const(intr, 0));
|
||||
|
||||
/* Intrinsic index validation. */
|
||||
assert(nir_intrinsic_dest_type(intr) == nir_type_float32);
|
||||
|
||||
struct nir_io_semantics io_semantics = nir_intrinsic_io_semantics(intr);
|
||||
size_t component = nir_intrinsic_component(intr);
|
||||
size_t coeff_index = rogue_coeff_index_fs(&fs_data->iterator_args,
|
||||
io_semantics.location,
|
||||
component);
|
||||
size_t wcoeff_index = rogue_coeff_index_fs(&fs_data->iterator_args, ~0, 0);
|
||||
size_t drc_num = rogue_acquire_drc(shader);
|
||||
uint64_t source_count = nir_dest_num_components(intr->dest);
|
||||
|
||||
size_t nir_dest_reg = nir_intr_dest_regindex(intr);
|
||||
|
||||
/* pixiter.w instruction. */
|
||||
struct rogue_instr *instr = rogue_shader_insert(shader, ROGUE_OP_PIX_ITER_W);
|
||||
|
||||
CHECK(rogue_instr_set_operand_vreg(instr, 0, nir_dest_reg));
|
||||
CHECK(rogue_instr_set_operand_drc(instr, 1, drc_num));
|
||||
CHECK(rogue_instr_set_operand_reg(instr,
|
||||
2,
|
||||
ROGUE_OPERAND_TYPE_REG_COEFF,
|
||||
coeff_index));
|
||||
CHECK(rogue_instr_set_operand_reg(instr,
|
||||
3,
|
||||
ROGUE_OPERAND_TYPE_REG_COEFF,
|
||||
wcoeff_index));
|
||||
CHECK(rogue_instr_set_operand_imm(instr, 4, source_count));
|
||||
|
||||
/* wdf instruction must follow the pixiter.w. */
|
||||
instr = rogue_shader_insert(shader, ROGUE_OP_WDF);
|
||||
|
||||
CHECK(rogue_instr_set_operand_drc(instr, 0, drc_num));
|
||||
rogue_release_drc(shader, drc_num);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_nir_intrinsic_load_input_vs(struct rogue_shader *shader,
|
||||
nir_intrinsic_instr *intr)
|
||||
{
|
||||
/* Src/dest validation. */
|
||||
assert(nir_dest_num_components(intr->dest) == 1);
|
||||
assert(nir_dest_bit_size(intr->dest) == 32);
|
||||
|
||||
assert(nir_src_num_components(intr->src[0]) == 1);
|
||||
assert(nir_src_bit_size(intr->src[0]) == 32);
|
||||
assert(nir_intr_src_is_const(intr, 0));
|
||||
|
||||
/* Intrinsic index validation. */
|
||||
assert(nir_intrinsic_dest_type(intr) == nir_type_float32);
|
||||
|
||||
size_t component = nir_intrinsic_component(intr);
|
||||
struct nir_io_semantics io_semantics = nir_intrinsic_io_semantics(intr);
|
||||
size_t vi_reg_index = ((io_semantics.location - VERT_ATTRIB_GENERIC0) * 3) +
|
||||
component; /* TODO: get these properly with the
|
||||
* intrinsic index (ssa argument)
|
||||
*/
|
||||
|
||||
size_t nir_dest_reg = nir_intr_dest_regindex(intr);
|
||||
|
||||
struct rogue_instr *instr = rogue_shader_insert(shader, ROGUE_OP_MOV);
|
||||
|
||||
CHECK(rogue_instr_set_operand_vreg(instr, 0, nir_dest_reg));
|
||||
CHECK(rogue_instr_set_operand_reg(instr,
|
||||
1,
|
||||
ROGUE_OPERAND_TYPE_REG_VERTEX_IN,
|
||||
vi_reg_index));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_nir_intrinsic_load_input(struct rogue_shader *shader,
|
||||
nir_intrinsic_instr *intr)
|
||||
{
|
||||
switch (shader->stage) {
|
||||
case MESA_SHADER_FRAGMENT:
|
||||
return trans_nir_intrinsic_load_input_fs(shader, intr);
|
||||
|
||||
case MESA_SHADER_VERTEX:
|
||||
return trans_nir_intrinsic_load_input_vs(shader, intr);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
unreachable("Unimplemented NIR load_input variant.");
|
||||
}
|
||||
|
||||
static bool trans_nir_intrinsic_store_output_fs(struct rogue_shader *shader,
|
||||
nir_intrinsic_instr *intr)
|
||||
{
|
||||
/* Src/dest validation. */
|
||||
assert(nir_src_num_components(intr->src[0]) == 1);
|
||||
assert(nir_src_bit_size(intr->src[0]) == 32);
|
||||
assert(!nir_intr_src_is_const(intr, 0));
|
||||
|
||||
assert(nir_src_num_components(intr->src[1]) == 1);
|
||||
assert(nir_src_bit_size(intr->src[1]) == 32);
|
||||
assert(nir_intr_src_is_const(intr, 1));
|
||||
|
||||
/* Intrinsic index validation. */
|
||||
assert(nir_intrinsic_src_type(intr) == nir_type_uint32);
|
||||
|
||||
/* Fetch the output offset. */
|
||||
/* TODO: Is this really the right value to use for pixel out reg. num? */
|
||||
size_t offset = nir_intr_src_const(intr, 1);
|
||||
|
||||
/* Fetch the components. */
|
||||
size_t src_reg = nir_intr_src_regindex(intr, 0);
|
||||
|
||||
/* mov.olchk instruction. */
|
||||
struct rogue_instr *instr = rogue_shader_insert(shader, ROGUE_OP_MOV);
|
||||
|
||||
CHECK(rogue_instr_set_operand_reg(instr,
|
||||
0,
|
||||
ROGUE_OPERAND_TYPE_REG_PIXEL_OUT,
|
||||
offset));
|
||||
CHECK(rogue_instr_set_operand_vreg(instr, 1, src_reg));
|
||||
CHECK(rogue_instr_set_flag(instr, ROGUE_INSTR_FLAG_OLCHK));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_nir_intrinsic_store_output_vs(struct rogue_shader *shader,
|
||||
nir_intrinsic_instr *intr)
|
||||
{
|
||||
struct rogue_vs_build_data *vs_data = &shader->ctx->stage_data.vs;
|
||||
|
||||
/* Src/dest validation. */
|
||||
assert(nir_src_num_components(intr->src[0]) == 1);
|
||||
assert(nir_src_bit_size(intr->src[0]) == 32);
|
||||
assert(!nir_intr_src_is_const(intr, 0));
|
||||
|
||||
assert(nir_src_num_components(intr->src[1]) == 1);
|
||||
assert(nir_src_bit_size(intr->src[1]) == 32);
|
||||
assert(nir_intr_src_is_const(intr, 1));
|
||||
|
||||
/* Intrinsic index validation. */
|
||||
assert(nir_intrinsic_src_type(intr) == nir_type_float32);
|
||||
assert(util_bitcount(nir_intrinsic_write_mask(intr)) == 1);
|
||||
|
||||
struct nir_io_semantics io_semantics = nir_intrinsic_io_semantics(intr);
|
||||
size_t component = nir_intrinsic_component(intr);
|
||||
size_t vo_index = rogue_output_index_vs(&vs_data->outputs,
|
||||
io_semantics.location,
|
||||
component);
|
||||
|
||||
size_t src_reg = nir_intr_src_regindex(intr, 0);
|
||||
|
||||
struct rogue_instr *instr = rogue_shader_insert(shader, ROGUE_OP_VTXOUT);
|
||||
|
||||
CHECK(rogue_instr_set_operand_imm(instr, 0, vo_index));
|
||||
CHECK(rogue_instr_set_operand_vreg(instr, 1, src_reg));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_nir_intrinsic_store_output(struct rogue_shader *shader,
|
||||
nir_intrinsic_instr *intr)
|
||||
{
|
||||
switch (shader->stage) {
|
||||
case MESA_SHADER_FRAGMENT:
|
||||
return trans_nir_intrinsic_store_output_fs(shader, intr);
|
||||
|
||||
case MESA_SHADER_VERTEX:
|
||||
return trans_nir_intrinsic_store_output_vs(shader, intr);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
unreachable("Unimplemented NIR store_output variant.");
|
||||
}
|
||||
|
||||
static bool trans_nir_intrinsic_load_ubo(struct rogue_shader *shader,
|
||||
nir_intrinsic_instr *intr)
|
||||
{
|
||||
struct rogue_ubo_data *ubo_data =
|
||||
&shader->ctx->common_data[shader->stage].ubo_data;
|
||||
|
||||
/* Src/dest validation. */
|
||||
assert(nir_dest_num_components(intr->dest) == 1);
|
||||
assert(nir_dest_bit_size(intr->dest) == 32);
|
||||
|
||||
assert(nir_src_num_components(intr->src[0]) == 2);
|
||||
assert(nir_src_bit_size(intr->src[0]) == 32);
|
||||
assert(nir_intr_src_is_const(intr, 0));
|
||||
|
||||
assert(nir_src_num_components(intr->src[1]) == 1);
|
||||
assert(nir_src_bit_size(intr->src[1]) == 32);
|
||||
assert(nir_intr_src_is_const(intr, 1));
|
||||
|
||||
/* Intrinsic index validation. */
|
||||
assert((nir_intrinsic_range_base(intr) % ROGUE_REG_SIZE_BYTES) == 0);
|
||||
assert(nir_intrinsic_range(intr) == ROGUE_REG_SIZE_BYTES);
|
||||
|
||||
size_t nir_dest_reg = nir_intr_dest_regindex(intr);
|
||||
|
||||
size_t desc_set = nir_intr_src_comp_const(intr, 0, 0);
|
||||
size_t binding = nir_intr_src_comp_const(intr, 0, 1);
|
||||
size_t offset = nir_intrinsic_range_base(intr);
|
||||
|
||||
size_t sh_num = rogue_ubo_reg(ubo_data, desc_set, binding, offset);
|
||||
|
||||
struct rogue_instr *instr = rogue_shader_insert(shader, ROGUE_OP_MOV);
|
||||
|
||||
CHECK(rogue_instr_set_operand_vreg(instr, 0, nir_dest_reg));
|
||||
CHECK(rogue_instr_set_operand_reg(instr,
|
||||
1,
|
||||
ROGUE_OPERAND_TYPE_REG_SHARED,
|
||||
sh_num));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_nir_intrinsic(struct rogue_shader *shader,
|
||||
nir_intrinsic_instr *intr)
|
||||
{
|
||||
switch (intr->intrinsic) {
|
||||
case nir_intrinsic_load_input:
|
||||
return trans_nir_intrinsic_load_input(shader, intr);
|
||||
|
||||
case nir_intrinsic_store_output:
|
||||
return trans_nir_intrinsic_store_output(shader, intr);
|
||||
|
||||
case nir_intrinsic_load_ubo:
|
||||
return trans_nir_intrinsic_load_ubo(shader, intr);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
unreachable("Unimplemented NIR intrinsic instruction.");
|
||||
}
|
||||
|
||||
static bool trans_nir_load_const(struct rogue_shader *shader,
|
||||
nir_load_const_instr *load_const)
|
||||
{
|
||||
/* Src/dest validation. */
|
||||
assert(load_const->def.bit_size == 32);
|
||||
|
||||
/* Ensure that two-component load_consts are used only by load_ubos. */
|
||||
if (load_const->def.num_components == 2) {
|
||||
nir_foreach_use (use_src, &load_const->def) {
|
||||
nir_instr *instr = use_src->parent_instr;
|
||||
assert(instr->type == nir_instr_type_intrinsic);
|
||||
|
||||
ASSERTED nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
|
||||
assert(intr->intrinsic == nir_intrinsic_load_ubo);
|
||||
}
|
||||
} else {
|
||||
assert(load_const->def.num_components == 1);
|
||||
}
|
||||
|
||||
/* TODO: This is currently done in MOV_IMM, but instead now would be the
|
||||
* time to lookup the constant value, see if it lives in const regs, or if
|
||||
* it needs to generate a MOV_IMM (or be constant calc-ed).
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_nir_jump_return(struct rogue_shader *shader,
|
||||
nir_jump_instr *jump)
|
||||
{
|
||||
enum rogue_opcode return_op;
|
||||
|
||||
switch (shader->stage) {
|
||||
case MESA_SHADER_FRAGMENT:
|
||||
return_op = ROGUE_OP_END_FRAG;
|
||||
break;
|
||||
|
||||
case MESA_SHADER_VERTEX:
|
||||
return_op = ROGUE_OP_END_VERT;
|
||||
break;
|
||||
|
||||
default:
|
||||
unreachable("Unimplemented NIR return instruction type.");
|
||||
}
|
||||
|
||||
rogue_shader_insert(shader, return_op);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_nir_jump(struct rogue_shader *shader, nir_jump_instr *jump)
|
||||
{
|
||||
switch (jump->type) {
|
||||
case nir_jump_return:
|
||||
return trans_nir_jump_return(shader, jump);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
unreachable("Unimplemented NIR jump instruction type.");
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Converts a NIR shader to Rogue.
|
||||
*
|
||||
* \param[in] ctx Shared multi-stage build context.
|
||||
* \param[in] nir NIR shader.
|
||||
* \return A rogue_shader* if successful, or NULL if unsuccessful.
|
||||
*/
|
||||
struct rogue_shader *rogue_nir_to_rogue(struct rogue_build_ctx *ctx,
|
||||
const nir_shader *nir)
|
||||
{
|
||||
gl_shader_stage stage = nir->info.stage;
|
||||
struct rogue_shader *shader = rogue_shader_create(ctx, stage);
|
||||
if (!shader)
|
||||
return NULL;
|
||||
|
||||
/* Make sure we only have a single function. */
|
||||
assert(exec_list_length(&nir->functions) == 1);
|
||||
|
||||
/* Translate shader entrypoint. */
|
||||
nir_function_impl *entry = nir_shader_get_entrypoint((nir_shader *)nir);
|
||||
nir_foreach_block (block, entry) {
|
||||
nir_foreach_instr (instr, block) {
|
||||
switch (instr->type) {
|
||||
case nir_instr_type_alu:
|
||||
/* TODO: Cleanup on failure. */
|
||||
CHECKF(trans_nir_alu(shader, nir_instr_as_alu(instr)),
|
||||
"Failed to translate NIR ALU instruction.");
|
||||
break;
|
||||
|
||||
case nir_instr_type_intrinsic:
|
||||
CHECKF(trans_nir_intrinsic(shader, nir_instr_as_intrinsic(instr)),
|
||||
"Failed to translate NIR intrinsic instruction.");
|
||||
break;
|
||||
|
||||
case nir_instr_type_load_const:
|
||||
CHECKF(trans_nir_load_const(shader, nir_instr_as_load_const(instr)),
|
||||
"Failed to translate NIR load_const instruction.");
|
||||
break;
|
||||
|
||||
case nir_instr_type_jump:
|
||||
CHECKF(trans_nir_jump(shader, nir_instr_as_jump(instr)),
|
||||
"Failed to translate NIR jump instruction.");
|
||||
break;
|
||||
|
||||
default:
|
||||
unreachable("Unimplemented NIR instruction type.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform register allocation. */
|
||||
/* TODO: handle failure. */
|
||||
if (!rogue_ra_alloc(&shader->instr_list,
|
||||
shader->ra,
|
||||
&ctx->common_data[stage].temps,
|
||||
&ctx->common_data[stage].internals))
|
||||
return NULL;
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Creates and sets up a shared multi-stage build context.
|
||||
*
|
||||
* \param[in] compiler The compiler context.
|
||||
* \return A pointer to the new build context, or NULL on failure.
|
||||
*/
|
||||
struct rogue_build_ctx *
|
||||
rogue_create_build_context(struct rogue_compiler *compiler)
|
||||
{
|
||||
struct rogue_build_ctx *ctx;
|
||||
|
||||
ctx = rzalloc_size(compiler, sizeof(*ctx));
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
ctx->compiler = compiler;
|
||||
|
||||
/* nir/rogue/binary shaders need to be default-zeroed;
|
||||
* this is taken care of by rzalloc_size.
|
||||
*/
|
||||
|
||||
/* Setup non-zero defaults. */
|
||||
ctx->stage_data.fs.msaa_mode = ROGUE_MSAA_MODE_PIXEL;
|
||||
|
||||
return ctx;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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 ROGUE_H
|
||||
#define ROGUE_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "compiler/shader_enums.h"
|
||||
#include "nir/nir.h"
|
||||
|
||||
/* All registers are 32-bit in size. */
|
||||
#define ROGUE_REG_SIZE_BYTES 4
|
||||
#define ROGUE_REG_UNUSED UINT32_MAX
|
||||
|
||||
struct nir_spirv_specialization;
|
||||
struct rogue_build_ctx;
|
||||
struct rogue_shader;
|
||||
|
||||
enum rogue_msaa_mode {
|
||||
ROGUE_MSAA_MODE_UNDEF = 0, /* explicitly treat 0 as undefined */
|
||||
/* One task for all samples. */
|
||||
ROGUE_MSAA_MODE_PIXEL,
|
||||
/* For on-edge pixels only: separate tasks for each sample. */
|
||||
ROGUE_MSAA_MODE_SELECTIVE,
|
||||
/* For all pixels: separate tasks for each sample. */
|
||||
ROGUE_MSAA_MODE_FULL,
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Shader binary.
|
||||
*/
|
||||
struct rogue_shader_binary {
|
||||
size_t size;
|
||||
uint8_t data[];
|
||||
};
|
||||
|
||||
PUBLIC
|
||||
nir_shader *rogue_spirv_to_nir(struct rogue_build_ctx *ctx,
|
||||
gl_shader_stage stage,
|
||||
const char *entry,
|
||||
size_t spirv_size,
|
||||
const uint32_t *spirv_data,
|
||||
unsigned num_spec,
|
||||
struct nir_spirv_specialization *spec);
|
||||
|
||||
PUBLIC
|
||||
struct rogue_shader_binary *rogue_to_binary(struct rogue_build_ctx *ctx,
|
||||
const struct rogue_shader *shader);
|
||||
|
||||
PUBLIC
|
||||
struct rogue_shader *rogue_nir_to_rogue(struct rogue_build_ctx *ctx,
|
||||
const nir_shader *nir);
|
||||
#endif /* ROGUE_H */
|
|
@ -0,0 +1,602 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "compiler/shader_enums.h"
|
||||
#include "nir/nir.h"
|
||||
#include "rogue_build_data.h"
|
||||
#include "rogue_nir_helpers.h"
|
||||
#include "rogue_operand.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
#define __pvr_address_type uint64_t
|
||||
#define __pvr_get_address(pvr_dev_addr) (pvr_dev_addr)
|
||||
|
||||
#include "csbgen/rogue_pds.h"
|
||||
|
||||
#undef __pvr_get_address
|
||||
#undef __pvr_address_type
|
||||
|
||||
/**
|
||||
* \brief Allocates the coefficient registers that will contain the iterator
|
||||
* data for the fragment shader input varyings.
|
||||
*
|
||||
* \param[in] args The iterator argument data.
|
||||
* \return The total number of coefficient registers required by the iterators.
|
||||
*/
|
||||
static size_t alloc_iterator_regs(struct rogue_iterator_args *args)
|
||||
{
|
||||
size_t coeffs = 0;
|
||||
|
||||
for (size_t u = 0; u < args->num_fpu_iterators; ++u) {
|
||||
/* Ensure there aren't any gaps. */
|
||||
assert(args->base[u] == ~0);
|
||||
|
||||
args->base[u] = coeffs;
|
||||
coeffs += ROGUE_COEFF_ALIGN * args->components[u];
|
||||
}
|
||||
|
||||
return coeffs;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reserves an iterator for a fragment shader input varying,
|
||||
* and calculates its setup data.
|
||||
*
|
||||
* \param[in] args The iterator argument data.
|
||||
* \param[in] i The iterator index.
|
||||
* \param[in] type The interpolation type of the varying.
|
||||
* \param[in] f16 Whether the data type is F16 or F32.
|
||||
* \param[in] components The number of components in the varying.
|
||||
*/
|
||||
static void reserve_iterator(struct rogue_iterator_args *args,
|
||||
size_t i,
|
||||
enum glsl_interp_mode type,
|
||||
bool f16,
|
||||
size_t components)
|
||||
{
|
||||
struct ROGUE_PDSINST_DOUT_FIELDS_DOUTI_SRC data = { 0 };
|
||||
|
||||
assert(components >= 1 && components <= 4);
|
||||
|
||||
/* The first iterator (W) *must* be INTERP_MODE_NOPERSPECTIVE. */
|
||||
assert(i > 0 || type == INTERP_MODE_NOPERSPECTIVE);
|
||||
assert(i < ARRAY_SIZE(args->fpu_iterators));
|
||||
|
||||
switch (type) {
|
||||
/* Default interpolation is smooth. */
|
||||
case INTERP_MODE_NONE:
|
||||
data.shademodel = ROGUE_PDSINST_DOUTI_SHADEMODEL_GOURUAD;
|
||||
data.perspective = true;
|
||||
break;
|
||||
|
||||
case INTERP_MODE_NOPERSPECTIVE:
|
||||
data.shademodel = ROGUE_PDSINST_DOUTI_SHADEMODEL_GOURUAD;
|
||||
data.perspective = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
unreachable("Unimplemented interpolation type.");
|
||||
}
|
||||
|
||||
/* Number of components in this varying
|
||||
* (corresponds to ROGUE_PDSINST_DOUTI_SIZE_1..4D).
|
||||
*/
|
||||
data.size = (components - 1);
|
||||
|
||||
/* TODO: Investigate F16 support. */
|
||||
assert(!f16);
|
||||
data.f16 = f16;
|
||||
|
||||
/* Offsets within the vertex. */
|
||||
data.f32_offset = 2 * i;
|
||||
data.f16_offset = data.f32_offset;
|
||||
|
||||
ROGUE_PDSINST_DOUT_FIELDS_DOUTI_SRC_pack(&args->fpu_iterators[i], &data);
|
||||
args->destination[i] = i;
|
||||
args->base[i] = ~0;
|
||||
args->components[i] = components;
|
||||
++args->num_fpu_iterators;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Collects the fragment shader I/O data to feed-back to the driver.
|
||||
*
|
||||
* \sa #collect_io_data()
|
||||
*
|
||||
* \param[in] common_data Common build data.
|
||||
* \param[in] fs_data Fragment-specific build data.
|
||||
* \param[in] nir NIR fragment shader.
|
||||
* \return true if successful, otherwise false.
|
||||
*/
|
||||
static bool collect_io_data_fs(struct rogue_common_build_data *common_data,
|
||||
struct rogue_fs_build_data *fs_data,
|
||||
nir_shader *nir)
|
||||
{
|
||||
size_t num_inputs = nir_count_variables_with_modes(nir, nir_var_shader_in);
|
||||
assert(num_inputs < (ARRAY_SIZE(fs_data->iterator_args.fpu_iterators) - 1));
|
||||
|
||||
/* Process inputs (if present). */
|
||||
if (num_inputs) {
|
||||
/* If the fragment shader has inputs, the first iterator
|
||||
* must be used for the W component.
|
||||
*/
|
||||
reserve_iterator(&fs_data->iterator_args,
|
||||
0,
|
||||
INTERP_MODE_NOPERSPECTIVE,
|
||||
false,
|
||||
1);
|
||||
|
||||
nir_foreach_shader_in_variable (var, nir) {
|
||||
size_t i = (var->data.location - VARYING_SLOT_VAR0) + 1;
|
||||
size_t components = glsl_get_components(var->type);
|
||||
enum glsl_interp_mode interp = var->data.interpolation;
|
||||
bool f16 = glsl_type_is_16bit(var->type);
|
||||
|
||||
/* Check that arguments are either F16 or F32. */
|
||||
assert(glsl_get_base_type(var->type) == GLSL_TYPE_FLOAT);
|
||||
assert(f16 || glsl_type_is_32bit(var->type));
|
||||
|
||||
/* Check input location. */
|
||||
assert(var->data.location >= VARYING_SLOT_VAR0 &&
|
||||
var->data.location <= VARYING_SLOT_VAR31);
|
||||
|
||||
reserve_iterator(&fs_data->iterator_args, i, interp, f16, components);
|
||||
}
|
||||
|
||||
common_data->coeffs = alloc_iterator_regs(&fs_data->iterator_args);
|
||||
assert(common_data->coeffs);
|
||||
assert(common_data->coeffs < ROGUE_MAX_REG_COEFF);
|
||||
}
|
||||
|
||||
/* TODO: Process outputs. */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Allocates the vertex shader input registers.
|
||||
*
|
||||
* \param[in] inputs The vertex shader input data.
|
||||
* \return The total number of vertex input registers required.
|
||||
*/
|
||||
static size_t alloc_vs_inputs(struct rogue_vertex_inputs *inputs)
|
||||
{
|
||||
size_t vs_inputs = 0;
|
||||
|
||||
for (size_t u = 0; u < inputs->num_input_vars; ++u) {
|
||||
/* Ensure there aren't any gaps. */
|
||||
assert(inputs->base[u] == ~0);
|
||||
|
||||
inputs->base[u] = vs_inputs;
|
||||
vs_inputs += inputs->components[u];
|
||||
}
|
||||
|
||||
return vs_inputs;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Allocates the vertex shader outputs.
|
||||
*
|
||||
* \param[in] outputs The vertex shader output data.
|
||||
* \return The total number of vertex outputs required.
|
||||
*/
|
||||
static size_t alloc_vs_outputs(struct rogue_vertex_outputs *outputs)
|
||||
{
|
||||
size_t vs_outputs = 0;
|
||||
|
||||
for (size_t u = 0; u < outputs->num_output_vars; ++u) {
|
||||
/* Ensure there aren't any gaps. */
|
||||
assert(outputs->base[u] == ~0);
|
||||
|
||||
outputs->base[u] = vs_outputs;
|
||||
vs_outputs += outputs->components[u];
|
||||
}
|
||||
|
||||
return vs_outputs;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Counts the varyings used by the vertex shader.
|
||||
*
|
||||
* \param[in] outputs The vertex shader output data.
|
||||
* \return The number of varyings used.
|
||||
*/
|
||||
static size_t count_vs_varyings(struct rogue_vertex_outputs *outputs)
|
||||
{
|
||||
size_t varyings = 0;
|
||||
|
||||
/* Skip the position. */
|
||||
for (size_t u = 1; u < outputs->num_output_vars; ++u)
|
||||
varyings += outputs->components[u];
|
||||
|
||||
return varyings;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reserves space for a vertex shader input.
|
||||
*
|
||||
* \param[in] inputs The vertex input data.
|
||||
* \param[in] i The vertex input index.
|
||||
* \param[in] components The number of components in the input.
|
||||
*/
|
||||
static void reserve_vs_input(struct rogue_vertex_inputs *inputs,
|
||||
size_t i,
|
||||
size_t components)
|
||||
{
|
||||
assert(components >= 1 && components <= 4);
|
||||
|
||||
assert(i < ARRAY_SIZE(inputs->base));
|
||||
|
||||
inputs->base[i] = ~0;
|
||||
inputs->components[i] = components;
|
||||
++inputs->num_input_vars;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reserves space for a vertex shader output.
|
||||
*
|
||||
* \param[in] outputs The vertex output data.
|
||||
* \param[in] i The vertex output index.
|
||||
* \param[in] components The number of components in the output.
|
||||
*/
|
||||
static void reserve_vs_output(struct rogue_vertex_outputs *outputs,
|
||||
size_t i,
|
||||
size_t components)
|
||||
{
|
||||
assert(components >= 1 && components <= 4);
|
||||
|
||||
assert(i < ARRAY_SIZE(outputs->base));
|
||||
|
||||
outputs->base[i] = ~0;
|
||||
outputs->components[i] = components;
|
||||
++outputs->num_output_vars;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Collects the vertex shader I/O data to feed-back to the driver.
|
||||
*
|
||||
* \sa #collect_io_data()
|
||||
*
|
||||
* \param[in] common_data Common build data.
|
||||
* \param[in] vs_data Vertex-specific build data.
|
||||
* \param[in] nir NIR vertex shader.
|
||||
* \return true if successful, otherwise false.
|
||||
*/
|
||||
static bool collect_io_data_vs(struct rogue_common_build_data *common_data,
|
||||
struct rogue_vs_build_data *vs_data,
|
||||
nir_shader *nir)
|
||||
{
|
||||
ASSERTED bool out_pos_present = false;
|
||||
ASSERTED size_t num_outputs =
|
||||
nir_count_variables_with_modes(nir, nir_var_shader_out);
|
||||
|
||||
/* Process inputs. */
|
||||
nir_foreach_shader_in_variable (var, nir) {
|
||||
size_t components = glsl_get_components(var->type);
|
||||
size_t i = var->data.location - VERT_ATTRIB_GENERIC0;
|
||||
|
||||
/* Check that inputs are F32. */
|
||||
/* TODO: Support other types. */
|
||||
assert(glsl_get_base_type(var->type) == GLSL_TYPE_FLOAT);
|
||||
assert(glsl_type_is_32bit(var->type));
|
||||
|
||||
/* Check input location. */
|
||||
assert(var->data.location >= VERT_ATTRIB_GENERIC0 &&
|
||||
var->data.location <= VERT_ATTRIB_GENERIC15);
|
||||
|
||||
reserve_vs_input(&vs_data->inputs, i, components);
|
||||
}
|
||||
|
||||
vs_data->num_vertex_input_regs = alloc_vs_inputs(&vs_data->inputs);
|
||||
assert(vs_data->num_vertex_input_regs);
|
||||
assert(vs_data->num_vertex_input_regs < ROGUE_MAX_REG_VERTEX_IN);
|
||||
|
||||
/* Process outputs. */
|
||||
|
||||
/* We should always have at least a position variable. */
|
||||
assert(num_outputs > 0 && "Invalid number of vertex shader outputs.");
|
||||
|
||||
nir_foreach_shader_out_variable (var, nir) {
|
||||
size_t components = glsl_get_components(var->type);
|
||||
|
||||
/* Check that outputs are F32. */
|
||||
/* TODO: Support other types. */
|
||||
assert(glsl_get_base_type(var->type) == GLSL_TYPE_FLOAT);
|
||||
assert(glsl_type_is_32bit(var->type));
|
||||
|
||||
if (var->data.location == VARYING_SLOT_POS) {
|
||||
assert(components == 4);
|
||||
out_pos_present = true;
|
||||
|
||||
reserve_vs_output(&vs_data->outputs, 0, components);
|
||||
} else if ((var->data.location >= VARYING_SLOT_VAR0) &&
|
||||
(var->data.location <= VARYING_SLOT_VAR31)) {
|
||||
size_t i = (var->data.location - VARYING_SLOT_VAR0) + 1;
|
||||
reserve_vs_output(&vs_data->outputs, i, components);
|
||||
} else {
|
||||
unreachable("Unsupported vertex output type.");
|
||||
}
|
||||
}
|
||||
|
||||
/* Always need the output position to be present. */
|
||||
assert(out_pos_present);
|
||||
|
||||
vs_data->num_vertex_outputs = alloc_vs_outputs(&vs_data->outputs);
|
||||
assert(vs_data->num_vertex_outputs);
|
||||
assert(vs_data->num_vertex_outputs < ROGUE_MAX_VERTEX_OUTPUTS);
|
||||
|
||||
vs_data->num_varyings = count_vs_varyings(&vs_data->outputs);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Allocates the shared registers that will contain the UBOs.
|
||||
*
|
||||
* \param[in] ubo_data The UBO data.
|
||||
* \return The total number of coefficient registers required by the iterators.
|
||||
*/
|
||||
static size_t alloc_ubos(struct rogue_ubo_data *ubo_data)
|
||||
{
|
||||
size_t shareds = 0;
|
||||
|
||||
for (size_t u = 0; u < ubo_data->num_ubo_entries; ++u) {
|
||||
/* Ensure there aren't any gaps. */
|
||||
assert(ubo_data->dest[u] == ~0);
|
||||
|
||||
ubo_data->dest[u] = shareds;
|
||||
shareds += ubo_data->size[u];
|
||||
}
|
||||
|
||||
return shareds;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reserves a UBO and calculates its data.
|
||||
*
|
||||
* \param[in] ubo_data The UBO data.
|
||||
* \param[in] desc_set The UBO descriptor set.
|
||||
* \param[in] binding The UBO binding.
|
||||
* \param[in] size The size required by the UBO (in dwords).
|
||||
*/
|
||||
static void reserve_ubo(struct rogue_ubo_data *ubo_data,
|
||||
size_t desc_set,
|
||||
size_t binding,
|
||||
size_t size)
|
||||
{
|
||||
size_t i = ubo_data->num_ubo_entries;
|
||||
assert(i < ARRAY_SIZE(ubo_data->desc_set));
|
||||
|
||||
ubo_data->desc_set[i] = desc_set;
|
||||
ubo_data->binding[i] = binding;
|
||||
ubo_data->dest[i] = ~0;
|
||||
ubo_data->size[i] = size;
|
||||
++ubo_data->num_ubo_entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Collects UBO data to feed-back to the driver.
|
||||
*
|
||||
* \param[in] common_data Common build data.
|
||||
* \param[in] nir NIR shader.
|
||||
* \return true if successful, otherwise false.
|
||||
*/
|
||||
static bool collect_ubo_data(struct rogue_common_build_data *common_data,
|
||||
nir_shader *nir)
|
||||
{
|
||||
/* Iterate over each UBO. */
|
||||
nir_foreach_variable_with_modes (var, nir, nir_var_mem_ubo) {
|
||||
size_t desc_set = var->data.driver_location;
|
||||
size_t binding = var->data.binding;
|
||||
size_t ubo_size_regs = 0;
|
||||
|
||||
nir_function_impl *entry = nir_shader_get_entrypoint(nir);
|
||||
/* Iterate over each load_ubo that uses this UBO. */
|
||||
nir_foreach_block (block, entry) {
|
||||
nir_foreach_instr (instr, block) {
|
||||
if (instr->type != nir_instr_type_intrinsic)
|
||||
continue;
|
||||
|
||||
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
|
||||
if (intr->intrinsic != nir_intrinsic_load_ubo)
|
||||
continue;
|
||||
|
||||
assert(nir_src_num_components(intr->src[0]) == 2);
|
||||
assert(nir_intr_src_is_const(intr, 0));
|
||||
|
||||
size_t load_desc_set = nir_intr_src_comp_const(intr, 0, 0);
|
||||
size_t load_binding = nir_intr_src_comp_const(intr, 0, 1);
|
||||
|
||||
if (load_desc_set != desc_set || load_binding != binding)
|
||||
continue;
|
||||
|
||||
ASSERTED size_t size_bytes = nir_intrinsic_range(intr);
|
||||
assert(size_bytes == ROGUE_REG_SIZE_BYTES);
|
||||
|
||||
size_t offset_bytes = nir_intrinsic_range_base(intr);
|
||||
assert(!(offset_bytes % ROGUE_REG_SIZE_BYTES));
|
||||
|
||||
size_t offset_regs = offset_bytes / ROGUE_REG_SIZE_BYTES;
|
||||
|
||||
/* TODO: Put offsets in a BITSET_DECLARE and check for gaps. */
|
||||
|
||||
/* Find the largest load offset. */
|
||||
ubo_size_regs = MAX2(ubo_size_regs, offset_regs);
|
||||
}
|
||||
}
|
||||
|
||||
/* UBO size = largest offset + 1. */
|
||||
++ubo_size_regs;
|
||||
|
||||
reserve_ubo(&common_data->ubo_data, desc_set, binding, ubo_size_regs);
|
||||
}
|
||||
|
||||
common_data->shareds = alloc_ubos(&common_data->ubo_data);
|
||||
assert(common_data->shareds < ROGUE_MAX_REG_SHARED);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Collects I/O data to feed-back to the driver.
|
||||
*
|
||||
* Collects the inputs/outputs/memory required, and feeds that back to the
|
||||
* driver. Done at this stage rather than at the start of rogue_to_binary, so
|
||||
* that all the I/O of all the shader stages is known before backend
|
||||
* compilation, which would let us do things like cull unused inputs.
|
||||
*
|
||||
* \param[in] ctx Shared multi-stage build context.
|
||||
* \param[in] nir NIR shader.
|
||||
* \return true if successful, otherwise false.
|
||||
*/
|
||||
bool rogue_collect_io_data(struct rogue_build_ctx *ctx, nir_shader *nir)
|
||||
{
|
||||
gl_shader_stage stage = nir->info.stage;
|
||||
struct rogue_common_build_data *common_data = &ctx->common_data[stage];
|
||||
|
||||
/* Collect stage-agnostic data. */
|
||||
if (!collect_ubo_data(common_data, nir))
|
||||
return false;
|
||||
|
||||
/* Collect stage-specific data. */
|
||||
switch (stage) {
|
||||
case MESA_SHADER_FRAGMENT:
|
||||
return collect_io_data_fs(common_data, &ctx->stage_data.fs, nir);
|
||||
|
||||
case MESA_SHADER_VERTEX:
|
||||
return collect_io_data_vs(common_data, &ctx->stage_data.vs, nir);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the allocated coefficient register index for a component of an
|
||||
* input varying location.
|
||||
*
|
||||
* \param[in] args The allocated iterator argument data.
|
||||
* \param[in] location The input varying location, or ~0 for the W coefficient.
|
||||
* \param[in] component The requested component.
|
||||
* \return The coefficient register index.
|
||||
*/
|
||||
size_t rogue_coeff_index_fs(struct rogue_iterator_args *args,
|
||||
gl_varying_slot location,
|
||||
size_t component)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
/* Special case: W coefficient. */
|
||||
if (location == ~0) {
|
||||
/* The W component shouldn't be the only one. */
|
||||
assert(args->num_fpu_iterators > 1);
|
||||
assert(args->destination[0] == 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
i = (location - VARYING_SLOT_VAR0) + 1;
|
||||
assert(location >= VARYING_SLOT_VAR0 && location <= VARYING_SLOT_VAR31);
|
||||
assert(i < args->num_fpu_iterators);
|
||||
assert(component < args->components[i]);
|
||||
assert(args->base[i] != ~0);
|
||||
|
||||
return args->base[i] + (ROGUE_COEFF_ALIGN * component);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the allocated vertex output index for a component of an input
|
||||
* varying location.
|
||||
*
|
||||
* \param[in] outputs The vertex output data.
|
||||
* \param[in] location The output varying location.
|
||||
* \param[in] component The requested component.
|
||||
* \return The vertex output index.
|
||||
*/
|
||||
size_t rogue_output_index_vs(struct rogue_vertex_outputs *outputs,
|
||||
gl_varying_slot location,
|
||||
size_t component)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (location == VARYING_SLOT_POS) {
|
||||
/* Always at location 0. */
|
||||
assert(outputs->base[0] == 0);
|
||||
i = 0;
|
||||
} else if ((location >= VARYING_SLOT_VAR0) &&
|
||||
(location <= VARYING_SLOT_VAR31)) {
|
||||
i = (location - VARYING_SLOT_VAR0) + 1;
|
||||
} else {
|
||||
unreachable("Unsupported vertex output type.");
|
||||
}
|
||||
|
||||
assert(i < outputs->num_output_vars);
|
||||
assert(component < outputs->components[i]);
|
||||
assert(outputs->base[i] != ~0);
|
||||
|
||||
return outputs->base[i] + component;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the allocated shared register index for a given UBO offset.
|
||||
*
|
||||
* \param[in] ubo_data The UBO data.
|
||||
* \param[in] desc_set The UBO descriptor set.
|
||||
* \param[in] binding The UBO binding.
|
||||
* \param[in] offset_bytes The UBO offset in bytes.
|
||||
* \return The UBO offset shared register index.
|
||||
*/
|
||||
size_t rogue_ubo_reg(struct rogue_ubo_data *ubo_data,
|
||||
size_t desc_set,
|
||||
size_t binding,
|
||||
size_t offset_bytes)
|
||||
{
|
||||
size_t ubo_index = ~0;
|
||||
size_t offset_regs;
|
||||
|
||||
/* Find UBO located at (desc_set, binding). */
|
||||
for (size_t u = 0; u < ubo_data->num_ubo_entries; ++u) {
|
||||
if (ubo_data->dest[u] == ~0)
|
||||
continue;
|
||||
|
||||
if (ubo_data->desc_set[u] != desc_set || ubo_data->binding[u] != binding)
|
||||
continue;
|
||||
|
||||
ubo_index = u;
|
||||
break;
|
||||
}
|
||||
|
||||
assert(ubo_index != ~0);
|
||||
|
||||
assert(!(offset_bytes % ROGUE_REG_SIZE_BYTES));
|
||||
offset_regs = offset_bytes / ROGUE_REG_SIZE_BYTES;
|
||||
|
||||
return ubo_data->dest[ubo_index] + offset_regs;
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* 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 ROGUE_BUILD_DATA_H
|
||||
#define ROGUE_BUILD_DATA_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "compiler/shader_enums.h"
|
||||
#include "nir/nir.h"
|
||||
#include "rogue.h"
|
||||
|
||||
/* Max number of I/O varying variables.
|
||||
* Fragment shader: MAX_VARYING + 1 (W coefficient).
|
||||
* Vertex shader: MAX_VARYING + 1 (position slot).
|
||||
*/
|
||||
#define ROGUE_MAX_IO_VARYING_VARS (MAX_VARYING + 1)
|
||||
|
||||
/* VERT_ATTRIB_GENERIC0-15 */
|
||||
#define ROGUE_MAX_IO_ATTRIB_VARS 16
|
||||
|
||||
/* Max buffers entries that can be used. */
|
||||
/* TODO: Currently UBOs are the only supported buffers. */
|
||||
#define ROGUE_MAX_BUFFERS 24
|
||||
|
||||
struct rogue_compiler;
|
||||
struct rogue_shader;
|
||||
struct rogue_shader_binary;
|
||||
|
||||
/**
|
||||
* \brief UBO data.
|
||||
*/
|
||||
struct rogue_ubo_data {
|
||||
size_t num_ubo_entries;
|
||||
size_t desc_set[ROGUE_MAX_BUFFERS];
|
||||
size_t binding[ROGUE_MAX_BUFFERS];
|
||||
size_t dest[ROGUE_MAX_BUFFERS];
|
||||
size_t size[ROGUE_MAX_BUFFERS];
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Per-stage common build data.
|
||||
*/
|
||||
struct rogue_common_build_data {
|
||||
size_t temps;
|
||||
size_t internals;
|
||||
size_t coeffs;
|
||||
size_t shareds;
|
||||
|
||||
struct rogue_ubo_data ubo_data;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Arguments for the FPU iterator(s)
|
||||
* (produces varyings for the fragment shader).
|
||||
*/
|
||||
struct rogue_iterator_args {
|
||||
uint32_t num_fpu_iterators;
|
||||
uint32_t fpu_iterators[ROGUE_MAX_IO_VARYING_VARS];
|
||||
uint32_t destination[ROGUE_MAX_IO_VARYING_VARS];
|
||||
size_t base[ROGUE_MAX_IO_VARYING_VARS];
|
||||
size_t components[ROGUE_MAX_IO_VARYING_VARS];
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Vertex input register allocations.
|
||||
*/
|
||||
struct rogue_vertex_inputs {
|
||||
size_t num_input_vars;
|
||||
size_t base[ROGUE_MAX_IO_ATTRIB_VARS];
|
||||
size_t components[ROGUE_MAX_IO_ATTRIB_VARS];
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Vertex output allocations.
|
||||
*/
|
||||
struct rogue_vertex_outputs {
|
||||
size_t num_output_vars;
|
||||
size_t base[ROGUE_MAX_IO_VARYING_VARS];
|
||||
size_t components[ROGUE_MAX_IO_VARYING_VARS];
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Stage-specific build data.
|
||||
*/
|
||||
struct rogue_build_data {
|
||||
struct rogue_fs_build_data {
|
||||
struct rogue_iterator_args iterator_args;
|
||||
enum rogue_msaa_mode msaa_mode;
|
||||
bool phas; /* Indicates the presence of PHAS instruction. */
|
||||
} fs;
|
||||
struct rogue_vs_build_data {
|
||||
struct rogue_vertex_inputs inputs;
|
||||
size_t num_vertex_input_regs; /* Final number of inputs. */
|
||||
|
||||
struct rogue_vertex_outputs outputs;
|
||||
size_t num_vertex_outputs; /* Final number of outputs. */
|
||||
|
||||
size_t num_varyings; /* Final number of varyings. */
|
||||
} vs;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Shared multi-stage build context.
|
||||
*/
|
||||
struct rogue_build_ctx {
|
||||
struct rogue_compiler *compiler;
|
||||
|
||||
/* Shaders in various stages of compilations. */
|
||||
nir_shader *nir[MESA_SHADER_FRAGMENT + 1];
|
||||
struct rogue_shader *rogue[MESA_SHADER_FRAGMENT + 1];
|
||||
struct rogue_shader_binary *binary[MESA_SHADER_FRAGMENT + 1];
|
||||
|
||||
struct rogue_common_build_data common_data[MESA_SHADER_FRAGMENT + 1];
|
||||
struct rogue_build_data stage_data;
|
||||
};
|
||||
|
||||
PUBLIC
|
||||
struct rogue_build_ctx *
|
||||
rogue_create_build_context(struct rogue_compiler *compiler);
|
||||
|
||||
PUBLIC
|
||||
bool rogue_collect_io_data(struct rogue_build_ctx *ctx, nir_shader *nir);
|
||||
|
||||
PUBLIC
|
||||
size_t rogue_coeff_index_fs(struct rogue_iterator_args *args,
|
||||
gl_varying_slot location,
|
||||
size_t component);
|
||||
|
||||
PUBLIC
|
||||
size_t rogue_output_index_vs(struct rogue_vertex_outputs *outputs,
|
||||
gl_varying_slot location,
|
||||
size_t component);
|
||||
|
||||
PUBLIC
|
||||
size_t rogue_ubo_reg(struct rogue_ubo_data *ubo_data,
|
||||
size_t desc_set,
|
||||
size_t binding,
|
||||
size_t offset_bytes);
|
||||
|
||||
#endif /* ROGUE_BUILD_DATA_H */
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* 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 <stddef.h>
|
||||
|
||||
#include "compiler/glsl_types.h"
|
||||
#include "rogue_compiler.h"
|
||||
#include "util/ralloc.h"
|
||||
|
||||
/**
|
||||
* \file rogue_compiler.c
|
||||
*
|
||||
* \brief Contains the Rogue compiler interface.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Creates and sets up a Rogue compiler context.
|
||||
*
|
||||
* \param[in] dev_info Device info pointer.
|
||||
* \return A pointer to the new compiler context, or NULL on failure.
|
||||
*/
|
||||
struct rogue_compiler *
|
||||
rogue_compiler_create(const struct pvr_device_info *dev_info)
|
||||
{
|
||||
struct rogue_compiler *compiler;
|
||||
|
||||
compiler = rzalloc_size(NULL, sizeof(*compiler));
|
||||
if (!compiler)
|
||||
return NULL;
|
||||
|
||||
compiler->dev_info = dev_info;
|
||||
|
||||
/* TODO: Additional compiler setup (allocators? error message output
|
||||
* location?).
|
||||
*/
|
||||
|
||||
glsl_type_singleton_init_or_ref();
|
||||
|
||||
return compiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Destroys and frees a compiler context.
|
||||
*
|
||||
* \param[in] compiler The compiler context.
|
||||
*/
|
||||
void rogue_compiler_destroy(struct rogue_compiler *compiler)
|
||||
{
|
||||
glsl_type_singleton_decref();
|
||||
|
||||
ralloc_free(compiler);
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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 ROGUE_COMPILER_H
|
||||
#define ROGUE_COMPILER_H
|
||||
|
||||
#include "util/macros.h"
|
||||
|
||||
struct pvr_device_info;
|
||||
|
||||
/**
|
||||
* \brief Compiler context.
|
||||
*/
|
||||
struct rogue_compiler {
|
||||
const struct pvr_device_info *dev_info;
|
||||
};
|
||||
|
||||
PUBLIC
|
||||
struct rogue_compiler *
|
||||
rogue_compiler_create(const struct pvr_device_info *dev_info);
|
||||
|
||||
PUBLIC
|
||||
void rogue_compiler_destroy(struct rogue_compiler *compiler);
|
||||
|
||||
#endif /* ROGUE_COMPILER_H */
|
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* 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 <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "rogue_constreg.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
/**
|
||||
* \file rogue_constreg.c
|
||||
*
|
||||
* \brief Contains functions to find and allocate constant register values.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Mapping of constant register values and their indices.
|
||||
*/
|
||||
struct rogue_constreg {
|
||||
uint32_t value;
|
||||
size_t index;
|
||||
};
|
||||
|
||||
#define CONSTREG(VALUE, INDEX) \
|
||||
{ \
|
||||
.value = (VALUE), .index = (INDEX), \
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Constant register values (sorted for bsearch).
|
||||
*/
|
||||
static const struct rogue_constreg const_regs[] = {
|
||||
CONSTREG(0x00000000U, 0U), /* 0 (INT32) / 0.0 (Float) */
|
||||
CONSTREG(0x00000001U, 1U), /* 1 (INT32) */
|
||||
CONSTREG(0x00000002U, 2U), /* 2 (INT32) */
|
||||
CONSTREG(0x00000003U, 3U), /* 3 (INT32) */
|
||||
CONSTREG(0x00000004U, 4U), /* 4 (INT32) */
|
||||
CONSTREG(0x00000005U, 5U), /* 5 (INT32) */
|
||||
CONSTREG(0x00000006U, 6U), /* 6 (INT32) */
|
||||
CONSTREG(0x00000007U, 7U), /* 7 (INT32) */
|
||||
CONSTREG(0x00000008U, 8U), /* 8 (INT32) */
|
||||
CONSTREG(0x00000009U, 9U), /* 9 (INT32) */
|
||||
CONSTREG(0x0000000aU, 10U), /* 10 (INT32) */
|
||||
CONSTREG(0x0000000bU, 11U), /* 11 (INT32) */
|
||||
CONSTREG(0x0000000cU, 12U), /* 12 (INT32) */
|
||||
CONSTREG(0x0000000dU, 13U), /* 13 (INT32) */
|
||||
CONSTREG(0x0000000eU, 14U), /* 14 (INT32) */
|
||||
CONSTREG(0x0000000fU, 15U), /* 15 (INT32) */
|
||||
CONSTREG(0x00000010U, 16U), /* 16 (INT32) */
|
||||
CONSTREG(0x00000011U, 17U), /* 17 (INT32) */
|
||||
CONSTREG(0x00000012U, 18U), /* 18 (INT32) */
|
||||
CONSTREG(0x00000013U, 19U), /* 19 (INT32) */
|
||||
CONSTREG(0x00000014U, 20U), /* 20 (INT32) */
|
||||
CONSTREG(0x00000015U, 21U), /* 21 (INT32) */
|
||||
CONSTREG(0x00000016U, 22U), /* 22 (INT32) */
|
||||
CONSTREG(0x00000017U, 23U), /* 23 (INT32) */
|
||||
CONSTREG(0x00000018U, 24U), /* 24 (INT32) */
|
||||
CONSTREG(0x00000019U, 25U), /* 25 (INT32) */
|
||||
CONSTREG(0x0000001aU, 26U), /* 26 (INT32) */
|
||||
CONSTREG(0x0000001bU, 27U), /* 27 (INT32) */
|
||||
CONSTREG(0x0000001cU, 28U), /* 28 (INT32) */
|
||||
CONSTREG(0x0000001dU, 29U), /* 29 (INT32) */
|
||||
CONSTREG(0x0000001eU, 30U), /* 30 (INT32) */
|
||||
CONSTREG(0x0000001fU, 31U), /* 31 (INT32) */
|
||||
CONSTREG(0x0000007fU, 147U), /* 127 (INT32) */
|
||||
|
||||
CONSTREG(0x37800000U, 134U), /* 1.0f/65536f */
|
||||
CONSTREG(0x38000000U, 135U), /* 1.0f/32768f */
|
||||
CONSTREG(0x38800000U, 88U), /* float(2^-14) */
|
||||
CONSTREG(0x39000000U, 87U), /* float(2^-13) */
|
||||
CONSTREG(0x39800000U, 86U), /* float(2^-12) */
|
||||
CONSTREG(0x3a000000U, 85U), /* float(2^-11) */
|
||||
CONSTREG(0x3a800000U, 84U), /* float(2^-10) */
|
||||
CONSTREG(0x3b000000U, 83U), /* float(2^-9) */
|
||||
CONSTREG(0x3b4d2e1cU, 136U), /* 0.0031308f */
|
||||
CONSTREG(0x3b800000U, 82U), /* float(2^-8) */
|
||||
CONSTREG(0x3c000000U, 81U), /* float(2^-7) */
|
||||
CONSTREG(0x3c800000U, 80U), /* float(2^-6) */
|
||||
CONSTREG(0x3d000000U, 79U), /* float(2^-5) */
|
||||
CONSTREG(0x3d25aee6U, 156U), /* 0.04045f */
|
||||
CONSTREG(0x3d6147aeU, 140U), /* 0.055f */
|
||||
CONSTREG(0x3d800000U, 78U), /* float(2^-4) */
|
||||
CONSTREG(0x3d9e8391U, 157U), /* 1.0f/12.92f */
|
||||
CONSTREG(0x3e000000U, 77U), /* float(2^-3) */
|
||||
CONSTREG(0x3e2aaaabU, 153U), /* 1/6 */
|
||||
CONSTREG(0x3e800000U, 76U), /* float(2^-2) */
|
||||
CONSTREG(0x3e9a209bU, 145U), /* Log_10(2) */
|
||||
CONSTREG(0x3ea2f983U, 128U), /* Float 1/PI */
|
||||
CONSTREG(0x3eaaaaabU, 152U), /* 1/3 */
|
||||
CONSTREG(0x3ebc5ab2U, 90U), /* 1/e */
|
||||
CONSTREG(0x3ed55555U, 138U), /* 1.0f/2.4f */
|
||||
CONSTREG(0x3f000000U, 75U), /* float(2^-1) */
|
||||
CONSTREG(0x3f22f983U, 129U), /* Float 2/PI */
|
||||
CONSTREG(0x3f317218U, 146U), /* Log_e(2) */
|
||||
CONSTREG(0x3f3504f3U, 92U), /* Float 1/SQRT(2) */
|
||||
CONSTREG(0x3f490fdbU, 93U), /* Float PI/4 */
|
||||
CONSTREG(0x3f72a76fU, 158U), /* 1.0f/1.055f */
|
||||
CONSTREG(0x3f800000U, 64U), /* 1.0f */
|
||||
CONSTREG(0x3f860a92U, 151U), /* Pi/3 */
|
||||
CONSTREG(0x3f870a3dU, 139U), /* 1.055f */
|
||||
CONSTREG(0x3fa2f983U, 130U), /* Float 4/PI */
|
||||
CONSTREG(0x3fb504f3U, 91U), /* Float SQRT(2) */
|
||||
CONSTREG(0x3fb8aa3bU, 155U), /* Log_2(e) */
|
||||
CONSTREG(0x3fc90fdbU, 94U), /* Float PI/2 */
|
||||
CONSTREG(0x40000000U, 65U), /* float(2^1) */
|
||||
CONSTREG(0x4019999aU, 159U), /* 2.4f */
|
||||
CONSTREG(0x402df854U, 89U), /* e */
|
||||
CONSTREG(0x40490fdbU, 95U), /* Float PI */
|
||||
CONSTREG(0x40549a78U, 154U), /* Log_2(10) */
|
||||
CONSTREG(0x40800000U, 66U), /* float(2^2) */
|
||||
CONSTREG(0x40c90fdbU, 131U), /* Float 2*PI */
|
||||
CONSTREG(0x41000000U, 67U), /* float(2^3) */
|
||||
CONSTREG(0x41490fdbU, 132U), /* Float 4*PI */
|
||||
CONSTREG(0x414eb852U, 137U), /* 12.92f */
|
||||
CONSTREG(0x41800000U, 68U), /* float(2^4) */
|
||||
CONSTREG(0x41c90fdbU, 133U), /* Float 8*PI */
|
||||
CONSTREG(0x42000000U, 69U), /* float(2^5) */
|
||||
CONSTREG(0x42800000U, 70U), /* float(2^6) */
|
||||
CONSTREG(0x43000000U, 71U), /* float(2^7) */
|
||||
CONSTREG(0x43800000U, 72U), /* float(2^8) */
|
||||
CONSTREG(0x44000000U, 73U), /* float(2^9) */
|
||||
CONSTREG(0x44800000U, 74U), /* float(2^10) */
|
||||
CONSTREG(0x4b000000U, 149U), /* 2^23 */
|
||||
CONSTREG(0x4b800000U, 150U), /* 2^24 */
|
||||
CONSTREG(0x7f7fffffU, 148U), /* FLT_MAX */
|
||||
CONSTREG(0x7f800000U, 142U), /* Infinity */
|
||||
CONSTREG(0x7fff7fffU, 144U), /* ARGB1555 mask */
|
||||
CONSTREG(0x80000000U, 141U), /* -0.0f */
|
||||
CONSTREG(0xffffffffU, 143U), /* -1 */
|
||||
};
|
||||
|
||||
#undef CONSTREG
|
||||
|
||||
/**
|
||||
* \brief Comparison function for bsearch() to support struct rogue_constreg.
|
||||
*
|
||||
* \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 rogue_constreg *l = lhs;
|
||||
const struct rogue_constreg *r = rhs;
|
||||
|
||||
if (l->value < r->value)
|
||||
return -1;
|
||||
else if (l->value > r->value)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Determines whether a given integer value exists in a constant
|
||||
* register.
|
||||
*
|
||||
* \param[in] value The value required.
|
||||
* \return The index of the constant register containing the value, or
|
||||
* ROGUE_NO_CONST_REG if the value is not found.
|
||||
*/
|
||||
size_t rogue_constreg_lookup(uint32_t value)
|
||||
{
|
||||
struct rogue_constreg constreg_target = {
|
||||
.value = value,
|
||||
};
|
||||
const struct rogue_constreg *constreg;
|
||||
|
||||
constreg = bsearch(&constreg_target,
|
||||
const_regs,
|
||||
ARRAY_SIZE(const_regs),
|
||||
sizeof(struct rogue_constreg),
|
||||
constreg_cmp);
|
||||
if (!constreg)
|
||||
return ROGUE_NO_CONST_REG;
|
||||
|
||||
return constreg->index;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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 ROGUE_CONSTREGS_H
|
||||
#define ROGUE_CONSTREGS_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util/macros.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
#define ROGUE_NO_CONST_REG SIZE_MAX
|
||||
|
||||
PUBLIC
|
||||
size_t rogue_constreg_lookup(uint32_t value);
|
||||
|
||||
/**
|
||||
* \brief Determines whether a given floating point value exists in a constant
|
||||
* register.
|
||||
*
|
||||
* \param[in] value The value required.
|
||||
* \return The index of the constant register containing the value, or
|
||||
* ROGUE_NO_CONST_REG if the value is not found.
|
||||
*/
|
||||
static inline size_t rogue_constreg_lookup_float(float value)
|
||||
{
|
||||
return rogue_constreg_lookup(fui(value));
|
||||
}
|
||||
|
||||
#endif /* ROGUE_CONSTREGS_H */
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* 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 <stdint.h>
|
||||
|
||||
#include "rogue_dump.h"
|
||||
#include "rogue_shader.h"
|
||||
#include "rogue_util.h"
|
||||
#include "util/bitscan.h"
|
||||
|
||||
/**
|
||||
* \file rogue_dump.c
|
||||
*
|
||||
* \brief Contains functions to dump Rogue data structures into a textual
|
||||
* format.
|
||||
*/
|
||||
|
||||
static const char *const rogue_operand_string[ROGUE_OPERAND_TYPE_COUNT] = {
|
||||
[ROGUE_OPERAND_TYPE_REG_TEMP] = "r",
|
||||
[ROGUE_OPERAND_TYPE_REG_COEFF] = "cf",
|
||||
[ROGUE_OPERAND_TYPE_REG_CONST] = "c",
|
||||
[ROGUE_OPERAND_TYPE_REG_SHARED] = "sh",
|
||||
[ROGUE_OPERAND_TYPE_REG_PIXEL_OUT] = "po",
|
||||
[ROGUE_OPERAND_TYPE_REG_VERTEX_IN] = "vi",
|
||||
[ROGUE_OPERAND_TYPE_REG_INTERNAL] = "i",
|
||||
[ROGUE_OPERAND_TYPE_IMMEDIATE] = "#",
|
||||
[ROGUE_OPERAND_TYPE_DRC] = "drc",
|
||||
[ROGUE_OPERAND_TYPE_VREG] = "V",
|
||||
};
|
||||
|
||||
static const char *const rogue_opcode_string[ROGUE_OP_COUNT] = {
|
||||
[ROGUE_OP_NOP] = "nop",
|
||||
[ROGUE_OP_END_FRAG] = "end.frag",
|
||||
[ROGUE_OP_END_VERT] = "end.vert",
|
||||
[ROGUE_OP_WDF] = "wdf",
|
||||
[ROGUE_OP_PIX_ITER_W] = "pixiter.w",
|
||||
[ROGUE_OP_MAX] = "max",
|
||||
[ROGUE_OP_MIN] = "min",
|
||||
[ROGUE_OP_PACK_U8888] = "pack.u8888",
|
||||
[ROGUE_OP_MOV] = "mov",
|
||||
[ROGUE_OP_MOV_IMM] = "mov.imm",
|
||||
[ROGUE_OP_FMA] = "fma",
|
||||
[ROGUE_OP_MUL] = "mul",
|
||||
[ROGUE_OP_VTXOUT] = "vtxout",
|
||||
};
|
||||
|
||||
static const char *const rogue_instr_flag_string[ROGUE_INSTR_FLAG_COUNT] = {
|
||||
[ROGUE_INSTR_FLAG_SAT] = "sat",
|
||||
[ROGUE_INSTR_FLAG_LP] = "lp",
|
||||
[ROGUE_INSTR_FLAG_OLCHK] = "olchk",
|
||||
};
|
||||
|
||||
static const char rogue_vector_string[4] = {
|
||||
'x',
|
||||
'y',
|
||||
'z',
|
||||
'w',
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Dumps an operand as text to a file pointer.
|
||||
*
|
||||
* \param[in] operand The operand.
|
||||
* \param[in] fp The file pointer.
|
||||
* \return true if successful, otherwise false.
|
||||
*/
|
||||
bool rogue_dump_operand(const struct rogue_operand *operand, FILE *fp)
|
||||
{
|
||||
ASSERT_OPERAND_RANGE(operand->type);
|
||||
|
||||
fprintf(fp, "%s", rogue_operand_string[operand->type]);
|
||||
|
||||
if (operand->type == ROGUE_OPERAND_TYPE_IMMEDIATE)
|
||||
fprintf(fp, "%" PRIu64, operand->immediate.value);
|
||||
else if (operand->type == ROGUE_OPERAND_TYPE_DRC)
|
||||
fprintf(fp, "%zu", operand->drc.number);
|
||||
else if (rogue_check_bitset(rogue_onehot(operand->type), ROGUE_MASK_ANY_REG))
|
||||
fprintf(fp, "%zu", operand->reg.number);
|
||||
else if (operand->type == ROGUE_OPERAND_TYPE_VREG) {
|
||||
fprintf(fp, "%zu", operand->vreg.number);
|
||||
if (operand->vreg.is_vector)
|
||||
fprintf(fp, ".%c", rogue_vector_string[operand->vreg.component]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Dumps an instruction as text to a file pointer.
|
||||
*
|
||||
* \param[in] instr The instruction.
|
||||
* \param[in] fp The file pointer.
|
||||
* \return true if successful, otherwise false.
|
||||
*/
|
||||
bool rogue_dump_instr(const struct rogue_instr *instr, FILE *fp)
|
||||
{
|
||||
uint64_t flags = 0U;
|
||||
|
||||
ASSERT_OPCODE_RANGE(instr->opcode);
|
||||
|
||||
flags = instr->flags;
|
||||
|
||||
fprintf(fp, "%s", rogue_opcode_string[instr->opcode]);
|
||||
|
||||
/* Iterate over each flag bit and print its string form. */
|
||||
while (flags) {
|
||||
uint64_t flag = u_bit_scan64(&flags);
|
||||
ASSERT_INSTR_FLAG_RANGE(flag);
|
||||
fprintf(fp, ".%s", rogue_instr_flag_string[flag]);
|
||||
}
|
||||
|
||||
if (instr->num_operands)
|
||||
fprintf(fp, " ");
|
||||
|
||||
/* Dump each operand. */
|
||||
for (size_t u = 0U; u < instr->num_operands; ++u) {
|
||||
CHECKF(rogue_dump_operand(&instr->operands[u], fp),
|
||||
"Failed to dump operand.");
|
||||
if (u < (instr->num_operands - 1))
|
||||
fprintf(fp, ", ");
|
||||
}
|
||||
|
||||
fprintf(fp, ";");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Dumps a shader as text to a file pointer.
|
||||
*
|
||||
* \param[in] shader The shader.
|
||||
* \param[in] fp The file pointer.
|
||||
* \return true if successful, otherwise false.
|
||||
*/
|
||||
bool rogue_dump_shader(const struct rogue_shader *shader, FILE *fp)
|
||||
{
|
||||
/* Dump the shader stage. */
|
||||
fprintf(fp, "# %s shader\n", _mesa_shader_stage_to_string(shader->stage));
|
||||
|
||||
/* Dump each instruction. */
|
||||
foreach_instr (instr, &shader->instr_list) {
|
||||
CHECKF(rogue_dump_instr(instr, fp), "Failed to dump instruction.");
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
|
||||
return true;
|
||||
}
|
|
@ -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 ROGUE_DUMP_H
|
||||
#define ROGUE_DUMP_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "rogue_instr.h"
|
||||
#include "rogue_operand.h"
|
||||
#include "rogue_shader.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
PUBLIC
|
||||
bool rogue_dump_operand(const struct rogue_operand *operand, FILE *fp);
|
||||
|
||||
PUBLIC
|
||||
bool rogue_dump_instr(const struct rogue_instr *instr, FILE *fp);
|
||||
|
||||
PUBLIC
|
||||
bool rogue_dump_shader(const struct rogue_shader *shader, FILE *fp);
|
||||
|
||||
#endif /* ROGUE_DUMP_H */
|
|
@ -0,0 +1,851 @@
|
|||
/*
|
||||
* 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 <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "hwdef/rogue_hw_defs.h"
|
||||
#include "rogue_encode.h"
|
||||
#include "rogue_encoders.h"
|
||||
#include "rogue_operand.h"
|
||||
#include "rogue_shader.h"
|
||||
#include "rogue_util.h"
|
||||
#include "util/bitscan.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
static size_t rogue_encode_reg_bank(const struct rogue_operand *operand)
|
||||
{
|
||||
switch (operand->type) {
|
||||
case ROGUE_OPERAND_TYPE_REG_INTERNAL:
|
||||
case ROGUE_OPERAND_TYPE_REG_PIXEL_OUT:
|
||||
case ROGUE_OPERAND_TYPE_REG_CONST:
|
||||
return 0;
|
||||
case ROGUE_OPERAND_TYPE_REG_TEMP:
|
||||
return 1;
|
||||
case ROGUE_OPERAND_TYPE_REG_VERTEX_IN:
|
||||
return 2;
|
||||
case ROGUE_OPERAND_TYPE_REG_COEFF:
|
||||
return 3;
|
||||
case ROGUE_OPERAND_TYPE_REG_SHARED:
|
||||
return 4;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
unreachable("Unimplemented register bank.");
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Field mapping type.
|
||||
*/
|
||||
enum rogue_map_type {
|
||||
ROGUE_MAP_TYPE_INSTR_FLAG = 0,
|
||||
ROGUE_MAP_TYPE_OPERAND_FLAG,
|
||||
ROGUE_MAP_TYPE_OPERAND,
|
||||
|
||||
ROGUE_MAP_TYPE_COUNT,
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Field mapping rule description.
|
||||
*/
|
||||
struct rogue_field_mapping {
|
||||
/* Type of mapping being performed. */
|
||||
enum rogue_map_type type;
|
||||
|
||||
/* Index of the source operand/flag being mapped. */
|
||||
size_t index;
|
||||
|
||||
/* List of ranges to perform mapping. */
|
||||
struct rogue_rangelist rangelist;
|
||||
|
||||
/* Function used to encode the input into the value to be mapped. */
|
||||
field_encoder_t encoder_fn;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Instruction encoding rule description.
|
||||
*/
|
||||
struct rogue_instr_encoding {
|
||||
/* Number of bytes making up the base mask. */
|
||||
size_t num_bytes;
|
||||
/* Base mask bytes. */
|
||||
uint8_t *bytes;
|
||||
|
||||
/* Number of field mappings for this instruction. */
|
||||
size_t num_mappings;
|
||||
/* Field mappings. */
|
||||
struct rogue_field_mapping *mappings;
|
||||
};
|
||||
|
||||
static const
|
||||
struct rogue_instr_encoding instr_encodings[ROGUE_OP_COUNT] = {
|
||||
[ROGUE_OP_NOP] = {
|
||||
.num_bytes = 8,
|
||||
.bytes = (uint8_t []) { 0x04, 0x80, 0x6e, 0x00, 0xf2, 0xff, 0xff, 0xff },
|
||||
},
|
||||
|
||||
[ROGUE_OP_END_FRAG] = {
|
||||
.num_bytes = 8,
|
||||
.bytes = (uint8_t []) { 0x04, 0x80, 0xee, 0x00, 0xf2, 0xff, 0xff, 0xff },
|
||||
},
|
||||
|
||||
[ROGUE_OP_END_VERT] = {
|
||||
.num_bytes = 8,
|
||||
.bytes = (uint8_t []) { 0x44, 0xa0, 0x80, 0x05, 0x00, 0x00, 0x00, 0xff },
|
||||
},
|
||||
|
||||
[ROGUE_OP_WDF] = {
|
||||
.num_bytes = 8,
|
||||
.bytes = (uint8_t []) { 0x04, 0x80, 0x6a, 0xff, 0xf2, 0xff, 0xff, 0xff },
|
||||
.num_mappings = 1,
|
||||
.mappings = (struct rogue_field_mapping []) {
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 0,
|
||||
.rangelist = {
|
||||
.num_ranges = 1,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 47, .num = 1, },
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_drc,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
[ROGUE_OP_PIX_ITER_W] = {
|
||||
.num_bytes = 16,
|
||||
.bytes = (uint8_t []) { 0x48, 0x20, 0xb0, 0x01, 0x80, 0x40, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff, 0xf1, 0xff },
|
||||
.num_mappings = 6,
|
||||
.mappings = (struct rogue_field_mapping []) {
|
||||
/* Instruction flag mappings. */
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_INSTR_FLAG,
|
||||
.index = ROGUE_INSTR_FLAG_SAT,
|
||||
.rangelist = {
|
||||
.num_ranges = 1,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 100, .num = 1, },
|
||||
},
|
||||
},
|
||||
.encoder_fn = NULL,
|
||||
},
|
||||
/* Operand mappings. */
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 0,
|
||||
.rangelist = {
|
||||
.num_ranges = 5,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 43, .num = 2, }, /* SB3(2..1) */
|
||||
{ .start = 54, .num = 1, }, /* SB3(0) */
|
||||
{ .start = 34, .num = 3, }, /* S3(10..8) */
|
||||
{ .start = 41, .num = 2, }, /* S3(7..6) */
|
||||
{ .start = 53, .num = 6, }, /* S3(5..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_3_11,
|
||||
},
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 1,
|
||||
.rangelist = {
|
||||
.num_ranges = 1,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 59, .num = 1, },
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_drc,
|
||||
},
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 2,
|
||||
.rangelist = {
|
||||
.num_ranges = 6,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 59, .num = 1, }, /* SB0(2) */
|
||||
{ .start = 76, .num = 1, }, /* SB0(1) */
|
||||
{ .start = 94, .num = 1, }, /* SB0(0) */
|
||||
{ .start = 57, .num = 1, }, /* S0(7) */
|
||||
{ .start = 74, .num = 1, }, /* S0(6) */
|
||||
{ .start = 93, .num = 6, }, /* S0(5..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_3_8,
|
||||
},
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 3,
|
||||
.rangelist = {
|
||||
.num_ranges = 4,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 63, .num = 1, }, /* SB2(2) */
|
||||
{ .start = 71, .num = 2, }, /* SB2(1..0) */
|
||||
{ .start = 62, .num = 2, }, /* S2(7..6) */
|
||||
{ .start = 69, .num = 6, }, /* S2(5..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_3_8,
|
||||
},
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 4,
|
||||
.rangelist = {
|
||||
.num_ranges = 1,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 99, .num = 4, },
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_ls_1_16,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
[ROGUE_OP_MAX] = {
|
||||
.num_bytes = 16,
|
||||
.bytes = (uint8_t []) { 0x68, 0x42, 0xd0, 0x3c, 0xfa, 0x10, 0x87, 0x80, 0xc0, 0x80, 0x10, 0x00, 0x32, 0x80, 0x00, 0xff },
|
||||
.num_mappings = 3,
|
||||
.mappings = (struct rogue_field_mapping []) {
|
||||
/* Operand mappings. */
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 0,
|
||||
.rangelist = {
|
||||
.num_ranges = 5,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 11, .num = 2, }, /* DBn(2..1) */
|
||||
{ .start = 22, .num = 1, }, /* DBn(0) */
|
||||
{ .start = 14, .num = 3, }, /* Dn(10..8) */
|
||||
{ .start = 9, .num = 2, }, /* Dn(7..6) */
|
||||
{ .start = 21, .num = 6, }, /* Dn(5..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_3_11,
|
||||
},
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 1,
|
||||
.rangelist = {
|
||||
.num_ranges = 7,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 43, .num = 1, }, /* SB0(2) */
|
||||
{ .start = 52, .num = 1, }, /* SB0(1) */
|
||||
{ .start = 70, .num = 1, }, /* SB0(0) */
|
||||
{ .start = 47, .num = 3, }, /* S0(10..8) */
|
||||
{ .start = 41, .num = 1, }, /* S0(7) */
|
||||
{ .start = 50, .num = 1, }, /* S0(6) */
|
||||
{ .start = 69, .num = 6, }, /* S0(5..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_3_11,
|
||||
},
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 2,
|
||||
.rangelist = {
|
||||
.num_ranges = 5,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 51, .num = 1, }, /* SB1(1) */
|
||||
{ .start = 61, .num = 1, }, /* SB1(0) */
|
||||
{ .start = 40, .num = 1, }, /* S1(7) */
|
||||
{ .start = 49, .num = 2, }, /* S1(6..5) */
|
||||
{ .start = 60, .num = 5, }, /* S1(4..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_2_8,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
[ROGUE_OP_MIN] = {
|
||||
.num_bytes = 16,
|
||||
.bytes = (uint8_t []) { 0x68, 0x42, 0xd0, 0x3c, 0xf0, 0x11, 0x87, 0x80, 0xc0, 0x80, 0x10, 0x00, 0x32, 0x80, 0x00, 0xff },
|
||||
.num_mappings = 3,
|
||||
.mappings = (struct rogue_field_mapping []) {
|
||||
/* Operand mappings. */
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 0,
|
||||
.rangelist = {
|
||||
.num_ranges = 5,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 11, .num = 2, }, /* DBn(2..1) */
|
||||
{ .start = 22, .num = 1, }, /* DBn(0) */
|
||||
{ .start = 14, .num = 3, }, /* Dn(10..8) */
|
||||
{ .start = 9, .num = 2, }, /* Dn(7..6) */
|
||||
{ .start = 21, .num = 6, }, /* Dn(5..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_3_11,
|
||||
},
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 1,
|
||||
.rangelist = {
|
||||
.num_ranges = 7,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 43, .num = 1, }, /* SB0(2) */
|
||||
{ .start = 52, .num = 1, }, /* SB0(1) */
|
||||
{ .start = 70, .num = 1, }, /* SB0(0) */
|
||||
{ .start = 47, .num = 3, }, /* S0(10..8) */
|
||||
{ .start = 41, .num = 1, }, /* S0(7) */
|
||||
{ .start = 50, .num = 1, }, /* S0(6) */
|
||||
{ .start = 69, .num = 6, }, /* S0(5..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_3_11,
|
||||
},
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 2,
|
||||
.rangelist = {
|
||||
.num_ranges = 5,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 51, .num = 1, }, /* SB1(1) */
|
||||
{ .start = 61, .num = 1, }, /* SB1(0) */
|
||||
{ .start = 40, .num = 1, }, /* S1(7) */
|
||||
{ .start = 49, .num = 2, }, /* S1(6..5) */
|
||||
{ .start = 60, .num = 5, }, /* S1(4..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_2_8,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
[ROGUE_OP_PACK_U8888] = {
|
||||
.num_bytes = 16,
|
||||
.bytes = (uint8_t []) { 0x58, 0x92, 0x06, 0x9c, 0x20, 0x80, 0x00, 0x00, 0x00, 0x2c, 0x80, 0x00, 0xf2, 0xff, 0xff, 0xff },
|
||||
.num_mappings = 2,
|
||||
.mappings = (struct rogue_field_mapping []) {
|
||||
/* Operand mappings. */
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 0,
|
||||
.rangelist = {
|
||||
.num_ranges = 5,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 35, .num = 2, }, /* DBn(2..1) */
|
||||
{ .start = 46, .num = 1, }, /* DBn(0) */
|
||||
{ .start = 38, .num = 3, }, /* Dn(10..8) */
|
||||
{ .start = 33, .num = 2, }, /* Dn(7..6) */
|
||||
{ .start = 45, .num = 6, }, /* Dn(5..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_3_11,
|
||||
},
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 1,
|
||||
.rangelist = {
|
||||
.num_ranges = 5,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 75, .num = 2, }, /* SB0(2..1) */
|
||||
{ .start = 86, .num = 1, }, /* SB0(0) */
|
||||
{ .start = 66, .num = 3, }, /* S0(10..8) */
|
||||
{ .start = 73, .num = 2, }, /* S0(7..6) */
|
||||
{ .start = 85, .num = 6, }, /* S0(5..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_3_11,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
[ROGUE_OP_MOV] = {
|
||||
.num_bytes = 16,
|
||||
.bytes = (uint8_t []) { 0x48, 0x42, 0xd0, 0x3f, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xf2, 0xff, 0xff, 0xff },
|
||||
.num_mappings = 3,
|
||||
.mappings = (struct rogue_field_mapping []) {
|
||||
/* Instruction flag mappings. */
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_INSTR_FLAG,
|
||||
.index = ROGUE_INSTR_FLAG_OLCHK,
|
||||
.rangelist = {
|
||||
.num_ranges = 1,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 115, .num = 1, },
|
||||
},
|
||||
},
|
||||
.encoder_fn = NULL,
|
||||
},
|
||||
/* Operand mappings. */
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 0,
|
||||
.rangelist = {
|
||||
.num_ranges = 5,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 35, .num = 2, }, /* DBn(2..1) */
|
||||
{ .start = 46, .num = 1, }, /* DBn(0) */
|
||||
{ .start = 38, .num = 3, }, /* Dn(10..8) */
|
||||
{ .start = 33, .num = 2, }, /* Dn(7..6) */
|
||||
{ .start = 45, .num = 6, }, /* Dn(5..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_3_11,
|
||||
},
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 1,
|
||||
.rangelist = {
|
||||
.num_ranges = 5,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 75, .num = 2, }, /* SB0(2..1) */
|
||||
{ .start = 86, .num = 1, }, /* SB0(0) */
|
||||
{ .start = 66, .num = 3, }, /* S0(10..8) */
|
||||
{ .start = 73, .num = 2, }, /* S0(7..6) */
|
||||
{ .start = 85, .num = 6, }, /* S0(5..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_3_11,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
[ROGUE_OP_MOV_IMM] = {
|
||||
.num_bytes = 16,
|
||||
.bytes = (uint8_t []) { 0x88, 0x92, 0x40, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xf2, 0xff, 0xff, 0xff },
|
||||
.num_mappings = 2,
|
||||
.mappings = (struct rogue_field_mapping []) {
|
||||
/* Operand mappings. */
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 0,
|
||||
.rangelist = {
|
||||
.num_ranges = 5,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 35, .num = 2, }, /* DBn(2..1) */
|
||||
{ .start = 46, .num = 1, }, /* DBn(0) */
|
||||
{ .start = 38, .num = 3, }, /* Dn(10..8) */
|
||||
{ .start = 33, .num = 2, }, /* Dn(7..6) */
|
||||
{ .start = 45, .num = 6, }, /* Dn(5..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_3_11,
|
||||
},
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 1,
|
||||
.rangelist = {
|
||||
.num_ranges = 4,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 71, .num = 8, }, /* imm(31:24) */
|
||||
{ .start = 79, .num = 8, }, /* imm(23:16) */
|
||||
{ .start = 87, .num = 8, }, /* imm(15:8) */
|
||||
{ .start = 95, .num = 8, }, /* imm(7:0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_imm,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
[ROGUE_OP_FMA] = {
|
||||
.num_bytes = 16,
|
||||
.bytes = (uint8_t []) { 0x28, 0x02, 0xd0, 0x00, 0x80, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xff, 0xf1, 0xff },
|
||||
.num_mappings = 6,
|
||||
.mappings = (struct rogue_field_mapping []) {
|
||||
/* Instruction flag mappings. */
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_INSTR_FLAG,
|
||||
.index = ROGUE_INSTR_FLAG_SAT,
|
||||
.rangelist = {
|
||||
.num_ranges = 1,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 104, .num = 1, },
|
||||
},
|
||||
},
|
||||
.encoder_fn = NULL,
|
||||
},
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_INSTR_FLAG,
|
||||
.index = ROGUE_INSTR_FLAG_LP,
|
||||
.rangelist = {
|
||||
.num_ranges = 1,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 100, .num = 1, },
|
||||
},
|
||||
},
|
||||
.encoder_fn = NULL,
|
||||
},
|
||||
/* Operand mappings. */
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 0,
|
||||
.rangelist = {
|
||||
.num_ranges = 5,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 27, .num = 2, }, /* DBn(2..1) */
|
||||
{ .start = 38, .num = 1, }, /* DBn(0) */
|
||||
{ .start = 30, .num = 3, }, /* Dn(10..8) */
|
||||
{ .start = 25, .num = 2, }, /* Dn(7..6) */
|
||||
{ .start = 37, .num = 6, }, /* Dn(5..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_3_11,
|
||||
},
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 1,
|
||||
.rangelist = {
|
||||
.num_ranges = 6,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 59, .num = 1, }, /* SB0(2) */
|
||||
{ .start = 76, .num = 1, }, /* SB0(1) */
|
||||
{ .start = 94, .num = 1, }, /* SB0(0) */
|
||||
{ .start = 57, .num = 1, }, /* S0(7) */
|
||||
{ .start = 74, .num = 1, }, /* S0(6) */
|
||||
{ .start = 93, .num = 6, }, /* S0(5..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_3_8,
|
||||
},
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 2,
|
||||
.rangelist = {
|
||||
.num_ranges = 5,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 75, .num = 1, }, /* SB1(1) */
|
||||
{ .start = 85, .num = 1, }, /* SB1(0) */
|
||||
{ .start = 56, .num = 1, }, /* S1(7) */
|
||||
{ .start = 73, .num = 2, }, /* S1(6..5) */
|
||||
{ .start = 84, .num = 5, }, /* S1(4..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_2_8,
|
||||
},
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 3,
|
||||
.rangelist = {
|
||||
.num_ranges = 4,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 63, .num = 1, }, /* SB2(2) */
|
||||
{ .start = 71, .num = 2, }, /* SB2(1..0) */
|
||||
{ .start = 62, .num = 2, }, /* S2(7..6) */
|
||||
{ .start = 69, .num = 6, }, /* S2(5..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_3_8,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
[ROGUE_OP_MUL] = {
|
||||
.num_bytes = 16,
|
||||
.bytes = (uint8_t []) { 0x28, 0x02, 0x40, 0x80, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0xff, 0xf2, 0xff, 0xff, 0xff },
|
||||
.num_mappings = 5,
|
||||
.mappings = (struct rogue_field_mapping []) {
|
||||
/* Instruction flag mappings. */
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_INSTR_FLAG,
|
||||
.index = ROGUE_INSTR_FLAG_SAT,
|
||||
.rangelist = {
|
||||
.num_ranges = 1,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 108, .num = 1, },
|
||||
},
|
||||
},
|
||||
.encoder_fn = NULL,
|
||||
},
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_INSTR_FLAG,
|
||||
.index = ROGUE_INSTR_FLAG_LP,
|
||||
.rangelist = {
|
||||
.num_ranges = 1,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 109, .num = 1, },
|
||||
},
|
||||
},
|
||||
.encoder_fn = NULL,
|
||||
},
|
||||
/* Operand mappings. */
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 0,
|
||||
.rangelist = {
|
||||
.num_ranges = 5,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 43, .num = 2, }, /* DBn(2..1) */
|
||||
{ .start = 54, .num = 1, }, /* DBn(0) */
|
||||
{ .start = 46, .num = 3, }, /* Dn(10..8) */
|
||||
{ .start = 41, .num = 2, }, /* Dn(7..6) */
|
||||
{ .start = 53, .num = 6, }, /* Dn(5..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_3_11,
|
||||
},
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 1,
|
||||
.rangelist = {
|
||||
.num_ranges = 7,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 75, .num = 1, }, /* SB0(2) */
|
||||
{ .start = 84, .num = 1, }, /* SB0(1) */
|
||||
{ .start = 102, .num = 1, }, /* SB0(0) */
|
||||
{ .start = 79, .num = 3, }, /* S0(10..8) */
|
||||
{ .start = 73, .num = 1, }, /* S0(7) */
|
||||
{ .start = 82, .num = 1, }, /* S0(6) */
|
||||
{ .start = 101, .num = 6, }, /* S0(5..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_3_11,
|
||||
},
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 2,
|
||||
.rangelist = {
|
||||
.num_ranges = 5,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 83, .num = 1, }, /* SB1(1) */
|
||||
{ .start = 93, .num = 1, }, /* SB1(0) */
|
||||
{ .start = 72, .num = 1, }, /* S1(7) */
|
||||
{ .start = 81, .num = 2, }, /* S1(6..5) */
|
||||
{ .start = 92, .num = 5, }, /* S1(4..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_2_8,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
[ROGUE_OP_VTXOUT] = {
|
||||
.num_bytes = 16,
|
||||
.bytes = (uint8_t []) { 0x48, 0x20, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x30, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff },
|
||||
.num_mappings = 2,
|
||||
.mappings = (struct rogue_field_mapping []) {
|
||||
/* Operand mappings. */
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 0,
|
||||
.rangelist = {
|
||||
.num_ranges = 1,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 103, .num = 8, }, /* Immediate address. */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_imm,
|
||||
},
|
||||
{
|
||||
.type = ROGUE_MAP_TYPE_OPERAND,
|
||||
.index = 1,
|
||||
.rangelist = {
|
||||
.num_ranges = 5,
|
||||
.ranges = (struct rogue_bitrange []) {
|
||||
{ .start = 83, .num = 2, }, /* SB0(2..1) */
|
||||
{ .start = 94, .num = 1, }, /* SB0(0) */
|
||||
{ .start = 74, .num = 3, }, /* S0(10..8) */
|
||||
{ .start = 81, .num = 2, }, /* S0(7..6) */
|
||||
{ .start = 93, .num = 6, }, /* S0(5..0) */
|
||||
},
|
||||
},
|
||||
.encoder_fn = &rogue_encoder_reg_3_11,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Applies a boolean flag encoding onto an instruction mask.
|
||||
*
|
||||
* \param[in] set Whether to set/unset the flag.
|
||||
* \param[in] mapping The field mapping to apply.
|
||||
* \param[in] instr_size The size of the instruction mask in bytes.
|
||||
* \param[in] instr_bytes The instruction mask.
|
||||
* \return true if encoding was successful.
|
||||
*/
|
||||
static bool rogue_encode_flag(bool set,
|
||||
const struct rogue_field_mapping *mapping,
|
||||
size_t instr_size,
|
||||
uint8_t instr_bytes[instr_size])
|
||||
{
|
||||
return rogue_distribute_value((uint64_t)set,
|
||||
&mapping->rangelist,
|
||||
instr_size,
|
||||
instr_bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Applies an operand encoding onto an instruction mask.
|
||||
*
|
||||
* \param[in] operand The operand to apply.
|
||||
* \param[in] mapping The field mapping to apply.
|
||||
* \param[in] instr_size The size of the instruction mask in bytes.
|
||||
* \param[in] instr_bytes The instruction mask.
|
||||
* \return true if encoding was successful.
|
||||
*/
|
||||
static bool rogue_encode_operand(const struct rogue_operand *operand,
|
||||
const struct rogue_field_mapping *mapping,
|
||||
size_t instr_size,
|
||||
uint8_t instr_bytes[instr_size])
|
||||
{
|
||||
uint64_t value = 0U;
|
||||
|
||||
switch (operand->type) {
|
||||
case ROGUE_OPERAND_TYPE_REG_PIXEL_OUT:
|
||||
CHECKF(
|
||||
mapping->encoder_fn(&value,
|
||||
2,
|
||||
rogue_encode_reg_bank(operand),
|
||||
operand->reg.number + ROGUE_PIXEL_OUT_REG_OFFSET),
|
||||
"Failed to encode pixel output register operand.");
|
||||
break;
|
||||
case ROGUE_OPERAND_TYPE_REG_INTERNAL:
|
||||
CHECKF(
|
||||
mapping->encoder_fn(&value,
|
||||
2,
|
||||
rogue_encode_reg_bank(operand),
|
||||
operand->reg.number + ROGUE_INTERNAL_REG_OFFSET),
|
||||
"Failed to encode internal register operand.");
|
||||
break;
|
||||
case ROGUE_OPERAND_TYPE_REG_TEMP:
|
||||
case ROGUE_OPERAND_TYPE_REG_COEFF:
|
||||
case ROGUE_OPERAND_TYPE_REG_CONST:
|
||||
case ROGUE_OPERAND_TYPE_REG_SHARED:
|
||||
case ROGUE_OPERAND_TYPE_REG_VERTEX_IN:
|
||||
CHECKF(mapping->encoder_fn(&value,
|
||||
2,
|
||||
rogue_encode_reg_bank(operand),
|
||||
operand->reg.number),
|
||||
"Failed to encode register operand.");
|
||||
break;
|
||||
|
||||
case ROGUE_OPERAND_TYPE_IMMEDIATE:
|
||||
CHECKF(mapping->encoder_fn(&value, 1, operand->immediate.value),
|
||||
"Failed to encode immediate operand.");
|
||||
break;
|
||||
|
||||
case ROGUE_OPERAND_TYPE_DRC:
|
||||
CHECKF(mapping->encoder_fn(&value, 1, (uint64_t)operand->drc.number),
|
||||
"Failed to encode DRC operand.");
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
CHECKF(rogue_distribute_value(value,
|
||||
&mapping->rangelist,
|
||||
instr_size,
|
||||
instr_bytes),
|
||||
"Failed to distribute value.");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Applies operand and flag encodings to the base instruction bytes, then
|
||||
* writes the result to file pointer "fp".
|
||||
*
|
||||
* \param[in] instr The instruction to be encoded.
|
||||
* \param[in] fp The file pointer.
|
||||
* \return true if encoding was successful.
|
||||
*/
|
||||
bool rogue_encode_instr(const struct rogue_instr *instr, FILE *fp)
|
||||
{
|
||||
const struct rogue_instr_encoding *instr_encoding;
|
||||
size_t instr_size;
|
||||
uint8_t instr_bytes[ROGUE_MAX_INSTR_BYTES];
|
||||
|
||||
ASSERT_OPCODE_RANGE(instr->opcode);
|
||||
|
||||
instr_encoding = &instr_encodings[instr->opcode];
|
||||
|
||||
/* Set up base instruction bytes. */
|
||||
instr_size = instr_encoding->num_bytes;
|
||||
assert(instr_size <= ARRAY_SIZE(instr_bytes));
|
||||
memcpy(instr_bytes, instr_encoding->bytes, instr_size);
|
||||
|
||||
/* Encode the operands and flags. */
|
||||
for (size_t u = 0U; u < instr_encoding->num_mappings; ++u) {
|
||||
const struct rogue_field_mapping *mapping = &instr_encoding->mappings[u];
|
||||
|
||||
switch (mapping->type) {
|
||||
case ROGUE_MAP_TYPE_INSTR_FLAG: {
|
||||
uint64_t flag = rogue_onehot(mapping->index);
|
||||
CHECKF(rogue_encode_flag(!!(instr->flags & flag),
|
||||
mapping,
|
||||
instr_size,
|
||||
instr_bytes),
|
||||
"Failed to encode instruction flag.");
|
||||
break;
|
||||
}
|
||||
|
||||
case ROGUE_MAP_TYPE_OPERAND_FLAG:
|
||||
return false;
|
||||
|
||||
case ROGUE_MAP_TYPE_OPERAND: {
|
||||
size_t operand_index = mapping->index;
|
||||
CHECKF(rogue_encode_operand(&instr->operands[operand_index],
|
||||
mapping,
|
||||
instr_size,
|
||||
instr_bytes),
|
||||
"Failed to encode instruction operand.");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
CHECKF(fwrite(instr_bytes, 1, instr_size, fp) == instr_size,
|
||||
"Failed to write encoded instruction bytes.");
|
||||
fflush(fp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Encodes each instruction in "shader", writing the output to "fp".
|
||||
*
|
||||
* \param[in] shader The shader to be encoded.
|
||||
* \param[in] fp The file pointer.
|
||||
* \return true if encoding was successful.
|
||||
*/
|
||||
bool rogue_encode_shader(const struct rogue_shader *shader, FILE *fp)
|
||||
{
|
||||
long bytes_written;
|
||||
|
||||
/* Encode each instruction. */
|
||||
foreach_instr (instr, &shader->instr_list)
|
||||
CHECKF(rogue_encode_instr(instr, fp), "Failed to encode instruction.");
|
||||
|
||||
/* Pad end of shader if required. */
|
||||
bytes_written = ftell(fp);
|
||||
if (bytes_written <= 0)
|
||||
return false;
|
||||
|
||||
/* FIXME: Figure out the define for alignment of 16. */
|
||||
for (size_t u = 0; u < (bytes_written % 16); ++u)
|
||||
fputc(0xff, fp);
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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 ROGUE_ENCODE_H
|
||||
#define ROGUE_ENCODE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "util/macros.h"
|
||||
|
||||
struct rogue_instr;
|
||||
struct rogue_shader;
|
||||
|
||||
PUBLIC
|
||||
bool rogue_encode_instr(const struct rogue_instr *instr, FILE *fp);
|
||||
|
||||
PUBLIC
|
||||
bool rogue_encode_shader(const struct rogue_shader *shader, FILE *fp);
|
||||
|
||||
#endif /* ROGUE_ENCODE_H */
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "rogue_encoders.h"
|
||||
#include "rogue_util.h"
|
||||
#include "util/bitscan.h"
|
||||
|
||||
/**
|
||||
* \brief Passes the input value through unchanged.
|
||||
*
|
||||
* \param[in] value Pointer to the destination value.
|
||||
* \param[in] inputs Number of inputs provided.
|
||||
* \param[in] ... Input value(s).
|
||||
* \return true if encoding was successful.
|
||||
*/
|
||||
bool rogue_encoder_pass(uint64_t *value, size_t inputs, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
assert(inputs == 1);
|
||||
|
||||
va_start(args, inputs);
|
||||
*value = va_arg(args, uint64_t);
|
||||
va_end(args);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Encoder for DRC values.
|
||||
*
|
||||
* \sa #rogue_encoder_pass()
|
||||
*
|
||||
* \param[in] value Pointer to the destination value.
|
||||
* \param[in] inputs Number of inputs provided.
|
||||
* \param[in] ... Input value(s).
|
||||
* \return true if encoding was successful.
|
||||
*/
|
||||
bool rogue_encoder_drc(uint64_t *value, size_t inputs, ...)
|
||||
__attribute__((alias("rogue_encoder_pass")));
|
||||
|
||||
/**
|
||||
* \brief Encoder for immediate values.
|
||||
*
|
||||
* \sa #rogue_encoder_pass()
|
||||
*
|
||||
* \param[in] value Pointer to the destination value.
|
||||
* \param[in] inputs Number of inputs provided.
|
||||
* \param[in] ... Input value(s).
|
||||
* \return true if encoding was successful.
|
||||
*/
|
||||
bool rogue_encoder_imm(uint64_t *value, size_t inputs, ...)
|
||||
__attribute__((alias("rogue_encoder_pass")));
|
||||
|
||||
/**
|
||||
* \brief Encodes input ranges {1..15 -> 1-15} and {16 -> 0}.
|
||||
*
|
||||
* The input should be in the range 1-16; the function represents 1-15 normally
|
||||
* and represents 16 by 0.
|
||||
*
|
||||
* \param[in] value Pointer to the destination value.
|
||||
* \param[in] inputs Number of inputs provided.
|
||||
* \param[in] ... Input value(s).
|
||||
* \return true if encoding was successful.
|
||||
*/
|
||||
bool rogue_encoder_ls_1_16(uint64_t *value, size_t inputs, ...)
|
||||
{
|
||||
va_list args;
|
||||
uint64_t input;
|
||||
|
||||
assert(inputs == 1);
|
||||
|
||||
va_start(args, inputs);
|
||||
input = va_arg(args, uint64_t);
|
||||
va_end(args);
|
||||
|
||||
/* Validate the input range. */
|
||||
if (!input || input > 16) {
|
||||
*value = UINT64_MAX;
|
||||
return false;
|
||||
}
|
||||
|
||||
*value = input % 16;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Encodes registers according to the number of bits needed to specify
|
||||
* the bank number and register number.
|
||||
*
|
||||
* \param[in] value Pointer to the destination value.
|
||||
* \param[in] bank_bits The number of bits used to represent the register bank.
|
||||
* \param[in] bank the register bank
|
||||
* \param[in] num_bits The number of bits used to represent the register number.
|
||||
* \param[in] num The register number.
|
||||
* \return true if encoding was successful.
|
||||
*/
|
||||
static bool rogue_encoder_reg(uint64_t *value,
|
||||
size_t bank_bits,
|
||||
size_t bank,
|
||||
size_t num_bits,
|
||||
size_t num)
|
||||
{
|
||||
/* Verify "num" fits in "num_bits" and "bank" fits in "bank_bits". */
|
||||
assert(util_last_bit64(num) <= num_bits);
|
||||
assert(util_last_bit64(bank) <= bank_bits);
|
||||
|
||||
*value = num;
|
||||
*value |= (bank << num_bits);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Macro to define the rogue_encoder_reg variants.
|
||||
*/
|
||||
#define ROGUE_ENCODER_REG_VARIANT(bank_bits, num_bits) \
|
||||
bool rogue_encoder_reg_##bank_bits##_##num_bits(uint64_t *value, \
|
||||
size_t inputs, \
|
||||
...) \
|
||||
{ \
|
||||
va_list args; \
|
||||
size_t bank; \
|
||||
size_t num; \
|
||||
assert(inputs == 2); \
|
||||
va_start(args, inputs); \
|
||||
bank = va_arg(args, size_t); \
|
||||
num = va_arg(args, size_t); \
|
||||
va_end(args); \
|
||||
return rogue_encoder_reg(value, bank_bits, bank, num_bits, num); \
|
||||
}
|
||||
|
||||
ROGUE_ENCODER_REG_VARIANT(2, 8)
|
||||
ROGUE_ENCODER_REG_VARIANT(3, 8)
|
||||
ROGUE_ENCODER_REG_VARIANT(3, 11)
|
||||
|
||||
#undef ROGUE_ENCODER_REG_VARIANT
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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 ROGUE_ENCODERS_H
|
||||
#define ROGUE_ENCODERS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util/macros.h"
|
||||
|
||||
/* Returns false if input was invalid. */
|
||||
typedef bool (*field_encoder_t)(uint64_t *value, size_t inputs, ...);
|
||||
|
||||
bool rogue_encoder_pass(uint64_t *value, size_t inputs, ...);
|
||||
bool rogue_encoder_drc(uint64_t *value, size_t inputs, ...);
|
||||
bool rogue_encoder_imm(uint64_t *value, size_t inputs, ...);
|
||||
bool rogue_encoder_ls_1_16(uint64_t *value, size_t inputs, ...);
|
||||
|
||||
/**
|
||||
* \brief Macro to declare the rogue_encoder_reg variants.
|
||||
*/
|
||||
#define ROGUE_ENCODER_REG_VARIANT(bank_bits, num_bits) \
|
||||
bool rogue_encoder_reg_##bank_bits##_##num_bits(uint64_t *value, \
|
||||
size_t inputs, \
|
||||
...);
|
||||
ROGUE_ENCODER_REG_VARIANT(2, 8)
|
||||
ROGUE_ENCODER_REG_VARIANT(3, 8)
|
||||
ROGUE_ENCODER_REG_VARIANT(3, 11)
|
||||
#undef ROGUE_ENCODER_REG_VARIANT
|
||||
|
||||
#endif /* ROGUE_ENCODERS_H */
|
|
@ -0,0 +1,227 @@
|
|||
/*
|
||||
* 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 <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "rogue_instr.h"
|
||||
#include "rogue_operand.h"
|
||||
#include "rogue_util.h"
|
||||
#include "util/ralloc.h"
|
||||
|
||||
/**
|
||||
* \file rogue_instr.c
|
||||
*
|
||||
* \brief Contains functions to manipulate Rogue instructions.
|
||||
*/
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
static const size_t instr_operand_count[ROGUE_OP_COUNT] = {
|
||||
[ROGUE_OP_NOP] = 0,
|
||||
[ROGUE_OP_END_FRAG] = 0,
|
||||
[ROGUE_OP_END_VERT] = 0,
|
||||
[ROGUE_OP_WDF] = 1,
|
||||
[ROGUE_OP_PIX_ITER_W] = 5,
|
||||
[ROGUE_OP_MAX] = 3,
|
||||
[ROGUE_OP_MIN] = 3,
|
||||
[ROGUE_OP_PACK_U8888] = 2,
|
||||
[ROGUE_OP_MOV] = 2,
|
||||
[ROGUE_OP_MOV_IMM] = 2,
|
||||
[ROGUE_OP_FMA] = 4,
|
||||
[ROGUE_OP_MUL] = 3,
|
||||
[ROGUE_OP_VTXOUT] = 2,
|
||||
};
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
/**
|
||||
* \brief Returns the number of operands an instruction takes.
|
||||
*
|
||||
* \param[in] opcode The instruction opcode.
|
||||
* \return The number of operands.
|
||||
*/
|
||||
static inline size_t rogue_instr_num_operands(enum rogue_opcode opcode)
|
||||
{
|
||||
ASSERT_OPCODE_RANGE(opcode);
|
||||
|
||||
return instr_operand_count[opcode];
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Allocates and sets up a Rogue instruction.
|
||||
*
|
||||
* \param[in] mem_ctx The memory context for the instruction.
|
||||
* \param[in] opcode The instruction opcode.
|
||||
* \return A rogue_instr* if successful, or NULL if unsuccessful.
|
||||
*/
|
||||
struct rogue_instr *rogue_instr_create(void *mem_ctx, enum rogue_opcode opcode)
|
||||
{
|
||||
struct rogue_instr *instr;
|
||||
|
||||
ASSERT_OPCODE_RANGE(opcode);
|
||||
|
||||
instr = rzalloc_size(mem_ctx, sizeof(*instr));
|
||||
if (!instr)
|
||||
return NULL;
|
||||
|
||||
instr->opcode = opcode;
|
||||
instr->num_operands = rogue_instr_num_operands(opcode);
|
||||
|
||||
/* Allocate space for operand array. */
|
||||
if (instr->num_operands) {
|
||||
instr->operands = rzalloc_array_size(instr,
|
||||
sizeof(*instr->operands),
|
||||
instr->num_operands);
|
||||
if (!instr->operands) {
|
||||
ralloc_free(instr);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return instr;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets a Rogue instruction flag.
|
||||
*
|
||||
* \param[in] instr The instruction.
|
||||
* \param[in] flag The flag to set.
|
||||
* \return true if valid, otherwise false.
|
||||
*/
|
||||
bool rogue_instr_set_flag(struct rogue_instr *instr, enum rogue_instr_flag flag)
|
||||
{
|
||||
instr->flags = ROH(flag);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets a Rogue instruction operand to an immediate value.
|
||||
*
|
||||
* \param[in] instr The instruction.
|
||||
* \param[in] index The operand index.
|
||||
* \param[in] value The value to set.
|
||||
* \return true if valid, otherwise false.
|
||||
*/
|
||||
bool rogue_instr_set_operand_imm(struct rogue_instr *instr,
|
||||
size_t index,
|
||||
uint64_t value)
|
||||
{
|
||||
ASSERT_INSTR_OPERAND_INDEX(instr, index);
|
||||
|
||||
instr->operands[index].type = ROGUE_OPERAND_TYPE_IMMEDIATE;
|
||||
instr->operands[index].immediate.value = value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets a Rogue instruction operand to a DRC number.
|
||||
*
|
||||
* \param[in] instr The instruction.
|
||||
* \param[in] index The operand index.
|
||||
* \param[in] number The DRC number to set.
|
||||
* \return true if valid, otherwise false.
|
||||
*/
|
||||
bool rogue_instr_set_operand_drc(struct rogue_instr *instr,
|
||||
size_t index,
|
||||
size_t number)
|
||||
{
|
||||
ASSERT_INSTR_OPERAND_INDEX(instr, index);
|
||||
|
||||
instr->operands[index].type = ROGUE_OPERAND_TYPE_DRC;
|
||||
instr->operands[index].drc.number = number;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets a Rogue instruction operand to a register.
|
||||
*
|
||||
* \param[in] instr The instruction.
|
||||
* \param[in] index The operand index.
|
||||
* \param[in] type The register type to set.
|
||||
* \param[in] number The register number to set.
|
||||
* \return true if valid, otherwise false.
|
||||
*/
|
||||
bool rogue_instr_set_operand_reg(struct rogue_instr *instr,
|
||||
size_t index,
|
||||
enum rogue_operand_type type,
|
||||
size_t number)
|
||||
{
|
||||
ASSERT_INSTR_OPERAND_INDEX(instr, index);
|
||||
ASSERT_OPERAND_REG(type);
|
||||
|
||||
instr->operands[index].type = type;
|
||||
instr->operands[index].reg.number = number;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets a Rogue instruction operand to a virtual register.
|
||||
*
|
||||
* \param[in] instr The instruction.
|
||||
* \param[in] index The operand index.
|
||||
* \param[in] number The register number to set.
|
||||
* \return true if valid, otherwise false.
|
||||
*/
|
||||
bool rogue_instr_set_operand_vreg(struct rogue_instr *instr,
|
||||
size_t index,
|
||||
size_t number)
|
||||
{
|
||||
ASSERT_INSTR_OPERAND_INDEX(instr, index);
|
||||
|
||||
instr->operands[index].type = ROGUE_OPERAND_TYPE_VREG;
|
||||
instr->operands[index].vreg.number = number;
|
||||
instr->operands[index].vreg.is_vector = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets a Rogue instruction operand to a virtual register
|
||||
* that is a vector type.
|
||||
*
|
||||
* \param[in] instr The instruction.
|
||||
* \param[in] index The operand index.
|
||||
* \param[in] component The vector component.
|
||||
* \param[in] number The register number to set.
|
||||
* \return true if valid, otherwise false.
|
||||
*/
|
||||
bool rogue_instr_set_operand_vreg_vec(struct rogue_instr *instr,
|
||||
size_t index,
|
||||
size_t component,
|
||||
size_t number)
|
||||
{
|
||||
ASSERT_INSTR_OPERAND_INDEX(instr, index);
|
||||
|
||||
instr->operands[index].type = ROGUE_OPERAND_TYPE_VREG;
|
||||
instr->operands[index].vreg.number = number;
|
||||
instr->operands[index].vreg.is_vector = true;
|
||||
instr->operands[index].vreg.component = component;
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* 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 ROGUE_INSTR_H
|
||||
#define ROGUE_INSTR_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "rogue_operand.h"
|
||||
#include "util/list.h"
|
||||
|
||||
/**
|
||||
* \brief Instruction opcodes.
|
||||
*/
|
||||
enum rogue_opcode {
|
||||
ROGUE_OP_NOP = 0, /** No-operation. */
|
||||
ROGUE_OP_END_FRAG, /** Fragment shader end. */
|
||||
ROGUE_OP_END_VERT, /** Vertex shader end. */
|
||||
ROGUE_OP_WDF, /** Write data fence. */
|
||||
|
||||
ROGUE_OP_PIX_ITER_W, /** Pixel iteration with coefficients. */
|
||||
|
||||
ROGUE_OP_MAX, /** Returns the largest out of two floats. */
|
||||
ROGUE_OP_MIN, /** Returns the smallest out of two floats. */
|
||||
|
||||
ROGUE_OP_PACK_U8888, /** Scales the four input floats:
|
||||
* [0.0f, 0.1f] -> [0, 255] and packs them
|
||||
* into a 32-bit unsigned integer.
|
||||
*/
|
||||
|
||||
ROGUE_OP_MOV, /** Register move instruction. */
|
||||
ROGUE_OP_MOV_IMM, /** Move immediate instruction. */
|
||||
|
||||
ROGUE_OP_FMA, /** Fused-multiply-add (float). */
|
||||
ROGUE_OP_MUL, /** Multiply (float). */
|
||||
|
||||
ROGUE_OP_VTXOUT, /** Writes the input register
|
||||
* to the given vertex output index.
|
||||
*/
|
||||
|
||||
ROGUE_OP_COUNT,
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Instruction flags.
|
||||
*/
|
||||
enum rogue_instr_flag {
|
||||
ROGUE_INSTR_FLAG_SAT = 0, /** Saturate values to 0.0 ... 1.0. */
|
||||
ROGUE_INSTR_FLAG_LP, /** Low-precision modifier. */
|
||||
ROGUE_INSTR_FLAG_OLCHK, /** Overlap check (pixel write). */
|
||||
|
||||
ROGUE_INSTR_FLAG_COUNT,
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Instruction description.
|
||||
*/
|
||||
struct rogue_instr {
|
||||
enum rogue_opcode opcode;
|
||||
|
||||
size_t num_operands;
|
||||
struct rogue_operand *operands;
|
||||
|
||||
uint64_t flags; /** A mask of #rogue_instr_flag values. */
|
||||
|
||||
struct list_head node; /** Linked list node. */
|
||||
};
|
||||
|
||||
struct rogue_instr *rogue_instr_create(void *mem_ctx, enum rogue_opcode opcode);
|
||||
|
||||
bool rogue_instr_set_flag(struct rogue_instr *instr,
|
||||
enum rogue_instr_flag flag);
|
||||
|
||||
bool rogue_instr_set_operand_imm(struct rogue_instr *instr,
|
||||
size_t index,
|
||||
uint64_t value);
|
||||
bool rogue_instr_set_operand_drc(struct rogue_instr *instr,
|
||||
size_t index,
|
||||
size_t number);
|
||||
bool rogue_instr_set_operand_reg(struct rogue_instr *instr,
|
||||
size_t index,
|
||||
enum rogue_operand_type type,
|
||||
size_t number);
|
||||
bool rogue_instr_set_operand_vreg(struct rogue_instr *instr,
|
||||
size_t index,
|
||||
size_t number);
|
||||
bool rogue_instr_set_operand_vreg_vec(struct rogue_instr *instr,
|
||||
size_t index,
|
||||
size_t component,
|
||||
size_t number);
|
||||
#endif /* ROGUE_INSTR_H */
|
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* 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 "compiler/spirv/nir_spirv.h"
|
||||
#include "nir/nir.h"
|
||||
#include "nir/nir_schedule.h"
|
||||
#include "rogue_nir.h"
|
||||
#include "rogue_operand.h"
|
||||
|
||||
/**
|
||||
* \file rogue_nir.c
|
||||
*
|
||||
* \brief Contains NIR-specific functions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief SPIR-V to NIR compilation options.
|
||||
*/
|
||||
static const struct spirv_to_nir_options spirv_options = {
|
||||
.environment = NIR_SPIRV_VULKAN,
|
||||
|
||||
/* Buffer address: (descriptor_set, binding), offset. */
|
||||
.ubo_addr_format = nir_address_format_vec2_index_32bit_offset,
|
||||
};
|
||||
|
||||
static const nir_shader_compiler_options nir_options = {
|
||||
.lower_fsat = true,
|
||||
.fuse_ffma32 = true,
|
||||
};
|
||||
|
||||
const struct spirv_to_nir_options *
|
||||
rogue_get_spirv_options(const struct rogue_compiler *compiler)
|
||||
{
|
||||
return &spirv_options;
|
||||
}
|
||||
|
||||
const nir_shader_compiler_options *
|
||||
rogue_get_compiler_options(const struct rogue_compiler *compiler)
|
||||
{
|
||||
return &nir_options;
|
||||
}
|
||||
|
||||
static int rogue_glsl_type_size(const struct glsl_type *type, bool bindless)
|
||||
{
|
||||
return glsl_count_attribute_slots(type, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Applies optimizations and passes required to lower the NIR shader into
|
||||
* a form suitable for lowering to Rogue IR.
|
||||
*
|
||||
* \param[in] ctx Shared multi-stage build context.
|
||||
* \param[in] shader Rogue shader.
|
||||
* \param[in] stage Shader stage.
|
||||
* \return true if successful, otherwise false.
|
||||
*/
|
||||
bool rogue_nir_passes(struct rogue_build_ctx *ctx,
|
||||
nir_shader *nir,
|
||||
gl_shader_stage stage)
|
||||
{
|
||||
bool progress;
|
||||
|
||||
nir_validate_shader(nir, "after spirv_to_nir");
|
||||
|
||||
/* Splitting. */
|
||||
NIR_PASS_V(nir, nir_split_var_copies);
|
||||
NIR_PASS_V(nir, nir_split_per_member_structs);
|
||||
|
||||
/* Ensure fs outputs are in the [0.0f...1.0f] range. */
|
||||
NIR_PASS_V(nir, nir_lower_clamp_color_outputs);
|
||||
|
||||
/* Replace references to I/O variables with intrinsics. */
|
||||
NIR_PASS_V(nir,
|
||||
nir_lower_io,
|
||||
nir_var_shader_in | nir_var_shader_out,
|
||||
rogue_glsl_type_size,
|
||||
(nir_lower_io_options)0);
|
||||
|
||||
/* Load inputs to scalars (single registers later). */
|
||||
NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_shader_in);
|
||||
|
||||
/* Optimize GL access qualifiers. */
|
||||
const nir_opt_access_options opt_access_options = {
|
||||
.is_vulkan = true,
|
||||
.infer_non_readable = true,
|
||||
};
|
||||
NIR_PASS_V(nir, nir_opt_access, &opt_access_options);
|
||||
|
||||
/* Apply PFO code to the fragment shader output. */
|
||||
if (nir->info.stage == MESA_SHADER_FRAGMENT)
|
||||
NIR_PASS_V(nir, rogue_nir_pfo);
|
||||
|
||||
/* Load outputs to scalars (single registers later). */
|
||||
NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_shader_out);
|
||||
|
||||
/* Lower ALU operations to scalars. */
|
||||
NIR_PASS_V(nir, nir_lower_alu_to_scalar, NULL, NULL);
|
||||
|
||||
/* Algebraic opts. */
|
||||
do {
|
||||
progress = false;
|
||||
|
||||
NIR_PASS(progress, nir, nir_copy_prop);
|
||||
NIR_PASS(progress, nir, nir_opt_cse);
|
||||
NIR_PASS(progress, nir, nir_opt_algebraic);
|
||||
NIR_PASS(progress, nir, nir_opt_constant_folding);
|
||||
NIR_PASS(progress, nir, nir_opt_dce);
|
||||
NIR_PASS_V(nir, nir_opt_gcm, false);
|
||||
} while (progress);
|
||||
|
||||
/* Additional I/O lowering. */
|
||||
NIR_PASS_V(nir,
|
||||
nir_lower_explicit_io,
|
||||
nir_var_mem_ubo,
|
||||
spirv_options.ubo_addr_format);
|
||||
NIR_PASS_V(nir, rogue_nir_lower_io, NULL);
|
||||
|
||||
/* Late algebraic opts. */
|
||||
do {
|
||||
progress = false;
|
||||
|
||||
NIR_PASS(progress, nir, nir_opt_algebraic_late);
|
||||
NIR_PASS_V(nir, nir_opt_constant_folding);
|
||||
NIR_PASS_V(nir, nir_copy_prop);
|
||||
NIR_PASS_V(nir, nir_opt_dce);
|
||||
NIR_PASS_V(nir, nir_opt_cse);
|
||||
} while (progress);
|
||||
|
||||
/* Replace SSA constant references with a register that loads the value. */
|
||||
NIR_PASS_V(nir, rogue_nir_constreg);
|
||||
/* Remove unused constant registers. */
|
||||
NIR_PASS_V(nir, nir_opt_dce);
|
||||
|
||||
/* Move loads to just before they're needed. */
|
||||
NIR_PASS_V(nir, nir_opt_move, nir_move_load_ubo | nir_move_load_input);
|
||||
|
||||
/* Convert vecNs to movs so we can sequentially allocate them later. */
|
||||
NIR_PASS_V(nir, nir_lower_vec_to_movs, NULL, NULL);
|
||||
|
||||
/* Out of SSA pass. */
|
||||
NIR_PASS_V(nir, nir_convert_from_ssa, false);
|
||||
|
||||
/* TODO: Re-enable scheduling after register pressure tweaks. */
|
||||
#if 0
|
||||
/* Instruction scheduling. */
|
||||
struct nir_schedule_options schedule_options = {
|
||||
.threshold = ROGUE_MAX_REG_TEMP / 2,
|
||||
};
|
||||
NIR_PASS_V(nir, nir_schedule, &schedule_options);
|
||||
#endif
|
||||
|
||||
/* Assign I/O locations. */
|
||||
nir_assign_io_var_locations(nir,
|
||||
nir_var_shader_in,
|
||||
&nir->num_inputs,
|
||||
nir->info.stage);
|
||||
nir_assign_io_var_locations(nir,
|
||||
nir_var_shader_out,
|
||||
&nir->num_outputs,
|
||||
nir->info.stage);
|
||||
|
||||
/* Gather info into nir shader struct. */
|
||||
nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
|
||||
|
||||
/* Clean-up after passes. */
|
||||
nir_sweep(nir);
|
||||
|
||||
nir_validate_shader(nir, "after passes");
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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 ROGUE_NIR_H
|
||||
#define ROGUE_NIR_H
|
||||
|
||||
#include "compiler/shader_enums.h"
|
||||
#include "nir/nir.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
struct rogue_build_ctx;
|
||||
struct rogue_compiler;
|
||||
struct spirv_to_nir_options;
|
||||
|
||||
PUBLIC
|
||||
const struct spirv_to_nir_options *
|
||||
rogue_get_spirv_options(const struct rogue_compiler *compiler);
|
||||
|
||||
PUBLIC
|
||||
const nir_shader_compiler_options *
|
||||
rogue_get_compiler_options(const struct rogue_compiler *compiler);
|
||||
|
||||
bool rogue_nir_passes(struct rogue_build_ctx *ctx,
|
||||
nir_shader *nir,
|
||||
gl_shader_stage stage);
|
||||
|
||||
/* Custom passes. */
|
||||
void rogue_nir_pfo(nir_shader *shader);
|
||||
void rogue_nir_constreg(nir_shader *shader);
|
||||
bool rogue_nir_lower_io(nir_shader *shader, void *layout);
|
||||
|
||||
#endif /* ROGUE_NIR_H */
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* 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 ROGUE_NIR_HELPERS_H
|
||||
#define ROGUE_NIR_HELPERS_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "nir/nir.h"
|
||||
#include "util/bitscan.h"
|
||||
|
||||
/**
|
||||
* \file rogue_nir.c
|
||||
*
|
||||
* \brief Contains various NIR helper functions.
|
||||
*/
|
||||
|
||||
static inline unsigned nir_alu_dest_regindex(const nir_alu_instr *alu)
|
||||
{
|
||||
assert(!alu->dest.dest.is_ssa);
|
||||
|
||||
return alu->dest.dest.reg.reg->index;
|
||||
}
|
||||
|
||||
static inline unsigned nir_alu_dest_comp(const nir_alu_instr *alu)
|
||||
{
|
||||
assert(!alu->dest.dest.is_ssa);
|
||||
assert(util_is_power_of_two_nonzero(alu->dest.write_mask));
|
||||
|
||||
return ffs(alu->dest.write_mask) - 1;
|
||||
}
|
||||
|
||||
static inline unsigned nir_alu_src_regindex(const nir_alu_instr *alu,
|
||||
size_t src)
|
||||
{
|
||||
assert(src < nir_op_infos[alu->op].num_inputs);
|
||||
assert(!alu->src[src].src.is_ssa);
|
||||
|
||||
return alu->src[src].src.reg.reg->index;
|
||||
}
|
||||
|
||||
static inline uint32_t nir_alu_src_const(const nir_alu_instr *alu, size_t src)
|
||||
{
|
||||
assert(src < nir_op_infos[alu->op].num_inputs);
|
||||
assert(alu->src[src].src.is_ssa);
|
||||
|
||||
nir_const_value *const_value = nir_src_as_const_value(alu->src[src].src);
|
||||
|
||||
return nir_const_value_as_uint(*const_value, 32);
|
||||
}
|
||||
|
||||
static inline bool nir_alu_src_is_const(const nir_alu_instr *alu, size_t src)
|
||||
{
|
||||
assert(src < nir_op_infos[alu->op].num_inputs);
|
||||
|
||||
if (!alu->src[src].src.is_ssa)
|
||||
return false;
|
||||
|
||||
assert(alu->src[src].src.ssa->parent_instr);
|
||||
|
||||
return (alu->src[src].src.ssa->parent_instr->type ==
|
||||
nir_instr_type_load_const);
|
||||
}
|
||||
|
||||
static inline unsigned nir_intr_dest_regindex(const nir_intrinsic_instr *intr)
|
||||
{
|
||||
assert(!intr->dest.is_ssa);
|
||||
|
||||
return intr->dest.reg.reg->index;
|
||||
}
|
||||
|
||||
static inline unsigned nir_intr_src_regindex(const nir_intrinsic_instr *intr,
|
||||
size_t src)
|
||||
{
|
||||
assert(src < nir_intrinsic_infos[intr->intrinsic].num_srcs);
|
||||
assert(!intr->src[src].is_ssa);
|
||||
|
||||
return intr->src[src].reg.reg->index;
|
||||
}
|
||||
|
||||
static inline uint32_t nir_intr_src_const(const nir_intrinsic_instr *intr,
|
||||
size_t src)
|
||||
{
|
||||
assert(src < nir_intrinsic_infos[intr->intrinsic].num_srcs);
|
||||
assert(intr->src[src].is_ssa);
|
||||
|
||||
nir_const_value *const_value = nir_src_as_const_value(intr->src[src]);
|
||||
|
||||
return nir_const_value_as_uint(*const_value, 32);
|
||||
}
|
||||
|
||||
static inline uint32_t nir_intr_src_comp_const(const nir_intrinsic_instr *intr,
|
||||
size_t src,
|
||||
size_t comp)
|
||||
{
|
||||
assert(src < nir_intrinsic_infos[intr->intrinsic].num_srcs);
|
||||
assert(intr->src[src].is_ssa);
|
||||
assert(comp < nir_src_num_components(intr->src[src]));
|
||||
|
||||
return nir_src_comp_as_uint(intr->src[src], comp);
|
||||
}
|
||||
|
||||
static inline bool nir_intr_src_is_const(const nir_intrinsic_instr *intr,
|
||||
size_t src)
|
||||
{
|
||||
assert(src < nir_intrinsic_infos[intr->intrinsic].num_srcs);
|
||||
|
||||
if (!intr->src[src].is_ssa)
|
||||
return false;
|
||||
|
||||
assert(intr->src[src].ssa->parent_instr);
|
||||
|
||||
return (intr->src[src].ssa->parent_instr->type == nir_instr_type_load_const);
|
||||
}
|
||||
|
||||
static inline size_t nir_count_variables_with_modes(const nir_shader *nir,
|
||||
nir_variable_mode mode)
|
||||
{
|
||||
size_t count = 0;
|
||||
|
||||
nir_foreach_variable_with_modes (var, nir, mode)
|
||||
++count;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif /* ROGUE_NIR_HELPERS_H */
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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 "rogue_operand.h"
|
||||
|
||||
/**
|
||||
* \file rogue_operand.c
|
||||
*
|
||||
* \brief Contains functions to manipulate Rogue instruction operands.
|
||||
*/
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* 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 ROGUE_OPERAND_H
|
||||
#define ROGUE_OPERAND_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "rogue_util.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
/* Register-related defines. */
|
||||
|
||||
/* Total max number of registers per class
|
||||
* (instances > ROGUE_MAX_REG_INDEX addressable via indexing only).
|
||||
*/
|
||||
#define ROGUE_MAX_REG_TEMP 248
|
||||
#define ROGUE_MAX_REG_COEFF 4096
|
||||
#define ROGUE_MAX_REG_CONST 240
|
||||
#define ROGUE_MAX_REG_SHARED 4096
|
||||
#define ROGUE_MAX_REG_PIXEL_OUT 8
|
||||
#define ROGUE_MAX_REG_VERTEX_IN 248
|
||||
#define ROGUE_MAX_REG_INTERNAL 8
|
||||
|
||||
/* Maximum register index via offset encoding. */
|
||||
#define ROGUE_MAX_REG_INDEX 256
|
||||
|
||||
/* Pixel-out register offset. */
|
||||
#define ROGUE_PIXEL_OUT_REG_OFFSET 32
|
||||
|
||||
/* Internal register offset. */
|
||||
#define ROGUE_INTERNAL_REG_OFFSET 36
|
||||
|
||||
/* Coefficient registers are typically used in groups of 4. */
|
||||
#define ROGUE_COEFF_ALIGN 4
|
||||
|
||||
/* Defines for other operand types. */
|
||||
|
||||
/* Available dependent read counters. */
|
||||
#define ROGUE_NUM_DRCS 2
|
||||
|
||||
/* Maximum number of vertex outputs. */
|
||||
#define ROGUE_MAX_VERTEX_OUTPUTS 256
|
||||
|
||||
/* All components of an emulated vec4 register group. */
|
||||
#define ROGUE_COMPONENT_ALL (~0)
|
||||
|
||||
/**
|
||||
* \brief Operand types.
|
||||
*/
|
||||
enum rogue_operand_type {
|
||||
/* Register operands. */
|
||||
ROGUE_OPERAND_TYPE_REG_TEMP = 0, /** Temporary register. */
|
||||
ROGUE_OPERAND_TYPE_REG_COEFF, /** Coefficient register. */
|
||||
ROGUE_OPERAND_TYPE_REG_CONST, /** Constant register. */
|
||||
ROGUE_OPERAND_TYPE_REG_SHARED, /** Shared register. */
|
||||
ROGUE_OPERAND_TYPE_REG_PIXEL_OUT, /** Pixel output register. */
|
||||
ROGUE_OPERAND_TYPE_REG_VERTEX_IN, /** Vertex input register. */
|
||||
ROGUE_OPERAND_TYPE_REG_INTERNAL, /** Internal register. */
|
||||
|
||||
ROGUE_OPERAND_TYPE_REG_MAX = ROGUE_OPERAND_TYPE_REG_INTERNAL,
|
||||
|
||||
ROGUE_OPERAND_TYPE_IMMEDIATE, /** Immediate value. */
|
||||
|
||||
ROGUE_OPERAND_TYPE_DRC, /** Dependent read counter. */
|
||||
|
||||
ROGUE_OPERAND_TYPE_VREG, /** Virtual register (pre-regalloc). */
|
||||
|
||||
ROGUE_OPERAND_TYPE_COUNT,
|
||||
};
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
#define ROGUE_NUM_REG_TYPES (ROGUE_OPERAND_TYPE_REG_MAX + 1)
|
||||
|
||||
/**
|
||||
* \brief A bitmask for any register operand type.
|
||||
*/
|
||||
#define ROGUE_MASK_ANY_REG \
|
||||
ROH(ROGUE_OPERAND_TYPE_REG_TEMP) | \
|
||||
ROH(ROGUE_OPERAND_TYPE_REG_COEFF) | \
|
||||
ROH(ROGUE_OPERAND_TYPE_REG_CONST) | \
|
||||
ROH(ROGUE_OPERAND_TYPE_REG_PIXEL_OUT) | \
|
||||
ROH(ROGUE_OPERAND_TYPE_REG_VERTEX_IN) | \
|
||||
ROH(ROGUE_OPERAND_TYPE_REG_SHARED) | \
|
||||
ROH(ROGUE_OPERAND_TYPE_REG_INTERNAL)
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
/**
|
||||
* \brief Operand description.
|
||||
*/
|
||||
struct rogue_operand {
|
||||
enum rogue_operand_type type;
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint64_t value;
|
||||
} immediate;
|
||||
|
||||
struct {
|
||||
size_t number;
|
||||
} drc;
|
||||
|
||||
struct {
|
||||
size_t number;
|
||||
} reg;
|
||||
|
||||
struct {
|
||||
size_t number;
|
||||
bool is_vector;
|
||||
size_t component;
|
||||
} vreg;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Register access flags.
|
||||
*/
|
||||
enum rogue_register_access {
|
||||
ROGUE_REG_ACCESS_READ = BITFIELD_BIT(0U), /** Read-only. */
|
||||
ROGUE_REG_ACCESS_WRITE = BITFIELD_BIT(1U), /* Write-only. */
|
||||
ROGUE_REG_ACCESS_RW = ROGUE_REG_ACCESS_READ |
|
||||
ROGUE_REG_ACCESS_WRITE, /** Read/write. */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Register modifier flags.
|
||||
*/
|
||||
enum rogue_register_modifier {
|
||||
ROGUE_REG_MOD_NONE = 0U,
|
||||
ROGUE_REG_MOD_IDX = BITFIELD_BIT(0U), /** Index modifier. */
|
||||
ROGUE_REG_MOD_DIM = BITFIELD_BIT(1U), /** Dimension modifier. */
|
||||
ROGUE_REG_MOD_ALL = ROGUE_REG_MOD_IDX | ROGUE_REG_MOD_DIM,
|
||||
};
|
||||
|
||||
#endif /* ROGUE_OPERAND_H */
|
|
@ -0,0 +1,313 @@
|
|||
/*
|
||||
* 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 <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "rogue_operand.h"
|
||||
#include "rogue_regalloc.h"
|
||||
#include "rogue_shader.h"
|
||||
#include "rogue_util.h"
|
||||
#include "util/hash_table.h"
|
||||
#include "util/list.h"
|
||||
#include "util/ralloc.h"
|
||||
#include "util/register_allocate.h"
|
||||
#include "util/u_dynarray.h"
|
||||
|
||||
/**
|
||||
* \file rogue_regalloc.c
|
||||
*
|
||||
* \brief Contains register allocation helper functions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Sets up the register data with the classes to be used for allocation.
|
||||
*
|
||||
* \param[in] data The register data array.
|
||||
*/
|
||||
static void
|
||||
rogue_reg_data_init(struct rogue_reg_data data[static ROGUE_REG_CLASS_COUNT])
|
||||
{
|
||||
data[ROGUE_REG_CLASS_TEMP].type = ROGUE_OPERAND_TYPE_REG_TEMP;
|
||||
data[ROGUE_REG_CLASS_TEMP].count = ROGUE_MAX_REG_TEMP;
|
||||
data[ROGUE_REG_CLASS_TEMP].stride = 1;
|
||||
|
||||
data[ROGUE_REG_CLASS_VEC4].type = ROGUE_OPERAND_TYPE_REG_INTERNAL;
|
||||
data[ROGUE_REG_CLASS_VEC4].count = ROGUE_MAX_REG_INTERNAL;
|
||||
data[ROGUE_REG_CLASS_VEC4].stride = 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initializes the Rogue register allocation context.
|
||||
*
|
||||
* \param[in] mem_ctx The memory context for the ra context.
|
||||
* \return A rogue_ra * if successful, or NULL if unsuccessful.
|
||||
*/
|
||||
struct rogue_ra *rogue_ra_init(void *mem_ctx)
|
||||
{
|
||||
struct rogue_ra *ra;
|
||||
size_t total_regs = 0;
|
||||
|
||||
ra = rzalloc_size(mem_ctx, sizeof(*ra));
|
||||
if (!ra)
|
||||
return NULL;
|
||||
|
||||
/* Initialize the register class data. */
|
||||
rogue_reg_data_init(ra->reg_data);
|
||||
|
||||
/* Count up the registers classes and set up their offsets.
|
||||
*
|
||||
* The physical register numbers are sequential, even if the
|
||||
* registers are from different banks, so keeping track of
|
||||
* the offset means we can get the true physical register
|
||||
* number back after allocation.
|
||||
*/
|
||||
for (size_t u = 0; u < ARRAY_SIZE(ra->reg_data); ++u) {
|
||||
ra->reg_data[u].offset = total_regs;
|
||||
total_regs += ra->reg_data[u].count;
|
||||
}
|
||||
|
||||
/* Create a register set for allocation. */
|
||||
ra->regs = ra_alloc_reg_set(ra, total_regs, true);
|
||||
if (!ra->regs) {
|
||||
ralloc_free(ra);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create the register class for the temps. */
|
||||
ra->reg_data[ROGUE_REG_CLASS_TEMP].class =
|
||||
ra_alloc_contig_reg_class(ra->regs, 1);
|
||||
|
||||
/* Create the register class for vec4 registers
|
||||
* (using the internal register bank).
|
||||
*/
|
||||
ra->reg_data[ROGUE_REG_CLASS_VEC4].class =
|
||||
ra_alloc_contig_reg_class(ra->regs, 4);
|
||||
|
||||
/* Populate the register classes. */
|
||||
for (size_t u = 0; u < ARRAY_SIZE(ra->reg_data); ++u) {
|
||||
struct rogue_reg_data *reg_data = &ra->reg_data[u];
|
||||
size_t offset = reg_data->offset;
|
||||
size_t end = reg_data->offset + reg_data->count;
|
||||
size_t stride = reg_data->stride;
|
||||
|
||||
for (size_t r = offset; r < end; r += stride)
|
||||
ra_class_add_reg(reg_data->class, r);
|
||||
}
|
||||
|
||||
/* Finalize the set (no early conflicts passed along for now). */
|
||||
ra_set_finalize(ra->regs, NULL);
|
||||
|
||||
return ra;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief The range for which a (virtual) register is live, and its references.
|
||||
*/
|
||||
struct live_range {
|
||||
size_t start;
|
||||
size_t end;
|
||||
enum rogue_reg_class class;
|
||||
struct util_dynarray operand_refs;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Performs register allocation.
|
||||
*
|
||||
* \param[in] instr_list A linked list of instructions with virtual registers to
|
||||
* be allocated.
|
||||
* \param[in] ra The register allocation context.
|
||||
*/
|
||||
bool rogue_ra_alloc(struct list_head *instr_list,
|
||||
struct rogue_ra *ra,
|
||||
size_t *temps_used,
|
||||
size_t *internals_used)
|
||||
{
|
||||
/* Used for ra_alloc_interference_graph() as it doesn't
|
||||
* like having gaps (e.g. with v0, v2 count = 3 rather
|
||||
* than 2).
|
||||
*/
|
||||
size_t max_vreg = 0;
|
||||
|
||||
struct hash_table *reg_ht =
|
||||
_mesa_hash_table_create(ra, _mesa_hash_uint, _mesa_key_uint_equal);
|
||||
if (!reg_ht)
|
||||
return false;
|
||||
|
||||
/* Calculate live ranges for virtual registers. */
|
||||
size_t ip = 0U; /* "Instruction pointer". */
|
||||
foreach_instr (instr, instr_list) {
|
||||
for (size_t u = 0U; u < instr->num_operands; ++u) {
|
||||
struct hash_entry *entry;
|
||||
struct live_range *range;
|
||||
|
||||
if (instr->operands[u].type != ROGUE_OPERAND_TYPE_VREG)
|
||||
continue;
|
||||
|
||||
entry =
|
||||
_mesa_hash_table_search(reg_ht, &instr->operands[u].vreg.number);
|
||||
if (!entry) {
|
||||
/* First use of this virtual register: initialize live range. */
|
||||
/* TODO: Error handling. */
|
||||
range = rzalloc_size(reg_ht, sizeof(*range));
|
||||
|
||||
range->start = ip;
|
||||
range->end = ip;
|
||||
range->class = instr->operands[u].vreg.is_vector
|
||||
? ROGUE_REG_CLASS_VEC4
|
||||
: ROGUE_REG_CLASS_TEMP;
|
||||
|
||||
entry = _mesa_hash_table_insert(reg_ht,
|
||||
&instr->operands[u].vreg.number,
|
||||
range);
|
||||
|
||||
max_vreg = MAX2(max_vreg, instr->operands[u].vreg.number);
|
||||
|
||||
util_dynarray_init(&range->operand_refs, range);
|
||||
} else {
|
||||
/* Subsequent uses: update live range end. */
|
||||
range = entry->data;
|
||||
range->end = MAX2(range->end, ip);
|
||||
assert(range->class == (instr->operands[u].vreg.is_vector
|
||||
? ROGUE_REG_CLASS_VEC4
|
||||
: ROGUE_REG_CLASS_TEMP));
|
||||
}
|
||||
|
||||
/* Save a reference to the operand. */
|
||||
util_dynarray_append(&range->operand_refs,
|
||||
struct rogue_operand *,
|
||||
&instr->operands[u]);
|
||||
}
|
||||
++ip;
|
||||
}
|
||||
|
||||
/* Initialize the interference graph. */
|
||||
struct ra_graph *g = ra_alloc_interference_graph(ra->regs, max_vreg + 1);
|
||||
|
||||
/* Set each virtual register to the appropriate class. */
|
||||
hash_table_foreach (reg_ht, entry) {
|
||||
const uint32_t *vreg = entry->key;
|
||||
struct live_range *range = entry->data;
|
||||
struct ra_class *class = ra->reg_data[range->class].class;
|
||||
|
||||
ra_set_node_class(g, *vreg, class);
|
||||
/* TODO: ra_set_node_spill_cost(g, *vreg, cost); */
|
||||
}
|
||||
|
||||
/* Build interference graph from overlapping live ranges. */
|
||||
hash_table_foreach (reg_ht, entry_first) {
|
||||
const uint32_t *vreg_first = entry_first->key;
|
||||
struct live_range *range_first = entry_first->data;
|
||||
|
||||
hash_table_foreach (reg_ht, entry_second) {
|
||||
const uint32_t *vreg_second = entry_second->key;
|
||||
struct live_range *range_second = entry_second->data;
|
||||
|
||||
if (*vreg_first == *vreg_second)
|
||||
continue;
|
||||
|
||||
/* If the live ranges overlap, those register nodes interfere. */
|
||||
if (!(range_first->start >= range_second->end ||
|
||||
range_second->start >= range_first->end)) {
|
||||
ra_add_node_interference(g, *vreg_first, *vreg_second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add node interferences such that the same register can't be used for
|
||||
* both an instruction's source and destination.
|
||||
*/
|
||||
foreach_instr (instr, instr_list) {
|
||||
for (size_t u = 0U; u < instr->num_operands; ++u) {
|
||||
if (instr->operands[u].type != ROGUE_OPERAND_TYPE_VREG)
|
||||
continue;
|
||||
|
||||
/* Operand 0 (if it exists and is virtual) is always
|
||||
* the destination register.
|
||||
*/
|
||||
if (u > 0 && instr->operands[0].type == ROGUE_OPERAND_TYPE_VREG)
|
||||
ra_add_node_interference(g,
|
||||
instr->operands[0].vreg.number,
|
||||
instr->operands[u].vreg.number);
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform register allocation. */
|
||||
/* TODO: Spilling support. */
|
||||
assert(ra_allocate(g));
|
||||
|
||||
/* Replace virtual registers with allocated physical registers.
|
||||
* N.B. This is a destructive process as it overwrites the hash table key!
|
||||
*/
|
||||
hash_table_foreach (reg_ht, entry) {
|
||||
uint32_t vreg = *(uint32_t *)entry->key;
|
||||
unsigned phy_reg = ra_get_node_reg(g, vreg);
|
||||
struct live_range *range = entry->data;
|
||||
|
||||
struct rogue_reg_data *reg_data = &ra->reg_data[range->class];
|
||||
enum rogue_operand_type type = reg_data->type;
|
||||
size_t reg_offset = reg_data->offset;
|
||||
size_t *num_used = ®_data->num_used;
|
||||
|
||||
util_dynarray_foreach (&range->operand_refs,
|
||||
struct rogue_operand *,
|
||||
operand_ptr) {
|
||||
size_t num = phy_reg - reg_offset;
|
||||
struct rogue_operand *operand = *operand_ptr;
|
||||
|
||||
assert(operand->type == ROGUE_OPERAND_TYPE_VREG);
|
||||
assert(operand->vreg.number == vreg);
|
||||
|
||||
/* Index the component of emulated vec4 registers. */
|
||||
if (operand->vreg.is_vector &&
|
||||
operand->vreg.component != ROGUE_COMPONENT_ALL)
|
||||
num += operand->vreg.component;
|
||||
|
||||
operand->type = type;
|
||||
operand->reg.number = num;
|
||||
|
||||
*num_used = MAX2(*num_used, operand->reg.number);
|
||||
}
|
||||
|
||||
util_dynarray_fini(&range->operand_refs);
|
||||
_mesa_hash_table_remove(reg_ht, entry);
|
||||
}
|
||||
|
||||
/* Registers used = max reg number + 1. */
|
||||
for (size_t u = 0; u < ARRAY_SIZE(ra->reg_data); ++u)
|
||||
if (ra->reg_data[u].num_used)
|
||||
++ra->reg_data[u].num_used;
|
||||
|
||||
/* Pass back the registers used. */
|
||||
if (temps_used)
|
||||
*temps_used = ra->reg_data[ROGUE_REG_CLASS_TEMP].num_used;
|
||||
|
||||
if (internals_used)
|
||||
*internals_used = ra->reg_data[ROGUE_REG_CLASS_VEC4].num_used;
|
||||
|
||||
ralloc_free(g);
|
||||
|
||||
_mesa_hash_table_destroy(reg_ht, NULL);
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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 ROGUE_REGALLOC_H
|
||||
#define ROGUE_REGALLOC_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "util/list.h"
|
||||
|
||||
/**
|
||||
* \brief Register classes used for allocation.
|
||||
*/
|
||||
enum rogue_reg_class {
|
||||
ROGUE_REG_CLASS_TEMP,
|
||||
ROGUE_REG_CLASS_VEC4,
|
||||
|
||||
ROGUE_REG_CLASS_COUNT,
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Register data for each class.
|
||||
*/
|
||||
struct rogue_reg_data {
|
||||
enum rogue_operand_type type;
|
||||
size_t count;
|
||||
size_t stride;
|
||||
|
||||
size_t offset;
|
||||
struct ra_class *class;
|
||||
size_t num_used;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Register allocation context.
|
||||
*/
|
||||
struct rogue_ra {
|
||||
struct ra_regs *regs;
|
||||
|
||||
struct rogue_reg_data reg_data[ROGUE_REG_CLASS_COUNT];
|
||||
};
|
||||
|
||||
struct rogue_ra *rogue_ra_init(void *mem_ctx);
|
||||
bool rogue_ra_alloc(struct list_head *instr_list,
|
||||
struct rogue_ra *ra,
|
||||
size_t *temps_used,
|
||||
size_t *internals_used);
|
||||
|
||||
#endif /* ROGUE_REGALLOC_H */
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "rogue_shader.h"
|
||||
#include "rogue_instr.h"
|
||||
#include "rogue_regalloc.h"
|
||||
#include "rogue_util.h"
|
||||
#include "util/ralloc.h"
|
||||
|
||||
/**
|
||||
* \file rogue_shader.c
|
||||
*
|
||||
* \brief Contains functions to manipulate Rogue shaders.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Counts how many times an instruction is used in a shader.
|
||||
*
|
||||
* \param[in] shader The shader containing instructions to count.
|
||||
* \param[in] opcode The opcode of the instruction to be counted.
|
||||
* \return The number of times "opcode" is present, or 0 on error.
|
||||
*/
|
||||
size_t rogue_shader_instr_count_type(const struct rogue_shader *shader,
|
||||
enum rogue_opcode opcode)
|
||||
{
|
||||
size_t count = 0U;
|
||||
|
||||
ASSERT_OPCODE_RANGE(opcode);
|
||||
|
||||
foreach_instr (instr, &shader->instr_list)
|
||||
if (instr->opcode == opcode)
|
||||
++count;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Allocates and sets up a Rogue shader.
|
||||
*
|
||||
* \param[in] stage The shader stage.
|
||||
* \return A rogue_shader* if successful, or NULL if unsuccessful.
|
||||
*/
|
||||
struct rogue_shader *rogue_shader_create(struct rogue_build_ctx *ctx,
|
||||
gl_shader_stage stage)
|
||||
{
|
||||
struct rogue_shader *shader;
|
||||
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
shader = rzalloc_size(ctx, sizeof(*shader));
|
||||
if (!shader)
|
||||
return NULL;
|
||||
|
||||
shader->stage = stage;
|
||||
|
||||
list_inithead(&shader->instr_list);
|
||||
|
||||
shader->ctx = ctx;
|
||||
shader->ra = rogue_ra_init(shader);
|
||||
if (!shader->ra) {
|
||||
ralloc_free(shader);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Creates an instruction and appends it to a Rogue shader.
|
||||
*
|
||||
* \param[in] shader The shader.
|
||||
* \param[in] opcode The instruction opcode.
|
||||
* \return A rogue_instr* if successful, or NULL if unsuccessful.
|
||||
*/
|
||||
struct rogue_instr *rogue_shader_insert(struct rogue_shader *shader,
|
||||
enum rogue_opcode opcode)
|
||||
{
|
||||
struct rogue_instr *instr = rogue_instr_create(shader, opcode);
|
||||
if (!instr)
|
||||
return NULL;
|
||||
|
||||
list_addtail(&instr->node, &shader->instr_list);
|
||||
|
||||
return instr;
|
||||
}
|
||||
|
||||
size_t rogue_acquire_drc(struct rogue_shader *shader)
|
||||
{
|
||||
size_t drc;
|
||||
|
||||
/* If both DRCs are in use, we have a problem. */
|
||||
if (shader->drc_used[0] && shader->drc_used[1])
|
||||
return SIZE_MAX;
|
||||
|
||||
drc = !shader->drc_used[0] ? 0 : 1;
|
||||
shader->drc_used[drc] = true;
|
||||
|
||||
return drc;
|
||||
}
|
||||
|
||||
void rogue_release_drc(struct rogue_shader *shader, size_t drc)
|
||||
{
|
||||
assert(drc < ROGUE_NUM_DRCS);
|
||||
assert(shader->drc_used[drc]);
|
||||
|
||||
shader->drc_used[drc] = false;
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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 ROGUE_SHADER_H
|
||||
#define ROGUE_SHADER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "compiler/shader_enums.h"
|
||||
#include "rogue_instr.h"
|
||||
#include "rogue_operand.h"
|
||||
#include "rogue_util.h"
|
||||
#include "util/list.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
struct rogue_build_ctx;
|
||||
struct rogue_ra;
|
||||
|
||||
/**
|
||||
* \brief Shader description.
|
||||
*/
|
||||
struct rogue_shader {
|
||||
gl_shader_stage stage; /** Shader stage. */
|
||||
|
||||
struct list_head instr_list; /** Instructions linked list. */
|
||||
|
||||
struct rogue_build_ctx *ctx;
|
||||
struct rogue_ra *ra;
|
||||
|
||||
bool drc_used[ROGUE_NUM_DRCS];
|
||||
};
|
||||
|
||||
/* Shader instruction list iterators and helpers. */
|
||||
#define foreach_instr(__instr, __list) \
|
||||
list_for_each_entry (struct rogue_instr, __instr, __list, node)
|
||||
#define foreach_instr_rev(__instr, __list) \
|
||||
list_for_each_entry_rev (struct rogue_instr, __instr, __list, node)
|
||||
#define foreach_instr_safe(__instr, __list) \
|
||||
list_for_each_entry_safe (struct rogue_instr, __instr, __list, node)
|
||||
|
||||
#define instr_first_entry(__list) \
|
||||
list_first_entry(__list, struct rogue_instr, node)
|
||||
#define instr_last_entry(__list) \
|
||||
list_last_entry(__list, struct rogue_instr, node)
|
||||
|
||||
size_t rogue_shader_instr_count_type(const struct rogue_shader *shader,
|
||||
enum rogue_opcode opcode);
|
||||
|
||||
PUBLIC
|
||||
struct rogue_shader *rogue_shader_create(struct rogue_build_ctx *ctx,
|
||||
gl_shader_stage stage);
|
||||
|
||||
PUBLIC
|
||||
struct rogue_instr *rogue_shader_insert(struct rogue_shader *shader,
|
||||
enum rogue_opcode opcode);
|
||||
|
||||
size_t rogue_acquire_drc(struct rogue_shader *shader);
|
||||
void rogue_release_drc(struct rogue_shader *shader, size_t drc);
|
||||
|
||||
#endif /* ROGUE_SHADER_H */
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "rogue_util.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
/**
|
||||
* \file rogue_util.c
|
||||
*
|
||||
* \brief Contains compiler utility and helper functions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Splits and distributes value "source" across "dest_bytes" according to
|
||||
* the ranges specified (from MSB to LSB).
|
||||
*
|
||||
* \param[in] source The source value to be distributed.
|
||||
* \param[in] rangelist The rangelist describing how to distribute "source".
|
||||
* \param[in] dest_size The size of the destination in bytes.
|
||||
* \param[in] dest_bytes The destination byte array.
|
||||
* \return false if invalid inputs were provided, else true.
|
||||
*/
|
||||
bool rogue_distribute_value(uint64_t source,
|
||||
const struct rogue_rangelist *rangelist,
|
||||
size_t dest_size,
|
||||
uint8_t dest_bytes[dest_size])
|
||||
{
|
||||
size_t total_bits_left = 0U;
|
||||
|
||||
/* Check that "value" is actually representable in "total_bits" bits. */
|
||||
total_bits_left = rogue_rangelist_bits(rangelist);
|
||||
assert(util_last_bit64(source) <= total_bits_left &&
|
||||
"Value cannot be represented.");
|
||||
|
||||
/* Iterate over each range. */
|
||||
for (size_t u = 0U; u < rangelist->num_ranges; ++u) {
|
||||
struct rogue_bitrange *range = &rangelist->ranges[u];
|
||||
|
||||
size_t dest_bit = range->start;
|
||||
size_t bits_left = range->num;
|
||||
size_t bytes_covered = rogue_bytes_spilled(range) + 1;
|
||||
size_t base_byte = rogue_byte_index(range, dest_size);
|
||||
|
||||
/* Iterate over each byte covered by the current range. */
|
||||
for (size_t b = 0U; b < bytes_covered; ++b) {
|
||||
size_t max_bits = rogue_max_bits(dest_bit);
|
||||
size_t bits_to_place = MIN2(bits_left, max_bits);
|
||||
size_t dest_byte_bit = dest_bit % 8;
|
||||
size_t source_bit = total_bits_left - 1;
|
||||
|
||||
/* Mask and shuffle the source value so that it'll fit into the
|
||||
* correct place in the destination byte:
|
||||
*/
|
||||
|
||||
/* Extract bits. */
|
||||
uint64_t value_masked =
|
||||
(source & BITMASK64_N(source_bit, bits_to_place));
|
||||
/* Shift all the way right. */
|
||||
value_masked >>= (1 + source_bit - bits_to_place);
|
||||
/* Shift left to the correct position. */
|
||||
value_masked <<= (1 + dest_byte_bit - bits_to_place);
|
||||
/* Place value into byte. */
|
||||
dest_bytes[base_byte + b] |= (value_masked & 0xff);
|
||||
|
||||
dest_bit -= max_bits;
|
||||
bits_left -= bits_to_place;
|
||||
total_bits_left -= bits_to_place;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,320 @@
|
|||
/*
|
||||
* 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 ROGUE_UTIL_H
|
||||
#define ROGUE_UTIL_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util/bitscan.h"
|
||||
#include "util/log.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
/* Input validation helpers. */
|
||||
|
||||
/**
|
||||
* \brief Returns false if "expr" is not asserted.
|
||||
*
|
||||
* \param[in] expr The expression to check.
|
||||
*/
|
||||
#define CHECK(expr) \
|
||||
do { \
|
||||
if (!(expr)) \
|
||||
return false; \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* \brief Returns false if "expr" is not asserted,
|
||||
* and logs the provided error message.
|
||||
*
|
||||
* \param[in] expr The expression to check.
|
||||
* \param[in] fmt The error message to print.
|
||||
* \param[in] ... The printf-style varable arguments.
|
||||
*/
|
||||
#define CHECKF(expr, fmt, ...) \
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
mesa_log(MESA_LOG_ERROR, "ROGUE", fmt, ##__VA_ARGS__); \
|
||||
return false; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* \brief Asserts if "opcode" is invalid.
|
||||
*
|
||||
* \param[in] opcode The opcode to check.
|
||||
*/
|
||||
#define ASSERT_OPCODE_RANGE(opcode) assert((opcode) < ROGUE_OP_COUNT)
|
||||
|
||||
/**
|
||||
* \brief Asserts if "operand" is invalid.
|
||||
*
|
||||
* \param[in] operand The operand to check.
|
||||
*/
|
||||
#define ASSERT_OPERAND_RANGE(operand) \
|
||||
assert((operand) < ROGUE_OPERAND_TYPE_COUNT)
|
||||
|
||||
/**
|
||||
* \brief Asserts if "operand" is not a register.
|
||||
*
|
||||
* \param[in] operand The operand to check.
|
||||
*/
|
||||
#define ASSERT_OPERAND_REG(operand) \
|
||||
assert((operand) <= ROGUE_OPERAND_TYPE_REG_MAX)
|
||||
|
||||
/**
|
||||
* \brief Asserts if "flag" is invalid.
|
||||
*
|
||||
* \param[in] flag The flag to check.
|
||||
*/
|
||||
#define ASSERT_INSTR_FLAG_RANGE(flag) assert((flag) < ROGUE_INSTR_FLAG_COUNT)
|
||||
|
||||
/**
|
||||
* \brief Asserts if operand index "index" is out of range.
|
||||
*
|
||||
* \param[in] instr The target instruction.
|
||||
* \param[in] index The operand index to check.
|
||||
*/
|
||||
#define ASSERT_INSTR_OPERAND_INDEX(instr, index) \
|
||||
assert((index) < (instr)->num_operands)
|
||||
|
||||
/**
|
||||
* \brief Asserts if "stage" is invalid.
|
||||
*
|
||||
* \param[in] stage The stage to check.
|
||||
*/
|
||||
#define ASSERT_SHADER_STAGE_RANGE(stage) assert((stage) < MESA_SHADER_STAGES)
|
||||
|
||||
/**
|
||||
* \brief Creates a "n"-bit mask starting from bit "b".
|
||||
*
|
||||
* \param[in] b The starting bit.
|
||||
* \param[in] n The number of bits in the mask.
|
||||
*/
|
||||
#define BITMASK64_N(b, n) (((~0ULL) << (64 - (n))) >> (63 - (b)))
|
||||
|
||||
/**
|
||||
* \brief Compile-time rogue_onehot.
|
||||
*
|
||||
* \sa #rogue_onehot()
|
||||
*/
|
||||
#define ROH(OFFSET) BITFIELD64_BIT(OFFSET)
|
||||
|
||||
/* TODO: Consider integrating the following into src/util/{macros,bitscan}.h */
|
||||
|
||||
/**
|
||||
* \brief Converts a one-hot encoding to an offset encoding.
|
||||
*
|
||||
* E.g. 0b10000 -> 4
|
||||
*
|
||||
* \param[in] onehot The one-hot encoding.
|
||||
* \return The offset encoding.
|
||||
*/
|
||||
static inline uint64_t rogue_offset(uint64_t onehot)
|
||||
{
|
||||
assert(util_bitcount64(onehot) == 1);
|
||||
return ffsll(onehot) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Converts an offset encoding to a one-hot encoding.
|
||||
*
|
||||
* E.g. 0 -> 0b1
|
||||
*
|
||||
* \param[in] offset The offset encoding.
|
||||
* \return The one-hot encoding.
|
||||
*/
|
||||
static inline uint64_t rogue_onehot(uint64_t offset)
|
||||
{
|
||||
assert(offset < 64ULL);
|
||||
return (1ULL << offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Checks whether an input bitfield contains only a valid bitset.
|
||||
*
|
||||
* E.g. rogue_check_bitset(0b00001100, 0b00001111) -> true
|
||||
* rogue_check_bitset(0b00001100, 0b00000111) -> false
|
||||
*
|
||||
* \param[in] input The input bitfield.
|
||||
* \param[in] valid_bits The valid bitset.
|
||||
* \return true if "input" contains only "valid_bits", false otherwise.
|
||||
*/
|
||||
static inline bool rogue_check_bitset(uint64_t input, uint64_t valid_bits)
|
||||
{
|
||||
input &= ~valid_bits;
|
||||
return !input;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Describes a downward range of bits within an arbitrarily-sized
|
||||
* sequence.
|
||||
*
|
||||
* E.g. for start = 7 and num = 3:
|
||||
*
|
||||
* 76543210
|
||||
* abcdefgh
|
||||
*
|
||||
* the bit range would be: abc.
|
||||
*/
|
||||
struct rogue_bitrange {
|
||||
size_t start;
|
||||
size_t num;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Describes a collection of bit-ranges within an arbitrarily-sized
|
||||
* sequence that are meaningful together.
|
||||
*
|
||||
* E.g. an 8-bit value that is encoded within a larger value:
|
||||
* 8-bit value: abcdefgh
|
||||
* Parent value: 010ab0cdef0010gh
|
||||
*
|
||||
*/
|
||||
struct rogue_rangelist {
|
||||
size_t num_ranges;
|
||||
struct rogue_bitrange *ranges;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Counts the total number of bits described in a rangelist.
|
||||
*
|
||||
* \param[in] rangelist The input rangelist.
|
||||
* \return The total number of bits.
|
||||
*/
|
||||
static inline size_t
|
||||
rogue_rangelist_bits(const struct rogue_rangelist *rangelist)
|
||||
{
|
||||
size_t total_bits = 0U;
|
||||
|
||||
for (size_t u = 0U; u < rangelist->num_ranges; ++u)
|
||||
total_bits += rangelist->ranges[u].num;
|
||||
|
||||
return total_bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the byte offset of the bitrange moving left from the LSB.
|
||||
*
|
||||
* \param[in] bitrange The input bit-range.
|
||||
* \return The byte offset.
|
||||
*/
|
||||
static inline size_t rogue_byte_num(const struct rogue_bitrange *bitrange)
|
||||
{
|
||||
/* Make sure there are enough bits. */
|
||||
assert(bitrange->num <= (bitrange->start + 1));
|
||||
|
||||
return bitrange->start / 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the array-indexable byte offset of a bit-range if the sequence
|
||||
* it represents were to be stored in an byte-array containing "num_bytes"
|
||||
* bytes.
|
||||
*
|
||||
* E.g. uint8_t array[2] is a sequence of 16 bits:
|
||||
* bit(0) is located in array[1].
|
||||
* bit(15) is located in array[0].
|
||||
*
|
||||
* For uint8_t array[4]:
|
||||
* bit(0) is located in array[3].
|
||||
* bit(15) is located in array[2].
|
||||
*
|
||||
* \param[in] bitrange The input bit-range.
|
||||
* \param[in] num_bytes The number of bytes that are used to contain the
|
||||
* bit-range. \return The byte offset.
|
||||
*/
|
||||
static inline size_t rogue_byte_index(const struct rogue_bitrange *bitrange,
|
||||
size_t num_bytes)
|
||||
{
|
||||
/* Make sure there are enough bits. */
|
||||
assert(bitrange->num <= (bitrange->start + 1));
|
||||
|
||||
return num_bytes - rogue_byte_num(bitrange) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the bit offset of a bit-range if the sequence it represents is
|
||||
* being accessed in a byte-wise manner.
|
||||
*
|
||||
* E.g. bit 17 has a bit offset of 1.
|
||||
*
|
||||
* \param[in] bitrange The input bit-range.
|
||||
* \return The bit offset.
|
||||
*/
|
||||
static inline size_t rogue_bit_offset(const struct rogue_bitrange *bitrange)
|
||||
{
|
||||
/* Make sure there are enough bits. */
|
||||
assert(bitrange->num <= (bitrange->start + 1));
|
||||
|
||||
return bitrange->start % 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the number of additional bytes that the bit-range spills into
|
||||
* (excluding its "starting" byte).
|
||||
*
|
||||
* \param[in] bitrange The input bit-range.
|
||||
* \return The number of bytes spilled.
|
||||
*/
|
||||
static inline size_t rogue_bytes_spilled(const struct rogue_bitrange *bitrange)
|
||||
{
|
||||
/* Make sure there are enough bits. */
|
||||
assert(bitrange->num <= (bitrange->start + 1));
|
||||
|
||||
return ((bitrange->num - 1) / 8) +
|
||||
((bitrange->num % 8) > (rogue_bit_offset(bitrange) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief For a given bit offset, returns the maximum number of bits (including
|
||||
* itself) that are accessible before spilling into the following byte.
|
||||
*
|
||||
* E.g. When trying to insert an 8-bit value offset of 13, a maximum of 6 bits
|
||||
* can be placed; the last 2 bits will need to go into the next byte.
|
||||
*
|
||||
* 8-bit value: abcdefgh
|
||||
*
|
||||
* array[0] array[1]
|
||||
* 15 8 7 0
|
||||
* iiiiiiii jjjjjjjj
|
||||
* ^
|
||||
* abcdef gh
|
||||
*
|
||||
* \param[in] The bit offset.
|
||||
* \return The maximum number of accessible bits.
|
||||
*/
|
||||
static inline size_t rogue_max_bits(size_t offset)
|
||||
{
|
||||
return (offset % 8) + 1;
|
||||
}
|
||||
|
||||
bool rogue_distribute_value(uint64_t source,
|
||||
const struct rogue_rangelist *rangelist,
|
||||
size_t dest_size,
|
||||
uint8_t dest_bytes[dest_size]);
|
||||
|
||||
#endif /* ROGUE_UTIL_H */
|
|
@ -0,0 +1,288 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file rogue_validate.c
|
||||
*
|
||||
* \brief Contains rules and functions for validating Rogue data structures.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "rogue_operand.h"
|
||||
#include "rogue_shader.h"
|
||||
#include "rogue_util.h"
|
||||
#include "rogue_validate.h"
|
||||
#include "util/list.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
/**
|
||||
* \brief Register operand rules.
|
||||
*/
|
||||
#define REG_RULE(OPERAND, ACCESS, MAX, MODIFIERS) \
|
||||
[ROGUE_OPERAND_TYPE_REG_##OPERAND] = { \
|
||||
.access = ROGUE_REG_ACCESS_##ACCESS, \
|
||||
.max = MAX, \
|
||||
.modifiers = ROGUE_REG_MOD_##MODIFIERS, \
|
||||
}
|
||||
|
||||
/* TODO: Support register indexing > ROGUE_MAX_REG_TEMP. */
|
||||
static const struct rogue_register_rule reg_rules[ROGUE_NUM_REG_TYPES] = {
|
||||
REG_RULE(TEMP, RW, MIN2(ROGUE_MAX_REG_INDEX, ROGUE_MAX_REG_TEMP), ALL),
|
||||
REG_RULE(COEFF, RW, MIN2(ROGUE_MAX_REG_INDEX, ROGUE_MAX_REG_COEFF), ALL),
|
||||
REG_RULE(CONST, RW, MIN2(ROGUE_MAX_REG_INDEX, ROGUE_MAX_REG_CONST), NONE),
|
||||
REG_RULE(SHARED, RW, MIN2(ROGUE_MAX_REG_INDEX, ROGUE_MAX_REG_SHARED), ALL),
|
||||
REG_RULE(PIXEL_OUT,
|
||||
RW,
|
||||
MIN2(ROGUE_MAX_REG_INDEX, ROGUE_MAX_REG_PIXEL_OUT),
|
||||
NONE),
|
||||
REG_RULE(VERTEX_IN,
|
||||
RW,
|
||||
MIN2(ROGUE_MAX_REG_INDEX, ROGUE_MAX_REG_VERTEX_IN),
|
||||
ALL),
|
||||
REG_RULE(INTERNAL,
|
||||
RW,
|
||||
MIN2(ROGUE_MAX_REG_INDEX, ROGUE_MAX_REG_INTERNAL),
|
||||
NONE),
|
||||
};
|
||||
#undef REG_RULE
|
||||
|
||||
/**
|
||||
* \brief Instruction rules.
|
||||
*/
|
||||
/* TODO: Common up register classes to prevent long lines. */
|
||||
static const struct rogue_instr_rule instr_rules[ROGUE_OP_COUNT] = {
|
||||
[ROGUE_OP_NOP] = { .flags = 0, .num_operands = 0, .operand_rules = NULL, },
|
||||
[ROGUE_OP_END_FRAG] = { .flags = 0, .num_operands = 0, .operand_rules = NULL, },
|
||||
[ROGUE_OP_END_VERT] = { .flags = 0, .num_operands = 0, .operand_rules = NULL, },
|
||||
[ROGUE_OP_WDF] = { .flags = 0,
|
||||
.num_operands = 1, .operand_rules = (struct rogue_instr_operand_rule[]){
|
||||
[0] = { .mask = ROH(ROGUE_OPERAND_TYPE_DRC), .min = -1, .max = -1, .align = -1, },
|
||||
},
|
||||
},
|
||||
[ROGUE_OP_PIX_ITER_W] = { .flags = ROH(ROGUE_INSTR_FLAG_SAT),
|
||||
.num_operands = 5, .operand_rules = (struct rogue_instr_operand_rule[]){
|
||||
[0] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_TEMP), .min = -1, .max = -1, .align = -1, },
|
||||
[1] = { .mask = ROH(ROGUE_OPERAND_TYPE_DRC), .min = -1, .max = -1, .align = -1, },
|
||||
[2] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_COEFF), .min = -1, .max = -1, .align = ROGUE_COEFF_ALIGN, },
|
||||
[3] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_COEFF), .min = -1, .max = -1, .align = ROGUE_COEFF_ALIGN, },
|
||||
[4] = { .mask = ROH(ROGUE_OPERAND_TYPE_IMMEDIATE), .min = 1, .max = 16, .align = -1, },
|
||||
},
|
||||
},
|
||||
[ROGUE_OP_MAX] = { .flags = 0,
|
||||
.num_operands = 3, .operand_rules = (struct rogue_instr_operand_rule[]){
|
||||
[0] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_TEMP), .min = -1, .max = -1, .align = -1, },
|
||||
[1] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_TEMP), .min = -1, .max = -1, .align = -1, },
|
||||
[2] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_CONST) | ROH(ROGUE_OPERAND_TYPE_REG_TEMP), .min = -1, .max = -1, .align = -1, },
|
||||
},
|
||||
},
|
||||
[ROGUE_OP_MIN] = { .flags = 0,
|
||||
.num_operands = 3, .operand_rules = (struct rogue_instr_operand_rule[]){
|
||||
[0] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_TEMP) | ROH(ROGUE_OPERAND_TYPE_REG_INTERNAL), .min = -1, .max = -1, .align = -1, },
|
||||
[1] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_TEMP), .min = -1, .max = -1, .align = -1, },
|
||||
[2] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_CONST) | ROH(ROGUE_OPERAND_TYPE_REG_TEMP), .min = -1, .max = -1, .align = -1, },
|
||||
},
|
||||
},
|
||||
/* TODO: Add representation for 4 sequential registers. */
|
||||
[ROGUE_OP_PACK_U8888] = { .flags = 0,
|
||||
.num_operands = 2, .operand_rules = (struct rogue_instr_operand_rule[]){
|
||||
[0] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_TEMP), .min = -1, .max = -1, .align = -1, },
|
||||
[1] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_INTERNAL), .min = -1, .max = -1, .align = -1, },
|
||||
},
|
||||
},
|
||||
[ROGUE_OP_MOV] = { .flags = ROH(ROGUE_INSTR_FLAG_OLCHK),
|
||||
.num_operands = 2, .operand_rules = (struct rogue_instr_operand_rule[]){
|
||||
[0] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_TEMP) | ROH(ROGUE_OPERAND_TYPE_REG_INTERNAL) | ROH(ROGUE_OPERAND_TYPE_REG_PIXEL_OUT), .min = -1, .max = -1, .align = -1, },
|
||||
[1] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_CONST) | ROH(ROGUE_OPERAND_TYPE_REG_TEMP) | ROH(ROGUE_OPERAND_TYPE_REG_SHARED) | ROH(ROGUE_OPERAND_TYPE_REG_VERTEX_IN), .min = -1, .max = -1, .align = -1, },
|
||||
},
|
||||
},
|
||||
[ROGUE_OP_MOV_IMM] = { .flags = 0,
|
||||
.num_operands = 2, .operand_rules = (struct rogue_instr_operand_rule[]){
|
||||
[0] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_TEMP), .min = -1, .max = -1, .align = -1, },
|
||||
[1] = { .mask = ROH(ROGUE_OPERAND_TYPE_IMMEDIATE), .min = 0, .max = UINT32_MAX, .align = -1, },
|
||||
},
|
||||
},
|
||||
[ROGUE_OP_FMA] = { .flags = ROH(ROGUE_INSTR_FLAG_SAT) | ROH(ROGUE_INSTR_FLAG_LP),
|
||||
.num_operands = 4, .operand_rules = (struct rogue_instr_operand_rule[]){
|
||||
[0] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_TEMP), .min = -1, .max = -1, .align = -1, },
|
||||
[1] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_TEMP), .min = -1, .max = -1, .align = -1, },
|
||||
[2] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_TEMP), .min = -1, .max = -1, .align = -1, },
|
||||
[3] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_TEMP), .min = -1, .max = -1, .align = -1, },
|
||||
},
|
||||
},
|
||||
[ROGUE_OP_MUL] = { .flags = ROH(ROGUE_INSTR_FLAG_SAT) | ROH(ROGUE_INSTR_FLAG_LP),
|
||||
.num_operands = 3, .operand_rules = (struct rogue_instr_operand_rule[]){
|
||||
[0] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_TEMP), .min = -1, .max = -1, .align = -1, },
|
||||
[1] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_TEMP), .min = -1, .max = -1, .align = -1, },
|
||||
[2] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_TEMP), .min = -1, .max = -1, .align = -1, },
|
||||
},
|
||||
},
|
||||
[ROGUE_OP_VTXOUT] = { .flags = 0,
|
||||
.num_operands = 2, .operand_rules = (struct rogue_instr_operand_rule[]){
|
||||
[0] = { .mask = ROH(ROGUE_OPERAND_TYPE_IMMEDIATE), .min = 0, .max = ROGUE_MAX_VERTEX_OUTPUTS, .align = -1, },
|
||||
[1] = { .mask = ROH(ROGUE_OPERAND_TYPE_REG_TEMP), .min = -1, .max = -1, .align = -1, },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Validates an operand.
|
||||
*
|
||||
* \param[in] operand The operand.
|
||||
* \return true if valid, otherwise false.
|
||||
*/
|
||||
bool rogue_validate_operand(const struct rogue_operand *operand)
|
||||
{
|
||||
ASSERT_OPERAND_RANGE(operand->type);
|
||||
|
||||
switch (operand->type) {
|
||||
case ROGUE_OPERAND_TYPE_IMMEDIATE:
|
||||
return true;
|
||||
|
||||
case ROGUE_OPERAND_TYPE_DRC:
|
||||
CHECKF(operand->drc.number < ROGUE_NUM_DRCS,
|
||||
"Invalid DRC number '%zu'.",
|
||||
operand->drc.number);
|
||||
return true;
|
||||
|
||||
case ROGUE_OPERAND_TYPE_REG_TEMP:
|
||||
case ROGUE_OPERAND_TYPE_REG_COEFF:
|
||||
case ROGUE_OPERAND_TYPE_REG_CONST:
|
||||
case ROGUE_OPERAND_TYPE_REG_SHARED:
|
||||
case ROGUE_OPERAND_TYPE_REG_PIXEL_OUT:
|
||||
case ROGUE_OPERAND_TYPE_REG_VERTEX_IN:
|
||||
case ROGUE_OPERAND_TYPE_REG_INTERNAL:
|
||||
CHECKF(operand->reg.number < reg_rules[operand->type].max,
|
||||
"Register number '%zu' out of range.",
|
||||
operand->reg.number);
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Validates an instruction.
|
||||
*
|
||||
* \param[in] instr The instruction.
|
||||
* \return true if valid, otherwise false.
|
||||
*/
|
||||
bool rogue_validate_instr(const struct rogue_instr *instr)
|
||||
{
|
||||
const struct rogue_instr_rule *rule;
|
||||
|
||||
ASSERT_OPCODE_RANGE(instr->opcode);
|
||||
|
||||
rule = &instr_rules[instr->opcode];
|
||||
|
||||
/* Validate flags. */
|
||||
CHECKF(rogue_check_bitset(instr->flags, rule->flags),
|
||||
"Invalid instruction flags specified.");
|
||||
|
||||
/* Validate number of operands. */
|
||||
CHECKF(instr->num_operands == rule->num_operands,
|
||||
"Invalid number of operands specified.");
|
||||
|
||||
CHECK(!rule->num_operands || instr->operands);
|
||||
for (size_t u = 0U; u < instr->num_operands; ++u) {
|
||||
/* Validate operand types. */
|
||||
CHECKF(rogue_check_bitset(rogue_onehot(instr->operands[u].type),
|
||||
rule->operand_rules[u].mask),
|
||||
"Invalid type for operand %zu.",
|
||||
u);
|
||||
|
||||
/* Validate immediate ranges. */
|
||||
if (rogue_check_bitset(rogue_onehot(instr->operands[u].type),
|
||||
ROH(ROGUE_OPERAND_TYPE_IMMEDIATE)) &&
|
||||
rule->operand_rules[u].min != -1 &&
|
||||
rule->operand_rules[u].max != -1) {
|
||||
CHECKF(
|
||||
instr->operands[u].immediate.value >= rule->operand_rules[u].min &&
|
||||
instr->operands[u].immediate.value <= rule->operand_rules[u].max,
|
||||
"Immediate value out of range for operand %zu.",
|
||||
u);
|
||||
}
|
||||
|
||||
/* Validate register alignment. */
|
||||
if (rogue_check_bitset(rogue_onehot(instr->operands[u].type),
|
||||
ROGUE_MASK_ANY_REG) &&
|
||||
rule->operand_rules[u].align != -1) {
|
||||
CHECKF(!(instr->operands[u].reg.number % rule->operand_rules[u].align),
|
||||
"Invalid register alignment in operand %zu.",
|
||||
u);
|
||||
}
|
||||
|
||||
/* Validate each operand. */
|
||||
CHECKF(rogue_validate_operand(&instr->operands[u]),
|
||||
"Failed to validate operand.");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Validates a shader.
|
||||
*
|
||||
* \param[in] shader The shader.
|
||||
* \return true if valid, otherwise false.
|
||||
*/
|
||||
bool rogue_validate_shader(const struct rogue_shader *shader)
|
||||
{
|
||||
CHECK(!list_is_empty(&shader->instr_list));
|
||||
ASSERT_SHADER_STAGE_RANGE(shader->stage);
|
||||
|
||||
/* Shader stage-specific validation. */
|
||||
switch (shader->stage) {
|
||||
case MESA_SHADER_VERTEX:
|
||||
/* Make sure there is (only) one end vertex shader instruction. */
|
||||
CHECKF(rogue_shader_instr_count_type(shader, ROGUE_OP_END_VERT) == 1,
|
||||
"Shader must contain a single end.vert instruction.");
|
||||
|
||||
/* Make sure the end vertex shader instruction is the last one. */
|
||||
CHECKF(instr_last_entry(&shader->instr_list)->opcode == ROGUE_OP_END_VERT,
|
||||
"end.vert not last instruction.");
|
||||
break;
|
||||
|
||||
case MESA_SHADER_FRAGMENT:
|
||||
/* Make sure there is (only) one end fragment shader instruction. */
|
||||
CHECKF(rogue_shader_instr_count_type(shader, ROGUE_OP_END_FRAG) == 1,
|
||||
"Shader must contain a single end.frag instruction.");
|
||||
|
||||
/* Make sure the end fragment shader instruction is the last one. */
|
||||
CHECKF(instr_last_entry(&shader->instr_list)->opcode == ROGUE_OP_END_FRAG,
|
||||
"end.frag not last instruction.");
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Validate each instruction. */
|
||||
foreach_instr (instr, &shader->instr_list)
|
||||
CHECKF(rogue_validate_instr(instr), "Failed to validate instruction.");
|
||||
|
||||
return true;
|
||||
}
|
|
@ -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.
|
||||
*/
|
||||
|
||||
#ifndef ROGUE_VALIDATE_H
|
||||
#define ROGUE_VALIDATE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "rogue_instr.h"
|
||||
#include "rogue_operand.h"
|
||||
#include "rogue_shader.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
/**
|
||||
* \brief Register rule description.
|
||||
*/
|
||||
struct rogue_register_rule {
|
||||
enum rogue_register_access access;
|
||||
size_t max;
|
||||
enum rogue_register_modifier modifiers;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Instruction operand rule description.
|
||||
*/
|
||||
struct rogue_instr_operand_rule {
|
||||
uint64_t mask;
|
||||
ssize_t min;
|
||||
ssize_t max;
|
||||
ssize_t align;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Instruction rule description.
|
||||
*/
|
||||
struct rogue_instr_rule {
|
||||
uint64_t flags; /** A mask of #rogue_instr_flag values. */
|
||||
size_t num_operands;
|
||||
struct rogue_instr_operand_rule *operand_rules;
|
||||
};
|
||||
|
||||
PUBLIC
|
||||
bool rogue_validate_operand(const struct rogue_operand *operand);
|
||||
|
||||
PUBLIC
|
||||
bool rogue_validate_instr(const struct rogue_instr *instr);
|
||||
|
||||
PUBLIC
|
||||
bool rogue_validate_shader(const struct rogue_shader *shader);
|
||||
|
||||
#endif /* ROGUE_VALIDATE_H */
|
|
@ -0,0 +1,314 @@
|
|||
/*
|
||||
* 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 "compiler/shader_enums.h"
|
||||
#include "nir/nir.h"
|
||||
#include "rogue.h"
|
||||
#include "rogue_build_data.h"
|
||||
#include "rogue_compiler.h"
|
||||
#include "rogue_dump.h"
|
||||
#include "util/os_file.h"
|
||||
#include "util/ralloc.h"
|
||||
|
||||
#include <getopt.h>
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Number of hex columns to dump before starting a new line. */
|
||||
#define ARRAY_DUMP_COLS 16
|
||||
|
||||
/**
|
||||
* \file compiler.c
|
||||
*
|
||||
* \brief Rogue offline compiler.
|
||||
*/
|
||||
|
||||
static const struct option cmdline_opts[] = {
|
||||
/* Arguments. */
|
||||
{ "stage", required_argument, NULL, 's' },
|
||||
{ "file", required_argument, NULL, 'f' },
|
||||
{ "entry", required_argument, NULL, 'e' },
|
||||
|
||||
/* Options. */
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "out", required_argument, NULL, 'o' },
|
||||
|
||||
{ "dump-c-array", no_argument, NULL, 'c' },
|
||||
{ "dump-rogue", no_argument, NULL, 'r' },
|
||||
{ "dump-nir", no_argument, NULL, 'n' },
|
||||
|
||||
{ NULL, 0, NULL, 0 },
|
||||
};
|
||||
|
||||
struct compiler_opts {
|
||||
gl_shader_stage stage;
|
||||
char *file;
|
||||
char *entry;
|
||||
char *out_file;
|
||||
bool dump_c_array;
|
||||
bool dump_rogue;
|
||||
bool dump_nir;
|
||||
};
|
||||
|
||||
static void usage(const char *argv0)
|
||||
{
|
||||
/* clang-format off */
|
||||
printf("Rogue offline compiler.\n");
|
||||
printf("Usage: %s -s <stage> -f <file> [-e <entry>] [-o <file>] [-c] [-r] [-n] [-h]\n", argv0);
|
||||
printf("\n");
|
||||
|
||||
printf("Required arguments:\n");
|
||||
printf("\t-s, --stage <stage> Shader stage (supported options: frag, vert).\n");
|
||||
printf("\t-f, --file <file> Shader SPIR-V filename.\n");
|
||||
printf("\n");
|
||||
|
||||
printf("Options:\n");
|
||||
printf("\t-h, --help Prints this help message.\n");
|
||||
printf("\t-e, --entry <entry> Overrides the shader entry-point name (default: 'main').\n");
|
||||
printf("\t-o, --out <file> Overrides the output filename (default: 'out.bin').\n");
|
||||
printf("\n");
|
||||
|
||||
printf("\t-c, --dump-c-array Print the shader binary as a C byte array.\n");
|
||||
printf("\t-r, --dump-rogue Prints the shader Rogue assembly.\n");
|
||||
printf("\t-n, --dump-nir Prints the shader NIR.\n");
|
||||
printf("\n");
|
||||
/* clang-format on */
|
||||
}
|
||||
|
||||
static bool parse_cmdline(int argc, char *argv[], struct compiler_opts *opts)
|
||||
{
|
||||
int opt;
|
||||
int longindex;
|
||||
|
||||
while (
|
||||
(opt =
|
||||
getopt_long(argc, argv, "crnhs:f:e:o:", cmdline_opts, &longindex)) !=
|
||||
-1) {
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
opts->dump_c_array = true;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
if (opts->entry)
|
||||
continue;
|
||||
|
||||
opts->entry = optarg;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (opts->file)
|
||||
continue;
|
||||
|
||||
opts->file = optarg;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
opts->dump_nir = true;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
if (opts->out_file)
|
||||
continue;
|
||||
|
||||
opts->out_file = optarg;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
opts->dump_rogue = true;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (opts->stage != MESA_SHADER_NONE)
|
||||
continue;
|
||||
|
||||
if (!strcmp(optarg, "frag"))
|
||||
opts->stage = MESA_SHADER_FRAGMENT;
|
||||
else if (!strcmp(optarg, "vert"))
|
||||
opts->stage = MESA_SHADER_VERTEX;
|
||||
else {
|
||||
fprintf(stderr, "Invalid stage \"%s\".\n", optarg);
|
||||
usage(argv[0]);
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
default:
|
||||
usage(argv[0]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (opts->stage == MESA_SHADER_NONE || !opts->file) {
|
||||
fprintf(stderr,
|
||||
"%s: --stage and --file are required arguments.\n",
|
||||
argv[0]);
|
||||
usage(argv[0]);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!opts->out_file)
|
||||
opts->out_file = "out.bin";
|
||||
|
||||
if (!opts->entry)
|
||||
opts->entry = "main";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
/* Command-line options. */
|
||||
/* N.B. MESA_SHADER_NONE != 0 */
|
||||
struct compiler_opts opts = { .stage = MESA_SHADER_NONE, 0 };
|
||||
|
||||
/* Input file data. */
|
||||
char *input_data;
|
||||
size_t input_size;
|
||||
|
||||
/* Compiler context. */
|
||||
struct rogue_compiler *compiler;
|
||||
|
||||
/* Multi-stage build context. */
|
||||
struct rogue_build_ctx *ctx;
|
||||
|
||||
/* Output file. */
|
||||
FILE *fp;
|
||||
size_t bytes_written;
|
||||
|
||||
/* Parse command-line options. */
|
||||
if (!parse_cmdline(argc, argv, &opts))
|
||||
return 1;
|
||||
|
||||
/* Load SPIR-V input file. */
|
||||
input_data = os_read_file(opts.file, &input_size);
|
||||
if (!input_data) {
|
||||
fprintf(stderr, "Failed to read file \"%s\".\n", opts.file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Create compiler context. */
|
||||
compiler = rogue_compiler_create(NULL);
|
||||
if (!compiler) {
|
||||
fprintf(stderr, "Failed to set up compiler context.\n");
|
||||
goto err_free_input;
|
||||
}
|
||||
|
||||
ctx = rogue_create_build_context(compiler);
|
||||
if (!ctx) {
|
||||
fprintf(stderr, "Failed to set up build context.\n");
|
||||
goto err_destroy_compiler;
|
||||
}
|
||||
|
||||
/* SPIR-V -> NIR. */
|
||||
ctx->nir[opts.stage] = rogue_spirv_to_nir(ctx,
|
||||
opts.stage,
|
||||
opts.entry,
|
||||
input_size / sizeof(uint32_t),
|
||||
(uint32_t *)input_data,
|
||||
0,
|
||||
NULL);
|
||||
if (!ctx->nir[opts.stage]) {
|
||||
fprintf(stderr, "Failed to translate SPIR-V input to NIR.\n");
|
||||
goto err_free_build_context;
|
||||
}
|
||||
|
||||
/* Dump NIR shader. */
|
||||
if (opts.dump_nir)
|
||||
nir_print_shader(ctx->nir[opts.stage], stdout);
|
||||
|
||||
/* NIR -> Rogue. */
|
||||
ctx->rogue[opts.stage] = rogue_nir_to_rogue(ctx, ctx->nir[opts.stage]);
|
||||
if (!ctx->rogue[opts.stage]) {
|
||||
fprintf(stderr, "Failed to translate NIR input to Rogue.\n");
|
||||
goto err_free_build_context;
|
||||
}
|
||||
|
||||
/* Dump Rogue shader. */
|
||||
if (opts.dump_rogue)
|
||||
rogue_dump_shader(ctx->rogue[opts.stage], stdout);
|
||||
|
||||
/* Rogue -> Binary. */
|
||||
ctx->binary[opts.stage] = rogue_to_binary(ctx, ctx->rogue[opts.stage]);
|
||||
if (!ctx->binary[opts.stage]) {
|
||||
fprintf(stderr, "Failed to translate Rogue to binary.\n");
|
||||
goto err_free_build_context;
|
||||
}
|
||||
|
||||
/* Dump binary as a C array. */
|
||||
if (opts.dump_c_array) {
|
||||
printf("uint8_t shader_bytes[%zu] = {", ctx->binary[opts.stage]->size);
|
||||
for (size_t u = 0U; u < ctx->binary[opts.stage]->size; ++u) {
|
||||
if (!(u % ARRAY_DUMP_COLS))
|
||||
printf("\n\t");
|
||||
|
||||
printf("0x%02x, ", ctx->binary[opts.stage]->data[u]);
|
||||
}
|
||||
printf("\n};\n");
|
||||
}
|
||||
|
||||
/* Write shader binary to disk. */
|
||||
fp = fopen(opts.out_file, "wb");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "Failed to open output file \"%s\".\n", opts.out_file);
|
||||
goto err_free_build_context;
|
||||
}
|
||||
|
||||
bytes_written = fwrite(ctx->binary[opts.stage]->data,
|
||||
1,
|
||||
ctx->binary[opts.stage]->size,
|
||||
fp);
|
||||
if (bytes_written != ctx->binary[opts.stage]->size) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"Failed to write to output file \"%s\" (%zu bytes of %zu written).\n",
|
||||
opts.out_file,
|
||||
bytes_written,
|
||||
ctx->binary[opts.stage]->size);
|
||||
goto err_close_outfile;
|
||||
}
|
||||
|
||||
/* Clean up. */
|
||||
fclose(fp);
|
||||
ralloc_free(ctx);
|
||||
rogue_compiler_destroy(compiler);
|
||||
free(input_data);
|
||||
|
||||
return 0;
|
||||
|
||||
err_close_outfile:
|
||||
fclose(fp);
|
||||
err_free_build_context:
|
||||
ralloc_free(ctx);
|
||||
err_destroy_compiler:
|
||||
rogue_compiler_destroy(compiler);
|
||||
err_free_input:
|
||||
free(input_data);
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
# 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.
|
||||
|
||||
subdir('pds')
|
||||
|
||||
pvr_entrypoints = custom_target(
|
||||
'pvr_entrypoints',
|
||||
input : [vk_entrypoints_gen, vk_api_xml],
|
||||
output : ['pvr_entrypoints.h', 'pvr_entrypoints.c'],
|
||||
command : [
|
||||
prog_python, '@INPUT0@', '--xml', '@INPUT1@', '--proto', '--weak',
|
||||
'--out-h', '@OUTPUT0@', '--out-c', '@OUTPUT1@', '--prefix', 'pvr',
|
||||
],
|
||||
depend_files : vk_entrypoints_gen_depend_files,
|
||||
)
|
||||
|
||||
pvr_files = files(
|
||||
'winsys/powervr/pvr_drm.c',
|
||||
'winsys/pvr_winsys.c',
|
||||
'winsys/pvr_winsys_helper.c',
|
||||
'pvr_blit.c',
|
||||
'pvr_bo.c',
|
||||
'pvr_cmd_buffer.c',
|
||||
'pvr_csb.c',
|
||||
'pvr_descriptor_set.c',
|
||||
'pvr_device.c',
|
||||
'pvr_formats.c',
|
||||
'pvr_hw_pass.c',
|
||||
'pvr_image.c',
|
||||
'pvr_job_common.c',
|
||||
'pvr_job_compute.c',
|
||||
'pvr_job_context.c',
|
||||
'pvr_job_render.c',
|
||||
'pvr_pass.c',
|
||||
'pvr_pipeline.c',
|
||||
'pvr_pipeline_cache.c',
|
||||
'pvr_query.c',
|
||||
'pvr_queue.c',
|
||||
'pvr_shader.c',
|
||||
'pvr_tex_state.c',
|
||||
'pvr_wsi.c',
|
||||
)
|
||||
|
||||
pvr_includes = [
|
||||
include_directories('usc/programs'),
|
||||
include_directories('winsys'),
|
||||
libpowervr_pds_includes,
|
||||
]
|
||||
|
||||
pvr_deps = [
|
||||
dep_csbgen,
|
||||
dep_libdrm,
|
||||
dep_valgrind,
|
||||
idep_vulkan_runtime,
|
||||
idep_vulkan_util,
|
||||
idep_vulkan_wsi,
|
||||
]
|
||||
|
||||
pvr_flags = [
|
||||
no_override_init_args,
|
||||
]
|
||||
|
||||
if with_imagination_srv
|
||||
pvr_files += files(
|
||||
'winsys/pvrsrvkm/pvr_srv.c',
|
||||
'winsys/pvrsrvkm/pvr_srv_bo.c',
|
||||
'winsys/pvrsrvkm/pvr_srv_bridge.c',
|
||||
'winsys/pvrsrvkm/pvr_srv_job_compute.c',
|
||||
'winsys/pvrsrvkm/pvr_srv_job_render.c',
|
||||
'winsys/pvrsrvkm/pvr_srv_syncobj.c',
|
||||
)
|
||||
pvr_flags += '-DPVR_SUPPORT_SERVICES_DRIVER'
|
||||
endif
|
||||
|
||||
libvulkan_powervr_mesa = shared_library(
|
||||
'vulkan_powervr_mesa',
|
||||
[pvr_files, pvr_entrypoints],
|
||||
include_directories : [
|
||||
pvr_includes,
|
||||
inc_gallium_aux,
|
||||
inc_imagination,
|
||||
inc_include,
|
||||
inc_src,
|
||||
inc_mesa,
|
||||
inc_gallium,
|
||||
inc_compiler,
|
||||
],
|
||||
link_with : [
|
||||
libpowervr_common,
|
||||
libpowervr_pds,
|
||||
libpowervr_rogue,
|
||||
libvulkan_wsi,
|
||||
],
|
||||
dependencies : [
|
||||
pvr_deps,
|
||||
idep_nir,
|
||||
],
|
||||
c_args : pvr_flags,
|
||||
link_args : [
|
||||
ld_args_build_id,
|
||||
ld_args_bsymbolic,
|
||||
ld_args_gc_sections
|
||||
],
|
||||
gnu_symbol_visibility : 'hidden',
|
||||
install : true,
|
||||
)
|
||||
|
||||
if with_symbols_check
|
||||
test(
|
||||
'pvr symbols check',
|
||||
symbols_check,
|
||||
args : [
|
||||
'--lib', libvulkan_powervr_mesa,
|
||||
'--symbols-file', vulkan_icd_symbols,
|
||||
symbols_check_args,
|
||||
],
|
||||
suite : ['imagination'],
|
||||
)
|
||||
endif
|
||||
|
||||
powervr_mesa_icd = custom_target(
|
||||
'powervr_mesa_icd',
|
||||
input : [vk_icd_gen, vk_api_xml],
|
||||
output : 'powervr_mesa_icd.@0@.json'.format(host_machine.cpu()),
|
||||
command : [
|
||||
prog_python, '@INPUT0@',
|
||||
'--api-version', '1.0', '--xml', '@INPUT1@',
|
||||
'--lib-path', join_paths(get_option('prefix'), get_option('libdir'),
|
||||
'libvulkan_powervr_mesa.so'),
|
||||
'--out', '@OUTPUT@',
|
||||
],
|
||||
build_by_default : true,
|
||||
install_dir : with_vulkan_icd_dir,
|
||||
install : true,
|
||||
)
|
||||
|
||||
if meson.version().version_compare('>= 0.58')
|
||||
_dev_icdname = 'powervr_mesa_devenv_icd.@0@.json'.format(host_machine.cpu())
|
||||
custom_target(
|
||||
'powervr_mesa_devenv_icd',
|
||||
input : [vk_icd_gen, vk_api_xml],
|
||||
output : _dev_icdname,
|
||||
command : [
|
||||
prog_python, '@INPUT0@',
|
||||
'--api-version', '1.0', '--xml', '@INPUT1@',
|
||||
'--lib-path', meson.current_build_dir() / 'libvulkan_powervr_mesa.so',
|
||||
'--out', '@OUTPUT@',
|
||||
],
|
||||
build_by_default : true,
|
||||
)
|
||||
|
||||
devenv.append('VK_ICD_FILENAMES', meson.current_build_dir() / _dev_icdname)
|
||||
endif
|
|
@ -0,0 +1,50 @@
|
|||
# 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.
|
||||
|
||||
|
||||
libpowervr_pds_files = files(
|
||||
'pvr_pds.c',
|
||||
'pvr_pds_disasm.c',
|
||||
'pvr_pds_printer.c',
|
||||
'pvr_xgl_pds.c',
|
||||
)
|
||||
|
||||
libpowervr_pds_includes = include_directories(
|
||||
'..',
|
||||
'.',
|
||||
'pvr_pds_programs',
|
||||
)
|
||||
|
||||
libpowervr_pds = static_library(
|
||||
'pvr_pds',
|
||||
[libpowervr_pds_files],
|
||||
include_directories : [
|
||||
libpowervr_pds_includes,
|
||||
inc_include,
|
||||
inc_src,
|
||||
inc_imagination,
|
||||
],
|
||||
c_args : [
|
||||
no_override_init_args,
|
||||
],
|
||||
gnu_symbol_visibility : 'hidden',
|
||||
pic : true,
|
||||
)
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,666 @@
|
|||
/*
|
||||
* 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 <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "pvr_rogue_pds_defs.h"
|
||||
#include "pvr_rogue_pds_disasm.h"
|
||||
#include "pvr_rogue_pds_encode.h"
|
||||
#include "util/log.h"
|
||||
|
||||
#define X(lop, str) #str,
|
||||
static const char *const LOP[] = { PVR_PDS_LOP };
|
||||
#undef X
|
||||
|
||||
static void pvr_pds_disassemble_operand(struct pvr_operand *op,
|
||||
char *instr_str,
|
||||
size_t instr_len)
|
||||
{
|
||||
#define X(enum, str, size) { #str, #size },
|
||||
static const char *const regs[][2] = { PVR_PDS_OPERAND_TYPES };
|
||||
#undef X
|
||||
|
||||
if (op->type == LITERAL_NUM) {
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%s (%llu)",
|
||||
regs[op->type][0],
|
||||
(unsigned long long)op->literal);
|
||||
} else if (op->type == UNRESOLVED) {
|
||||
snprintf(instr_str, instr_len, "UNRESOLVED");
|
||||
} else {
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%s[%u].%s",
|
||||
regs[op->type][0],
|
||||
op->absolute_address,
|
||||
regs[op->type][1]);
|
||||
}
|
||||
}
|
||||
|
||||
static void pvr_pds_disassemble_instruction_add64(struct pvr_add *add,
|
||||
char *instr_str,
|
||||
size_t instr_len)
|
||||
{
|
||||
char dst[32];
|
||||
char src0[32];
|
||||
char src1[32];
|
||||
|
||||
pvr_pds_disassemble_operand(add->src0, src0, sizeof(src0));
|
||||
pvr_pds_disassemble_operand(add->src1, src1, sizeof(src1));
|
||||
pvr_pds_disassemble_operand(add->dst, dst, sizeof(dst));
|
||||
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%-16s%s%s = %s %s %s %s",
|
||||
"ADD64",
|
||||
add->cc ? "? " : "",
|
||||
dst,
|
||||
src0,
|
||||
add->sna ? "-" : "+",
|
||||
src1,
|
||||
add->alum ? "[signed]" : "");
|
||||
}
|
||||
|
||||
static void pvr_pds_disassemble_instruction_add32(struct pvr_add *add,
|
||||
char *instr_str,
|
||||
size_t instr_len)
|
||||
{
|
||||
char dst[32];
|
||||
char src0[32];
|
||||
char src1[32];
|
||||
|
||||
pvr_pds_disassemble_operand(add->src0, src0, sizeof(src0));
|
||||
pvr_pds_disassemble_operand(add->src1, src1, sizeof(src1));
|
||||
pvr_pds_disassemble_operand(add->dst, dst, sizeof(dst));
|
||||
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%-16s%s%s = %s %s %s %s",
|
||||
"ADD32",
|
||||
add->cc ? "? " : "",
|
||||
dst,
|
||||
src0,
|
||||
add->sna ? "-" : "+",
|
||||
src1,
|
||||
add->alum ? "[signed]" : "");
|
||||
}
|
||||
|
||||
static void
|
||||
pvr_pds_disassemble_instruction_sftlp32(struct pvr_sftlp *instruction,
|
||||
char *instr_str,
|
||||
size_t instr_len)
|
||||
{
|
||||
char dst[32];
|
||||
char src0[32];
|
||||
char src1[32];
|
||||
char src2[32];
|
||||
|
||||
pvr_pds_disassemble_operand(instruction->src0, src0, sizeof(src0));
|
||||
pvr_pds_disassemble_operand(instruction->src1, src1, sizeof(src1));
|
||||
pvr_pds_disassemble_operand(instruction->dst, dst, sizeof(dst));
|
||||
|
||||
if (instruction->IM)
|
||||
snprintf(src2, sizeof(src2), "%u", (uint32_t)instruction->src2->literal);
|
||||
else
|
||||
pvr_pds_disassemble_operand(instruction->src2, src2, sizeof(src2));
|
||||
|
||||
if (instruction->lop == LOP_NONE) {
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%-16s%s%s = %s %s %s",
|
||||
"SFTLP32",
|
||||
instruction->cc ? "? " : "",
|
||||
dst,
|
||||
src0,
|
||||
instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
|
||||
src2);
|
||||
} else if (instruction->lop == LOP_NOT) {
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%-16s%s%s = (~%s) %s %s",
|
||||
"SFTLP32",
|
||||
instruction->cc ? "? " : "",
|
||||
dst,
|
||||
src0,
|
||||
instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
|
||||
src2);
|
||||
} else {
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%-16s%s%s = (%s %s %s) %s %s",
|
||||
"SFTLP32",
|
||||
instruction->cc ? "? " : "",
|
||||
dst,
|
||||
src0,
|
||||
LOP[instruction->lop],
|
||||
src1,
|
||||
instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
|
||||
src2);
|
||||
}
|
||||
}
|
||||
|
||||
static void pvr_pds_disassemble_instruction_stm(struct pvr_stm *instruction,
|
||||
char *instr_str,
|
||||
size_t instr_len)
|
||||
{
|
||||
char src0[32];
|
||||
char src1[32];
|
||||
char src2[32];
|
||||
char src3[32];
|
||||
|
||||
char stm_pred[64];
|
||||
|
||||
pvr_pds_disassemble_operand(instruction->src0, src0, sizeof(src0));
|
||||
pvr_pds_disassemble_operand(instruction->src1, src1, sizeof(src1));
|
||||
pvr_pds_disassemble_operand(instruction->src2, src2, sizeof(src2));
|
||||
pvr_pds_disassemble_operand(instruction->src3, src3, sizeof(src3));
|
||||
|
||||
if (instruction->ccs_global)
|
||||
snprintf(stm_pred, sizeof(stm_pred), "overflow_any");
|
||||
else if (instruction->ccs_so)
|
||||
snprintf(stm_pred, sizeof(stm_pred), "overflow_current");
|
||||
else
|
||||
stm_pred[0] = 0;
|
||||
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%-16s%s%s%s stm%u = %s, %s, %s, %s",
|
||||
"STM",
|
||||
instruction->cc ? "? " : "",
|
||||
stm_pred,
|
||||
instruction->tst ? " (TST only)" : "",
|
||||
instruction->stream_out,
|
||||
src0,
|
||||
src1,
|
||||
src2,
|
||||
src3);
|
||||
}
|
||||
|
||||
static void pds_disassemble_instruction_stmc(struct pvr_stmc *instruction,
|
||||
char *instr_str,
|
||||
size_t instr_len)
|
||||
{
|
||||
char src0[32];
|
||||
|
||||
pvr_pds_disassemble_operand(instruction->src0, src0, sizeof(src0));
|
||||
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%-16s%s %s",
|
||||
"STMC",
|
||||
instruction->cc ? "? " : "",
|
||||
src0);
|
||||
}
|
||||
|
||||
static void
|
||||
pvr_pds_disassemble_instruction_sftlp64(struct pvr_sftlp *instruction,
|
||||
char *instr_str,
|
||||
size_t instr_len)
|
||||
{
|
||||
char dst[32];
|
||||
char src0[32];
|
||||
char src1[32];
|
||||
char src2[32];
|
||||
|
||||
pvr_pds_disassemble_operand(instruction->src0, src0, sizeof(src0));
|
||||
pvr_pds_disassemble_operand(instruction->src1, src1, sizeof(src1));
|
||||
pvr_pds_disassemble_operand(instruction->dst, dst, sizeof(dst));
|
||||
|
||||
if (instruction->IM)
|
||||
snprintf(src2, sizeof(src2), "%u", (uint32_t)instruction->src2->literal);
|
||||
else
|
||||
pvr_pds_disassemble_operand(instruction->src2, src2, sizeof(src2));
|
||||
|
||||
if (instruction->lop == LOP_NONE) {
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%-16s%s%s = %s %s %s",
|
||||
"SFTLP64",
|
||||
instruction->cc ? "? " : "",
|
||||
dst,
|
||||
src0,
|
||||
instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
|
||||
src2);
|
||||
} else if (instruction->lop == LOP_NOT) {
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%-16s%s%s = (~%s) %s %s",
|
||||
"SFTLP64",
|
||||
instruction->cc ? "? " : "",
|
||||
dst,
|
||||
src0,
|
||||
instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
|
||||
src2);
|
||||
} else {
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%-16s%s%s = (%s %s %s) %s %s",
|
||||
"SFTLP64",
|
||||
instruction->cc ? "? " : "",
|
||||
dst,
|
||||
src0,
|
||||
LOP[instruction->lop],
|
||||
src1,
|
||||
instruction->IM ? instruction->src2->negate ? ">>" : "<<" : "<<",
|
||||
src2);
|
||||
}
|
||||
}
|
||||
|
||||
static void pvr_pds_disassemble_instruction_cmp(struct pvr_cmp *cmp,
|
||||
char *instr_str,
|
||||
size_t instr_len)
|
||||
{
|
||||
char src0[32];
|
||||
char src1[32];
|
||||
static const char *const COP[] = { "=", ">", "<", "!=" };
|
||||
|
||||
pvr_pds_disassemble_operand(cmp->src0, src0, sizeof(src0));
|
||||
|
||||
if (cmp->IM) {
|
||||
snprintf(src1,
|
||||
sizeof(src1),
|
||||
"%#04llx",
|
||||
(unsigned long long)cmp->src1->literal);
|
||||
} else {
|
||||
pvr_pds_disassemble_operand(cmp->src1, src1, sizeof(src1));
|
||||
}
|
||||
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%-16s%sP0 = (%s %s %s)",
|
||||
"CMP",
|
||||
cmp->cc ? "? " : "",
|
||||
src0,
|
||||
COP[cmp->cop],
|
||||
src1);
|
||||
}
|
||||
|
||||
static void pvr_pds_disassemble_instruction_ldst(struct pvr_ldst *ins,
|
||||
char *instr_str,
|
||||
size_t instr_len)
|
||||
{
|
||||
char src0[PVR_PDS_MAX_INST_STR_LEN];
|
||||
|
||||
pvr_pds_disassemble_operand(ins->src0, src0, sizeof(src0));
|
||||
|
||||
if (ins->st) {
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%-16s%s%s: mem(%s) <= src(%s)",
|
||||
"ST",
|
||||
ins->cc ? "? " : "",
|
||||
src0,
|
||||
"?",
|
||||
"?");
|
||||
} else {
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%-16s%s%s: dst(%s) <= mem(%s)",
|
||||
"ld",
|
||||
ins->cc ? "? " : "",
|
||||
src0,
|
||||
"?",
|
||||
"?");
|
||||
}
|
||||
}
|
||||
|
||||
static void pvr_pds_disassemble_simple(struct pvr_simple *simple,
|
||||
const char *type,
|
||||
char *instr_str,
|
||||
size_t instr_len)
|
||||
{
|
||||
snprintf(instr_str, instr_len, "%-16s%s", type, simple->cc ? "? " : "");
|
||||
}
|
||||
|
||||
static void pvr_pds_disassemble_instruction_limm(struct pvr_limm *limm,
|
||||
char *instr_str,
|
||||
size_t instr_len)
|
||||
{
|
||||
int32_t imm = (uint32_t)limm->src0->literal;
|
||||
char dst[PVR_PDS_MAX_INST_STR_LEN];
|
||||
|
||||
pvr_pds_disassemble_operand(limm->dst, dst, sizeof(dst));
|
||||
|
||||
if (limm->GR) {
|
||||
char *pchGReg;
|
||||
|
||||
switch (imm) {
|
||||
case 0:
|
||||
pchGReg = "cluster";
|
||||
break;
|
||||
case 1:
|
||||
pchGReg = "instance";
|
||||
break;
|
||||
default:
|
||||
pchGReg = "unknown";
|
||||
}
|
||||
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%-16s%s%s = G%d (%s)",
|
||||
"LIMM",
|
||||
limm->cc ? "? " : "",
|
||||
dst,
|
||||
imm,
|
||||
pchGReg);
|
||||
} else {
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%-16s%s%s = %#04x",
|
||||
"LIMM",
|
||||
limm->cc ? "? " : "",
|
||||
dst,
|
||||
imm);
|
||||
}
|
||||
}
|
||||
|
||||
static void pvr_pds_disassemble_instruction_ddmad(struct pvr_ddmad *ddmad,
|
||||
char *instr_str,
|
||||
size_t instr_len)
|
||||
{
|
||||
char src0[PVR_PDS_MAX_INST_STR_LEN];
|
||||
char src1[PVR_PDS_MAX_INST_STR_LEN];
|
||||
char src2[PVR_PDS_MAX_INST_STR_LEN];
|
||||
char src3[PVR_PDS_MAX_INST_STR_LEN];
|
||||
|
||||
pvr_pds_disassemble_operand(ddmad->src0, src0, sizeof(src0));
|
||||
pvr_pds_disassemble_operand(ddmad->src1, src1, sizeof(src1));
|
||||
pvr_pds_disassemble_operand(ddmad->src2, src2, sizeof(src2));
|
||||
pvr_pds_disassemble_operand(ddmad->src3, src3, sizeof(src3));
|
||||
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%-16s%sdoutd = (%s * %s) + %s, %s%s",
|
||||
"DDMAD",
|
||||
ddmad->cc ? "? " : "",
|
||||
src0,
|
||||
src1,
|
||||
src2,
|
||||
src3,
|
||||
ddmad->END ? "; HALT" : "");
|
||||
}
|
||||
|
||||
static void pvr_pds_disassemble_predicate(uint32_t predicate,
|
||||
char *buffer,
|
||||
size_t buffer_length)
|
||||
{
|
||||
switch (predicate) {
|
||||
case PVR_ROGUE_PDSINST_PREDICATE_P0:
|
||||
snprintf(buffer, buffer_length, "%s", "p0");
|
||||
break;
|
||||
case PVR_ROGUE_PDSINST_PREDICATE_IF0:
|
||||
snprintf(buffer, buffer_length, "%s", "if0");
|
||||
break;
|
||||
case PVR_ROGUE_PDSINST_PREDICATE_IF1:
|
||||
snprintf(buffer, buffer_length, "%s", "if1");
|
||||
break;
|
||||
case PVR_ROGUE_PDSINST_PREDICATE_SO_OVERFLOW_PREDICATE_0:
|
||||
snprintf(buffer, buffer_length, "%s", "so_overflow_0");
|
||||
break;
|
||||
case PVR_ROGUE_PDSINST_PREDICATE_SO_OVERFLOW_PREDICATE_1:
|
||||
snprintf(buffer, buffer_length, "%s", "so_overflow_1");
|
||||
break;
|
||||
case PVR_ROGUE_PDSINST_PREDICATE_SO_OVERFLOW_PREDICATE_2:
|
||||
snprintf(buffer, buffer_length, "%s", "so_overflow_2");
|
||||
break;
|
||||
case PVR_ROGUE_PDSINST_PREDICATE_SO_OVERFLOW_PREDICATE_3:
|
||||
snprintf(buffer, buffer_length, "%s", "so_overflow_3");
|
||||
break;
|
||||
case PVR_ROGUE_PDSINST_PREDICATE_SO_OVERFLOW_PREDICATE_GLOBAL:
|
||||
snprintf(buffer, buffer_length, "%s", "so_overflow_any");
|
||||
break;
|
||||
case PVR_ROGUE_PDSINST_PREDICATE_KEEP:
|
||||
snprintf(buffer, buffer_length, "%s", "keep");
|
||||
break;
|
||||
case PVR_ROGUE_PDSINST_PREDICATE_OOB:
|
||||
snprintf(buffer, buffer_length, "%s", "oob");
|
||||
break;
|
||||
default:
|
||||
snprintf(buffer, buffer_length, "%s", "<ERROR>");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void pvr_pds_disassemble_instruction_bra(struct pvr_bra *bra,
|
||||
char *instr_str,
|
||||
size_t instr_len)
|
||||
{
|
||||
char setc_pred[32];
|
||||
char srcc_pred[32];
|
||||
|
||||
pvr_pds_disassemble_predicate(bra->srcc->predicate,
|
||||
srcc_pred,
|
||||
sizeof(srcc_pred));
|
||||
pvr_pds_disassemble_predicate(bra->setc->predicate,
|
||||
setc_pred,
|
||||
sizeof(setc_pred));
|
||||
|
||||
if (bra->setc->predicate != PVR_ROGUE_PDSINST_PREDICATE_KEEP) {
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%-16sif %s%s %d ( setc = %s )",
|
||||
"BRA",
|
||||
bra->srcc->negate ? "! " : "",
|
||||
srcc_pred,
|
||||
bra->address,
|
||||
setc_pred);
|
||||
} else {
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%-16sif %s%s %d",
|
||||
"BRA",
|
||||
bra->srcc->negate ? "! " : "",
|
||||
srcc_pred,
|
||||
bra->address);
|
||||
}
|
||||
}
|
||||
|
||||
static void pvr_pds_disassemble_instruction_mad(struct pvr_mad *mad,
|
||||
char *instr_str,
|
||||
size_t instr_len)
|
||||
{
|
||||
char src0[PVR_PDS_MAX_INST_STR_LEN];
|
||||
char src1[PVR_PDS_MAX_INST_STR_LEN];
|
||||
char src2[PVR_PDS_MAX_INST_STR_LEN];
|
||||
char dst[PVR_PDS_MAX_INST_STR_LEN];
|
||||
|
||||
pvr_pds_disassemble_operand(mad->src0, src0, sizeof(src0));
|
||||
pvr_pds_disassemble_operand(mad->src1, src1, sizeof(src1));
|
||||
pvr_pds_disassemble_operand(mad->src2, src2, sizeof(src2));
|
||||
pvr_pds_disassemble_operand(mad->dst, dst, sizeof(dst));
|
||||
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%-16s%s%s = (%s * %s) %s %s%s",
|
||||
"MAD",
|
||||
mad->cc ? "? " : "",
|
||||
dst,
|
||||
src0,
|
||||
src1,
|
||||
mad->sna ? "-" : "+",
|
||||
src2,
|
||||
mad->alum ? " [signed]" : "");
|
||||
}
|
||||
|
||||
static void pvr_pds_disassemble_instruction_dout(struct pvr_dout *dout,
|
||||
char *instr_str,
|
||||
size_t instr_len)
|
||||
{
|
||||
char src0[PVR_PDS_MAX_INST_STR_LEN];
|
||||
char src1[PVR_PDS_MAX_INST_STR_LEN];
|
||||
|
||||
#define X(dout_dst, str) #str,
|
||||
static const char *const dst[] = { PVR_PDS_DOUT_DSTS };
|
||||
#undef X
|
||||
|
||||
pvr_pds_disassemble_operand(dout->src0, src0, sizeof(src0));
|
||||
pvr_pds_disassemble_operand(dout->src1, src1, sizeof(src1));
|
||||
|
||||
{
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"%-16s%s%s = %s, %s%s",
|
||||
"DOUT",
|
||||
dout->cc ? "? " : "",
|
||||
dst[dout->dst],
|
||||
src0,
|
||||
src1,
|
||||
dout->END ? "; HALT" : "");
|
||||
}
|
||||
}
|
||||
|
||||
void pvr_pds_disassemble_instruction(char *instr_str,
|
||||
size_t instr_len,
|
||||
struct pvr_instruction *instruction)
|
||||
{
|
||||
if (!instruction) {
|
||||
snprintf(instr_str,
|
||||
instr_len,
|
||||
"Instruction was not disassembled properly\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (instruction->type) {
|
||||
case INS_LIMM:
|
||||
pvr_pds_disassemble_instruction_limm((struct pvr_limm *)instruction,
|
||||
instr_str,
|
||||
instr_len);
|
||||
break;
|
||||
case INS_ADD64:
|
||||
pvr_pds_disassemble_instruction_add64((struct pvr_add *)instruction,
|
||||
instr_str,
|
||||
instr_len);
|
||||
break;
|
||||
case INS_ADD32:
|
||||
pvr_pds_disassemble_instruction_add32((struct pvr_add *)instruction,
|
||||
instr_str,
|
||||
instr_len);
|
||||
break;
|
||||
case INS_CMP:
|
||||
pvr_pds_disassemble_instruction_cmp((struct pvr_cmp *)instruction,
|
||||
instr_str,
|
||||
instr_len);
|
||||
break;
|
||||
case INS_MAD:
|
||||
pvr_pds_disassemble_instruction_mad((struct pvr_mad *)instruction,
|
||||
instr_str,
|
||||
instr_len);
|
||||
break;
|
||||
case INS_BRA:
|
||||
pvr_pds_disassemble_instruction_bra((struct pvr_bra *)instruction,
|
||||
instr_str,
|
||||
instr_len);
|
||||
break;
|
||||
case INS_DDMAD:
|
||||
pvr_pds_disassemble_instruction_ddmad((struct pvr_ddmad *)instruction,
|
||||
instr_str,
|
||||
instr_len);
|
||||
break;
|
||||
case INS_DOUT:
|
||||
pvr_pds_disassemble_instruction_dout((struct pvr_dout *)instruction,
|
||||
instr_str,
|
||||
instr_len);
|
||||
break;
|
||||
case INS_LD:
|
||||
case INS_ST:
|
||||
pvr_pds_disassemble_instruction_ldst((struct pvr_ldst *)instruction,
|
||||
instr_str,
|
||||
instr_len);
|
||||
break;
|
||||
case INS_WDF:
|
||||
pvr_pds_disassemble_simple((struct pvr_simple *)instruction,
|
||||
"WDF",
|
||||
instr_str,
|
||||
instr_len);
|
||||
break;
|
||||
case INS_LOCK:
|
||||
pvr_pds_disassemble_simple((struct pvr_simple *)instruction,
|
||||
"LOCK",
|
||||
instr_str,
|
||||
instr_len);
|
||||
break;
|
||||
case INS_RELEASE:
|
||||
pvr_pds_disassemble_simple((struct pvr_simple *)instruction,
|
||||
"RELEASE",
|
||||
instr_str,
|
||||
instr_len);
|
||||
break;
|
||||
case INS_HALT:
|
||||
pvr_pds_disassemble_simple((struct pvr_simple *)instruction,
|
||||
"HALT",
|
||||
instr_str,
|
||||
instr_len);
|
||||
break;
|
||||
case INS_NOP:
|
||||
pvr_pds_disassemble_simple((struct pvr_simple *)instruction,
|
||||
"NOP",
|
||||
instr_str,
|
||||
instr_len);
|
||||
break;
|
||||
case INS_SFTLP32:
|
||||
pvr_pds_disassemble_instruction_sftlp32((struct pvr_sftlp *)instruction,
|
||||
instr_str,
|
||||
instr_len);
|
||||
break;
|
||||
case INS_SFTLP64:
|
||||
pvr_pds_disassemble_instruction_sftlp64((struct pvr_sftlp *)instruction,
|
||||
instr_str,
|
||||
instr_len);
|
||||
break;
|
||||
case INS_STM:
|
||||
pvr_pds_disassemble_instruction_stm((struct pvr_stm *)instruction,
|
||||
instr_str,
|
||||
instr_len);
|
||||
break;
|
||||
case INS_STMC:
|
||||
pds_disassemble_instruction_stmc((struct pvr_stmc *)instruction,
|
||||
instr_str,
|
||||
instr_len);
|
||||
break;
|
||||
default:
|
||||
snprintf(instr_str, instr_len, "Printing not implemented\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(DUMP_PDS)
|
||||
void pvr_pds_print_instruction(uint32_t instr)
|
||||
{
|
||||
char instruction_str[1024];
|
||||
struct pvr_instruction *decoded =
|
||||
pvr_pds_disassemble_instruction2(0, 0, instr);
|
||||
|
||||
if (!decoded) {
|
||||
mesa_logd("%X\n", instr);
|
||||
} else {
|
||||
pvr_pds_disassemble_instruction(instruction_str,
|
||||
sizeof(instruction_str),
|
||||
decoded);
|
||||
mesa_logd("\t0x%08x, /* %s */\n", instr, instruction_str);
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTARRAYS0_H
|
||||
#define PVR_DRAW_INDIRECTARRAYS0_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_arrays.pds */
|
||||
|
||||
static const uint32_t pvr_draw_indirect_arrays0_code[15] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd1940000, /* LIMM temp[5].32 = 0000 */
|
||||
0x500c0804, /* SFTLP32 temp[4].32 = temp[1].32 << 0 */
|
||||
0xb1880000, /* CMP P0 = (temp[4].64 = 0000) */
|
||||
0xd9800000, /* LIMM ? temp[0].32 = 0000 */
|
||||
0xd9840000, /* LIMM ? temp[1].32 = 0000 */
|
||||
0x04081023, /* MAD temp[6].64 = (temp[1].32 * const[2].32) +
|
||||
const[4].64 */
|
||||
0x50343001, /* SFTLP32 temp[1].32 = temp[6].32 << 0 */
|
||||
0x912040c1, /* ADD32 temp[1].32 = temp[1].32 - const[3].32 */
|
||||
0xd0800003, /* ST const[6].64: mem(?) <= src(?) */
|
||||
0xd0000004, /* LD const[8].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf40a4003, /* DOUT doutv = temp[0].64, const[10].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output pvr_draw_indirect_arrays0_program = {
|
||||
pvr_draw_indirect_arrays0_code, /* code segment */
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
4, /* number of constant mappings */
|
||||
|
||||
12, /* size of data segment, in dwords, aligned to 4 */
|
||||
16, /* size of code segment, in dwords, aligned to 4 */
|
||||
12, /* size of temp segment, in dwords, aligned to 4 */
|
||||
11, /* size of data segment, in dwords */
|
||||
15, /* size of code segment, in dwords */
|
||||
10, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_arrays0_di_data(buffer, addr, device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x40000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays0_write_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x30000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays0_flush_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x1940000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays0_num_views(buffer, value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays0_immediates(buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTARRAYS1_H
|
||||
#define PVR_DRAW_INDIRECTARRAYS1_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_arrays.pds */
|
||||
|
||||
static const uint32_t pvr_draw_indirect_arrays1_code[15] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd1940000, /* LIMM temp[5].32 = 0000 */
|
||||
0x50141004, /* SFTLP32 temp[4].32 = temp[2].32 << 0 */
|
||||
0xb1880000, /* CMP P0 = (temp[4].64 = 0000) */
|
||||
0xd9840000, /* LIMM ? temp[1].32 = 0000 */
|
||||
0xd9880000, /* LIMM ? temp[2].32 = 0000 */
|
||||
0x04101023, /* MAD temp[6].64 = (temp[2].32 * const[2].32) +
|
||||
const[4].64 */
|
||||
0x50343002, /* SFTLP32 temp[2].32 = temp[6].32 << 0 */
|
||||
0x912080c2, /* ADD32 temp[2].32 = temp[2].32 - const[3].32 */
|
||||
0xd0800003, /* ST const[6].64: mem(?) <= src(?) */
|
||||
0xd0000004, /* LD const[8].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf40a4003, /* DOUT doutv = temp[0].64, const[10].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output pvr_draw_indirect_arrays1_program = {
|
||||
pvr_draw_indirect_arrays1_code, /* code segment */
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
4, /* number of constant mappings */
|
||||
|
||||
12, /* size of data segment, in dwords, aligned to 4 */
|
||||
16, /* size of code segment, in dwords, aligned to 4 */
|
||||
12, /* size of temp segment, in dwords, aligned to 4 */
|
||||
11, /* size of data segment, in dwords */
|
||||
15, /* size of code segment, in dwords */
|
||||
10, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_arrays1_di_data(buffer, addr, device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x40000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays1_write_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x430000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays1_flush_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x1940000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays1_num_views(buffer, value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays1_immediates(buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTARRAYS2_H
|
||||
#define PVR_DRAW_INDIRECTARRAYS2_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_arrays.pds */
|
||||
|
||||
static const uint32_t pvr_draw_indirect_arrays2_code[15] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd1840000, /* LIMM temp[1].32 = 0000 */
|
||||
0x501c1800, /* SFTLP32 temp[0].32 = temp[3].32 << 0 */
|
||||
0xb1800000, /* CMP P0 = (temp[0].64 = 0000) */
|
||||
0xd9880000, /* LIMM ? temp[2].32 = 0000 */
|
||||
0xd98c0000, /* LIMM ? temp[3].32 = 0000 */
|
||||
0x04181023, /* MAD temp[6].64 = (temp[3].32 * const[2].32) +
|
||||
const[4].64 */
|
||||
0x50343003, /* SFTLP32 temp[3].32 = temp[6].32 << 0 */
|
||||
0x9120c0c3, /* ADD32 temp[3].32 = temp[3].32 - const[3].32 */
|
||||
0xd0800003, /* ST const[6].64: mem(?) <= src(?) */
|
||||
0xd0000004, /* LD const[8].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf40a4003, /* DOUT doutv = temp[0].64, const[10].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output pvr_draw_indirect_arrays2_program = {
|
||||
pvr_draw_indirect_arrays2_code, /* code segment */
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
4, /* number of constant mappings */
|
||||
|
||||
12, /* size of data segment, in dwords, aligned to 4 */
|
||||
16, /* size of code segment, in dwords, aligned to 4 */
|
||||
12, /* size of temp segment, in dwords, aligned to 4 */
|
||||
11, /* size of data segment, in dwords */
|
||||
15, /* size of code segment, in dwords */
|
||||
10, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_arrays2_di_data(buffer, addr, device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x60000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays2_write_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x830000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays2_flush_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x1940000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays2_num_views(buffer, value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays2_immediates(buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTARRAYS3_H
|
||||
#define PVR_DRAW_INDIRECTARRAYS3_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_arrays.pds */
|
||||
|
||||
static const uint32_t pvr_draw_indirect_arrays3_code[15] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd1840000, /* LIMM temp[1].32 = 0000 */
|
||||
0x50242000, /* SFTLP32 temp[0].32 = temp[4].32 << 0 */
|
||||
0xb1800000, /* CMP P0 = (temp[0].64 = 0000) */
|
||||
0xd98c0000, /* LIMM ? temp[3].32 = 0000 */
|
||||
0xd9900000, /* LIMM ? temp[4].32 = 0000 */
|
||||
0x04201023, /* MAD temp[6].64 = (temp[4].32 * const[2].32) +
|
||||
const[4].64 */
|
||||
0x50343004, /* SFTLP32 temp[4].32 = temp[6].32 << 0 */
|
||||
0x912100c4, /* ADD32 temp[4].32 = temp[4].32 - const[3].32 */
|
||||
0xd0800003, /* ST const[6].64: mem(?) <= src(?) */
|
||||
0xd0000004, /* LD const[8].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf40a4003, /* DOUT doutv = temp[0].64, const[10].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output pvr_draw_indirect_arrays3_program = {
|
||||
pvr_draw_indirect_arrays3_code, /* code segment */
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
4, /* number of constant mappings */
|
||||
|
||||
12, /* size of data segment, in dwords, aligned to 4 */
|
||||
16, /* size of code segment, in dwords, aligned to 4 */
|
||||
12, /* size of temp segment, in dwords, aligned to 4 */
|
||||
11, /* size of data segment, in dwords */
|
||||
15, /* size of code segment, in dwords */
|
||||
10, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_arrays3_di_data(buffer, addr, device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x60000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays3_write_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0xc30000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays3_flush_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x1940000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays3_num_views(buffer, value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays3_immediates(buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTARRAYS_BASE_INSTANCE0_H
|
||||
#define PVR_DRAW_INDIRECTARRAYS_BASE_INSTANCE0_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_arrays.pds */
|
||||
|
||||
static const uint32_t pvr_draw_indirect_arrays_base_instance0_code[18] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd1940000, /* LIMM temp[5].32 = 0000 */
|
||||
0x500c0804, /* SFTLP32 temp[4].32 = temp[1].32 << 0 */
|
||||
0xb1880000, /* CMP P0 = (temp[4].64 = 0000) */
|
||||
0xd9800000, /* LIMM ? temp[0].32 = 0000 */
|
||||
0xd9840000, /* LIMM ? temp[1].32 = 0000 */
|
||||
0x04081023, /* MAD temp[6].64 = (temp[1].32 * const[2].32) +
|
||||
const[4].64 */
|
||||
0x50343001, /* SFTLP32 temp[1].32 = temp[6].32 << 0 */
|
||||
0x912040c1, /* ADD32 temp[1].32 = temp[1].32 - const[3].32 */
|
||||
0x9001a0a0, /* ADD32 ptemp[0].32 = const[6].32 + temp[2].32 */
|
||||
0xd0800004, /* ST const[8].64: mem(?) <= src(?) */
|
||||
0x9001a0e1, /* ADD32 ptemp[1].32 = const[6].32 + temp[3].32 */
|
||||
0x9130f0e3, /* ADD32 ptemp[3].32 = ptemp[3].32 - ptemp[3].32 */
|
||||
0xd0000005, /* LD const[10].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf4064003, /* DOUT doutv = temp[0].64, const[6].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output
|
||||
pvr_draw_indirect_arrays_base_instance0_program = {
|
||||
pvr_draw_indirect_arrays_base_instance0_code, /* code segment */
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
4, /* number of constant mappings */
|
||||
|
||||
12, /* size of data segment, in dwords, aligned to 4 */
|
||||
20, /* size of code segment, in dwords, aligned to 4 */
|
||||
12, /* size of temp segment, in dwords, aligned to 4 */
|
||||
12, /* size of data segment, in dwords */
|
||||
18, /* size of code segment, in dwords */
|
||||
10, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_arrays_base_instance0_di_data(buffer, \
|
||||
addr, \
|
||||
device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x40000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance0_write_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x30000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance0_flush_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x1940000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance0_num_views(buffer, value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance0_immediates(buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTARRAYS_BASE_INSTANCE1_H
|
||||
#define PVR_DRAW_INDIRECTARRAYS_BASE_INSTANCE1_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_arrays.pds */
|
||||
|
||||
static const uint32_t pvr_draw_indirect_arrays_base_instance1_code[18] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd19c0000, /* LIMM temp[7].32 = 0000 */
|
||||
0x50141006, /* SFTLP32 temp[6].32 = temp[2].32 << 0 */
|
||||
0xb18c0000, /* CMP P0 = (temp[6].64 = 0000) */
|
||||
0xd9840000, /* LIMM ? temp[1].32 = 0000 */
|
||||
0xd9880000, /* LIMM ? temp[2].32 = 0000 */
|
||||
0x04101024, /* MAD temp[8].64 = (temp[2].32 * const[2].32) +
|
||||
const[4].64 */
|
||||
0x50444002, /* SFTLP32 temp[2].32 = temp[8].32 << 0 */
|
||||
0x912080c2, /* ADD32 temp[2].32 = temp[2].32 - const[3].32 */
|
||||
0x9001a0e0, /* ADD32 ptemp[0].32 = const[6].32 + temp[3].32 */
|
||||
0xd0800004, /* ST const[8].64: mem(?) <= src(?) */
|
||||
0x9001a121, /* ADD32 ptemp[1].32 = const[6].32 + temp[4].32 */
|
||||
0x9130f0e3, /* ADD32 ptemp[3].32 = ptemp[3].32 - ptemp[3].32 */
|
||||
0xd0000005, /* LD const[10].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf4064003, /* DOUT doutv = temp[0].64, const[6].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output
|
||||
pvr_draw_indirect_arrays_base_instance1_program = {
|
||||
pvr_draw_indirect_arrays_base_instance1_code, /* code segment */
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
4, /* number of constant mappings */
|
||||
|
||||
12, /* size of data segment, in dwords, aligned to 4 */
|
||||
20, /* size of code segment, in dwords, aligned to 4 */
|
||||
12, /* size of temp segment, in dwords, aligned to 4 */
|
||||
12, /* size of data segment, in dwords */
|
||||
18, /* size of code segment, in dwords */
|
||||
12, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_arrays_base_instance1_di_data(buffer, \
|
||||
addr, \
|
||||
device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x60000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance1_write_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x430000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance1_flush_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x2140000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance1_num_views(buffer, value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance1_immediates(buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTARRAYS_BASE_INSTANCE2_H
|
||||
#define PVR_DRAW_INDIRECTARRAYS_BASE_INSTANCE2_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_arrays.pds */
|
||||
|
||||
static const uint32_t pvr_draw_indirect_arrays_base_instance2_code[18] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd1840000, /* LIMM temp[1].32 = 0000 */
|
||||
0x501c1800, /* SFTLP32 temp[0].32 = temp[3].32 << 0 */
|
||||
0xb1800000, /* CMP P0 = (temp[0].64 = 0000) */
|
||||
0xd9880000, /* LIMM ? temp[2].32 = 0000 */
|
||||
0xd98c0000, /* LIMM ? temp[3].32 = 0000 */
|
||||
0x04181023, /* MAD temp[6].64 = (temp[3].32 * const[2].32) +
|
||||
const[4].64 */
|
||||
0x50343003, /* SFTLP32 temp[3].32 = temp[6].32 << 0 */
|
||||
0x9120c0c3, /* ADD32 temp[3].32 = temp[3].32 - const[3].32 */
|
||||
0x9001a120, /* ADD32 ptemp[0].32 = const[6].32 + temp[4].32 */
|
||||
0xd0800004, /* ST const[8].64: mem(?) <= src(?) */
|
||||
0x9001a161, /* ADD32 ptemp[1].32 = const[6].32 + temp[5].32 */
|
||||
0x9130f0e3, /* ADD32 ptemp[3].32 = ptemp[3].32 - ptemp[3].32 */
|
||||
0xd0000005, /* LD const[10].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf4064003, /* DOUT doutv = temp[0].64, const[6].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output
|
||||
pvr_draw_indirect_arrays_base_instance2_program = {
|
||||
pvr_draw_indirect_arrays_base_instance2_code, /* code segment */
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
4, /* number of constant mappings */
|
||||
|
||||
12, /* size of data segment, in dwords, aligned to 4 */
|
||||
20, /* size of code segment, in dwords, aligned to 4 */
|
||||
12, /* size of temp segment, in dwords, aligned to 4 */
|
||||
12, /* size of data segment, in dwords */
|
||||
18, /* size of code segment, in dwords */
|
||||
10, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_arrays_base_instance2_di_data(buffer, \
|
||||
addr, \
|
||||
device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x60000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance2_write_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x830000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance2_flush_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x1940000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance2_num_views(buffer, value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance2_immediates(buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTARRAYS_BASE_INSTANCE3_H
|
||||
#define PVR_DRAW_INDIRECTARRAYS_BASE_INSTANCE3_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_arrays.pds */
|
||||
|
||||
static const uint32_t pvr_draw_indirect_arrays_base_instance3_code[18] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd1840000, /* LIMM temp[1].32 = 0000 */
|
||||
0x50242000, /* SFTLP32 temp[0].32 = temp[4].32 << 0 */
|
||||
0xb1800000, /* CMP P0 = (temp[0].64 = 0000) */
|
||||
0xd98c0000, /* LIMM ? temp[3].32 = 0000 */
|
||||
0xd9900000, /* LIMM ? temp[4].32 = 0000 */
|
||||
0x04201024, /* MAD temp[8].64 = (temp[4].32 * const[2].32) +
|
||||
const[4].64 */
|
||||
0x50444004, /* SFTLP32 temp[4].32 = temp[8].32 << 0 */
|
||||
0x912100c4, /* ADD32 temp[4].32 = temp[4].32 - const[3].32 */
|
||||
0x9001a160, /* ADD32 ptemp[0].32 = const[6].32 + temp[5].32 */
|
||||
0xd0800004, /* ST const[8].64: mem(?) <= src(?) */
|
||||
0x9001a1a1, /* ADD32 ptemp[1].32 = const[6].32 + temp[6].32 */
|
||||
0x9130f0e3, /* ADD32 ptemp[3].32 = ptemp[3].32 - ptemp[3].32 */
|
||||
0xd0000005, /* LD const[10].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf4064003, /* DOUT doutv = temp[0].64, const[6].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output
|
||||
pvr_draw_indirect_arrays_base_instance3_program = {
|
||||
pvr_draw_indirect_arrays_base_instance3_code, /* code segment */
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
4, /* number of constant mappings */
|
||||
|
||||
12, /* size of data segment, in dwords, aligned to 4 */
|
||||
20, /* size of code segment, in dwords, aligned to 4 */
|
||||
12, /* size of temp segment, in dwords, aligned to 4 */
|
||||
12, /* size of data segment, in dwords */
|
||||
18, /* size of code segment, in dwords */
|
||||
12, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_arrays_base_instance3_di_data(buffer, \
|
||||
addr, \
|
||||
device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x80000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance3_write_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0xc30000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance3_flush_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x2140000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance3_num_views(buffer, value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance3_immediates(buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTARRAYS_BASE_INSTANCE_DRAWID0_H
|
||||
#define PVR_DRAW_INDIRECTARRAYS_BASE_INSTANCE_DRAWID0_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_arrays.pds */
|
||||
|
||||
static const uint32_t pvr_draw_indirect_arrays_base_instance_drawid0_code[18] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd1940000, /* LIMM temp[5].32 = 0000 */
|
||||
0x500c0804, /* SFTLP32 temp[4].32 = temp[1].32 << 0 */
|
||||
0xb1880000, /* CMP P0 = (temp[4].64 = 0000) */
|
||||
0xd9800000, /* LIMM ? temp[0].32 = 0000 */
|
||||
0xd9840000, /* LIMM ? temp[1].32 = 0000 */
|
||||
0x04081023, /* MAD temp[6].64 = (temp[1].32 * const[2].32) +
|
||||
const[4].64 */
|
||||
0x50343001, /* SFTLP32 temp[1].32 = temp[6].32 << 0 */
|
||||
0x912040c1, /* ADD32 temp[1].32 = temp[1].32 - const[3].32 */
|
||||
0x9001a0a0, /* ADD32 ptemp[0].32 = const[6].32 + temp[2].32 */
|
||||
0xd0800004, /* ST const[8].64: mem(?) <= src(?) */
|
||||
0x9001a0e1, /* ADD32 ptemp[1].32 = const[6].32 + temp[3].32 */
|
||||
0x9030c0e3, /* ADD32 ptemp[3].32 = ptemp[3].32 + const[3].32 */
|
||||
0xd0000005, /* LD const[10].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf4064003, /* DOUT doutv = temp[0].64, const[6].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output
|
||||
pvr_draw_indirect_arrays_base_instance_drawid0_program = {
|
||||
pvr_draw_indirect_arrays_base_instance_drawid0_code, /* code segment */
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
4, /* number of constant mappings */
|
||||
|
||||
12, /* size of data segment, in dwords, aligned to 4 */
|
||||
20, /* size of code segment, in dwords, aligned to 4 */
|
||||
12, /* size of temp segment, in dwords, aligned to 4 */
|
||||
12, /* size of data segment, in dwords */
|
||||
18, /* size of code segment, in dwords */
|
||||
10, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_arrays_base_instance_drawid0_di_data(buffer, \
|
||||
addr, \
|
||||
device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x40000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance_drawid0_write_vdm(buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x30000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance_drawid0_flush_vdm(buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x1940000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance_drawid0_num_views(buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance_drawid0_immediates( \
|
||||
buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTARRAYS_BASE_INSTANCE_DRAWID1_H
|
||||
#define PVR_DRAW_INDIRECTARRAYS_BASE_INSTANCE_DRAWID1_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_arrays.pds */
|
||||
|
||||
static const uint32_t pvr_draw_indirect_arrays_base_instance_drawid1_code[18] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd19c0000, /* LIMM temp[7].32 = 0000 */
|
||||
0x50141006, /* SFTLP32 temp[6].32 = temp[2].32 << 0 */
|
||||
0xb18c0000, /* CMP P0 = (temp[6].64 = 0000) */
|
||||
0xd9840000, /* LIMM ? temp[1].32 = 0000 */
|
||||
0xd9880000, /* LIMM ? temp[2].32 = 0000 */
|
||||
0x04101024, /* MAD temp[8].64 = (temp[2].32 * const[2].32) +
|
||||
const[4].64 */
|
||||
0x50444002, /* SFTLP32 temp[2].32 = temp[8].32 << 0 */
|
||||
0x912080c2, /* ADD32 temp[2].32 = temp[2].32 - const[3].32 */
|
||||
0x9001a0e0, /* ADD32 ptemp[0].32 = const[6].32 + temp[3].32 */
|
||||
0xd0800004, /* ST const[8].64: mem(?) <= src(?) */
|
||||
0x9001a121, /* ADD32 ptemp[1].32 = const[6].32 + temp[4].32 */
|
||||
0x9030c0e3, /* ADD32 ptemp[3].32 = ptemp[3].32 + const[3].32 */
|
||||
0xd0000005, /* LD const[10].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf4064003, /* DOUT doutv = temp[0].64, const[6].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output
|
||||
pvr_draw_indirect_arrays_base_instance_drawid1_program = {
|
||||
pvr_draw_indirect_arrays_base_instance_drawid1_code, /* code segment */
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
4, /* number of constant mappings */
|
||||
|
||||
12, /* size of data segment, in dwords, aligned to 4 */
|
||||
20, /* size of code segment, in dwords, aligned to 4 */
|
||||
12, /* size of temp segment, in dwords, aligned to 4 */
|
||||
12, /* size of data segment, in dwords */
|
||||
18, /* size of code segment, in dwords */
|
||||
12, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_arrays_base_instance_drawid1_di_data(buffer, \
|
||||
addr, \
|
||||
device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x60000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance_drawid1_write_vdm(buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x430000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance_drawid1_flush_vdm(buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x2140000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance_drawid1_num_views(buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance_drawid1_immediates( \
|
||||
buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTARRAYS_BASE_INSTANCE_DRAWID2_H
|
||||
#define PVR_DRAW_INDIRECTARRAYS_BASE_INSTANCE_DRAWID2_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_arrays.pds */
|
||||
|
||||
static const uint32_t pvr_draw_indirect_arrays_base_instance_drawid2_code[18] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd1840000, /* LIMM temp[1].32 = 0000 */
|
||||
0x501c1800, /* SFTLP32 temp[0].32 = temp[3].32 << 0 */
|
||||
0xb1800000, /* CMP P0 = (temp[0].64 = 0000) */
|
||||
0xd9880000, /* LIMM ? temp[2].32 = 0000 */
|
||||
0xd98c0000, /* LIMM ? temp[3].32 = 0000 */
|
||||
0x04181023, /* MAD temp[6].64 = (temp[3].32 * const[2].32) +
|
||||
const[4].64 */
|
||||
0x50343003, /* SFTLP32 temp[3].32 = temp[6].32 << 0 */
|
||||
0x9120c0c3, /* ADD32 temp[3].32 = temp[3].32 - const[3].32 */
|
||||
0x9001a120, /* ADD32 ptemp[0].32 = const[6].32 + temp[4].32 */
|
||||
0xd0800004, /* ST const[8].64: mem(?) <= src(?) */
|
||||
0x9001a161, /* ADD32 ptemp[1].32 = const[6].32 + temp[5].32 */
|
||||
0x9030c0e3, /* ADD32 ptemp[3].32 = ptemp[3].32 + const[3].32 */
|
||||
0xd0000005, /* LD const[10].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf4064003, /* DOUT doutv = temp[0].64, const[6].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output
|
||||
pvr_draw_indirect_arrays_base_instance_drawid2_program = {
|
||||
pvr_draw_indirect_arrays_base_instance_drawid2_code, /* code segment */
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
4, /* number of constant mappings */
|
||||
|
||||
12, /* size of data segment, in dwords, aligned to 4 */
|
||||
20, /* size of code segment, in dwords, aligned to 4 */
|
||||
12, /* size of temp segment, in dwords, aligned to 4 */
|
||||
12, /* size of data segment, in dwords */
|
||||
18, /* size of code segment, in dwords */
|
||||
10, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_arrays_base_instance_drawid2_di_data(buffer, \
|
||||
addr, \
|
||||
device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x60000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance_drawid2_write_vdm(buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x830000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance_drawid2_flush_vdm(buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x1940000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance_drawid2_num_views(buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance_drawid2_immediates( \
|
||||
buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTARRAYS_BASE_INSTANCE_DRAWID3_H
|
||||
#define PVR_DRAW_INDIRECTARRAYS_BASE_INSTANCE_DRAWID3_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_arrays.pds */
|
||||
|
||||
static const uint32_t pvr_draw_indirect_arrays_base_instance_drawid3_code[18] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd1840000, /* LIMM temp[1].32 = 0000 */
|
||||
0x50242000, /* SFTLP32 temp[0].32 = temp[4].32 << 0 */
|
||||
0xb1800000, /* CMP P0 = (temp[0].64 = 0000) */
|
||||
0xd98c0000, /* LIMM ? temp[3].32 = 0000 */
|
||||
0xd9900000, /* LIMM ? temp[4].32 = 0000 */
|
||||
0x04201024, /* MAD temp[8].64 = (temp[4].32 * const[2].32) +
|
||||
const[4].64 */
|
||||
0x50444004, /* SFTLP32 temp[4].32 = temp[8].32 << 0 */
|
||||
0x912100c4, /* ADD32 temp[4].32 = temp[4].32 - const[3].32 */
|
||||
0x9001a160, /* ADD32 ptemp[0].32 = const[6].32 + temp[5].32 */
|
||||
0xd0800004, /* ST const[8].64: mem(?) <= src(?) */
|
||||
0x9001a1a1, /* ADD32 ptemp[1].32 = const[6].32 + temp[6].32 */
|
||||
0x9030c0e3, /* ADD32 ptemp[3].32 = ptemp[3].32 + const[3].32 */
|
||||
0xd0000005, /* LD const[10].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf4064003, /* DOUT doutv = temp[0].64, const[6].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output
|
||||
pvr_draw_indirect_arrays_base_instance_drawid3_program = {
|
||||
pvr_draw_indirect_arrays_base_instance_drawid3_code, /* code segment */
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
4, /* number of constant mappings */
|
||||
|
||||
12, /* size of data segment, in dwords, aligned to 4 */
|
||||
20, /* size of code segment, in dwords, aligned to 4 */
|
||||
12, /* size of temp segment, in dwords, aligned to 4 */
|
||||
12, /* size of data segment, in dwords */
|
||||
18, /* size of code segment, in dwords */
|
||||
12, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_arrays_base_instance_drawid3_di_data(buffer, \
|
||||
addr, \
|
||||
device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x80000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance_drawid3_write_vdm(buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0xc30000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance_drawid3_flush_vdm(buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x2140000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance_drawid3_num_views(buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_arrays_base_instance_drawid3_immediates( \
|
||||
buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ARRAYS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTELEMENTS0_H
|
||||
#define PVR_DRAW_INDIRECTELEMENTS0_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_elements.pds */
|
||||
|
||||
static const uint32_t pvr_draw_indirect_elements0_code[21] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0x9000a0e0, /* ADD32 ptemp[0].32 = const[2].32 + temp[3].32 */
|
||||
0x04101822, /* MAD temp[4].64 = (temp[2].32 * const[3].32) +
|
||||
const[4].64 */
|
||||
0x53283006, /* SFTLP32 temp[6].32 = (temp[5].32 | const[6].32) << 0
|
||||
*/
|
||||
0x50242007, /* SFTLP32 temp[7].32 = temp[4].32 << 0 */
|
||||
0x04083842, /* MAD temp[4].64 = (temp[1].32 * const[7].32) +
|
||||
const[8].64 */
|
||||
0x50242001, /* SFTLP32 temp[1].32 = temp[4].32 << 0 */
|
||||
0x50040008, /* SFTLP32 temp[8].32 = temp[0].32 << 0 */
|
||||
0x91204289, /* ADD32 temp[9].32 = temp[1].32 - const[10].32 */
|
||||
0x501c180a, /* SFTLP32 temp[10].32 = temp[3].32 << 0 */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd1940000, /* LIMM temp[5].32 = 0000 */
|
||||
0x500c0804, /* SFTLP32 temp[4].32 = temp[1].32 << 0 */
|
||||
0xb1880000, /* CMP P0 = (temp[4].64 = 0000) */
|
||||
0xd9a00000, /* LIMM ? temp[8].32 = 0000 */
|
||||
0xd9a40000, /* LIMM ? temp[9].32 = 0000 */
|
||||
0xd0800006, /* ST const[12].64: mem(?) <= src(?) */
|
||||
0xd0000007, /* LD const[14].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf4024003, /* DOUT doutv = temp[0].64, const[2].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output pvr_draw_indirect_elements0_program = {
|
||||
pvr_draw_indirect_elements0_code, /* code segment */
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
7, /* number of constant mappings */
|
||||
|
||||
16, /* size of data segment, in dwords, aligned to 4 */
|
||||
24, /* size of code segment, in dwords, aligned to 4 */
|
||||
20, /* size of temp segment, in dwords, aligned to 4 */
|
||||
16, /* size of data segment, in dwords */
|
||||
21, /* size of code segment, in dwords */
|
||||
18, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_elements0_di_data(buffer, addr, device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x40000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements0_write_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x1850000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 12, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements0_flush_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x3160000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 14, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements0_idx_stride(buffer, value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements0_idx_base(buffer, value) \
|
||||
do { \
|
||||
uint64_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements0_idx_header(buffer, value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements0_num_views(buffer, value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 7, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements0_immediates(buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTELEMENTS1_H
|
||||
#define PVR_DRAW_INDIRECTELEMENTS1_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_elements.pds */
|
||||
|
||||
static const uint32_t pvr_draw_indirect_elements1_code[21] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0x9000a120, /* ADD32 ptemp[0].32 = const[2].32 + temp[4].32 */
|
||||
0x04181823, /* MAD temp[6].64 = (temp[3].32 * const[3].32) +
|
||||
const[4].64 */
|
||||
0x53383008, /* SFTLP32 temp[8].32 = (temp[7].32 | const[6].32) << 0
|
||||
*/
|
||||
0x50343009, /* SFTLP32 temp[9].32 = temp[6].32 << 0 */
|
||||
0x04103843, /* MAD temp[6].64 = (temp[2].32 * const[7].32) +
|
||||
const[8].64 */
|
||||
0x50343002, /* SFTLP32 temp[2].32 = temp[6].32 << 0 */
|
||||
0x500c080a, /* SFTLP32 temp[10].32 = temp[1].32 << 0 */
|
||||
0x9120828b, /* ADD32 temp[11].32 = temp[2].32 - const[10].32 */
|
||||
0x5024200c, /* SFTLP32 temp[12].32 = temp[4].32 << 0 */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd19c0000, /* LIMM temp[7].32 = 0000 */
|
||||
0x50141006, /* SFTLP32 temp[6].32 = temp[2].32 << 0 */
|
||||
0xb18c0000, /* CMP P0 = (temp[6].64 = 0000) */
|
||||
0xd9a80000, /* LIMM ? temp[10].32 = 0000 */
|
||||
0xd9ac0000, /* LIMM ? temp[11].32 = 0000 */
|
||||
0xd0800006, /* ST const[12].64: mem(?) <= src(?) */
|
||||
0xd0000007, /* LD const[14].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf4024003, /* DOUT doutv = temp[0].64, const[2].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output pvr_draw_indirect_elements1_program = {
|
||||
pvr_draw_indirect_elements1_code, /* code segment */
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
7, /* number of constant mappings */
|
||||
|
||||
16, /* size of data segment, in dwords, aligned to 4 */
|
||||
24, /* size of code segment, in dwords, aligned to 4 */
|
||||
20, /* size of temp segment, in dwords, aligned to 4 */
|
||||
16, /* size of data segment, in dwords */
|
||||
21, /* size of code segment, in dwords */
|
||||
20, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_elements1_di_data(buffer, addr, device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x60000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements1_write_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x2050000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 12, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements1_flush_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x3960000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 14, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements1_idx_stride(buffer, value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements1_idx_base(buffer, value) \
|
||||
do { \
|
||||
uint64_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements1_idx_header(buffer, value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements1_num_views(buffer, value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 7, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements1_immediates(buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTELEMENTS2_H
|
||||
#define PVR_DRAW_INDIRECTELEMENTS2_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_elements.pds */
|
||||
|
||||
static const uint32_t pvr_draw_indirect_elements2_code[21] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0x9000a160, /* ADD32 ptemp[0].32 = const[2].32 + temp[5].32 */
|
||||
0x04201820, /* MAD temp[0].64 = (temp[4].32 * const[3].32) +
|
||||
const[4].64 */
|
||||
0x53083006, /* SFTLP32 temp[6].32 = (temp[1].32 | const[6].32) << 0
|
||||
*/
|
||||
0x50040007, /* SFTLP32 temp[7].32 = temp[0].32 << 0 */
|
||||
0x04183840, /* MAD temp[0].64 = (temp[3].32 * const[7].32) +
|
||||
const[8].64 */
|
||||
0x50040003, /* SFTLP32 temp[3].32 = temp[0].32 << 0 */
|
||||
0x50141008, /* SFTLP32 temp[8].32 = temp[2].32 << 0 */
|
||||
0x9120c289, /* ADD32 temp[9].32 = temp[3].32 - const[10].32 */
|
||||
0x502c280a, /* SFTLP32 temp[10].32 = temp[5].32 << 0 */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd1840000, /* LIMM temp[1].32 = 0000 */
|
||||
0x501c1800, /* SFTLP32 temp[0].32 = temp[3].32 << 0 */
|
||||
0xb1800000, /* CMP P0 = (temp[0].64 = 0000) */
|
||||
0xd9a00000, /* LIMM ? temp[8].32 = 0000 */
|
||||
0xd9a40000, /* LIMM ? temp[9].32 = 0000 */
|
||||
0xd0800006, /* ST const[12].64: mem(?) <= src(?) */
|
||||
0xd0000007, /* LD const[14].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf4024003, /* DOUT doutv = temp[0].64, const[2].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output pvr_draw_indirect_elements2_program = {
|
||||
pvr_draw_indirect_elements2_code, /* code segment */
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
7, /* number of constant mappings */
|
||||
|
||||
16, /* size of data segment, in dwords, aligned to 4 */
|
||||
24, /* size of code segment, in dwords, aligned to 4 */
|
||||
20, /* size of temp segment, in dwords, aligned to 4 */
|
||||
16, /* size of data segment, in dwords */
|
||||
21, /* size of code segment, in dwords */
|
||||
18, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_elements2_di_data(buffer, addr, device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x60000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements2_write_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x1850000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 12, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements2_flush_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x3160000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 14, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements2_idx_stride(buffer, value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements2_idx_base(buffer, value) \
|
||||
do { \
|
||||
uint64_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements2_idx_header(buffer, value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements2_num_views(buffer, value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 7, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements2_immediates(buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTELEMENTS3_H
|
||||
#define PVR_DRAW_INDIRECTELEMENTS3_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_elements.pds */
|
||||
|
||||
static const uint32_t pvr_draw_indirect_elements3_code[21] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0x9000a1a0, /* ADD32 ptemp[0].32 = const[2].32 + temp[6].32 */
|
||||
0x04281820, /* MAD temp[0].64 = (temp[5].32 * const[3].32) +
|
||||
const[4].64 */
|
||||
0x53083007, /* SFTLP32 temp[7].32 = (temp[1].32 | const[6].32) << 0
|
||||
*/
|
||||
0x50040008, /* SFTLP32 temp[8].32 = temp[0].32 << 0 */
|
||||
0x04203840, /* MAD temp[0].64 = (temp[4].32 * const[7].32) +
|
||||
const[8].64 */
|
||||
0x50040004, /* SFTLP32 temp[4].32 = temp[0].32 << 0 */
|
||||
0x501c1809, /* SFTLP32 temp[9].32 = temp[3].32 << 0 */
|
||||
0x9121028a, /* ADD32 temp[10].32 = temp[4].32 - const[10].32 */
|
||||
0x5034300b, /* SFTLP32 temp[11].32 = temp[6].32 << 0 */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd1840000, /* LIMM temp[1].32 = 0000 */
|
||||
0x50242000, /* SFTLP32 temp[0].32 = temp[4].32 << 0 */
|
||||
0xb1800000, /* CMP P0 = (temp[0].64 = 0000) */
|
||||
0xd9a40000, /* LIMM ? temp[9].32 = 0000 */
|
||||
0xd9a80000, /* LIMM ? temp[10].32 = 0000 */
|
||||
0xd0800006, /* ST const[12].64: mem(?) <= src(?) */
|
||||
0xd0000007, /* LD const[14].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf4024003, /* DOUT doutv = temp[0].64, const[2].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output pvr_draw_indirect_elements3_program = {
|
||||
pvr_draw_indirect_elements3_code, /* code segment */
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
7, /* number of constant mappings */
|
||||
|
||||
16, /* size of data segment, in dwords, aligned to 4 */
|
||||
24, /* size of code segment, in dwords, aligned to 4 */
|
||||
20, /* size of temp segment, in dwords, aligned to 4 */
|
||||
16, /* size of data segment, in dwords */
|
||||
21, /* size of code segment, in dwords */
|
||||
18, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_elements3_di_data(buffer, addr, device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x80000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements3_write_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x1c50000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 12, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements3_flush_vdm(buffer, addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x3160000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 14, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements3_idx_stride(buffer, value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements3_idx_base(buffer, value) \
|
||||
do { \
|
||||
uint64_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements3_idx_header(buffer, value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements3_num_views(buffer, value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 7, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements3_immediates(buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTELEMENTS_BASE_INSTANCE0_H
|
||||
#define PVR_DRAW_INDIRECTELEMENTS_BASE_INSTANCE0_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_elements.pds */
|
||||
|
||||
static const uint32_t pvr_draw_indirect_elements_base_instance0_code[23] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0x9000a0e0, /* ADD32 ptemp[0].32 = const[2].32 + temp[3].32 */
|
||||
0x9000a121, /* ADD32 ptemp[1].32 = const[2].32 + temp[4].32 */
|
||||
0x9130f0e3, /* ADD32 ptemp[3].32 = ptemp[3].32 - ptemp[3].32 */
|
||||
0x04101823, /* MAD temp[6].64 = (temp[2].32 * const[3].32) +
|
||||
const[4].64 */
|
||||
0x53383008, /* SFTLP32 temp[8].32 = (temp[7].32 | const[6].32) << 0
|
||||
*/
|
||||
0x50343009, /* SFTLP32 temp[9].32 = temp[6].32 << 0 */
|
||||
0x04083843, /* MAD temp[6].64 = (temp[1].32 * const[7].32) +
|
||||
const[8].64 */
|
||||
0x50343001, /* SFTLP32 temp[1].32 = temp[6].32 << 0 */
|
||||
0x5004000a, /* SFTLP32 temp[10].32 = temp[0].32 << 0 */
|
||||
0x9120428b, /* ADD32 temp[11].32 = temp[1].32 - const[10].32 */
|
||||
0x501c180c, /* SFTLP32 temp[12].32 = temp[3].32 << 0 */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd19c0000, /* LIMM temp[7].32 = 0000 */
|
||||
0x500c0806, /* SFTLP32 temp[6].32 = temp[1].32 << 0 */
|
||||
0xb18c0000, /* CMP P0 = (temp[6].64 = 0000) */
|
||||
0xd9a80000, /* LIMM ? temp[10].32 = 0000 */
|
||||
0xd9ac0000, /* LIMM ? temp[11].32 = 0000 */
|
||||
0xd0800006, /* ST const[12].64: mem(?) <= src(?) */
|
||||
0xd0000007, /* LD const[14].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf4024003, /* DOUT doutv = temp[0].64, const[2].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output
|
||||
pvr_draw_indirect_elements_base_instance0_program = {
|
||||
pvr_draw_indirect_elements_base_instance0_code, /* code segment */
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
7, /* number of constant mappings */
|
||||
|
||||
16, /* size of data segment, in dwords, aligned to 4 */
|
||||
24, /* size of code segment, in dwords, aligned to 4 */
|
||||
20, /* size of temp segment, in dwords, aligned to 4 */
|
||||
16, /* size of data segment, in dwords */
|
||||
23, /* size of code segment, in dwords */
|
||||
20, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_elements_base_instance0_di_data(buffer, \
|
||||
addr, \
|
||||
device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x60000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance0_write_vdm(buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x2050000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 12, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance0_flush_vdm(buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x3960000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 14, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance0_idx_stride(buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance0_idx_base(buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint64_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance0_idx_header(buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance0_num_views(buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 7, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance0_immediates(buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTELEMENTS_BASE_INSTANCE1_H
|
||||
#define PVR_DRAW_INDIRECTELEMENTS_BASE_INSTANCE1_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_elements.pds */
|
||||
|
||||
static const uint32_t pvr_draw_indirect_elements_base_instance1_code[23] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0x9000a120, /* ADD32 ptemp[0].32 = const[2].32 + temp[4].32 */
|
||||
0x9000a161, /* ADD32 ptemp[1].32 = const[2].32 + temp[5].32 */
|
||||
0x9130f0e3, /* ADD32 ptemp[3].32 = ptemp[3].32 - ptemp[3].32 */
|
||||
0x04181823, /* MAD temp[6].64 = (temp[3].32 * const[3].32) +
|
||||
const[4].64 */
|
||||
0x53383008, /* SFTLP32 temp[8].32 = (temp[7].32 | const[6].32) << 0
|
||||
*/
|
||||
0x50343009, /* SFTLP32 temp[9].32 = temp[6].32 << 0 */
|
||||
0x04103843, /* MAD temp[6].64 = (temp[2].32 * const[7].32) +
|
||||
const[8].64 */
|
||||
0x50343002, /* SFTLP32 temp[2].32 = temp[6].32 << 0 */
|
||||
0x500c080a, /* SFTLP32 temp[10].32 = temp[1].32 << 0 */
|
||||
0x9120828b, /* ADD32 temp[11].32 = temp[2].32 - const[10].32 */
|
||||
0x5024200c, /* SFTLP32 temp[12].32 = temp[4].32 << 0 */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd19c0000, /* LIMM temp[7].32 = 0000 */
|
||||
0x50141006, /* SFTLP32 temp[6].32 = temp[2].32 << 0 */
|
||||
0xb18c0000, /* CMP P0 = (temp[6].64 = 0000) */
|
||||
0xd9a80000, /* LIMM ? temp[10].32 = 0000 */
|
||||
0xd9ac0000, /* LIMM ? temp[11].32 = 0000 */
|
||||
0xd0800006, /* ST const[12].64: mem(?) <= src(?) */
|
||||
0xd0000007, /* LD const[14].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf4024003, /* DOUT doutv = temp[0].64, const[2].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output
|
||||
pvr_draw_indirect_elements_base_instance1_program = {
|
||||
pvr_draw_indirect_elements_base_instance1_code, /* code segment */
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
7, /* number of constant mappings */
|
||||
|
||||
16, /* size of data segment, in dwords, aligned to 4 */
|
||||
24, /* size of code segment, in dwords, aligned to 4 */
|
||||
20, /* size of temp segment, in dwords, aligned to 4 */
|
||||
16, /* size of data segment, in dwords */
|
||||
23, /* size of code segment, in dwords */
|
||||
20, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_elements_base_instance1_di_data(buffer, \
|
||||
addr, \
|
||||
device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x60000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance1_write_vdm(buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x2050000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 12, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance1_flush_vdm(buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x3960000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 14, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance1_idx_stride(buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance1_idx_base(buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint64_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance1_idx_header(buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance1_num_views(buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 7, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance1_immediates(buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTELEMENTS_BASE_INSTANCE2_H
|
||||
#define PVR_DRAW_INDIRECTELEMENTS_BASE_INSTANCE2_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_elements.pds */
|
||||
|
||||
static const uint32_t pvr_draw_indirect_elements_base_instance2_code[23] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0x9000a160, /* ADD32 ptemp[0].32 = const[2].32 + temp[5].32 */
|
||||
0x9000a1a1, /* ADD32 ptemp[1].32 = const[2].32 + temp[6].32 */
|
||||
0x9130f0e3, /* ADD32 ptemp[3].32 = ptemp[3].32 - ptemp[3].32 */
|
||||
0x04201820, /* MAD temp[0].64 = (temp[4].32 * const[3].32) +
|
||||
const[4].64 */
|
||||
0x53083007, /* SFTLP32 temp[7].32 = (temp[1].32 | const[6].32) << 0
|
||||
*/
|
||||
0x50040008, /* SFTLP32 temp[8].32 = temp[0].32 << 0 */
|
||||
0x04183840, /* MAD temp[0].64 = (temp[3].32 * const[7].32) +
|
||||
const[8].64 */
|
||||
0x50040003, /* SFTLP32 temp[3].32 = temp[0].32 << 0 */
|
||||
0x50141009, /* SFTLP32 temp[9].32 = temp[2].32 << 0 */
|
||||
0x9120c28a, /* ADD32 temp[10].32 = temp[3].32 - const[10].32 */
|
||||
0x502c280b, /* SFTLP32 temp[11].32 = temp[5].32 << 0 */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd1840000, /* LIMM temp[1].32 = 0000 */
|
||||
0x501c1800, /* SFTLP32 temp[0].32 = temp[3].32 << 0 */
|
||||
0xb1800000, /* CMP P0 = (temp[0].64 = 0000) */
|
||||
0xd9a40000, /* LIMM ? temp[9].32 = 0000 */
|
||||
0xd9a80000, /* LIMM ? temp[10].32 = 0000 */
|
||||
0xd0800006, /* ST const[12].64: mem(?) <= src(?) */
|
||||
0xd0000007, /* LD const[14].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf4024003, /* DOUT doutv = temp[0].64, const[2].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output
|
||||
pvr_draw_indirect_elements_base_instance2_program = {
|
||||
pvr_draw_indirect_elements_base_instance2_code, /* code segment */
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
7, /* number of constant mappings */
|
||||
|
||||
16, /* size of data segment, in dwords, aligned to 4 */
|
||||
24, /* size of code segment, in dwords, aligned to 4 */
|
||||
20, /* size of temp segment, in dwords, aligned to 4 */
|
||||
16, /* size of data segment, in dwords */
|
||||
23, /* size of code segment, in dwords */
|
||||
18, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_elements_base_instance2_di_data(buffer, \
|
||||
addr, \
|
||||
device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x80000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance2_write_vdm(buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x1c50000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 12, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance2_flush_vdm(buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x3160000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 14, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance2_idx_stride(buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance2_idx_base(buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint64_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance2_idx_header(buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance2_num_views(buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 7, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance2_immediates(buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTELEMENTS_BASE_INSTANCE3_H
|
||||
#define PVR_DRAW_INDIRECTELEMENTS_BASE_INSTANCE3_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_elements.pds */
|
||||
|
||||
static const uint32_t pvr_draw_indirect_elements_base_instance3_code[23] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0x9000a1a0, /* ADD32 ptemp[0].32 = const[2].32 + temp[6].32 */
|
||||
0x9000a1e1, /* ADD32 ptemp[1].32 = const[2].32 + temp[7].32 */
|
||||
0x9130f0e3, /* ADD32 ptemp[3].32 = ptemp[3].32 - ptemp[3].32 */
|
||||
0x04281820, /* MAD temp[0].64 = (temp[5].32 * const[3].32) +
|
||||
const[4].64 */
|
||||
0x53083008, /* SFTLP32 temp[8].32 = (temp[1].32 | const[6].32) << 0
|
||||
*/
|
||||
0x50040009, /* SFTLP32 temp[9].32 = temp[0].32 << 0 */
|
||||
0x04203840, /* MAD temp[0].64 = (temp[4].32 * const[7].32) +
|
||||
const[8].64 */
|
||||
0x50040004, /* SFTLP32 temp[4].32 = temp[0].32 << 0 */
|
||||
0x501c180a, /* SFTLP32 temp[10].32 = temp[3].32 << 0 */
|
||||
0x9121028b, /* ADD32 temp[11].32 = temp[4].32 - const[10].32 */
|
||||
0x5034300c, /* SFTLP32 temp[12].32 = temp[6].32 << 0 */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd1840000, /* LIMM temp[1].32 = 0000 */
|
||||
0x50242000, /* SFTLP32 temp[0].32 = temp[4].32 << 0 */
|
||||
0xb1800000, /* CMP P0 = (temp[0].64 = 0000) */
|
||||
0xd9a80000, /* LIMM ? temp[10].32 = 0000 */
|
||||
0xd9ac0000, /* LIMM ? temp[11].32 = 0000 */
|
||||
0xd0800006, /* ST const[12].64: mem(?) <= src(?) */
|
||||
0xd0000007, /* LD const[14].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf4024003, /* DOUT doutv = temp[0].64, const[2].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output
|
||||
pvr_draw_indirect_elements_base_instance3_program = {
|
||||
pvr_draw_indirect_elements_base_instance3_code, /* code segment */
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
7, /* number of constant mappings */
|
||||
|
||||
16, /* size of data segment, in dwords, aligned to 4 */
|
||||
24, /* size of code segment, in dwords, aligned to 4 */
|
||||
20, /* size of temp segment, in dwords, aligned to 4 */
|
||||
16, /* size of data segment, in dwords */
|
||||
23, /* size of code segment, in dwords */
|
||||
20, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_elements_base_instance3_di_data(buffer, \
|
||||
addr, \
|
||||
device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x80000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance3_write_vdm(buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x2050000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 12, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance3_flush_vdm(buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x3960000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 14, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance3_idx_stride(buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance3_idx_base(buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint64_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance3_idx_header(buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance3_num_views(buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 7, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance3_immediates(buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTELEMENTS_BASE_INSTANCE_DRAWID0_H
|
||||
#define PVR_DRAW_INDIRECTELEMENTS_BASE_INSTANCE_DRAWID0_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_elements.pds */
|
||||
|
||||
static const uint32_t
|
||||
pvr_draw_indirect_elements_base_instance_drawid0_code[23] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0x9000a0e0, /* ADD32 ptemp[0].32 = const[2].32 + temp[3].32 */
|
||||
0x9000a121, /* ADD32 ptemp[1].32 = const[2].32 + temp[4].32 */
|
||||
0x9030c0e3, /* ADD32 ptemp[3].32 = ptemp[3].32 + const[3].32 */
|
||||
0x04102033, /* MAD temp[6].64 = (temp[2].32 * const[4].32) +
|
||||
const[6].64 */
|
||||
0x53382808, /* SFTLP32 temp[8].32 = (temp[7].32 | const[5].32) <<
|
||||
* 0
|
||||
*/
|
||||
0x50343009, /* SFTLP32 temp[9].32 = temp[6].32 << 0 */
|
||||
0x04084053, /* MAD temp[6].64 = (temp[1].32 * const[8].32) +
|
||||
const[10].64 */
|
||||
0x50343001, /* SFTLP32 temp[1].32 = temp[6].32 << 0 */
|
||||
0x5004000a, /* SFTLP32 temp[10].32 = temp[0].32 << 0 */
|
||||
0x912040cb, /* ADD32 temp[11].32 = temp[1].32 - const[3].32 */
|
||||
0x501c180c, /* SFTLP32 temp[12].32 = temp[3].32 << 0 */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd19c0000, /* LIMM temp[7].32 = 0000 */
|
||||
0x500c0806, /* SFTLP32 temp[6].32 = temp[1].32 << 0 */
|
||||
0xb18c0000, /* CMP P0 = (temp[6].64 = 0000) */
|
||||
0xd9a80000, /* LIMM ? temp[10].32 = 0000 */
|
||||
0xd9ac0000, /* LIMM ? temp[11].32 = 0000 */
|
||||
0xd0800006, /* ST const[12].64: mem(?) <= src(?) */
|
||||
0xd0000007, /* LD const[14].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf4024003, /* DOUT doutv = temp[0].64, const[2].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output
|
||||
pvr_draw_indirect_elements_base_instance_drawid0_program = {
|
||||
pvr_draw_indirect_elements_base_instance_drawid0_code, /* code segment
|
||||
*/
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
7, /* number of constant mappings */
|
||||
|
||||
16, /* size of data segment, in dwords, aligned to 4 */
|
||||
24, /* size of code segment, in dwords, aligned to 4 */
|
||||
20, /* size of temp segment, in dwords, aligned to 4 */
|
||||
16, /* size of data segment, in dwords */
|
||||
23, /* size of code segment, in dwords */
|
||||
20, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid0_di_data(buffer, \
|
||||
addr, \
|
||||
device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x60000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid0_write_vdm( \
|
||||
buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x2050000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 12, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid0_flush_vdm( \
|
||||
buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x3960000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 14, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid0_idx_stride( \
|
||||
buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid0_idx_base( \
|
||||
buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint64_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid0_idx_header( \
|
||||
buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 5, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid0_num_views( \
|
||||
buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid0_immediates( \
|
||||
buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTELEMENTS_BASE_INSTANCE_DRAWID1_H
|
||||
#define PVR_DRAW_INDIRECTELEMENTS_BASE_INSTANCE_DRAWID1_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_elements.pds */
|
||||
|
||||
static const uint32_t
|
||||
pvr_draw_indirect_elements_base_instance_drawid1_code[23] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0x9000a120, /* ADD32 ptemp[0].32 = const[2].32 + temp[4].32 */
|
||||
0x9000a161, /* ADD32 ptemp[1].32 = const[2].32 + temp[5].32 */
|
||||
0x9030c0e3, /* ADD32 ptemp[3].32 = ptemp[3].32 + const[3].32 */
|
||||
0x04182033, /* MAD temp[6].64 = (temp[3].32 * const[4].32) +
|
||||
const[6].64 */
|
||||
0x53382808, /* SFTLP32 temp[8].32 = (temp[7].32 | const[5].32) <<
|
||||
* 0
|
||||
*/
|
||||
0x50343009, /* SFTLP32 temp[9].32 = temp[6].32 << 0 */
|
||||
0x04104053, /* MAD temp[6].64 = (temp[2].32 * const[8].32) +
|
||||
const[10].64 */
|
||||
0x50343002, /* SFTLP32 temp[2].32 = temp[6].32 << 0 */
|
||||
0x500c080a, /* SFTLP32 temp[10].32 = temp[1].32 << 0 */
|
||||
0x912080cb, /* ADD32 temp[11].32 = temp[2].32 - const[3].32 */
|
||||
0x5024200c, /* SFTLP32 temp[12].32 = temp[4].32 << 0 */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd19c0000, /* LIMM temp[7].32 = 0000 */
|
||||
0x50141006, /* SFTLP32 temp[6].32 = temp[2].32 << 0 */
|
||||
0xb18c0000, /* CMP P0 = (temp[6].64 = 0000) */
|
||||
0xd9a80000, /* LIMM ? temp[10].32 = 0000 */
|
||||
0xd9ac0000, /* LIMM ? temp[11].32 = 0000 */
|
||||
0xd0800006, /* ST const[12].64: mem(?) <= src(?) */
|
||||
0xd0000007, /* LD const[14].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf4024003, /* DOUT doutv = temp[0].64, const[2].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output
|
||||
pvr_draw_indirect_elements_base_instance_drawid1_program = {
|
||||
pvr_draw_indirect_elements_base_instance_drawid1_code, /* code segment
|
||||
*/
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
7, /* number of constant mappings */
|
||||
|
||||
16, /* size of data segment, in dwords, aligned to 4 */
|
||||
24, /* size of code segment, in dwords, aligned to 4 */
|
||||
20, /* size of temp segment, in dwords, aligned to 4 */
|
||||
16, /* size of data segment, in dwords */
|
||||
23, /* size of code segment, in dwords */
|
||||
20, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid1_di_data(buffer, \
|
||||
addr, \
|
||||
device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x60000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid1_write_vdm( \
|
||||
buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x2050000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 12, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid1_flush_vdm( \
|
||||
buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x3960000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 14, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid1_idx_stride( \
|
||||
buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid1_idx_base( \
|
||||
buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint64_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid1_idx_header( \
|
||||
buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 5, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid1_num_views( \
|
||||
buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid1_immediates( \
|
||||
buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTELEMENTS_BASE_INSTANCE_DRAWID2_H
|
||||
#define PVR_DRAW_INDIRECTELEMENTS_BASE_INSTANCE_DRAWID2_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_elements.pds */
|
||||
|
||||
static const uint32_t
|
||||
pvr_draw_indirect_elements_base_instance_drawid2_code[23] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0x9000a160, /* ADD32 ptemp[0].32 = const[2].32 + temp[5].32 */
|
||||
0x9000a1a1, /* ADD32 ptemp[1].32 = const[2].32 + temp[6].32 */
|
||||
0x9030c0e3, /* ADD32 ptemp[3].32 = ptemp[3].32 + const[3].32 */
|
||||
0x04202030, /* MAD temp[0].64 = (temp[4].32 * const[4].32) +
|
||||
const[6].64 */
|
||||
0x53082807, /* SFTLP32 temp[7].32 = (temp[1].32 | const[5].32) <<
|
||||
* 0
|
||||
*/
|
||||
0x50040008, /* SFTLP32 temp[8].32 = temp[0].32 << 0 */
|
||||
0x04184050, /* MAD temp[0].64 = (temp[3].32 * const[8].32) +
|
||||
const[10].64 */
|
||||
0x50040003, /* SFTLP32 temp[3].32 = temp[0].32 << 0 */
|
||||
0x50141009, /* SFTLP32 temp[9].32 = temp[2].32 << 0 */
|
||||
0x9120c0ca, /* ADD32 temp[10].32 = temp[3].32 - const[3].32 */
|
||||
0x502c280b, /* SFTLP32 temp[11].32 = temp[5].32 << 0 */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd1840000, /* LIMM temp[1].32 = 0000 */
|
||||
0x501c1800, /* SFTLP32 temp[0].32 = temp[3].32 << 0 */
|
||||
0xb1800000, /* CMP P0 = (temp[0].64 = 0000) */
|
||||
0xd9a40000, /* LIMM ? temp[9].32 = 0000 */
|
||||
0xd9a80000, /* LIMM ? temp[10].32 = 0000 */
|
||||
0xd0800006, /* ST const[12].64: mem(?) <= src(?) */
|
||||
0xd0000007, /* LD const[14].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf4024003, /* DOUT doutv = temp[0].64, const[2].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output
|
||||
pvr_draw_indirect_elements_base_instance_drawid2_program = {
|
||||
pvr_draw_indirect_elements_base_instance_drawid2_code, /* code segment
|
||||
*/
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
7, /* number of constant mappings */
|
||||
|
||||
16, /* size of data segment, in dwords, aligned to 4 */
|
||||
24, /* size of code segment, in dwords, aligned to 4 */
|
||||
20, /* size of temp segment, in dwords, aligned to 4 */
|
||||
16, /* size of data segment, in dwords */
|
||||
23, /* size of code segment, in dwords */
|
||||
18, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid2_di_data(buffer, \
|
||||
addr, \
|
||||
device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x80000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid2_write_vdm( \
|
||||
buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x1c50000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 12, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid2_flush_vdm( \
|
||||
buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x3160000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 14, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid2_idx_stride( \
|
||||
buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid2_idx_base( \
|
||||
buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint64_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid2_idx_header( \
|
||||
buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 5, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid2_num_views( \
|
||||
buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid2_immediates( \
|
||||
buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* 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_DRAW_INDIRECTELEMENTS_BASE_INSTANCE_DRAWID3_H
|
||||
#define PVR_DRAW_INDIRECTELEMENTS_BASE_INSTANCE_DRAWID3_H
|
||||
|
||||
/* Initially generated from ARB_draw_indirect_elements.pds */
|
||||
|
||||
static const uint32_t
|
||||
pvr_draw_indirect_elements_base_instance_drawid3_code[23] = {
|
||||
0xd0000000, /* LD const[0].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0x9000a1a0, /* ADD32 ptemp[0].32 = const[2].32 + temp[6].32 */
|
||||
0x9000a1e1, /* ADD32 ptemp[1].32 = const[2].32 + temp[7].32 */
|
||||
0x9030c0e3, /* ADD32 ptemp[3].32 = ptemp[3].32 + const[3].32 */
|
||||
0x04282030, /* MAD temp[0].64 = (temp[5].32 * const[4].32) +
|
||||
const[6].64 */
|
||||
0x53082808, /* SFTLP32 temp[8].32 = (temp[1].32 | const[5].32) <<
|
||||
* 0
|
||||
*/
|
||||
0x50040009, /* SFTLP32 temp[9].32 = temp[0].32 << 0 */
|
||||
0x04204050, /* MAD temp[0].64 = (temp[4].32 * const[8].32) +
|
||||
const[10].64 */
|
||||
0x50040004, /* SFTLP32 temp[4].32 = temp[0].32 << 0 */
|
||||
0x501c180a, /* SFTLP32 temp[10].32 = temp[3].32 << 0 */
|
||||
0x912100cb, /* ADD32 temp[11].32 = temp[4].32 - const[3].32 */
|
||||
0x5034300c, /* SFTLP32 temp[12].32 = temp[6].32 << 0 */
|
||||
0xc8000001, /* BRA if keep 1 ( setc = p0 ) */
|
||||
0xd1840000, /* LIMM temp[1].32 = 0000 */
|
||||
0x50242000, /* SFTLP32 temp[0].32 = temp[4].32 << 0 */
|
||||
0xb1800000, /* CMP P0 = (temp[0].64 = 0000) */
|
||||
0xd9a80000, /* LIMM ? temp[10].32 = 0000 */
|
||||
0xd9ac0000, /* LIMM ? temp[11].32 = 0000 */
|
||||
0xd0800006, /* ST const[12].64: mem(?) <= src(?) */
|
||||
0xd0000007, /* LD const[14].64: dst(?) <= mem(?) */
|
||||
0xd1000000, /* WDF */
|
||||
0xf4024003, /* DOUT doutv = temp[0].64, const[2].32; HALT */
|
||||
};
|
||||
|
||||
static const struct pvr_psc_program_output
|
||||
pvr_draw_indirect_elements_base_instance_drawid3_program = {
|
||||
pvr_draw_indirect_elements_base_instance_drawid3_code, /* code segment
|
||||
*/
|
||||
0, /* constant mappings, zeroed since we use the macros below */
|
||||
7, /* number of constant mappings */
|
||||
|
||||
16, /* size of data segment, in dwords, aligned to 4 */
|
||||
24, /* size of code segment, in dwords, aligned to 4 */
|
||||
20, /* size of temp segment, in dwords, aligned to 4 */
|
||||
16, /* size of data segment, in dwords */
|
||||
23, /* size of code segment, in dwords */
|
||||
20, /* size of temp segment, in dwords */
|
||||
NULL /* function pointer to write data segment */
|
||||
};
|
||||
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid3_di_data(buffer, \
|
||||
addr, \
|
||||
device) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x80000000000ULL) | \
|
||||
ENABLE_SLC_MCU_CACHE_CONTROLS(device)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 0, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid3_write_vdm( \
|
||||
buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x2050000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 12, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid3_flush_vdm( \
|
||||
buffer, \
|
||||
addr) \
|
||||
do { \
|
||||
uint64_t data = ((addr) | (0x3960000000000ULL)); \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 14, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid3_idx_stride( \
|
||||
buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 4, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid3_idx_base( \
|
||||
buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint64_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 6, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid3_idx_header( \
|
||||
buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 5, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid3_num_views( \
|
||||
buffer, \
|
||||
value) \
|
||||
do { \
|
||||
uint32_t data = value; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 8, &data, sizeof(data)); \
|
||||
} while (0)
|
||||
#define pvr_write_draw_indirect_elements_base_instance_drawid3_immediates( \
|
||||
buffer) \
|
||||
do { \
|
||||
{ \
|
||||
uint32_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 2, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint32_t data = 0x1; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 3, &data, sizeof(data)); \
|
||||
} \
|
||||
{ \
|
||||
uint64_t data = 0x0; \
|
||||
PVR_PDS_PRINT_DATA("DRAW_INDIRECT_ELEMENTS", data, 0); \
|
||||
memcpy(buffer + 10, &data, sizeof(data)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
* 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_ROGUE_PDS_DISASM_H
|
||||
#define PVR_ROGUE_PDS_DISASM_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
/* Type of operand for an instruction. */
|
||||
#define PVR_PDS_OPERAND_TYPES \
|
||||
X(TEMP32, temp, 32) \
|
||||
X(PTEMP32, ptemp, 32) \
|
||||
X(CONST32, const, 32) \
|
||||
X(TEMP64, temp, 64) \
|
||||
X(PTEMP64, ptemp, 64) \
|
||||
X(CONST64, const, 64) \
|
||||
X(UNRESOLVED, UNRESOLVED, 0) \
|
||||
X(LITERAL_NUM, literal, 0)
|
||||
|
||||
#define X(enum, str, size) enum,
|
||||
enum pvr_operand_type { PVR_PDS_OPERAND_TYPES };
|
||||
#undef X
|
||||
|
||||
#if defined(DUMP_PDS)
|
||||
# define PVR_PDS_PRINT_INST(X) pvr_pds_print_instruction(X)
|
||||
# define PVR_PDS_PRINT_DATA(X, Y, Z) \
|
||||
mesa_logd("\t%s : DATA = 0x%lX ADDRESS = 0x%X\n", X, (uint64_t)(Y), Z)
|
||||
#else
|
||||
# define PVR_PDS_PRINT_INST(X)
|
||||
# define PVR_PDS_PRINT_DATA(X, Y, Z)
|
||||
#endif
|
||||
|
||||
#define PVR_INSTRUCTION_STMP
|
||||
#define PVR_INSTRUCTION_IDIV
|
||||
#define PVR_INSTRUCTION_AA
|
||||
#define PVR_INSTRUCTION_POL
|
||||
#define PVR_INSTRUCTION_IDF
|
||||
|
||||
#define PVR_INSTRUCTIONS \
|
||||
X(STM) \
|
||||
PVR_INSTRUCTION_STMP \
|
||||
PVR_INSTRUCTION_IDIV \
|
||||
PVR_INSTRUCTION_AA \
|
||||
PVR_INSTRUCTION_IDF \
|
||||
PVR_INSTRUCTION_POL \
|
||||
X(STMC) \
|
||||
X(LD) \
|
||||
X(ST) \
|
||||
X(ADD32) \
|
||||
X(ADD64) \
|
||||
X(MAD) \
|
||||
X(DDMAD) \
|
||||
X(DOUT) \
|
||||
X(CMP) \
|
||||
X(BRA) \
|
||||
X(LIMM) \
|
||||
X(SFTLP32) \
|
||||
X(SFTLP64) \
|
||||
X(WDF) \
|
||||
X(LOCK) \
|
||||
X(RELEASE) \
|
||||
X(HALT) \
|
||||
X(NOP)
|
||||
|
||||
#define X(a) INS_##a,
|
||||
enum pvr_instruction_type { PVR_INSTRUCTIONS };
|
||||
#undef X
|
||||
|
||||
struct pvr_predicate {
|
||||
uint32_t predicate;
|
||||
bool negate;
|
||||
};
|
||||
|
||||
struct pvr_instruction;
|
||||
|
||||
/* Operands are either sources or dst of an instruction. */
|
||||
struct pvr_operand {
|
||||
enum pvr_operand_type type;
|
||||
|
||||
struct pvr_instruction *instruction;
|
||||
uint64_t literal; /* Literal value if type == LITERAL_NUM */
|
||||
int address; /* Address in word-sizes. */
|
||||
unsigned absolute_address; /* Address in segment, */
|
||||
unsigned index; /* Index within instruction, 0 = dst, 1 = src0 .. */
|
||||
bool negate; /* True if the literal is negative. */
|
||||
};
|
||||
|
||||
#define PVR_PDS_LOP \
|
||||
X(LOP_NONE, none) \
|
||||
X(LOP_NOT, ~) \
|
||||
X(LOP_AND, &) \
|
||||
X(LOP_OR, |) \
|
||||
X(LOP_XOR, xor) \
|
||||
X(LOP_XNOR, xnor) \
|
||||
X(LOP_NAND, nand) \
|
||||
X(LOP_NOR, nor)
|
||||
|
||||
#define X(lop, str) lop,
|
||||
enum pvr_pds_lop { PVR_PDS_LOP };
|
||||
#undef X
|
||||
|
||||
#define PVR_PDS_DOUT_DSTS \
|
||||
X(DOUT_D, doutd) \
|
||||
X(DOUT_W, doutw) \
|
||||
X(DOUT_U, doutu) \
|
||||
X(DOUT_V, doutv) \
|
||||
X(DOUT_I, douti) \
|
||||
X(DOUT_C, doutc) \
|
||||
X(DOUT_R, doutr) \
|
||||
X(DOUT_INVALID0, invalid)
|
||||
|
||||
#define X(dout_dst, str) dout_dst,
|
||||
enum pvr_dout_type { PVR_PDS_DOUT_DSTS };
|
||||
#undef X
|
||||
|
||||
#define PVR_PDS_MAX_INST_STR_LEN 256
|
||||
|
||||
enum pvr_cop { COP_EQ, COP_GT, COP_LT, COP_NE };
|
||||
|
||||
struct pvr_instruction {
|
||||
enum pvr_instruction_type type;
|
||||
struct pvr_instruction *next;
|
||||
};
|
||||
|
||||
struct pvr_add {
|
||||
struct pvr_instruction instruction;
|
||||
struct pvr_operand *dst;
|
||||
struct pvr_operand *src1;
|
||||
struct pvr_operand *src0;
|
||||
bool cc;
|
||||
bool sna;
|
||||
bool alum;
|
||||
};
|
||||
|
||||
struct pvr_simple {
|
||||
struct pvr_instruction instruction;
|
||||
bool cc;
|
||||
};
|
||||
|
||||
struct pvr_ldst {
|
||||
struct pvr_instruction instruction;
|
||||
bool cc;
|
||||
struct pvr_operand *src0;
|
||||
bool st;
|
||||
};
|
||||
|
||||
struct pvr_mad {
|
||||
struct pvr_instruction instruction;
|
||||
struct pvr_operand *dst;
|
||||
struct pvr_operand *src0;
|
||||
struct pvr_operand *src1;
|
||||
struct pvr_operand *src2;
|
||||
bool cc;
|
||||
bool sna;
|
||||
bool alum;
|
||||
};
|
||||
|
||||
struct pvr_stm {
|
||||
struct pvr_instruction instruction;
|
||||
struct pvr_operand *src0;
|
||||
struct pvr_operand *src1;
|
||||
struct pvr_operand *src2;
|
||||
struct pvr_operand *src3;
|
||||
unsigned stream_out;
|
||||
bool tst;
|
||||
bool cc;
|
||||
bool ccs_global;
|
||||
bool ccs_so;
|
||||
};
|
||||
|
||||
struct pvr_stmc {
|
||||
struct pvr_instruction instruction;
|
||||
struct pvr_operand *src0;
|
||||
bool cc;
|
||||
};
|
||||
|
||||
struct pvr_bra {
|
||||
struct pvr_instruction instruction;
|
||||
struct pvr_predicate *srcc;
|
||||
struct pvr_predicate *setc; /* negate ignored */
|
||||
char *target;
|
||||
signed address; /* signed relative address */
|
||||
};
|
||||
|
||||
struct pvr_dout {
|
||||
struct pvr_instruction instruction;
|
||||
struct pvr_operand *src0;
|
||||
struct pvr_operand *src1;
|
||||
enum pvr_dout_type dst;
|
||||
bool cc;
|
||||
bool END;
|
||||
};
|
||||
|
||||
struct pvr_ddmad {
|
||||
struct pvr_instruction instruction;
|
||||
struct pvr_operand *src0;
|
||||
struct pvr_operand *src1;
|
||||
struct pvr_operand *src2;
|
||||
struct pvr_operand *src3;
|
||||
bool cc;
|
||||
bool END;
|
||||
};
|
||||
|
||||
struct pvr_sftlp {
|
||||
struct pvr_instruction instruction;
|
||||
enum pvr_pds_lop lop;
|
||||
struct pvr_operand *dst;
|
||||
struct pvr_operand *src0;
|
||||
struct pvr_operand *src1;
|
||||
struct pvr_operand *src2;
|
||||
bool cc;
|
||||
bool IM;
|
||||
};
|
||||
|
||||
struct pvr_limm {
|
||||
struct pvr_instruction instruction;
|
||||
bool cc;
|
||||
bool GR;
|
||||
struct pvr_operand *dst;
|
||||
struct pvr_operand *src0;
|
||||
};
|
||||
|
||||
struct pvr_cmp {
|
||||
struct pvr_instruction instruction;
|
||||
enum pvr_cop cop;
|
||||
bool IM;
|
||||
bool cc;
|
||||
struct pvr_operand *src0;
|
||||
struct pvr_operand *src1;
|
||||
};
|
||||
|
||||
#define PVR_PDS_ERR_PARAM_RANGE 0 /* Error when register is out of range. */
|
||||
#define PVR_PDS_ERR_SP_UNKNOWN \
|
||||
1 /* Error when opcode for sp instruction is unknown. */
|
||||
|
||||
struct pvr_dissassembler_error {
|
||||
uint32_t type; /* One of PDS_ERR_* */
|
||||
enum pvr_instruction_type instruction; /* The type of instruction where
|
||||
the error occurred. */
|
||||
char *text; /* A string representation of the error. */
|
||||
uint32_t parameter; /* The parameter of the instruction, 0 = dst,
|
||||
1 = src0.. */
|
||||
uint32_t raw; /* The raw value that caused the error. */
|
||||
|
||||
void *context; /* The passed in context. */
|
||||
};
|
||||
|
||||
/* Callback when an error happens. */
|
||||
typedef void (*PVR_ERR_CALLBACK)(struct pvr_dissassembler_error);
|
||||
|
||||
void pvr_pds_free_instruction(struct pvr_instruction *inst);
|
||||
struct pvr_instruction *
|
||||
pvr_pds_disassemble_instruction2(void *context,
|
||||
PVR_ERR_CALLBACK error_call_back,
|
||||
uint32_t instruction);
|
||||
void pvr_pds_disassemble_instruction(char *buffer,
|
||||
size_t instr_len,
|
||||
struct pvr_instruction *instruction);
|
||||
|
||||
#if defined(DUMP_PDS)
|
||||
void pvr_pds_print_instruction(uint32_t instr);
|
||||
#endif
|
||||
|
||||
#endif /* PVR_ROGUE_PDS_DISASM_H */
|
|
@ -0,0 +1,538 @@
|
|||
/*
|
||||
* 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_ROGUE_PDS_ENCODE_H
|
||||
#define PVR_ROGUE_PDS_ENCODE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "pvr_rogue_pds_defs.h"
|
||||
#include "pvr_rogue_pds_disasm.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
static ALWAYS_INLINE uint32_t
|
||||
pvr_pds_inst_decode_field_range_regs64tp(uint32_t value)
|
||||
{
|
||||
if (value <= PVR_ROGUE_PDSINST_REGS64TP_TEMP64_UPPER)
|
||||
return PVR_ROGUE_PDSINST_REGS64TP_TEMP64;
|
||||
|
||||
if ((value >= PVR_ROGUE_PDSINST_REGS64TP_PTEMP64_LOWER) &&
|
||||
(value <= PVR_ROGUE_PDSINST_REGS64TP_PTEMP64_UPPER)) {
|
||||
return PVR_ROGUE_PDSINST_REGS64TP_PTEMP64;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t
|
||||
pvr_pds_inst_decode_field_range_regs32(uint32_t value)
|
||||
{
|
||||
if (value <= PVR_ROGUE_PDSINST_REGS32_CONST32_UPPER)
|
||||
return PVR_ROGUE_PDSINST_REGS32_CONST32;
|
||||
|
||||
if ((value >= PVR_ROGUE_PDSINST_REGS32_TEMP32_LOWER) &&
|
||||
(value <= PVR_ROGUE_PDSINST_REGS32_TEMP32_UPPER)) {
|
||||
return PVR_ROGUE_PDSINST_REGS32_TEMP32;
|
||||
}
|
||||
if ((value >= PVR_ROGUE_PDSINST_REGS32_PTEMP32_LOWER) &&
|
||||
(value <= PVR_ROGUE_PDSINST_REGS32_PTEMP32_UPPER)) {
|
||||
return PVR_ROGUE_PDSINST_REGS32_PTEMP32;
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t pvr_pds_inst_encode_stflp64(uint32_t cc,
|
||||
uint32_t lop,
|
||||
uint32_t im,
|
||||
uint32_t src0,
|
||||
uint32_t src1,
|
||||
uint32_t src2,
|
||||
uint32_t dst)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODEC_SFTLP64
|
||||
<< PVR_ROGUE_PDSINST_SFTLP64_OPCODE_SHIFT;
|
||||
encoded |= ((dst & PVR_ROGUE_PDSINST_REGS64TP_MASK)
|
||||
<< PVR_ROGUE_PDSINST_SFTLP64_DST_SHIFT);
|
||||
encoded |= ((src2 & PVR_ROGUE_PDSINST_REGS32_MASK)
|
||||
<< PVR_ROGUE_PDSINST_SFTLP64_SRC2_SHIFT);
|
||||
encoded |= ((src1 & PVR_ROGUE_PDSINST_REGS64TP_MASK)
|
||||
<< PVR_ROGUE_PDSINST_SFTLP64_SRC1_SHIFT);
|
||||
encoded |= ((src0 & PVR_ROGUE_PDSINST_REGS64TP_MASK)
|
||||
<< PVR_ROGUE_PDSINST_SFTLP64_SRC0_SHIFT);
|
||||
encoded |= ((im & 1U) << PVR_ROGUE_PDSINST_SFTLP64_IM_SHIFT);
|
||||
encoded |= ((lop & PVR_ROGUE_PDSINST_LOP_MASK)
|
||||
<< PVR_ROGUE_PDSINST_SFTLP64_LOP_SHIFT);
|
||||
encoded |= ((cc & 1U) << PVR_ROGUE_PDSINST_SFTLP64_CC_SHIFT);
|
||||
|
||||
PVR_PDS_PRINT_INST(encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t
|
||||
pvr_pds_inst_decode_field_range_regs32t(uint32_t value)
|
||||
{
|
||||
if (value <= PVR_ROGUE_PDSINST_REGS32T_TEMP32_UPPER)
|
||||
return PVR_ROGUE_PDSINST_REGS32T_TEMP32;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t
|
||||
pvr_pds_inst_decode_field_range_regs32tp(uint32_t value)
|
||||
{
|
||||
if (value <= PVR_ROGUE_PDSINST_REGS32TP_TEMP32_UPPER)
|
||||
return PVR_ROGUE_PDSINST_REGS32TP_TEMP32;
|
||||
|
||||
if ((value >= PVR_ROGUE_PDSINST_REGS32TP_PTEMP32_LOWER) &&
|
||||
(value <= PVR_ROGUE_PDSINST_REGS32TP_PTEMP32_UPPER)) {
|
||||
return PVR_ROGUE_PDSINST_REGS32TP_PTEMP32;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t pvr_pds_inst_encode_stflp32(uint32_t im,
|
||||
uint32_t cc,
|
||||
uint32_t lop,
|
||||
uint32_t src0,
|
||||
uint32_t src1,
|
||||
uint32_t src2,
|
||||
uint32_t dst)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODEB_SFTLP32
|
||||
<< PVR_ROGUE_PDSINST_SFTLP32_OPCODE_SHIFT;
|
||||
encoded |= ((dst & PVR_ROGUE_PDSINST_REGS32T_MASK)
|
||||
<< PVR_ROGUE_PDSINST_SFTLP32_DST_SHIFT);
|
||||
encoded |= ((src2 & PVR_ROGUE_PDSINST_REGS32TP_MASK)
|
||||
<< PVR_ROGUE_PDSINST_SFTLP32_SRC2_SHIFT);
|
||||
encoded |= ((src1 & PVR_ROGUE_PDSINST_REGS32_MASK)
|
||||
<< PVR_ROGUE_PDSINST_SFTLP32_SRC1_SHIFT);
|
||||
encoded |= ((src0 & PVR_ROGUE_PDSINST_REGS32T_MASK)
|
||||
<< PVR_ROGUE_PDSINST_SFTLP32_SRC0_SHIFT);
|
||||
encoded |= ((lop & PVR_ROGUE_PDSINST_LOP_MASK)
|
||||
<< PVR_ROGUE_PDSINST_SFTLP32_LOP_SHIFT);
|
||||
encoded |= ((cc & 1U) << PVR_ROGUE_PDSINST_SFTLP32_CC_SHIFT);
|
||||
encoded |= ((im & 1U) << PVR_ROGUE_PDSINST_SFTLP32_IM_SHIFT);
|
||||
|
||||
PVR_PDS_PRINT_INST(encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t pvr_pds_inst_encode_stm(uint32_t CCS_CCS_GLOBAL,
|
||||
uint32_t CCS_CCS_SO,
|
||||
uint32_t CCS_CCS_CC,
|
||||
uint32_t SO_TST,
|
||||
uint32_t SO,
|
||||
uint32_t SO_SRC0,
|
||||
uint32_t SO_SRC1,
|
||||
uint32_t SO_SRC2,
|
||||
uint32_t SO_SRC3)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODEB_STM
|
||||
<< PVR_ROGUE_PDSINST_STM_OPCODE_SHIFT;
|
||||
encoded |= ((SO_SRC3 & PVR_ROGUE_PDSINST_REGS64TP_MASK)
|
||||
<< PVR_ROGUE_PDSINST_STM_SO_SRC3_SHIFT);
|
||||
encoded |= ((SO_SRC2 & PVR_ROGUE_PDSINST_REGS32_MASK)
|
||||
<< PVR_ROGUE_PDSINST_STM_SO_SRC2_SHIFT);
|
||||
encoded |= ((SO_SRC1 & PVR_ROGUE_PDSINST_REGS64TP_MASK)
|
||||
<< PVR_ROGUE_PDSINST_STM_SO_SRC1_SHIFT);
|
||||
encoded |= ((SO_SRC0 & PVR_ROGUE_PDSINST_REGS64TP_MASK)
|
||||
<< PVR_ROGUE_PDSINST_STM_SO_SRC0_SHIFT);
|
||||
encoded |=
|
||||
((SO & PVR_ROGUE_PDSINST_SO_MASK) << PVR_ROGUE_PDSINST_STM_SO_SHIFT);
|
||||
encoded |= ((SO_TST & 1U) << PVR_ROGUE_PDSINST_STM_SO_TST_SHIFT);
|
||||
encoded |= ((CCS_CCS_CC & 1U) << PVR_ROGUE_PDSINST_STM_CCS_CCS_CC_SHIFT);
|
||||
encoded |= ((CCS_CCS_SO & 1U) << PVR_ROGUE_PDSINST_STM_CCS_CCS_SO_SHIFT);
|
||||
encoded |=
|
||||
((CCS_CCS_GLOBAL & 1U) << PVR_ROGUE_PDSINST_STM_CCS_CCS_GLOBAL_SHIFT);
|
||||
|
||||
PVR_PDS_PRINT_INST(encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t
|
||||
pvr_pds_inst_decode_field_range_regs64(uint32_t value)
|
||||
{
|
||||
if (value <= PVR_ROGUE_PDSINST_REGS64_CONST64_UPPER)
|
||||
return PVR_ROGUE_PDSINST_REGS64_CONST64;
|
||||
|
||||
if ((value >= PVR_ROGUE_PDSINST_REGS64_TEMP64_LOWER) &&
|
||||
(value <= PVR_ROGUE_PDSINST_REGS64_TEMP64_UPPER)) {
|
||||
return PVR_ROGUE_PDSINST_REGS64_TEMP64;
|
||||
}
|
||||
if ((value >= PVR_ROGUE_PDSINST_REGS64_PTEMP64_LOWER) &&
|
||||
(value <= PVR_ROGUE_PDSINST_REGS64_PTEMP64_UPPER)) {
|
||||
return PVR_ROGUE_PDSINST_REGS64_PTEMP64;
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t pvr_rogue_inst_encode_mad(uint32_t sna,
|
||||
uint32_t alum,
|
||||
uint32_t cc,
|
||||
uint32_t src0,
|
||||
uint32_t src1,
|
||||
uint32_t src2,
|
||||
uint32_t dst)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODEA_MAD
|
||||
<< PVR_ROGUE_PDSINST_MAD_OPCODE_SHIFT;
|
||||
encoded |= ((dst & PVR_ROGUE_PDSINST_REGS64T_MASK)
|
||||
<< PVR_ROGUE_PDSINST_MAD_DST_SHIFT);
|
||||
encoded |= ((src2 & PVR_ROGUE_PDSINST_REGS64_MASK)
|
||||
<< PVR_ROGUE_PDSINST_MAD_SRC2_SHIFT);
|
||||
encoded |= ((src1 & PVR_ROGUE_PDSINST_REGS32_MASK)
|
||||
<< PVR_ROGUE_PDSINST_MAD_SRC1_SHIFT);
|
||||
encoded |= ((src0 & PVR_ROGUE_PDSINST_REGS32_MASK)
|
||||
<< PVR_ROGUE_PDSINST_MAD_SRC0_SHIFT);
|
||||
encoded |= ((cc & 1U) << PVR_ROGUE_PDSINST_MAD_CC_SHIFT);
|
||||
encoded |= ((alum & 1U) << PVR_ROGUE_PDSINST_MAD_ALUM_SHIFT);
|
||||
encoded |= ((sna & 1U) << PVR_ROGUE_PDSINST_MAD_SNA_SHIFT);
|
||||
|
||||
PVR_PDS_PRINT_INST(encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t pvr_pds_inst_encode_add64(uint32_t cc,
|
||||
uint32_t alum,
|
||||
uint32_t sna,
|
||||
uint32_t src0,
|
||||
uint32_t src1,
|
||||
uint32_t dst)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODEC_ADD64
|
||||
<< PVR_ROGUE_PDSINST_ADD64_OPCODE_SHIFT;
|
||||
encoded |= ((dst & PVR_ROGUE_PDSINST_REGS64TP_MASK)
|
||||
<< PVR_ROGUE_PDSINST_ADD64_DST_SHIFT);
|
||||
encoded |= ((src1 & PVR_ROGUE_PDSINST_REGS64_MASK)
|
||||
<< PVR_ROGUE_PDSINST_ADD64_SRC1_SHIFT);
|
||||
encoded |= ((src0 & PVR_ROGUE_PDSINST_REGS64_MASK)
|
||||
<< PVR_ROGUE_PDSINST_ADD64_SRC0_SHIFT);
|
||||
encoded |= ((sna & 1U) << PVR_ROGUE_PDSINST_ADD64_SNA_SHIFT);
|
||||
encoded |= ((alum & 1U) << PVR_ROGUE_PDSINST_ADD64_ALUM_SHIFT);
|
||||
encoded |= ((cc & 1U) << PVR_ROGUE_PDSINST_ADD64_CC_SHIFT);
|
||||
|
||||
PVR_PDS_PRINT_INST(encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t pvr_pds_inst_encode_add32(uint32_t cc,
|
||||
uint32_t alum,
|
||||
uint32_t sna,
|
||||
uint32_t src0,
|
||||
uint32_t src1,
|
||||
uint32_t dst)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODEC_ADD32
|
||||
<< PVR_ROGUE_PDSINST_ADD32_OPCODE_SHIFT;
|
||||
encoded |= ((dst & PVR_ROGUE_PDSINST_REGS32TP_MASK)
|
||||
<< PVR_ROGUE_PDSINST_ADD32_DST_SHIFT);
|
||||
encoded |= ((src1 & PVR_ROGUE_PDSINST_REGS32_MASK)
|
||||
<< PVR_ROGUE_PDSINST_ADD32_SRC1_SHIFT);
|
||||
encoded |= ((src0 & PVR_ROGUE_PDSINST_REGS32_MASK)
|
||||
<< PVR_ROGUE_PDSINST_ADD32_SRC0_SHIFT);
|
||||
encoded |= ((sna & 1U) << PVR_ROGUE_PDSINST_ADD32_SNA_SHIFT);
|
||||
encoded |= ((alum & 1U) << PVR_ROGUE_PDSINST_ADD32_ALUM_SHIFT);
|
||||
encoded |= ((cc & 1U) << PVR_ROGUE_PDSINST_ADD32_CC_SHIFT);
|
||||
|
||||
PVR_PDS_PRINT_INST(encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t pvr_pds_inst_encode_cmp(uint32_t cc,
|
||||
uint32_t cop,
|
||||
uint32_t src0,
|
||||
uint32_t src1)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODEC_CMP
|
||||
<< PVR_ROGUE_PDSINST_CMP_OPCODE_SHIFT;
|
||||
encoded |= ((src1 & PVR_ROGUE_PDSINST_REGS64_MASK)
|
||||
<< PVR_ROGUE_PDSINST_CMP_SRC1_SHIFT);
|
||||
encoded |= ((src0 & PVR_ROGUE_PDSINST_REGS64TP_MASK)
|
||||
<< PVR_ROGUE_PDSINST_CMP_SRC0_SHIFT);
|
||||
encoded |= UINT32_C(0x0) << PVR_ROGUE_PDSINST_CMP_IM_SHIFT;
|
||||
encoded |= UINT32_C(0x1) << PVR_ROGUE_PDSINST_CMP_SETCP_SHIFT;
|
||||
encoded |=
|
||||
((cop & PVR_ROGUE_PDSINST_COP_MASK) << PVR_ROGUE_PDSINST_CMP_COP_SHIFT);
|
||||
encoded |= ((cc & 1U) << PVR_ROGUE_PDSINST_CMP_CC_SHIFT);
|
||||
|
||||
PVR_PDS_PRINT_INST(encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t pvr_pds_inst_encode_cmpi(uint32_t cc,
|
||||
uint32_t cop,
|
||||
uint32_t src0,
|
||||
uint32_t im16)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODEC_CMP
|
||||
<< PVR_ROGUE_PDSINST_CMPI_OPCODE_SHIFT;
|
||||
encoded |= ((im16 & PVR_ROGUE_PDSINST_IMM16_MASK)
|
||||
<< PVR_ROGUE_PDSINST_CMPI_IM16_SHIFT);
|
||||
encoded |= ((src0 & PVR_ROGUE_PDSINST_REGS64TP_MASK)
|
||||
<< PVR_ROGUE_PDSINST_CMPI_SRC0_SHIFT);
|
||||
encoded |= UINT32_C(0x1) << PVR_ROGUE_PDSINST_CMPI_IM_SHIFT;
|
||||
encoded |= UINT32_C(0x1) << PVR_ROGUE_PDSINST_CMPI_SETCP_SHIFT;
|
||||
encoded |=
|
||||
((cop & PVR_ROGUE_PDSINST_COP_MASK) << PVR_ROGUE_PDSINST_CMPI_COP_SHIFT);
|
||||
encoded |= ((cc & 1U) << PVR_ROGUE_PDSINST_CMPI_CC_SHIFT);
|
||||
|
||||
PVR_PDS_PRINT_INST(encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t pvr_pds_inst_encode_bra(uint32_t srcc,
|
||||
uint32_t neg,
|
||||
uint32_t setc,
|
||||
uint32_t addr)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODEC_BRA
|
||||
<< PVR_ROGUE_PDSINST_BRA_OPCODE_SHIFT;
|
||||
encoded |= ((addr & PVR_ROGUE_PDSINST_BRAADDR_MASK)
|
||||
<< PVR_ROGUE_PDSINST_BRA_ADDR_SHIFT);
|
||||
encoded |= ((setc & PVR_ROGUE_PDSINST_PREDICATE_MASK)
|
||||
<< PVR_ROGUE_PDSINST_BRA_SETC_SHIFT);
|
||||
encoded |= ((neg & 1U) << PVR_ROGUE_PDSINST_BRA_NEG_SHIFT);
|
||||
encoded |= ((srcc & PVR_ROGUE_PDSINST_PREDICATE_MASK)
|
||||
<< PVR_ROGUE_PDSINST_BRA_SRCC_SHIFT);
|
||||
|
||||
PVR_PDS_PRINT_INST(encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t pvr_pds_inst_encode_ld(uint32_t cc, uint32_t src0)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODEC_SP << PVR_ROGUE_PDSINST_LD_OPCODE_SHIFT;
|
||||
encoded |= ((src0 & PVR_ROGUE_PDSINST_REGS64_MASK)
|
||||
<< PVR_ROGUE_PDSINST_LD_SRC0_SHIFT);
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODESP_LD << PVR_ROGUE_PDSINST_LD_OP_SHIFT;
|
||||
encoded |= ((cc & 1U) << PVR_ROGUE_PDSINST_LD_CC_SHIFT);
|
||||
|
||||
PVR_PDS_PRINT_INST(encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t pvr_pds_inst_encode_st(uint32_t cc, uint32_t src0)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODEC_SP << PVR_ROGUE_PDSINST_ST_OPCODE_SHIFT;
|
||||
encoded |= ((src0 & PVR_ROGUE_PDSINST_REGS64_MASK)
|
||||
<< PVR_ROGUE_PDSINST_ST_SRC0_SHIFT);
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODESP_ST << PVR_ROGUE_PDSINST_ST_OP_SHIFT;
|
||||
encoded |= ((cc & 1U) << PVR_ROGUE_PDSINST_ST_CC_SHIFT);
|
||||
|
||||
PVR_PDS_PRINT_INST(encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t pvr_pds_inst_encode_wdf(uint32_t cc)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODEC_SP
|
||||
<< PVR_ROGUE_PDSINST_WDF_OPCODE_SHIFT;
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODESP_WDF << PVR_ROGUE_PDSINST_WDF_OP_SHIFT;
|
||||
encoded |= ((cc & 1U) << PVR_ROGUE_PDSINST_WDF_CC_SHIFT);
|
||||
|
||||
PVR_PDS_PRINT_INST(encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t pvr_pds_inst_encode_limm(uint32_t cc,
|
||||
uint32_t src1,
|
||||
uint32_t src0,
|
||||
uint32_t gr)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODEC_SP
|
||||
<< PVR_ROGUE_PDSINST_LIMM_OPCODE_SHIFT;
|
||||
encoded |= ((gr & 1U) << PVR_ROGUE_PDSINST_LIMM_GR_SHIFT);
|
||||
encoded |= ((src0 & PVR_ROGUE_PDSINST_IMM16_MASK)
|
||||
<< PVR_ROGUE_PDSINST_LIMM_SRC0_SHIFT);
|
||||
encoded |= ((src1 & PVR_ROGUE_PDSINST_REGS32T_MASK)
|
||||
<< PVR_ROGUE_PDSINST_LIMM_SRC1_SHIFT);
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODESP_LIMM
|
||||
<< PVR_ROGUE_PDSINST_LIMM_OP_SHIFT;
|
||||
encoded |= ((cc & 1U) << PVR_ROGUE_PDSINST_LIMM_CC_SHIFT);
|
||||
|
||||
PVR_PDS_PRINT_INST(encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t pvr_pds_inst_encode_lock(uint32_t cc)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODEC_SP
|
||||
<< PVR_ROGUE_PDSINST_LOCK_OPCODE_SHIFT;
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODESP_LOCK
|
||||
<< PVR_ROGUE_PDSINST_LOCK_OP_SHIFT;
|
||||
encoded |= ((cc & 1U) << PVR_ROGUE_PDSINST_LOCK_CC_SHIFT);
|
||||
|
||||
PVR_PDS_PRINT_INST(encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t pvr_pds_inst_encode_release(uint32_t cc)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODEC_SP
|
||||
<< PVR_ROGUE_PDSINST_RELEASE_OPCODE_SHIFT;
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODESP_RELEASE
|
||||
<< PVR_ROGUE_PDSINST_RELEASE_OP_SHIFT;
|
||||
encoded |= ((cc & 1U) << PVR_ROGUE_PDSINST_RELEASE_CC_SHIFT);
|
||||
|
||||
PVR_PDS_PRINT_INST(encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t pvr_pds_inst_encode_halt(uint32_t cc)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODEC_SP
|
||||
<< PVR_ROGUE_PDSINST_HALT_OPCODE_SHIFT;
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODESP_HALT
|
||||
<< PVR_ROGUE_PDSINST_HALT_OP_SHIFT;
|
||||
encoded |= ((cc & 1U) << PVR_ROGUE_PDSINST_HALT_CC_SHIFT);
|
||||
|
||||
PVR_PDS_PRINT_INST(encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t pvr_pds_inst_encode_stmc(uint32_t cc,
|
||||
uint32_t so_mask)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODEC_SP
|
||||
<< PVR_ROGUE_PDSINST_STMC_OPCODE_SHIFT;
|
||||
encoded |= ((so_mask & PVR_ROGUE_PDSINST_SOMASK_MASK)
|
||||
<< PVR_ROGUE_PDSINST_STMC_SOMASK_SHIFT);
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODESP_STMC
|
||||
<< PVR_ROGUE_PDSINST_STMC_OP_SHIFT;
|
||||
encoded |= ((cc & 1U) << PVR_ROGUE_PDSINST_STMC_CC_SHIFT);
|
||||
|
||||
PVR_PDS_PRINT_INST(encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t
|
||||
pvr_rogue_pds_inst_decode_field_range_regs64c(uint32_t value)
|
||||
{
|
||||
if (value <= PVR_ROGUE_PDSINST_REGS64C_CONST64_UPPER)
|
||||
return PVR_ROGUE_PDSINST_REGS64C_CONST64;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t pvr_pds_inst_encode_ddmad(uint32_t cc,
|
||||
uint32_t end,
|
||||
uint32_t src0,
|
||||
uint32_t src1,
|
||||
uint32_t src2,
|
||||
uint32_t src3)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODEC_DDMAD
|
||||
<< PVR_ROGUE_PDSINST_DDMAD_OPCODE_SHIFT;
|
||||
encoded |= ((src3 & PVR_ROGUE_PDSINST_REGS64C_MASK)
|
||||
<< PVR_ROGUE_PDSINST_DDMAD_SRC3_SHIFT);
|
||||
encoded |= ((src2 & PVR_ROGUE_PDSINST_REGS64_MASK)
|
||||
<< PVR_ROGUE_PDSINST_DDMAD_SRC2_SHIFT);
|
||||
encoded |= ((src1 & PVR_ROGUE_PDSINST_REGS32T_MASK)
|
||||
<< PVR_ROGUE_PDSINST_DDMAD_SRC1_SHIFT);
|
||||
encoded |= ((src0 & PVR_ROGUE_PDSINST_REGS32_MASK)
|
||||
<< PVR_ROGUE_PDSINST_DDMAD_SRC0_SHIFT);
|
||||
encoded |= ((end & 1U) << PVR_ROGUE_PDSINST_DDMAD_END_SHIFT);
|
||||
encoded |= ((cc & 1U) << PVR_ROGUE_PDSINST_DDMAD_CC_SHIFT);
|
||||
|
||||
PVR_PDS_PRINT_INST(encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint32_t pvr_pds_inst_encode_dout(uint32_t cc,
|
||||
uint32_t end,
|
||||
uint32_t src1,
|
||||
uint32_t src0,
|
||||
uint32_t dst)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
encoded |= PVR_ROGUE_PDSINST_OPCODEC_DOUT
|
||||
<< PVR_ROGUE_PDSINST_DOUT_OPCODE_SHIFT;
|
||||
encoded |= ((dst & PVR_ROGUE_PDSINST_DSTDOUT_MASK)
|
||||
<< PVR_ROGUE_PDSINST_DOUT_DST_SHIFT);
|
||||
encoded |= ((src0 & PVR_ROGUE_PDSINST_REGS64_MASK)
|
||||
<< PVR_ROGUE_PDSINST_DOUT_SRC0_SHIFT);
|
||||
encoded |= ((src1 & PVR_ROGUE_PDSINST_REGS32_MASK)
|
||||
<< PVR_ROGUE_PDSINST_DOUT_SRC1_SHIFT);
|
||||
encoded |= ((end & 1U) << PVR_ROGUE_PDSINST_DOUT_END_SHIFT);
|
||||
encoded |= ((cc & 1U) << PVR_ROGUE_PDSINST_DOUT_CC_SHIFT);
|
||||
|
||||
PVR_PDS_PRINT_INST(encoded);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
#endif /* PVR_ROGUE_PDS_ENCODE_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include "pvr_csb.h"
|
||||
#include "pvr_private.h"
|
||||
#include "util/list.h"
|
||||
#include "vk_alloc.h"
|
||||
#include "vk_command_buffer.h"
|
||||
#include "vk_command_pool.h"
|
||||
#include "vk_log.h"
|
||||
|
||||
/* TODO: Investigate where this limit comes from. */
|
||||
#define PVR_MAX_TRANSFER_SIZE_IN_TEXELS 2048U
|
||||
|
||||
void pvr_CmdBlitImage2KHR(VkCommandBuffer commandBuffer,
|
||||
const VkBlitImageInfo2KHR *pBlitImageInfo)
|
||||
{
|
||||
assert(!"Unimplemented");
|
||||
}
|
||||
|
||||
void pvr_CmdCopyImageToBuffer2KHR(
|
||||
VkCommandBuffer commandBuffer,
|
||||
const VkCopyImageToBufferInfo2KHR *pCopyImageToBufferInfo)
|
||||
{
|
||||
assert(!"Unimplemented");
|
||||
}
|
||||
|
||||
void pvr_CmdCopyImage2KHR(VkCommandBuffer commandBuffer,
|
||||
const VkCopyImageInfo2KHR *pCopyImageInfo)
|
||||
{
|
||||
assert(!"Unimplemented");
|
||||
}
|
||||
|
||||
void pvr_CmdUpdateBuffer(VkCommandBuffer commandBuffer,
|
||||
VkBuffer dstBuffer,
|
||||
VkDeviceSize dstOffset,
|
||||
VkDeviceSize dataSize,
|
||||
const void *pData)
|
||||
{
|
||||
assert(!"Unimplemented");
|
||||
}
|
||||
|
||||
void pvr_CmdFillBuffer(VkCommandBuffer commandBuffer,
|
||||
VkBuffer dstBuffer,
|
||||
VkDeviceSize dstOffset,
|
||||
VkDeviceSize fillSize,
|
||||
uint32_t data)
|
||||
{
|
||||
assert(!"Unimplemented");
|
||||
}
|
||||
|
||||
void pvr_CmdCopyBufferToImage2KHR(
|
||||
VkCommandBuffer commandBuffer,
|
||||
const VkCopyBufferToImageInfo2KHR *pCopyBufferToImageInfo)
|
||||
{
|
||||
assert(!"Unimplemented");
|
||||
}
|
||||
|
||||
void pvr_CmdClearColorImage(VkCommandBuffer commandBuffer,
|
||||
VkImage _image,
|
||||
VkImageLayout imageLayout,
|
||||
const VkClearColorValue *pColor,
|
||||
uint32_t rangeCount,
|
||||
const VkImageSubresourceRange *pRanges)
|
||||
{
|
||||
assert(!"Unimplemented");
|
||||
}
|
||||
|
||||
void pvr_CmdClearDepthStencilImage(VkCommandBuffer commandBuffer,
|
||||
VkImage image_h,
|
||||
VkImageLayout imageLayout,
|
||||
const VkClearDepthStencilValue *pDepthStencil,
|
||||
uint32_t rangeCount,
|
||||
const VkImageSubresourceRange *pRanges)
|
||||
{
|
||||
assert(!"Unimplemented");
|
||||
}
|
||||
|
||||
void pvr_CmdCopyBuffer2KHR(VkCommandBuffer commandBuffer,
|
||||
const VkCopyBufferInfo2KHR *pCopyBufferInfo)
|
||||
{
|
||||
PVR_FROM_HANDLE(pvr_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
PVR_FROM_HANDLE(pvr_buffer, src, pCopyBufferInfo->srcBuffer);
|
||||
PVR_FROM_HANDLE(pvr_buffer, dst, pCopyBufferInfo->dstBuffer);
|
||||
const size_t regions_size =
|
||||
pCopyBufferInfo->regionCount * sizeof(*pCopyBufferInfo->pRegions);
|
||||
struct pvr_transfer_cmd *transfer_cmd;
|
||||
|
||||
PVR_CHECK_COMMAND_BUFFER_BUILDING_STATE(cmd_buffer);
|
||||
|
||||
transfer_cmd = vk_alloc(&cmd_buffer->vk.pool->alloc,
|
||||
sizeof(*transfer_cmd) + regions_size,
|
||||
8U,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (!transfer_cmd) {
|
||||
cmd_buffer->state.status =
|
||||
vk_error(cmd_buffer, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
transfer_cmd->src = src;
|
||||
transfer_cmd->dst = dst;
|
||||
transfer_cmd->region_count = pCopyBufferInfo->regionCount;
|
||||
memcpy(transfer_cmd->regions, pCopyBufferInfo->pRegions, regions_size);
|
||||
|
||||
pvr_cmd_buffer_add_transfer_cmd(cmd_buffer, transfer_cmd);
|
||||
}
|
||||
|
||||
void pvr_CmdClearAttachments(VkCommandBuffer commandBuffer,
|
||||
uint32_t attachmentCount,
|
||||
const VkClearAttachment *pAttachments,
|
||||
uint32_t rectCount,
|
||||
const VkClearRect *pRects)
|
||||
{
|
||||
assert(!"Unimplemented");
|
||||
}
|
||||
|
||||
void pvr_CmdResolveImage2KHR(VkCommandBuffer commandBuffer,
|
||||
const VkResolveImageInfo2KHR *pResolveImageInfo)
|
||||
{
|
||||
assert(!"Unimplemented");
|
||||
}
|
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include "pvr_bo.h"
|
||||
#include "pvr_private.h"
|
||||
#include "pvr_winsys.h"
|
||||
#include "vk_alloc.h"
|
||||
#include "vk_log.h"
|
||||
|
||||
static uint32_t pvr_bo_alloc_to_winsys_flags(uint64_t flags)
|
||||
{
|
||||
uint32_t ws_flags = 0;
|
||||
|
||||
if (flags & PVR_BO_ALLOC_FLAG_CPU_ACCESS)
|
||||
ws_flags |= PVR_WINSYS_BO_FLAG_CPU_ACCESS;
|
||||
|
||||
if (flags & PVR_BO_ALLOC_FLAG_GPU_UNCACHED)
|
||||
ws_flags |= PVR_WINSYS_BO_FLAG_GPU_UNCACHED;
|
||||
|
||||
if (flags & PVR_BO_ALLOC_FLAG_PM_FW_PROTECT)
|
||||
ws_flags |= PVR_WINSYS_BO_FLAG_PM_FW_PROTECT;
|
||||
|
||||
if (flags & PVR_BO_ALLOC_FLAG_ZERO_ON_ALLOC)
|
||||
ws_flags |= PVR_WINSYS_BO_FLAG_ZERO_ON_ALLOC;
|
||||
|
||||
return ws_flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Helper interface to allocate a GPU buffer and map it to both host and
|
||||
* device virtual memory. Host mapping is conditional and is controlled by
|
||||
* flags.
|
||||
*
|
||||
* \param[in] device Logical device pointer.
|
||||
* \param[in] heap Heap to allocate device virtual address from.
|
||||
* \param[in] size Size of buffer to allocate.
|
||||
* \param[in] alignment Required alignment of the allocation. Must be a power
|
||||
* of two.
|
||||
* \param[in] flags Controls allocation, CPU and GPU mapping behavior
|
||||
* using PVR_BO_ALLOC_FLAG_*.
|
||||
* \param[out] pvr_bo_out On success output buffer is returned in this pointer.
|
||||
* \return VK_SUCCESS on success, or error code otherwise.
|
||||
*
|
||||
* \sa #pvr_bo_free()
|
||||
*/
|
||||
VkResult pvr_bo_alloc(struct pvr_device *device,
|
||||
struct pvr_winsys_heap *heap,
|
||||
uint64_t size,
|
||||
uint64_t alignment,
|
||||
uint64_t flags,
|
||||
struct pvr_bo **const pvr_bo_out)
|
||||
{
|
||||
const uint32_t ws_flags = pvr_bo_alloc_to_winsys_flags(flags);
|
||||
struct pvr_bo *pvr_bo;
|
||||
pvr_dev_addr_t addr;
|
||||
VkResult result;
|
||||
|
||||
pvr_bo = vk_alloc(&device->vk.alloc,
|
||||
sizeof(*pvr_bo),
|
||||
8,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (!pvr_bo)
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
result = device->ws->ops->buffer_create(device->ws,
|
||||
size,
|
||||
alignment,
|
||||
PVR_WINSYS_BO_TYPE_GPU,
|
||||
ws_flags,
|
||||
&pvr_bo->bo);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_vk_free;
|
||||
|
||||
if (flags & PVR_BO_ALLOC_FLAG_CPU_MAPPED) {
|
||||
void *map = device->ws->ops->buffer_map(pvr_bo->bo);
|
||||
if (!map) {
|
||||
result = VK_ERROR_MEMORY_MAP_FAILED;
|
||||
goto err_buffer_destroy;
|
||||
}
|
||||
}
|
||||
|
||||
pvr_bo->vma = device->ws->ops->heap_alloc(heap, size, alignment);
|
||||
if (!pvr_bo->vma) {
|
||||
result = VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
||||
goto err_buffer_unmap;
|
||||
}
|
||||
|
||||
addr = device->ws->ops->vma_map(pvr_bo->vma, pvr_bo->bo, 0, size);
|
||||
if (!addr.addr) {
|
||||
result = VK_ERROR_MEMORY_MAP_FAILED;
|
||||
goto err_heap_free;
|
||||
}
|
||||
|
||||
*pvr_bo_out = pvr_bo;
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
err_heap_free:
|
||||
device->ws->ops->heap_free(pvr_bo->vma);
|
||||
|
||||
err_buffer_unmap:
|
||||
if (flags & PVR_BO_ALLOC_FLAG_CPU_MAPPED)
|
||||
device->ws->ops->buffer_unmap(pvr_bo->bo);
|
||||
|
||||
err_buffer_destroy:
|
||||
device->ws->ops->buffer_destroy(pvr_bo->bo);
|
||||
|
||||
err_vk_free:
|
||||
vk_free(&device->vk.alloc, pvr_bo);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Interface to map the buffer into host virtual address space.
|
||||
*
|
||||
* Buffer should have been created with the #PVR_BO_ALLOC_FLAG_CPU_ACCESS
|
||||
* flag. It should also not already be mapped or it should have been unmapped
|
||||
* using #pvr_bo_cpu_unmap() before mapping again.
|
||||
*
|
||||
* \param[in] device Logical device pointer.
|
||||
* \param[in] pvr_bo Buffer to map.
|
||||
* \return Valid host virtual address on success, or NULL otherwise.
|
||||
*
|
||||
* \sa #pvr_bo_alloc(), #PVR_BO_ALLOC_FLAG_CPU_MAPPED
|
||||
*/
|
||||
void *pvr_bo_cpu_map(struct pvr_device *device, struct pvr_bo *pvr_bo)
|
||||
{
|
||||
assert(!pvr_bo->bo->map);
|
||||
|
||||
return device->ws->ops->buffer_map(pvr_bo->bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Interface to unmap the buffer from host virtual address space.
|
||||
*
|
||||
* Buffer should have a valid mapping, created either using #pvr_bo_cpu_map() or
|
||||
* by passing #PVR_BO_ALLOC_FLAG_CPU_MAPPED flag to #pvr_bo_alloc() at
|
||||
* allocation time.
|
||||
*
|
||||
* Buffer can be remapped using #pvr_bo_cpu_map().
|
||||
*
|
||||
* \param[in] device Logical device pointer.
|
||||
* \param[in] pvr_bo Buffer to unmap.
|
||||
*/
|
||||
void pvr_bo_cpu_unmap(struct pvr_device *device, struct pvr_bo *pvr_bo)
|
||||
{
|
||||
assert(pvr_bo->bo->map);
|
||||
device->ws->ops->buffer_unmap(pvr_bo->bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Interface to free the buffer object.
|
||||
*
|
||||
* \param[in] device Logical device pointer.
|
||||
* \param[in] pvr_bo Buffer to free.
|
||||
*
|
||||
* \sa #pvr_bo_alloc()
|
||||
*/
|
||||
void pvr_bo_free(struct pvr_device *device, struct pvr_bo *pvr_bo)
|
||||
{
|
||||
if (!pvr_bo)
|
||||
return;
|
||||
|
||||
device->ws->ops->vma_unmap(pvr_bo->vma);
|
||||
device->ws->ops->heap_free(pvr_bo->vma);
|
||||
|
||||
if (pvr_bo->bo->map)
|
||||
device->ws->ops->buffer_unmap(pvr_bo->bo);
|
||||
|
||||
device->ws->ops->buffer_destroy(pvr_bo->bo);
|
||||
|
||||
vk_free(&device->vk.alloc, pvr_bo);
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* 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_BO_H
|
||||
#define PVR_BO_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include "util/list.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
struct pvr_device;
|
||||
struct pvr_winsys_bo;
|
||||
struct pvr_winsys_vma;
|
||||
struct pvr_winsys_heap;
|
||||
|
||||
struct pvr_bo {
|
||||
/* Since multiple components (csb, caching logic, etc) can make use of
|
||||
* linking buffers in a list, we add 'link' in pvr_bo to avoid an extra
|
||||
* level of structure inheritance. It's the responsibility of the buffer
|
||||
* user to manage the list and remove the buffer from the list before
|
||||
* freeing it.
|
||||
*/
|
||||
struct list_head link;
|
||||
|
||||
struct pvr_winsys_bo *bo;
|
||||
struct pvr_winsys_vma *vma;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Flag passed to #pvr_bo_alloc() to indicate that the buffer should be
|
||||
* CPU accessible. This is required in order to map a buffer with
|
||||
* #pvr_bo_cpu_map().
|
||||
*/
|
||||
#define PVR_BO_ALLOC_FLAG_CPU_ACCESS BITFIELD_BIT(0U)
|
||||
/**
|
||||
* \brief Flag passed to #pvr_bo_alloc() to indicate that the buffer should
|
||||
* be mapped to the CPU. Implies #PVR_BO_ALLOC_FLAG_CPU_ACCESS.
|
||||
*/
|
||||
#define PVR_BO_ALLOC_FLAG_CPU_MAPPED \
|
||||
(BITFIELD_BIT(1U) | PVR_BO_ALLOC_FLAG_CPU_ACCESS)
|
||||
/**
|
||||
* \brief Flag passed to #pvr_bo_alloc() to indicate that the buffer should be
|
||||
* mapped to the GPU as uncached.
|
||||
*/
|
||||
#define PVR_BO_ALLOC_FLAG_GPU_UNCACHED BITFIELD_BIT(2U)
|
||||
/**
|
||||
* \brief Flag passed to #pvr_bo_alloc() to indicate that the buffer GPU mapping
|
||||
* should be restricted to only allow access to the Parameter Manager unit and
|
||||
* firmware processor.
|
||||
*/
|
||||
#define PVR_BO_ALLOC_FLAG_PM_FW_PROTECT BITFIELD_BIT(3U)
|
||||
/**
|
||||
* \brief Flag passed to #pvr_bo_alloc() to indicate that the buffer should be
|
||||
* zeroed at allocation time.
|
||||
*/
|
||||
#define PVR_BO_ALLOC_FLAG_ZERO_ON_ALLOC BITFIELD_BIT(4U)
|
||||
|
||||
VkResult pvr_bo_alloc(struct pvr_device *device,
|
||||
struct pvr_winsys_heap *heap,
|
||||
uint64_t size,
|
||||
uint64_t alignment,
|
||||
uint64_t flags,
|
||||
struct pvr_bo **const bo_out);
|
||||
void *pvr_bo_cpu_map(struct pvr_device *device, struct pvr_bo *bo);
|
||||
void pvr_bo_cpu_unmap(struct pvr_device *device, struct pvr_bo *bo);
|
||||
void pvr_bo_free(struct pvr_device *device, struct pvr_bo *bo);
|
||||
|
||||
#endif /* PVR_BO_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,281 @@
|
|||
/*
|
||||
* Copyright © 2022 Imagination Technologies Ltd.
|
||||
*
|
||||
* based in part on anv driver which is:
|
||||
* Copyright © 2015 Intel Corporation
|
||||
*
|
||||
* based in part on v3dv_cl.c which is:
|
||||
* Copyright © 2019 Raspberry Pi
|
||||
*
|
||||
* 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 <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include "hwdef/rogue_hw_utils.h"
|
||||
#include "pvr_bo.h"
|
||||
#include "pvr_csb.h"
|
||||
#include "pvr_device_info.h"
|
||||
#include "pvr_private.h"
|
||||
#include "vk_log.h"
|
||||
|
||||
/**
|
||||
* \file pvr_csb.c
|
||||
*
|
||||
* \brief Contains functions to manage Control Stream Builder (csb) object.
|
||||
*
|
||||
* A csb object can be used to create a primary/main control stream, referred
|
||||
* as control stream hereafter, or a secondary control stream, also referred as
|
||||
* a sub control stream. The main difference between these is that, the control
|
||||
* stream is the one directly submitted to the GPU and is terminated using
|
||||
* STREAM_TERMINATE. Whereas, the secondary control stream can be thought of as
|
||||
* an independent set of commands that can be referenced by a primary control
|
||||
* stream to avoid duplication and is instead terminated using STREAM_RETURN,
|
||||
* which means the control stream parser should return to the main stream it
|
||||
* came from.
|
||||
*
|
||||
* Note: Sub control stream is only supported for PVR_CMD_STREAM_TYPE_GRAPHICS
|
||||
* type control streams.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Size of the individual csb buffer object.
|
||||
*/
|
||||
#define PVR_CMD_BUFFER_CSB_BO_SIZE 4096
|
||||
|
||||
/**
|
||||
* \brief Initializes the csb object.
|
||||
*
|
||||
* \param[in] device Logical device pointer.
|
||||
* \param[in] csb Control Stream Builder object to initialize.
|
||||
*
|
||||
* \sa #pvr_csb_finish()
|
||||
*/
|
||||
void pvr_csb_init(struct pvr_device *device,
|
||||
enum pvr_cmd_stream_type stream_type,
|
||||
struct pvr_csb *csb)
|
||||
{
|
||||
csb->start = NULL;
|
||||
csb->next = NULL;
|
||||
csb->pvr_bo = NULL;
|
||||
csb->end = NULL;
|
||||
csb->device = device;
|
||||
csb->stream_type = stream_type;
|
||||
csb->status = VK_SUCCESS;
|
||||
list_inithead(&csb->pvr_bo_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Frees the resources associated with the csb object.
|
||||
*
|
||||
* \param[in] csb Control Stream Builder object to free.
|
||||
*
|
||||
* \sa #pvr_csb_init()
|
||||
*/
|
||||
void pvr_csb_finish(struct pvr_csb *csb)
|
||||
{
|
||||
list_for_each_entry_safe (struct pvr_bo, pvr_bo, &csb->pvr_bo_list, link) {
|
||||
list_del(&pvr_bo->link);
|
||||
pvr_bo_free(csb->device, pvr_bo);
|
||||
}
|
||||
|
||||
/* Leave the csb in a reset state to catch use after destroy instances */
|
||||
pvr_csb_init(NULL, PVR_CMD_STREAM_TYPE_INVALID, csb);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Helper function to extend csb memory.
|
||||
*
|
||||
* Allocates a new buffer object and links it with the previous buffer object
|
||||
* using STREAM_LINK dwords and updates csb object to use the new buffer.
|
||||
*
|
||||
* To make sure that we have enough space to emit STREAM_LINK dwords in the
|
||||
* current buffer, a few bytes are reserved at the end, every time a buffer is
|
||||
* created. Every time we allocate a new buffer we fix the current buffer in use
|
||||
* to emit the stream link dwords. This makes sure that when
|
||||
* #pvr_csb_alloc_dwords() is called from #pvr_csb_emit() to add STREAM_LINK0
|
||||
* and STREAM_LINK1, it succeeds without trying to allocate new pages.
|
||||
*
|
||||
* \param[in] csb Control Stream Builder object to extend.
|
||||
* \return true on success and false otherwise.
|
||||
*/
|
||||
static bool pvr_csb_buffer_extend(struct pvr_csb *csb)
|
||||
{
|
||||
const uint8_t stream_link_space = (pvr_cmd_length(VDMCTRL_STREAM_LINK0) +
|
||||
pvr_cmd_length(VDMCTRL_STREAM_LINK1)) *
|
||||
4;
|
||||
const uint32_t cache_line_size =
|
||||
rogue_get_slc_cache_line_size(&csb->device->pdevice->dev_info);
|
||||
struct pvr_bo *pvr_bo;
|
||||
VkResult result;
|
||||
|
||||
/* Make sure extra space allocated for stream links is sufficient for both
|
||||
* stream types.
|
||||
*/
|
||||
STATIC_ASSERT((pvr_cmd_length(VDMCTRL_STREAM_LINK0) +
|
||||
pvr_cmd_length(VDMCTRL_STREAM_LINK1)) ==
|
||||
(pvr_cmd_length(CDMCTRL_STREAM_LINK0) +
|
||||
pvr_cmd_length(CDMCTRL_STREAM_LINK1)));
|
||||
|
||||
result = pvr_bo_alloc(csb->device,
|
||||
csb->device->heaps.general_heap,
|
||||
PVR_CMD_BUFFER_CSB_BO_SIZE,
|
||||
cache_line_size,
|
||||
PVR_BO_ALLOC_FLAG_CPU_MAPPED,
|
||||
&pvr_bo);
|
||||
if (result != VK_SUCCESS) {
|
||||
vk_error(csb->device, result);
|
||||
csb->status = result;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Chain to the old BO if this is not the first BO in csb */
|
||||
if (csb->pvr_bo) {
|
||||
csb->end += stream_link_space;
|
||||
assert(csb->next + stream_link_space <= csb->end);
|
||||
|
||||
switch (csb->stream_type) {
|
||||
case PVR_CMD_STREAM_TYPE_GRAPHICS:
|
||||
pvr_csb_emit (csb, VDMCTRL_STREAM_LINK0, link) {
|
||||
link.link_addrmsb = pvr_bo->vma->dev_addr;
|
||||
}
|
||||
|
||||
pvr_csb_emit (csb, VDMCTRL_STREAM_LINK1, link) {
|
||||
link.link_addrlsb = pvr_bo->vma->dev_addr;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PVR_CMD_STREAM_TYPE_COMPUTE:
|
||||
pvr_csb_emit (csb, CDMCTRL_STREAM_LINK0, link) {
|
||||
link.link_addrmsb = pvr_bo->vma->dev_addr;
|
||||
}
|
||||
|
||||
pvr_csb_emit (csb, CDMCTRL_STREAM_LINK1, link) {
|
||||
link.link_addrlsb = pvr_bo->vma->dev_addr;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
unreachable("Unknown stream type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
csb->pvr_bo = pvr_bo;
|
||||
csb->start = pvr_bo->bo->map;
|
||||
|
||||
/* Reserve stream link size at the end to make sure we don't run out of
|
||||
* space when a stream link is required.
|
||||
*/
|
||||
csb->end = csb->start + pvr_bo->bo->size - stream_link_space;
|
||||
csb->next = csb->start;
|
||||
|
||||
list_addtail(&pvr_bo->link, &csb->pvr_bo_list);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Provides a chunk of memory from the current csb buffer. In cases where
|
||||
* the buffer is not able to fulfill the required amount of memory,
|
||||
* #pvr_csb_buffer_extend() is called to allocate a new buffer. Maximum size
|
||||
* allocable in bytes is #PVR_CMD_BUFFER_CSB_BO_SIZE - size of STREAM_LINK0
|
||||
* and STREAM_LINK1 dwords.
|
||||
*
|
||||
* \param[in] csb Control Stream Builder object to allocate from.
|
||||
* \param[in] num_dwords Number of dwords to allocate.
|
||||
* \return Valid host virtual address or NULL otherwise.
|
||||
*/
|
||||
void *pvr_csb_alloc_dwords(struct pvr_csb *csb, uint32_t num_dwords)
|
||||
{
|
||||
const uint32_t required_space = num_dwords * 4;
|
||||
|
||||
if (csb->status != VK_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
if (csb->next + required_space > csb->end) {
|
||||
bool ret = pvr_csb_buffer_extend(csb);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *p = csb->next;
|
||||
|
||||
csb->next += required_space;
|
||||
assert(csb->next <= csb->end);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Adds VDMCTRL_STREAM_RETURN dword into the control stream pointed by
|
||||
* csb object. Given a VDMCTRL_STREAM_RETURN marks the end of the sub control
|
||||
* stream, we return the status of the control stream as well.
|
||||
*
|
||||
* \param[in] csb Control Stream Builder object to add VDMCTRL_STREAM_RETURN to.
|
||||
* \return VK_SUCCESS on success, or error code otherwise.
|
||||
*/
|
||||
VkResult pvr_csb_emit_return(struct pvr_csb *csb)
|
||||
{
|
||||
/* STREAM_RETURN is only supported by graphics control stream. */
|
||||
assert(csb->stream_type == PVR_CMD_STREAM_TYPE_GRAPHICS);
|
||||
|
||||
/* clang-format off */
|
||||
pvr_csb_emit(csb, VDMCTRL_STREAM_RETURN, ret);
|
||||
/* clang-format on */
|
||||
|
||||
return csb->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Adds STREAM_TERMINATE dword into the control stream pointed by csb
|
||||
* object. Given a STREAM_TERMINATE marks the end of the control stream, we
|
||||
* return the status of the control stream as well.
|
||||
*
|
||||
* \param[in] csb Control Stream Builder object to terminate.
|
||||
* \return VK_SUCCESS on success, or error code otherwise.
|
||||
*/
|
||||
VkResult pvr_csb_emit_terminate(struct pvr_csb *csb)
|
||||
{
|
||||
switch (csb->stream_type) {
|
||||
case PVR_CMD_STREAM_TYPE_GRAPHICS:
|
||||
/* clang-format off */
|
||||
pvr_csb_emit(csb, VDMCTRL_STREAM_TERMINATE, terminate);
|
||||
/* clang-format on */
|
||||
break;
|
||||
|
||||
case PVR_CMD_STREAM_TYPE_COMPUTE:
|
||||
/* clang-format off */
|
||||
pvr_csb_emit(csb, CDMCTRL_STREAM_TERMINATE, terminate);
|
||||
/* clang-format on */
|
||||
break;
|
||||
|
||||
default:
|
||||
unreachable("Unknown stream type");
|
||||
break;
|
||||
}
|
||||
|
||||
return csb->status;
|
||||
}
|
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
* Copyright © 2022 Imagination Technologies Ltd.
|
||||
*
|
||||
* based in part on anv driver which is:
|
||||
* Copyright © 2015 Intel Corporation
|
||||
*
|
||||
* based in part on v3dv_cl.h which is:
|
||||
* Copyright © 2019 Raspberry Pi
|
||||
*
|
||||
* 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_CSB_H
|
||||
#define PVR_CSB_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include "pvr_bo.h"
|
||||
#include "pvr_winsys.h"
|
||||
#include "util/list.h"
|
||||
|
||||
#define __pvr_address_type pvr_dev_addr_t
|
||||
#define __pvr_get_address(pvr_dev_addr) (pvr_dev_addr).addr
|
||||
|
||||
#include "csbgen/rogue_hwdefs.h"
|
||||
|
||||
struct pvr_device;
|
||||
|
||||
enum pvr_cmd_stream_type {
|
||||
PVR_CMD_STREAM_TYPE_INVALID = 0, /* explicitly treat 0 as invalid */
|
||||
PVR_CMD_STREAM_TYPE_GRAPHICS,
|
||||
PVR_CMD_STREAM_TYPE_COMPUTE,
|
||||
};
|
||||
|
||||
struct pvr_csb {
|
||||
struct pvr_device *device;
|
||||
|
||||
/* Pointer to current csb buffer object */
|
||||
struct pvr_bo *pvr_bo;
|
||||
|
||||
/* pointers to current bo memory */
|
||||
void *start;
|
||||
void *end;
|
||||
void *next;
|
||||
|
||||
/* List of csb buffer objects */
|
||||
struct list_head pvr_bo_list;
|
||||
|
||||
enum pvr_cmd_stream_type stream_type;
|
||||
|
||||
/* Current error status of the command buffer. Used to track inconsistent
|
||||
* or incomplete command buffer states that are the consequence of run-time
|
||||
* errors such as out of memory scenarios. We want to track this in the
|
||||
* csb because the command buffer object is not visible to some parts
|
||||
* of the driver.
|
||||
*/
|
||||
VkResult status;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Gets the status of the csb.
|
||||
*
|
||||
* \param[in] csb Control Stream Builder object.
|
||||
* \return VK_SUCCESS if the csb hasn't encountered any error or error code
|
||||
* otherwise.
|
||||
*/
|
||||
static inline VkResult pvr_csb_get_status(struct pvr_csb *csb)
|
||||
{
|
||||
return csb->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Checks if the control stream is empty or not.
|
||||
*
|
||||
* \param[in] csb Control Stream Builder object.
|
||||
* \return true if csb is empty false otherwise.
|
||||
*/
|
||||
static inline bool pvr_csb_is_empty(struct pvr_csb *csb)
|
||||
{
|
||||
return list_is_empty(&csb->pvr_bo_list);
|
||||
}
|
||||
|
||||
static inline pvr_dev_addr_t pvr_csb_get_start_address(struct pvr_csb *csb)
|
||||
{
|
||||
if (!pvr_csb_is_empty(csb)) {
|
||||
struct pvr_bo *pvr_bo =
|
||||
list_first_entry(&csb->pvr_bo_list, struct pvr_bo, link);
|
||||
|
||||
return pvr_bo->vma->dev_addr;
|
||||
}
|
||||
|
||||
return PVR_DEV_ADDR_INVALID;
|
||||
}
|
||||
|
||||
void pvr_csb_init(struct pvr_device *device,
|
||||
enum pvr_cmd_stream_type stream_type,
|
||||
struct pvr_csb *csb);
|
||||
void pvr_csb_finish(struct pvr_csb *csb);
|
||||
void *pvr_csb_alloc_dwords(struct pvr_csb *csb, uint32_t num_dwords);
|
||||
VkResult pvr_csb_emit_return(struct pvr_csb *csb);
|
||||
VkResult pvr_csb_emit_terminate(struct pvr_csb *csb);
|
||||
|
||||
#define PVRX(x) ROGUE_##x
|
||||
#define pvr_cmd_struct(x) PVRX(x)
|
||||
#define pvr_cmd_length(x) PVRX(x##_length)
|
||||
#define pvr_cmd_header(x) PVRX(x##_header)
|
||||
#define pvr_cmd_pack(x) PVRX(x##_pack)
|
||||
|
||||
/**
|
||||
* \brief Packs a command/state into one or more dwords and stores them in the
|
||||
* memory pointed to by _dst.
|
||||
*
|
||||
* \param[out] _dst Pointer to store the packed command/state.
|
||||
* \param[in] cmd Command/state type.
|
||||
* \param[in,out] name Name to give to the command/state structure variable,
|
||||
* which contains the information to be packed and emitted.
|
||||
* This can be used by the caller to modify the command or
|
||||
* state information before it's packed.
|
||||
*/
|
||||
#define pvr_csb_pack(_dst, cmd, name) \
|
||||
for (struct pvr_cmd_struct(cmd) name = { pvr_cmd_header(cmd) }, \
|
||||
*_loop_terminate = &name; \
|
||||
__builtin_expect(_loop_terminate != NULL, 1); \
|
||||
({ \
|
||||
pvr_cmd_pack(cmd)((_dst), &name); \
|
||||
_loop_terminate = NULL; \
|
||||
}))
|
||||
|
||||
/**
|
||||
* \brief Merges dwords0 and dwords1 arrays and stores the result into the
|
||||
* control stream pointed by the csb object.
|
||||
*
|
||||
* \param[in] csb Control Stream Builder object.
|
||||
* \param[in] dwords0 Dwords0 array.
|
||||
* \param[in] dwords1 Dwords1 array.
|
||||
*/
|
||||
#define pvr_csb_emit_merge(csb, dwords0, dwords1) \
|
||||
do { \
|
||||
uint32_t *dw; \
|
||||
STATIC_ASSERT(ARRAY_SIZE(dwords0) == ARRAY_SIZE(dwords1)); \
|
||||
dw = pvr_csb_alloc_dwords(csb, ARRAY_SIZE(dwords0)); \
|
||||
if (!dw) \
|
||||
break; \
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(dwords0); i++) \
|
||||
dw[i] = (dwords0)[i] | (dwords1)[i]; \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* \brief Packs a command/state into one or more dwords and stores them into
|
||||
* the control stream pointed by the csb object.
|
||||
*
|
||||
* \param[in] csb Control Stream Builder object.
|
||||
* \param[in] cmd Command/state type.
|
||||
* \param[in,out] name Name to give to the command/state structure variable,
|
||||
* which contains the information to be packed. This can be
|
||||
* used by the caller to modify the command or state
|
||||
* information before it's packed.
|
||||
*/
|
||||
#define pvr_csb_emit(csb, cmd, name) \
|
||||
for (struct pvr_cmd_struct(cmd) \
|
||||
name = { pvr_cmd_header(cmd) }, \
|
||||
*_dst = pvr_csb_alloc_dwords(csb, pvr_cmd_length(cmd)); \
|
||||
__builtin_expect(_dst != NULL, 1); \
|
||||
({ \
|
||||
pvr_cmd_pack(cmd)(_dst, &name); \
|
||||
_dst = NULL; \
|
||||
}))
|
||||
|
||||
/**
|
||||
* \brief Stores dword into the control stream pointed by the csb object.
|
||||
*
|
||||
* \param[in] csb Control Stream Builder object.
|
||||
* \param[in] dword Dword to store into control stream.
|
||||
*/
|
||||
#define pvr_csb_emit_dword(csb, dword) \
|
||||
do { \
|
||||
uint32_t *dw; \
|
||||
STATIC_ASSERT(sizeof(dword) == sizeof(uint32_t)); \
|
||||
dw = pvr_csb_alloc_dwords(csb, 1U); \
|
||||
if (!dw) \
|
||||
break; \
|
||||
*dw = dword; \
|
||||
} while (0)
|
||||
|
||||
#endif /* PVR_CSB_H */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue