File: feature_not_present.py

package info (click to toggle)
vulkan-validationlayers 1.4.328.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 49,412 kB
  • sloc: cpp: 615,223; python: 12,115; sh: 24; makefile: 20; xml: 14
file content (125 lines) | stat: -rw-r--r-- 6,029 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/usr/bin/python3 -i
#
# Copyright (c) 2015-2025 The Khronos Group Inc.
# Copyright (c) 2015-2025 Valve Corporation
# Copyright (c) 2015-2025 LunarG, Inc.
# Copyright (c) 2015-2025 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


import os
from base_generator import BaseGenerator
from generators.generator_utils import PlatformGuardHelper

class FeatureNotPresentGenerator(BaseGenerator):
    def __init__(self):
        BaseGenerator.__init__(self)

    def generate(self):
        out = []
        out.append(f'''// *** THIS FILE IS GENERATED - DO NOT EDIT ***
            // See {os.path.basename(__file__)} for modifications

            /***************************************************************************
            *
            * Copyright (c) 2025 Valve Corporation
            * Copyright (c) 2025 LunarG, Inc.
            *
            * Licensed under the Apache License, Version 2.0 (the "License");
            * you may not use this file except in compliance with the License.
            * You may obtain a copy of the License at
            *
            *     http://www.apache.org/licenses/LICENSE-2.0
            *
            * Unless required by applicable law or agreed to in writing, software
            * distributed under the License is distributed on an "AS IS" BASIS,
            * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            * See the License for the specific language governing permissions and
            * limitations under the License.
            ****************************************************************************/\n\n''')
        out.append(self.generateSource())
        self.write("".join(out))

    def generateSource(self):
        out = []
        guard_helper = PlatformGuardHelper()
        out.append('''
            #include "chassis/dispatch_object.h"
            #include "generated/dispatch_functions.h"
            #include "error_message/error_location.h"

            namespace vvl {
            namespace dispatch {

            void Instance::ReportErrorFeatureNotPresent(VkPhysicalDevice gpu, const VkDeviceCreateInfo &create_info) {
                std::stringstream ss;
                ss << "returned VK_ERROR_FEATURE_NOT_PRESENT because the following features were not supported on this physical device:\\n";

                // First do 1.0 VkPhysicalDeviceFeatures
                {
                    const auto *features2 = vku::FindStructInPNextChain<VkPhysicalDeviceFeatures2>(create_info.pNext);
                    const VkPhysicalDeviceFeatures &enabling = create_info.pEnabledFeatures ? *create_info.pEnabledFeatures : features2->features;

                    VkPhysicalDeviceFeatures supported = {};
                    DispatchGetPhysicalDeviceFeatures(gpu, &supported);
        ''')

        for member in self.vk.structs['VkPhysicalDeviceFeatures'].members:
            out.append(f'''if (enabling.{member.name} && !supported.{member.name}) {{
                               ss << "VkPhysicalDeviceFeatures::{member.name} is not supported\\n";
                           }}
                        ''')
        out.append('}')
        out.append('''
                    VkPhysicalDeviceFeatures2 features_2 = vku::InitStructHelper();
                    for (const VkBaseInStructure* current = static_cast<const VkBaseInStructure*>(create_info.pNext); current != nullptr; current = current->pNext) {
                        switch(current->sType) {
                    ''')

        feature_structs = self.vk.structs['VkPhysicalDeviceFeatures2'].extendedBy
        for extending_struct_name in feature_structs:
            # TODO - When script is ran by itself this works fine, but when ran together, "VkPhysicalDeviceFeatures" is somehow added to extendedBy
            # Seems to be an issue with the caching, likely the VulkanObject is being overwritten somewhere
            if extending_struct_name == 'VkPhysicalDeviceFeatures':
                continue

            extending_struct = self.vk.structs[extending_struct_name]
            out.extend(guard_helper.add_guard(extending_struct.protect))
            out.append(f'''case {extending_struct.sType}: {{
                            {extending_struct_name} supported = vku::InitStructHelper();
                            features_2.pNext = &supported;
                            DispatchGetPhysicalDeviceFeatures2(gpu, &features_2);
                            const {extending_struct_name} *enabling = reinterpret_cast<const {extending_struct_name} *>(current);
                       ''')

            for member in [x for x in extending_struct.members if x.type == 'VkBool32']:
                out.append(f'''if (enabling->{member.name} && !supported.{member.name}) {{
                                ss << "{extending_struct_name}::{member.name} is not supported\\n";
                            }}
                            ''')
            out.append('break;\n}\n')
            out.extend(guard_helper.add_guard(None))
        out.append('''
                        default:
                            break;
                        }
                    }

                    Location loc(vvl::Func::vkCreateDevice);
                    LogWarning("WARNING-vkCreateDevice-FeatureNotPresent", instance, loc, "%s", ss.str().c_str());
                }  // ReportErrorFeatureNotPresent
                }  // namespace dispatch
                }  // namespace vvl
                ''')
        return "".join(out)