├── .clang-format
├── .gitlab-ci.yml
├── .pre-commit-config.yaml
├── CMakeLists.txt
├── DCO.txt
├── LICENSE
├── README.md
├── check_copyright.py
├── docs
└── guidelines.md
├── layer
├── VkLayer_window_system_integration.json
├── layer.cpp
├── present_timing.cpp
├── private_data.cpp
├── private_data.hpp
├── surface_api.cpp
├── surface_api.hpp
├── swapchain_api.cpp
├── swapchain_api.hpp
├── swapchain_maintenance_api.cpp
├── swapchain_maintenance_api.hpp
└── wsi_layer_experimental.hpp
├── util
├── custom_allocator.cpp
├── custom_allocator.hpp
├── drm
│ ├── drm_utils.cpp
│ ├── drm_utils.hpp
│ ├── format_table.c
│ └── format_table.h
├── extension_list.cpp
├── extension_list.hpp
├── file_descriptor.hpp
├── format_modifiers.cpp
├── format_modifiers.hpp
├── helpers.hpp
├── log.cpp
├── log.hpp
├── macros.hpp
├── platform_set.hpp
├── ring_buffer.hpp
├── timed_semaphore.cpp
├── timed_semaphore.hpp
├── unordered_map.hpp
├── unordered_set.hpp
└── wsialloc
│ ├── wsialloc.h
│ └── wsialloc_ion.c
└── wsi
├── README.md
├── compatible_present_modes.hpp
├── display
├── drm_display.cpp
├── drm_display.hpp
├── surface.cpp
├── surface.hpp
├── surface_properties.cpp
├── surface_properties.hpp
├── swapchain.cpp
└── swapchain.hpp
├── external_memory.cpp
├── external_memory.hpp
├── frame_boundary.cpp
├── frame_boundary.hpp
├── headless
├── surface.cpp
├── surface.hpp
├── surface_properties.cpp
├── surface_properties.hpp
├── swapchain.cpp
└── swapchain.hpp
├── surface.hpp
├── surface_properties.cpp
├── surface_properties.hpp
├── swapchain_base.cpp
├── swapchain_base.hpp
├── synchronization.cpp
├── synchronization.hpp
├── wayland
├── surface.cpp
├── surface.hpp
├── surface_properties.cpp
├── surface_properties.hpp
├── swapchain.cpp
├── swapchain.hpp
├── wl_helpers.cpp
├── wl_helpers.hpp
└── wl_object_owner.hpp
├── wsi_factory.cpp
├── wsi_factory.hpp
└── x11
├── surface.cpp
├── surface.hpp
├── surface_properties.cpp
├── surface_properties.hpp
├── swapchain.cpp
└── swapchain.hpp
/.clang-format:
--------------------------------------------------------------------------------
1 | # The style used for all options not specifically set in the configuration.
2 | BasedOnStyle: LLVM
3 |
4 | # The extra indent or outdent of access modifiers, e.g. public:.
5 | AccessModifierOffset: -3
6 |
7 | # If true, aligns escaped newlines as far left as possible. Otherwise puts them into the right-most column.
8 | AlignEscapedNewlinesLeft: true
9 |
10 | # If true, aligns trailing comments.
11 | AlignTrailingComments: true
12 |
13 | # Allow putting all parameters of a function declaration onto the next line even if BinPackParameters is false.
14 | AllowAllParametersOfDeclarationOnNextLine: false
15 |
16 | # Allows contracting simple braced statements to a single line.
17 | AllowShortBlocksOnASingleLine: false
18 |
19 | # If true, short case labels will be contracted to a single line.
20 | AllowShortCaseLabelsOnASingleLine: false
21 |
22 | # Dependent on the value, int f() { return 0; } can be put on a single line. Possible values: None, Inline, All.
23 | AllowShortFunctionsOnASingleLine: None
24 |
25 | # If true, if (a) return; can be put on a single line.
26 | AllowShortIfStatementsOnASingleLine: false
27 |
28 | # If true, while (true) continue; can be put on a single line.
29 | AllowShortLoopsOnASingleLine: false
30 |
31 | # If true, always break after function definition return types.
32 | AlwaysBreakAfterDefinitionReturnType: false
33 |
34 | # If true, always break before multiline string literals.
35 | AlwaysBreakBeforeMultilineStrings: false
36 |
37 | # If true, always break after the template<...> of a template declaration.
38 | AlwaysBreakTemplateDeclarations: true
39 |
40 | # If false, a function call's arguments will either be all on the same line or will have one line each.
41 | BinPackArguments: true
42 |
43 | # If false, a function declaration's or function definition's parameters will either all be on the same line
44 | # or will have one line each.
45 | BinPackParameters: true
46 |
47 | # The way to wrap binary operators. Possible values: None, NonAssignment, All.
48 | BreakBeforeBinaryOperators: None
49 |
50 | # The brace breaking style to use. Possible values: Attach, Linux, Stroustrup, Allman, GNU.
51 | BreakBeforeBraces: Custom
52 | # Like Allman but do not indent extern blocks
53 | BraceWrapping:
54 | AfterExternBlock: 'false'
55 | AfterCaseLabel: 'true'
56 | AfterClass: 'true'
57 | AfterEnum: 'true'
58 | AfterFunction: 'true'
59 | AfterNamespace: 'true'
60 | AfterObjCDeclaration: 'true'
61 | AfterStruct: 'true'
62 | AfterUnion: 'true'
63 | BeforeCatch: 'true'
64 | BeforeElse: 'true'
65 | AfterControlStatement: 'Always'
66 |
67 | # If true, ternary operators will be placed after line breaks.
68 | BreakBeforeTernaryOperators: false
69 |
70 | # Always break constructor initializers before commas and align the commas with the colon.
71 | BreakConstructorInitializersBeforeComma: true
72 |
73 | # The column limit. A column limit of 0 means that there is no column limit.
74 | ColumnLimit: 120
75 |
76 | # A regular expression that describes comments with special meaning, which should not be split into lines or otherwise changed.
77 | CommentPragmas: '^ *'
78 |
79 | # If the constructor initializers don't fit on a line, put each initializer on its own line.
80 | ConstructorInitializerAllOnOneLineOrOnePerLine: false
81 |
82 | # The number of characters to use for indentation of constructor initializer lists.
83 | ConstructorInitializerIndentWidth: 3
84 |
85 | # Indent width for line continuations.
86 | ContinuationIndentWidth: 3
87 |
88 | # If true, format braced lists as best suited for C++11 braced lists.
89 | Cpp11BracedListStyle: false
90 |
91 | # Disables formatting at all.
92 | DisableFormat: false
93 |
94 | # A vector of macros that should be interpreted as foreach loops instead of as function calls.
95 | ForEachMacros: ['']
96 |
97 | # Indent case labels one level from the switch statement.
98 | # When false, use the same indentation level as for the switch statement.
99 | # Switch statement body is always indented one level more than case labels.
100 | IndentCaseLabels: false
101 |
102 | # The number of columns to use for indentation.
103 | IndentWidth: 3
104 |
105 | # Indent if a function definition or declaration is wrapped after the type.
106 | IndentWrappedFunctionNames: false
107 |
108 | # If true, empty lines at the start of blocks are kept.
109 | KeepEmptyLinesAtTheStartOfBlocks: true
110 |
111 | # Language, this format style is targeted at. Possible values: None, Cpp, Java, JavaScript, Proto.
112 | Language: Cpp
113 |
114 | # The maximum number of consecutive empty lines to keep.
115 | MaxEmptyLinesToKeep: 1
116 |
117 | # The indentation used for namespaces. Possible values: None, Inner, All.
118 | NamespaceIndentation: None
119 |
120 | # The penalty for breaking a function call after "call(".
121 | PenaltyBreakBeforeFirstCallParameter: 19
122 |
123 | # The penalty for each line break introduced inside a comment.
124 | PenaltyBreakComment: 300
125 |
126 | # The penalty for breaking before the first <<.
127 | PenaltyBreakFirstLessLess: 120
128 |
129 | # The penalty for each line break introduced inside a string literal.
130 | PenaltyBreakString: 1000
131 |
132 | # The penalty for each character outside of the column limit.
133 | PenaltyExcessCharacter: 1000000
134 |
135 | # Penalty for putting the return type of a function onto its own line.
136 | PenaltyReturnTypeOnItsOwnLine: 1000000000
137 |
138 | # Pointer and reference alignment style. Possible values: Left, Right, Middle.
139 | PointerAlignment: Right
140 |
141 | # Do not sort includes
142 | SortIncludes: false
143 |
144 | # If true, a space may be inserted after C style casts.
145 | SpaceAfterCStyleCast: false
146 |
147 | # If false, spaces will be removed before assignment operators.
148 | SpaceBeforeAssignmentOperators: true
149 |
150 | # Defines in which cases to put a space before opening parentheses. Possible values: Never, ControlStatements, Always.
151 | SpaceBeforeParens: ControlStatements
152 |
153 | # If true, spaces may be inserted into '()'.
154 | SpaceInEmptyParentheses: false
155 |
156 | # The number of spaces before trailing line comments (// - comments).
157 | SpacesBeforeTrailingComments: 1
158 |
159 | # If true, spaces will be inserted after '<' and before '>' in template argument lists.
160 | SpacesInAngles: false
161 |
162 | # If true, spaces may be inserted into C style casts.
163 | SpacesInCStyleCastParentheses: false
164 |
165 | # If true, spaces are inserted inside container literals (e.g. ObjC and Javascript array and dict literals).
166 | SpacesInContainerLiterals: false
167 |
168 | # If true, spaces will be inserted after '(' and before ')'.
169 | SpacesInParentheses: false
170 |
171 | # If true, spaces will be inserted after '[' and befor']'.
172 | SpacesInSquareBrackets: false
173 |
174 | # Format compatible with this standard, e.g. use A > instead of A> for LS_Cpp03. Possible values: Cpp03, Cpp11, Auto.
175 | Standard: Cpp11
176 |
177 | # The number of columns used for tab stops.
178 | TabWidth: 3
179 |
180 | # The way to use tab characters in the resulting file. Possible values: Never, ForIndentation, Always.
181 | UseTab: Never
182 |
183 | FixNamespaceComments: false
184 |
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2019-2024 Arm Limited.
2 | #
3 | # SPDX-License-Identifier: MIT
4 | #
5 | # Permission is hereby granted, free of charge, to any person obtaining a copy
6 | # of this software and associated documentation files (the "Software"), to
7 | # deal in the Software without restriction, including without limitation the
8 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 | # sell copies of the Software, and to permit persons to whom the Software is
10 | # furnished to do so, subject to the following conditions:
11 | #
12 | # The above copyright notice and this permission notice shall be included in all
13 | # copies or substantial portions of the Software.
14 | #
15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | # SOFTWARE.
22 |
23 | pre-commit:
24 | image: python:3.10.6
25 | rules:
26 | - if: $CI_MERGE_REQUEST_DIFF_BASE_SHA
27 | script:
28 | - pip install pre-commit
29 | - echo Using $CI_MERGE_REQUEST_DIFF_BASE_SHA as Pre-commit base
30 | - pre-commit run --show-diff-on-failure --from-ref $CI_MERGE_REQUEST_DIFF_BASE_SHA --to-ref HEAD
31 |
32 | build_vulkan_wsi_layer:
33 | # For now start from a standard Fedora image and install everything each time.
34 | image: "registry.fedoraproject.org/fedora"
35 | before_script:
36 | - pwd
37 | - uname -a
38 | # Install necessary packages.
39 | # Oddly the exit status of the command below is nonzero even on success, just ignore it.
40 | - yes | dnf install make cmake gcc g++ python git libxcb-devel libxkbcommon-devel wayland-devel libXrandr-devel || true
41 | # Check out and set-up the Vulkan Loader.
42 | - mkdir /build
43 | - pushd /build
44 | - git clone --depth=1 https://github.com/KhronosGroup/Vulkan-Loader.git
45 | - cd Vulkan-Loader
46 | - mkdir build
47 | - cd build/
48 | - ../scripts/update_deps.py --cmake_var VULKAN_HEADERS_ENABLE_MODULE=OFF
49 | # Build the Vulkan loader.
50 | - cmake -C helper.cmake ..
51 | - make
52 | - make install
53 | - popd
54 | script:
55 | - pwd
56 | - mkdir build
57 | - cd build
58 | - cmake .. -DVULKAN_CXX_INCLUDE=/build/Vulkan-Loader/build/Vulkan-Headers/build/install/include
59 | - make
60 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | # See https://pre-commit.com for more information
2 | # See https://pre-commit.com/hooks.html for more hooks
3 |
4 | minimum_pre_commit_version: 2.9.0
5 |
6 | repos:
7 | - repo: https://github.com/pre-commit/mirrors-clang-format
8 | rev: v14.0.0
9 | hooks:
10 | - id: clang-format
11 | types_or: [c, c++]
12 |
13 | - repo: local
14 | hooks:
15 | - id: copyright-check
16 | name: copyright-check
17 | description: Checks for a valid copyright header
18 | entry: check_copyright.py
19 | language: script
20 | types_or: [c, c++]
21 |
--------------------------------------------------------------------------------
/DCO.txt:
--------------------------------------------------------------------------------
1 | Developer Certificate of Origin
2 | Version 1.1
3 |
4 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
5 | 1 Letterman Drive
6 | Suite D4700
7 | San Francisco, CA, 94129
8 |
9 | Everyone is permitted to copy and distribute verbatim copies of this
10 | license document, but changing it is not allowed.
11 |
12 |
13 | Developer's Certificate of Origin 1.1
14 |
15 | By making a contribution to this project, I certify that:
16 |
17 | (a) The contribution was created in whole or in part by me and I
18 | have the right to submit it under the open source license
19 | indicated in the file; or
20 |
21 | (b) The contribution is based upon previous work that, to the best
22 | of my knowledge, is covered under an appropriate open source
23 | license and I have the right under that license to submit that
24 | work with modifications, whether created in whole or in part
25 | by me, under the same open source license (unless I am
26 | permitted to submit under a different license), as indicated
27 | in the file; or
28 |
29 | (c) The contribution was provided directly to me by some other
30 | person who certified (a), (b) or (c) and I have not modified
31 | it.
32 |
33 | (d) I understand and agree that this project and the contribution
34 | are public and that a record of the contribution (including all
35 | personal information I submit with it, including my sign-off) is
36 | maintained indefinitely and may be redistributed consistent with
37 | this project or the open source license(s) involved.
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2019 Arm Limited.
2 |
3 | SPDX-License-Identifier: MIT
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to
7 | deal in the Software without restriction, including without limitation the
8 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 | sell copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/check_copyright.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # Copyright (c) 2022 Arm Limited.
4 | #
5 | # SPDX-License-Identifier: MIT
6 | #
7 | # Permission is hereby granted, free of charge, to any person obtaining a copy
8 | # of this software and associated documentation files (the "Software"), to
9 | # deal in the Software without restriction, including without limitation the
10 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | # sell copies of the Software, and to permit persons to whom the Software is
12 | # furnished to do so, subject to the following conditions:
13 | #
14 | # The above copyright notice and this permission notice shall be included in all
15 | # copies or substantial portions of the Software.
16 | #
17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | # SOFTWARE.
24 |
25 | '''
26 | This script will check the files passed as arguments for a valid copyright
27 | header. It will run against all changed files as part of the pre-commit hook
28 | after running `pre-commit install` in the root of the repository. It can also
29 | be run manually e.g. `./check_copyright.py file1 dir1/file2`
30 |
31 | A valid copyright header includes the word 'Copyright' followed by the
32 | relevant copyright years. It also requires an SPDX licence id string identifying
33 | the license as MIT, as follows: 'SPDX-License-Identifier: MIT'
34 | '''
35 |
36 | import datetime
37 | import re
38 | import sys
39 | from typing import List
40 |
41 | # Set the limit on number of lines at top of file to search
42 | MAX_SEARCH_LINES = 20
43 | CURRENT_YEAR = datetime.datetime.now().year
44 |
45 | # Regex for positive copyright string
46 | COPYRIGHT_YEAR_REGEX = re.compile(
47 | r".*\bCOPYRIGHT.*%s.*" % str(CURRENT_YEAR), re.IGNORECASE
48 | )
49 |
50 | # Regex for positive SPDX id string
51 | SPDX_REGEX = re.compile(r".*SPDX-License-Identifier: MIT.*", re.IGNORECASE)
52 |
53 | # To match eg: "Copyright (C) 2014-2021"
54 | PATTERN_STRING = r"\bCopyright\b.*[0-9,)]"
55 | PATTERN_COPYRIGHT = re.compile(PATTERN_STRING, re.IGNORECASE)
56 |
57 |
58 | def generate_years_string(years: List[int]) -> str:
59 | """
60 | Create a compacted string representation of a list of years.
61 |
62 | E.g. [1991, 2001, 2002, 2003, 2006, 2007] becomes "1991, 2001-2003,
63 | 2006-2007"
64 | """
65 |
66 | generated_years_string = ""
67 | if len(years) > 0:
68 | y_mod_strings = ["%d" % years[0]]
69 |
70 | last_element_was_incremental = False
71 | for i in range(1, len(years)):
72 | # Are we in an incremental sequence?
73 | if years[i] == years[i - 1] + 1:
74 |
75 | last_element_was_incremental = True
76 |
77 | # Are we at the last element?
78 | if i == len(years) - 1:
79 | y_mod_strings.append("-%d" % years[i])
80 | else:
81 | continue
82 |
83 | else:
84 | # End of a sequence?
85 | if last_element_was_incremental:
86 | y_mod_strings.append("-%d, " % years[i - 1])
87 | else:
88 | y_mod_strings.append(", ")
89 |
90 | y_mod_strings.append("%d" % years[i])
91 | last_element_was_incremental = False
92 |
93 | generated_years_string = "".join(y_mod_strings)
94 |
95 | return generated_years_string
96 |
97 |
98 | def parse_years_string(s: str) -> List[int]:
99 | """
100 | Given the string "1999, 2001-2005" this function returns the list:
101 | [1999, 2001, 2002, 2003, 2004, 2005]
102 | """
103 | singles = re.findall(r"(? None:
118 | """
119 | Updates the Copyright header in 'filename' to hold the correct years.
120 | """
121 |
122 | with open(filename, "r+", encoding="utf-8") as file_handle:
123 | file_data = file_handle.read()
124 |
125 | copyright_match = re.search(PATTERN_COPYRIGHT, file_data)
126 | if copyright_match:
127 |
128 | notice_years = parse_years_string(copyright_match.group(0))
129 |
130 | if not notice_years or notice_years[-1] != CURRENT_YEAR:
131 | notice_years.append(CURRENT_YEAR)
132 |
133 | years_string = generate_years_string(notice_years)
134 |
135 | file_data = re.sub(
136 | PATTERN_COPYRIGHT, "Copyright (c) %s" % years_string, file_data, 1
137 | )
138 | file_handle.seek(0)
139 | file_handle.write(file_data)
140 | file_handle.truncate()
141 |
142 |
143 | bad_copyright_files = []
144 | bad_spdx_files = []
145 |
146 | for changed_file in sys.argv[1:]:
147 | copyright_found = False
148 | spdx_found = False
149 |
150 | with open(changed_file, encoding="utf-8") as f:
151 | for line_num, line in enumerate(f):
152 | if line_num > MAX_SEARCH_LINES:
153 | break
154 | if COPYRIGHT_YEAR_REGEX.match(line):
155 | copyright_found = True
156 | if SPDX_REGEX.match(line):
157 | spdx_found = True
158 |
159 | if not copyright_found:
160 | bad_copyright_files.append(changed_file)
161 | update_header(changed_file)
162 | if not spdx_found:
163 | bad_spdx_files.append(changed_file)
164 |
165 | if bad_copyright_files:
166 | print(
167 | "The following files did not have a valid copyright header: "
168 | + str(bad_copyright_files)
169 | + "\nAn attempted fix may have been made please check the files and re-commit",
170 | file=sys.stderr,
171 | )
172 |
173 | if bad_spdx_files:
174 | print(
175 | "The following files do not have a valid SPDX licence identifier: "
176 | + str(bad_spdx_files)
177 | + "\nPlease add the identifier as follows 'SPDX-License-Identifier: MIT'",
178 | file=sys.stderr,
179 | )
180 |
181 | if bad_copyright_files or bad_spdx_files:
182 | sys.exit(1)
183 |
--------------------------------------------------------------------------------
/docs/guidelines.md:
--------------------------------------------------------------------------------
1 | # Guidelines for development
2 | This document outlines the guidelines that should be followed when submitting changes to the WSI layer. Although these
3 | rules should not be taken as set in stone, we encourage contributors to follow them in order to make the WSI layer
4 | more maintainable and easier to review.
5 |
6 | ## Exceptions
7 | We discourage the use of exceptions in the codebase. The preferred error handling mechanism is to return
8 | error codes. This closely aligns to the way the Vulkan API returns VkResult error codes to
9 | indicate an error or success. In addition, some of the libraries used in the layer are written using C rather
10 | than C++. In order to ensure interoperability between C and C++ code in the layer we have decided to forgo exceptions
11 | as there is no way for the C code to clean up correctly when an exception is thrown in C++ code.
12 |
13 | In some cases you might find that avoiding exceptions is very difficult. As an example we can use the STL
14 | containers such as std::vector or std::map which, by design, throw exceptions for memory allocation failures.
15 | In addition, the Vulkan API allows the application to supply custom allocation callbacks for memory allocation by
16 | passing a VkAllocationCallbacks structure. We must be able to handle these exceptions, possibly caused by failures in
17 | custom allocators, STL containers, etc., in order to correctly implement the Vulkan API and return the appropriate
18 | error codes, e.g. VK_ERROR_OUT_OF_HOST_MEMORY.
19 |
20 | A good idea is to introduce a wrapper around the STL container to ensure all exceptions are caught and converted to
21 | error codes that are propagated back to the caller. It is highly recommended to use the
22 | [utility classes](https://gitlab.freedesktop.org/mesa/vulkan-wsi-layer/-/tree/main/util) provided by the WSI layer
23 | if you need an exception-safe wrapper for STL containers:
24 | * [util::vector](https://gitlab.freedesktop.org/mesa/vulkan-wsi-layer/-/blob/main/util/custom_allocator.hpp)
25 | * [util::unordered_map](https://gitlab.freedesktop.org/mesa/vulkan-wsi-layer/-/blob/main/util/unordered_map.hpp)
26 | * [util::unordered_set](https://gitlab.freedesktop.org/mesa/vulkan-wsi-layer/-/blob/main/util/unordered_set.hpp)
27 |
28 | For other helper components provided by the WSI layer please see
29 | [WSI integration document](https://gitlab.freedesktop.org/mesa/vulkan-wsi-layer/-/blob/main/wsi/README.md#helpers).
30 |
--------------------------------------------------------------------------------
/layer/VkLayer_window_system_integration.json:
--------------------------------------------------------------------------------
1 | {
2 | "file_format_version": "1.1.2",
3 | "layer": {
4 | "name": "VK_LAYER_window_system_integration",
5 | "type": "GLOBAL",
6 | "library_path": "./libVkLayer_window_system_integration.so",
7 | "api_version": "1.3.216",
8 | "implementation_version": "1",
9 | "description": "Window system integration layer",
10 | "functions": {
11 | "vkNegotiateLoaderLayerInterfaceVersion": "wsi_layer_vkNegotiateLoaderLayerInterfaceVersion"
12 | },
13 | "instance_extensions": [
14 | {"name" : "VK_EXT_headless_surface", "spec_version" : "1"},
15 | {"name" : "VK_KHR_wayland_surface", "spec_version" : "6"},
16 | {"name" : "VK_KHR_xcb_surface", "spec_version" : "1"},
17 | {"name" : "VK_KHR_xlib_surface", "spec_version" : "1"},
18 | {"name" : "VK_KHR_surface", "spec_version" : "25"},
19 | {"name" : "VK_KHR_display", "spec_version" : "23"},
20 | {"name" : "VK_KHR_get_surface_capabilities2", "spec_version" : "1"},
21 | {"name" : "VK_EXT_surface_maintenance1", "spec_version" : "1"}
22 | ],
23 | "device_extensions": [
24 | {"name": "VK_KHR_shared_presentable_image", "spec_version": "1", "entrypoints": ["vkGetSwapchainStatusKHR"]},
25 | {"name": "VK_EXT_image_compression_control_swapchain", "spec_version": "1"},
26 | {
27 | "name": "VK_KHR_swapchain",
28 | "spec_version": "70",
29 | "entrypoints": [
30 | "vkAcquireNextImageKHR",
31 | "vkCreateSwapchainKHR",
32 | "vkDestroySwapchainKHR",
33 | "vkGetSwapchainImagesKHR",
34 | "vkQueuePresentKHR",
35 | "vkAcquireNextImage2KHR",
36 | "vkGetDeviceGroupPresentCapabilitiesKHR",
37 | "vkGetDeviceGroupSurfacePresentModesKHR",
38 | "vkGetPhysicalDevicePresentRectanglesKHR"
39 | ]
40 | },
41 | {"name": "VK_KHR_present_id", "spec_version": "1"},
42 | {
43 | "name": "VK_EXT_swapchain_maintenance1",
44 | "spec_version": "1",
45 | "entrypoints": [
46 | "vkReleaseSwapchainImagesEXT"
47 | ]
48 | },
49 | {
50 | "name": "VK_EXT_present_timing",
51 | "spec_version": "1",
52 | "entrypoints": [
53 | "vkSetSwapchainPresentTimingQueueSizeEXT",
54 | "vkGetSwapchainTimingPropertiesEXT",
55 | "vkGetSwapchainTimeDomainPropertiesEXT",
56 | "vkGetPastPresentationTimingEXT"
57 | ]
58 | }
59 | ],
60 | "disable_environment": {
61 | "DISABLE_WSI_LAYER": "1"
62 | }
63 | }
64 | }
--------------------------------------------------------------------------------
/layer/present_timing.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /**
26 | * @file present_timing.cpp
27 | *
28 | * @brief Contains the Vulkan entrypoints for the present timing.
29 | */
30 | #include
31 | #include "wsi_layer_experimental.hpp"
32 | #include "wsi/swapchain_base.hpp"
33 |
34 | #if VULKAN_WSI_LAYER_EXPERIMENTAL
35 |
36 | /**
37 | * @brief Implements vkSetSwapchainPresentTimingQueueSizeEXT Vulkan entrypoint.
38 | */
39 | VWL_VKAPI_CALL(VkResult)
40 | wsi_layer_vkSetSwapchainPresentTimingQueueSizeEXT(VkDevice device, VkSwapchainKHR swapchain, uint32_t size) VWL_API_POST
41 | {
42 | assert(swapchain != VK_NULL_HANDLE);
43 | auto *sc = reinterpret_cast(swapchain);
44 | return sc->presentation_timing_queue_set_size(size);
45 | }
46 |
47 | /**
48 | * @brief Implements vkGetSwapchainTimingPropertiesEXT Vulkan entrypoint.
49 | */
50 | VWL_VKAPI_CALL(VkResult)
51 | wsi_layer_vkGetSwapchainTimingPropertiesEXT(VkDevice device, VkSwapchainKHR swapchain,
52 | uint64_t *pSwapchainTimingPropertiesCounter,
53 | VkSwapchainTimingPropertiesEXT *pSwapchainTimingProperties) VWL_API_POST
54 | {
55 | VkResult result = VK_SUCCESS;
56 | return result;
57 | }
58 |
59 | /**
60 | * @brief Implements vkGetSwapchainTimeDomainPropertiesEXT Vulkan entrypoint.
61 | */
62 | VWL_VKAPI_CALL(VkResult)
63 | wsi_layer_vkGetSwapchainTimeDomainPropertiesEXT(
64 | VkDevice device, VkSwapchainKHR swapchain, uint64_t *pTimeDomainsCounter,
65 | VkSwapchainTimeDomainPropertiesEXT *pSwapchainTimeDomainProperties) VWL_API_POST
66 | {
67 | VkResult result = VK_SUCCESS;
68 | return result;
69 | }
70 |
71 | /**
72 | * @brief Implements vkGetPastPresentationTimingEXT Vulkan entrypoint.
73 | */
74 | VWL_VKAPI_CALL(VkResult)
75 | wsi_layer_vkGetPastPresentationTimingEXT(
76 | VkDevice device, const VkPastPresentationTimingInfoEXT *pPastPresentationTimingInfo,
77 | VkPastPresentationTimingPropertiesEXT *pPastPresentationTimingProperties) VWL_API_POST
78 | {
79 | VkResult result = VK_SUCCESS;
80 | return result;
81 | }
82 | #endif /* VULKAN_WSI_LAYER_EXPERIMENTAL */
83 |
--------------------------------------------------------------------------------
/layer/surface_api.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018-2019, 2021-2022 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /**
26 | * @file surface_api.hpp
27 | *
28 | * @brief Contains the Vulkan entrypoints for the VkSurfaceKHR.
29 | */
30 | #pragma once
31 |
32 | #include
33 | #include "util/macros.hpp"
34 |
35 | /**
36 | * @brief Implements vkGetPhysicalDeviceSurfaceCapabilitiesKHR Vulkan entrypoint.
37 | */
38 | VWL_VKAPI_CALL(VkResult)
39 | wsi_layer_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
40 | VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) VWL_API_POST;
41 |
42 | /**
43 | * @brief Implements vkGetPhysicalDeviceSurfaceCapabilities2KHR Vulkan entrypoint.
44 | */
45 | VWL_VKAPI_CALL(VkResult)
46 | wsi_layer_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,
47 | const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
48 | VkSurfaceCapabilities2KHR *pSurfaceCapabilities) VWL_API_POST;
49 |
50 | /**
51 | * @brief Implements vkGetPhysicalDeviceSurfaceFormatsKHR Vulkan entrypoint.
52 | */
53 | VWL_VKAPI_CALL(VkResult)
54 | wsi_layer_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
55 | uint32_t *pSurfaceFormatCount,
56 | VkSurfaceFormatKHR *pSurfaceFormats) VWL_API_POST;
57 |
58 | /**
59 | * @brief Implements vkGetPhysicalDeviceSurfaceFormats2KHR Vulkan entrypoint.
60 | */
61 | VWL_VKAPI_CALL(VkResult)
62 | wsi_layer_vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
63 | const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
64 | uint32_t *pSurfaceFormatCount,
65 | VkSurfaceFormat2KHR *pSurfaceFormats) VWL_API_POST;
66 |
67 | /**
68 | * @brief Implements vkGetPhysicalDeviceSurfacePresentModesKHR Vulkan entrypoint.
69 | */
70 | VWL_VKAPI_CALL(VkResult)
71 | wsi_layer_vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
72 | uint32_t *pPresentModeCount,
73 | VkPresentModeKHR *pPresentModes) VWL_API_POST;
74 |
75 | /**
76 | * @brief Implements vkGetPhysicalDeviceSurfaceSupportKHR Vulkan entrypoint.
77 | */
78 | VWL_VKAPI_CALL(VkResult)
79 | wsi_layer_vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex,
80 | VkSurfaceKHR surface, VkBool32 *pSupported) VWL_API_POST;
81 |
82 | /**
83 | * @brief Implements vkDestroySurfaceKHR Vulkan entrypoint.
84 | */
85 | VWL_VKAPI_CALL(void)
86 | wsi_layer_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
87 | const VkAllocationCallbacks *pAllocator) VWL_API_POST;
88 |
--------------------------------------------------------------------------------
/layer/swapchain_api.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018-2019, 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /**
26 | * @file swapchain_api.hpp
27 | *
28 | * @brief Contains the Vulkan entrypoints for the swapchain.
29 | */
30 |
31 | #pragma once
32 |
33 | #include
34 | #include "util/macros.hpp"
35 |
36 | VWL_VKAPI_CALL(VkResult)
37 | wsi_layer_vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pSwapchainCreateInfo,
38 | const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) VWL_API_POST;
39 |
40 | VWL_VKAPI_CALL(void)
41 | wsi_layer_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapc,
42 | const VkAllocationCallbacks *pAllocator) VWL_API_POST;
43 |
44 | VWL_VKAPI_CALL(VkResult)
45 | wsi_layer_vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapc, uint32_t *pSwapchainImageCount,
46 | VkImage *pSwapchainImages) VWL_API_POST;
47 |
48 | VWL_VKAPI_CALL(VkResult)
49 | wsi_layer_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapc, uint64_t timeout, VkSemaphore semaphore,
50 | VkFence fence, uint32_t *pImageIndex) VWL_API_POST;
51 |
52 | VWL_VKAPI_CALL(VkResult)
53 | wsi_layer_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) VWL_API_POST;
54 |
55 | /* 1.1 entrypoints */
56 | VWL_VKAPI_CALL(VkResult)
57 | wsi_layer_vkGetDeviceGroupPresentCapabilitiesKHR(
58 | VkDevice device, VkDeviceGroupPresentCapabilitiesKHR *pDeviceGroupPresentCapabilities) VWL_API_POST;
59 |
60 | VWL_VKAPI_CALL(VkResult)
61 | wsi_layer_vkGetDeviceGroupSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface,
62 | VkDeviceGroupPresentModeFlagsKHR *pModes) VWL_API_POST;
63 |
64 | VWL_VKAPI_CALL(VkResult)
65 | wsi_layer_vkGetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
66 | uint32_t *pRectCount, VkRect2D *pRects) VWL_API_POST;
67 |
68 | VWL_VKAPI_CALL(VkResult)
69 | wsi_layer_vkAcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR *pAcquireInfo,
70 | uint32_t *pImageIndex) VWL_API_POST;
71 |
72 | VWL_VKAPI_CALL(VkResult)
73 | wsi_layer_vkCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
74 | VkImage *pImage) VWL_API_POST;
75 |
76 | VWL_VKAPI_CALL(VkResult)
77 | wsi_layer_vkBindImageMemory2(VkDevice device, uint32_t bindInfoCount,
78 | const VkBindImageMemoryInfo *pBindInfos) VWL_API_POST;
79 |
80 | VWL_VKAPI_CALL(VkResult)
81 | wsi_layer_vkGetSwapchainStatusKHR(VkDevice device, VkSwapchainKHR swapchain) VWL_API_POST;
82 |
--------------------------------------------------------------------------------
/layer/swapchain_maintenance_api.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /**
26 | * @file swapchain_maintenance_api.cpp
27 | *
28 | * @brief Contains the Vulkan entrypoints for the swapchain maintenance.
29 | */
30 |
31 | #include "swapchain_maintenance_api.hpp"
32 | #include "private_data.hpp"
33 |
34 | #include
35 | #include
36 |
37 | VWL_VKAPI_CALL(VkResult)
38 | wsi_layer_vkReleaseSwapchainImagesEXT(VkDevice device, const VkReleaseSwapchainImagesInfoEXT *pReleaseInfo) VWL_API_POST
39 | {
40 | if (pReleaseInfo == nullptr || pReleaseInfo->imageIndexCount == 0)
41 | {
42 | return VK_SUCCESS;
43 | }
44 |
45 | assert(pReleaseInfo->pImageIndices != nullptr);
46 | assert(pReleaseInfo->swapchain != VK_NULL_HANDLE);
47 |
48 | auto &device_data = layer::device_private_data::get(device);
49 | if (!device_data.layer_owns_swapchain(pReleaseInfo->swapchain))
50 | {
51 | return device_data.disp.ReleaseSwapchainImagesEXT(device, pReleaseInfo);
52 | }
53 |
54 | auto *sc = reinterpret_cast(pReleaseInfo->swapchain);
55 | sc->release_images(pReleaseInfo->imageIndexCount, pReleaseInfo->pImageIndices);
56 |
57 | return VK_SUCCESS;
58 | }
--------------------------------------------------------------------------------
/layer/swapchain_maintenance_api.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /**
26 | * @file swapchain_maintenance_api.hpp
27 | *
28 | * @brief Contains the Vulkan entrypoints for the swapchain maintenance.
29 | */
30 |
31 | #pragma once
32 |
33 | #include
34 | #include "util/macros.hpp"
35 |
36 | VWL_VKAPI_CALL(VkResult)
37 | wsi_layer_vkReleaseSwapchainImagesEXT(VkDevice device,
38 | const VkReleaseSwapchainImagesInfoEXT *pReleaseInfo) VWL_API_POST;
--------------------------------------------------------------------------------
/layer/wsi_layer_experimental.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /**
26 | * @file wsi_layer_experimental.hpp
27 | *
28 | * @brief Contains the Vulkan definitions for experimental features.
29 | */
30 | #pragma once
31 |
32 | #include
33 | #include "util/macros.hpp"
34 |
35 | #if VULKAN_WSI_LAYER_EXPERIMENTAL
36 | #define VK_KHR_present_timing 1
37 | #define VK_KHR_PRESENT_TIMING_SPEC_VERSION 1
38 | #define VK_KHR_PRESENT_TIMING_EXTENSION_NAME "VK_KHR_present_timing"
39 |
40 | #define VK_ERROR_PRESENT_TIMING_QUEUE_FULL_EXT ((VkResult)(-1000208000))
41 | #define VK_TIME_DOMAIN_PRESENT_STAGE_LOCAL_EXT ((VkTimeDomainEXT)(1000208000))
42 | #define VK_TIME_DOMAIN_SWAPCHAIN_LOCAL_EXT ((VkTimeDomainEXT)(1000208001))
43 | #define VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_TIMING_FEATURES_EXT ((VkStructureType)1000208002)
44 | #define VK_STRUCTURE_TYPE_PRESENT_TIMING_SURFACE_CAPABILITIES_EXT ((VkStructureType)1000208003)
45 | #define VK_STRUCTURE_TYPE_SWAPCHAIN_TIMING_PROPERTIES_EXT ((VkStructureType)1000208004)
46 | #define VK_STRUCTURE_TYPE_SWAPCHAIN_TIME_DOMAIN_PROPERTIES_EXT ((VkStructureType)1000208005)
47 | #define VK_STRUCTURE_TYPE_SWAPCHAIN_CALIBRATED_TIMESTAMP_INFO_EXT ((VkStructureType)1000208006)
48 | #define VK_STRUCTURE_TYPE_PAST_PRESENTATION_TIMING_EXT ((VkStructureType)1000208007)
49 | #define VK_STRUCTURE_TYPE_PAST_PRESENTATION_TIMING_PROPERTIES_EXT ((VkStructureType)1000208008)
50 | #define VK_STRUCTURE_TYPE_PAST_PRESENTATION_TIMING_INFO_EXT ((VkStructureType)1000208009)
51 | #define VK_STRUCTURE_TYPE_PRESENT_TIMING_INFO_EXT ((VkStructureType)1000208010)
52 | #define VK_STRUCTURE_TYPE_PRESENT_TIMINGS_INFO_EXT ((VkStructureType)1000208011)
53 |
54 | typedef VkFlags VkPresentStageFlagsEXT;
55 |
56 | typedef struct VkPhysicalDevicePresentTimingFeaturesEXT
57 | {
58 | VkStructureType sType;
59 | void *pNext;
60 | VkBool32 presentTiming;
61 | VkBool32 presentAtAbsoluteTime;
62 | VkBool32 presentAtRelativeTime;
63 | } VkPhysicalDevicePresentTimingFeaturesEXT;
64 |
65 | typedef struct VkPresentTimingSurfaceCapabilitiesEXT
66 | {
67 | VkStructureType sType;
68 | void *pNext;
69 | VkBool32 presentTimingSupported;
70 | VkBool32 presentAtAbsoluteTimeSupported;
71 | VkBool32 presentAtRelativeTimeSupported;
72 | VkPresentStageFlagsEXT presentStageQueries;
73 | VkPresentStageFlagsEXT presentStageTargets;
74 | } VkPresentTimingSurfaceCapabilitiesEXT;
75 |
76 | typedef enum VkPresentStageFlagBitsEXT
77 | {
78 | VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT = 0x00000001,
79 | VK_PRESENT_STAGE_IMAGE_LATCHED_BIT_EXT = 0x00000002,
80 | VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT = 0x00000004,
81 | VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT = 0x00000008,
82 | } VkPresentStageFlagBitsEXT;
83 |
84 | typedef struct VkSwapchainTimingPropertiesEXT
85 | {
86 | VkStructureType sType;
87 | const void *pNext;
88 | uint64_t refreshDuration;
89 | uint64_t variableRefreshDelay;
90 | } VkSwapchainTimingPropertiesEXT;
91 |
92 | typedef struct VkSwapchainTimeDomainPropertiesEXT
93 | {
94 | VkStructureType sType;
95 | void *pNext;
96 | uint32_t timeDomainCount;
97 | VkTimeDomainEXT *pTimeDomains;
98 | uint64_t *pTimeDomainIds;
99 | } VkSwapchainTimeDomainPropertiesEXT;
100 |
101 | typedef struct VkSwapchainCalibratedTimestampInfoEXT
102 | {
103 | VkStructureType sType;
104 | const void *pNext;
105 | VkSwapchainKHR swapchain;
106 | VkPresentStageFlagsEXT presentStage;
107 | uint64_t timeDomainId;
108 | } VkSwapchainCalibratedTimestampInfoEXT;
109 |
110 | typedef struct VkPresentStageTimeEXT
111 | {
112 | VkPresentStageFlagsEXT stage;
113 | uint64_t time;
114 | } VkPresentStageTimeEXT;
115 |
116 | typedef struct VkPastPresentationTimingEXT
117 | {
118 | VkStructureType sType;
119 | const void *pNext;
120 | uint64_t presentId;
121 | uint32_t presentStageCount;
122 | VkPresentStageTimeEXT *pPresentStages;
123 | VkTimeDomainEXT timeDomain;
124 | uint64_t timeDomainId;
125 | VkBool32 reportComplete;
126 | } VkPastPresentationTimingEXT;
127 |
128 | typedef struct VkPastPresentationTimingPropertiesEXT
129 | {
130 | VkStructureType sType;
131 | const void *pNext;
132 | uint64_t timingPropertiesCounter;
133 | uint64_t timeDomainsCounter;
134 | uint32_t presentationTimingCount;
135 | VkPastPresentationTimingEXT *pPresentationTimings;
136 | } VkPastPresentationTimingPropertiesEXT;
137 |
138 | typedef struct VkPastPresentationTimingInfoEXT
139 | {
140 | VkStructureType sType;
141 | const void *pNext;
142 | VkSwapchainKHR swapchain;
143 | } VkPastPresentationTimingInfoEXT;
144 |
145 | typedef union VkPresentTimeEXT
146 | {
147 | uint64_t targetPresentTime;
148 | uint64_t presentDuration;
149 | } VkPresentTimeEXT;
150 |
151 | typedef struct VkPresentTimingInfoEXT
152 | {
153 | VkStructureType sType;
154 | const void *pNext;
155 | VkPresentTimeEXT time;
156 | uint64_t timeDomainId;
157 | VkPresentStageFlagsEXT presentStageQueries;
158 | VkPresentStageFlagsEXT targetPresentStage;
159 | VkBool32 presentAtRelativeTime;
160 | VkBool32 presentAtNearestRefreshCycle;
161 | } VkPresentTimingInfoEXT;
162 |
163 | typedef struct VkPresentTimingsInfoEXT
164 | {
165 | VkStructureType sType;
166 | const void *pNext;
167 | uint32_t swapchainCount;
168 | const VkPresentTimingInfoEXT *pTimingInfos;
169 | } VkPresentTimingsInfoEXT;
170 |
171 | VWL_VKAPI_CALL(VkResult)
172 | wsi_layer_vkSetSwapchainPresentTimingQueueSizeEXT(VkDevice device, VkSwapchainKHR swapchain,
173 | uint32_t size) VWL_API_POST;
174 |
175 | VWL_VKAPI_CALL(VkResult)
176 | wsi_layer_vkGetSwapchainTimingPropertiesEXT(VkDevice device, VkSwapchainKHR swapchain,
177 | uint64_t *pSwapchainTimingPropertiesCounter,
178 | VkSwapchainTimingPropertiesEXT *pSwapchainTimingProperties) VWL_API_POST;
179 | VWL_VKAPI_CALL(VkResult)
180 | wsi_layer_vkGetSwapchainTimeDomainPropertiesEXT(
181 | VkDevice device, VkSwapchainKHR swapchain, uint64_t *pTimeDomainsCounter,
182 | VkSwapchainTimeDomainPropertiesEXT *pSwapchainTimeDomainProperties) VWL_API_POST;
183 |
184 | VWL_VKAPI_CALL(VkResult)
185 | wsi_layer_vkGetPastPresentationTimingEXT(
186 | VkDevice device, const VkPastPresentationTimingInfoEXT *pPastPresentationTimingInfo,
187 | VkPastPresentationTimingPropertiesEXT *pPastPresentationTimingProperties) VWL_API_POST;
188 | #endif
189 |
--------------------------------------------------------------------------------
/util/custom_allocator.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2020-2021, 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #include "custom_allocator.hpp"
26 | #include "macros.hpp"
27 | #include
28 |
29 | namespace util
30 | {
31 |
32 | VWL_VKAPI_CALL(void *) default_allocation(void *, size_t size, size_t, VkSystemAllocationScope) VWL_API_POST
33 | {
34 | return malloc(size);
35 | }
36 |
37 | VWL_VKAPI_CALL(void *)
38 | default_reallocation(void *, void *pOriginal, size_t size, size_t, VkSystemAllocationScope) VWL_API_POST
39 | {
40 | return realloc(pOriginal, size);
41 | }
42 |
43 | VWL_VKAPI_CALL(void) default_free(void *, void *pMemory) VWL_API_POST
44 | {
45 | free(pMemory);
46 | }
47 |
48 | const allocator &allocator::get_generic()
49 | {
50 | static allocator generic{ VK_SYSTEM_ALLOCATION_SCOPE_COMMAND, nullptr };
51 | return generic;
52 | }
53 |
54 | allocator::allocator(const allocator &other, VkSystemAllocationScope new_scope, const VkAllocationCallbacks *callbacks)
55 | : allocator{ new_scope, callbacks == nullptr ? other.get_original_callbacks() : callbacks }
56 | {
57 | }
58 |
59 | /* If callbacks is already populated by vulkan then use those specified as default. */
60 | allocator::allocator(VkSystemAllocationScope scope, const VkAllocationCallbacks *callbacks)
61 | {
62 | m_scope = scope;
63 | if (callbacks != nullptr)
64 | {
65 | m_callbacks = *callbacks;
66 | }
67 | else
68 | {
69 | m_callbacks = {};
70 | m_callbacks.pfnAllocation = default_allocation;
71 | m_callbacks.pfnReallocation = default_reallocation;
72 | m_callbacks.pfnFree = default_free;
73 | }
74 | }
75 |
76 | const VkAllocationCallbacks *allocator::get_original_callbacks() const
77 | {
78 | return m_callbacks.pfnAllocation == default_allocation ? nullptr : &m_callbacks;
79 | }
80 |
81 | } /* namespace util */
82 |
--------------------------------------------------------------------------------
/util/drm/drm_utils.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, 2021, 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #include "drm_utils.hpp"
26 | #include "format_table.h"
27 |
28 | namespace util
29 | {
30 | namespace drm
31 | {
32 |
33 | uint32_t vk_to_drm_format(VkFormat vk_format)
34 | {
35 | for (size_t i = 0; i < fourcc_format_table_len; i++)
36 | {
37 | if (vk_format == fourcc_format_table[i].vk_format)
38 | {
39 | return fourcc_format_table[i].drm_format;
40 | }
41 | }
42 |
43 | for (size_t i = 0; i < srgb_fourcc_format_table_len; i++)
44 | {
45 | if (vk_format == srgb_fourcc_format_table[i].vk_format)
46 | {
47 | return srgb_fourcc_format_table[i].drm_format;
48 | }
49 | }
50 |
51 | return 0;
52 | }
53 |
54 | VkFormat drm_to_vk_format(uint32_t drm_format)
55 | {
56 | for (size_t i = 0; i < fourcc_format_table_len; i++)
57 | {
58 | if (drm_format == fourcc_format_table[i].drm_format)
59 | {
60 | return fourcc_format_table[i].vk_format;
61 | }
62 | }
63 |
64 | return VK_FORMAT_UNDEFINED;
65 | }
66 |
67 | VkFormat drm_to_vk_srgb_format(uint32_t drm_format)
68 | {
69 | for (size_t i = 0; i < srgb_fourcc_format_table_len; i++)
70 | {
71 | if (drm_format == srgb_fourcc_format_table[i].drm_format)
72 | {
73 | return srgb_fourcc_format_table[i].vk_format;
74 | }
75 | }
76 |
77 | return VK_FORMAT_UNDEFINED;
78 | }
79 |
80 | /* Returns the number of planes represented by a fourcc format. */
81 | uint32_t drm_fourcc_format_get_num_planes(uint32_t format)
82 | {
83 | switch (format)
84 | {
85 | default:
86 | return 0;
87 |
88 | case DRM_FORMAT_RGB332:
89 | case DRM_FORMAT_BGR233:
90 | case DRM_FORMAT_XRGB4444:
91 | case DRM_FORMAT_XBGR4444:
92 | case DRM_FORMAT_RGBX4444:
93 | case DRM_FORMAT_BGRX4444:
94 | case DRM_FORMAT_ARGB4444:
95 | case DRM_FORMAT_ABGR4444:
96 | case DRM_FORMAT_RGBA4444:
97 | case DRM_FORMAT_BGRA4444:
98 | case DRM_FORMAT_XRGB1555:
99 | case DRM_FORMAT_XBGR1555:
100 | case DRM_FORMAT_RGBX5551:
101 | case DRM_FORMAT_BGRX5551:
102 | case DRM_FORMAT_ARGB1555:
103 | case DRM_FORMAT_ABGR1555:
104 | case DRM_FORMAT_RGBA5551:
105 | case DRM_FORMAT_BGRA5551:
106 | case DRM_FORMAT_RGB565:
107 | case DRM_FORMAT_BGR565:
108 | case DRM_FORMAT_RGB888:
109 | case DRM_FORMAT_BGR888:
110 | case DRM_FORMAT_XRGB8888:
111 | case DRM_FORMAT_XBGR8888:
112 | case DRM_FORMAT_RGBX8888:
113 | case DRM_FORMAT_BGRX8888:
114 | case DRM_FORMAT_ARGB8888:
115 | case DRM_FORMAT_ABGR8888:
116 | case DRM_FORMAT_RGBA8888:
117 | case DRM_FORMAT_BGRA8888:
118 | return 1;
119 | }
120 | }
121 |
122 | } // namespace drm
123 | } // namespace util
124 |
--------------------------------------------------------------------------------
/util/drm/drm_utils.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, 2021-2022, 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #pragma once
26 |
27 | #include
28 |
29 | namespace util
30 | {
31 | namespace drm
32 | {
33 |
34 | uint32_t vk_to_drm_format(VkFormat vk_format);
35 | VkFormat drm_to_vk_format(uint32_t drm_format);
36 | VkFormat drm_to_vk_srgb_format(uint32_t drm_format);
37 | uint32_t drm_fourcc_format_get_num_planes(uint32_t format);
38 |
39 | } // namespace drm
40 | } // namespace util
41 |
--------------------------------------------------------------------------------
/util/drm/format_table.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #include "format_table.h"
26 |
27 | const fmt_spec fourcc_format_table[] = {
28 | /* Supported R,G,B,A formats */
29 | { DRM_FORMAT_RGB332, 1, { 8, 0, 0, 0 }, VK_FORMAT_UNDEFINED },
30 | { DRM_FORMAT_BGR233, 1, { 8, 0, 0, 0 }, VK_FORMAT_UNDEFINED },
31 | { DRM_FORMAT_XRGB4444, 1, { 16, 0, 0, 0 }, VK_FORMAT_UNDEFINED },
32 | { DRM_FORMAT_XBGR4444, 1, { 16, 0, 0, 0 }, VK_FORMAT_UNDEFINED },
33 | { DRM_FORMAT_RGBX4444, 1, { 16, 0, 0, 0 }, VK_FORMAT_UNDEFINED },
34 | { DRM_FORMAT_BGRX4444, 1, { 16, 0, 0, 0 }, VK_FORMAT_UNDEFINED },
35 | { DRM_FORMAT_ARGB4444, 1, { 16, 0, 0, 0 }, VK_FORMAT_UNDEFINED },
36 | { DRM_FORMAT_ABGR4444, 1, { 16, 0, 0, 0 }, VK_FORMAT_UNDEFINED },
37 | { DRM_FORMAT_RGBA4444, 1, { 16, 0, 0, 0 }, VK_FORMAT_R4G4B4A4_UNORM_PACK16 },
38 | { DRM_FORMAT_BGRA4444, 1, { 16, 0, 0, 0 }, VK_FORMAT_B4G4R4A4_UNORM_PACK16 },
39 | { DRM_FORMAT_XRGB1555, 1, { 16, 0, 0, 0 }, VK_FORMAT_UNDEFINED },
40 | { DRM_FORMAT_XBGR1555, 1, { 16, 0, 0, 0 }, VK_FORMAT_UNDEFINED },
41 | { DRM_FORMAT_RGBX5551, 1, { 16, 0, 0, 0 }, VK_FORMAT_UNDEFINED },
42 | { DRM_FORMAT_BGRX5551, 1, { 16, 0, 0, 0 }, VK_FORMAT_UNDEFINED },
43 | { DRM_FORMAT_ARGB1555, 1, { 16, 0, 0, 0 }, VK_FORMAT_A1R5G5B5_UNORM_PACK16 },
44 | { DRM_FORMAT_ABGR1555, 1, { 16, 0, 0, 0 }, VK_FORMAT_UNDEFINED },
45 | { DRM_FORMAT_RGBA5551, 1, { 16, 0, 0, 0 }, VK_FORMAT_R5G5B5A1_UNORM_PACK16 },
46 | { DRM_FORMAT_BGRA5551, 1, { 16, 0, 0, 0 }, VK_FORMAT_B5G5R5A1_UNORM_PACK16 },
47 | { DRM_FORMAT_RGB565, 1, { 16, 0, 0, 0 }, VK_FORMAT_R5G6B5_UNORM_PACK16 },
48 | { DRM_FORMAT_BGR565, 1, { 16, 0, 0, 0 }, VK_FORMAT_B5G6R5_UNORM_PACK16 },
49 | { DRM_FORMAT_RGB888, 1, { 24, 0, 0, 0 }, VK_FORMAT_B8G8R8_UNORM },
50 | { DRM_FORMAT_BGR888, 1, { 24, 0, 0, 0 }, VK_FORMAT_R8G8B8_UNORM },
51 | { DRM_FORMAT_XRGB8888, 1, { 32, 0, 0, 0 }, VK_FORMAT_UNDEFINED },
52 | { DRM_FORMAT_XBGR8888, 1, { 32, 0, 0, 0 }, VK_FORMAT_UNDEFINED },
53 | { DRM_FORMAT_RGBX8888, 1, { 32, 0, 0, 0 }, VK_FORMAT_UNDEFINED },
54 | { DRM_FORMAT_BGRX8888, 1, { 32, 0, 0, 0 }, VK_FORMAT_UNDEFINED },
55 | { DRM_FORMAT_ARGB8888, 1, { 32, 0, 0, 0 }, VK_FORMAT_B8G8R8A8_UNORM },
56 | { DRM_FORMAT_ABGR8888, 1, { 32, 0, 0, 0 }, VK_FORMAT_R8G8B8A8_UNORM },
57 | { DRM_FORMAT_RGBA8888, 1, { 32, 0, 0, 0 }, VK_FORMAT_UNDEFINED },
58 | { DRM_FORMAT_BGRA8888, 1, { 32, 0, 0, 0 }, VK_FORMAT_UNDEFINED },
59 | };
60 |
61 | const fmt_spec srgb_fourcc_format_table[] = {
62 | { DRM_FORMAT_ARGB8888, 1, { 32, 0, 0, 0 }, VK_FORMAT_B8G8R8A8_SRGB },
63 | { DRM_FORMAT_ABGR8888, 1, { 32, 0, 0, 0 }, VK_FORMAT_R8G8B8A8_SRGB },
64 | };
65 |
66 | const size_t fourcc_format_table_len = NELEMS(fourcc_format_table);
67 | const size_t srgb_fourcc_format_table_len = NELEMS(srgb_fourcc_format_table);
68 |
--------------------------------------------------------------------------------
/util/drm/format_table.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #pragma once
26 |
27 | #include
28 | #include
29 | #include "wsialloc.h"
30 |
31 | /* Define DRM linear modifier for compatibility with older DRM header versions. */
32 | #ifndef DRM_FORMAT_MOD_LINEAR
33 | #define DRM_FORMAT_MOD_LINEAR 0
34 | #endif
35 |
36 | #define NELEMS(x) (sizeof(x) / sizeof(x[0]))
37 |
38 | typedef struct fmt_spec
39 | {
40 | uint32_t drm_format;
41 | uint32_t nr_planes;
42 | uint8_t bpp[WSIALLOC_MAX_PLANES];
43 | VkFormat vk_format;
44 | } fmt_spec;
45 |
46 | extern const fmt_spec fourcc_format_table[];
47 | extern const fmt_spec srgb_fourcc_format_table[];
48 |
49 | extern size_t const fourcc_format_table_len;
50 | extern size_t const srgb_fourcc_format_table_len;
51 |
--------------------------------------------------------------------------------
/util/extension_list.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, 2021-2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #include "extension_list.hpp"
26 | #include "util/custom_allocator.hpp"
27 | #include
28 | #include
29 | #include
30 | #include
31 |
32 | namespace util
33 | {
34 |
35 | extension_list::extension_list(const util::allocator &allocator)
36 | : m_alloc{ allocator }
37 | , m_ext_props(allocator)
38 | {
39 | }
40 |
41 | VkResult extension_list::add(const char *const *extensions, size_t count)
42 | {
43 | auto initial_size = m_ext_props.size();
44 | if (!m_ext_props.try_resize(initial_size + count))
45 | {
46 | return VK_ERROR_OUT_OF_HOST_MEMORY;
47 | }
48 |
49 | for (size_t i = 0; i < count; i++)
50 | {
51 | auto &dst = m_ext_props[initial_size + i];
52 |
53 | const size_t len = strlen(extensions[i]);
54 | bool success = false;
55 | if (len < sizeof(dst.extensionName))
56 | {
57 | int chars_printed = snprintf(dst.extensionName, len + 1, "%s", extensions[i]);
58 | if (chars_printed >= 0 && static_cast(chars_printed) == len)
59 | {
60 | success = true;
61 | }
62 | }
63 |
64 | if (!success)
65 | {
66 | abort();
67 | }
68 | }
69 | return VK_SUCCESS;
70 | }
71 |
72 | VkResult extension_list::add(const char *const *extensions, size_t count, const char *const *extensions_subset,
73 | size_t subset_count)
74 | {
75 | util::vector extensions_to_add(m_alloc);
76 | for (size_t ext_index = 0; ext_index < count; ++ext_index)
77 | {
78 | for (size_t subset_index = 0; subset_index < subset_count; ++subset_index)
79 | {
80 | if (!strcmp(extensions[ext_index], extensions_subset[subset_index]))
81 | {
82 | if (!extensions_to_add.try_push_back(extensions[ext_index]))
83 | {
84 | return VK_ERROR_OUT_OF_HOST_MEMORY;
85 | }
86 | }
87 | }
88 | }
89 |
90 | VkResult result = add(extensions_to_add.data(), extensions_to_add.size());
91 | if (result != VK_SUCCESS)
92 | {
93 | return result;
94 | }
95 |
96 | return VK_SUCCESS;
97 | }
98 |
99 | VkResult extension_list::add(VkExtensionProperties ext_prop)
100 | {
101 | if (!contains(ext_prop.extensionName))
102 | {
103 | if (!m_ext_props.try_push_back(ext_prop))
104 | {
105 | return VK_ERROR_OUT_OF_HOST_MEMORY;
106 | }
107 | }
108 | return VK_SUCCESS;
109 | }
110 |
111 | VkResult extension_list::add(const VkExtensionProperties *props, size_t count)
112 | {
113 | auto initial_size = m_ext_props.size();
114 | if (!m_ext_props.try_resize(initial_size + count))
115 | {
116 | return VK_ERROR_OUT_OF_HOST_MEMORY;
117 | }
118 | for (size_t i = 0; i < count; i++)
119 | {
120 | m_ext_props[initial_size + i] = props[i];
121 | }
122 | return VK_SUCCESS;
123 | }
124 |
125 | VkResult extension_list::add(const extension_list &ext_list)
126 | {
127 | util::vector ext_vect{ m_alloc };
128 | VkResult result = ext_list.get_extension_strings(ext_vect);
129 | if (result != VK_SUCCESS)
130 | {
131 | return result;
132 | }
133 | return add(ext_vect.data(), ext_vect.size());
134 | }
135 |
136 | VkResult extension_list::get_extension_strings(util::vector &out) const
137 | {
138 | size_t old_size = out.size();
139 | size_t new_size = old_size + m_ext_props.size();
140 | if (!out.try_resize(new_size))
141 | {
142 | return VK_ERROR_OUT_OF_HOST_MEMORY;
143 | }
144 |
145 | for (size_t i = old_size; i < new_size; i++)
146 | {
147 | out[i] = m_ext_props[i - old_size].extensionName;
148 | }
149 | return VK_SUCCESS;
150 | }
151 |
152 | bool extension_list::contains(const extension_list &req) const
153 | {
154 | for (const auto &req_ext : req.m_ext_props)
155 | {
156 | if (!contains(req_ext.extensionName))
157 | {
158 | return false;
159 | }
160 | }
161 | return true;
162 | }
163 |
164 | bool extension_list::contains(const char *extension_name) const
165 | {
166 | for (const auto &p : m_ext_props)
167 | {
168 | if (strcmp(p.extensionName, extension_name) == 0)
169 | {
170 | return true;
171 | }
172 | }
173 | return false;
174 | }
175 |
176 | void extension_list::remove(const char *ext)
177 | {
178 | m_ext_props.erase(std::remove_if(m_ext_props.begin(), m_ext_props.end(), [&ext](VkExtensionProperties ext_prop) {
179 | return (strcmp(ext_prop.extensionName, ext) == 0);
180 | }));
181 | }
182 | } // namespace util
183 |
--------------------------------------------------------------------------------
/util/extension_list.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, 2021-2022 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | #pragma once
25 |
26 | #include "custom_allocator.hpp"
27 | #include "helpers.hpp"
28 |
29 | #include
30 | #include
31 |
32 | #include
33 |
34 | namespace util
35 | {
36 |
37 | /**
38 | * @brief A helper class for storing a vector of extension names
39 | *
40 | * @note This class does not store the extension versions.
41 | */
42 | class extension_list : private noncopyable
43 | {
44 | public:
45 | extension_list(const util::allocator &allocator);
46 |
47 | /**
48 | * @brief Get the allocator used to manage the memory of this object.
49 | */
50 | const util::allocator get_allocator() const
51 | {
52 | return m_alloc;
53 | }
54 |
55 | /**
56 | * @brief Append pointers to extension strings to the given vector.
57 | *
58 | * @warning Pointers in the vector are referring to string allocated in this extension_list and will become invalid
59 | * if the extension_list is modified (e.g. by adding/removing elements.)
60 | *
61 | * @param[out] out A vector of C strings to which all extension are appended.
62 | *
63 | * @return Indicates whether the operation was successful. If this is @c VK_ERROR_OUT_OF_HOST_MEMORY,
64 | * then @p out is unmodified.
65 | */
66 | VkResult get_extension_strings(util::vector &out) const;
67 |
68 | /**
69 | * @brief Check if this extension list contains all the extensions listed in req.
70 | */
71 | bool contains(const extension_list &req) const;
72 |
73 | /**
74 | * @brief Check if this extension list contains the extension specified by ext.
75 | */
76 | bool contains(const char *ext) const;
77 |
78 | /**
79 | * @brief Remove an extension from a extension list
80 | */
81 | void remove(const char *ext);
82 |
83 | VkResult add(VkExtensionProperties ext_prop);
84 | VkResult add(const VkExtensionProperties *props, size_t count);
85 | VkResult add(const extension_list &ext_list);
86 | VkResult add(const char *const *extensions, size_t count);
87 |
88 | VkResult add(const char *extension)
89 | {
90 | return add(&extension, 1);
91 | }
92 |
93 | /**
94 | * @brief Perform intersection between extensions and add them to the list.
95 | *
96 | * Adds the extensions from @p extensions that are also part of @p extensions_subset.
97 | *
98 | * @param extensions A list with the names of the extensions to be added.
99 | * @param count Length of the extensions list.
100 | * @param extensions_subset A list with the names of the target extensions.
101 | * @param subset_count Length of the target list.
102 | *
103 | * @return VK_SUCCESS on success, otherwise an error.
104 | */
105 | VkResult add(const char *const *extensions, size_t count, const char *const *extensions_subset, size_t subset_count);
106 |
107 | private:
108 | util::allocator m_alloc;
109 |
110 | /**
111 | * @note We are using VkExtensionProperties to store the extension name only
112 | */
113 | util::vector m_ext_props;
114 | };
115 | } // namespace util
116 |
--------------------------------------------------------------------------------
/util/file_descriptor.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021, 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /**
26 | * @file
27 | *
28 | * @brief Contains the defintions of file descriptor utilities.
29 | */
30 |
31 | #pragma once
32 |
33 | #include
34 | #include
35 |
36 | #include "helpers.hpp"
37 |
38 | namespace util
39 | {
40 |
41 | /**
42 | * Manages a POSIX file descriptor.
43 | */
44 | class fd_owner : private noncopyable
45 | {
46 | public:
47 | fd_owner() = default;
48 | fd_owner(int fd)
49 | : fd_handle{ fd }
50 | {
51 | }
52 |
53 | fd_owner(fd_owner &&rhs)
54 | {
55 | *this = std::move(rhs);
56 | }
57 |
58 | fd_owner &operator=(fd_owner &&rhs)
59 | {
60 | std::swap(fd_handle, rhs.fd_handle);
61 | return *this;
62 | }
63 |
64 | ~fd_owner()
65 | {
66 | if (is_valid())
67 | {
68 | close(fd_handle);
69 | }
70 | }
71 |
72 | int get() const
73 | {
74 | return fd_handle;
75 | }
76 |
77 | bool is_valid() const
78 | {
79 | return fd_handle >= 0;
80 | }
81 |
82 | private:
83 | int fd_handle{ -1 };
84 | };
85 |
86 | } /* namespace util */
87 |
--------------------------------------------------------------------------------
/util/format_modifiers.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022, 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #include "format_modifiers.hpp"
26 | #include "layer/private_data.hpp"
27 |
28 | namespace util
29 | {
30 |
31 | VkResult get_drm_format_properties(VkPhysicalDevice physical_device, VkFormat format,
32 | util::vector &format_props_list)
33 | {
34 | auto &instance_data = layer::instance_private_data::get(physical_device);
35 |
36 | VkDrmFormatModifierPropertiesListEXT format_modifier_props = {};
37 | format_modifier_props.sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT;
38 |
39 | VkFormatProperties2KHR format_props = {};
40 | format_props.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR;
41 | format_props.pNext = &format_modifier_props;
42 |
43 | instance_data.disp.GetPhysicalDeviceFormatProperties2KHR(physical_device, format, &format_props);
44 |
45 | if (!format_props_list.try_resize(format_modifier_props.drmFormatModifierCount))
46 | {
47 | return VK_ERROR_OUT_OF_HOST_MEMORY;
48 | }
49 |
50 | format_modifier_props.pDrmFormatModifierProperties = format_props_list.data();
51 | instance_data.disp.GetPhysicalDeviceFormatProperties2KHR(physical_device, format, &format_props);
52 | return VK_SUCCESS;
53 | }
54 | } /* namespace util */
55 |
--------------------------------------------------------------------------------
/util/format_modifiers.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #pragma once
26 |
27 | #include
28 | #include "custom_allocator.hpp"
29 |
30 | namespace util
31 | {
32 |
33 | /**
34 | * @brief Get the properties a format has when combined with a DRM modifier.
35 | *
36 | * @param physical_device The physical device
37 | * @param format The target format.
38 | * @param[out] format_props_list A vector which will store the supported properties
39 | * for every modifier.
40 | *
41 | * @return VK_SUCCESS on success. VK_ERROR_OUT_OF_HOST_MEMORY is returned when
42 | * the host gets out of memory.
43 | */
44 | VkResult get_drm_format_properties(VkPhysicalDevice physical_device, VkFormat format,
45 | util::vector &format_props_list);
46 |
47 | } /* namespace util */
48 |
--------------------------------------------------------------------------------
/util/helpers.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021-2022, 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /**
26 | * @file helpers.hpp
27 | *
28 | * @brief Contains common utility functions used across the project.
29 | */
30 |
31 | #pragma once
32 |
33 | #include
34 | #include "log.hpp"
35 |
36 | /*
37 | * Conditional return statement. This allows functions to return early for
38 | * failing Vulkan commands with a terse syntax.
39 | *
40 | * Example usage:
41 | *
42 | * VkResult foo()
43 | * {
44 | * TRY(vkCommand());
45 | * return VK_SUCCESS;
46 | * }
47 | *
48 | * The above is equivalent to:
49 | *
50 | * VkResult foo()
51 | * {
52 | * VkResult result = vkCommand();
53 | * if (result != VK_SUCCESS)
54 | * {
55 | * return result;
56 | * }
57 | * return VK_SUCCESS;
58 | * }
59 | */
60 | #define TRY_HANDLER(expression, do_log, ...) \
61 | do \
62 | { \
63 | VkResult try_result = expression; \
64 | if (try_result != VK_SUCCESS) \
65 | { \
66 | if (do_log) \
67 | { \
68 | WSI_LOG_ERROR(__VA_ARGS__); \
69 | } \
70 | return try_result; \
71 | } \
72 | } while (0)
73 |
74 | #define TRY(expression) TRY_HANDLER(expression, false, "PLACEHOLDER")
75 | #define TRY_LOG_CALL(expression) TRY_HANDLER(expression, true, #expression)
76 | #define TRY_LOG(expression, ...) TRY_HANDLER(expression, true, __VA_ARGS__)
77 |
78 | namespace util
79 | {
80 | template
81 | const T *find_extension(VkStructureType sType, const void *pNext)
82 | {
83 | auto entry = reinterpret_cast(pNext);
84 | while (entry && entry->sType != sType)
85 | {
86 | entry = entry->pNext;
87 | }
88 | return reinterpret_cast(entry);
89 | }
90 |
91 | template
92 | T *find_extension(VkStructureType sType, void *pNext)
93 | {
94 | auto entry = reinterpret_cast(pNext);
95 | while (entry && entry->sType != sType)
96 | {
97 | entry = entry->pNext;
98 | }
99 | return reinterpret_cast(entry);
100 | }
101 |
102 | template
103 | inline T shallow_copy_extension(const T *structure_to_copy)
104 | {
105 | T shallow_copy = *structure_to_copy;
106 | shallow_copy.pNext = nullptr;
107 |
108 | return shallow_copy;
109 | }
110 |
111 | class noncopyable
112 | {
113 | protected:
114 | noncopyable() = default;
115 | ~noncopyable() = default;
116 |
117 | private:
118 | noncopyable(const noncopyable &) = delete;
119 | noncopyable &operator=(const noncopyable &) = delete;
120 | };
121 |
122 | static constexpr uint32_t MAX_PLANES = 4;
123 |
124 | /**
125 | * @brief Helper variable for plane image aspect flag bits.
126 | */
127 | const VkImageAspectFlagBits PLANE_FLAG_BITS[MAX_PLANES] = {
128 | VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT,
129 | VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT,
130 | VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT,
131 | VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT,
132 | };
133 |
134 | } // namespace util
135 |
--------------------------------------------------------------------------------
/util/log.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021-2023 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #include "log.hpp"
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 |
34 | namespace util
35 | {
36 |
37 | #ifndef NDEBUG
38 |
39 | /**
40 | * @brief check if a log level is enabled, and print it
41 | */
42 | static bool check_and_print_log_level(int level)
43 | {
44 | struct log_state
45 | {
46 | int level = WSI_DEFAULT_LOG_LEVEL;
47 | log_state()
48 | {
49 | if (const char *env = std::getenv("VULKAN_WSI_DEBUG_LEVEL"))
50 | {
51 | std::from_chars(env, env + std::strlen(env), level);
52 | }
53 | }
54 | };
55 | static log_state state;
56 |
57 | bool result = level <= state.level;
58 | if (result)
59 | {
60 | switch (level)
61 | {
62 | case 0:
63 | /* Reserved for no logging */
64 | break;
65 | case 1:
66 | std::fprintf(stderr, "ERROR");
67 | break;
68 | case 2:
69 | std::fprintf(stderr, "WARNING");
70 | break;
71 | case 3:
72 | std::fprintf(stderr, "INFO");
73 | break;
74 | default:
75 | std::fprintf(stderr, "LEVEL_%d", level);
76 | break;
77 | }
78 | }
79 | return result;
80 | }
81 |
82 | void wsi_log_message(int level, const char *file, int line, const char *format, ...)
83 | {
84 | if (check_and_print_log_level(level))
85 | {
86 | std::fprintf(stderr, "(%s:%d): ", file, line);
87 | std::va_list args;
88 | va_start(args, format);
89 | std::vfprintf(stderr, format, args);
90 | va_end(args);
91 | std::putc('\n', stderr);
92 | }
93 | }
94 |
95 | #endif
96 |
97 | } /* namespace util */
98 |
--------------------------------------------------------------------------------
/util/log.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021-2023 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #pragma once
26 | namespace util
27 | {
28 | #define WSI_DEFAULT_LOG_LEVEL 1
29 |
30 | /**
31 | * @brief Log a message to a certain log level
32 | *
33 | * @details For the log level, we use a bigger integer to represent an increased
34 | * level of verbosity. If this is not specified, the log level is default to 1.
35 | * We use a "staircase" approach with respect to printing logs. We print all log
36 | * messages equal or below the log level set, e.g. if VULKAN_WSI_DEBUG_LEVEL
37 | * is set to 2, messages with log level 1 and 2 are printed. Please note that
38 | * the newline character '\n' is automatically appended.
39 | *
40 | * @param[in] level The log level of this message, you can set an arbitary
41 | * integer however please refer to the included macros for
42 | * the sensible defaults.
43 | * @param[in] file The source file name (``__FILE__``)
44 | * @param[in] line The source file line number (``__LINE__``)
45 | * @param[in] format A C-style formatting string.
46 | */
47 |
48 | void wsi_log_message(int level, const char *file, int line, const char *format, ...)
49 | #ifdef __GNUC__
50 | __attribute__((format(printf, 4, 5)))
51 | #endif
52 | ;
53 |
54 | #ifdef NDEBUG
55 | static constexpr bool wsi_log_enable = false;
56 | #else
57 | static constexpr bool wsi_log_enable = true;
58 | #endif
59 |
60 | #define WSI_LOG(level, ...) \
61 | do \
62 | { \
63 | if (::util::wsi_log_enable) \
64 | ::util::wsi_log_message(level, __FILE__, __LINE__, __VA_ARGS__); \
65 | } while (0)
66 |
67 | #define WSI_LOG_ERROR(...) WSI_LOG(1, __VA_ARGS__)
68 | #define WSI_LOG_WARNING(...) WSI_LOG(2, __VA_ARGS__)
69 | #define WSI_LOG_INFO(...) WSI_LOG(3, __VA_ARGS__)
70 |
71 | } /* namespace util */
72 |
--------------------------------------------------------------------------------
/util/macros.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021, 2023-2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /**
26 | * @file macros.hpp
27 | *
28 | * @brief Contains useful utility macros used across the project.
29 | */
30 | #include
31 |
32 | /*
33 | * Macros that are used to mark functions signatures.
34 | *
35 | * VWL_VKAPI_CALL - Replaces the return type of the function. Use to mark functions to use the expected
36 | * Vulkan calling conventions.
37 | * VWL_CAPI_CALL - Replaces the return type of the function. Use to mark other non-Vulkan functions
38 | * that should use the C calling convention, such as callbacks implemented in C++ that
39 | * are used by C code.
40 | * VWL_API_POST - Placed at the end of the function signature. These will typically be
41 | * functions that need to be callable from C.
42 | * VWL_VKAPI_EXPORT - Marks that the symbol should use the "default" visibility
43 | */
44 | #define VWL_VKAPI_CALL(ret_type) extern "C" VKAPI_ATTR ret_type VKAPI_CALL
45 | #define VWL_CAPI_CALL(ret_type) extern "C" ret_type
46 | #define VWL_API_POST noexcept
47 |
48 | #if defined(__GNUC__) && __GNUC__ >= 4
49 | #define VWL_VKAPI_EXPORT __attribute__((visibility("default")))
50 | #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)
51 | #define VWL_VKAPI_EXPORT __attribute__((visibility("default")))
52 | #else
53 | #define VWL_VKAPI_EXPORT
54 | #endif
55 |
56 | /* Unused parameter macro */
57 | #define UNUSED(x) ((void)(x))
--------------------------------------------------------------------------------
/util/platform_set.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021-2022 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #pragma once
26 |
27 | #include
28 | #include
29 |
30 | #include
31 |
32 | namespace util
33 | {
34 |
35 | /**
36 | * @brief Set of WSI platforms.
37 | * @note This could be implemented via std::unordered_set, but would require handling allocation callbacks and would
38 | * therefore be less convenient to use. Instead, we can store all info in the bits of uint64_t.
39 | */
40 | class wsi_platform_set
41 | {
42 | public:
43 | void add(VkIcdWsiPlatform p)
44 | {
45 | m_platforms |= (static_cast(1) << to_int(p));
46 | }
47 |
48 | bool contains(VkIcdWsiPlatform p) const
49 | {
50 | return (m_platforms & (static_cast(1) << to_int(p))) != 0;
51 | }
52 |
53 | bool empty() const
54 | {
55 | return m_platforms == 0;
56 | }
57 |
58 | private:
59 | /**
60 | * @brief Convert a VkIcdWsiPlatform to an integer between 0-63.
61 | */
62 | static int to_int(VkIcdWsiPlatform p)
63 | {
64 | assert(static_cast(p) >= 0 && static_cast(p) < 64);
65 | return static_cast(p);
66 | }
67 |
68 | uint64_t m_platforms = 0;
69 | };
70 |
71 | } /* namespace util */
72 |
--------------------------------------------------------------------------------
/util/ring_buffer.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021-2022 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #include
26 | #include
27 | #include
28 |
29 | namespace util
30 | {
31 |
32 | template
33 | class ring_buffer
34 | {
35 | public:
36 | /**
37 | * @brief Return maximum capacity of the ring buffer.
38 | */
39 | constexpr std::size_t capacity()
40 | {
41 | return N;
42 | }
43 |
44 | /**
45 | * @brief Return current size of the ring buffer.
46 | */
47 | std::size_t size() const
48 | {
49 | return m_size;
50 | }
51 |
52 | /**
53 | * @brief Places item into next slot of the ring buffer.
54 | * @return Boolean to indicate success or failure.
55 | */
56 | template
57 | bool push_back(U &&item)
58 | {
59 | if (size() == capacity())
60 | {
61 | return false;
62 | }
63 |
64 | m_data[(m_begin + m_size) % N].emplace(std::forward(item));
65 | ++m_size;
66 |
67 | return true;
68 | }
69 |
70 | /**
71 | * @brief Gets a pointer to the item at the starting index of the ring buffer.
72 | */
73 | T *front()
74 | {
75 | return get(m_begin);
76 | }
77 |
78 | /**
79 | * @brief Gets a pointer to the item that was last placed into the ring buffer.
80 | */
81 | T *back()
82 | {
83 | return get((m_begin + m_size + N - 1) % N);
84 | }
85 |
86 | /**
87 | * @brief Pop the front of the ring buffer.
88 | *
89 | * Item at the starting index of the ring buffer is returned. The slot is subsequently emptied. The starting index of
90 | * the ring buffer increments by 1.
91 | *
92 | * @return Item wrapped in an optional.
93 | */
94 | std::optional pop_front()
95 | {
96 | if (size() == 0)
97 | {
98 | return std::nullopt;
99 | }
100 |
101 | std::optional value = std::move(m_data[m_begin]);
102 |
103 | m_begin = (m_begin + 1) % N;
104 | --m_size;
105 |
106 | return value;
107 | }
108 |
109 | private:
110 | T *get(std::size_t index)
111 | {
112 | if (m_data[index].has_value())
113 | {
114 | return std::addressof(m_data[index].value());
115 | }
116 | else
117 | {
118 | return nullptr;
119 | }
120 | }
121 |
122 | std::array, N> m_data{};
123 |
124 | // Marks the start index of the ring buffer.
125 | std::size_t m_begin{};
126 |
127 | // The number of entries in the ring buffer from the start index.
128 | std::size_t m_size{};
129 | };
130 |
131 | } /* namespace util */
132 |
--------------------------------------------------------------------------------
/util/timed_semaphore.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017, 2019, 2021-2022 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #include
26 | #include
27 |
28 | #include "timed_semaphore.hpp"
29 |
30 | namespace util
31 | {
32 |
33 | VkResult timed_semaphore::init(unsigned count)
34 | {
35 | int res;
36 |
37 | m_count = count;
38 |
39 | pthread_condattr_t attr;
40 | res = pthread_condattr_init(&attr);
41 | /* the only failure that can occur is ENOMEM */
42 | assert(res == 0 || res == ENOMEM);
43 | if (res != 0)
44 | {
45 | return VK_ERROR_OUT_OF_HOST_MEMORY;
46 | }
47 |
48 | res = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
49 | /* only programming error can cause _setclock to fail */
50 | assert(res == 0);
51 |
52 | res = pthread_cond_init(&m_cond, &attr);
53 | /* the only failure that can occur that is not programming error is ENOMEM */
54 | assert(res == 0 || res == ENOMEM);
55 | if (res != 0)
56 | {
57 | res = pthread_condattr_destroy(&attr);
58 | assert(res == 0);
59 | return VK_ERROR_OUT_OF_HOST_MEMORY;
60 | }
61 |
62 | res = pthread_condattr_destroy(&attr);
63 | /* only programming error can cause _destroy to fail */
64 | assert(res == 0);
65 |
66 | res = pthread_mutex_init(&m_mutex, nullptr);
67 | /* only programming errors can result in failure */
68 | assert(res == 0);
69 |
70 | initialized = true;
71 |
72 | return VK_SUCCESS;
73 | }
74 |
75 | timed_semaphore::~timed_semaphore()
76 | {
77 | int res;
78 | (void)res; /* unused when NDEBUG */
79 |
80 | if (initialized)
81 | {
82 | res = pthread_cond_destroy(&m_cond);
83 | assert(res == 0); /* only programming error (EBUSY, EINVAL) */
84 |
85 | res = pthread_mutex_destroy(&m_mutex);
86 | assert(res == 0); /* only programming error (EBUSY, EINVAL) */
87 | }
88 | }
89 |
90 | VkResult timed_semaphore::wait(uint64_t timeout)
91 | {
92 | VkResult retval = VK_SUCCESS;
93 | int res;
94 |
95 | assert(initialized);
96 |
97 | res = pthread_mutex_lock(&m_mutex);
98 | assert(res == 0); /* only fails with programming error (EINVAL) */
99 |
100 | if (m_count == 0)
101 | {
102 | switch (timeout)
103 | {
104 | case 0:
105 | retval = VK_NOT_READY;
106 | break;
107 | case UINT64_MAX:
108 | res = pthread_cond_wait(&m_cond, &m_mutex);
109 | assert(res == 0); /* only fails with programming error (EINVAL) */
110 |
111 | break;
112 | default:
113 | struct timespec diff = { /* narrowing casts */
114 | static_cast(timeout / (1000 * 1000 * 1000)),
115 | static_cast(timeout % (1000 * 1000 * 1000))
116 | };
117 |
118 | struct timespec now = {};
119 | res = clock_gettime(CLOCK_MONOTONIC, &now);
120 | assert(res == 0); /* only fails with programming error (EINVAL, EFAULT, EPERM) */
121 |
122 | /* add diff to now, handling overflow */
123 | struct timespec end = { now.tv_sec + diff.tv_sec, now.tv_nsec + diff.tv_nsec };
124 |
125 | if (end.tv_nsec >= 1000 * 1000 * 1000)
126 | {
127 | end.tv_nsec -= 1000 * 1000 * 1000;
128 | end.tv_sec++;
129 | }
130 |
131 | res = pthread_cond_timedwait(&m_cond, &m_mutex, &end);
132 | /* only fails with programming error, other than timeout */
133 | assert(res == 0 || res == ETIMEDOUT);
134 | if (res != 0)
135 | {
136 | retval = VK_TIMEOUT;
137 | }
138 | }
139 | }
140 | if (retval == VK_SUCCESS)
141 | {
142 | assert(m_count > 0);
143 | m_count--;
144 | }
145 | res = pthread_mutex_unlock(&m_mutex);
146 | assert(res == 0); /* only fails with programming error (EPERM) */
147 |
148 | return retval;
149 | }
150 |
151 | void timed_semaphore::post()
152 | {
153 | int res;
154 | (void)res; /* unused when NDEBUG */
155 |
156 | assert(initialized);
157 |
158 | res = pthread_mutex_lock(&m_mutex);
159 | assert(res == 0); /* only fails with programming error (EINVAL) */
160 |
161 | m_count++;
162 |
163 | res = pthread_cond_signal(&m_cond);
164 | assert(res == 0); /* only fails with programming error (EINVAL) */
165 |
166 | res = pthread_mutex_unlock(&m_mutex);
167 | assert(res == 0); /* only fails with programming error (EPERM) */
168 | }
169 |
170 | } /* namespace util */
171 |
--------------------------------------------------------------------------------
/util/timed_semaphore.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017, 2019, 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /**
26 | * @file timed_semaphore.hpp
27 | *
28 | * @brief Contains the class definition for a semaphore with a relative timedwait
29 | *
30 | * sem_timedwait takes an absolute time, based on CLOCK_REALTIME. Simply
31 | * taking the current time and adding on a relative timeout is not correct,
32 | * as the system time may change, resulting in an incorrect timeout period
33 | * (potentially by a significant amount).
34 | *
35 | * We therefore have to re-engineer semaphores using condition variables.
36 | *
37 | * This code does not use the C++ standard library to avoid exceptions.
38 | */
39 |
40 | #pragma once
41 |
42 | extern "C" {
43 | #include
44 | }
45 |
46 | #include
47 | #include "helpers.hpp"
48 |
49 | namespace util
50 | {
51 |
52 | /**
53 | * brief semaphore with a safe relative timed wait
54 | *
55 | * sem_timedwait takes an absolute time, based on CLOCK_REALTIME. Simply
56 | * taking the current time and adding on a relative timeout is not correct,
57 | * as the system time may change, resulting in an incorrect timeout period
58 | * (potentially by a significant amount).
59 | *
60 | * We therefore have to re-engineer semaphores using condition variables.
61 | *
62 | * This code does not use the C++ standard library to avoid exceptions.
63 | */
64 | class timed_semaphore : private noncopyable
65 | {
66 | public:
67 | ~timed_semaphore();
68 | timed_semaphore()
69 | : initialized(false){};
70 |
71 | /**
72 | * @brief initializes the semaphore
73 | *
74 | * @param count initial value of the semaphore
75 | * @retval VK_ERROR_OUT_OF_HOST_MEMORY out of memory condition from pthread calls
76 | * @retval VK_SUCCESS on success
77 | */
78 | VkResult init(unsigned count);
79 |
80 | /**
81 | * @brief decrement semaphore, waiting (with timeout) if the value is 0
82 | *
83 | * @param timeout time to wait (ns). 0 doesn't block, UINT64_MAX waits indefinately.
84 | * @retval VK_TIMEOUT timeout was non-zero and reached the timeout
85 | * @retval VK_NOT_READY timeout was zero and count is 0
86 | * @retval VK_SUCCESS on success
87 | */
88 | VkResult wait(uint64_t timeout);
89 |
90 | /**
91 | * @brief increment semaphore, potentially unblocking a waiting thread
92 | */
93 | void post();
94 |
95 | private:
96 | /**
97 | * @brief true if the semaphore has been initialized
98 | *
99 | * Determines if the destructor should cleanup the mutex and cond.
100 | */
101 | bool initialized;
102 | /**
103 | * @brief semaphore value
104 | */
105 | unsigned m_count;
106 |
107 | pthread_mutex_t m_mutex;
108 | pthread_cond_t m_cond;
109 | };
110 |
111 | } /* namespace util */
112 |
--------------------------------------------------------------------------------
/util/unordered_map.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021-2022, 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | #pragma once
25 |
26 | #include
27 | #include
28 |
29 | #include "custom_allocator.hpp"
30 | #include "helpers.hpp"
31 |
32 | namespace util
33 | {
34 | /**
35 | * @brief This utility class has the same purpose as std::unordered_map, but
36 | * ensures that the operations that could result in out of memory
37 | * exceptions don't throw them and also ensures that the memory can
38 | * only be allocated by an custom_allocator.
39 | */
40 | template , typename Comparator = std::equal_to,
41 | typename Allocator = util::custom_allocator>>
42 | class unordered_map : public std::unordered_map, private noncopyable
43 | {
44 | using base = std::unordered_map;
45 | using size_type = typename base::size_type;
46 | using iterator = typename base::iterator;
47 |
48 | public:
49 | /**
50 | * Delete all member functions that can cause allocation failure by throwing std::bad_alloc.
51 | */
52 | Value &operator[](const Key &key) = delete;
53 | Value &operator[](Key &&key) = delete;
54 |
55 | void insert() = delete;
56 | void emplace() = delete;
57 | void emplace_hint() = delete;
58 | void reserve() = delete;
59 | void rehash() = delete;
60 |
61 | /**
62 | * @brief Construct a new unordered map object with a custom allocator.
63 | *
64 | * @param allocator The allocator that will be used.
65 | */
66 | explicit unordered_map(util::custom_allocator> allocator)
67 | : base(allocator)
68 | {
69 | }
70 |
71 | /**
72 | * @brief Like std::unordered_map.insert but doesn't throw on out of memory errors.
73 | *
74 | * @param value The value to insert in the map.
75 | * @return std::optional> If successful, the optional will
76 | * contain the same return value as from std::unordered_map.insert, otherwise
77 | * if out of memory, the function returns std::nullopt.
78 | */
79 | std::optional> try_insert(const std::pair &value)
80 | {
81 | try
82 | {
83 | return { base::insert(value) };
84 | }
85 | catch (std::bad_alloc &e)
86 | {
87 | return std::nullopt;
88 | }
89 | }
90 |
91 | /**
92 | * @brief Like std::unordered_map.reserve but doesn't throw on out of memory errors.
93 | *
94 | * @param size The new capacity of the container. Same as std::unordered_map.reserve.
95 | * @return true If the container was resized successfuly.
96 | * @return false If the host has run out of memory
97 | */
98 | bool try_reserve(size_type size)
99 | {
100 | try
101 | {
102 | base::reserve(size);
103 | return true;
104 | }
105 | catch (std::bad_alloc &e)
106 | {
107 | return false;
108 | }
109 | }
110 |
111 | /**
112 | * @brief Like std::unordered_map.rehash but doesn't throw on out of memory errors.
113 | *
114 | * @param count Number of buckets. Same as std::unordered_map.rehash.
115 | * @return true If the container was rehashed successfuly.
116 | * @return false If the host has run out of memory
117 | */
118 | bool try_rehash(size_type count)
119 | {
120 | try
121 | {
122 | base::rehash(count);
123 | return true;
124 | }
125 | catch (std::bad_alloc &e)
126 | {
127 | return false;
128 | }
129 | }
130 | };
131 | } /* namespace util */
132 |
--------------------------------------------------------------------------------
/util/unordered_set.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021-2022, 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | #pragma once
25 |
26 | #include
27 | #include
28 |
29 | #include "custom_allocator.hpp"
30 | #include "helpers.hpp"
31 |
32 | namespace util
33 | {
34 | /**
35 | * @brief This utility class has the same purpose as std::unordered_set, but
36 | * ensures that the operations that could result in out of memory
37 | * exceptions don't throw them and also ensures that the memory can
38 | * only be allocated by an custom_allocator.
39 | */
40 | template , typename Comparator = std::equal_to,
41 | typename Allocator = util::custom_allocator>
42 | class unordered_set : public std::unordered_set, private noncopyable
43 | {
44 | using value_type = Key;
45 | using base = std::unordered_set;
46 | using size_type = typename base::size_type;
47 | using iterator = typename base::iterator;
48 |
49 | public:
50 | /**
51 | * Delete all member functions that can cause allocation failure by throwing std::bad_alloc.
52 | */
53 | void insert() = delete;
54 | void emplace() = delete;
55 | void emplace_hint() = delete;
56 | void rehash() = delete;
57 | void reserve() = delete;
58 |
59 | /**
60 | * @brief Construct a new unordered set object with a custom allocator.
61 | *
62 | * @param allocator The allocator that will be used.
63 | */
64 | explicit unordered_set(util::custom_allocator allocator)
65 | : base(allocator)
66 | {
67 | }
68 |
69 | /**
70 | * @brief Like std::unordered_set.insert but doesn't throw on out of memory errors.
71 | *
72 | * @param value The value to insert in the map.
73 | * @return std::optional> If successful, the optional will
74 | * contain the same return value as from std::unordered_set.insert, otherwise
75 | * if out of memory, the function returns std::nullopt.
76 | */
77 | std::optional> try_insert(const value_type &value) noexcept
78 | {
79 | try
80 | {
81 | return { base::insert(value) };
82 | }
83 | catch (const std::bad_alloc &e)
84 | {
85 | return std::nullopt;
86 | }
87 | }
88 |
89 | /**
90 | * @brief Like std::unordered_set.reserve but doesn't throw on out of memory errors.
91 | *
92 | * @param size The new capacity of the container. Same as std::unordered_set.reserve.
93 | * @return true If the container was resized successfuly.
94 | * @return false If the host has run out of memory
95 | */
96 | bool try_reserve(size_type size)
97 | {
98 | try
99 | {
100 | base::reserve(size);
101 | return true;
102 | }
103 | catch (std::bad_alloc &e)
104 | {
105 | return false;
106 | }
107 | }
108 |
109 | /**
110 | * @brief Like std::unordered_set.rehash but doesn't throw on out of memory errors.
111 | *
112 | * @param count Number of buckets. Same as std::unordered_set.rehash.
113 | * @return true If the container was rehashed successfuly.
114 | * @return false If the host has run out of memory
115 | */
116 | bool try_rehash(size_type count)
117 | {
118 | try
119 | {
120 | base::rehash(count);
121 | return true;
122 | }
123 | catch (std::bad_alloc &e)
124 | {
125 | return false;
126 | }
127 | }
128 | };
129 | } // namespace util
130 |
--------------------------------------------------------------------------------
/wsi/compatible_present_modes.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /**
26 | * @file compatible_present_modes.hpp
27 | *
28 | * @brief Contains functions for handling compatibility between different presentation modes
29 | */
30 |
31 | #pragma once
32 |
33 | #include
34 | #include
35 | #include
36 |
37 | namespace wsi
38 | {
39 |
40 | static constexpr uint32_t MAX_PRESENT_MODES = 6;
41 | struct present_mode_compatibility
42 | {
43 | /* Presentation mode */
44 | VkPresentModeKHR present_mode;
45 |
46 | /* Number of presentation modes compatible */
47 | uint32_t present_mode_count;
48 |
49 | /* Stores the compatible presentation modes */
50 | std::array compatible_present_modes;
51 | };
52 |
53 | template
54 | class compatible_present_modes
55 | {
56 | public:
57 | compatible_present_modes()
58 | {
59 | }
60 |
61 | compatible_present_modes(std::array present_mode_compatibilites)
62 | : m_present_mode_compatibilites(present_mode_compatibilites)
63 | {
64 | }
65 |
66 | /**
67 | * @brief Common function for handling VkSurfacePresentModeCompatibilityEXT if it exists in the pNext chain of VkSurfaceCapabilities2KHR.
68 | *
69 | * If pSurfaceInfo contains a VkSurfacePresentModeEXT struct in its pNext chain, and pSurfaceCapabilities contains a VkSurfacePresentModeCompatibilityEXT struct
70 | * then this function fills the VkSurfacePresentModeCompatibilityEXT struct with the presentation modes that are compatible with the presentation mode specified
71 | * in the VkSurfacePresentModeEXT struct.
72 | *
73 | * @param pSurfaceInfo Pointer to surface info that may or may not contain a VkSurfacePresentModeEXT.
74 | * @param pSurfaceCapabilities Pointer to surface capabilities that may or may not contain a VkSurfacePresentModeCompatibilityEXT struct.
75 | *
76 | */
77 | void get_surface_present_mode_compatibility_common(const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
78 | VkSurfaceCapabilities2KHR *pSurfaceCapabilities)
79 | {
80 | auto surface_present_mode =
81 | util::find_extension(VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_EXT, pSurfaceInfo);
82 | auto surface_present_mode_compatibility = util::find_extension(
83 | VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_COMPATIBILITY_EXT, pSurfaceCapabilities);
84 |
85 | if (surface_present_mode == nullptr || surface_present_mode_compatibility == nullptr)
86 | {
87 | return;
88 | }
89 |
90 | VkPresentModeKHR present_mode = surface_present_mode->presentMode;
91 | auto it = std::find_if(m_present_mode_compatibilites.begin(), m_present_mode_compatibilites.end(),
92 | [present_mode](present_mode_compatibility p) { return p.present_mode == present_mode; });
93 | if (it == m_present_mode_compatibilites.end())
94 | {
95 | WSI_LOG_ERROR("Querying compatible presentation mode support for a presentation mode that is not supported.");
96 | return;
97 | }
98 | const present_mode_compatibility &surface_supported_compatibility = *it;
99 |
100 | if (surface_present_mode_compatibility->pPresentModes == nullptr)
101 | {
102 | surface_present_mode_compatibility->presentModeCount = surface_supported_compatibility.present_mode_count;
103 | return;
104 | }
105 |
106 | surface_present_mode_compatibility->presentModeCount = std::min(
107 | surface_present_mode_compatibility->presentModeCount, surface_supported_compatibility.present_mode_count);
108 | std::copy(surface_supported_compatibility.compatible_present_modes.begin(),
109 | surface_supported_compatibility.compatible_present_modes.begin() +
110 | surface_present_mode_compatibility->presentModeCount,
111 | surface_present_mode_compatibility->pPresentModes);
112 | }
113 |
114 | /**
115 | * @brief Common function for handling checking whether a present mode is compatible with another.
116 | *
117 | * @param present_mode_a First present mode.
118 | * @param present_mode_b Second present mode to compare against.
119 | *
120 | * @return true if compatible, false otherwise.
121 | */
122 | bool is_compatible_present_modes(VkPresentModeKHR present_mode_a, VkPresentModeKHR present_mode_b)
123 | {
124 | auto it =
125 | std::find_if(m_present_mode_compatibilites.begin(), m_present_mode_compatibilites.end(),
126 | [present_mode_a](present_mode_compatibility p) { return p.present_mode == present_mode_a; });
127 | if (it == m_present_mode_compatibilites.end())
128 | {
129 | WSI_LOG_ERROR("Querying compatible presentation mode support for a presentation mode that is not supported.");
130 | return false;
131 | }
132 |
133 | const present_mode_compatibility &present_mode_comp = *it;
134 | auto present_mode_it =
135 | std::find_if(present_mode_comp.compatible_present_modes.begin(),
136 | present_mode_comp.compatible_present_modes.begin() + present_mode_comp.present_mode_count,
137 | [present_mode_b](VkPresentModeKHR p) { return p == present_mode_b; });
138 | return present_mode_it != present_mode_comp.compatible_present_modes.end();
139 | }
140 |
141 | private:
142 | std::array m_present_mode_compatibilites;
143 | };
144 |
145 | } // namespace wsi
146 |
--------------------------------------------------------------------------------
/wsi/display/surface.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /** @file
26 | * @brief Implementation of a headless WSI Surface
27 | */
28 |
29 | #include "surface.hpp"
30 | #include "swapchain.hpp"
31 | #include "surface_properties.hpp"
32 |
33 | namespace wsi
34 | {
35 | namespace display
36 | {
37 |
38 | surface::surface(drm_display_mode *display_mode, VkExtent2D extent)
39 | : m_display_mode(display_mode)
40 | , m_extent(extent)
41 | {
42 | }
43 |
44 | wsi::surface_properties &surface::get_properties()
45 | {
46 | return m_surface_properties;
47 | }
48 |
49 | util::unique_ptr surface::allocate_swapchain(layer::device_private_data &dev_data,
50 | const VkAllocationCallbacks *allocator)
51 | {
52 | util::allocator alloc{ dev_data.get_allocator(), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT, allocator };
53 | return util::unique_ptr(alloc.make_unique(dev_data, allocator, *this));
54 | }
55 |
56 | VkExtent2D surface::get_extent() const
57 | {
58 | return m_extent;
59 | }
60 |
61 | drm_display_mode *surface::get_display_mode()
62 | {
63 | return m_display_mode;
64 | }
65 |
66 | } /* namespace display */
67 | } /* namespace wsi */
68 |
--------------------------------------------------------------------------------
/wsi/display/surface.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /** @file
26 | * @brief Definitions for a headless WSI Surface
27 | */
28 |
29 | #pragma once
30 |
31 | #include "wsi/surface.hpp"
32 | #include "surface_properties.hpp"
33 | #include "drm_display.hpp"
34 |
35 | namespace wsi
36 | {
37 | namespace display
38 | {
39 |
40 | class surface : public wsi::surface
41 | {
42 | public:
43 | /**
44 | * @brief Construct a new surface.
45 | *
46 | * @param mode The display mode to be used with the surface.
47 | * @param extent The extent of the surface.
48 | */
49 | surface(drm_display_mode *mode, VkExtent2D extent);
50 |
51 | wsi::surface_properties &get_properties() override;
52 | util::unique_ptr allocate_swapchain(layer::device_private_data &dev_data,
53 | const VkAllocationCallbacks *allocator) override;
54 |
55 | /**
56 | * @brief Get the extent of the surface.
57 | */
58 | VkExtent2D get_extent() const;
59 |
60 | /**
61 | * @brief Get the display mode associated with this surface.
62 | */
63 | drm_display_mode *get_display_mode();
64 |
65 | private:
66 | /**
67 | * @brief Pointer to the DRM display mode used with this surface.
68 | */
69 | drm_display_mode *m_display_mode;
70 |
71 | /**
72 | * @brief The extent of this surface.
73 | */
74 | VkExtent2D m_extent;
75 |
76 | /**
77 | * @brief Surface properties instance specific to this surface.
78 | */
79 | surface_properties m_surface_properties;
80 | };
81 |
82 | } /* namespace display */
83 | } /* namespace wsi */
84 |
--------------------------------------------------------------------------------
/wsi/display/surface_properties.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #pragma once
26 |
27 | #include
28 |
29 | #include "wsi/surface_properties.hpp"
30 | #include "drm_display.hpp"
31 | #include "wsi/compatible_present_modes.hpp"
32 |
33 | namespace wsi
34 | {
35 |
36 | namespace display
37 | {
38 |
39 | class surface;
40 |
41 | class surface_properties : public wsi::surface_properties
42 | {
43 | public:
44 | surface_properties();
45 |
46 | surface_properties(surface *wsi_surface);
47 |
48 | VkResult get_surface_capabilities(VkPhysicalDevice physical_device,
49 | VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) override;
50 | VkResult get_surface_capabilities(VkPhysicalDevice physical_device,
51 | const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
52 | VkSurfaceCapabilities2KHR *pSurfaceCapabilities) override;
53 |
54 | VkResult get_surface_formats(VkPhysicalDevice physical_device, uint32_t *surfaceFormatCount,
55 | VkSurfaceFormatKHR *surfaceFormats,
56 | VkSurfaceFormat2KHR *extended_surface_formats) override;
57 |
58 | VkResult get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
59 | uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) override;
60 |
61 | PFN_vkVoidFunction get_proc_addr(const char *name) override;
62 |
63 | VkResult get_required_instance_extensions(util::extension_list &extension_list) override;
64 |
65 | VkResult get_required_device_extensions(util::extension_list &extension_list) override;
66 |
67 | bool is_surface_extension_enabled(const layer::instance_private_data &instance_data) override;
68 |
69 | #if VULKAN_WSI_LAYER_EXPERIMENTAL
70 | void get_present_timing_surface_caps(VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) override;
71 | #endif
72 |
73 | static surface_properties &get_instance();
74 |
75 | bool is_compatible_present_modes(VkPresentModeKHR present_mode_a, VkPresentModeKHR present_mode_b) override;
76 |
77 | private:
78 | surface *const m_specific_surface;
79 |
80 | /* List of supported presentation modes */
81 | std::array m_supported_modes;
82 |
83 | /* Stores compatible presentation modes */
84 | compatible_present_modes<1> m_compatible_present_modes;
85 |
86 | void get_surface_present_scaling_and_gravity(VkSurfacePresentScalingCapabilitiesEXT *scaling_capabilities) override;
87 | void populate_present_mode_compatibilities() override;
88 | };
89 |
90 | } /* namespace display */
91 |
92 | } /* namespace wsi */
--------------------------------------------------------------------------------
/wsi/display/swapchain.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /**
26 | * @file swapchain.hpp
27 | *
28 | * @brief Contains the class definition for a display swapchain.
29 | */
30 |
31 | #pragma once
32 |
33 | #include
34 | #include
35 | #include
36 | #include "util/wsialloc/wsialloc.h"
37 | #include "drm_display.hpp"
38 | #include "wsi/external_memory.hpp"
39 | #include "surface.hpp"
40 |
41 | namespace wsi
42 | {
43 |
44 | namespace display
45 | {
46 |
47 | struct display_image_data
48 | {
49 | display_image_data(const VkDevice &device, const util::allocator &allocator)
50 | : external_mem(device, allocator)
51 | , fb_id(std::numeric_limits::max())
52 | {
53 | }
54 |
55 | external_memory external_mem;
56 | uint32_t fb_id;
57 | sync_fd_fence_sync present_fence;
58 | };
59 |
60 | struct image_creation_parameters
61 | {
62 | wsialloc_format m_allocated_format;
63 | util::vector m_image_layout;
64 | VkExternalMemoryImageCreateInfoKHR m_external_info;
65 | VkImageDrmFormatModifierExplicitCreateInfoEXT m_drm_mod_info;
66 |
67 | image_creation_parameters(wsialloc_format allocated_format, util::allocator allocator,
68 | VkExternalMemoryImageCreateInfoKHR external_info,
69 | VkImageDrmFormatModifierExplicitCreateInfoEXT drm_mod_info)
70 | : m_allocated_format(allocated_format)
71 | , m_image_layout(allocator)
72 | , m_external_info(external_info)
73 | , m_drm_mod_info(drm_mod_info)
74 | {
75 | }
76 | };
77 |
78 | /**
79 | * @brief Display swapchain class.
80 | */
81 | class swapchain : public wsi::swapchain_base
82 | {
83 | public:
84 | swapchain(layer::device_private_data &dev_data, const VkAllocationCallbacks *pAllocator, surface &wsi_surface);
85 | virtual ~swapchain();
86 | virtual VkResult init_platform(VkDevice device, const VkSwapchainCreateInfoKHR *swapchain_create_info,
87 | bool &use_presentation_thread) override;
88 |
89 | virtual VkResult bind_swapchain_image(VkDevice &device, const VkBindImageMemoryInfo *bind_image_mem_info,
90 | const VkBindImageMemorySwapchainInfoKHR *bind_sc_info) override;
91 |
92 | VkResult allocate_and_bind_swapchain_image(VkImageCreateInfo image_create_info, swapchain_image &image) override;
93 |
94 | virtual VkResult create_swapchain_image(VkImageCreateInfo image_create_info, swapchain_image &image) override;
95 |
96 | /**
97 | * @brief Method to present and image
98 | *
99 | * It sends the next image for presentation to the presentation engine.
100 | *
101 | * @param pending_present Information on the pending present request.
102 | */
103 | void present_image(const pending_present_request &pending_present) override;
104 |
105 | virtual VkResult image_set_present_payload(swapchain_image &image, VkQueue queue,
106 | const queue_submit_semaphores &semaphores,
107 | const void *submission_pnext) override;
108 |
109 | virtual VkResult image_wait_present(swapchain_image &image, uint64_t timeout) override;
110 |
111 | void destroy_image(swapchain_image &image) override;
112 |
113 | private:
114 | VkResult allocate_image(VkImageCreateInfo &image_create_info, display_image_data *image_data);
115 |
116 | VkResult allocate_wsialloc(VkImageCreateInfo &image_create_info, display_image_data *image_data,
117 | util::vector &importable_formats, wsialloc_format *allocated_format,
118 | bool avoid_allocation);
119 |
120 | VkResult get_surface_compatible_formats(const VkImageCreateInfo &info,
121 | util::vector &importable_formats,
122 | util::vector &exportable_modifers,
123 | util::vector &drm_format_props);
124 |
125 | VkResult create_framebuffer(const VkImageCreateInfo &image_create_info, swapchain_image &image,
126 | display_image_data *image_data);
127 |
128 | wsialloc_allocator *m_wsi_allocator;
129 | drm_display_mode *m_display_mode;
130 | image_creation_parameters m_image_creation_parameters;
131 | };
132 |
133 | } /* namespace display */
134 |
135 | } /* namespace wsi*/
136 |
--------------------------------------------------------------------------------
/wsi/frame_boundary.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /**
26 | * @file frame_boundary.cpp
27 | *
28 | * @brief Contains the functionality for frame boundary handling.
29 | */
30 |
31 | #include "frame_boundary.hpp"
32 |
33 | namespace wsi
34 | {
35 | frame_boundary_handler::frame_boundary_handler(const layer::device_private_data &device_data)
36 | : m_handle_frame_boundary_events(device_data.should_layer_handle_frame_boundary_events())
37 | {
38 | }
39 |
40 | std::optional frame_boundary_handler::handle_frame_boundary_event(
41 | const VkPresentInfoKHR *present_info, VkImage *current_image_to_be_presented)
42 | {
43 | /* If frame boundary feature is not enabled by the application, the layer will pass its own frame boundary events back to ICD.
44 | * Otherwise, let the application handle the frame boundary events. */
45 | return m_handle_frame_boundary_events ? create_frame_boundary(current_image_to_be_presented) :
46 | wsi::create_frame_boundary(*present_info);
47 | }
48 |
49 | std::optional create_frame_boundary(const VkPresentInfoKHR &present_info)
50 | {
51 | auto *present_frame_boundary =
52 | util::find_extension(VK_STRUCTURE_TYPE_PRESENT_ID_KHR, present_info.pNext);
53 |
54 | /* Extract the VkFrameBoundaryEXT structure to avoid passing other, unrelated structures to vkQueueSubmit */
55 | if (present_frame_boundary != nullptr)
56 | {
57 | return util::shallow_copy_extension(present_frame_boundary);
58 | }
59 |
60 | return std::nullopt;
61 | }
62 |
63 | bool frame_boundary_handler::should_layer_handle_frame_boundary_events() const
64 | {
65 | return m_handle_frame_boundary_events;
66 | }
67 |
68 | VkFrameBoundaryEXT frame_boundary_handler::create_frame_boundary(VkImage *image)
69 | {
70 | VkFrameBoundaryEXT frame_boundary{};
71 | frame_boundary.pNext = nullptr;
72 | frame_boundary.sType = VK_STRUCTURE_TYPE_FRAME_BOUNDARY_EXT;
73 | frame_boundary.flags = VK_FRAME_BOUNDARY_FRAME_END_BIT_EXT;
74 | /* Number of presented images by swapchain as the frame boundary
75 | * would not work as when the page flip thread is running, the
76 | * number frame ID could remain the same until the image is picked
77 | * up by the thread so we use our own counter for the frame boundary. */
78 | frame_boundary.frameID = m_current_frame_boundary_id++;
79 | frame_boundary.imageCount = 1;
80 | frame_boundary.pImages = image;
81 | frame_boundary.pBuffers = nullptr;
82 | frame_boundary.bufferCount = 0;
83 |
84 | /* Create an unique identifier for the layer in case tools make use of it.
85 | * The number below is derived from converting characters 'WSI' into
86 | * their numerical representation from the ASCII table. */
87 | frame_boundary.tagName = 0x575349;
88 |
89 | /* No additional data attached */
90 | frame_boundary.tagSize = 0;
91 | frame_boundary.pTag = nullptr;
92 |
93 | return frame_boundary;
94 | }
95 |
96 | }
--------------------------------------------------------------------------------
/wsi/frame_boundary.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /**
26 | * @file frame_boundary.hpp
27 | *
28 | * @brief Contains the functionality for frame boundary handling.
29 | */
30 |
31 | #pragma once
32 |
33 | #include
34 | #include
35 |
36 | #include
37 |
38 | namespace wsi
39 | {
40 | class frame_boundary_handler
41 | {
42 | public:
43 | frame_boundary_handler(const layer::device_private_data &device_data);
44 |
45 | /**
46 | * @brief Handle frame boundary event at present time
47 | *
48 | * @param present_info Information about the swapchain and image to be presented.
49 | * @param current_image_to_be_presented Address to the currently to be presented image
50 | */
51 | std::optional handle_frame_boundary_event(const VkPresentInfoKHR *present_info,
52 | VkImage *current_image_to_be_presented);
53 |
54 | private:
55 | /**
56 | * @brief Create a frame boundary with the current image
57 | *
58 | * @param image Address to the currently to be presented image
59 | * @return Frame boundary structure
60 | */
61 | VkFrameBoundaryEXT create_frame_boundary(VkImage *image);
62 |
63 | /**
64 | * @brief Check whether we should handle frame boundary events.
65 | *
66 | * @return true if supported, false otherwise.
67 | */
68 | bool should_layer_handle_frame_boundary_events() const;
69 |
70 | /**
71 | * @brief Holds the number of the current frame identifier for the swapchain
72 | */
73 | uint64_t m_current_frame_boundary_id{ 0 };
74 |
75 | /**
76 | * @brief Stores whether the layer should handle frame boundary events.
77 | */
78 | const bool m_handle_frame_boundary_events;
79 | };
80 |
81 | /**
82 | * @brief Create a frame boundary object
83 | *
84 | * @param present_info Present info
85 | * @return Frame boundary if @p present_info has passed it.
86 | */
87 | std::optional create_frame_boundary(const VkPresentInfoKHR &present_info);
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/wsi/headless/surface.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /** @file
26 | * @brief Implementation of a headless WSI Surface
27 | */
28 |
29 | #include "surface.hpp"
30 | #include "swapchain.hpp"
31 | #include "surface_properties.hpp"
32 |
33 | namespace wsi
34 | {
35 | namespace headless
36 | {
37 |
38 | wsi::surface_properties &surface::get_properties()
39 | {
40 | return surface_properties::get_instance();
41 | }
42 |
43 | util::unique_ptr surface::allocate_swapchain(layer::device_private_data &dev_data,
44 | const VkAllocationCallbacks *allocator)
45 | {
46 | util::allocator alloc{ dev_data.get_allocator(), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT, allocator };
47 | return util::unique_ptr(alloc.make_unique(dev_data, allocator));
48 | }
49 |
50 | } /* namespace headless */
51 | } /* namespace wsi */
52 |
--------------------------------------------------------------------------------
/wsi/headless/surface.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /** @file
26 | * @brief Definitions for a headless WSI Surface
27 | */
28 |
29 | #pragma once
30 |
31 | #include "wsi/surface.hpp"
32 |
33 | namespace wsi
34 | {
35 | namespace headless
36 | {
37 |
38 | class surface : public wsi::surface
39 | {
40 | public:
41 | surface() = default;
42 | wsi::surface_properties &get_properties() override;
43 | util::unique_ptr allocate_swapchain(layer::device_private_data &dev_data,
44 | const VkAllocationCallbacks *allocator) override;
45 | };
46 |
47 | } /* namespace headless */
48 | } /* namespace wsi */
49 |
--------------------------------------------------------------------------------
/wsi/headless/surface_properties.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2019, 2022-2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #pragma once
26 |
27 | #include
28 | #include
29 | #include
30 | #include
31 | namespace wsi
32 | {
33 | namespace headless
34 | {
35 |
36 | class surface_properties : public wsi::surface_properties
37 | {
38 | public:
39 | surface_properties();
40 |
41 | VkResult get_surface_capabilities(VkPhysicalDevice physical_device,
42 | VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) override;
43 |
44 | VkResult get_surface_capabilities(VkPhysicalDevice physical_device,
45 | const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
46 | VkSurfaceCapabilities2KHR *pSurfaceCapabilities) override;
47 |
48 | VkResult get_surface_formats(VkPhysicalDevice physical_device, uint32_t *surfaceFormatCount,
49 | VkSurfaceFormatKHR *surfaceFormats,
50 | VkSurfaceFormat2KHR *extended_surface_formats) override;
51 |
52 | VkResult get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
53 | uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) override;
54 |
55 | PFN_vkVoidFunction get_proc_addr(const char *name) override;
56 |
57 | VkResult get_required_instance_extensions(util::extension_list &extension_list) override;
58 |
59 | bool is_surface_extension_enabled(const layer::instance_private_data &instance_data) override;
60 |
61 | static surface_properties &get_instance();
62 |
63 | bool is_compatible_present_modes(VkPresentModeKHR present_mode_a, VkPresentModeKHR present_mode_b) override;
64 |
65 | #if VULKAN_WSI_LAYER_EXPERIMENTAL
66 | void get_present_timing_surface_caps(VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) override;
67 | #endif
68 |
69 | private:
70 | /* List of supported presentation modes */
71 | std::array m_supported_modes;
72 |
73 | /* Stores compatible presentation modes */
74 | compatible_present_modes<4> m_compatible_present_modes;
75 |
76 | void populate_present_mode_compatibilities() override;
77 |
78 | void get_surface_present_scaling_and_gravity(VkSurfacePresentScalingCapabilitiesEXT *scaling_capabilities) override;
79 | };
80 |
81 | } /* namespace headless */
82 | } /* namespace wsi */
83 |
--------------------------------------------------------------------------------
/wsi/headless/swapchain.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /**
26 | * @file swapchain.hpp
27 | *
28 | * @brief Contains the class definition for a headless swapchain.
29 | */
30 |
31 | #pragma once
32 |
33 | #include
34 | #include
35 | #include
36 |
37 | namespace wsi
38 | {
39 | namespace headless
40 | {
41 |
42 | /**
43 | * @brief Headless swapchain class.
44 | *
45 | * This class is mostly empty, because all the swapchain stuff is handled by the swapchain class,
46 | * which we inherit. This class only provides a way to create an image and page-flip ops.
47 | */
48 | class swapchain : public wsi::swapchain_base
49 | {
50 | public:
51 | explicit swapchain(layer::device_private_data &dev_data, const VkAllocationCallbacks *pAllocator);
52 |
53 | ~swapchain();
54 |
55 | protected:
56 | /**
57 | * @brief Platform specific init
58 | */
59 | VkResult init_platform(VkDevice device, const VkSwapchainCreateInfoKHR *swapchain_create_info,
60 | bool &use_presentation_thread) override;
61 |
62 | /**
63 | * @brief Allocates and binds a new swapchain image.
64 | *
65 | * @param image_create_info Data to be used to create the image.
66 | * @param image Handle to the image.
67 | *
68 | * @return Returns VK_SUCCESS on success, otherwise an appropriate error code.
69 | */
70 | VkResult allocate_and_bind_swapchain_image(VkImageCreateInfo image_create_info, swapchain_image &image) override;
71 |
72 | /**
73 | * @brief Creates a new swapchain image.
74 | *
75 | * @param image_create_info Data to be used to create the image.
76 | * @param image Handle to the image.
77 | *
78 | * @return If image creation is successful returns VK_SUCCESS, otherwise
79 | * will return VK_ERROR_OUT_OF_DEVICE_MEMORY or VK_ERROR_INITIALIZATION_FAILED
80 | * depending on the error that occurred.
81 | */
82 | VkResult create_swapchain_image(VkImageCreateInfo image_create_info, swapchain_image &image) override;
83 |
84 | /**
85 | * @brief Method to present and image
86 | *
87 | * It sends the next image for presentation to the presentation engine.
88 | *
89 | * @param pending_present Information on the pending present request.
90 | */
91 | void present_image(const pending_present_request &pending_present) override;
92 |
93 | /**
94 | * @brief Method to release a swapchain image
95 | *
96 | * @param image Handle to the image about to be released.
97 | */
98 | void destroy_image(wsi::swapchain_image &image);
99 |
100 | /**
101 | * @brief Sets the present payload for a swapchain image.
102 | *
103 | * @param[in] image The swapchain image for which to set a present payload.
104 | * @param queue A Vulkan queue that can be used for any Vulkan commands needed.
105 | * @param[in] sem_payload Array of Vulkan semaphores that constitute the payload.
106 | * @param[in] submission_pnext Chain of pointers to attach to the payload submission.
107 | *
108 | * @return VK_SUCCESS on success or an error code otherwise.
109 | */
110 | VkResult image_set_present_payload(swapchain_image &image, VkQueue queue, const queue_submit_semaphores &semaphores,
111 | const void *submission_pnext) override;
112 |
113 | VkResult image_wait_present(swapchain_image &image, uint64_t timeout) override;
114 |
115 | /**
116 | * @brief Bind image to a swapchain
117 | *
118 | * @param device is the logical device that owns the images and memory.
119 | * @param bind_image_mem_info details the image we want to bind.
120 | * @param bind_sc_info describes the swapchain memory to bind to.
121 | *
122 | * @return VK_SUCCESS on success, otherwise on failure VK_ERROR_OUT_OF_HOST_MEMORY or VK_ERROR_OUT_OF_DEVICE_MEMORY
123 | * can be returned.
124 | */
125 | VkResult bind_swapchain_image(VkDevice &device, const VkBindImageMemoryInfo *bind_image_mem_info,
126 | const VkBindImageMemorySwapchainInfoKHR *bind_sc_info) override;
127 |
128 | private:
129 | #if WSI_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN
130 | VkImageCompressionControlEXT m_image_compression_control;
131 | #endif
132 | };
133 |
134 | } /* namespace headless */
135 | } /* namespace wsi */
136 |
--------------------------------------------------------------------------------
/wsi/surface.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021, 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /**
26 | * @file
27 | * @brief Vulkan WSI surface interfaces.
28 | */
29 |
30 | #pragma once
31 |
32 | #include
33 | #include "surface_properties.hpp"
34 | #include "swapchain_base.hpp"
35 |
36 | namespace wsi
37 | {
38 |
39 | /**
40 | * @brief Struct describing a DRM format with modifier.
41 | */
42 | struct drm_format_pair
43 | {
44 | uint32_t fourcc;
45 | uint64_t modifier;
46 | };
47 |
48 | /**
49 | * @brief A generic WSI representation of a VkSurface.
50 | *
51 | * The association between these objects and VkSurfaces is kept in the VkInstance private data.
52 | */
53 | class surface
54 | {
55 | public:
56 | virtual ~surface() = default;
57 |
58 | /**
59 | * @brief Returns a @ref surface_properties implementation that can be specific to the VkSurface represented.
60 | */
61 | virtual surface_properties &get_properties() = 0;
62 |
63 | /**
64 | * @brief Allocates a swapchain for the VkSurface type represented.
65 | *
66 | * @param dev_data The VkDevice associated private date.
67 | * @param allocator Allocation callbacks to use for host memory.
68 | *
69 | * @return nullptr on failure otherwise a constructed swapchain.
70 | */
71 | virtual util::unique_ptr allocate_swapchain(layer::device_private_data &dev_data,
72 | const VkAllocationCallbacks *allocator) = 0;
73 | };
74 |
75 | } /* namespace wsi */
76 |
--------------------------------------------------------------------------------
/wsi/surface_properties.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #include "surface_properties.hpp"
26 | #include "layer/private_data.hpp"
27 |
28 | namespace wsi
29 | {
30 |
31 | VkResult surface_format_properties::check_device_support(VkPhysicalDevice phys_dev,
32 | VkPhysicalDeviceImageFormatInfo2KHR image_format_info)
33 | {
34 | VkImageFormatProperties2KHR image_format_props{ VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR, nullptr };
35 |
36 | auto &instance_data = layer::instance_private_data::get(phys_dev);
37 |
38 | return instance_data.disp.GetPhysicalDeviceImageFormatProperties2KHR(phys_dev, &image_format_info,
39 | &image_format_props);
40 | }
41 |
42 | #if WSI_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN
43 | VkResult surface_format_properties::add_device_compression_support(
44 | VkPhysicalDevice phys_dev, VkPhysicalDeviceImageFormatInfo2KHR image_format_info)
45 | {
46 | auto &instance_data = layer::instance_private_data::get(phys_dev);
47 |
48 | VkImageCompressionPropertiesEXT compression_props = { VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_PROPERTIES_EXT, nullptr, 0,
49 | 0 };
50 | VkImageFormatProperties2KHR image_format_props{ VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR,
51 | &compression_props };
52 |
53 | VkImageCompressionControlEXT compression_control{ VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT,
54 | image_format_info.pNext,
55 | VK_IMAGE_COMPRESSION_FIXED_RATE_DEFAULT_EXT };
56 | image_format_info.pNext = &compression_control;
57 |
58 | VkResult res =
59 | instance_data.disp.GetPhysicalDeviceImageFormatProperties2KHR(phys_dev, &image_format_info, &image_format_props);
60 | if (res == VK_SUCCESS)
61 | {
62 | m_compression.imageCompressionFlags |= compression_props.imageCompressionFlags;
63 | m_compression.imageCompressionFixedRateFlags |= compression_props.imageCompressionFixedRateFlags;
64 | }
65 | else if (res != VK_ERROR_FORMAT_NOT_SUPPORTED)
66 | {
67 | return res;
68 | }
69 |
70 | return VK_SUCCESS;
71 | }
72 | #endif
73 |
74 | void surface_format_properties::fill_format_properties(VkSurfaceFormat2KHR &surf_format) const
75 | {
76 | surf_format.surfaceFormat = m_surface_format;
77 | #if WSI_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN
78 | auto *compression_properties = util::find_extension(
79 | VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_PROPERTIES_EXT, surf_format.pNext);
80 | if (compression_properties != nullptr)
81 | {
82 | /** While a format can support multiple compression control flags the returned value is only allowed to be:
83 | * VK_IMAGE_COMPRESSION_DEFAULT_EXT, VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT or
84 | * VK_IMAGE_COMPRESSION_DISABLED_EXT.
85 | *
86 | * Since currently formats that are supported with both default and disabled compression are not distinguished
87 | * from formats that would always be with disabled compression, disabled is not returned.
88 | */
89 | compression_properties->imageCompressionFlags = VK_IMAGE_COMPRESSION_DEFAULT_EXT;
90 | if (m_compression.imageCompressionFlags & VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT)
91 | {
92 | compression_properties->imageCompressionFlags = VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT;
93 | compression_properties->imageCompressionFixedRateFlags = m_compression.imageCompressionFixedRateFlags;
94 | }
95 | }
96 | #endif
97 | }
98 |
99 | void get_surface_capabilities_common(VkPhysicalDevice physical_device, VkSurfaceCapabilitiesKHR *surface_capabilities)
100 | {
101 | /* Image count limits */
102 | surface_capabilities->minImageCount = 1;
103 | surface_capabilities->maxImageCount = surface_properties::MAX_SWAPCHAIN_IMAGE_COUNT;
104 |
105 | /* Surface extents */
106 | surface_capabilities->currentExtent = { 0xffffffff, 0xffffffff };
107 | surface_capabilities->minImageExtent = { 1, 1 };
108 | /* Ask the device for max */
109 | VkPhysicalDeviceProperties dev_props = {};
110 | layer::instance_private_data::get(physical_device).disp.GetPhysicalDeviceProperties(physical_device, &dev_props);
111 |
112 | surface_capabilities->maxImageExtent = { dev_props.limits.maxImageDimension2D,
113 | dev_props.limits.maxImageDimension2D };
114 | surface_capabilities->maxImageArrayLayers = 1;
115 |
116 | /* Surface transforms */
117 | surface_capabilities->supportedTransforms = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
118 | surface_capabilities->currentTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
119 |
120 | /* Composite alpha */
121 | surface_capabilities->supportedCompositeAlpha = static_cast(
122 | VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR | VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR |
123 | VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR | VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR);
124 |
125 | /* Image usage flags */
126 | surface_capabilities->supportedUsageFlags =
127 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
128 | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
129 | }
130 |
131 | } /* namespace wsi */
--------------------------------------------------------------------------------
/wsi/synchronization.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021-2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /**
26 | * @file
27 | *
28 | * @brief Contains the defintions of WSI synchronization primitives.
29 | */
30 |
31 | #pragma once
32 |
33 | #include
34 |
35 | #include "util/file_descriptor.hpp"
36 |
37 | #include
38 |
39 | namespace layer
40 | {
41 | class device_private_data;
42 | class instance_private_data;
43 | } /* namespace layer */
44 |
45 | namespace wsi
46 | {
47 |
48 | struct queue_submit_semaphores
49 | {
50 | const VkSemaphore *wait_semaphores;
51 | uint32_t wait_semaphores_count;
52 | const VkSemaphore *signal_semaphores;
53 | uint32_t signal_semaphores_count;
54 | };
55 |
56 | /**
57 | * Synchronization using a Vulkan Fence object.
58 | */
59 | class fence_sync
60 | {
61 | public:
62 | /**
63 | * Creates a new fence synchronization object.
64 | *
65 | * @param device The device private data for which to create it.
66 | *
67 | * @return Empty optional on failure or initialized fence.
68 | */
69 | static std::optional create(layer::device_private_data &device);
70 |
71 | fence_sync() = default;
72 | fence_sync(const fence_sync &) = delete;
73 | fence_sync &operator=(const fence_sync &) = delete;
74 |
75 | fence_sync(fence_sync &&rhs);
76 | fence_sync &operator=(fence_sync &&rhs);
77 |
78 | virtual ~fence_sync();
79 |
80 | /**
81 | * Waits for any pending payload to complete execution.
82 | *
83 | * @note This method is not threadsafe.
84 | *
85 | * @param timeout Timeout for waiting in nanoseconds.
86 | *
87 | * @return VK_SUCCESS on success or if no payload or a completed payload is set.
88 | * Other error code on failure or timeout.
89 | */
90 | VkResult wait_payload(uint64_t timeout);
91 |
92 | /**
93 | * Sets the payload for the fence that would need to complete before operations that wait on it.
94 | *
95 | * @note This method is not threadsafe.
96 | *
97 | * @param queue The Vulkan queue that may be used to submit synchronization commands.
98 | * @param semaphores The wait and signal semaphores.
99 | * @param submission_pnext Chain of pointers to attach to the payload submission.
100 | *
101 | * @return VK_SUCCESS on success or other error code on failing to set the payload.
102 | */
103 | VkResult set_payload(VkQueue queue, const queue_submit_semaphores &semaphores,
104 | const void *submission_pnext = nullptr);
105 |
106 | protected:
107 | /**
108 | * Non-public constructor to initialize the object with valid data.
109 | *
110 | * @param device The device private data for the fence.
111 | * @param vk_fence The created Vulkan fence.
112 | */
113 | fence_sync(layer::device_private_data &device, VkFence vk_fence);
114 |
115 | VkFence get_fence()
116 | {
117 | return fence;
118 | }
119 |
120 | /**
121 | * Swaps current payload. This operation could be performed when exporting or importing external fences.
122 | *
123 | * @param new_payload Whether a new payload is set.
124 | *
125 | * @return If there is an existing payload that is being replaced.
126 | */
127 | bool swap_payload(bool new_payload);
128 |
129 | layer::device_private_data &get_device()
130 | {
131 | return *dev;
132 | }
133 |
134 | private:
135 | VkFence fence{ VK_NULL_HANDLE };
136 | bool has_payload{ false };
137 | bool payload_finished{ false };
138 | layer::device_private_data *dev{ nullptr };
139 | };
140 |
141 | /**
142 | * Synchronization using a Vulkan fence exportable to a native Sync FD object.
143 | */
144 | class sync_fd_fence_sync : public fence_sync
145 | {
146 | public:
147 | sync_fd_fence_sync() = default;
148 |
149 | /**
150 | * Checks if a Vulkan device can support Sync FD fences.
151 | *
152 | * @param instance The instance private data for the physical device.
153 | * @param phys_dev The physical device to check support for.
154 | *
155 | * @return true if supported, false otherwise.
156 | */
157 | static bool is_supported(layer::instance_private_data &instance, VkPhysicalDevice phys_dev);
158 |
159 | /**
160 | * Creates a new fence compatible with Sync FD.
161 | *
162 | * @param device The device private data for which to create the fence.
163 | *
164 | * @return Empty optional on failure or initialized fence.
165 | */
166 | static std::optional create(layer::device_private_data &device);
167 |
168 | /**
169 | * Exports the fence to a native Sync FD.
170 | *
171 | * @note This method is not threadsafe.
172 | *
173 | * @return The exported Sync FD on success or empty optional on failure.
174 | */
175 | std::optional export_sync_fd();
176 |
177 | private:
178 | /**
179 | * Non-public constructor to initialize the object with valid data.
180 | *
181 | * @param device The device private data for the fence.
182 | * @param vk_fence The created exportable Vulkan fence.
183 | */
184 | sync_fd_fence_sync(layer::device_private_data &device, VkFence vk_fence);
185 | };
186 |
187 | /**
188 | * @brief Submit an empty queue operation for synchronization.
189 | *
190 | * @param device The device private data for the fence.
191 | * @param queue The Vulkan queue that may be used to submit synchronization commands.
192 | * @param fence The fence to be signalled, it could be VK_NULL_HANDLE in the absence
193 | * of a fence to be signalled.
194 | * @param semaphores The wait and signal semaphores.
195 | * @param submission_pnext Chain of pointers to attach to the payload submission.
196 | *
197 | * @return VK_SUCCESS on success, an appropiate error code otherwise.
198 | */
199 | VkResult sync_queue_submit(const layer::device_private_data &device, VkQueue queue, VkFence fence,
200 | const queue_submit_semaphores &semaphores, const void *submission_pnext = nullptr);
201 | } /* namespace wsi */
202 |
--------------------------------------------------------------------------------
/wsi/wayland/surface.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021, 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /** @file
26 | * @brief Definitions for a Wayland WSI Surface
27 | */
28 |
29 | #pragma once
30 |
31 | #ifndef __STDC_VERSION__
32 | #define __STDC_VERSION__ 0
33 | #endif
34 | #include
35 |
36 | #include "wsi/surface.hpp"
37 | #include "surface_properties.hpp"
38 | #include "wl_object_owner.hpp"
39 | #include "util/macros.hpp"
40 |
41 | namespace wsi
42 | {
43 | namespace wayland
44 | {
45 |
46 | /**
47 | * Wayland callback for global wl_registry events to handle global objects required by @ref wsi::wayland::surface
48 | */
49 | VWL_CAPI_CALL(void)
50 | surface_registry_handler(void *data, struct wl_registry *wl_registry, uint32_t name, const char *interface,
51 | uint32_t version) VWL_API_POST;
52 |
53 | class surface : public wsi::surface
54 | {
55 | public:
56 | surface() = delete;
57 | struct init_parameters;
58 |
59 | /** Constructor to allow for custom allocation, but require privately defined arguments. */
60 | surface(const init_parameters &);
61 |
62 | /**
63 | * @brief Allocates and initializes a surface
64 | *
65 | * @param allocator An allocator to use for host allocations needed for the surface.
66 | * @param display The Wayland display used to create the VkSurface
67 | * @param surf The Wayland surface used to create the VkSurface
68 | *
69 | * @return A constructed and initalized surface or nullptr on failure
70 | */
71 | static util::unique_ptr make_surface(const util::allocator &allocator, wl_display *display,
72 | wl_surface *surf);
73 |
74 | /** Destructor */
75 | ~surface() override;
76 |
77 | wsi::surface_properties &get_properties() override;
78 | util::unique_ptr allocate_swapchain(layer::device_private_data &dev_data,
79 | const VkAllocationCallbacks *allocator) override;
80 |
81 | /** Returns the Wayland display */
82 | wl_display *get_wl_display() const
83 | {
84 | return wayland_display;
85 | }
86 |
87 | /** Returns the Wayland surface */
88 | wl_surface *get_wl_surface() const
89 | {
90 | return wayland_surface;
91 | }
92 |
93 | /**
94 | * @brief Returns a pointer to the Wayland zwp_linux_dmabuf_v1 interface.
95 | *
96 | * The raw pointer is valid throughout the lifetime of this surface.
97 | */
98 | zwp_linux_dmabuf_v1 *get_dmabuf_interface()
99 | {
100 | return dmabuf_interface.get();
101 | }
102 |
103 | /**
104 | * @brief Returns a pointer to the Wayland zwp_linux_surface_synchronization_v1 interface obtained for the wayland
105 | * surface.
106 | *
107 | * The raw pointer is valid for the lifetime of the surface.
108 | */
109 | zwp_linux_surface_synchronization_v1 *get_surface_sync_interface()
110 | {
111 | return surface_sync_interface.get();
112 | }
113 |
114 | /**
115 | * @brief Returns a reference to a list of DRM formats supported by the Wayland surface.
116 | *
117 | * The reference is valid throughout the lifetime of this surface.
118 | */
119 | const util::vector &get_formats() const
120 | {
121 | return supported_formats;
122 | }
123 |
124 | /**
125 | * @brief Set the next frame callback.
126 | *
127 | * Make a frame request on the compositor which will be applied in the next
128 | * wl_surface::commit. It overwrites previous requested frame events.
129 | *
130 | * @return true for success, false otherwise.
131 | */
132 | bool set_frame_callback();
133 |
134 | /**
135 | * @brief Wait for the compositor's last requested frame event.
136 | *
137 | * @return true for success, false otherwise.
138 | */
139 | bool wait_next_frame_event();
140 |
141 | private:
142 | /**
143 | * @brief Initialize the WSI surface by creating Wayland queues and linking to Wayland protocols.
144 | *
145 | * @return true on success, false otherwise.
146 | */
147 | bool init();
148 |
149 | friend void surface_registry_handler(void *data, struct wl_registry *wl_registry, uint32_t name,
150 | const char *interface, uint32_t version) VWL_API_POST;
151 |
152 | /** The native Wayland display */
153 | wl_display *wayland_display;
154 |
155 | /**
156 | * Container for a private queue for surface events generated by the layer.
157 | * The queue is also used for dispatching frame callback events.
158 | * It should be destroyed after the objects that attached to it.
159 | */
160 | wayland_owner surface_queue;
161 |
162 | /** The native Wayland surface */
163 | wl_surface *wayland_surface;
164 | /** A list of DRM formats supported by the Wayland compositor on this surface */
165 | util::vector supported_formats;
166 | /** Surface properties specific to the Wayland surface. */
167 | surface_properties properties;
168 |
169 | /** Container for the zwp_linux_dmabuf_v1 interface binding */
170 | wayland_owner dmabuf_interface;
171 |
172 | /** Container for the zwp_linux_explicit_synchronization_v1 interface binding */
173 | wayland_owner explicit_sync_interface;
174 | /** Container for the surface specific zwp_linux_surface_synchronization_v1 interface. */
175 | wayland_owner surface_sync_interface;
176 |
177 | /** Container for the wp_presentation interface binding */
178 | wayland_owner presentation_time_interface;
179 |
180 | /**
181 | * Container for a callback object for the latest frame done event.
182 | *
183 | * The callback object should be destroyed before the queue so any new events
184 | * on the queue will be discarded. If a proxy object is destroyed after a queue,
185 | * it is possible in the meantime for a new event to arrive and processed.
186 | * This will result in a use after free error.
187 | */
188 | wayland_owner last_frame_callback;
189 |
190 | /**
191 | * @brief true when waiting for the server hint to present a buffer
192 | *
193 | * true if a buffer has been presented and we've not had a wl_surface::frame
194 | * callback to indicate the server is ready for the next buffer.
195 | */
196 | bool present_pending;
197 | };
198 |
199 | } // namespace wayland
200 | } // namespace wsi
201 |
--------------------------------------------------------------------------------
/wsi/wayland/surface_properties.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2019, 2021-2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #pragma once
26 |
27 | #include "wsi/surface_properties.hpp"
28 | #include "util/unordered_set.hpp"
29 | #include "wsi/compatible_present_modes.hpp"
30 |
31 | namespace wsi
32 | {
33 | namespace wayland
34 | {
35 |
36 | struct surface_format_properties_hasher
37 | {
38 | size_t operator()(const VkFormat &format) const
39 | {
40 | return std::hash()(static_cast(format));
41 | }
42 | };
43 |
44 | using surface_format_properties_map =
45 | util::unordered_map;
46 |
47 | class surface;
48 |
49 | class surface_properties : public wsi::surface_properties
50 | {
51 | public:
52 | surface_properties(surface *wsi_surface, const util::allocator &alloc);
53 |
54 | static surface_properties &get_instance();
55 |
56 | VkResult get_surface_capabilities(VkPhysicalDevice physical_device,
57 | VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) override;
58 | VkResult get_surface_capabilities(VkPhysicalDevice physical_device,
59 | const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
60 | VkSurfaceCapabilities2KHR *pSurfaceCapabilities) override;
61 | VkResult get_surface_formats(VkPhysicalDevice physical_device, uint32_t *surfaceFormatCount,
62 | VkSurfaceFormatKHR *surfaceFormats,
63 | VkSurfaceFormat2KHR *extended_surface_formats) override;
64 | VkResult get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
65 | uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) override;
66 |
67 | VkResult get_required_device_extensions(util::extension_list &extension_list) override;
68 |
69 | VkResult get_required_instance_extensions(util::extension_list &extension_list) override;
70 |
71 | PFN_vkVoidFunction get_proc_addr(const char *name) override;
72 |
73 | bool is_surface_extension_enabled(const layer::instance_private_data &instance_data) override;
74 |
75 | bool is_compatible_present_modes(VkPresentModeKHR present_mode_a, VkPresentModeKHR present_mode_b) override;
76 |
77 | #if VULKAN_WSI_LAYER_EXPERIMENTAL
78 | void get_present_timing_surface_caps(VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) override;
79 | #endif
80 | private:
81 | surface_properties();
82 |
83 | /** If the properties are specific to a @ref wsi::wayland::surface this is a pointer to it. Can be nullptr for
84 | * generic Wayland surface properties.
85 | */
86 | surface *specific_surface;
87 | /** Set of supported Vulkan formats by the @ref specific_surface. */
88 | surface_format_properties_map supported_formats;
89 |
90 | /* List of supported presentation modes */
91 | std::array m_supported_modes;
92 |
93 | /* Stores compatible presentation modes */
94 | compatible_present_modes<2> m_compatible_present_modes;
95 |
96 | void populate_present_mode_compatibilities() override;
97 |
98 | void get_surface_present_scaling_and_gravity(VkSurfacePresentScalingCapabilitiesEXT *scaling_capabilities) override;
99 | };
100 |
101 | } // namespace wayland
102 | } // namespace wsi
103 |
--------------------------------------------------------------------------------
/wsi/wayland/wl_helpers.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2019, 2021, 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #include "wl_helpers.hpp"
26 |
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 |
33 | #include "wl_object_owner.hpp"
34 |
35 | #include "util/log.hpp"
36 |
37 | int dispatch_queue(struct wl_display *display, struct wl_event_queue *queue, int timeout)
38 | {
39 | int err;
40 | struct pollfd pfd = {};
41 | int retval;
42 |
43 | /* Before we sleep, dispatch any pending events. prepare_read_queue will return 0 whilst there are pending
44 | * events to dispatch on the queue. */
45 | while (0 != wl_display_prepare_read_queue(display, queue))
46 | {
47 | /* dispatch_queue_pending returns -1 on error, or the number of events dispatched otherwise. If we
48 | * already dispatched some events, then we might not need to sleep, as we might have just dispatched
49 | * the event we want, so return immediately. */
50 | err = wl_display_dispatch_queue_pending(display, queue);
51 | if (err)
52 | {
53 | return (0 > err) ? -1 : 1;
54 | }
55 | }
56 |
57 | /* wl_display_read_events performs a non-blocking read. */
58 | pfd.fd = wl_display_get_fd(display);
59 | pfd.events = POLLIN;
60 | while (true)
61 | {
62 | /* Timeout is given in milliseconds. A return value of 0, or -1 with errno set to EINTR means that we
63 | * should retry as the timeout was exceeded or we were interrupted by a signal, respectively. A
64 | * return value of 1 means that something happened, and we should inspect the pollfd structure to see
65 | * just what that was.
66 | */
67 | err = poll(&pfd, 1, timeout);
68 | if (0 == err)
69 | {
70 | /* Timeout. */
71 | wl_display_cancel_read(display);
72 | return 0;
73 | }
74 | else if (-1 == err)
75 | {
76 | if (EINTR == errno)
77 | {
78 | /* Interrupted by a signal; restart. This resets the timeout. */
79 | continue;
80 | }
81 | else
82 | {
83 | /* Something else bad happened; abort. */
84 | wl_display_cancel_read(display);
85 | return -1;
86 | }
87 | }
88 | else
89 | {
90 | if (POLLIN == pfd.revents)
91 | {
92 | /* We have data to read, and no errors; proceed to read_events. */
93 | break;
94 | }
95 | else
96 | {
97 | /* An error occurred, e.g. file descriptor was closed from underneath us. */
98 | wl_display_cancel_read(display);
99 | return -1;
100 | }
101 | }
102 | }
103 |
104 | /* Actually read the events from the display. A failure in read_events calls cancel_read internally for us,
105 | * so we don't need to do that here. */
106 | err = wl_display_read_events(display);
107 | if (0 != err)
108 | {
109 | return -1;
110 | }
111 |
112 | /* Finally, if we read any events relevant to our queue, we can dispatch them. */
113 | err = wl_display_dispatch_queue_pending(display, queue);
114 | retval = err < 0 ? -1 : 1;
115 |
116 | return retval;
117 | }
118 |
--------------------------------------------------------------------------------
/wsi/wayland/wl_helpers.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2019, 2021, 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #pragma once
26 |
27 | #include
28 |
29 | #ifndef __STDC_VERSION__
30 | #define __STDC_VERSION__ 0
31 | #endif
32 | #include
33 |
34 | #include "util/custom_allocator.hpp"
35 |
36 | /**
37 | * @brief Dispatch events from a Wayland event queue
38 | *
39 | * Dispatch events from a given Wayland display event queue, including calling event handlers, and flush out any
40 | * requests the event handlers may have written. Specification of a timeout allows the wait to be bounded. If any
41 | * events are already pending dispatch (have been read from the display by another thread or event queue), they
42 | * will be dispatched and the function will return immediately, without waiting for new events to arrive.
43 | *
44 | * @param display Wayland display to dispatch events from
45 | * @param queue Event queue to dispatch events from; other event queues will not have their handlers called from
46 | * within this function
47 | * @param timeout Maximum time to wait for events to arrive, in milliseconds
48 | * @return 1 if one or more events were dispatched on this queue, 0 if the timeout was reached without any
49 | * events being dispatched, or -1 on error.
50 | */
51 | int dispatch_queue(struct wl_display *display, struct wl_event_queue *queue, int timeout);
52 |
--------------------------------------------------------------------------------
/wsi/wayland/wl_object_owner.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021, 2024 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #pragma once
26 |
27 | #ifndef __STDC_VERSION__
28 | #define __STDC_VERSION__ 0
29 | #endif
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 |
37 | namespace wsi
38 | {
39 | namespace wayland
40 | {
41 |
42 | static inline void wayland_object_destroy(wl_registry *obj)
43 | {
44 | wl_registry_destroy(obj);
45 | }
46 |
47 | static inline void wayland_object_destroy(zwp_linux_dmabuf_v1 *obj)
48 | {
49 | zwp_linux_dmabuf_v1_destroy(obj);
50 | }
51 |
52 | static inline void wayland_object_destroy(zwp_linux_explicit_synchronization_v1 *obj)
53 | {
54 | zwp_linux_explicit_synchronization_v1_destroy(obj);
55 | }
56 |
57 | static inline void wayland_object_destroy(zwp_linux_surface_synchronization_v1 *obj)
58 | {
59 | zwp_linux_surface_synchronization_v1_destroy(obj);
60 | }
61 |
62 | static inline void wayland_object_destroy(wp_presentation *obj)
63 | {
64 | wp_presentation_destroy(obj);
65 | }
66 |
67 | static inline void wayland_object_destroy(wl_callback *obj)
68 | {
69 | wl_callback_destroy(obj);
70 | }
71 |
72 | static inline void wayland_object_destroy(wl_event_queue *obj)
73 | {
74 | wl_event_queue_destroy(obj);
75 | }
76 |
77 | template
78 | struct wayland_deleter
79 | {
80 | void operator()(T *obj) const
81 | {
82 | if (obj != nullptr)
83 | {
84 | wayland_object_destroy(obj);
85 | }
86 | }
87 | };
88 |
89 | template
90 | using wayland_owner = std::unique_ptr>;
91 |
92 | template
93 | static std::unique_ptr> make_proxy_with_queue(T *object, wl_event_queue *queue)
94 | {
95 | auto proxy = reinterpret_cast(wl_proxy_create_wrapper(object));
96 | if (proxy != nullptr)
97 | {
98 | wl_proxy_set_queue(reinterpret_cast(proxy), queue);
99 | }
100 |
101 | auto delete_proxy = [](T *proxy) { wl_proxy_wrapper_destroy(reinterpret_cast(proxy)); };
102 |
103 | return std::unique_ptr>(proxy, delete_proxy);
104 | }
105 |
106 | } // namespace wayland
107 | } // namespace wsi
108 |
--------------------------------------------------------------------------------
/wsi/wsi_factory.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, 2021, 2023 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /**
26 | * @file
27 | * @brief Contains the factory methods for obtaining the specific surface and swapchain implementations.
28 | */
29 |
30 | #pragma once
31 |
32 | #include "swapchain_base.hpp"
33 | #include "surface_properties.hpp"
34 | #include "util/platform_set.hpp"
35 |
36 | #include
37 |
38 | namespace wsi
39 | {
40 |
41 | /**
42 | * @brief Obtains the surface properties for the specific surface type.
43 | *
44 | * @param instance_data The instance specific data.
45 | * @param surface The surface for which to get the properties.
46 | *
47 | * @return nullptr if surface type is unsupported.
48 | */
49 | surface_properties *get_surface_properties(layer::instance_private_data &instance_data, VkSurfaceKHR surface);
50 |
51 | /**
52 | * @brief Allocates a surface specific swapchain.
53 | *
54 | * @param surface The surface for which a swapchain is allocated.
55 | * @param dev_data The device specific data.
56 | * @param pAllocator The allocator from which to allocate any memory.
57 | *
58 | * @return nullptr on failure.
59 | */
60 | util::unique_ptr allocate_surface_swapchain(VkSurfaceKHR surface, layer::device_private_data &dev_data,
61 | const VkAllocationCallbacks *pAllocator);
62 |
63 | /**
64 | * @brief Destroys a swapchain and frees memory. Used with @ref allocate_surface_swapchain.
65 | *
66 | * @param swapchain Pointer to the swapchain to destroy.
67 | * @param dev_data The device specific data.
68 | * @param pAllocator The allocator to use for freeing memory.
69 | */
70 | void destroy_surface_swapchain(swapchain_base *swapchain, layer::device_private_data &dev_data,
71 | const VkAllocationCallbacks *pAllocator);
72 |
73 | /**
74 | * @brief Return which platforms the layer can handle for an instance constructed in the specified way.
75 | *
76 | * @details This function looks at the extensions specified in @p pCreateInfo and based on this returns a list of
77 | * platforms that the layer can support. For example, if the @c pCreateInfo.ppEnabledExtensionNames contains the string
78 | * "VK_EXT_headless_surface" then the returned platform set will contain @c VK_ICD_WSI_PLATFORM_HEADLESS.
79 | *
80 | * @param pCreateInfo Structure used when creating the instance in vkCreateInstance().
81 | *
82 | * @return A list of WS platforms supported by the layer.
83 | */
84 | util::wsi_platform_set find_enabled_layer_platforms(const VkInstanceCreateInfo *pCreateInfo);
85 |
86 | /**
87 | * @brief Add extra extensions that the layer requires to support the specified list of enabled platforms.
88 | *
89 | * @details Check whether @p phys_dev has support for the extensions required by the layer in order to support the
90 | * platforms it implements. The extensions that the layer requires to operate are added to @p extensions_to_enable.
91 | *
92 | * @param[in] phys_dev The physical device to check.
93 | * @param[in] enabled_platforms All the platforms that the layer must enable for @p phys_dev.
94 | * @param[in,out] extensions_to_enable All the extensions required by the layer are added to this list.
95 | *
96 | * @retval @c VK_SUCCESS if the operation was successful.
97 | */
98 | VkResult add_device_extensions_required_by_layer(VkPhysicalDevice phys_dev,
99 | const util::wsi_platform_set enabled_platforms,
100 | util::extension_list &extensions_to_enable);
101 |
102 | /**
103 | * @brief Add required instance extensions by the layer.
104 | *
105 | * @param[in] enabled_platforms All the enabled platforms for the current instance.
106 | * @param[in,out] extensions_to_enable All the extensions required by the layer are added to this list.
107 | *
108 | * @retval @c VK_SUCCESS if the operation was successful.
109 | */
110 | VkResult add_instance_extensions_required_by_layer(const util::wsi_platform_set enabled_platforms,
111 | util::extension_list &extensions_to_enable);
112 |
113 | /**
114 | * @brief Return a function pointer for surface specific functions.
115 | *
116 | * @details This function iterates through the supported platforms and queries them for the
117 | * implementation of the @p name function.
118 | *
119 | * @param name The name of the target function
120 | * @param instance_data The instance specific data.
121 | *
122 | * @return A pointer to the implementation of the @p name function or null pointer in case this
123 | * function isn't implemented for any platform.
124 | */
125 | PFN_vkVoidFunction get_proc_addr(const char *name, const layer::instance_private_data &instance_data);
126 |
127 | } // namespace wsi
128 |
--------------------------------------------------------------------------------
/wsi/x11/surface.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /** @file
26 | * @brief Implementation of a x11 WSI Surface
27 | */
28 |
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include "surface.hpp"
34 | #include "swapchain.hpp"
35 | #include "surface_properties.hpp"
36 |
37 | namespace wsi
38 | {
39 | namespace x11
40 | {
41 |
42 | struct surface::init_parameters
43 | {
44 | const util::allocator &allocator;
45 | xcb_connection_t *connection;
46 | xcb_window_t window;
47 | };
48 |
49 | surface::surface(const init_parameters ¶ms)
50 | : wsi::surface()
51 | , m_connection(params.connection)
52 | , m_window(params.window)
53 | , properties(this, params.allocator)
54 | {
55 | }
56 |
57 | surface::~surface()
58 | {
59 | }
60 |
61 | bool surface::init()
62 | {
63 | auto dri3_cookie = xcb_dri3_query_version_unchecked(m_connection, 1, 2);
64 | auto dri3_reply = xcb_dri3_query_version_reply(m_connection, dri3_cookie, nullptr);
65 | auto has_dri3 = dri3_reply && (dri3_reply->major_version > 1 || dri3_reply->minor_version >= 2);
66 | free(dri3_reply);
67 |
68 | auto present_cookie = xcb_present_query_version_unchecked(m_connection, 1, 2);
69 | auto present_reply = xcb_present_query_version_reply(m_connection, present_cookie, nullptr);
70 | auto has_present = present_reply && (present_reply->major_version > 1 || present_reply->minor_version >= 2);
71 | free(present_reply);
72 |
73 | if (!has_dri3 || !has_present)
74 | {
75 | WSI_LOG_ERROR("DRI3 extension not present");
76 | return false;
77 | }
78 |
79 | return true;
80 | }
81 |
82 | bool surface::get_size_and_depth(uint32_t *width, uint32_t *height, int *depth)
83 | {
84 | auto cookie = xcb_get_geometry(m_connection, m_window);
85 | if (auto *geom = xcb_get_geometry_reply(m_connection, cookie, nullptr))
86 | {
87 | *width = static_cast(geom->width);
88 | *height = static_cast(geom->height);
89 | *depth = static_cast(geom->depth);
90 | free(geom);
91 | return true;
92 | }
93 | return false;
94 | }
95 |
96 | wsi::surface_properties &surface::get_properties()
97 | {
98 | return properties;
99 | }
100 |
101 | util::unique_ptr surface::allocate_swapchain(layer::device_private_data &dev_data,
102 | const VkAllocationCallbacks *allocator)
103 | {
104 | util::allocator alloc{ dev_data.get_allocator(), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT, allocator };
105 | auto chain = util::unique_ptr(alloc.make_unique(dev_data, allocator, this));
106 |
107 | return chain;
108 | }
109 |
110 | util::unique_ptr surface::make_surface(const util::allocator &allocator, xcb_connection_t *conn,
111 | xcb_window_t window)
112 | {
113 | init_parameters params{ allocator, conn, window };
114 | auto wsi_surface = allocator.make_unique(params);
115 | if (wsi_surface != nullptr)
116 | {
117 | if (wsi_surface->init())
118 | {
119 | return wsi_surface;
120 | }
121 | }
122 | return nullptr;
123 | }
124 |
125 | } /* namespace x11 */
126 | } /* namespace wsi */
127 |
--------------------------------------------------------------------------------
/wsi/x11/surface.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /** @file
26 | * @brief Definitions for a x11 WSI Surface
27 | */
28 |
29 | #pragma once
30 | #include
31 | #include
32 | #include
33 | #include "wsi/surface.hpp"
34 | #include "surface_properties.hpp"
35 |
36 | namespace wsi
37 | {
38 | namespace x11
39 | {
40 |
41 | class surface : public wsi::surface
42 | {
43 | public:
44 | /**
45 | * @brief Initialize the WSI surface.
46 | *
47 | * @return true on success, false otherwise.
48 | */
49 | bool init();
50 |
51 | surface() = delete;
52 | struct init_parameters;
53 |
54 | surface(const init_parameters &);
55 | ~surface();
56 |
57 | wsi::surface_properties &get_properties() override;
58 | util::unique_ptr allocate_swapchain(layer::device_private_data &dev_data,
59 | const VkAllocationCallbacks *allocator) override;
60 | static util::unique_ptr make_surface(const util::allocator &allocator, xcb_connection_t *conn,
61 | xcb_window_t window);
62 |
63 | bool get_size_and_depth(uint32_t *width, uint32_t *height, int *depth);
64 |
65 | xcb_connection_t *get_connection()
66 | {
67 | return m_connection;
68 | }
69 |
70 | xcb_window_t get_window()
71 | {
72 | return m_window;
73 | };
74 |
75 | private:
76 | xcb_connection_t *m_connection;
77 | xcb_window_t m_window;
78 | /** Surface properties specific to the X11 surface. */
79 | surface_properties properties;
80 | };
81 |
82 | } /* namespace x11 */
83 | } /* namespace wsi */
84 |
--------------------------------------------------------------------------------
/wsi/x11/surface_properties.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2019, 2021-2022 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | #pragma once
26 |
27 | #include
28 | #include
29 |
30 | namespace wsi
31 | {
32 | namespace x11
33 | {
34 |
35 | class surface;
36 |
37 | class surface_properties : public wsi::surface_properties
38 | {
39 | public:
40 | surface_properties(surface *wsi_surface, const util::allocator &alloc);
41 |
42 | static surface_properties &get_instance();
43 |
44 | VkResult get_surface_capabilities(VkPhysicalDevice physical_device,
45 | VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) override;
46 | VkResult get_surface_capabilities(VkPhysicalDevice physical_device,
47 | const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
48 | VkSurfaceCapabilities2KHR *pSurfaceCapabilities) override;
49 | VkResult get_surface_formats(VkPhysicalDevice physical_device, uint32_t *surfaceFormatCount,
50 | VkSurfaceFormatKHR *surfaceFormats,
51 | VkSurfaceFormat2KHR *extended_surface_formats) override;
52 | VkResult get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
53 | uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) override;
54 |
55 | VkResult get_required_device_extensions(util::extension_list &extension_list) override;
56 |
57 | VkResult get_required_instance_extensions(util::extension_list &extension_list) override;
58 |
59 | PFN_vkVoidFunction get_proc_addr(const char *name) override;
60 |
61 | bool is_surface_extension_enabled(const layer::instance_private_data &instance_data) override;
62 |
63 | bool is_compatible_present_modes(VkPresentModeKHR present_mode_a, VkPresentModeKHR present_mode_b) override;
64 |
65 | #if VULKAN_WSI_LAYER_EXPERIMENTAL
66 | void get_present_timing_surface_caps(VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) override;
67 | #endif
68 | private:
69 | surface_properties();
70 |
71 | /** If the properties are specific to a @ref wsi::wayland::surface this is a pointer to it. Can be nullptr for
72 | * generic Wayland surface properties.
73 | */
74 | surface *specific_surface;
75 |
76 | /* List of supported presentation modes */
77 | std::array m_supported_modes;
78 |
79 | /* Stores compatible presentation modes */
80 | compatible_present_modes<2> m_compatible_present_modes;
81 |
82 | void populate_present_mode_compatibilities() override;
83 |
84 | void get_surface_present_scaling_and_gravity(VkSurfacePresentScalingCapabilitiesEXT *scaling_capabilities) override;
85 | };
86 |
87 | } // namespace x11
88 | } // namespace wsi
89 |
--------------------------------------------------------------------------------
/wsi/x11/swapchain.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2019, 2021-2022 Arm Limited.
3 | *
4 | * SPDX-License-Identifier: MIT
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | /**
26 | * @file swapchain.hpp
27 | *
28 | * @brief Contains the class definition for a x11 swapchain.
29 | */
30 |
31 | #pragma once
32 |
33 | #include "surface.hpp"
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include
43 | #include
44 |
45 | namespace wsi
46 | {
47 | namespace x11
48 | {
49 |
50 | using pfnAHardwareBuffer_release = void (*)(AHardwareBuffer *);
51 | using pfnAHardwareBuffer_sendHandleToUnixSocket = int (*)(AHardwareBuffer *, int);
52 |
53 | /**
54 | * @brief x11 swapchain class.
55 | *
56 | * This class is mostly empty, because all the swapchain stuff is handled by the swapchain class,
57 | * which we inherit. This class only provides a way to create an image and page-flip ops.
58 | */
59 | class swapchain : public wsi::swapchain_base
60 | {
61 | public:
62 | explicit swapchain(layer::device_private_data &dev_data, const VkAllocationCallbacks *pAllocator,
63 | surface *wsi_surface);
64 |
65 | ~swapchain();
66 |
67 | protected:
68 | /**
69 | * @brief Platform specific init
70 | */
71 | VkResult init_platform(VkDevice device, const VkSwapchainCreateInfoKHR *swapchain_create_info,
72 | bool &use_presentation_thread) override;
73 | /**
74 | * @brief Allocates and binds a new swapchain image.
75 | *
76 | * @param image_create_info Data to be used to create the image.
77 | * @param image Handle to the image.
78 | *
79 | * @return Returns VK_SUCCESS on success, otherwise an appropriate error code.
80 | */
81 | VkResult allocate_and_bind_swapchain_image(VkImageCreateInfo image_create_info, swapchain_image &image) override;
82 |
83 | /**
84 | * @brief Creates a new swapchain image.
85 | *
86 | * @param image_create_info Data to be used to create the image.
87 | * @param image Handle to the image.
88 | *
89 | * @return If image creation is successful returns VK_SUCCESS, otherwise
90 | * will return VK_ERROR_OUT_OF_DEVICE_MEMORY or VK_ERROR_INITIALIZATION_FAILED
91 | * depending on the error that occurred.
92 | */
93 | VkResult create_swapchain_image(VkImageCreateInfo image_create_info, swapchain_image &image) override;
94 |
95 | /**
96 | * @brief Method to present and image
97 | *
98 | * It sends the next image for presentation to the presentation engine.
99 | *
100 | * @param pending_present Information on the pending present request.
101 | */
102 | void present_image(const pending_present_request &pending_present) override;
103 |
104 | /**
105 | * @brief Method to release a swapchain image
106 | *
107 | * @param image Handle to the image about to be released.
108 | */
109 | void destroy_image(wsi::swapchain_image &image) override;
110 |
111 | /**
112 | * @brief Sets the present payload for a swapchain image.
113 | *
114 | * @param[in] image The swapchain image for which to set a present payload.
115 | * @param queue A Vulkan queue that can be used for any Vulkan commands needed.
116 | * @param[in] sem_payload Array of Vulkan semaphores that constitute the payload.
117 | * @param[in] submission_pnext Chain of pointers to attach to the payload submission.
118 | *
119 | * @return VK_SUCCESS on success or an error code otherwise.
120 | */
121 | VkResult image_set_present_payload(swapchain_image &image, VkQueue queue, const queue_submit_semaphores &semaphores,
122 | const void *submission_pnext) override;
123 |
124 | VkResult image_wait_present(swapchain_image &image, uint64_t timeout) override;
125 |
126 | /**
127 | * @brief Bind image to a swapchain
128 | *
129 | * @param device is the logical device that owns the images and memory.
130 | * @param bind_image_mem_info details the image we want to bind.
131 | * @param bind_sc_info describes the swapchain memory to bind to.
132 | *
133 | * @return VK_SUCCESS on success, otherwise on failure VK_ERROR_OUT_OF_HOST_MEMORY or VK_ERROR_OUT_OF_DEVICE_MEMORY
134 | * can be returned.
135 | */
136 | VkResult bind_swapchain_image(VkDevice &device, const VkBindImageMemoryInfo *bind_image_mem_info,
137 | const VkBindImageMemorySwapchainInfoKHR *bind_sc_info) override;
138 |
139 | /**
140 | * @brief Method to check if there are any free images
141 | *
142 | * @return true if any images are free, otherwise false.
143 | */
144 | bool free_image_found();
145 |
146 | /**
147 | * @brief Hook for any actions to free up a buffer for acquire
148 | *
149 | * @param[in,out] timeout time to wait, in nanoseconds. 0 doesn't block,
150 | * UINT64_MAX waits indefinitely. The timeout should
151 | * be updated if a sleep is required - this can
152 | * be set to 0 if the semaphore is now not expected
153 | * block.
154 | */
155 | VkResult get_free_buffer(uint64_t *timeout) override;
156 |
157 | private:
158 | xcb_connection_t *m_connection;
159 | xcb_window_t m_window;
160 |
161 | surface *m_surface;
162 | uint64_t m_send_sbc;
163 | uint64_t m_target_msc;
164 | uint64_t m_last_present_msc;
165 |
166 | xcb_special_event_t *m_special_event;
167 | VkPhysicalDeviceMemoryProperties2 m_memory_props;
168 |
169 | xcb_pixmap_t create_pixmap(swapchain_image &image);
170 |
171 | void present_event_thread();
172 | bool m_present_event_thread_run;
173 | std::thread m_present_event_thread;
174 | std::mutex m_thread_status_lock;
175 | std::condition_variable m_thread_status_cond;
176 | util::ring_buffer m_free_buffer_pool;
177 |
178 | pfnAHardwareBuffer_release HardwareBuffer_release;
179 | pfnAHardwareBuffer_sendHandleToUnixSocket HardwareBuffer_sendHandleToUnixSocket;
180 | };
181 |
182 | } /* namespace x11 */
183 | } /* namespace wsi */
184 |
--------------------------------------------------------------------------------