This is page 3 of 9. Use http://codebase.md/mehmetoguzderin/shaderc-vkrunner-mcp?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .devcontainer
│ ├── devcontainer.json
│ ├── docker-compose.yml
│ └── Dockerfile
├── .gitattributes
├── .github
│ └── workflows
│ └── build-push-image.yml
├── .gitignore
├── .vscode
│ └── mcp.json
├── Cargo.lock
├── Cargo.toml
├── Dockerfile
├── LICENSE
├── README.adoc
├── shaderc-vkrunner-mcp.jpg
├── src
│ └── main.rs
└── vkrunner
├── .editorconfig
├── .gitignore
├── .gitlab-ci.yml
├── build.rs
├── Cargo.toml
├── COPYING
├── examples
│ ├── compute-shader.shader_test
│ ├── cooperative-matrix.shader_test
│ ├── depth-buffer.shader_test
│ ├── desc_set_and_binding.shader_test
│ ├── entrypoint.shader_test
│ ├── float-framebuffer.shader_test
│ ├── frexp.shader_test
│ ├── geometry.shader_test
│ ├── indices.shader_test
│ ├── layouts.shader_test
│ ├── properties.shader_test
│ ├── push-constants.shader_test
│ ├── require-subgroup-size.shader_test
│ ├── row-major.shader_test
│ ├── spirv.shader_test
│ ├── ssbo.shader_test
│ ├── tolerance.shader_test
│ ├── tricolore.shader_test
│ ├── ubo.shader_test
│ ├── vertex-data-piglit.shader_test
│ └── vertex-data.shader_test
├── include
│ ├── vk_video
│ │ ├── vulkan_video_codec_av1std_decode.h
│ │ ├── vulkan_video_codec_av1std_encode.h
│ │ ├── vulkan_video_codec_av1std.h
│ │ ├── vulkan_video_codec_h264std_decode.h
│ │ ├── vulkan_video_codec_h264std_encode.h
│ │ ├── vulkan_video_codec_h264std.h
│ │ ├── vulkan_video_codec_h265std_decode.h
│ │ ├── vulkan_video_codec_h265std_encode.h
│ │ ├── vulkan_video_codec_h265std.h
│ │ └── vulkan_video_codecs_common.h
│ └── vulkan
│ ├── vk_platform.h
│ ├── vulkan_core.h
│ └── vulkan.h
├── precompile-script.py
├── README.md
├── scripts
│ └── update-vulkan.sh
├── src
│ └── main.rs
├── test-build.sh
└── vkrunner
├── allocate_store.rs
├── buffer.rs
├── compiler
│ └── fake_process.rs
├── compiler.rs
├── config.rs
├── context.rs
├── enum_table.rs
├── env_var_test.rs
├── executor.rs
├── fake_vulkan.rs
├── features.rs
├── flush_memory.rs
├── format_table.rs
├── format.rs
├── half_float.rs
├── hex.rs
├── inspect.rs
├── lib.rs
├── logger.rs
├── make-enums.py
├── make-features.py
├── make-formats.py
├── make-pipeline-key-data.py
├── make-vulkan-funcs-data.py
├── parse_num.rs
├── pipeline_key_data.rs
├── pipeline_key.rs
├── pipeline_set.rs
├── requirements.rs
├── result.rs
├── script.rs
├── shader_stage.rs
├── slot.rs
├── small_float.rs
├── source.rs
├── stream.rs
├── temp_file.rs
├── tester.rs
├── tolerance.rs
├── util.rs
├── vbo.rs
├── vk.rs
├── vulkan_funcs_data.rs
├── vulkan_funcs.rs
├── window_format.rs
└── window.rs
```
# Files
--------------------------------------------------------------------------------
/vkrunner/vkrunner/executor.rs:
--------------------------------------------------------------------------------
```rust
1 | // vkrunner
2 | //
3 | // Copyright (C) 2018 Intel Corporation
4 | // Copyright 2023 Neil Roberts
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a
7 | // copy of this software and associated documentation files (the "Software"),
8 | // to deal in the Software without restriction, including without limitation
9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 | // and/or sell copies of the Software, and to permit persons to whom the
11 | // Software is furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice (including the next
14 | // paragraph) shall be included in all copies or substantial portions of the
15 | // 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
20 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 | // DEALINGS IN THE SOFTWARE.
24 |
25 | use crate::vulkan_funcs;
26 | use crate::context::{self, Context};
27 | use crate::window::{Window, WindowError};
28 | use crate::config::Config;
29 | use crate::script::Script;
30 | use crate::source::Source;
31 | use crate::result;
32 | use crate::vk;
33 | use crate::requirements::Requirements;
34 | use crate::pipeline_set::{self, PipelineSet};
35 | use crate::tester;
36 | use crate::requirements;
37 | use std::ffi::c_void;
38 | use std::fmt;
39 | use std::rc::Rc;
40 | use std::cell::RefCell;
41 |
42 | #[derive(Debug)]
43 | pub(crate) enum Error {
44 | Context(context::Error),
45 | Window(WindowError),
46 | PipelineError(pipeline_set::Error),
47 | TestError(tester::Error),
48 | ExternalDeviceRequirementsError(requirements::Error),
49 | }
50 |
51 | impl Error {
52 | pub fn result(&self) -> result::Result {
53 | match self {
54 | Error::Context(e) => e.result(),
55 | Error::Window(e) => e.result(),
56 | Error::ExternalDeviceRequirementsError(e) => e.result(),
57 | Error::PipelineError(_) => result::Result::Fail,
58 | Error::TestError(_) => result::Result::Fail,
59 | }
60 | }
61 | }
62 |
63 | impl From<context::Error> for Error {
64 | fn from(error: context::Error) -> Error {
65 | Error::Context(error)
66 | }
67 | }
68 |
69 | impl From<WindowError> for Error {
70 | fn from(error: WindowError) -> Error {
71 | Error::Window(error)
72 | }
73 | }
74 |
75 | impl From<pipeline_set::Error> for Error {
76 | fn from(error: pipeline_set::Error) -> Error {
77 | Error::PipelineError(error)
78 | }
79 | }
80 |
81 | impl From<tester::Error> for Error {
82 | fn from(error: tester::Error) -> Error {
83 | Error::TestError(error)
84 | }
85 | }
86 |
87 | impl fmt::Display for Error {
88 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
89 | match self {
90 | Error::Context(e) => e.fmt(f),
91 | Error::Window(e) => e.fmt(f),
92 | Error::PipelineError(e) => e.fmt(f),
93 | Error::TestError(e) => e.fmt(f),
94 | Error::ExternalDeviceRequirementsError(e) => e.fmt(f),
95 | }
96 | }
97 | }
98 |
99 | #[derive(Debug)]
100 | struct ExternalData {
101 | get_instance_proc_cb: vulkan_funcs::GetInstanceProcFunc,
102 | user_data: *const c_void,
103 | physical_device: vk::VkPhysicalDevice,
104 | queue_family: u32,
105 | vk_device: vk::VkDevice,
106 | }
107 |
108 | #[derive(Debug)]
109 | pub struct Executor {
110 | config: Rc<RefCell<Config>>,
111 |
112 | window: Option<Rc<Window>>,
113 | context: Option<Rc<Context>>,
114 | // A cache of the requirements that the context was created with.
115 | // Used to detect if the requirements have changed. This won’t be
116 | // used if the context is external.
117 | requirements: Requirements,
118 |
119 | external: Option<ExternalData>,
120 | }
121 |
122 | impl Executor {
123 | fn reset_window(&mut self) {
124 | self.window = None;
125 | }
126 |
127 | fn reset_context(&mut self) {
128 | self.reset_window();
129 | self.context = None;
130 | }
131 |
132 | fn context_is_compatible(&self, script: &Script) -> bool {
133 | // If the device is created externally then it’s up to the
134 | // caller to ensure the device has all the necessary features
135 | // enabled.
136 | if self.external.is_some() {
137 | return true;
138 | }
139 |
140 | match self.context {
141 | Some(_) => self.requirements.eq(script.requirements()),
142 | None => false,
143 | }
144 | }
145 |
146 | pub fn new(config: Rc<RefCell<Config>>) -> Executor {
147 | Executor {
148 | config,
149 |
150 | window: None,
151 | context: None,
152 | requirements: Requirements::new(),
153 | external: None,
154 | }
155 | }
156 |
157 | pub fn set_device(
158 | &mut self,
159 | get_instance_proc_cb: vulkan_funcs::GetInstanceProcFunc,
160 | user_data: *const c_void,
161 | physical_device: vk::VkPhysicalDevice,
162 | queue_family: u32,
163 | vk_device: vk::VkDevice,
164 | ) {
165 | self.reset_context();
166 |
167 | self.external = Some(ExternalData {
168 | get_instance_proc_cb,
169 | user_data,
170 | physical_device,
171 | queue_family,
172 | vk_device,
173 | });
174 | }
175 |
176 | fn create_context(
177 | &self,
178 | requirements: &Requirements,
179 | ) -> Result<Context, Error> {
180 | match &self.external {
181 | Some(e) => {
182 | Ok(Context::new_with_device(
183 | e.get_instance_proc_cb,
184 | e.user_data,
185 | e.physical_device,
186 | e.queue_family,
187 | e.vk_device,
188 | )?)
189 | },
190 | None => Ok(Context::new(
191 | requirements,
192 | self.config.borrow().device_id()
193 | )?),
194 | }
195 | }
196 |
197 | fn context_for_script(
198 | &mut self,
199 | script: &Script,
200 | ) -> Result<Rc<Context>, Error> {
201 | // Recreate the context if the features or extensions have changed
202 | if !self.context_is_compatible(script) {
203 | self.reset_context();
204 | }
205 |
206 | match &self.context {
207 | Some(c) => Ok(Rc::clone(c)),
208 | None => {
209 | self.requirements.clone_from(script.requirements());
210 | let context = self.create_context(&self.requirements)?;
211 |
212 | Ok(Rc::clone(self.context.insert(Rc::new(context))))
213 | }
214 | }
215 | }
216 |
217 | fn window_for_script(
218 | &mut self,
219 | script: &Script,
220 | context: Rc<Context>,
221 | ) -> Result<Rc<Window>, Error> {
222 | // Recreate the window if the framebuffer format is different
223 | if let Some(window) = &self.window {
224 | if !window.format().eq(script.window_format()) {
225 | self.reset_window();
226 | }
227 | }
228 |
229 | match &self.window {
230 | Some(w) => Ok(Rc::clone(w)),
231 | None => Ok(Rc::clone(self.window.insert(Rc::new(Window::new(
232 | context,
233 | script.window_format(),
234 | )?)))),
235 | }
236 | }
237 |
238 | fn handle_execute_result(
239 | &self,
240 | result: Result<(), Error>
241 | ) -> result::Result {
242 | match result {
243 | Ok(()) => result::Result::Pass,
244 | Err(e) => {
245 | use std::fmt::Write;
246 | let _ = writeln!(
247 | self.config.borrow_mut().logger().borrow_mut(),
248 | "{}",
249 | e
250 | );
251 | e.result()
252 | }
253 | }
254 | }
255 |
256 | fn execute_script_or_error(
257 | &mut self,
258 | script: &Script
259 | ) -> Result<(), Error> {
260 | let context = self.context_for_script(script)?;
261 |
262 | if self.external.is_some() {
263 | if let Err(e) = script.requirements().check(
264 | context.instance(),
265 | context.physical_device(),
266 | ) {
267 | return Err(Error::ExternalDeviceRequirementsError(e));
268 | }
269 | }
270 |
271 | let window = self.window_for_script(script, Rc::clone(&context))?;
272 |
273 | let pipeline_set = PipelineSet::new(
274 | &mut self.config.borrow().logger().borrow_mut(),
275 | Rc::clone(&window),
276 | script,
277 | self.config.borrow().show_disassembly(),
278 | )?;
279 |
280 | tester::run(
281 | window.as_ref(),
282 | &pipeline_set,
283 | script,
284 | self.config.borrow().inspector().clone(),
285 | )?;
286 |
287 | Ok(())
288 | }
289 |
290 | pub fn execute_script(
291 | &mut self,
292 | script: &Script
293 | ) -> result::Result {
294 | let res = self.execute_script_or_error(script);
295 | self.handle_execute_result(res)
296 | }
297 |
298 | pub fn execute(
299 | &mut self,
300 | source: &Source,
301 | ) -> result::Result {
302 | let load_res = Script::load(&self.config.borrow(), source);
303 |
304 | load_res
305 | .and_then(|script| Some(self.execute_script(&script)))
306 | .unwrap_or(result::Result::Fail)
307 | }
308 | }
309 |
310 | #[cfg(test)]
311 | mod test {
312 | use super::*;
313 | use crate::fake_vulkan::FakeVulkan;
314 | use crate::config::Config;
315 | use std::ffi::c_char;
316 |
317 | fn create_fake_vulkan() -> Box<FakeVulkan> {
318 | let mut fake_vulkan = FakeVulkan::new();
319 | fake_vulkan.physical_devices.push(Default::default());
320 | fake_vulkan.physical_devices[0].features.wideLines = vk::VK_TRUE;
321 | fake_vulkan.physical_devices[0].format_properties.insert(
322 | vk::VK_FORMAT_B8G8R8A8_UNORM,
323 | vk::VkFormatProperties {
324 | linearTilingFeatures: 0,
325 | optimalTilingFeatures:
326 | vk::VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT
327 | | vk::VK_FORMAT_FEATURE_BLIT_SRC_BIT,
328 | bufferFeatures: 0,
329 | },
330 | );
331 | fake_vulkan.physical_devices[0].format_properties.insert(
332 | vk::VK_FORMAT_R8_UNORM,
333 | vk::VkFormatProperties {
334 | linearTilingFeatures: 0,
335 | optimalTilingFeatures:
336 | vk::VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT
337 | | vk::VK_FORMAT_FEATURE_BLIT_SRC_BIT,
338 | bufferFeatures: 0,
339 | },
340 | );
341 |
342 | let memory_properties =
343 | &mut fake_vulkan.physical_devices[0].memory_properties;
344 | memory_properties.memoryTypes[0].propertyFlags =
345 | vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
346 | memory_properties.memoryTypeCount = 1;
347 | fake_vulkan.memory_requirements.memoryTypeBits = 1;
348 |
349 | fake_vulkan
350 | }
351 |
352 | #[test]
353 | fn recreate_resources() {
354 | let fake_vulkan = create_fake_vulkan();
355 |
356 | let config = Rc::new(RefCell::new(Config::new()));
357 |
358 | let mut executor = Executor::new(Rc::clone(&config));
359 |
360 | fake_vulkan.set_override();
361 | assert_eq!(
362 | executor.execute(&Source::from_string("".to_string())),
363 | result::Result::Pass,
364 | );
365 |
366 | let context = Rc::clone(executor.context.as_ref().unwrap());
367 | let window = Rc::clone(&executor.window.as_ref().unwrap());
368 |
369 | // Run another script that has the same requirements
370 | assert_eq!(
371 | executor.execute(&Source::from_string(
372 | "[test]\n\
373 | draw rect -1 -1 2 2".to_string()
374 | )),
375 | result::Result::Pass,
376 | );
377 |
378 | // The context and window shouldn’t have changed
379 | assert!(Rc::ptr_eq(&context, executor.context.as_ref().unwrap()));
380 | assert!(Rc::ptr_eq(&window, executor.window.as_ref().unwrap()));
381 |
382 | // Run a script with different requirements
383 | fake_vulkan.set_override();
384 | assert_eq!(
385 | executor.execute(&Source::from_string(
386 | "[require]\n\
387 | wideLines\n\
388 | [test]\n\
389 | draw rect -1 -1 2 2".to_string()
390 | )),
391 | result::Result::Pass,
392 | );
393 |
394 | // The context and window should have changed
395 | assert!(!Rc::ptr_eq(&context, executor.context.as_ref().unwrap()));
396 | assert!(!Rc::ptr_eq(&window, executor.window.as_ref().unwrap()));
397 |
398 | let context = Rc::clone(executor.context.as_ref().unwrap());
399 | let window = Rc::clone(&executor.window.as_ref().unwrap());
400 |
401 | // Run the same script with a different framebuffer format
402 | assert_eq!(
403 | executor.execute(&Source::from_string(
404 | "[require]\n\
405 | wideLines\n\
406 | framebuffer R8_UNORM\n\
407 | [test]\n\
408 | draw rect -1 -1 2 2".to_string()
409 | )),
410 | result::Result::Pass,
411 | );
412 |
413 | // The context should stay the same but the framebuffer should
414 | // have changed
415 | assert!(Rc::ptr_eq(&context, executor.context.as_ref().unwrap()));
416 | assert!(!Rc::ptr_eq(&window, executor.window.as_ref().unwrap()));
417 | }
418 |
419 | extern "C" fn get_instance_proc_cb(
420 | func_name: *const c_char,
421 | user_data: *const c_void,
422 | ) -> *const c_void {
423 | unsafe {
424 | let fake_vulkan = &*(user_data as *const FakeVulkan);
425 |
426 | let func = fake_vulkan.get_function(func_name);
427 |
428 | std::mem::transmute(func)
429 | }
430 | }
431 |
432 | #[test]
433 | fn external_device() {
434 | let fake_vulkan = create_fake_vulkan();
435 |
436 | fake_vulkan.set_override();
437 | let context = Context::new(&Requirements::new(), None).unwrap();
438 |
439 | let config = Rc::new(RefCell::new(Config::new()));
440 |
441 | let mut executor = Executor::new(Rc::clone(&config));
442 |
443 | let (queue_family, _) = FakeVulkan::unmake_queue(context.queue());
444 |
445 | executor.set_device(
446 | get_instance_proc_cb,
447 | (fake_vulkan.as_ref() as *const FakeVulkan).cast(),
448 | context.physical_device(),
449 | queue_family,
450 | context.vk_device()
451 | );
452 |
453 | assert_eq!(
454 | executor.execute(&Source::from_string("".to_string())),
455 | result::Result::Pass,
456 | );
457 | }
458 |
459 | #[test]
460 | fn external_requirements_error() {
461 | let fake_vulkan = create_fake_vulkan();
462 |
463 | fake_vulkan.set_override();
464 | let context = Context::new(&Requirements::new(), None).unwrap();
465 |
466 | let config = Rc::new(RefCell::new(Config::new()));
467 |
468 | let mut executor = Executor::new(Rc::clone(&config));
469 |
470 | let (queue_family, _) = FakeVulkan::unmake_queue(context.queue());
471 |
472 | executor.set_device(
473 | get_instance_proc_cb,
474 | (fake_vulkan.as_ref() as *const FakeVulkan).cast(),
475 | context.physical_device(),
476 | queue_family,
477 | context.vk_device()
478 | );
479 |
480 | let source = Source::from_string(
481 | "[require]\n\
482 | logicOp".to_string()
483 | );
484 | let script = Script::load(&executor.config.borrow(), &source).unwrap();
485 |
486 | let error = executor.execute_script_or_error(&script).unwrap_err();
487 |
488 | assert_eq!(
489 | &error.to_string(),
490 | "Missing required feature: logicOp",
491 | );
492 | assert_eq!(
493 | error.result(),
494 | result::Result::Skip,
495 | );
496 | }
497 |
498 | #[test]
499 | fn context_error() {
500 | let fake_vulkan = create_fake_vulkan();
501 |
502 | let config = Rc::new(RefCell::new(Config::new()));
503 | config.borrow_mut().set_device_id(Some(12));
504 |
505 | let mut executor = Executor::new(Rc::clone(&config));
506 |
507 | let source = Source::from_string("".to_string());
508 | let script = Script::load(&executor.config.borrow(), &source).unwrap();
509 |
510 | fake_vulkan.set_override();
511 | let error = executor.execute_script_or_error(&script).unwrap_err();
512 |
513 | assert_eq!(
514 | &error.to_string(),
515 | "Device 13 was selected but the Vulkan instance only reported \
516 | 1 device.",
517 | );
518 | assert_eq!(
519 | error.result(),
520 | result::Result::Fail,
521 | );
522 | }
523 |
524 | fn run_script_error(source: &str) -> Error {
525 | let fake_vulkan = create_fake_vulkan();
526 |
527 | let config = Rc::new(RefCell::new(Config::new()));
528 |
529 | let mut executor = Executor::new(config);
530 |
531 | let source = Source::from_string(source.to_string());
532 | let script = Script::load(&executor.config.borrow(), &source).unwrap();
533 |
534 | fake_vulkan.set_override();
535 | executor.execute_script_or_error(&script).unwrap_err()
536 | }
537 |
538 | #[test]
539 | fn window_error() {
540 | let error = run_script_error(
541 | "[require]\n\
542 | depthstencil R8_UNORM"
543 | );
544 |
545 | assert_eq!(
546 | &error.to_string(),
547 | "Format R8_UNORM is not supported as a depth/stencil attachment",
548 | );
549 | assert_eq!(
550 | error.result(),
551 | result::Result::Skip,
552 | );
553 | }
554 |
555 | #[test]
556 | fn pipeline_error() {
557 | let error = run_script_error(
558 | "[vertex shader]\n\
559 | 12"
560 | );
561 |
562 | assert_eq!(
563 | &error.to_string(),
564 | "The compiler or assembler generated an invalid SPIR-V binary",
565 | );
566 | assert_eq!(
567 | error.result(),
568 | result::Result::Fail,
569 | );
570 | }
571 |
572 | #[test]
573 | fn tester_error() {
574 | let error = run_script_error(
575 | "[test]\n\
576 | probe all rgb 1 2 3"
577 | );
578 |
579 | assert_eq!(
580 | &error.to_string(),
581 | "line 2: Probe color at (0,0)\n\
582 | \x20 Expected: 1 2 3\n\
583 | \x20 Observed: 0 0 0"
584 | );
585 | assert_eq!(
586 | error.result(),
587 | result::Result::Fail,
588 | );
589 | }
590 | }
591 |
```
--------------------------------------------------------------------------------
/vkrunner/vkrunner/compiler.rs:
--------------------------------------------------------------------------------
```rust
1 | // vkrunner
2 | //
3 | // Copyright (C) 2018 Intel Corporation
4 | // Copyright 2023 Neil Roberts
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a
7 | // copy of this software and associated documentation files (the "Software"),
8 | // to deal in the Software without restriction, including without limitation
9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 | // and/or sell copies of the Software, and to permit persons to whom the
11 | // Software is furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice (including the next
14 | // paragraph) shall be included in all copies or substantial portions of the
15 | // 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
20 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 | // DEALINGS IN THE SOFTWARE.
24 |
25 | use crate::vk;
26 | use crate::shader_stage;
27 | use crate::logger::Logger;
28 | use crate::context::Context;
29 | use crate::script::{Script, Shader};
30 | use crate::temp_file;
31 | use crate::requirements::extract_version;
32 | use std::fmt;
33 | use std::mem;
34 | use std::ptr;
35 | use std::io::{self, Write, Read, BufWriter};
36 | use std::fs::File;
37 | use std::path::Path;
38 | use std::env;
39 | // When testing we’ll divert to a fake command so that we don’t need
40 | // to depend on glslangValidator
41 | #[cfg(test)]
42 | mod fake_process;
43 | #[cfg(test)]
44 | use fake_process::{Command, Output};
45 | #[cfg(not(test))]
46 | use std::process::{Command, Output};
47 | use std::process::Stdio;
48 |
49 | /// An error that can be returned by [build_stage].
50 | #[derive(Debug)]
51 | pub enum Error {
52 | /// There were no shaders for this stage in the script
53 | MissingStageShaders(shader_stage::Stage),
54 | /// vkCreateShaderModule returned an error
55 | CreateShaderModuleFailed,
56 | /// Error creating a temporary file
57 | TempFile(temp_file::Error),
58 | /// Other I/O error
59 | IoError(io::Error),
60 | /// A compiler or assembler command returned a non-zero status
61 | CommandFailed,
62 | /// The generated shader binary didn’t have the right SPIR-V magic
63 | /// number or wasn’t a multiple of 32-bit integers.
64 | InvalidShaderBinary,
65 | }
66 |
67 | impl fmt::Display for Error {
68 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69 | match self {
70 | Error::MissingStageShaders(stage) => write!(
71 | f,
72 | "No shaders for stage {:?}",
73 | stage,
74 | ),
75 | Error::CreateShaderModuleFailed => write!(
76 | f,
77 | "vkCreateShaderModule failed"
78 | ),
79 | Error::TempFile(e) => e.fmt(f),
80 | Error::IoError(e) => e.fmt(f),
81 | Error::CommandFailed => write!(
82 | f,
83 | "A subprocess failed with a non-zero exit status",
84 | ),
85 | Error::InvalidShaderBinary => write!(
86 | f,
87 | "The compiler or assembler generated an invalid SPIR-V binary",
88 | ),
89 | }
90 | }
91 | }
92 |
93 | impl From<temp_file::Error> for Error {
94 | fn from(e: temp_file::Error) -> Error {
95 | Error::TempFile(e)
96 | }
97 | }
98 |
99 | impl From<io::Error> for Error {
100 | fn from(e: io::Error) -> Error {
101 | Error::IoError(e)
102 | }
103 | }
104 |
105 | fn stage_name(stage: shader_stage::Stage) -> &'static str {
106 | match stage {
107 | shader_stage::Stage::Vertex => "vert",
108 | shader_stage::Stage::TessCtrl => "tesc",
109 | shader_stage::Stage::TessEval => "tese",
110 | shader_stage::Stage::Geometry => "geom",
111 | shader_stage::Stage::Fragment => "frag",
112 | shader_stage::Stage::Compute => "comp",
113 | }
114 | }
115 |
116 | fn handle_command_output(
117 | logger: &mut Logger,
118 | output: Output,
119 | ) -> Result<(), Error> {
120 | logger.write_all(output.stdout.as_slice())?;
121 | logger.write_all(output.stderr.as_slice())?;
122 |
123 | if output.status.success() {
124 | Ok(())
125 | } else {
126 | Err(Error::CommandFailed)
127 | }
128 | }
129 |
130 | fn show_disassembly_from_file(
131 | logger: &mut Logger,
132 | filename: &Path,
133 | ) -> Result<(), Error> {
134 | let exe = match env::var_os("PIGLIT_SPIRV_DIS_BINARY") {
135 | Some(exe) => exe,
136 | None => "spirv-dis".into(),
137 | };
138 |
139 | handle_command_output(
140 | logger,
141 | Command::new(exe)
142 | .arg(filename)
143 | .stdout(Stdio::piped())
144 | .stderr(Stdio::piped())
145 | .output()?
146 | )
147 | }
148 |
149 | fn create_shader_from_binary(
150 | context: &Context,
151 | data: &[u32],
152 | ) -> Result<vk::VkShaderModule, Error> {
153 | let shader_module_create_info = vk::VkShaderModuleCreateInfo {
154 | sType: vk::VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
155 | pNext: ptr::null(),
156 | flags: 0,
157 | codeSize: data.len() * mem::size_of::<u32>(),
158 | pCode: data.as_ptr(),
159 | };
160 |
161 | let mut module: vk::VkShaderModule = vk::null_handle();
162 |
163 | let res = unsafe {
164 | context.device().vkCreateShaderModule.unwrap()(
165 | context.vk_device(),
166 | ptr::addr_of!(shader_module_create_info),
167 | ptr::null(), // allocator
168 | ptr::addr_of_mut!(module),
169 | )
170 | };
171 |
172 | if res == vk::VK_SUCCESS {
173 | Ok(module)
174 | } else {
175 | Err(Error::CreateShaderModuleFailed)
176 | }
177 | }
178 |
179 | fn create_shader_from_binary_file(
180 | context: &Context,
181 | file: &mut File,
182 | ) -> Result<vk::VkShaderModule, Error> {
183 | let mut data = Vec::<u32>::new();
184 | let mut buf = vec![0u8; 512];
185 | let mut buf_length = 0usize;
186 | let mut big_endian = false;
187 | let mut bytes = [0u8; mem::size_of::<u32>()];
188 |
189 | loop {
190 | let got = file.read(&mut buf[buf_length..])?;
191 |
192 | if got == 0 {
193 | break;
194 | }
195 |
196 | buf_length += got;
197 |
198 | for i in 0..buf_length / mem::size_of::<u32>() {
199 | let buf_start = i * mem::size_of::<u32>();
200 | bytes.copy_from_slice(&buf[
201 | buf_start..buf_start + mem::size_of::<u32>()
202 | ]);
203 |
204 | if data.len() == 0 {
205 | if bytes == [0x07, 0x23, 0x02, 0x03] {
206 | big_endian = true;
207 | } else if bytes == [0x03, 0x02, 0x23, 0x07] {
208 | big_endian = false;
209 | } else {
210 | return Err(Error::InvalidShaderBinary);
211 | }
212 | }
213 |
214 | data.push(if big_endian {
215 | u32::from_be_bytes(bytes)
216 | } else {
217 | u32::from_le_bytes(bytes)
218 | });
219 | }
220 |
221 | let remainder = buf_length % mem::size_of::<u32>();
222 |
223 | buf.copy_within(buf_length - remainder.., 0);
224 | buf_length = remainder;
225 | }
226 |
227 | if buf_length != 0 {
228 | Err(Error::InvalidShaderBinary)
229 | } else {
230 | create_shader_from_binary(context, &data)
231 | }
232 | }
233 |
234 | fn create_temp_file_for_source(
235 | source: &str
236 | ) -> Result<temp_file::TempFile, Error> {
237 | let mut temp_file = temp_file::TempFile::new()?;
238 | temp_file.file().unwrap().write_all(source.as_bytes())?;
239 | temp_file.file().unwrap().flush()?;
240 | temp_file.close();
241 |
242 | Ok(temp_file)
243 | }
244 |
245 | fn version_string(version: u32) -> String {
246 | let (version_major, version_minor, _) = extract_version(version);
247 | format!("vulkan{}.{}", version_major, version_minor)
248 | }
249 |
250 | fn compile_glsl(
251 | logger: &mut Logger,
252 | context: &Context,
253 | script: &Script,
254 | stage: shader_stage::Stage,
255 | show_disassembly: bool,
256 | ) -> Result<vk::VkShaderModule, Error> {
257 | let mut shader_files = Vec::new();
258 |
259 | for shader in script.shaders(stage) {
260 | let source = match &shader {
261 | Shader::Glsl(s) => s,
262 | _ => unreachable!("Unexpected shader type"),
263 | };
264 | shader_files.push(create_temp_file_for_source(&source)?);
265 | }
266 |
267 | let version_str = version_string(script.requirements().version());
268 |
269 | let mut module_file = temp_file::TempFile::new()?;
270 |
271 | let exe = match env::var_os("PIGLIT_GLSLANG_VALIDATOR_BINARY") {
272 | Some(exe) => exe,
273 | None => "glslangValidator".into(),
274 | };
275 |
276 | handle_command_output(
277 | logger,
278 | Command::new(exe)
279 | .args([
280 | "--quiet",
281 | "-V",
282 | "--target-env", &version_str,
283 | "-S", stage_name(stage),
284 | ])
285 | .arg("-o").arg(module_file.filename())
286 | .args(shader_files.iter().map(|file| file.filename()))
287 | .stdout(Stdio::piped())
288 | .stderr(Stdio::piped())
289 | .output()?
290 | )?;
291 |
292 | drop(shader_files);
293 |
294 | if show_disassembly {
295 | show_disassembly_from_file(logger, module_file.filename())?;
296 | }
297 |
298 | create_shader_from_binary_file(context, module_file.file().unwrap())
299 | }
300 |
301 | fn assemble_spirv(
302 | logger: &mut Logger,
303 | context: &Context,
304 | script: &Script,
305 | source: &str,
306 | show_disassembly: bool,
307 | ) -> Result<vk::VkShaderModule, Error> {
308 | let version_str = version_string(script.requirements().version());
309 |
310 | let mut module_file = temp_file::TempFile::new()?;
311 |
312 | let source_file = create_temp_file_for_source(source)?;
313 |
314 | let exe = match env::var_os("PIGLIT_SPIRV_AS_BINARY") {
315 | Some(exe) => exe,
316 | None => "spirv-as".into(),
317 | };
318 |
319 | handle_command_output(
320 | logger,
321 | Command::new(exe)
322 | .args(["--target-env", &version_str])
323 | .arg("-o").arg(module_file.filename())
324 | .arg(source_file.filename())
325 | .stdout(Stdio::piped())
326 | .stderr(Stdio::piped())
327 | .output()?
328 | )?;
329 |
330 | drop(source_file);
331 |
332 | if show_disassembly {
333 | show_disassembly_from_file(logger, module_file.filename())?;
334 | }
335 |
336 | create_shader_from_binary_file(context, module_file.file().unwrap())
337 | }
338 |
339 | fn load_binary_stage(
340 | logger: &mut Logger,
341 | context: &Context,
342 | data: &[u32],
343 | show_disassembly: bool,
344 | ) -> Result<vk::VkShaderModule, Error> {
345 | if show_disassembly {
346 | let mut temp_file = temp_file::TempFile::new()?;
347 | let mut writer = BufWriter::new(temp_file.file().unwrap());
348 |
349 | for value in data {
350 | writer.write_all(&value.to_ne_bytes())?;
351 | }
352 |
353 | writer.flush()?;
354 |
355 | drop(writer);
356 |
357 | temp_file.close();
358 |
359 | show_disassembly_from_file(logger, temp_file.filename())?;
360 | }
361 |
362 | create_shader_from_binary(context, data)
363 | }
364 |
365 | pub fn build_stage(
366 | logger: &mut Logger,
367 | context: &Context,
368 | script: &Script,
369 | stage: shader_stage::Stage,
370 | show_disassembly: bool,
371 | ) -> Result<vk::VkShaderModule, Error> {
372 | let shaders = script.shaders(stage);
373 |
374 | match shaders.get(0) {
375 | None => Err(Error::MissingStageShaders(stage)),
376 | Some(Shader::Glsl(_)) => compile_glsl(
377 | logger,
378 | context,
379 | script,
380 | stage,
381 | show_disassembly,
382 | ),
383 | Some(Shader::Spirv(source)) => {
384 | // The script parser should have ensured that there’s
385 | // only one shader
386 | assert_eq!(shaders.len(), 1);
387 | assemble_spirv(
388 | logger,
389 | context,
390 | script,
391 | source,
392 | show_disassembly
393 | )
394 | },
395 | Some(Shader::Binary(data)) => {
396 | // The script parser should have ensured that there’s
397 | // only one shader
398 | assert_eq!(shaders.len(), 1);
399 | load_binary_stage(
400 | logger,
401 | context,
402 | data,
403 | show_disassembly
404 | )
405 | },
406 | }
407 | }
408 |
409 | #[cfg(test)]
410 | mod test {
411 | use super::*;
412 | use crate::fake_vulkan::{FakeVulkan, HandleType};
413 | use crate::context::Context;
414 | use crate::requirements::Requirements;
415 | use crate::source::Source;
416 | use crate::config::Config;
417 | use std::ffi::{c_char, c_void, CStr};
418 |
419 | struct CompileOutput {
420 | log: Vec<String>,
421 | result: Result<Vec<u32>, Error>,
422 | }
423 |
424 | extern "C" fn log_cb(message: *const c_char, user_data: *mut c_void) {
425 | unsafe {
426 | let message = CStr::from_ptr(message).to_str().unwrap().to_owned();
427 | let log = &mut *(user_data as *mut Vec<String>);
428 | log.push(message);
429 | }
430 | }
431 |
432 | fn compile_script(
433 | source: &str,
434 | stage: shader_stage::Stage,
435 | show_disassembly: bool,
436 | ) -> CompileOutput {
437 | let mut fake_vulkan = FakeVulkan::new();
438 | fake_vulkan.physical_devices.push(Default::default());
439 |
440 | compile_script_with_fake_vulkan(
441 | &mut fake_vulkan,
442 | source,
443 | stage,
444 | show_disassembly
445 | )
446 | }
447 |
448 | fn compile_script_with_fake_vulkan(
449 | fake_vulkan: &mut FakeVulkan,
450 | source: &str,
451 | stage: shader_stage::Stage,
452 | show_disassembly: bool,
453 | ) -> CompileOutput {
454 | fake_vulkan.set_override();
455 | let context = Context::new(&Requirements::new(), None).unwrap();
456 |
457 | let source = Source::from_string(source.to_owned());
458 | let script = Script::load(&Config::new(), &source).unwrap();
459 | let mut log = Vec::new();
460 | let mut logger = Logger::new(
461 | Some(log_cb),
462 | ptr::addr_of_mut!(log).cast(),
463 | );
464 |
465 | let result = build_stage(
466 | &mut logger,
467 | &context,
468 | &script,
469 | stage,
470 | show_disassembly,
471 | ).map(|module| {
472 | let code = match &fake_vulkan.get_handle(module).data {
473 | HandleType::ShaderModule { code } => code.clone(),
474 | _ => unreachable!("Unexpected Vulkan handle type"),
475 | };
476 | unsafe {
477 | context.device().vkDestroyShaderModule.unwrap()(
478 | context.vk_device(),
479 | module,
480 | ptr::null(), // allocator
481 | );
482 | }
483 | code
484 | });
485 |
486 | CompileOutput { log, result }
487 | }
488 |
489 | #[test]
490 | fn glsl_le() {
491 | let CompileOutput { log, result } = compile_script(
492 | "[fragment shader]\n\
493 | 03 02 23 07\n\
494 | fe ca fe ca\n",
495 | shader_stage::Stage::Fragment,
496 | false, // show_disassembly
497 | );
498 |
499 | assert_eq!(
500 | &log,
501 | &[
502 | "quiet",
503 | "vulkan_spirv",
504 | "target_env: vulkan1.0",
505 | "stage: frag",
506 | ],
507 | );
508 |
509 | assert_eq!(result.unwrap(), &[0x07230203, 0xcafecafe]);
510 | }
511 |
512 | #[test]
513 | fn glsl_be() {
514 | let CompileOutput { log, result } = compile_script(
515 | "[vertex shader]\n\
516 | 07 23 02 03\n\
517 | ca fe ca fe\n",
518 | shader_stage::Stage::Vertex,
519 | false, // show_disassembly
520 | );
521 |
522 | assert_eq!(
523 | &log,
524 | &[
525 | "quiet",
526 | "vulkan_spirv",
527 | "target_env: vulkan1.0",
528 | "stage: vert",
529 | ],
530 | );
531 |
532 | assert_eq!(result.unwrap(), &[0x07230203, 0xcafecafe]);
533 | }
534 |
535 | #[test]
536 | fn spirv() {
537 | let CompileOutput { log, result } = compile_script(
538 | "[vertex shader spirv]\n\
539 | 07 23 02 03\n\
540 | f0 0d fe ed\n",
541 | shader_stage::Stage::Vertex,
542 | false, // show_disassembly
543 | );
544 |
545 | assert_eq!(&log, &["target_env: vulkan1.0"]);
546 |
547 | assert_eq!(result.unwrap(), &[0x07230203, 0xf00dfeed]);
548 | }
549 |
550 | #[test]
551 | fn binary() {
552 | let CompileOutput { log, result } = compile_script(
553 | "[vertex shader binary]\n\
554 | 07230203\n\
555 | f00dfeed\n",
556 | shader_stage::Stage::Vertex,
557 | false, // show_disassembly
558 | );
559 |
560 | assert!(log.is_empty());
561 |
562 | assert_eq!(result.unwrap(), &[0x07230203, 0xf00dfeed]);
563 | }
564 |
565 | fn test_stage(
566 | stage: shader_stage::Stage,
567 | section_name: &str,
568 | compiler_argument: &str
569 | ) {
570 | let CompileOutput { log, result } = compile_script(
571 | &format!(
572 | "[{}]\n\
573 | 07 23 02 03\n",
574 | section_name,
575 | ),
576 | stage,
577 | false, // show_disassembly
578 | );
579 |
580 | assert_eq!(
581 | &log,
582 | &[
583 | "quiet",
584 | "vulkan_spirv",
585 | "target_env: vulkan1.0",
586 | &format!("stage: {}", compiler_argument)
587 | ]
588 | );
589 |
590 | assert!(result.is_ok());
591 | }
592 |
593 | #[test]
594 | fn all_stages() {
595 | test_stage(
596 | shader_stage::Stage::Vertex,
597 | "vertex shader",
598 | "vert"
599 | );
600 | test_stage(
601 | shader_stage::Stage::TessCtrl,
602 | "tessellation control shader",
603 | "tesc"
604 | );
605 | test_stage(
606 | shader_stage::Stage::TessEval,
607 | "tessellation evaluation shader",
608 | "tese"
609 | );
610 | test_stage(
611 | shader_stage::Stage::Geometry,
612 | "geometry shader",
613 | "geom"
614 | );
615 | test_stage(
616 | shader_stage::Stage::Fragment,
617 | "fragment shader",
618 | "frag"
619 | );
620 | test_stage(
621 | shader_stage::Stage::Compute,
622 | "compute shader",
623 | "comp"
624 | );
625 | }
626 |
627 | #[test]
628 | fn no_shaders() {
629 | let CompileOutput { result, .. } = compile_script(
630 | "[vertex shader]\n\
631 | 07 23 02 03\n",
632 | shader_stage::Stage::Fragment,
633 | false, // show_disassembly
634 | );
635 | assert_eq!(
636 | &result.unwrap_err().to_string(),
637 | "No shaders for stage Fragment",
638 | );
639 | }
640 |
641 | #[test]
642 | fn create_shader_module_error() {
643 | let mut fake_vulkan = FakeVulkan::new();
644 | fake_vulkan.physical_devices.push(Default::default());
645 | fake_vulkan.queue_result(
646 | "vkCreateShaderModule".to_string(),
647 | vk::VK_ERROR_UNKNOWN
648 | );
649 |
650 | let CompileOutput { result, .. } = compile_script_with_fake_vulkan(
651 | &mut fake_vulkan,
652 | "[vertex shader]\n\
653 | 07 23 02 03\n",
654 | shader_stage::Stage::Vertex,
655 | false, // show_disassembly
656 | );
657 | assert_eq!(
658 | &result.unwrap_err().to_string(),
659 | "vkCreateShaderModule failed",
660 | );
661 | }
662 |
663 | #[test]
664 | fn invalid_magic() {
665 | let CompileOutput { result, .. } = compile_script(
666 | "[vertex shader]\n\
667 | 12 34 56 78\n",
668 | shader_stage::Stage::Vertex,
669 | false, // show_disassembly
670 | );
671 | assert_eq!(
672 | &result.unwrap_err().to_string(),
673 | "The compiler or assembler generated an invalid SPIR-V binary",
674 | );
675 | }
676 |
677 | #[test]
678 | fn not_multiple_of_u32() {
679 | let CompileOutput { result, .. } = compile_script(
680 | "[vertex shader]\n\
681 | 07 23 02 03 9a\n",
682 | shader_stage::Stage::Vertex,
683 | false, // show_disassembly
684 | );
685 | assert_eq!(
686 | &result.unwrap_err().to_string(),
687 | "The compiler or assembler generated an invalid SPIR-V binary",
688 | );
689 | }
690 |
691 | #[test]
692 | fn compiler_failed() {
693 | let CompileOutput { result, .. } = compile_script(
694 | "[vertex shader]\n\
695 | invalid hex values\n",
696 | shader_stage::Stage::Vertex,
697 | false, // show_disassembly
698 | );
699 | assert_eq!(
700 | &result.unwrap_err().to_string(),
701 | "A subprocess failed with a non-zero exit status",
702 | );
703 | }
704 |
705 | fn test_show_disassembly(section_suffix: &str) {
706 | let CompileOutput { log, result } = compile_script(
707 | &format!(
708 | "[fragment shader{}]\n\
709 | 03 02 23 07\n\
710 | fe ca fe ca\n",
711 | section_suffix,
712 | ),
713 | shader_stage::Stage::Fragment,
714 | true, // show_disassembly
715 | );
716 |
717 | assert!(log.iter().find(|&line| line == "disassembly").is_some());
718 |
719 | assert!(result.is_ok());
720 | }
721 |
722 | #[test]
723 | fn show_glsl_disassembly() {
724 | test_show_disassembly("");
725 | }
726 |
727 | #[test]
728 | fn show_spirv_disassembly() {
729 | test_show_disassembly(" spirv");
730 | }
731 |
732 | #[test]
733 | fn show_binary_disassembly() {
734 | test_show_disassembly(" binary");
735 | }
736 | }
737 |
```
--------------------------------------------------------------------------------
/vkrunner/vkrunner/format.rs:
--------------------------------------------------------------------------------
```rust
1 | // vkrunner
2 | //
3 | // Copyright (C) 2018 Intel Corporation
4 | // Copyright 2023 Neil Roberts
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a
7 | // copy of this software and associated documentation files (the "Software"),
8 | // to deal in the Software without restriction, including without limitation
9 | // on the rights to use, copy, modify, merge, publish, distribute, sub
10 | // license, and/or sell copies of the Software, and to permit persons to whom
11 | // the Software is furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice (including the next
14 | // paragraph) shall be included in all copies or substantial portions of the
15 | // 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 NON-INFRINGEMENT. IN NO EVENT SHALL
20 | // VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
21 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23 | // USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | use crate::small_float;
26 | use crate::half_float;
27 | use crate::vk;
28 | use std::convert::TryInto;
29 | use std::num::NonZeroUsize;
30 |
31 | #[derive(Debug)]
32 | pub struct Format {
33 | pub(crate) vk_format: vk::VkFormat,
34 | pub(crate) name: &'static str,
35 | pub(crate) packed_size: Option<NonZeroUsize>,
36 | n_parts: usize,
37 | parts: [Part; 4],
38 | }
39 |
40 | #[derive(Debug, Eq, PartialEq, Copy, Clone)]
41 | pub(crate) enum Component {
42 | R,
43 | G,
44 | B,
45 | A,
46 | D,
47 | S,
48 | X,
49 | }
50 |
51 | #[derive(Debug, Eq, PartialEq, Copy, Clone)]
52 | pub(crate) enum Mode {
53 | UNORM,
54 | SNORM,
55 | USCALED,
56 | SSCALED,
57 | UINT,
58 | SINT,
59 | UFLOAT,
60 | SFLOAT,
61 | SRGB,
62 | }
63 |
64 | #[derive(Debug, PartialEq, Eq)]
65 | pub(crate) struct Part {
66 | pub bits: usize,
67 | pub component: Component,
68 | pub mode: Mode,
69 | }
70 |
71 | include!{"format_table.rs"}
72 |
73 | impl PartialEq for Format {
74 | #[inline]
75 | fn eq(&self, other: &Format) -> bool {
76 | // If the Vulkan format enum is the same then everything else
77 | // about the format should be the same too
78 | self.vk_format == other.vk_format
79 | }
80 | }
81 |
82 | impl PartialEq<vk::VkFormat> for Format {
83 | #[inline]
84 | fn eq(&self, other: &vk::VkFormat) -> bool {
85 | self.vk_format == *other
86 | }
87 | }
88 |
89 | impl PartialEq<Format> for vk::VkFormat {
90 | #[inline]
91 | fn eq(&self, other: &Format) -> bool {
92 | *self == other.vk_format
93 | }
94 | }
95 |
96 | impl Format {
97 | pub(crate) fn lookup_by_name(name: &str) -> Option<&'static Format> {
98 | match FORMATS.binary_search_by(|format| format.name.cmp(name)) {
99 | Ok(pos) => Some(&FORMATS[pos]),
100 | Err(_) => None,
101 | }
102 | }
103 |
104 | pub(crate) fn lookup_by_vk_format(
105 | vk_format: vk::VkFormat
106 | ) -> &'static Format {
107 | for format in FORMATS.iter() {
108 | if format.vk_format == vk_format {
109 | return format;
110 | }
111 | }
112 |
113 | unreachable!("lookup failed for format {:?}", vk_format);
114 | }
115 |
116 | pub(crate) fn lookup_by_details(
117 | bit_size: usize,
118 | mode: Mode,
119 | n_components: usize
120 | ) -> Option<&'static Format> {
121 | static COMP_ORDER: [Component; 4] = [
122 | Component::R,
123 | Component::G,
124 | Component::B,
125 | Component::A,
126 | ];
127 |
128 | 'format_loop: for format in FORMATS.iter() {
129 | if format.n_parts != n_components {
130 | continue;
131 | }
132 |
133 | if let Some(_) = format.packed_size {
134 | continue;
135 | }
136 |
137 | for (i, part) in format.parts().iter().enumerate() {
138 | if part.bits != bit_size
139 | || part.component != COMP_ORDER[i]
140 | || part.mode != mode
141 | {
142 | continue 'format_loop;
143 | }
144 | }
145 |
146 | return Some(format);
147 | }
148 |
149 | None
150 | }
151 |
152 | pub(crate) fn parts(&self) -> &[Part] {
153 | &self.parts[0..self.n_parts]
154 | }
155 |
156 | pub fn size(&self) -> usize {
157 | match self.packed_size {
158 | Some(size) => usize::from(size) / 8,
159 | None => self.parts().iter().map(|p| p.bits).sum::<usize>() / 8,
160 | }
161 | }
162 |
163 | pub(crate) fn packed_size(&self) -> Option<usize> {
164 | self.packed_size.map(|s| usize::from(s))
165 | }
166 |
167 | pub(crate) fn alignment(&self) -> usize {
168 | match self.packed_size {
169 | Some(size) => usize::from(size) / 8,
170 | None => self.parts().iter().map(|p| p.bits).max().unwrap() / 8,
171 | }
172 | }
173 |
174 | pub(crate) fn depth_stencil_aspect_flags(&self) -> vk::VkImageAspectFlags {
175 | self.parts().iter().map(|part| match part.component {
176 | Component::D => vk::VK_IMAGE_ASPECT_DEPTH_BIT,
177 | Component::S => vk::VK_IMAGE_ASPECT_STENCIL_BIT,
178 | _ => 0,
179 | }).fold(0, |a, b| a | b)
180 | }
181 | }
182 |
183 | impl Mode {
184 | fn load_packed_part(&self, part: u32, bits: usize) -> f64 {
185 | assert!(bits < 32);
186 |
187 | match self {
188 | Mode::SRGB | Mode::UNORM => part as f64 / ((1 << bits) - 1) as f64,
189 | Mode::SNORM => {
190 | sign_extend(part, bits) as f64 / ((1 << (bits - 1)) - 1) as f64
191 | },
192 | Mode::UINT | Mode::USCALED => part as f64,
193 | Mode::SSCALED | Mode::SINT => sign_extend(part, bits) as f64,
194 | Mode::UFLOAT => {
195 | match bits {
196 | 10 => small_float::load_unsigned(part, 5, 5),
197 | 11 => small_float::load_unsigned(part, 5, 6),
198 | _ => {
199 | unreachable!(
200 | "unknown bit size {} in packed UFLOAT \
201 | format",
202 | bits
203 | )
204 | },
205 | }
206 | },
207 | Mode::SFLOAT => unreachable!("Unexpected packed SFLOAT format"),
208 | }
209 | }
210 |
211 | fn load_part(&self, bits: usize, fb: &[u8]) -> f64 {
212 | match self {
213 | Mode::SRGB | Mode::UNORM => {
214 | match bits {
215 | 8 => fb[0] as f64 / u8::MAX as f64,
216 | 16 => {
217 | u16::from_ne_bytes(fb[0..2].try_into().unwrap()) as f64
218 | / u16::MAX as f64
219 | },
220 | 24 => extract_u24(fb) as f64 / 16777215.0,
221 | 32 => {
222 | u32::from_ne_bytes(fb[0..4].try_into().unwrap()) as f64
223 | / u32::MAX as f64
224 | },
225 | 64 => {
226 | u64::from_ne_bytes(fb[0..8].try_into().unwrap()) as f64
227 | / u64::MAX as f64
228 | },
229 | _=> unreachable!("unsupported component bit size {}", bits),
230 | }
231 | },
232 | Mode::SNORM => {
233 | match bits {
234 | 8 => fb[0] as i8 as f64 / i8::MAX as f64,
235 | 16 => {
236 | i16::from_ne_bytes(fb[0..2].try_into().unwrap()) as f64
237 | / i16::MAX as f64
238 | },
239 | 32 => {
240 | i32::from_ne_bytes(fb[0..4].try_into().unwrap()) as f64
241 | / i32::MAX as f64
242 | },
243 | 64 => {
244 | i64::from_ne_bytes(fb[0..8].try_into().unwrap()) as f64
245 | / i64::MAX as f64
246 | },
247 | _=> unreachable!("unsupported component bit size {}", bits),
248 | }
249 | },
250 | Mode::UINT | Mode::USCALED => {
251 | match bits {
252 | 8 => fb[0] as f64,
253 | 16 => {
254 | u16::from_ne_bytes(fb[0..2].try_into().unwrap()) as f64
255 | },
256 | 32 => {
257 | u32::from_ne_bytes(fb[0..4].try_into().unwrap()) as f64
258 | },
259 | 64 => {
260 | u64::from_ne_bytes(fb[0..8].try_into().unwrap()) as f64
261 | },
262 | _=> unreachable!("unsupported component bit size {}", bits),
263 | }
264 | },
265 | Mode::SINT | Mode::SSCALED => {
266 | match bits {
267 | 8 => fb[0] as i8 as f64,
268 | 16 => {
269 | i16::from_ne_bytes(fb[0..2].try_into().unwrap()) as f64
270 | },
271 | 32 => {
272 | i32::from_ne_bytes(fb[0..4].try_into().unwrap()) as f64
273 | },
274 | 64 => {
275 | i64::from_ne_bytes(fb[0..8].try_into().unwrap()) as f64
276 | },
277 | _=> unreachable!("unsupported component bit size {}", bits),
278 | }
279 | },
280 | Mode::UFLOAT => unreachable!("unexpected unpacked UFLOAT part"),
281 | Mode::SFLOAT => {
282 | match bits {
283 | 16 => {
284 | let bits =
285 | u16::from_ne_bytes(fb[0..2].try_into().unwrap());
286 | half_float::to_f64(bits)
287 | },
288 | 32 => {
289 | f32::from_ne_bytes(fb[0..4].try_into().unwrap()) as f64
290 | },
291 | 64 => f64::from_ne_bytes(fb[0..8].try_into().unwrap()),
292 | _ => {
293 | unreachable!(
294 | "unsupported unpacked SFLOAT size {}",
295 | bits
296 | );
297 | },
298 | }
299 | },
300 | }
301 | }
302 | }
303 |
304 | impl Format {
305 | fn load_packed_parts(&self, source: &[u8], parts: &mut [f64]) {
306 | let mut packed_parts = match self.packed_size().unwrap() {
307 | 8 => source[0] as u32,
308 | 16 => u16::from_ne_bytes(source[0..2].try_into().unwrap()) as u32,
309 | 32 => u32::from_ne_bytes(source[0..4].try_into().unwrap()),
310 | _ => {
311 | unreachable!(
312 | "unsupported packed bit size {}",
313 | self.packed_size.unwrap()
314 | );
315 | },
316 | };
317 |
318 | for (i, part) in self.parts().iter().enumerate().rev() {
319 | let part_bits =
320 | packed_parts
321 | & (u32::MAX >> (u32::BITS - part.bits as u32));
322 | parts[i] = part.mode.load_packed_part(part_bits, part.bits);
323 | packed_parts >>= part.bits;
324 | }
325 | }
326 |
327 | pub fn load_pixel(&self, source: &[u8]) -> [f64; 4] {
328 | assert!(source.len() >= self.size());
329 | assert!(self.n_parts <= 4);
330 |
331 | let mut parts = [0.0; 4];
332 |
333 | match self.packed_size {
334 | Some(_) => self.load_packed_parts(source, &mut parts),
335 | None => {
336 | let mut source = source;
337 |
338 | for (i, part) in self.parts().iter().enumerate() {
339 | parts[i] = part.mode.load_part(part.bits, source);
340 | source = &source[part.bits / 8..];
341 | }
342 | },
343 | }
344 |
345 | // Set all the colour components to zero in case they aren’t
346 | // contained in the format. The alpha component default to 1.0
347 | // if it’s not in the format.
348 | let mut pixel = [0.0, 0.0, 0.0, 1.0];
349 |
350 | for (i, part) in self.parts().iter().enumerate() {
351 | match part.component {
352 | Component::R => pixel[0] = parts[i],
353 | Component::G => pixel[1] = parts[i],
354 | Component::B => pixel[2] = parts[i],
355 | Component::A => pixel[3] = parts[i],
356 | Component::D | Component::S | Component:: X => (),
357 | }
358 | }
359 |
360 | pixel
361 | }
362 | }
363 |
364 | fn sign_extend(part: u32, bits: usize) -> i32
365 | {
366 | let uresult = if part & (1 << (bits - 1)) != 0 {
367 | ((u32::MAX) << bits) | part
368 | } else {
369 | part
370 | };
371 |
372 | uresult as i32
373 | }
374 |
375 | fn extract_u24(bytes: &[u8]) -> u32 {
376 | let mut value = 0;
377 |
378 | for i in 0..3 {
379 | let byte_pos;
380 |
381 | #[cfg(target_endian = "little")]
382 | {
383 | byte_pos = 2 - i;
384 | }
385 | #[cfg(not(target_endian = "little"))]
386 | {
387 | byte_pos = i;
388 | }
389 |
390 | value = ((value) << 8) | bytes[byte_pos] as u32;
391 | }
392 |
393 | value
394 | }
395 |
396 | #[cfg(test)]
397 | mod test {
398 | use super::*;
399 |
400 | #[test]
401 | fn test_lookup_by_name() {
402 | // Test that we can find every name
403 | for format in FORMATS.iter() {
404 | let other_format = match Format::lookup_by_name(format.name) {
405 | Some(f) => f,
406 | None => unreachable!("lookup for {} failed", format.name),
407 | };
408 |
409 | // Assert that it returns a reference to the same object
410 | assert!(std::ptr::eq(format, other_format));
411 | }
412 |
413 | // Test that a similar name fails
414 | assert!(matches!(Format::lookup_by_name("B8G8R8_SRGBC"), None));
415 | }
416 |
417 | #[test]
418 | fn test_lookup_by_vk_format() {
419 | // Test that we can find every format
420 | for format in FORMATS.iter() {
421 | let other_format = Format::lookup_by_vk_format(format.vk_format);
422 | // Assert that it returns a reference to the same object
423 | assert!(std::ptr::eq(format, other_format));
424 | }
425 | }
426 |
427 | #[test]
428 | fn test_lookup_by_details() {
429 | let expected_format =
430 | Format::lookup_by_vk_format(vk::VK_FORMAT_R8G8B8_UNORM);
431 | assert_eq!(
432 | Format::lookup_by_details(8, Mode::UNORM, 3),
433 | Some(expected_format),
434 | );
435 | let expected_format =
436 | Format::lookup_by_vk_format(vk::VK_FORMAT_R64G64B64A64_SFLOAT);
437 | assert_eq!(
438 | Format::lookup_by_details(64, Mode::SFLOAT, 4),
439 | Some(expected_format),
440 | );
441 | assert_eq!(
442 | Format::lookup_by_details(64, Mode::UFLOAT, 4),
443 | None
444 | );
445 | }
446 |
447 | #[test]
448 | fn test_parts() {
449 | // Check that parts returns the right size slice for each type
450 | for format in FORMATS.iter() {
451 | assert_eq!(format.parts().len(), format.n_parts);
452 | }
453 |
454 | // Check some types
455 | assert_eq!(
456 | Format::lookup_by_vk_format(vk::VK_FORMAT_R8_UINT).parts(),
457 | &[Part { bits: 8, component: Component::R, mode: Mode::UINT }]
458 | );
459 | assert_eq!(
460 | Format::lookup_by_vk_format(vk::VK_FORMAT_B5G6R5_UNORM_PACK16)
461 | .parts(),
462 | &[
463 | Part { bits: 5, component: Component::B, mode: Mode::UNORM },
464 | Part { bits: 6, component: Component::G, mode: Mode::UNORM },
465 | Part { bits: 5, component: Component::R, mode: Mode::UNORM },
466 | ]
467 | );
468 | }
469 |
470 | #[test]
471 | fn test_size() {
472 | assert_eq!(
473 | Format::lookup_by_vk_format(vk::VK_FORMAT_B8G8R8_UINT).size(),
474 | 3
475 | );
476 | assert_eq!(
477 | Format::lookup_by_vk_format(vk::VK_FORMAT_R16G16_SINT).size(),
478 | 4
479 | );
480 | assert_eq!(
481 | Format::lookup_by_vk_format(vk::VK_FORMAT_B5G6R5_UNORM_PACK16)
482 | .size(),
483 | 2
484 | );
485 | }
486 |
487 | #[test]
488 | fn test_sign_extend() {
489 | assert_eq!(sign_extend(0xff, 8), -1);
490 | assert_eq!(sign_extend(1, 8), 1);
491 | }
492 |
493 | fn assert_float_equal(a: f64, b: f64) {
494 | assert!((a - b).abs() < 0.01, "a={}, b={}", a, b);
495 | }
496 |
497 | #[test]
498 | fn test_load_packed_part() {
499 | // Test that there are no formats with unsupported packed modes
500 | for format in FORMATS.iter() {
501 | if let Some(_) = format.packed_size {
502 | for part in format.parts().iter() {
503 | part.mode.load_packed_part(0, part.bits);
504 | }
505 | }
506 | }
507 |
508 | assert_float_equal(Mode::SRGB.load_packed_part(0x80, 8), 0.5);
509 | assert_float_equal(Mode::SNORM.load_packed_part(0x80, 8), -1.0);
510 | assert_float_equal(Mode::SNORM.load_packed_part(0x7f, 8), 1.0);
511 | assert_float_equal(Mode::UINT.load_packed_part(42, 8), 42.0);
512 | assert_float_equal(Mode::SINT.load_packed_part(0xff, 8), -1.0);
513 | assert_float_equal(Mode::UFLOAT.load_packed_part(0x1e0, 10), 1.0);
514 | assert_float_equal(Mode::UFLOAT.load_packed_part(0x3c0, 11), 1.0);
515 | }
516 |
517 | fn load_part(mode: Mode, bits: usize, fb_bytes: u64) -> f64 {
518 | let mut fb = Vec::new();
519 | let n_bytes = bits / 8;
520 |
521 | for i in 0..n_bytes {
522 | let byte_pos;
523 |
524 | #[cfg(target_endian = "little")]
525 | {
526 | byte_pos = i
527 | }
528 | #[cfg(not(target_endian = "little"))]
529 | {
530 | byte_pos = n_bytes - 1 - i
531 | }
532 |
533 | fb.push(((fb_bytes >> (byte_pos * 8)) & 0xff) as u8);
534 | }
535 |
536 | mode.load_part(bits, &fb)
537 | }
538 |
539 | #[test]
540 | fn test_load_part() {
541 | let dummy_array = [0u8; 8];
542 |
543 | // Test that there are no formats with unsupported unpacked modes
544 | for format in FORMATS.iter() {
545 | if let None = format.packed_size {
546 | for part in format.parts().iter() {
547 | assert!(part.bits <= dummy_array.len() * 8);
548 | part.mode.load_part(part.bits, &dummy_array);
549 | }
550 | }
551 | }
552 |
553 | assert_float_equal(load_part(Mode::UNORM, 8, 0x80), 0.5);
554 | assert_float_equal(load_part(Mode::UNORM, 16, 0x8000), 0.5);
555 | assert_float_equal(load_part(Mode::UNORM, 24, 0x800000), 0.5);
556 | assert_float_equal(load_part(Mode::UNORM, 32, 0x80000000), 0.5);
557 | assert_float_equal(load_part(Mode::UNORM, 64, 0x8000000000000000), 0.5);
558 | assert_float_equal(load_part(Mode::SNORM, 8, 0x81), -1.0);
559 | assert_float_equal(load_part(Mode::SNORM, 16, 0x8001), -1.0);
560 | assert_float_equal(load_part(Mode::SNORM, 32, 0x80000001), -1.0);
561 | assert_float_equal(
562 | load_part(Mode::SNORM, 64, 0x8000000000000001),
563 | -1.0
564 | );
565 | assert_float_equal(load_part(Mode::UINT, 8, 0x80), 128.0);
566 | assert_float_equal(load_part(Mode::UINT, 16, 0x8000), 32768.0);
567 | assert_float_equal(load_part(Mode::UINT, 32, 0x80000000), 2147483648.0);
568 | assert_float_equal(
569 | load_part(Mode::UINT, 64, 0x200000000),
570 | 8589934592.0,
571 | );
572 | assert_float_equal(load_part(Mode::SINT, 8, 0x80), -128.0);
573 | assert_float_equal(load_part(Mode::SINT, 16, 0x8000), -32768.0);
574 | assert_float_equal(
575 | load_part(Mode::SINT, 32, 0x80000000),
576 | -2147483648.0
577 | );
578 | assert_float_equal(
579 | load_part(Mode::SINT, 64, u64::MAX),
580 | -1.0,
581 | );
582 | assert_float_equal(load_part(Mode::SFLOAT, 16, 0x3c00), 1.0);
583 | assert_float_equal(load_part(Mode::SFLOAT, 32, 0x3f800000), 1.0);
584 | assert_float_equal(
585 | load_part(Mode::SFLOAT, 64, 0xbfe0000000000000),
586 | -0.5
587 | );
588 | }
589 |
590 | #[test]
591 | fn test_load_pixel() {
592 | let dummy_source = [0u8; 32];
593 |
594 | // Test that the code handles every format
595 | for format in FORMATS.iter() {
596 | format.load_pixel(&dummy_source);
597 | }
598 |
599 | let source_data = [5.0f64, 4.0f64, -3.0f64, 0.5f64];
600 | let pixel: Vec<u8> = source_data
601 | .iter()
602 | .map(|v| v.to_ne_bytes())
603 | .flatten()
604 | .collect();
605 | let format =
606 | Format::lookup_by_vk_format(vk::VK_FORMAT_R64G64B64A64_SFLOAT);
607 | assert_eq!(format.load_pixel(&pixel), source_data);
608 |
609 | // Try a depth-stencil format. This should just return the
610 | // default rgb values.
611 | let format =
612 | Format::lookup_by_vk_format(vk::VK_FORMAT_D24_UNORM_S8_UINT);
613 | assert_eq!(format.load_pixel(&[0xff; 4]), [0.0, 0.0, 0.0, 1.0]);
614 |
615 | // Packed format
616 | let format =
617 | Format::lookup_by_vk_format(vk::VK_FORMAT_R5G6B5_UNORM_PACK16);
618 | let pixel = format.load_pixel(&0xae27u16.to_ne_bytes());
619 | let expected = [
620 | 0b10101 as f64 / 0b11111 as f64,
621 | 0b110001 as f64 / 0b111111 as f64,
622 | 0b00111 as f64 / 0b11111 as f64,
623 | 1.0,
624 | ];
625 | for (i, &pixel_comp) in pixel.iter().enumerate() {
626 | assert_float_equal(pixel_comp, expected[i]);
627 | }
628 | }
629 |
630 | #[test]
631 | fn test_alignment() {
632 | let format =
633 | Format::lookup_by_vk_format(vk::VK_FORMAT_R5G6B5_UNORM_PACK16);
634 | assert_eq!(format.alignment(), 2);
635 |
636 | let format =
637 | Format::lookup_by_vk_format(vk::VK_FORMAT_D24_UNORM_S8_UINT);
638 | assert_eq!(format.alignment(), 3);
639 |
640 | let format =
641 | Format::lookup_by_vk_format(vk::VK_FORMAT_R8G8B8_UNORM);
642 | assert_eq!(format.alignment(), 1);
643 | }
644 | }
645 |
```
--------------------------------------------------------------------------------
/vkrunner/vkrunner/enum_table.rs:
--------------------------------------------------------------------------------
```rust
1 | // Automatically generated by make-enums.py
2 | static ENUM_VALUES: [EnumValue; 174] = [
3 | EnumValue {
4 | name: "VK_BLEND_FACTOR_CONSTANT_ALPHA",
5 | value: vk::VK_BLEND_FACTOR_CONSTANT_ALPHA as i32
6 | },
7 | EnumValue {
8 | name: "VK_BLEND_FACTOR_CONSTANT_COLOR",
9 | value: vk::VK_BLEND_FACTOR_CONSTANT_COLOR as i32
10 | },
11 | EnumValue {
12 | name: "VK_BLEND_FACTOR_DST_ALPHA",
13 | value: vk::VK_BLEND_FACTOR_DST_ALPHA as i32
14 | },
15 | EnumValue {
16 | name: "VK_BLEND_FACTOR_DST_COLOR",
17 | value: vk::VK_BLEND_FACTOR_DST_COLOR as i32
18 | },
19 | EnumValue {
20 | name: "VK_BLEND_FACTOR_MAX_ENUM",
21 | value: vk::VK_BLEND_FACTOR_MAX_ENUM as i32
22 | },
23 | EnumValue {
24 | name: "VK_BLEND_FACTOR_ONE",
25 | value: vk::VK_BLEND_FACTOR_ONE as i32
26 | },
27 | EnumValue {
28 | name: "VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA",
29 | value: vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA as i32
30 | },
31 | EnumValue {
32 | name: "VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR",
33 | value: vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR as i32
34 | },
35 | EnumValue {
36 | name: "VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA",
37 | value: vk::VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA as i32
38 | },
39 | EnumValue {
40 | name: "VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR",
41 | value: vk::VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR as i32
42 | },
43 | EnumValue {
44 | name: "VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA",
45 | value: vk::VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA as i32
46 | },
47 | EnumValue {
48 | name: "VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR",
49 | value: vk::VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR as i32
50 | },
51 | EnumValue {
52 | name: "VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA",
53 | value: vk::VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA as i32
54 | },
55 | EnumValue {
56 | name: "VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR",
57 | value: vk::VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR as i32
58 | },
59 | EnumValue {
60 | name: "VK_BLEND_FACTOR_SRC1_ALPHA",
61 | value: vk::VK_BLEND_FACTOR_SRC1_ALPHA as i32
62 | },
63 | EnumValue {
64 | name: "VK_BLEND_FACTOR_SRC1_COLOR",
65 | value: vk::VK_BLEND_FACTOR_SRC1_COLOR as i32
66 | },
67 | EnumValue {
68 | name: "VK_BLEND_FACTOR_SRC_ALPHA",
69 | value: vk::VK_BLEND_FACTOR_SRC_ALPHA as i32
70 | },
71 | EnumValue {
72 | name: "VK_BLEND_FACTOR_SRC_ALPHA_SATURATE",
73 | value: vk::VK_BLEND_FACTOR_SRC_ALPHA_SATURATE as i32
74 | },
75 | EnumValue {
76 | name: "VK_BLEND_FACTOR_SRC_COLOR",
77 | value: vk::VK_BLEND_FACTOR_SRC_COLOR as i32
78 | },
79 | EnumValue {
80 | name: "VK_BLEND_FACTOR_ZERO",
81 | value: vk::VK_BLEND_FACTOR_ZERO as i32
82 | },
83 | EnumValue {
84 | name: "VK_BLEND_OP_ADD",
85 | value: vk::VK_BLEND_OP_ADD as i32
86 | },
87 | EnumValue {
88 | name: "VK_BLEND_OP_BLUE_EXT",
89 | value: vk::VK_BLEND_OP_BLUE_EXT as i32
90 | },
91 | EnumValue {
92 | name: "VK_BLEND_OP_COLORBURN_EXT",
93 | value: vk::VK_BLEND_OP_COLORBURN_EXT as i32
94 | },
95 | EnumValue {
96 | name: "VK_BLEND_OP_COLORDODGE_EXT",
97 | value: vk::VK_BLEND_OP_COLORDODGE_EXT as i32
98 | },
99 | EnumValue {
100 | name: "VK_BLEND_OP_CONTRAST_EXT",
101 | value: vk::VK_BLEND_OP_CONTRAST_EXT as i32
102 | },
103 | EnumValue {
104 | name: "VK_BLEND_OP_DARKEN_EXT",
105 | value: vk::VK_BLEND_OP_DARKEN_EXT as i32
106 | },
107 | EnumValue {
108 | name: "VK_BLEND_OP_DIFFERENCE_EXT",
109 | value: vk::VK_BLEND_OP_DIFFERENCE_EXT as i32
110 | },
111 | EnumValue {
112 | name: "VK_BLEND_OP_DST_ATOP_EXT",
113 | value: vk::VK_BLEND_OP_DST_ATOP_EXT as i32
114 | },
115 | EnumValue {
116 | name: "VK_BLEND_OP_DST_EXT",
117 | value: vk::VK_BLEND_OP_DST_EXT as i32
118 | },
119 | EnumValue {
120 | name: "VK_BLEND_OP_DST_IN_EXT",
121 | value: vk::VK_BLEND_OP_DST_IN_EXT as i32
122 | },
123 | EnumValue {
124 | name: "VK_BLEND_OP_DST_OUT_EXT",
125 | value: vk::VK_BLEND_OP_DST_OUT_EXT as i32
126 | },
127 | EnumValue {
128 | name: "VK_BLEND_OP_DST_OVER_EXT",
129 | value: vk::VK_BLEND_OP_DST_OVER_EXT as i32
130 | },
131 | EnumValue {
132 | name: "VK_BLEND_OP_EXCLUSION_EXT",
133 | value: vk::VK_BLEND_OP_EXCLUSION_EXT as i32
134 | },
135 | EnumValue {
136 | name: "VK_BLEND_OP_GREEN_EXT",
137 | value: vk::VK_BLEND_OP_GREEN_EXT as i32
138 | },
139 | EnumValue {
140 | name: "VK_BLEND_OP_HARDLIGHT_EXT",
141 | value: vk::VK_BLEND_OP_HARDLIGHT_EXT as i32
142 | },
143 | EnumValue {
144 | name: "VK_BLEND_OP_HARDMIX_EXT",
145 | value: vk::VK_BLEND_OP_HARDMIX_EXT as i32
146 | },
147 | EnumValue {
148 | name: "VK_BLEND_OP_HSL_COLOR_EXT",
149 | value: vk::VK_BLEND_OP_HSL_COLOR_EXT as i32
150 | },
151 | EnumValue {
152 | name: "VK_BLEND_OP_HSL_HUE_EXT",
153 | value: vk::VK_BLEND_OP_HSL_HUE_EXT as i32
154 | },
155 | EnumValue {
156 | name: "VK_BLEND_OP_HSL_LUMINOSITY_EXT",
157 | value: vk::VK_BLEND_OP_HSL_LUMINOSITY_EXT as i32
158 | },
159 | EnumValue {
160 | name: "VK_BLEND_OP_HSL_SATURATION_EXT",
161 | value: vk::VK_BLEND_OP_HSL_SATURATION_EXT as i32
162 | },
163 | EnumValue {
164 | name: "VK_BLEND_OP_INVERT_EXT",
165 | value: vk::VK_BLEND_OP_INVERT_EXT as i32
166 | },
167 | EnumValue {
168 | name: "VK_BLEND_OP_INVERT_OVG_EXT",
169 | value: vk::VK_BLEND_OP_INVERT_OVG_EXT as i32
170 | },
171 | EnumValue {
172 | name: "VK_BLEND_OP_INVERT_RGB_EXT",
173 | value: vk::VK_BLEND_OP_INVERT_RGB_EXT as i32
174 | },
175 | EnumValue {
176 | name: "VK_BLEND_OP_LIGHTEN_EXT",
177 | value: vk::VK_BLEND_OP_LIGHTEN_EXT as i32
178 | },
179 | EnumValue {
180 | name: "VK_BLEND_OP_LINEARBURN_EXT",
181 | value: vk::VK_BLEND_OP_LINEARBURN_EXT as i32
182 | },
183 | EnumValue {
184 | name: "VK_BLEND_OP_LINEARDODGE_EXT",
185 | value: vk::VK_BLEND_OP_LINEARDODGE_EXT as i32
186 | },
187 | EnumValue {
188 | name: "VK_BLEND_OP_LINEARLIGHT_EXT",
189 | value: vk::VK_BLEND_OP_LINEARLIGHT_EXT as i32
190 | },
191 | EnumValue {
192 | name: "VK_BLEND_OP_MAX",
193 | value: vk::VK_BLEND_OP_MAX as i32
194 | },
195 | EnumValue {
196 | name: "VK_BLEND_OP_MAX_ENUM",
197 | value: vk::VK_BLEND_OP_MAX_ENUM as i32
198 | },
199 | EnumValue {
200 | name: "VK_BLEND_OP_MIN",
201 | value: vk::VK_BLEND_OP_MIN as i32
202 | },
203 | EnumValue {
204 | name: "VK_BLEND_OP_MINUS_CLAMPED_EXT",
205 | value: vk::VK_BLEND_OP_MINUS_CLAMPED_EXT as i32
206 | },
207 | EnumValue {
208 | name: "VK_BLEND_OP_MINUS_EXT",
209 | value: vk::VK_BLEND_OP_MINUS_EXT as i32
210 | },
211 | EnumValue {
212 | name: "VK_BLEND_OP_MULTIPLY_EXT",
213 | value: vk::VK_BLEND_OP_MULTIPLY_EXT as i32
214 | },
215 | EnumValue {
216 | name: "VK_BLEND_OP_OVERLAY_EXT",
217 | value: vk::VK_BLEND_OP_OVERLAY_EXT as i32
218 | },
219 | EnumValue {
220 | name: "VK_BLEND_OP_PINLIGHT_EXT",
221 | value: vk::VK_BLEND_OP_PINLIGHT_EXT as i32
222 | },
223 | EnumValue {
224 | name: "VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT",
225 | value: vk::VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT as i32
226 | },
227 | EnumValue {
228 | name: "VK_BLEND_OP_PLUS_CLAMPED_EXT",
229 | value: vk::VK_BLEND_OP_PLUS_CLAMPED_EXT as i32
230 | },
231 | EnumValue {
232 | name: "VK_BLEND_OP_PLUS_DARKER_EXT",
233 | value: vk::VK_BLEND_OP_PLUS_DARKER_EXT as i32
234 | },
235 | EnumValue {
236 | name: "VK_BLEND_OP_PLUS_EXT",
237 | value: vk::VK_BLEND_OP_PLUS_EXT as i32
238 | },
239 | EnumValue {
240 | name: "VK_BLEND_OP_RED_EXT",
241 | value: vk::VK_BLEND_OP_RED_EXT as i32
242 | },
243 | EnumValue {
244 | name: "VK_BLEND_OP_REVERSE_SUBTRACT",
245 | value: vk::VK_BLEND_OP_REVERSE_SUBTRACT as i32
246 | },
247 | EnumValue {
248 | name: "VK_BLEND_OP_SCREEN_EXT",
249 | value: vk::VK_BLEND_OP_SCREEN_EXT as i32
250 | },
251 | EnumValue {
252 | name: "VK_BLEND_OP_SOFTLIGHT_EXT",
253 | value: vk::VK_BLEND_OP_SOFTLIGHT_EXT as i32
254 | },
255 | EnumValue {
256 | name: "VK_BLEND_OP_SRC_ATOP_EXT",
257 | value: vk::VK_BLEND_OP_SRC_ATOP_EXT as i32
258 | },
259 | EnumValue {
260 | name: "VK_BLEND_OP_SRC_EXT",
261 | value: vk::VK_BLEND_OP_SRC_EXT as i32
262 | },
263 | EnumValue {
264 | name: "VK_BLEND_OP_SRC_IN_EXT",
265 | value: vk::VK_BLEND_OP_SRC_IN_EXT as i32
266 | },
267 | EnumValue {
268 | name: "VK_BLEND_OP_SRC_OUT_EXT",
269 | value: vk::VK_BLEND_OP_SRC_OUT_EXT as i32
270 | },
271 | EnumValue {
272 | name: "VK_BLEND_OP_SRC_OVER_EXT",
273 | value: vk::VK_BLEND_OP_SRC_OVER_EXT as i32
274 | },
275 | EnumValue {
276 | name: "VK_BLEND_OP_SUBTRACT",
277 | value: vk::VK_BLEND_OP_SUBTRACT as i32
278 | },
279 | EnumValue {
280 | name: "VK_BLEND_OP_VIVIDLIGHT_EXT",
281 | value: vk::VK_BLEND_OP_VIVIDLIGHT_EXT as i32
282 | },
283 | EnumValue {
284 | name: "VK_BLEND_OP_XOR_EXT",
285 | value: vk::VK_BLEND_OP_XOR_EXT as i32
286 | },
287 | EnumValue {
288 | name: "VK_BLEND_OP_ZERO_EXT",
289 | value: vk::VK_BLEND_OP_ZERO_EXT as i32
290 | },
291 | EnumValue {
292 | name: "VK_COLOR_COMPONENT_A_BIT",
293 | value: vk::VK_COLOR_COMPONENT_A_BIT as i32
294 | },
295 | EnumValue {
296 | name: "VK_COLOR_COMPONENT_B_BIT",
297 | value: vk::VK_COLOR_COMPONENT_B_BIT as i32
298 | },
299 | EnumValue {
300 | name: "VK_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM",
301 | value: vk::VK_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM as i32
302 | },
303 | EnumValue {
304 | name: "VK_COLOR_COMPONENT_G_BIT",
305 | value: vk::VK_COLOR_COMPONENT_G_BIT as i32
306 | },
307 | EnumValue {
308 | name: "VK_COLOR_COMPONENT_R_BIT",
309 | value: vk::VK_COLOR_COMPONENT_R_BIT as i32
310 | },
311 | EnumValue {
312 | name: "VK_COMPARE_OP_ALWAYS",
313 | value: vk::VK_COMPARE_OP_ALWAYS as i32
314 | },
315 | EnumValue {
316 | name: "VK_COMPARE_OP_EQUAL",
317 | value: vk::VK_COMPARE_OP_EQUAL as i32
318 | },
319 | EnumValue {
320 | name: "VK_COMPARE_OP_GREATER",
321 | value: vk::VK_COMPARE_OP_GREATER as i32
322 | },
323 | EnumValue {
324 | name: "VK_COMPARE_OP_GREATER_OR_EQUAL",
325 | value: vk::VK_COMPARE_OP_GREATER_OR_EQUAL as i32
326 | },
327 | EnumValue {
328 | name: "VK_COMPARE_OP_LESS",
329 | value: vk::VK_COMPARE_OP_LESS as i32
330 | },
331 | EnumValue {
332 | name: "VK_COMPARE_OP_LESS_OR_EQUAL",
333 | value: vk::VK_COMPARE_OP_LESS_OR_EQUAL as i32
334 | },
335 | EnumValue {
336 | name: "VK_COMPARE_OP_MAX_ENUM",
337 | value: vk::VK_COMPARE_OP_MAX_ENUM as i32
338 | },
339 | EnumValue {
340 | name: "VK_COMPARE_OP_NEVER",
341 | value: vk::VK_COMPARE_OP_NEVER as i32
342 | },
343 | EnumValue {
344 | name: "VK_COMPARE_OP_NOT_EQUAL",
345 | value: vk::VK_COMPARE_OP_NOT_EQUAL as i32
346 | },
347 | EnumValue {
348 | name: "VK_COMPONENT_TYPE_BFLOAT16_KHR",
349 | value: vk::VK_COMPONENT_TYPE_BFLOAT16_KHR as i32
350 | },
351 | EnumValue {
352 | name: "VK_COMPONENT_TYPE_FLOAT16_KHR",
353 | value: vk::VK_COMPONENT_TYPE_FLOAT16_KHR as i32
354 | },
355 | EnumValue {
356 | name: "VK_COMPONENT_TYPE_FLOAT16_NV",
357 | value: vk::VK_COMPONENT_TYPE_FLOAT16_NV as i32
358 | },
359 | EnumValue {
360 | name: "VK_COMPONENT_TYPE_FLOAT32_KHR",
361 | value: vk::VK_COMPONENT_TYPE_FLOAT32_KHR as i32
362 | },
363 | EnumValue {
364 | name: "VK_COMPONENT_TYPE_FLOAT32_NV",
365 | value: vk::VK_COMPONENT_TYPE_FLOAT32_NV as i32
366 | },
367 | EnumValue {
368 | name: "VK_COMPONENT_TYPE_FLOAT64_KHR",
369 | value: vk::VK_COMPONENT_TYPE_FLOAT64_KHR as i32
370 | },
371 | EnumValue {
372 | name: "VK_COMPONENT_TYPE_FLOAT64_NV",
373 | value: vk::VK_COMPONENT_TYPE_FLOAT64_NV as i32
374 | },
375 | EnumValue {
376 | name: "VK_COMPONENT_TYPE_FLOAT_E4M3_NV",
377 | value: vk::VK_COMPONENT_TYPE_FLOAT_E4M3_NV as i32
378 | },
379 | EnumValue {
380 | name: "VK_COMPONENT_TYPE_FLOAT_E5M2_NV",
381 | value: vk::VK_COMPONENT_TYPE_FLOAT_E5M2_NV as i32
382 | },
383 | EnumValue {
384 | name: "VK_COMPONENT_TYPE_MAX_ENUM_KHR",
385 | value: vk::VK_COMPONENT_TYPE_MAX_ENUM_KHR as i32
386 | },
387 | EnumValue {
388 | name: "VK_COMPONENT_TYPE_SINT16_KHR",
389 | value: vk::VK_COMPONENT_TYPE_SINT16_KHR as i32
390 | },
391 | EnumValue {
392 | name: "VK_COMPONENT_TYPE_SINT16_NV",
393 | value: vk::VK_COMPONENT_TYPE_SINT16_NV as i32
394 | },
395 | EnumValue {
396 | name: "VK_COMPONENT_TYPE_SINT32_KHR",
397 | value: vk::VK_COMPONENT_TYPE_SINT32_KHR as i32
398 | },
399 | EnumValue {
400 | name: "VK_COMPONENT_TYPE_SINT32_NV",
401 | value: vk::VK_COMPONENT_TYPE_SINT32_NV as i32
402 | },
403 | EnumValue {
404 | name: "VK_COMPONENT_TYPE_SINT64_KHR",
405 | value: vk::VK_COMPONENT_TYPE_SINT64_KHR as i32
406 | },
407 | EnumValue {
408 | name: "VK_COMPONENT_TYPE_SINT64_NV",
409 | value: vk::VK_COMPONENT_TYPE_SINT64_NV as i32
410 | },
411 | EnumValue {
412 | name: "VK_COMPONENT_TYPE_SINT8_KHR",
413 | value: vk::VK_COMPONENT_TYPE_SINT8_KHR as i32
414 | },
415 | EnumValue {
416 | name: "VK_COMPONENT_TYPE_SINT8_NV",
417 | value: vk::VK_COMPONENT_TYPE_SINT8_NV as i32
418 | },
419 | EnumValue {
420 | name: "VK_COMPONENT_TYPE_SINT8_PACKED_NV",
421 | value: vk::VK_COMPONENT_TYPE_SINT8_PACKED_NV as i32
422 | },
423 | EnumValue {
424 | name: "VK_COMPONENT_TYPE_UINT16_KHR",
425 | value: vk::VK_COMPONENT_TYPE_UINT16_KHR as i32
426 | },
427 | EnumValue {
428 | name: "VK_COMPONENT_TYPE_UINT16_NV",
429 | value: vk::VK_COMPONENT_TYPE_UINT16_NV as i32
430 | },
431 | EnumValue {
432 | name: "VK_COMPONENT_TYPE_UINT32_KHR",
433 | value: vk::VK_COMPONENT_TYPE_UINT32_KHR as i32
434 | },
435 | EnumValue {
436 | name: "VK_COMPONENT_TYPE_UINT32_NV",
437 | value: vk::VK_COMPONENT_TYPE_UINT32_NV as i32
438 | },
439 | EnumValue {
440 | name: "VK_COMPONENT_TYPE_UINT64_KHR",
441 | value: vk::VK_COMPONENT_TYPE_UINT64_KHR as i32
442 | },
443 | EnumValue {
444 | name: "VK_COMPONENT_TYPE_UINT64_NV",
445 | value: vk::VK_COMPONENT_TYPE_UINT64_NV as i32
446 | },
447 | EnumValue {
448 | name: "VK_COMPONENT_TYPE_UINT8_KHR",
449 | value: vk::VK_COMPONENT_TYPE_UINT8_KHR as i32
450 | },
451 | EnumValue {
452 | name: "VK_COMPONENT_TYPE_UINT8_NV",
453 | value: vk::VK_COMPONENT_TYPE_UINT8_NV as i32
454 | },
455 | EnumValue {
456 | name: "VK_COMPONENT_TYPE_UINT8_PACKED_NV",
457 | value: vk::VK_COMPONENT_TYPE_UINT8_PACKED_NV as i32
458 | },
459 | EnumValue {
460 | name: "VK_CULL_MODE_BACK_BIT",
461 | value: vk::VK_CULL_MODE_BACK_BIT as i32
462 | },
463 | EnumValue {
464 | name: "VK_CULL_MODE_FLAG_BITS_MAX_ENUM",
465 | value: vk::VK_CULL_MODE_FLAG_BITS_MAX_ENUM as i32
466 | },
467 | EnumValue {
468 | name: "VK_CULL_MODE_FRONT_AND_BACK",
469 | value: vk::VK_CULL_MODE_FRONT_AND_BACK as i32
470 | },
471 | EnumValue {
472 | name: "VK_CULL_MODE_FRONT_BIT",
473 | value: vk::VK_CULL_MODE_FRONT_BIT as i32
474 | },
475 | EnumValue {
476 | name: "VK_CULL_MODE_NONE",
477 | value: vk::VK_CULL_MODE_NONE as i32
478 | },
479 | EnumValue {
480 | name: "VK_FRONT_FACE_CLOCKWISE",
481 | value: vk::VK_FRONT_FACE_CLOCKWISE as i32
482 | },
483 | EnumValue {
484 | name: "VK_FRONT_FACE_COUNTER_CLOCKWISE",
485 | value: vk::VK_FRONT_FACE_COUNTER_CLOCKWISE as i32
486 | },
487 | EnumValue {
488 | name: "VK_FRONT_FACE_MAX_ENUM",
489 | value: vk::VK_FRONT_FACE_MAX_ENUM as i32
490 | },
491 | EnumValue {
492 | name: "VK_LOGIC_OP_AND",
493 | value: vk::VK_LOGIC_OP_AND as i32
494 | },
495 | EnumValue {
496 | name: "VK_LOGIC_OP_AND_INVERTED",
497 | value: vk::VK_LOGIC_OP_AND_INVERTED as i32
498 | },
499 | EnumValue {
500 | name: "VK_LOGIC_OP_AND_REVERSE",
501 | value: vk::VK_LOGIC_OP_AND_REVERSE as i32
502 | },
503 | EnumValue {
504 | name: "VK_LOGIC_OP_CLEAR",
505 | value: vk::VK_LOGIC_OP_CLEAR as i32
506 | },
507 | EnumValue {
508 | name: "VK_LOGIC_OP_COPY",
509 | value: vk::VK_LOGIC_OP_COPY as i32
510 | },
511 | EnumValue {
512 | name: "VK_LOGIC_OP_COPY_INVERTED",
513 | value: vk::VK_LOGIC_OP_COPY_INVERTED as i32
514 | },
515 | EnumValue {
516 | name: "VK_LOGIC_OP_EQUIVALENT",
517 | value: vk::VK_LOGIC_OP_EQUIVALENT as i32
518 | },
519 | EnumValue {
520 | name: "VK_LOGIC_OP_INVERT",
521 | value: vk::VK_LOGIC_OP_INVERT as i32
522 | },
523 | EnumValue {
524 | name: "VK_LOGIC_OP_MAX_ENUM",
525 | value: vk::VK_LOGIC_OP_MAX_ENUM as i32
526 | },
527 | EnumValue {
528 | name: "VK_LOGIC_OP_NAND",
529 | value: vk::VK_LOGIC_OP_NAND as i32
530 | },
531 | EnumValue {
532 | name: "VK_LOGIC_OP_NOR",
533 | value: vk::VK_LOGIC_OP_NOR as i32
534 | },
535 | EnumValue {
536 | name: "VK_LOGIC_OP_NO_OP",
537 | value: vk::VK_LOGIC_OP_NO_OP as i32
538 | },
539 | EnumValue {
540 | name: "VK_LOGIC_OP_OR",
541 | value: vk::VK_LOGIC_OP_OR as i32
542 | },
543 | EnumValue {
544 | name: "VK_LOGIC_OP_OR_INVERTED",
545 | value: vk::VK_LOGIC_OP_OR_INVERTED as i32
546 | },
547 | EnumValue {
548 | name: "VK_LOGIC_OP_OR_REVERSE",
549 | value: vk::VK_LOGIC_OP_OR_REVERSE as i32
550 | },
551 | EnumValue {
552 | name: "VK_LOGIC_OP_SET",
553 | value: vk::VK_LOGIC_OP_SET as i32
554 | },
555 | EnumValue {
556 | name: "VK_LOGIC_OP_XOR",
557 | value: vk::VK_LOGIC_OP_XOR as i32
558 | },
559 | EnumValue {
560 | name: "VK_POLYGON_MODE_FILL",
561 | value: vk::VK_POLYGON_MODE_FILL as i32
562 | },
563 | EnumValue {
564 | name: "VK_POLYGON_MODE_FILL_RECTANGLE_NV",
565 | value: vk::VK_POLYGON_MODE_FILL_RECTANGLE_NV as i32
566 | },
567 | EnumValue {
568 | name: "VK_POLYGON_MODE_LINE",
569 | value: vk::VK_POLYGON_MODE_LINE as i32
570 | },
571 | EnumValue {
572 | name: "VK_POLYGON_MODE_MAX_ENUM",
573 | value: vk::VK_POLYGON_MODE_MAX_ENUM as i32
574 | },
575 | EnumValue {
576 | name: "VK_POLYGON_MODE_POINT",
577 | value: vk::VK_POLYGON_MODE_POINT as i32
578 | },
579 | EnumValue {
580 | name: "VK_PRIMITIVE_TOPOLOGY_LINE_LIST",
581 | value: vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST as i32
582 | },
583 | EnumValue {
584 | name: "VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY",
585 | value: vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY as i32
586 | },
587 | EnumValue {
588 | name: "VK_PRIMITIVE_TOPOLOGY_LINE_STRIP",
589 | value: vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP as i32
590 | },
591 | EnumValue {
592 | name: "VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY",
593 | value: vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY as i32
594 | },
595 | EnumValue {
596 | name: "VK_PRIMITIVE_TOPOLOGY_MAX_ENUM",
597 | value: vk::VK_PRIMITIVE_TOPOLOGY_MAX_ENUM as i32
598 | },
599 | EnumValue {
600 | name: "VK_PRIMITIVE_TOPOLOGY_PATCH_LIST",
601 | value: vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST as i32
602 | },
603 | EnumValue {
604 | name: "VK_PRIMITIVE_TOPOLOGY_POINT_LIST",
605 | value: vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST as i32
606 | },
607 | EnumValue {
608 | name: "VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN",
609 | value: vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN as i32
610 | },
611 | EnumValue {
612 | name: "VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST",
613 | value: vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST as i32
614 | },
615 | EnumValue {
616 | name: "VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY",
617 | value: vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY as i32
618 | },
619 | EnumValue {
620 | name: "VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP",
621 | value: vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP as i32
622 | },
623 | EnumValue {
624 | name: "VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY",
625 | value: vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY as i32
626 | },
627 | EnumValue {
628 | name: "VK_SCOPE_DEVICE_KHR",
629 | value: vk::VK_SCOPE_DEVICE_KHR as i32
630 | },
631 | EnumValue {
632 | name: "VK_SCOPE_DEVICE_NV",
633 | value: vk::VK_SCOPE_DEVICE_NV as i32
634 | },
635 | EnumValue {
636 | name: "VK_SCOPE_MAX_ENUM_KHR",
637 | value: vk::VK_SCOPE_MAX_ENUM_KHR as i32
638 | },
639 | EnumValue {
640 | name: "VK_SCOPE_QUEUE_FAMILY_KHR",
641 | value: vk::VK_SCOPE_QUEUE_FAMILY_KHR as i32
642 | },
643 | EnumValue {
644 | name: "VK_SCOPE_QUEUE_FAMILY_NV",
645 | value: vk::VK_SCOPE_QUEUE_FAMILY_NV as i32
646 | },
647 | EnumValue {
648 | name: "VK_SCOPE_SUBGROUP_KHR",
649 | value: vk::VK_SCOPE_SUBGROUP_KHR as i32
650 | },
651 | EnumValue {
652 | name: "VK_SCOPE_SUBGROUP_NV",
653 | value: vk::VK_SCOPE_SUBGROUP_NV as i32
654 | },
655 | EnumValue {
656 | name: "VK_SCOPE_WORKGROUP_KHR",
657 | value: vk::VK_SCOPE_WORKGROUP_KHR as i32
658 | },
659 | EnumValue {
660 | name: "VK_SCOPE_WORKGROUP_NV",
661 | value: vk::VK_SCOPE_WORKGROUP_NV as i32
662 | },
663 | EnumValue {
664 | name: "VK_STENCIL_OP_DECREMENT_AND_CLAMP",
665 | value: vk::VK_STENCIL_OP_DECREMENT_AND_CLAMP as i32
666 | },
667 | EnumValue {
668 | name: "VK_STENCIL_OP_DECREMENT_AND_WRAP",
669 | value: vk::VK_STENCIL_OP_DECREMENT_AND_WRAP as i32
670 | },
671 | EnumValue {
672 | name: "VK_STENCIL_OP_INCREMENT_AND_CLAMP",
673 | value: vk::VK_STENCIL_OP_INCREMENT_AND_CLAMP as i32
674 | },
675 | EnumValue {
676 | name: "VK_STENCIL_OP_INCREMENT_AND_WRAP",
677 | value: vk::VK_STENCIL_OP_INCREMENT_AND_WRAP as i32
678 | },
679 | EnumValue {
680 | name: "VK_STENCIL_OP_INVERT",
681 | value: vk::VK_STENCIL_OP_INVERT as i32
682 | },
683 | EnumValue {
684 | name: "VK_STENCIL_OP_KEEP",
685 | value: vk::VK_STENCIL_OP_KEEP as i32
686 | },
687 | EnumValue {
688 | name: "VK_STENCIL_OP_MAX_ENUM",
689 | value: vk::VK_STENCIL_OP_MAX_ENUM as i32
690 | },
691 | EnumValue {
692 | name: "VK_STENCIL_OP_REPLACE",
693 | value: vk::VK_STENCIL_OP_REPLACE as i32
694 | },
695 | EnumValue {
696 | name: "VK_STENCIL_OP_ZERO",
697 | value: vk::VK_STENCIL_OP_ZERO as i32
698 | },
699 | ];
700 |
```
--------------------------------------------------------------------------------
/vkrunner/include/vk_video/vulkan_video_codec_h265std.h:
--------------------------------------------------------------------------------
```
1 | #ifndef VULKAN_VIDEO_CODEC_H265STD_H_
2 | #define VULKAN_VIDEO_CODEC_H265STD_H_ 1
3 |
4 | /*
5 | ** Copyright 2015-2025 The Khronos Group Inc.
6 | **
7 | ** SPDX-License-Identifier: Apache-2.0
8 | */
9 |
10 | /*
11 | ** This header is generated from the Khronos Vulkan XML API Registry.
12 | **
13 | */
14 |
15 |
16 | #ifdef __cplusplus
17 | extern "C" {
18 | #endif
19 |
20 |
21 |
22 | // vulkan_video_codec_h265std is a preprocessor guard. Do not pass it to API calls.
23 | #define vulkan_video_codec_h265std 1
24 | #include "vulkan_video_codecs_common.h"
25 | #define STD_VIDEO_H265_CPB_CNT_LIST_SIZE 32
26 | #define STD_VIDEO_H265_SUBLAYERS_LIST_SIZE 7
27 | #define STD_VIDEO_H265_SCALING_LIST_4X4_NUM_LISTS 6
28 | #define STD_VIDEO_H265_SCALING_LIST_4X4_NUM_ELEMENTS 16
29 | #define STD_VIDEO_H265_SCALING_LIST_8X8_NUM_LISTS 6
30 | #define STD_VIDEO_H265_SCALING_LIST_8X8_NUM_ELEMENTS 64
31 | #define STD_VIDEO_H265_SCALING_LIST_16X16_NUM_LISTS 6
32 | #define STD_VIDEO_H265_SCALING_LIST_16X16_NUM_ELEMENTS 64
33 | #define STD_VIDEO_H265_SCALING_LIST_32X32_NUM_LISTS 2
34 | #define STD_VIDEO_H265_SCALING_LIST_32X32_NUM_ELEMENTS 64
35 | #define STD_VIDEO_H265_CHROMA_QP_OFFSET_LIST_SIZE 6
36 | #define STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_COLS_LIST_SIZE 19
37 | #define STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_ROWS_LIST_SIZE 21
38 | #define STD_VIDEO_H265_PREDICTOR_PALETTE_COMPONENTS_LIST_SIZE 3
39 | #define STD_VIDEO_H265_PREDICTOR_PALETTE_COMP_ENTRIES_LIST_SIZE 128
40 | #define STD_VIDEO_H265_MAX_NUM_LIST_REF 15
41 | #define STD_VIDEO_H265_MAX_CHROMA_PLANES 2
42 | #define STD_VIDEO_H265_MAX_SHORT_TERM_REF_PIC_SETS 64
43 | #define STD_VIDEO_H265_MAX_DPB_SIZE 16
44 | #define STD_VIDEO_H265_MAX_LONG_TERM_REF_PICS_SPS 32
45 | #define STD_VIDEO_H265_MAX_LONG_TERM_PICS 16
46 | #define STD_VIDEO_H265_MAX_DELTA_POC 48
47 | #define STD_VIDEO_H265_NO_REFERENCE_PICTURE 0xFF
48 |
49 | typedef enum StdVideoH265ChromaFormatIdc {
50 | STD_VIDEO_H265_CHROMA_FORMAT_IDC_MONOCHROME = 0,
51 | STD_VIDEO_H265_CHROMA_FORMAT_IDC_420 = 1,
52 | STD_VIDEO_H265_CHROMA_FORMAT_IDC_422 = 2,
53 | STD_VIDEO_H265_CHROMA_FORMAT_IDC_444 = 3,
54 | STD_VIDEO_H265_CHROMA_FORMAT_IDC_INVALID = 0x7FFFFFFF,
55 | STD_VIDEO_H265_CHROMA_FORMAT_IDC_MAX_ENUM = 0x7FFFFFFF
56 | } StdVideoH265ChromaFormatIdc;
57 |
58 | typedef enum StdVideoH265ProfileIdc {
59 | STD_VIDEO_H265_PROFILE_IDC_MAIN = 1,
60 | STD_VIDEO_H265_PROFILE_IDC_MAIN_10 = 2,
61 | STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE = 3,
62 | STD_VIDEO_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSIONS = 4,
63 | STD_VIDEO_H265_PROFILE_IDC_SCC_EXTENSIONS = 9,
64 | STD_VIDEO_H265_PROFILE_IDC_INVALID = 0x7FFFFFFF,
65 | STD_VIDEO_H265_PROFILE_IDC_MAX_ENUM = 0x7FFFFFFF
66 | } StdVideoH265ProfileIdc;
67 |
68 | typedef enum StdVideoH265LevelIdc {
69 | STD_VIDEO_H265_LEVEL_IDC_1_0 = 0,
70 | STD_VIDEO_H265_LEVEL_IDC_2_0 = 1,
71 | STD_VIDEO_H265_LEVEL_IDC_2_1 = 2,
72 | STD_VIDEO_H265_LEVEL_IDC_3_0 = 3,
73 | STD_VIDEO_H265_LEVEL_IDC_3_1 = 4,
74 | STD_VIDEO_H265_LEVEL_IDC_4_0 = 5,
75 | STD_VIDEO_H265_LEVEL_IDC_4_1 = 6,
76 | STD_VIDEO_H265_LEVEL_IDC_5_0 = 7,
77 | STD_VIDEO_H265_LEVEL_IDC_5_1 = 8,
78 | STD_VIDEO_H265_LEVEL_IDC_5_2 = 9,
79 | STD_VIDEO_H265_LEVEL_IDC_6_0 = 10,
80 | STD_VIDEO_H265_LEVEL_IDC_6_1 = 11,
81 | STD_VIDEO_H265_LEVEL_IDC_6_2 = 12,
82 | STD_VIDEO_H265_LEVEL_IDC_INVALID = 0x7FFFFFFF,
83 | STD_VIDEO_H265_LEVEL_IDC_MAX_ENUM = 0x7FFFFFFF
84 | } StdVideoH265LevelIdc;
85 |
86 | typedef enum StdVideoH265SliceType {
87 | STD_VIDEO_H265_SLICE_TYPE_B = 0,
88 | STD_VIDEO_H265_SLICE_TYPE_P = 1,
89 | STD_VIDEO_H265_SLICE_TYPE_I = 2,
90 | STD_VIDEO_H265_SLICE_TYPE_INVALID = 0x7FFFFFFF,
91 | STD_VIDEO_H265_SLICE_TYPE_MAX_ENUM = 0x7FFFFFFF
92 | } StdVideoH265SliceType;
93 |
94 | typedef enum StdVideoH265PictureType {
95 | STD_VIDEO_H265_PICTURE_TYPE_P = 0,
96 | STD_VIDEO_H265_PICTURE_TYPE_B = 1,
97 | STD_VIDEO_H265_PICTURE_TYPE_I = 2,
98 | STD_VIDEO_H265_PICTURE_TYPE_IDR = 3,
99 | STD_VIDEO_H265_PICTURE_TYPE_INVALID = 0x7FFFFFFF,
100 | STD_VIDEO_H265_PICTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
101 | } StdVideoH265PictureType;
102 |
103 | typedef enum StdVideoH265AspectRatioIdc {
104 | STD_VIDEO_H265_ASPECT_RATIO_IDC_UNSPECIFIED = 0,
105 | STD_VIDEO_H265_ASPECT_RATIO_IDC_SQUARE = 1,
106 | STD_VIDEO_H265_ASPECT_RATIO_IDC_12_11 = 2,
107 | STD_VIDEO_H265_ASPECT_RATIO_IDC_10_11 = 3,
108 | STD_VIDEO_H265_ASPECT_RATIO_IDC_16_11 = 4,
109 | STD_VIDEO_H265_ASPECT_RATIO_IDC_40_33 = 5,
110 | STD_VIDEO_H265_ASPECT_RATIO_IDC_24_11 = 6,
111 | STD_VIDEO_H265_ASPECT_RATIO_IDC_20_11 = 7,
112 | STD_VIDEO_H265_ASPECT_RATIO_IDC_32_11 = 8,
113 | STD_VIDEO_H265_ASPECT_RATIO_IDC_80_33 = 9,
114 | STD_VIDEO_H265_ASPECT_RATIO_IDC_18_11 = 10,
115 | STD_VIDEO_H265_ASPECT_RATIO_IDC_15_11 = 11,
116 | STD_VIDEO_H265_ASPECT_RATIO_IDC_64_33 = 12,
117 | STD_VIDEO_H265_ASPECT_RATIO_IDC_160_99 = 13,
118 | STD_VIDEO_H265_ASPECT_RATIO_IDC_4_3 = 14,
119 | STD_VIDEO_H265_ASPECT_RATIO_IDC_3_2 = 15,
120 | STD_VIDEO_H265_ASPECT_RATIO_IDC_2_1 = 16,
121 | STD_VIDEO_H265_ASPECT_RATIO_IDC_EXTENDED_SAR = 255,
122 | STD_VIDEO_H265_ASPECT_RATIO_IDC_INVALID = 0x7FFFFFFF,
123 | STD_VIDEO_H265_ASPECT_RATIO_IDC_MAX_ENUM = 0x7FFFFFFF
124 | } StdVideoH265AspectRatioIdc;
125 | typedef struct StdVideoH265DecPicBufMgr {
126 | uint32_t max_latency_increase_plus1[STD_VIDEO_H265_SUBLAYERS_LIST_SIZE];
127 | uint8_t max_dec_pic_buffering_minus1[STD_VIDEO_H265_SUBLAYERS_LIST_SIZE];
128 | uint8_t max_num_reorder_pics[STD_VIDEO_H265_SUBLAYERS_LIST_SIZE];
129 | } StdVideoH265DecPicBufMgr;
130 |
131 | typedef struct StdVideoH265SubLayerHrdParameters {
132 | uint32_t bit_rate_value_minus1[STD_VIDEO_H265_CPB_CNT_LIST_SIZE];
133 | uint32_t cpb_size_value_minus1[STD_VIDEO_H265_CPB_CNT_LIST_SIZE];
134 | uint32_t cpb_size_du_value_minus1[STD_VIDEO_H265_CPB_CNT_LIST_SIZE];
135 | uint32_t bit_rate_du_value_minus1[STD_VIDEO_H265_CPB_CNT_LIST_SIZE];
136 | uint32_t cbr_flag;
137 | } StdVideoH265SubLayerHrdParameters;
138 |
139 | typedef struct StdVideoH265HrdFlags {
140 | uint32_t nal_hrd_parameters_present_flag : 1;
141 | uint32_t vcl_hrd_parameters_present_flag : 1;
142 | uint32_t sub_pic_hrd_params_present_flag : 1;
143 | uint32_t sub_pic_cpb_params_in_pic_timing_sei_flag : 1;
144 | uint32_t fixed_pic_rate_general_flag : 8;
145 | uint32_t fixed_pic_rate_within_cvs_flag : 8;
146 | uint32_t low_delay_hrd_flag : 8;
147 | } StdVideoH265HrdFlags;
148 |
149 | typedef struct StdVideoH265HrdParameters {
150 | StdVideoH265HrdFlags flags;
151 | uint8_t tick_divisor_minus2;
152 | uint8_t du_cpb_removal_delay_increment_length_minus1;
153 | uint8_t dpb_output_delay_du_length_minus1;
154 | uint8_t bit_rate_scale;
155 | uint8_t cpb_size_scale;
156 | uint8_t cpb_size_du_scale;
157 | uint8_t initial_cpb_removal_delay_length_minus1;
158 | uint8_t au_cpb_removal_delay_length_minus1;
159 | uint8_t dpb_output_delay_length_minus1;
160 | uint8_t cpb_cnt_minus1[STD_VIDEO_H265_SUBLAYERS_LIST_SIZE];
161 | uint16_t elemental_duration_in_tc_minus1[STD_VIDEO_H265_SUBLAYERS_LIST_SIZE];
162 | uint16_t reserved[3];
163 | const StdVideoH265SubLayerHrdParameters* pSubLayerHrdParametersNal;
164 | const StdVideoH265SubLayerHrdParameters* pSubLayerHrdParametersVcl;
165 | } StdVideoH265HrdParameters;
166 |
167 | typedef struct StdVideoH265VpsFlags {
168 | uint32_t vps_temporal_id_nesting_flag : 1;
169 | uint32_t vps_sub_layer_ordering_info_present_flag : 1;
170 | uint32_t vps_timing_info_present_flag : 1;
171 | uint32_t vps_poc_proportional_to_timing_flag : 1;
172 | } StdVideoH265VpsFlags;
173 |
174 | typedef struct StdVideoH265ProfileTierLevelFlags {
175 | uint32_t general_tier_flag : 1;
176 | uint32_t general_progressive_source_flag : 1;
177 | uint32_t general_interlaced_source_flag : 1;
178 | uint32_t general_non_packed_constraint_flag : 1;
179 | uint32_t general_frame_only_constraint_flag : 1;
180 | } StdVideoH265ProfileTierLevelFlags;
181 |
182 | typedef struct StdVideoH265ProfileTierLevel {
183 | StdVideoH265ProfileTierLevelFlags flags;
184 | StdVideoH265ProfileIdc general_profile_idc;
185 | StdVideoH265LevelIdc general_level_idc;
186 | } StdVideoH265ProfileTierLevel;
187 |
188 | typedef struct StdVideoH265VideoParameterSet {
189 | StdVideoH265VpsFlags flags;
190 | uint8_t vps_video_parameter_set_id;
191 | uint8_t vps_max_sub_layers_minus1;
192 | uint8_t reserved1;
193 | uint8_t reserved2;
194 | uint32_t vps_num_units_in_tick;
195 | uint32_t vps_time_scale;
196 | uint32_t vps_num_ticks_poc_diff_one_minus1;
197 | uint32_t reserved3;
198 | const StdVideoH265DecPicBufMgr* pDecPicBufMgr;
199 | const StdVideoH265HrdParameters* pHrdParameters;
200 | const StdVideoH265ProfileTierLevel* pProfileTierLevel;
201 | } StdVideoH265VideoParameterSet;
202 |
203 | typedef struct StdVideoH265ScalingLists {
204 | uint8_t ScalingList4x4[STD_VIDEO_H265_SCALING_LIST_4X4_NUM_LISTS][STD_VIDEO_H265_SCALING_LIST_4X4_NUM_ELEMENTS];
205 | uint8_t ScalingList8x8[STD_VIDEO_H265_SCALING_LIST_8X8_NUM_LISTS][STD_VIDEO_H265_SCALING_LIST_8X8_NUM_ELEMENTS];
206 | uint8_t ScalingList16x16[STD_VIDEO_H265_SCALING_LIST_16X16_NUM_LISTS][STD_VIDEO_H265_SCALING_LIST_16X16_NUM_ELEMENTS];
207 | uint8_t ScalingList32x32[STD_VIDEO_H265_SCALING_LIST_32X32_NUM_LISTS][STD_VIDEO_H265_SCALING_LIST_32X32_NUM_ELEMENTS];
208 | uint8_t ScalingListDCCoef16x16[STD_VIDEO_H265_SCALING_LIST_16X16_NUM_LISTS];
209 | uint8_t ScalingListDCCoef32x32[STD_VIDEO_H265_SCALING_LIST_32X32_NUM_LISTS];
210 | } StdVideoH265ScalingLists;
211 |
212 | typedef struct StdVideoH265SpsVuiFlags {
213 | uint32_t aspect_ratio_info_present_flag : 1;
214 | uint32_t overscan_info_present_flag : 1;
215 | uint32_t overscan_appropriate_flag : 1;
216 | uint32_t video_signal_type_present_flag : 1;
217 | uint32_t video_full_range_flag : 1;
218 | uint32_t colour_description_present_flag : 1;
219 | uint32_t chroma_loc_info_present_flag : 1;
220 | uint32_t neutral_chroma_indication_flag : 1;
221 | uint32_t field_seq_flag : 1;
222 | uint32_t frame_field_info_present_flag : 1;
223 | uint32_t default_display_window_flag : 1;
224 | uint32_t vui_timing_info_present_flag : 1;
225 | uint32_t vui_poc_proportional_to_timing_flag : 1;
226 | uint32_t vui_hrd_parameters_present_flag : 1;
227 | uint32_t bitstream_restriction_flag : 1;
228 | uint32_t tiles_fixed_structure_flag : 1;
229 | uint32_t motion_vectors_over_pic_boundaries_flag : 1;
230 | uint32_t restricted_ref_pic_lists_flag : 1;
231 | } StdVideoH265SpsVuiFlags;
232 |
233 | typedef struct StdVideoH265SequenceParameterSetVui {
234 | StdVideoH265SpsVuiFlags flags;
235 | StdVideoH265AspectRatioIdc aspect_ratio_idc;
236 | uint16_t sar_width;
237 | uint16_t sar_height;
238 | uint8_t video_format;
239 | uint8_t colour_primaries;
240 | uint8_t transfer_characteristics;
241 | uint8_t matrix_coeffs;
242 | uint8_t chroma_sample_loc_type_top_field;
243 | uint8_t chroma_sample_loc_type_bottom_field;
244 | uint8_t reserved1;
245 | uint8_t reserved2;
246 | uint16_t def_disp_win_left_offset;
247 | uint16_t def_disp_win_right_offset;
248 | uint16_t def_disp_win_top_offset;
249 | uint16_t def_disp_win_bottom_offset;
250 | uint32_t vui_num_units_in_tick;
251 | uint32_t vui_time_scale;
252 | uint32_t vui_num_ticks_poc_diff_one_minus1;
253 | uint16_t min_spatial_segmentation_idc;
254 | uint16_t reserved3;
255 | uint8_t max_bytes_per_pic_denom;
256 | uint8_t max_bits_per_min_cu_denom;
257 | uint8_t log2_max_mv_length_horizontal;
258 | uint8_t log2_max_mv_length_vertical;
259 | const StdVideoH265HrdParameters* pHrdParameters;
260 | } StdVideoH265SequenceParameterSetVui;
261 |
262 | typedef struct StdVideoH265PredictorPaletteEntries {
263 | uint16_t PredictorPaletteEntries[STD_VIDEO_H265_PREDICTOR_PALETTE_COMPONENTS_LIST_SIZE][STD_VIDEO_H265_PREDICTOR_PALETTE_COMP_ENTRIES_LIST_SIZE];
264 | } StdVideoH265PredictorPaletteEntries;
265 |
266 | typedef struct StdVideoH265SpsFlags {
267 | uint32_t sps_temporal_id_nesting_flag : 1;
268 | uint32_t separate_colour_plane_flag : 1;
269 | uint32_t conformance_window_flag : 1;
270 | uint32_t sps_sub_layer_ordering_info_present_flag : 1;
271 | uint32_t scaling_list_enabled_flag : 1;
272 | uint32_t sps_scaling_list_data_present_flag : 1;
273 | uint32_t amp_enabled_flag : 1;
274 | uint32_t sample_adaptive_offset_enabled_flag : 1;
275 | uint32_t pcm_enabled_flag : 1;
276 | uint32_t pcm_loop_filter_disabled_flag : 1;
277 | uint32_t long_term_ref_pics_present_flag : 1;
278 | uint32_t sps_temporal_mvp_enabled_flag : 1;
279 | uint32_t strong_intra_smoothing_enabled_flag : 1;
280 | uint32_t vui_parameters_present_flag : 1;
281 | uint32_t sps_extension_present_flag : 1;
282 | uint32_t sps_range_extension_flag : 1;
283 | uint32_t transform_skip_rotation_enabled_flag : 1;
284 | uint32_t transform_skip_context_enabled_flag : 1;
285 | uint32_t implicit_rdpcm_enabled_flag : 1;
286 | uint32_t explicit_rdpcm_enabled_flag : 1;
287 | uint32_t extended_precision_processing_flag : 1;
288 | uint32_t intra_smoothing_disabled_flag : 1;
289 | uint32_t high_precision_offsets_enabled_flag : 1;
290 | uint32_t persistent_rice_adaptation_enabled_flag : 1;
291 | uint32_t cabac_bypass_alignment_enabled_flag : 1;
292 | uint32_t sps_scc_extension_flag : 1;
293 | uint32_t sps_curr_pic_ref_enabled_flag : 1;
294 | uint32_t palette_mode_enabled_flag : 1;
295 | uint32_t sps_palette_predictor_initializers_present_flag : 1;
296 | uint32_t intra_boundary_filtering_disabled_flag : 1;
297 | } StdVideoH265SpsFlags;
298 |
299 | typedef struct StdVideoH265ShortTermRefPicSetFlags {
300 | uint32_t inter_ref_pic_set_prediction_flag : 1;
301 | uint32_t delta_rps_sign : 1;
302 | } StdVideoH265ShortTermRefPicSetFlags;
303 |
304 | typedef struct StdVideoH265ShortTermRefPicSet {
305 | StdVideoH265ShortTermRefPicSetFlags flags;
306 | uint32_t delta_idx_minus1;
307 | uint16_t use_delta_flag;
308 | uint16_t abs_delta_rps_minus1;
309 | uint16_t used_by_curr_pic_flag;
310 | uint16_t used_by_curr_pic_s0_flag;
311 | uint16_t used_by_curr_pic_s1_flag;
312 | uint16_t reserved1;
313 | uint8_t reserved2;
314 | uint8_t reserved3;
315 | uint8_t num_negative_pics;
316 | uint8_t num_positive_pics;
317 | uint16_t delta_poc_s0_minus1[STD_VIDEO_H265_MAX_DPB_SIZE];
318 | uint16_t delta_poc_s1_minus1[STD_VIDEO_H265_MAX_DPB_SIZE];
319 | } StdVideoH265ShortTermRefPicSet;
320 |
321 | typedef struct StdVideoH265LongTermRefPicsSps {
322 | uint32_t used_by_curr_pic_lt_sps_flag;
323 | uint32_t lt_ref_pic_poc_lsb_sps[STD_VIDEO_H265_MAX_LONG_TERM_REF_PICS_SPS];
324 | } StdVideoH265LongTermRefPicsSps;
325 |
326 | typedef struct StdVideoH265SequenceParameterSet {
327 | StdVideoH265SpsFlags flags;
328 | StdVideoH265ChromaFormatIdc chroma_format_idc;
329 | uint32_t pic_width_in_luma_samples;
330 | uint32_t pic_height_in_luma_samples;
331 | uint8_t sps_video_parameter_set_id;
332 | uint8_t sps_max_sub_layers_minus1;
333 | uint8_t sps_seq_parameter_set_id;
334 | uint8_t bit_depth_luma_minus8;
335 | uint8_t bit_depth_chroma_minus8;
336 | uint8_t log2_max_pic_order_cnt_lsb_minus4;
337 | uint8_t log2_min_luma_coding_block_size_minus3;
338 | uint8_t log2_diff_max_min_luma_coding_block_size;
339 | uint8_t log2_min_luma_transform_block_size_minus2;
340 | uint8_t log2_diff_max_min_luma_transform_block_size;
341 | uint8_t max_transform_hierarchy_depth_inter;
342 | uint8_t max_transform_hierarchy_depth_intra;
343 | uint8_t num_short_term_ref_pic_sets;
344 | uint8_t num_long_term_ref_pics_sps;
345 | uint8_t pcm_sample_bit_depth_luma_minus1;
346 | uint8_t pcm_sample_bit_depth_chroma_minus1;
347 | uint8_t log2_min_pcm_luma_coding_block_size_minus3;
348 | uint8_t log2_diff_max_min_pcm_luma_coding_block_size;
349 | uint8_t reserved1;
350 | uint8_t reserved2;
351 | uint8_t palette_max_size;
352 | uint8_t delta_palette_max_predictor_size;
353 | uint8_t motion_vector_resolution_control_idc;
354 | uint8_t sps_num_palette_predictor_initializers_minus1;
355 | uint32_t conf_win_left_offset;
356 | uint32_t conf_win_right_offset;
357 | uint32_t conf_win_top_offset;
358 | uint32_t conf_win_bottom_offset;
359 | const StdVideoH265ProfileTierLevel* pProfileTierLevel;
360 | const StdVideoH265DecPicBufMgr* pDecPicBufMgr;
361 | const StdVideoH265ScalingLists* pScalingLists;
362 | const StdVideoH265ShortTermRefPicSet* pShortTermRefPicSet;
363 | const StdVideoH265LongTermRefPicsSps* pLongTermRefPicsSps;
364 | const StdVideoH265SequenceParameterSetVui* pSequenceParameterSetVui;
365 | const StdVideoH265PredictorPaletteEntries* pPredictorPaletteEntries;
366 | } StdVideoH265SequenceParameterSet;
367 |
368 | typedef struct StdVideoH265PpsFlags {
369 | uint32_t dependent_slice_segments_enabled_flag : 1;
370 | uint32_t output_flag_present_flag : 1;
371 | uint32_t sign_data_hiding_enabled_flag : 1;
372 | uint32_t cabac_init_present_flag : 1;
373 | uint32_t constrained_intra_pred_flag : 1;
374 | uint32_t transform_skip_enabled_flag : 1;
375 | uint32_t cu_qp_delta_enabled_flag : 1;
376 | uint32_t pps_slice_chroma_qp_offsets_present_flag : 1;
377 | uint32_t weighted_pred_flag : 1;
378 | uint32_t weighted_bipred_flag : 1;
379 | uint32_t transquant_bypass_enabled_flag : 1;
380 | uint32_t tiles_enabled_flag : 1;
381 | uint32_t entropy_coding_sync_enabled_flag : 1;
382 | uint32_t uniform_spacing_flag : 1;
383 | uint32_t loop_filter_across_tiles_enabled_flag : 1;
384 | uint32_t pps_loop_filter_across_slices_enabled_flag : 1;
385 | uint32_t deblocking_filter_control_present_flag : 1;
386 | uint32_t deblocking_filter_override_enabled_flag : 1;
387 | uint32_t pps_deblocking_filter_disabled_flag : 1;
388 | uint32_t pps_scaling_list_data_present_flag : 1;
389 | uint32_t lists_modification_present_flag : 1;
390 | uint32_t slice_segment_header_extension_present_flag : 1;
391 | uint32_t pps_extension_present_flag : 1;
392 | uint32_t cross_component_prediction_enabled_flag : 1;
393 | uint32_t chroma_qp_offset_list_enabled_flag : 1;
394 | uint32_t pps_curr_pic_ref_enabled_flag : 1;
395 | uint32_t residual_adaptive_colour_transform_enabled_flag : 1;
396 | uint32_t pps_slice_act_qp_offsets_present_flag : 1;
397 | uint32_t pps_palette_predictor_initializers_present_flag : 1;
398 | uint32_t monochrome_palette_flag : 1;
399 | uint32_t pps_range_extension_flag : 1;
400 | } StdVideoH265PpsFlags;
401 |
402 | typedef struct StdVideoH265PictureParameterSet {
403 | StdVideoH265PpsFlags flags;
404 | uint8_t pps_pic_parameter_set_id;
405 | uint8_t pps_seq_parameter_set_id;
406 | uint8_t sps_video_parameter_set_id;
407 | uint8_t num_extra_slice_header_bits;
408 | uint8_t num_ref_idx_l0_default_active_minus1;
409 | uint8_t num_ref_idx_l1_default_active_minus1;
410 | int8_t init_qp_minus26;
411 | uint8_t diff_cu_qp_delta_depth;
412 | int8_t pps_cb_qp_offset;
413 | int8_t pps_cr_qp_offset;
414 | int8_t pps_beta_offset_div2;
415 | int8_t pps_tc_offset_div2;
416 | uint8_t log2_parallel_merge_level_minus2;
417 | uint8_t log2_max_transform_skip_block_size_minus2;
418 | uint8_t diff_cu_chroma_qp_offset_depth;
419 | uint8_t chroma_qp_offset_list_len_minus1;
420 | int8_t cb_qp_offset_list[STD_VIDEO_H265_CHROMA_QP_OFFSET_LIST_SIZE];
421 | int8_t cr_qp_offset_list[STD_VIDEO_H265_CHROMA_QP_OFFSET_LIST_SIZE];
422 | uint8_t log2_sao_offset_scale_luma;
423 | uint8_t log2_sao_offset_scale_chroma;
424 | int8_t pps_act_y_qp_offset_plus5;
425 | int8_t pps_act_cb_qp_offset_plus5;
426 | int8_t pps_act_cr_qp_offset_plus3;
427 | uint8_t pps_num_palette_predictor_initializers;
428 | uint8_t luma_bit_depth_entry_minus8;
429 | uint8_t chroma_bit_depth_entry_minus8;
430 | uint8_t num_tile_columns_minus1;
431 | uint8_t num_tile_rows_minus1;
432 | uint8_t reserved1;
433 | uint8_t reserved2;
434 | uint16_t column_width_minus1[STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_COLS_LIST_SIZE];
435 | uint16_t row_height_minus1[STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_ROWS_LIST_SIZE];
436 | uint32_t reserved3;
437 | const StdVideoH265ScalingLists* pScalingLists;
438 | const StdVideoH265PredictorPaletteEntries* pPredictorPaletteEntries;
439 | } StdVideoH265PictureParameterSet;
440 |
441 |
442 | #ifdef __cplusplus
443 | }
444 | #endif
445 |
446 | #endif
447 |
```
--------------------------------------------------------------------------------
/vkrunner/src/main.rs:
--------------------------------------------------------------------------------
```rust
1 | // vkrunner
2 | //
3 | // Copyright (C) 2018 Intel Corporation
4 | // Copyright 2023 Neil Roberts
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a
7 | // copy of this software and associated documentation files (the "Software"),
8 | // to deal in the Software without restriction, including without limitation
9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 | // and/or sell copies of the Software, and to permit persons to whom the
11 | // Software is furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice (including the next
14 | // paragraph) shall be included in all copies or substantial portions of the
15 | // 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
20 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 | // DEALINGS IN THE SOFTWARE.
24 |
25 | use std::ffi::{OsString, OsStr};
26 | use std::collections::HashMap;
27 | use std::fmt;
28 | use std::process::ExitCode;
29 | use std::ptr;
30 | use std::rc::Rc;
31 | use std::cell::RefCell;
32 | use std::ffi::c_void;
33 | use std::io::{self, BufWriter};
34 | use std::fs::File;
35 | extern crate vkrunner;
36 | use vkrunner::{Config, Executor, Source, inspect, result};
37 |
38 | #[derive(Debug)]
39 | struct Opt {
40 | short: Option<char>,
41 | long: &'static str,
42 | help: &'static str,
43 | argument_name: Option<&'static str>,
44 | argument_type: ArgumentType,
45 | }
46 |
47 | #[derive(Debug)]
48 | enum OptError {
49 | UnknownOption(String),
50 | MissingArgument(&'static Opt),
51 | InvalidUtf8(&'static Opt),
52 | InvalidInteger(String),
53 | ArgumentForFlag(&'static Opt),
54 | }
55 |
56 | #[derive(Debug)]
57 | enum Error {
58 | OptError(OptError),
59 | InvalidTokenReplacement(String),
60 | ShowHelp,
61 | TestFailed,
62 | IoError(io::Error),
63 | BufferNotFound(u32),
64 | NoBuffers,
65 | ZeroDeviceId,
66 | }
67 |
68 | #[derive(Debug)]
69 | enum ArgumentType {
70 | Flag,
71 | Filename,
72 | StringArray,
73 | Integer,
74 | }
75 |
76 | #[derive(Debug)]
77 | enum ArgumentValue {
78 | Flag,
79 | Filename(OsString),
80 | StringArray(Vec<String>),
81 | Integer(u32),
82 | }
83 |
84 | type OptValues = HashMap<&'static str, ArgumentValue>;
85 |
86 | #[derive(Debug)]
87 | struct Options {
88 | values: OptValues,
89 | scripts: Vec<OsString>,
90 | }
91 |
92 | #[derive(Debug)]
93 | struct TokenReplacement<'a> {
94 | token: &'a str,
95 | replacement: &'a str,
96 | }
97 |
98 | impl fmt::Display for OptError {
99 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
100 | match self {
101 | OptError::UnknownOption(s) => write!(f, "Unknown option: {}", s),
102 | OptError::MissingArgument(o) => {
103 | write!(f, "Option --{} requires an argument", o.long)
104 | },
105 | OptError::InvalidUtf8(o) => {
106 | write!(f, "Invalid UTF-8 in argument to --{}", o.long)
107 | },
108 | OptError::InvalidInteger(s) => {
109 | write!(f, "Invalid integer: {}", s)
110 | },
111 | OptError::ArgumentForFlag(o) => {
112 | write!(
113 | f,
114 | "Option --{} is a flag and can not take an argument",
115 | o.long,
116 | )
117 | },
118 | }
119 | }
120 | }
121 |
122 | impl fmt::Display for Error {
123 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
124 | match self {
125 | Error::OptError(e) => e.fmt(f),
126 | Error::InvalidTokenReplacement(s) => {
127 | write!(f, "Invalid token replacement: {}", s)
128 | },
129 | Error::ShowHelp => format_help(f),
130 | Error::TestFailed => {
131 | write!(f, "{}", format_result(result::Result::Fail))
132 | },
133 | Error::IoError(e) => e.fmt(f),
134 | Error::BufferNotFound(binding) => {
135 | write!(f, "No buffer with binding {} was found", binding)
136 | },
137 | Error::NoBuffers => {
138 | write!(
139 | f,
140 | "Buffer dump requested but the script has no buffers"
141 | )
142 | },
143 | Error::ZeroDeviceId => {
144 | write!(
145 | f,
146 | "Device IDs start from 1 but 0 was specified",
147 | )
148 | },
149 | }
150 | }
151 | }
152 |
153 | impl From<OptError> for Error {
154 | fn from(e: OptError) -> Error {
155 | Error::OptError(e)
156 | }
157 | }
158 |
159 | impl From<io::Error> for Error {
160 | fn from(e: io::Error) -> Error {
161 | Error::IoError(e)
162 | }
163 | }
164 |
165 | static HELP_OPTION: &'static str = "help";
166 | static IMAGE_OPTION: &'static str = "image";
167 | static BUFFER_OPTION: &'static str = "buffer";
168 | static BINDING_OPTION: &'static str = "binding";
169 | static DISASM_OPTION: &'static str = "disasm";
170 | static REPLACE_OPTION: &'static str = "replace";
171 | static QUIET_OPTION: &'static str = "quiet";
172 | static DEVICE_ID_OPTION: &'static str = "device-id";
173 |
174 | static OPTIONS: [Opt; 8] = [
175 | Opt {
176 | short: Some('h'),
177 | long: HELP_OPTION,
178 | help: "Show this help message",
179 | argument_name: None,
180 | argument_type: ArgumentType::Flag,
181 | },
182 | Opt {
183 | short: Some('i'),
184 | long: IMAGE_OPTION,
185 | help: "Write the final rendering to IMG as a PPM image",
186 | argument_name: Some("IMG"),
187 | argument_type: ArgumentType::Filename,
188 | },
189 | Opt {
190 | short: Some('b'),
191 | long: BUFFER_OPTION,
192 | help: "Dump contents of a UBO or SSBO to BUF",
193 | argument_name: Some("BUF"),
194 | argument_type: ArgumentType::Filename,
195 | },
196 | Opt {
197 | short: Some('B'),
198 | long: BINDING_OPTION,
199 | help: "Select which buffer to dump using the -b option. Defaults to \
200 | first buffer",
201 | argument_name: Some("BINDING"),
202 | argument_type: ArgumentType::Integer,
203 | },
204 | Opt {
205 | short: Some('d'),
206 | long: DISASM_OPTION,
207 | help: "Show the SPIR-V disassembly",
208 | argument_name: None,
209 | argument_type: ArgumentType::Flag,
210 | },
211 | Opt {
212 | short: Some('D'),
213 | long: REPLACE_OPTION,
214 | help: "Replace occurences of TOK with REPL in the scripts",
215 | argument_name: Some("TOK=REPL"),
216 | argument_type: ArgumentType::StringArray,
217 | },
218 | Opt {
219 | short: Some('q'),
220 | long: QUIET_OPTION,
221 | help: "Don’t print any non-error information to stdout",
222 | argument_name: None,
223 | argument_type: ArgumentType::Flag,
224 | },
225 | Opt {
226 | short: None,
227 | long: DEVICE_ID_OPTION,
228 | help: "Select the Vulkan device",
229 | argument_name: Some("DEVID"),
230 | argument_type: ArgumentType::Integer,
231 | },
232 | ];
233 |
234 | fn format_help(f: &mut fmt::Formatter) -> fmt::Result {
235 | writeln!(
236 | f,
237 | "usage: vkrunner [OPTION]… SCRIPT…\n\
238 | Runs the shader test script SCRIPT\n\
239 | \n\
240 | Options:"
241 | )?;
242 |
243 | let longest_long = OPTIONS
244 | .iter()
245 | .map(|o| o.long.chars().count())
246 | .max()
247 | .unwrap();
248 | let longest_arg = OPTIONS
249 | .iter()
250 | .map(|o| o.argument_name.map(|n| n.chars().count()).unwrap_or(0))
251 | .max()
252 | .unwrap();
253 |
254 | for (i, option) in OPTIONS.iter().enumerate() {
255 | if i > 0 {
256 | writeln!(f)?;
257 | }
258 |
259 | write!(f, " ")?;
260 |
261 | match option.short {
262 | Some(c) => write!(f, "-{},", c)?,
263 | None => write!(f, " ")?,
264 | }
265 |
266 | write!(
267 | f,
268 | "--{:long_width$} {:arg_width$} {}",
269 | option.long,
270 | option.argument_name.unwrap_or(""),
271 | option.help,
272 | long_width = longest_long,
273 | arg_width = longest_arg,
274 | )?;
275 | }
276 |
277 | Ok(())
278 | }
279 |
280 | fn next_arg<I>(
281 | opt: &'static Opt,
282 | args: &mut I,
283 | opt_arg: Option<&str>
284 | ) -> Result<OsString, OptError>
285 | where I: Iterator<Item = OsString>
286 | {
287 | // Use opt_arg if it’s available or else get the next arg from the iterator
288 | opt_arg
289 | .map(|arg| arg.into())
290 | .or_else(|| args.next())
291 | .ok_or_else(|| OptError::MissingArgument(opt))
292 | }
293 |
294 | fn process_argument<I>(
295 | values: &mut OptValues,
296 | args: &mut I,
297 | opt: &'static Opt,
298 | opt_arg: Option<&str>,
299 | ) -> Result<(), OptError>
300 | where I: Iterator<Item = OsString>
301 | {
302 | match opt.argument_type {
303 | ArgumentType::Flag => {
304 | if opt_arg.is_some() {
305 | return Err(OptError::ArgumentForFlag(opt));
306 | }
307 |
308 | values.insert(opt.long, ArgumentValue::Flag);
309 | },
310 | ArgumentType::Filename => {
311 | values.insert(
312 | opt.long,
313 | ArgumentValue::Filename(next_arg(opt, args, opt_arg)?),
314 | );
315 | },
316 | ArgumentType::StringArray => {
317 | let arg = next_arg(opt, args, opt_arg)?;
318 |
319 | match arg.to_str() {
320 | Some(s) => {
321 | values.entry(opt.long)
322 | .and_modify(|value| match value {
323 | ArgumentValue::StringArray(values) =>
324 | values.push(s.to_string()),
325 | _ => unreachable!(),
326 | })
327 | .or_insert_with(|| ArgumentValue::StringArray(
328 | vec![s.to_string()]
329 | ));
330 | },
331 | None => return Err(OptError::InvalidUtf8(opt)),
332 | }
333 | },
334 | ArgumentType::Integer => {
335 | let arg = next_arg(opt, args, opt_arg)?;
336 |
337 | match arg.to_str() {
338 | Some(s) => match s.parse::<u32>() {
339 | Ok(value) => {
340 | values.insert(
341 | opt.long,
342 | ArgumentValue::Integer(value),
343 | );
344 | },
345 | Err(_) => {
346 | return Err(OptError::InvalidInteger(
347 | s.to_owned()
348 | ));
349 | },
350 | },
351 | None => return Err(OptError::InvalidUtf8(opt)),
352 | }
353 | },
354 | }
355 |
356 | Ok(())
357 | }
358 |
359 | fn process_long_arg<I>(
360 | values: &mut OptValues,
361 | args: &mut I,
362 | arg: &str
363 | ) -> Result<(), OptError>
364 | where I: Iterator<Item = OsString>
365 | {
366 | let (arg, opt_arg) = match arg.split_once('=') {
367 | Some((arg, opt_arg)) => (arg, Some(opt_arg)),
368 | None => (arg, None),
369 | };
370 |
371 | for opt in OPTIONS.iter() {
372 | if opt.long.eq(arg) {
373 | return process_argument(values, args, opt, opt_arg);
374 | }
375 | }
376 |
377 | Err(OptError::UnknownOption(format!("--{}", arg)))
378 | }
379 |
380 | fn process_short_args<I>(
381 | values: &mut OptValues,
382 | args: &mut I,
383 | arg: &str
384 | ) -> Result<(), OptError>
385 | where I: Iterator<Item = OsString>
386 | {
387 | if arg.len() == 0 {
388 | return Err(OptError::UnknownOption("-".to_string()));
389 | }
390 |
391 | 'arg_loop: for ch in arg.chars() {
392 | for opt in OPTIONS.iter() {
393 | if let Some(opt_ch) = opt.short {
394 | if opt_ch == ch {
395 | process_argument(values, args, opt, None)?;
396 | continue 'arg_loop;
397 | }
398 | }
399 | }
400 |
401 | return Err(OptError::UnknownOption(format!("{}", ch)));
402 | }
403 |
404 | Ok(())
405 | }
406 |
407 | fn parse_options<I>(
408 | mut args: I
409 | ) -> Result<Options, OptError>
410 | where I: Iterator<Item = OsString>
411 | {
412 | let mut values = HashMap::new();
413 | let mut scripts = Vec::new();
414 |
415 | // Skip the first arg
416 | if args.next().is_none() {
417 | return Ok(Options { values, scripts });
418 | }
419 |
420 | while let Some(arg) = args.next() {
421 | match arg.to_str() {
422 | Some(arg_str) => {
423 | if arg_str == "--" {
424 | scripts.extend(args);
425 | break;
426 | } else if arg_str.starts_with("--") {
427 | process_long_arg(&mut values, &mut args, &arg_str[2..])?;
428 | } else if arg_str.starts_with("-") {
429 | process_short_args(&mut values, &mut args, &arg_str[1..])?;
430 | } else {
431 | scripts.push(arg);
432 | }
433 | },
434 | None => scripts.push(arg),
435 | }
436 | }
437 |
438 | Ok(Options { values, scripts })
439 | }
440 |
441 | impl<'a> InspectData<'a> {
442 | fn new(options: &'a Options) -> InspectData<'a> {
443 | InspectData {
444 | image_filename: match options.values.get(IMAGE_OPTION) {
445 | Some(ArgumentValue::Filename(filename)) => {
446 | Some(filename)
447 | },
448 | _ => None,
449 | },
450 | buffer_filename: match options.values.get(BUFFER_OPTION) {
451 | Some(ArgumentValue::Filename(filename)) => {
452 | Some(filename)
453 | },
454 | _ => None,
455 | },
456 | buffer_binding: match options.values.get(BINDING_OPTION) {
457 | Some(&ArgumentValue::Integer(binding)) => {
458 | Some(binding)
459 | },
460 | _ => None,
461 | },
462 | failed: false,
463 | }
464 | }
465 | }
466 |
467 | fn get_token_replacements<'a>(
468 | values: &'a OptValues
469 | ) -> Result<Vec<TokenReplacement<'a>>, Error> {
470 | let mut res = Vec::new();
471 |
472 | if let Some(ArgumentValue::StringArray(replacements)) =
473 | values.get(REPLACE_OPTION)
474 | {
475 | for replacement in replacements {
476 | match replacement.split_once('=') {
477 | None => {
478 | return Err(Error::InvalidTokenReplacement(
479 | replacement.to_owned()
480 | ));
481 | },
482 | Some((token, replacement)) => res.push(TokenReplacement {
483 | token,
484 | replacement,
485 | }),
486 | }
487 | }
488 | }
489 |
490 | Ok(res)
491 | }
492 |
493 | struct InspectData<'a> {
494 | image_filename: Option<&'a OsStr>,
495 | buffer_filename: Option<&'a OsStr>,
496 | buffer_binding: Option<u32>,
497 | failed: bool,
498 | }
499 |
500 | fn write_ppm(
501 | image: &inspect::Image,
502 | filename: &OsStr,
503 | ) -> Result<(), Error> {
504 | let mut file = BufWriter::new(File::create(filename)?);
505 |
506 | use std::io::Write;
507 |
508 | write!(
509 | &mut file,
510 | "P6\n\
511 | {} {}\n\
512 | 255\n",
513 | image.width,
514 | image.height,
515 | )?;
516 |
517 | let format_size = image.format.size();
518 |
519 | for y in 0..image.height {
520 | let mut line = unsafe {
521 | std::slice::from_raw_parts(
522 | (image.data as *const u8).add(y as usize * image.stride),
523 | image.width as usize * format_size,
524 | )
525 | };
526 |
527 | for _ in 0..image.width {
528 | let pixel = image.format.load_pixel(&line[0..format_size]);
529 | let mut bytes = [0u8; 3];
530 |
531 | for (i, component) in pixel[0..3].iter().enumerate() {
532 | bytes[i] = (component.clamp(0.0, 1.0) * 255.0).round() as u8;
533 | }
534 |
535 | file.write_all(&bytes)?;
536 |
537 | line = &line[format_size..];
538 | }
539 | }
540 |
541 | Ok(())
542 | }
543 |
544 | fn write_buffer(
545 | data: &inspect::Data,
546 | filename: &OsStr,
547 | binding: Option<u32>,
548 | ) -> Result<(), Error> {
549 | let buffers = unsafe {
550 | std::slice::from_raw_parts(data.buffers, data.n_buffers)
551 | };
552 |
553 | let buffer = match binding {
554 | None => match buffers.get(0) {
555 | Some(buffer) => buffer,
556 | None => return Err(Error::NoBuffers),
557 | },
558 | Some(binding) => match buffers.iter().find(
559 | |b| b.binding as u32 == binding
560 | ) {
561 | Some(buffer) => buffer,
562 | None => return Err(Error::BufferNotFound(binding)),
563 | },
564 | };
565 |
566 | let mut file = File::create(filename)?;
567 |
568 | let data = unsafe {
569 | std::slice::from_raw_parts(
570 | buffer.data as *const u8,
571 | buffer.size,
572 | )
573 | };
574 |
575 | use std::io::Write;
576 |
577 | file.write_all(data)?;
578 |
579 | Ok(())
580 | }
581 |
582 | extern "C" fn inspect_cb(data: &inspect::Data, user_data: *mut c_void) {
583 | let inspect_data = unsafe { &mut *(user_data as *mut InspectData) };
584 |
585 | if let Some(filename) = inspect_data.image_filename {
586 | match write_ppm(&data.color_buffer, filename) {
587 | Err(e) => {
588 | eprintln!("{}", e);
589 | inspect_data.failed = true;
590 | },
591 | Ok(()) => (),
592 | }
593 | }
594 |
595 | if let Some(filename) = inspect_data.buffer_filename {
596 | match write_buffer(&data, filename, inspect_data.buffer_binding) {
597 | Err(e) => {
598 | eprintln!("{}", e);
599 | inspect_data.failed = true;
600 | },
601 | Ok(()) => (),
602 | }
603 | }
604 | }
605 |
606 | fn set_up_config(
607 | config: &Rc<RefCell<Config>>,
608 | options: &Options,
609 | inspect_data: &mut InspectData,
610 | ) -> Result<(), Error> {
611 | let mut config = config.borrow_mut();
612 |
613 | config.set_inspect_cb(Some(inspect_cb));
614 | config.set_user_data(ptr::addr_of_mut!(*inspect_data).cast());
615 |
616 | if let Some(&ArgumentValue::Integer(device_id))
617 | = options.values.get(DEVICE_ID_OPTION)
618 | {
619 | match device_id.checked_sub(1) {
620 | None => return Err(Error::ZeroDeviceId),
621 | Some(device_id) => config.set_device_id(Some(device_id as usize)),
622 | }
623 | }
624 |
625 | if let Some(ArgumentValue::Flag) = options.values.get(DISASM_OPTION) {
626 | config.set_show_disassembly(true);
627 | }
628 |
629 | Ok(())
630 | }
631 |
632 | fn format_result(result: result::Result) -> String {
633 | format!("PIGLIT: {{\"result\": \"{}\" }}", result.name())
634 | }
635 |
636 | fn add_token_replacements(
637 | token_replacements: &[TokenReplacement<'_>],
638 | source: &mut Source,
639 | ) {
640 | for token_replacement in token_replacements.iter() {
641 | source.add_token_replacement(
642 | token_replacement.token.to_owned(),
643 | token_replacement.replacement.to_owned(),
644 | );
645 | }
646 | }
647 |
648 | fn run() -> Result<(), Error> {
649 | let options = parse_options(std::env::args_os())?;
650 |
651 | if options.values.contains_key(HELP_OPTION) || options.scripts.is_empty() {
652 | return Err(Error::ShowHelp);
653 | }
654 |
655 | let config = Rc::new(RefCell::new(Config::new()));
656 |
657 | let mut inspect_data = InspectData::new(&options);
658 |
659 | set_up_config(&config, &options, &mut inspect_data)?;
660 |
661 | let token_replacements = get_token_replacements(&options.values)?;
662 |
663 | let mut executor = Executor::new(Rc::clone(&config));
664 |
665 | let mut overall_result = result::Result::Skip;
666 |
667 | for script_filename in options.scripts.iter() {
668 | if options.scripts.len() > 1
669 | && !options.values.contains_key(QUIET_OPTION)
670 | {
671 | println!("{}", script_filename.to_string_lossy());
672 | }
673 |
674 | let mut source = Source::from_file(script_filename.into());
675 |
676 | add_token_replacements(&token_replacements, &mut source);
677 |
678 | let result = executor.execute(&source);
679 |
680 | overall_result = overall_result.merge(result);
681 | }
682 |
683 | if inspect_data.failed {
684 | overall_result = overall_result.merge(result::Result::Fail);
685 | }
686 |
687 | match overall_result {
688 | result::Result::Fail => Err(Error::TestFailed),
689 | result::Result::Pass if options.values.contains_key(QUIET_OPTION) => {
690 | Ok(())
691 | },
692 | _ => {
693 | println!("{}", format_result(overall_result));
694 | Ok(())
695 | },
696 | }
697 | }
698 |
699 | fn main() -> ExitCode {
700 | match run() {
701 | Ok(()) => ExitCode::SUCCESS,
702 | Err(e) => {
703 | eprintln!("{}", e);
704 | ExitCode::FAILURE
705 | },
706 | }
707 | }
708 |
709 | #[cfg(test)]
710 | mod test {
711 | use super::*;
712 |
713 | #[test]
714 | fn all_arg_types() {
715 | let args: Vec<OsString> = vec![
716 | "vkrunner".into(),
717 | "-dB".into(), "12".into(),
718 | "--image".into(), "screenshot.png".into(),
719 | "--replace".into(), "bad=aĉa".into(),
720 | "--replace=good=bona".into(),
721 | "script.shader_test".into(),
722 | ];
723 |
724 | let options = parse_options(args.into_iter()).unwrap();
725 |
726 | assert!(matches!(&options.values[DISASM_OPTION], ArgumentValue::Flag));
727 |
728 | let ArgumentValue::Integer(binding) = &options.values[BINDING_OPTION]
729 | else { unreachable!(); };
730 | assert_eq!(*binding, 12);
731 |
732 | let ArgumentValue::Filename(image) = &options.values[IMAGE_OPTION]
733 | else { unreachable!(); };
734 | assert_eq!(image.to_str().unwrap(), "screenshot.png");
735 |
736 | let ArgumentValue::StringArray(values) = &options.values[REPLACE_OPTION]
737 | else { unreachable!(); };
738 | assert_eq!(
739 | values,
740 | &vec!["bad=aĉa".to_string(), "good=bona".to_string()]
741 | );
742 |
743 | assert_eq!(options.scripts.len(), 1);
744 | assert_eq!(options.scripts[0].to_str().unwrap(), "script.shader_test");
745 | }
746 |
747 | #[test]
748 | fn multi_arguments() {
749 | let args = vec![
750 | "vkrunner".into(),
751 | "-ib".into(), "image.png".into(), "buffer.raw".into(),
752 | ];
753 |
754 | let options = parse_options(args.into_iter()).unwrap();
755 |
756 | let ArgumentValue::Filename(image) = &options.values[IMAGE_OPTION]
757 | else { unreachable!(); };
758 | assert_eq!(image.to_str().unwrap(), "image.png");
759 |
760 | let ArgumentValue::Filename(image) = &options.values[BUFFER_OPTION]
761 | else { unreachable!(); };
762 | assert_eq!(image.to_str().unwrap(), "buffer.raw");
763 | }
764 |
765 | #[test]
766 | fn unknown_option() {
767 | let args = vec!["vkrunner".into(), "--bad-option".into()].into_iter();
768 | let error = parse_options(args).unwrap_err();
769 | assert_eq!(&error.to_string(), "Unknown option: --bad-option");
770 |
771 | let args = vec!["vkrunner".into(), "-d?".into()].into_iter();
772 | let error = parse_options(args).unwrap_err();
773 | assert_eq!(&error.to_string(), "Unknown option: ?");
774 |
775 | let args = vec!["vkrunner".into(), "-".into()].into_iter();
776 | let error = parse_options(args).unwrap_err();
777 | assert_eq!(&error.to_string(), "Unknown option: -");
778 | }
779 |
780 | #[test]
781 | fn trailing_arguments() {
782 | let args = vec![
783 | "vkrunner".into(),
784 | "-i".into(), "image.png".into(),
785 | "--".into(),
786 | "-i.shader_test".into(),
787 | ];
788 |
789 | let options = parse_options(args.into_iter()).unwrap();
790 |
791 | assert_eq!(options.scripts.len(), 1);
792 | assert_eq!(options.scripts[0].to_str().unwrap(), "-i.shader_test");
793 | }
794 |
795 | #[test]
796 | fn missing_argument() {
797 | let args = vec!["vkrunner".into(), "--buffer".into()].into_iter();
798 | let error = parse_options(args).unwrap_err();
799 | assert_eq!(&error.to_string(), "Option --buffer requires an argument");
800 |
801 | let args = vec!["vkrunner".into(), "-D".into()].into_iter();
802 | let error = parse_options(args).unwrap_err();
803 | assert_eq!(&error.to_string(), "Option --replace requires an argument");
804 |
805 | let args = vec!["vkrunner".into(), "-B".into()].into_iter();
806 | let error = parse_options(args).unwrap_err();
807 | assert_eq!(&error.to_string(), "Option --binding requires an argument");
808 | }
809 |
810 | #[test]
811 | #[cfg(unix)]
812 | fn invalid_utf8() {
813 | use std::os::unix::ffi::OsStrExt;
814 | use std::ffi::OsStr;
815 |
816 | let args = vec![
817 | "vkrunner".into(),
818 | "-D".into(),
819 | OsStr::from_bytes(b"buffer-\x80.raw").into(),
820 | ].into_iter();
821 |
822 | let error = parse_options(args).unwrap_err();
823 | assert_eq!(
824 | &error.to_string(),
825 | "Invalid UTF-8 in argument to --replace",
826 | );
827 |
828 | let args = vec![
829 | "vkrunner".into(),
830 | "-B".into(),
831 | OsStr::from_bytes(b"TWELVE-\x80").into(),
832 | ].into_iter();
833 |
834 | let error = parse_options(args).unwrap_err();
835 | assert_eq!(
836 | &error.to_string(),
837 | "Invalid UTF-8 in argument to --binding",
838 | );
839 | }
840 |
841 | #[test]
842 | fn invalid_integer() {
843 | let args = vec![
844 | "vkrunner".into(),
845 | "-B".into(), "twelve".into(),
846 | ].into_iter();
847 |
848 | let error = parse_options(args).unwrap_err();
849 | assert_eq!(
850 | &error.to_string(),
851 | "Invalid integer: twelve",
852 | );
853 | }
854 |
855 | #[test]
856 | fn argument_for_flag() {
857 | let args = vec!["vkrunner".into(), "--quiet=yes".into()].into_iter();
858 | let error = parse_options(args).unwrap_err();
859 | assert_eq!(
860 | &error.to_string(),
861 | "Option --quiet is a flag and can not take an argument",
862 | );
863 | }
864 | }
865 |
```
--------------------------------------------------------------------------------
/vkrunner/vkrunner/vulkan_funcs_data.rs:
--------------------------------------------------------------------------------
```rust
1 | // Automatically generated by make-vulkan-funcs-data.py
2 |
3 | #[derive(Debug, Clone)]
4 | #[allow(non_snake_case)]
5 | pub struct Library {
6 | lib_vulkan: *const c_void,
7 | lib_vulkan_is_fake: bool,
8 |
9 | pub vkGetInstanceProcAddr: vk::PFN_vkGetInstanceProcAddr,
10 | pub vkCreateInstance: vk::PFN_vkCreateInstance,
11 | pub vkEnumerateInstanceExtensionProperties: vk::PFN_vkEnumerateInstanceExtensionProperties,
12 | }
13 |
14 | #[derive(Debug, Clone)]
15 | #[allow(non_snake_case)]
16 | pub struct Instance {
17 | pub vkCreateDevice: vk::PFN_vkCreateDevice,
18 | pub vkDestroyInstance: vk::PFN_vkDestroyInstance,
19 | pub vkEnumerateDeviceExtensionProperties: vk::PFN_vkEnumerateDeviceExtensionProperties,
20 | pub vkEnumeratePhysicalDevices: vk::PFN_vkEnumeratePhysicalDevices,
21 | pub vkGetDeviceProcAddr: vk::PFN_vkGetDeviceProcAddr,
22 | pub vkGetPhysicalDeviceFeatures: vk::PFN_vkGetPhysicalDeviceFeatures,
23 | pub vkGetPhysicalDeviceFeatures2KHR: vk::PFN_vkGetPhysicalDeviceFeatures2KHR,
24 | pub vkGetPhysicalDeviceFormatProperties: vk::PFN_vkGetPhysicalDeviceFormatProperties,
25 | pub vkGetPhysicalDeviceMemoryProperties: vk::PFN_vkGetPhysicalDeviceMemoryProperties,
26 | pub vkGetPhysicalDeviceProperties: vk::PFN_vkGetPhysicalDeviceProperties,
27 | pub vkGetPhysicalDeviceProperties2: vk::PFN_vkGetPhysicalDeviceProperties2,
28 | pub vkGetPhysicalDeviceQueueFamilyProperties: vk::PFN_vkGetPhysicalDeviceQueueFamilyProperties,
29 | pub vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR: vk::PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR,
30 | }
31 |
32 | #[derive(Debug, Clone)]
33 | #[allow(non_snake_case)]
34 | #[allow(dead_code)]
35 | pub struct Device {
36 | pub vkAllocateCommandBuffers: vk::PFN_vkAllocateCommandBuffers,
37 | pub vkAllocateDescriptorSets: vk::PFN_vkAllocateDescriptorSets,
38 | pub vkAllocateMemory: vk::PFN_vkAllocateMemory,
39 | pub vkBeginCommandBuffer: vk::PFN_vkBeginCommandBuffer,
40 | pub vkBindBufferMemory: vk::PFN_vkBindBufferMemory,
41 | pub vkBindImageMemory: vk::PFN_vkBindImageMemory,
42 | pub vkCmdBeginRenderPass: vk::PFN_vkCmdBeginRenderPass,
43 | pub vkCmdBindDescriptorSets: vk::PFN_vkCmdBindDescriptorSets,
44 | pub vkCmdBindIndexBuffer: vk::PFN_vkCmdBindIndexBuffer,
45 | pub vkCmdBindPipeline: vk::PFN_vkCmdBindPipeline,
46 | pub vkCmdBindVertexBuffers: vk::PFN_vkCmdBindVertexBuffers,
47 | pub vkCmdClearAttachments: vk::PFN_vkCmdClearAttachments,
48 | pub vkCmdCopyBufferToImage: vk::PFN_vkCmdCopyBufferToImage,
49 | pub vkCmdCopyImageToBuffer: vk::PFN_vkCmdCopyImageToBuffer,
50 | pub vkCmdDispatch: vk::PFN_vkCmdDispatch,
51 | pub vkCmdDraw: vk::PFN_vkCmdDraw,
52 | pub vkCmdDrawIndexed: vk::PFN_vkCmdDrawIndexed,
53 | pub vkCmdDrawIndexedIndirect: vk::PFN_vkCmdDrawIndexedIndirect,
54 | pub vkCmdEndRenderPass: vk::PFN_vkCmdEndRenderPass,
55 | pub vkCmdPipelineBarrier: vk::PFN_vkCmdPipelineBarrier,
56 | pub vkCmdPushConstants: vk::PFN_vkCmdPushConstants,
57 | pub vkCmdSetScissor: vk::PFN_vkCmdSetScissor,
58 | pub vkCmdSetViewport: vk::PFN_vkCmdSetViewport,
59 | pub vkCreateBuffer: vk::PFN_vkCreateBuffer,
60 | pub vkCreateCommandPool: vk::PFN_vkCreateCommandPool,
61 | pub vkCreateComputePipelines: vk::PFN_vkCreateComputePipelines,
62 | pub vkCreateDescriptorPool: vk::PFN_vkCreateDescriptorPool,
63 | pub vkCreateDescriptorSetLayout: vk::PFN_vkCreateDescriptorSetLayout,
64 | pub vkCreateFence: vk::PFN_vkCreateFence,
65 | pub vkCreateFramebuffer: vk::PFN_vkCreateFramebuffer,
66 | pub vkCreateGraphicsPipelines: vk::PFN_vkCreateGraphicsPipelines,
67 | pub vkCreateImage: vk::PFN_vkCreateImage,
68 | pub vkCreateImageView: vk::PFN_vkCreateImageView,
69 | pub vkCreatePipelineCache: vk::PFN_vkCreatePipelineCache,
70 | pub vkCreatePipelineLayout: vk::PFN_vkCreatePipelineLayout,
71 | pub vkCreateRenderPass: vk::PFN_vkCreateRenderPass,
72 | pub vkCreateSampler: vk::PFN_vkCreateSampler,
73 | pub vkCreateSemaphore: vk::PFN_vkCreateSemaphore,
74 | pub vkCreateShaderModule: vk::PFN_vkCreateShaderModule,
75 | pub vkDestroyBuffer: vk::PFN_vkDestroyBuffer,
76 | pub vkDestroyCommandPool: vk::PFN_vkDestroyCommandPool,
77 | pub vkDestroyDescriptorPool: vk::PFN_vkDestroyDescriptorPool,
78 | pub vkDestroyDescriptorSetLayout: vk::PFN_vkDestroyDescriptorSetLayout,
79 | pub vkDestroyDevice: vk::PFN_vkDestroyDevice,
80 | pub vkDestroyFence: vk::PFN_vkDestroyFence,
81 | pub vkDestroyFramebuffer: vk::PFN_vkDestroyFramebuffer,
82 | pub vkDestroyImage: vk::PFN_vkDestroyImage,
83 | pub vkDestroyImageView: vk::PFN_vkDestroyImageView,
84 | pub vkDestroyPipeline: vk::PFN_vkDestroyPipeline,
85 | pub vkDestroyPipelineCache: vk::PFN_vkDestroyPipelineCache,
86 | pub vkDestroyPipelineLayout: vk::PFN_vkDestroyPipelineLayout,
87 | pub vkDestroyRenderPass: vk::PFN_vkDestroyRenderPass,
88 | pub vkDestroySampler: vk::PFN_vkDestroySampler,
89 | pub vkDestroySemaphore: vk::PFN_vkDestroySemaphore,
90 | pub vkDestroyShaderModule: vk::PFN_vkDestroyShaderModule,
91 | pub vkEndCommandBuffer: vk::PFN_vkEndCommandBuffer,
92 | pub vkFlushMappedMemoryRanges: vk::PFN_vkFlushMappedMemoryRanges,
93 | pub vkFreeCommandBuffers: vk::PFN_vkFreeCommandBuffers,
94 | pub vkFreeDescriptorSets: vk::PFN_vkFreeDescriptorSets,
95 | pub vkFreeMemory: vk::PFN_vkFreeMemory,
96 | pub vkGetBufferMemoryRequirements: vk::PFN_vkGetBufferMemoryRequirements,
97 | pub vkGetDeviceQueue: vk::PFN_vkGetDeviceQueue,
98 | pub vkGetImageMemoryRequirements: vk::PFN_vkGetImageMemoryRequirements,
99 | pub vkGetImageSubresourceLayout: vk::PFN_vkGetImageSubresourceLayout,
100 | pub vkInvalidateMappedMemoryRanges: vk::PFN_vkInvalidateMappedMemoryRanges,
101 | pub vkMapMemory: vk::PFN_vkMapMemory,
102 | pub vkQueueSubmit: vk::PFN_vkQueueSubmit,
103 | pub vkQueueWaitIdle: vk::PFN_vkQueueWaitIdle,
104 | pub vkResetFences: vk::PFN_vkResetFences,
105 | pub vkUnmapMemory: vk::PFN_vkUnmapMemory,
106 | pub vkUpdateDescriptorSets: vk::PFN_vkUpdateDescriptorSets,
107 | pub vkWaitForFences: vk::PFN_vkWaitForFences,
108 | }
109 |
110 | impl Instance {
111 | pub unsafe fn new(
112 | get_instance_proc_cb: GetInstanceProcFunc,
113 | user_data: *const c_void,
114 | ) -> Instance {
115 | Instance {
116 | vkCreateDevice: std::mem::transmute(get_instance_proc_cb(
117 | "vkCreateDevice\0".as_ptr().cast(),
118 | user_data,
119 | )),
120 | vkDestroyInstance: std::mem::transmute(get_instance_proc_cb(
121 | "vkDestroyInstance\0".as_ptr().cast(),
122 | user_data,
123 | )),
124 | vkEnumerateDeviceExtensionProperties: std::mem::transmute(get_instance_proc_cb(
125 | "vkEnumerateDeviceExtensionProperties\0".as_ptr().cast(),
126 | user_data,
127 | )),
128 | vkEnumeratePhysicalDevices: std::mem::transmute(get_instance_proc_cb(
129 | "vkEnumeratePhysicalDevices\0".as_ptr().cast(),
130 | user_data,
131 | )),
132 | vkGetDeviceProcAddr: std::mem::transmute(get_instance_proc_cb(
133 | "vkGetDeviceProcAddr\0".as_ptr().cast(),
134 | user_data,
135 | )),
136 | vkGetPhysicalDeviceFeatures: std::mem::transmute(get_instance_proc_cb(
137 | "vkGetPhysicalDeviceFeatures\0".as_ptr().cast(),
138 | user_data,
139 | )),
140 | vkGetPhysicalDeviceFeatures2KHR: std::mem::transmute(get_instance_proc_cb(
141 | "vkGetPhysicalDeviceFeatures2KHR\0".as_ptr().cast(),
142 | user_data,
143 | )),
144 | vkGetPhysicalDeviceFormatProperties: std::mem::transmute(get_instance_proc_cb(
145 | "vkGetPhysicalDeviceFormatProperties\0".as_ptr().cast(),
146 | user_data,
147 | )),
148 | vkGetPhysicalDeviceMemoryProperties: std::mem::transmute(get_instance_proc_cb(
149 | "vkGetPhysicalDeviceMemoryProperties\0".as_ptr().cast(),
150 | user_data,
151 | )),
152 | vkGetPhysicalDeviceProperties: std::mem::transmute(get_instance_proc_cb(
153 | "vkGetPhysicalDeviceProperties\0".as_ptr().cast(),
154 | user_data,
155 | )),
156 | vkGetPhysicalDeviceProperties2: std::mem::transmute(get_instance_proc_cb(
157 | "vkGetPhysicalDeviceProperties2\0".as_ptr().cast(),
158 | user_data,
159 | )),
160 | vkGetPhysicalDeviceQueueFamilyProperties: std::mem::transmute(get_instance_proc_cb(
161 | "vkGetPhysicalDeviceQueueFamilyProperties\0".as_ptr().cast(),
162 | user_data,
163 | )),
164 | vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR: std::mem::transmute(get_instance_proc_cb(
165 | "vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR\0".as_ptr().cast(),
166 | user_data,
167 | )),
168 | }
169 | }
170 | }
171 |
172 | #[allow(dead_code)]
173 | impl Device {
174 | pub fn new(instance: &Instance, device: vk::VkDevice) -> Device {
175 | Device {
176 | vkAllocateCommandBuffers: unsafe {
177 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
178 | device,
179 | "vkAllocateCommandBuffers\0".as_ptr().cast(),
180 | ))
181 | },
182 | vkAllocateDescriptorSets: unsafe {
183 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
184 | device,
185 | "vkAllocateDescriptorSets\0".as_ptr().cast(),
186 | ))
187 | },
188 | vkAllocateMemory: unsafe {
189 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
190 | device,
191 | "vkAllocateMemory\0".as_ptr().cast(),
192 | ))
193 | },
194 | vkBeginCommandBuffer: unsafe {
195 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
196 | device,
197 | "vkBeginCommandBuffer\0".as_ptr().cast(),
198 | ))
199 | },
200 | vkBindBufferMemory: unsafe {
201 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
202 | device,
203 | "vkBindBufferMemory\0".as_ptr().cast(),
204 | ))
205 | },
206 | vkBindImageMemory: unsafe {
207 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
208 | device,
209 | "vkBindImageMemory\0".as_ptr().cast(),
210 | ))
211 | },
212 | vkCmdBeginRenderPass: unsafe {
213 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
214 | device,
215 | "vkCmdBeginRenderPass\0".as_ptr().cast(),
216 | ))
217 | },
218 | vkCmdBindDescriptorSets: unsafe {
219 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
220 | device,
221 | "vkCmdBindDescriptorSets\0".as_ptr().cast(),
222 | ))
223 | },
224 | vkCmdBindIndexBuffer: unsafe {
225 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
226 | device,
227 | "vkCmdBindIndexBuffer\0".as_ptr().cast(),
228 | ))
229 | },
230 | vkCmdBindPipeline: unsafe {
231 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
232 | device,
233 | "vkCmdBindPipeline\0".as_ptr().cast(),
234 | ))
235 | },
236 | vkCmdBindVertexBuffers: unsafe {
237 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
238 | device,
239 | "vkCmdBindVertexBuffers\0".as_ptr().cast(),
240 | ))
241 | },
242 | vkCmdClearAttachments: unsafe {
243 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
244 | device,
245 | "vkCmdClearAttachments\0".as_ptr().cast(),
246 | ))
247 | },
248 | vkCmdCopyBufferToImage: unsafe {
249 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
250 | device,
251 | "vkCmdCopyBufferToImage\0".as_ptr().cast(),
252 | ))
253 | },
254 | vkCmdCopyImageToBuffer: unsafe {
255 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
256 | device,
257 | "vkCmdCopyImageToBuffer\0".as_ptr().cast(),
258 | ))
259 | },
260 | vkCmdDispatch: unsafe {
261 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
262 | device,
263 | "vkCmdDispatch\0".as_ptr().cast(),
264 | ))
265 | },
266 | vkCmdDraw: unsafe {
267 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
268 | device,
269 | "vkCmdDraw\0".as_ptr().cast(),
270 | ))
271 | },
272 | vkCmdDrawIndexed: unsafe {
273 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
274 | device,
275 | "vkCmdDrawIndexed\0".as_ptr().cast(),
276 | ))
277 | },
278 | vkCmdDrawIndexedIndirect: unsafe {
279 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
280 | device,
281 | "vkCmdDrawIndexedIndirect\0".as_ptr().cast(),
282 | ))
283 | },
284 | vkCmdEndRenderPass: unsafe {
285 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
286 | device,
287 | "vkCmdEndRenderPass\0".as_ptr().cast(),
288 | ))
289 | },
290 | vkCmdPipelineBarrier: unsafe {
291 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
292 | device,
293 | "vkCmdPipelineBarrier\0".as_ptr().cast(),
294 | ))
295 | },
296 | vkCmdPushConstants: unsafe {
297 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
298 | device,
299 | "vkCmdPushConstants\0".as_ptr().cast(),
300 | ))
301 | },
302 | vkCmdSetScissor: unsafe {
303 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
304 | device,
305 | "vkCmdSetScissor\0".as_ptr().cast(),
306 | ))
307 | },
308 | vkCmdSetViewport: unsafe {
309 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
310 | device,
311 | "vkCmdSetViewport\0".as_ptr().cast(),
312 | ))
313 | },
314 | vkCreateBuffer: unsafe {
315 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
316 | device,
317 | "vkCreateBuffer\0".as_ptr().cast(),
318 | ))
319 | },
320 | vkCreateCommandPool: unsafe {
321 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
322 | device,
323 | "vkCreateCommandPool\0".as_ptr().cast(),
324 | ))
325 | },
326 | vkCreateComputePipelines: unsafe {
327 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
328 | device,
329 | "vkCreateComputePipelines\0".as_ptr().cast(),
330 | ))
331 | },
332 | vkCreateDescriptorPool: unsafe {
333 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
334 | device,
335 | "vkCreateDescriptorPool\0".as_ptr().cast(),
336 | ))
337 | },
338 | vkCreateDescriptorSetLayout: unsafe {
339 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
340 | device,
341 | "vkCreateDescriptorSetLayout\0".as_ptr().cast(),
342 | ))
343 | },
344 | vkCreateFence: unsafe {
345 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
346 | device,
347 | "vkCreateFence\0".as_ptr().cast(),
348 | ))
349 | },
350 | vkCreateFramebuffer: unsafe {
351 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
352 | device,
353 | "vkCreateFramebuffer\0".as_ptr().cast(),
354 | ))
355 | },
356 | vkCreateGraphicsPipelines: unsafe {
357 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
358 | device,
359 | "vkCreateGraphicsPipelines\0".as_ptr().cast(),
360 | ))
361 | },
362 | vkCreateImage: unsafe {
363 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
364 | device,
365 | "vkCreateImage\0".as_ptr().cast(),
366 | ))
367 | },
368 | vkCreateImageView: unsafe {
369 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
370 | device,
371 | "vkCreateImageView\0".as_ptr().cast(),
372 | ))
373 | },
374 | vkCreatePipelineCache: unsafe {
375 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
376 | device,
377 | "vkCreatePipelineCache\0".as_ptr().cast(),
378 | ))
379 | },
380 | vkCreatePipelineLayout: unsafe {
381 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
382 | device,
383 | "vkCreatePipelineLayout\0".as_ptr().cast(),
384 | ))
385 | },
386 | vkCreateRenderPass: unsafe {
387 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
388 | device,
389 | "vkCreateRenderPass\0".as_ptr().cast(),
390 | ))
391 | },
392 | vkCreateSampler: unsafe {
393 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
394 | device,
395 | "vkCreateSampler\0".as_ptr().cast(),
396 | ))
397 | },
398 | vkCreateSemaphore: unsafe {
399 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
400 | device,
401 | "vkCreateSemaphore\0".as_ptr().cast(),
402 | ))
403 | },
404 | vkCreateShaderModule: unsafe {
405 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
406 | device,
407 | "vkCreateShaderModule\0".as_ptr().cast(),
408 | ))
409 | },
410 | vkDestroyBuffer: unsafe {
411 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
412 | device,
413 | "vkDestroyBuffer\0".as_ptr().cast(),
414 | ))
415 | },
416 | vkDestroyCommandPool: unsafe {
417 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
418 | device,
419 | "vkDestroyCommandPool\0".as_ptr().cast(),
420 | ))
421 | },
422 | vkDestroyDescriptorPool: unsafe {
423 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
424 | device,
425 | "vkDestroyDescriptorPool\0".as_ptr().cast(),
426 | ))
427 | },
428 | vkDestroyDescriptorSetLayout: unsafe {
429 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
430 | device,
431 | "vkDestroyDescriptorSetLayout\0".as_ptr().cast(),
432 | ))
433 | },
434 | vkDestroyDevice: unsafe {
435 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
436 | device,
437 | "vkDestroyDevice\0".as_ptr().cast(),
438 | ))
439 | },
440 | vkDestroyFence: unsafe {
441 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
442 | device,
443 | "vkDestroyFence\0".as_ptr().cast(),
444 | ))
445 | },
446 | vkDestroyFramebuffer: unsafe {
447 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
448 | device,
449 | "vkDestroyFramebuffer\0".as_ptr().cast(),
450 | ))
451 | },
452 | vkDestroyImage: unsafe {
453 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
454 | device,
455 | "vkDestroyImage\0".as_ptr().cast(),
456 | ))
457 | },
458 | vkDestroyImageView: unsafe {
459 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
460 | device,
461 | "vkDestroyImageView\0".as_ptr().cast(),
462 | ))
463 | },
464 | vkDestroyPipeline: unsafe {
465 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
466 | device,
467 | "vkDestroyPipeline\0".as_ptr().cast(),
468 | ))
469 | },
470 | vkDestroyPipelineCache: unsafe {
471 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
472 | device,
473 | "vkDestroyPipelineCache\0".as_ptr().cast(),
474 | ))
475 | },
476 | vkDestroyPipelineLayout: unsafe {
477 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
478 | device,
479 | "vkDestroyPipelineLayout\0".as_ptr().cast(),
480 | ))
481 | },
482 | vkDestroyRenderPass: unsafe {
483 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
484 | device,
485 | "vkDestroyRenderPass\0".as_ptr().cast(),
486 | ))
487 | },
488 | vkDestroySampler: unsafe {
489 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
490 | device,
491 | "vkDestroySampler\0".as_ptr().cast(),
492 | ))
493 | },
494 | vkDestroySemaphore: unsafe {
495 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
496 | device,
497 | "vkDestroySemaphore\0".as_ptr().cast(),
498 | ))
499 | },
500 | vkDestroyShaderModule: unsafe {
501 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
502 | device,
503 | "vkDestroyShaderModule\0".as_ptr().cast(),
504 | ))
505 | },
506 | vkEndCommandBuffer: unsafe {
507 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
508 | device,
509 | "vkEndCommandBuffer\0".as_ptr().cast(),
510 | ))
511 | },
512 | vkFlushMappedMemoryRanges: unsafe {
513 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
514 | device,
515 | "vkFlushMappedMemoryRanges\0".as_ptr().cast(),
516 | ))
517 | },
518 | vkFreeCommandBuffers: unsafe {
519 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
520 | device,
521 | "vkFreeCommandBuffers\0".as_ptr().cast(),
522 | ))
523 | },
524 | vkFreeDescriptorSets: unsafe {
525 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
526 | device,
527 | "vkFreeDescriptorSets\0".as_ptr().cast(),
528 | ))
529 | },
530 | vkFreeMemory: unsafe {
531 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
532 | device,
533 | "vkFreeMemory\0".as_ptr().cast(),
534 | ))
535 | },
536 | vkGetBufferMemoryRequirements: unsafe {
537 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
538 | device,
539 | "vkGetBufferMemoryRequirements\0".as_ptr().cast(),
540 | ))
541 | },
542 | vkGetDeviceQueue: unsafe {
543 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
544 | device,
545 | "vkGetDeviceQueue\0".as_ptr().cast(),
546 | ))
547 | },
548 | vkGetImageMemoryRequirements: unsafe {
549 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
550 | device,
551 | "vkGetImageMemoryRequirements\0".as_ptr().cast(),
552 | ))
553 | },
554 | vkGetImageSubresourceLayout: unsafe {
555 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
556 | device,
557 | "vkGetImageSubresourceLayout\0".as_ptr().cast(),
558 | ))
559 | },
560 | vkInvalidateMappedMemoryRanges: unsafe {
561 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
562 | device,
563 | "vkInvalidateMappedMemoryRanges\0".as_ptr().cast(),
564 | ))
565 | },
566 | vkMapMemory: unsafe {
567 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
568 | device,
569 | "vkMapMemory\0".as_ptr().cast(),
570 | ))
571 | },
572 | vkQueueSubmit: unsafe {
573 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
574 | device,
575 | "vkQueueSubmit\0".as_ptr().cast(),
576 | ))
577 | },
578 | vkQueueWaitIdle: unsafe {
579 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
580 | device,
581 | "vkQueueWaitIdle\0".as_ptr().cast(),
582 | ))
583 | },
584 | vkResetFences: unsafe {
585 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
586 | device,
587 | "vkResetFences\0".as_ptr().cast(),
588 | ))
589 | },
590 | vkUnmapMemory: unsafe {
591 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
592 | device,
593 | "vkUnmapMemory\0".as_ptr().cast(),
594 | ))
595 | },
596 | vkUpdateDescriptorSets: unsafe {
597 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
598 | device,
599 | "vkUpdateDescriptorSets\0".as_ptr().cast(),
600 | ))
601 | },
602 | vkWaitForFences: unsafe {
603 | std::mem::transmute(instance.vkGetDeviceProcAddr.unwrap()(
604 | device,
605 | "vkWaitForFences\0".as_ptr().cast(),
606 | ))
607 | },
608 | }
609 | }
610 | }
611 |
```