├── .gitattributes
├── .gitignore
├── LICENSE.txt
├── README.md
├── hellovulkan
├── .gitignore
├── build
│ ├── HelloVulkan_2013.sln
│ ├── HelloVulkan_2013.vcxproj
│ ├── HelloVulkan_2015.sln
│ ├── HelloVulkan_2015.vcxproj
│ └── Windows10SDKVS13_x64.props
├── premake
│ └── premake5.lua
├── src
│ ├── ImageIO.cpp
│ ├── ImageIO.h
│ ├── Main.cpp
│ ├── RubyTexture.h
│ ├── Shaders.h
│ ├── Utility.cpp
│ ├── Utility.h
│ ├── VulkanQuad.cpp
│ ├── VulkanQuad.h
│ ├── VulkanSample.cpp
│ ├── VulkanSample.h
│ ├── VulkanTexturedQuad.cpp
│ ├── VulkanTexturedQuad.h
│ ├── Window.cpp
│ ├── Window.h
│ ├── basic.frag
│ ├── basic.spv
│ ├── textured.frag
│ ├── textured.spv
│ ├── tri.vert
│ └── vs.spv
└── tools
│ ├── binaryToHeader.py
│ └── sourceToHeader.py
└── premake
├── LICENSE.txt
├── amd_premake_util.lua
└── premake5.exe
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Vulkan is a cross-platform API.
2 | # Deal with different line endings on different operating systems.
3 | * text=auto
4 |
5 | # Explicitly declare text files you want to always be normalized and converted
6 | # to native line endings on checkout.
7 | *.h text
8 | *.cpp text
9 | *.inl text
10 | *.frag text
11 | *.vert text
12 | *.txt text
13 | *.lua text
14 | *.md text
15 | *.py text
16 |
17 | # Declare files that will always have CRLF line endings on checkout.
18 | *.vcxproj text eol=crlf
19 | *.filters text eol=crlf
20 | *.props text eol=crlf
21 | *.sln text eol=crlf
22 | *.bat text eol=crlf
23 |
24 | # Denote all files that are binary and should not be modified.
25 | *.pdf binary
26 | *.jpg binary
27 | *.png binary
28 | *.spv binary
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio.
3 | ################################################################################
4 |
5 | /hellovulkan/build/HelloVulkan_2015.VC.db
6 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Hello Vulkan
2 | ============
3 |
4 | Welcome to a Vulkan™ "Hello Triangle" sample which shows how to set up a window, set up a Vulkan context, and render a triangle. This sample is designed to help you get started with Vulkan and does not use any wrappers or helper libraries - pure Vulkan all the way.
5 |
6 | License
7 | -------
8 |
9 | MIT: see `LICENSE.txt` for details.
10 |
11 | System requirements
12 | -------------------
13 |
14 | * AMD Radeon™ GCN-based GPU (HD 7000 series or newer)
15 | * Or other Vulkan™ compatible discrete GPU
16 | * 64-bit Windows® 7 (SP1 with the [Platform Update](https://msdn.microsoft.com/en-us/library/windows/desktop/jj863687.aspx)), Windows® 8.1, or Windows® 10
17 | * Visual Studio® 2013 or Visual Studio® 2015
18 | * Graphics driver with Vulkan support
19 | * For example, AMD Radeon Software Crimson Edition 16.5.2 or later
20 | * The [Vulkan SDK](https://vulkan.lunarg.com) must be installed
21 |
22 | Building
23 | --------
24 |
25 | Visual Studio files can be found in the `hellovulkan\build` directory.
26 |
27 | If you need to regenerate the Visual Studio files, open a command prompt in the `hellovulkan\premake` directory and run `..\..\premake\premake5.exe vs2015` (or `..\..\premake\premake5.exe vs2013` for Visual Studio 2013.)
28 |
29 | Vulkan also supports Linux®, of course, and Premake can generate GNU Makefiles. However, at this time, the sample itself is Windows specific (because the helper code in Window.h/.cpp is Windows specific).
30 |
31 | Third-party software
32 | ------------------
33 |
34 | * Premake is distributed under the terms of the BSD License. See `premake\LICENSE.txt`.
35 |
36 | Known issues
37 | ------------
38 |
39 | The sample uses `PRESENT_MODE_FIFO` to run with VSync. On the NVIDIA 365.19 driver, FIFO is ignored and the sample will exit after a very brief period of time. You can increase the number of frames rendered to ensure it remains visible for a couple of seconds.
40 |
41 | Attribution
42 | -----------
43 |
44 | * AMD, the AMD Arrow logo, Radeon, and combinations thereof are either registered trademarks or trademarks of Advanced Micro Devices, Inc. in the United States and/or other countries.
45 | * Microsoft, Visual Studio, and Windows are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries.
46 | * Linux is the registered trademark of Linus Torvalds in the U.S. and other countries.
47 | * Vulkan and the Vulkan logo are trademarks of the Khronos Group, Inc.
48 |
--------------------------------------------------------------------------------
/hellovulkan/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, etc.
2 |
3 | # User-specific files
4 | *.suo
5 | *.user
6 |
7 | # Build results
8 | [Dd]esktop_*/
9 | HelloVulkan_Debug_*.*
10 | HelloVulkan_Release_*.*
11 |
12 | # Visual Studo 2015 cache/options directory
13 | .vs/
14 |
15 | # Visual C++ cache files
16 | ipch/
17 | *.aps
18 | *.ncb
19 | *.opensdf
20 | *.sdf
21 | *.cachefile
22 | *.opendb
23 |
24 | # Visual Studio profiler
25 | *.psess
26 | *.vsp
27 | *.vspx
28 |
29 | # Installshield output folder
30 | [Ee]xpress/
31 |
32 | # Backup & report files from converting an old project file
33 | # to a newer Visual Studio version. Backup files are not needed,
34 | # because we have git ;-)
35 | _UpgradeReport_Files/
36 | Backup*/
37 | UpgradeLog*.XML
38 | UpgradeLog*.htm
39 |
--------------------------------------------------------------------------------
/hellovulkan/build/HelloVulkan_2013.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HelloVulkan", "HelloVulkan_2013.vcxproj", "{4ABD8B07-B672-04FD-3F67-FED3AB1BFB00}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|x64 = Debug|x64
9 | Release|x64 = Release|x64
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {4ABD8B07-B672-04FD-3F67-FED3AB1BFB00}.Debug|x64.ActiveCfg = Debug|x64
13 | {4ABD8B07-B672-04FD-3F67-FED3AB1BFB00}.Debug|x64.Build.0 = Debug|x64
14 | {4ABD8B07-B672-04FD-3F67-FED3AB1BFB00}.Release|x64.ActiveCfg = Release|x64
15 | {4ABD8B07-B672-04FD-3F67-FED3AB1BFB00}.Release|x64.Build.0 = Release|x64
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/hellovulkan/build/HelloVulkan_2013.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | x64
7 |
8 |
9 | Release
10 | x64
11 |
12 |
13 |
14 | {4ABD8B07-B672-04FD-3F67-FED3AB1BFB00}
15 | true
16 | Win32Proj
17 | HelloVulkan
18 | HelloVulkan
19 |
20 |
21 |
22 | Application
23 | true
24 | Unicode
25 | v120
26 |
27 |
28 | Application
29 | false
30 | Unicode
31 | v120
32 | true
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | true
48 | ..\bin\
49 | Desktop_2013\x64\Debug\
50 | HelloVulkan_Debug_2013
51 | .exe
52 |
53 |
54 | false
55 | ..\bin\
56 | Desktop_2013\x64\Release\
57 | HelloVulkan_Release_2013
58 | .exe
59 |
60 |
61 |
62 | NotUsing
63 | Level4
64 | true
65 | _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;DEBUG;_WINDOWS;%(PreprocessorDefinitions)
66 | $(VULKAN_SDK)\include;%(AdditionalIncludeDirectories)
67 | ProgramDatabase
68 | Disabled
69 | Fast
70 |
71 |
72 | Windows
73 | true
74 | $(VULKAN_SDK)\lib\vulkan-1.lib;%(AdditionalDependencies)
75 | true
76 |
77 |
78 |
79 |
80 | NotUsing
81 | Level4
82 | true
83 | _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;PROFILE;_WINDOWS;%(PreprocessorDefinitions)
84 | $(VULKAN_SDK)\include;%(AdditionalIncludeDirectories)
85 | ProgramDatabase
86 | Full
87 | true
88 | true
89 | false
90 | true
91 | Fast
92 |
93 |
94 | Windows
95 | true
96 | true
97 | true
98 | $(VULKAN_SDK)\lib\vulkan-1.lib;%(AdditionalDependencies)
99 | true
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/hellovulkan/build/HelloVulkan_2015.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HelloVulkan", "HelloVulkan_2015.vcxproj", "{4ABD8B07-B672-04FD-3F67-FED3AB1BFB00}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|x64 = Debug|x64
9 | Release|x64 = Release|x64
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {4ABD8B07-B672-04FD-3F67-FED3AB1BFB00}.Debug|x64.ActiveCfg = Debug|x64
13 | {4ABD8B07-B672-04FD-3F67-FED3AB1BFB00}.Debug|x64.Build.0 = Debug|x64
14 | {4ABD8B07-B672-04FD-3F67-FED3AB1BFB00}.Release|x64.ActiveCfg = Release|x64
15 | {4ABD8B07-B672-04FD-3F67-FED3AB1BFB00}.Release|x64.Build.0 = Release|x64
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/hellovulkan/build/HelloVulkan_2015.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | x64
7 |
8 |
9 | Release
10 | x64
11 |
12 |
13 |
14 | {4ABD8B07-B672-04FD-3F67-FED3AB1BFB00}
15 | true
16 | Win32Proj
17 | HelloVulkan
18 | HelloVulkan
19 | 8.1
20 |
21 |
22 |
23 | Application
24 | true
25 | Unicode
26 | v140
27 |
28 |
29 | Application
30 | false
31 | Unicode
32 | v140
33 | true
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | true
47 | ..\bin\
48 | Desktop_2015\x64\Debug\
49 | HelloVulkan_Debug_2015
50 | .exe
51 |
52 |
53 | false
54 | ..\bin\
55 | Desktop_2015\x64\Release\
56 | HelloVulkan_Release_2015
57 | .exe
58 |
59 |
60 |
61 | NotUsing
62 | Level4
63 | true
64 | _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;DEBUG;_WINDOWS;%(PreprocessorDefinitions)
65 | $(VULKAN_SDK)\include;%(AdditionalIncludeDirectories)
66 | ProgramDatabase
67 | Disabled
68 | Fast
69 |
70 |
71 | Windows
72 | true
73 | $(VULKAN_SDK)\lib\vulkan-1.lib;%(AdditionalDependencies)
74 | true
75 |
76 |
77 |
78 |
79 | NotUsing
80 | Level4
81 | true
82 | _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;PROFILE;_WINDOWS;%(PreprocessorDefinitions)
83 | $(VULKAN_SDK)\include;%(AdditionalIncludeDirectories)
84 | ProgramDatabase
85 | Full
86 | true
87 | true
88 | false
89 | true
90 | Fast
91 |
92 |
93 | Windows
94 | true
95 | true
96 | true
97 | $(VULKAN_SDK)\lib\vulkan-1.lib;%(AdditionalDependencies)
98 | true
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/hellovulkan/build/Windows10SDKVS13_x64.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(ProgramFiles)\Windows Kits\10\bin\x86;$(ExecutablePath)
7 | $(ProgramFiles)\Windows Kits\10\Include\10.0.10240.0\um;$(ProgramFiles)\Windows Kits\10\Include\10.0.10240.0\shared;$(ProgramFiles)\Windows Kits\10\Include\10.0.10240.0\winrt;$(IncludePath)
8 | $(ProgramFiles)\Windows Kits\10\lib\10.0.10240.0\um\x64;$(LibraryPath)
9 | $(ProgramFiles)\Windows Kits\10\Include\10.0.10240.0\um;$(ProgramFiles)\Windows Kits\10\Include\10.0.10240.0\shared;$(ProgramFiles)\Windows Kits\10\Include\10.0.10240.0\winrt;$(ExcludePath)
10 |
11 |
12 |
--------------------------------------------------------------------------------
/hellovulkan/premake/premake5.lua:
--------------------------------------------------------------------------------
1 | _AMD_SAMPLE_NAME = "HelloVulkan"
2 |
3 | dofile ("../../premake/amd_premake_util.lua")
4 |
5 | workspace (_AMD_SAMPLE_NAME)
6 | configurations { "Debug", "Release" }
7 | platforms { "x64" }
8 | location "../build"
9 | filename (_AMD_SAMPLE_NAME .. _AMD_VS_SUFFIX)
10 | startproject (_AMD_SAMPLE_NAME)
11 |
12 | filter "platforms:x64"
13 | system "Windows"
14 | architecture "x64"
15 |
16 | project (_AMD_SAMPLE_NAME)
17 | kind "WindowedApp"
18 | language "C++"
19 | location "../build"
20 | filename (_AMD_SAMPLE_NAME .. _AMD_VS_SUFFIX)
21 | uuid "4ABD8B07-B672-04FD-3F67-FED3AB1BFB00"
22 | targetdir "../bin"
23 | objdir "../build/%{_AMD_SAMPLE_DIR_LAYOUT}"
24 | warnings "Extra"
25 | floatingpoint "Fast"
26 |
27 | -- Specify WindowsTargetPlatformVersion here for VS2015
28 | windowstarget (_AMD_WIN_SDK_VERSION)
29 |
30 | files { "../src/**.h", "../src/**.cpp" }
31 | links { "$(VULKAN_SDK)/lib/vulkan-1.lib" }
32 | includedirs { "$(VULKAN_SDK)/include" }
33 |
34 | defines { "_CRT_SECURE_NO_WARNINGS" }
35 |
36 | filter "configurations:Debug"
37 | defines { "WIN32", "_DEBUG", "DEBUG", "_WINDOWS" }
38 | flags { "Symbols", "FatalWarnings", "Unicode", "WinMain" }
39 | targetsuffix ("_Debug" .. _AMD_VS_SUFFIX)
40 |
41 | filter "configurations:Release"
42 | defines { "WIN32", "NDEBUG", "PROFILE", "_WINDOWS" }
43 | flags { "LinkTimeOptimization", "Symbols", "FatalWarnings", "Unicode", "WinMain" }
44 | targetsuffix ("_Release" .. _AMD_VS_SUFFIX)
45 | optimize "On"
46 |
--------------------------------------------------------------------------------
/hellovulkan/src/ImageIO.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #include "ImageIO.h"
24 |
25 | #include
26 | #include
27 | #include
28 | // for _com_error
29 | #include
30 |
31 | #include "Utility.h"
32 | #define SAFE_WIC(expr) do {const auto r = expr; if (FAILED(r)) {_com_error err (r); OutputDebugString (err.ErrorMessage()); __debugbreak ();} } while (0,0)
33 |
34 | using namespace Microsoft::WRL;
35 |
36 | #undef LoadImage
37 |
38 | namespace {
39 | std::vector LoadInternal(ComPtr factory, ComPtr stream,
40 | const int rowAlignment, int* outputWidth, int* outputHeight)
41 | {
42 | ComPtr decoder;
43 | factory->CreateDecoderFromStream(stream.Get(), nullptr,
44 | WICDecodeMetadataCacheOnDemand, &decoder);
45 |
46 | ComPtr frame;
47 | decoder->GetFrame(0, &frame);
48 |
49 | ComPtr converter;
50 | factory->CreateFormatConverter(&converter);
51 | converter->Initialize(
52 | frame.Get(), GUID_WICPixelFormat32bppRGBA,
53 | WICBitmapDitherTypeNone, nullptr, 0.f,
54 | WICBitmapPaletteTypeMedianCut);
55 |
56 | UINT width, height;
57 | converter->GetSize(&width, &height);
58 |
59 | std::vector result(
60 | RoundToNextMultiple(width, static_cast (rowAlignment)) * height * 4);
61 |
62 | SAFE_WIC(converter->CopyPixels(nullptr,
63 | RoundToNextMultiple(width, static_cast (rowAlignment)) * 4,
64 | static_cast (result.size()), result.data()));
65 |
66 | if (outputWidth) {
67 | *outputWidth = static_cast (width);
68 | }
69 |
70 | if (outputHeight) {
71 | *outputHeight = static_cast (height);
72 | }
73 |
74 | return result;
75 | }
76 | }
77 |
78 | std::vector LoadImageFromFile (const char* path, const int rowAlignment,
79 | int* outputWidth, int* outputHeight)
80 | {
81 | ComPtr factory;
82 | HRESULT hr = CoCreateInstance (
83 | CLSID_WICImagingFactory,
84 | NULL,
85 | CLSCTX_INPROC_SERVER,
86 | IID_PPV_ARGS (&factory)
87 | );
88 |
89 | if (FAILED(hr)) {
90 | throw std::runtime_error ("Could not create WIC factory");
91 | }
92 |
93 | ComPtr decoder;
94 |
95 | std::vector pathWchar (::strlen (path) + 1);
96 | mbstowcs (pathWchar.data (), path, pathWchar.size ());
97 |
98 | ComPtr stream;
99 | factory->CreateStream(&stream);
100 | stream->InitializeFromFilename(pathWchar.data (), GENERIC_READ);
101 |
102 | return LoadInternal(factory, stream, rowAlignment, outputWidth, outputHeight);
103 |
104 | }
105 |
106 | std::vector LoadImageFromMemory(const void* data, const std::size_t size,
107 | const int rowAlignment, int* outputWidth, int* outputHeight)
108 | {
109 | ComPtr factory;
110 | HRESULT hr = CoCreateInstance(
111 | CLSID_WICImagingFactory,
112 | NULL,
113 | CLSCTX_INPROC_SERVER,
114 | IID_PPV_ARGS(&factory)
115 | );
116 |
117 | if (FAILED (hr)) {
118 | throw std::runtime_error ("Could not create WIC factory");
119 | }
120 |
121 | ComPtr stream;
122 | factory->CreateStream(&stream);
123 |
124 | // This is fine here as the memory will live on when the stream is long gone
125 | stream->InitializeFromMemory(static_cast (const_cast (data)),
126 | static_cast (size));
127 |
128 | return LoadInternal(factory, stream, rowAlignment, outputWidth, outputHeight);
129 | }
130 |
--------------------------------------------------------------------------------
/hellovulkan/src/ImageIO.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #ifndef AMD_VULKAN_SAMPLE_IMAGE_IO_H_
24 | #define AMD_VULKAN_SAMPLE_IMAGE_IO_H_
25 |
26 | #include
27 | #include
28 |
29 | #ifdef LoadImage
30 | #undef LoadImage
31 | #endif
32 |
33 | std::vector LoadImageFromFile (const char* path, const int rowAlignment,
34 | int* width, int* height);
35 |
36 | std::vector LoadImageFromMemory(const void* data, const std::size_t size, const int rowAlignment,
37 | int* width, int* height);
38 |
39 | #endif
--------------------------------------------------------------------------------
/hellovulkan/src/Main.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #include "VulkanQuad.h"
24 | #include "VulkanTexturedQuad.h"
25 |
26 | int WinMain(
27 | _In_ HINSTANCE /* hInstance */,
28 | _In_opt_ HINSTANCE /* hPrevInstance */,
29 | _In_ LPSTR /* lpCmdLine */,
30 | _In_ int /* nCmdShow */
31 | )
32 | {
33 | AMD::VulkanSample* sample = nullptr;
34 |
35 | const auto sampleId = 0;
36 |
37 | switch (sampleId)
38 | {
39 | case 0: sample = new AMD::VulkanQuad; break;
40 | case 1: sample = new AMD::VulkanTexturedQuad; break;
41 | }
42 |
43 | if (sample == nullptr || sample->IsInitialized() == false)
44 | {
45 | return 1;
46 | }
47 |
48 | sample->Run(512);
49 | delete sample;
50 |
51 | return 0;
52 | }
53 |
--------------------------------------------------------------------------------
/hellovulkan/src/Shaders.h:
--------------------------------------------------------------------------------
1 | const unsigned char BasicFragmentShader [] = {
2 | 0x3 , 0x2 , 0x23, 0x7 , 0x0 , 0x0 , 0x1 , 0x0 , 0x1 , 0x0 , 0x8 , 0x0 , 0x13,
3 | 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x11, 0x0 , 0x2 , 0x0 , 0x1 , 0x0 ,
4 | 0x0 , 0x0 , 0xb , 0x0 , 0x6 , 0x0 , 0x1 , 0x0 , 0x0 , 0x0 , 0x47, 0x4c, 0x53,
5 | 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, 0x0 , 0x0 , 0x0 , 0x0 ,
6 | 0xe , 0x0 , 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x1 , 0x0 , 0x0 , 0x0 , 0xf ,
7 | 0x0 , 0x7 , 0x0 , 0x4 , 0x0 , 0x0 , 0x0 , 0x4 , 0x0 , 0x0 , 0x0 , 0x6d, 0x61,
8 | 0x69, 0x6e, 0x0 , 0x0 , 0x0 , 0x0 , 0x9 , 0x0 , 0x0 , 0x0 , 0xc , 0x0 , 0x0 ,
9 | 0x0 , 0x10, 0x0 , 0x3 , 0x0 , 0x4 , 0x0 , 0x0 , 0x0 , 0x7 , 0x0 , 0x0 , 0x0 ,
10 | 0x3 , 0x0 , 0x3 , 0x0 , 0x2 , 0x0 , 0x0 , 0x0 , 0x90, 0x1 , 0x0 , 0x0 , 0x4 ,
11 | 0x0 , 0x9 , 0x0 , 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, 0x65, 0x70,
12 | 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f,
13 | 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x0 , 0x0 , 0x4 , 0x0 , 0x9 , 0x0 ,
14 | 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x69, 0x6e,
15 | 0x67, 0x5f, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x5f, 0x34, 0x32,
16 | 0x30, 0x70, 0x61, 0x63, 0x6b, 0x0 , 0x5 , 0x0 , 0x4 , 0x0 , 0x4 , 0x0 , 0x0 ,
17 | 0x0 , 0x6d, 0x61, 0x69, 0x6e, 0x0 , 0x0 , 0x0 , 0x0 , 0x5 , 0x0 , 0x5 , 0x0 ,
18 | 0x9 , 0x0 , 0x0 , 0x0 , 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x43, 0x6f, 0x6c,
19 | 0x6f, 0x72, 0x0 , 0x5 , 0x0 , 0x3 , 0x0 , 0xc , 0x0 , 0x0 , 0x0 , 0x75, 0x76,
20 | 0x0 , 0x0 , 0x47, 0x0 , 0x4 , 0x0 , 0x9 , 0x0 , 0x0 , 0x0 , 0x1e, 0x0 , 0x0 ,
21 | 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x47, 0x0 , 0x4 , 0x0 , 0xc , 0x0 , 0x0 , 0x0 ,
22 | 0x1e, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x13, 0x0 , 0x2 , 0x0 , 0x2 ,
23 | 0x0 , 0x0 , 0x0 , 0x21, 0x0 , 0x3 , 0x0 , 0x3 , 0x0 , 0x0 , 0x0 , 0x2 , 0x0 ,
24 | 0x0 , 0x0 , 0x16, 0x0 , 0x3 , 0x0 , 0x6 , 0x0 , 0x0 , 0x0 , 0x20, 0x0 , 0x0 ,
25 | 0x0 , 0x17, 0x0 , 0x4 , 0x0 , 0x7 , 0x0 , 0x0 , 0x0 , 0x6 , 0x0 , 0x0 , 0x0 ,
26 | 0x4 , 0x0 , 0x0 , 0x0 , 0x20, 0x0 , 0x4 , 0x0 , 0x8 , 0x0 , 0x0 , 0x0 , 0x3 ,
27 | 0x0 , 0x0 , 0x0 , 0x7 , 0x0 , 0x0 , 0x0 , 0x3b, 0x0 , 0x4 , 0x0 , 0x8 , 0x0 ,
28 | 0x0 , 0x0 , 0x9 , 0x0 , 0x0 , 0x0 , 0x3 , 0x0 , 0x0 , 0x0 , 0x17, 0x0 , 0x4 ,
29 | 0x0 , 0xa , 0x0 , 0x0 , 0x0 , 0x6 , 0x0 , 0x0 , 0x0 , 0x2 , 0x0 , 0x0 , 0x0 ,
30 | 0x20, 0x0 , 0x4 , 0x0 , 0xb , 0x0 , 0x0 , 0x0 , 0x1 , 0x0 , 0x0 , 0x0 , 0xa ,
31 | 0x0 , 0x0 , 0x0 , 0x3b, 0x0 , 0x4 , 0x0 , 0xb , 0x0 , 0x0 , 0x0 , 0xc , 0x0 ,
32 | 0x0 , 0x0 , 0x1 , 0x0 , 0x0 , 0x0 , 0x2b, 0x0 , 0x4 , 0x0 , 0x6 , 0x0 , 0x0 ,
33 | 0x0 , 0xe , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x2b, 0x0 , 0x4 , 0x0 ,
34 | 0x6 , 0x0 , 0x0 , 0x0 , 0xf , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x80, 0x3f, 0x36,
35 | 0x0 , 0x5 , 0x0 , 0x2 , 0x0 , 0x0 , 0x0 , 0x4 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
36 | 0x0 , 0x0 , 0x3 , 0x0 , 0x0 , 0x0 , 0xf8, 0x0 , 0x2 , 0x0 , 0x5 , 0x0 , 0x0 ,
37 | 0x0 , 0x3d, 0x0 , 0x4 , 0x0 , 0xa , 0x0 , 0x0 , 0x0 , 0xd , 0x0 , 0x0 , 0x0 ,
38 | 0xc , 0x0 , 0x0 , 0x0 , 0x51, 0x0 , 0x5 , 0x0 , 0x6 , 0x0 , 0x0 , 0x0 , 0x10,
39 | 0x0 , 0x0 , 0x0 , 0xd , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x51, 0x0 ,
40 | 0x5 , 0x0 , 0x6 , 0x0 , 0x0 , 0x0 , 0x11, 0x0 , 0x0 , 0x0 , 0xd , 0x0 , 0x0 ,
41 | 0x0 , 0x1 , 0x0 , 0x0 , 0x0 , 0x50, 0x0 , 0x7 , 0x0 , 0x7 , 0x0 , 0x0 , 0x0 ,
42 | 0x12, 0x0 , 0x0 , 0x0 , 0x10, 0x0 , 0x0 , 0x0 , 0x11, 0x0 , 0x0 , 0x0 , 0xe ,
43 | 0x0 , 0x0 , 0x0 , 0xf , 0x0 , 0x0 , 0x0 , 0x3e, 0x0 , 0x3 , 0x0 , 0x9 , 0x0 ,
44 | 0x0 , 0x0 , 0x12, 0x0 , 0x0 , 0x0 , 0xfd, 0x0 , 0x1 , 0x0 , 0x38, 0x0 , 0x1 ,
45 | 0x0 ,
46 | };
47 | const unsigned char BasicVertexShader [] = {
48 | 0x3 , 0x2 , 0x23, 0x7 , 0x0 , 0x0 , 0x1 , 0x0 , 0x1 , 0x0 , 0x8 , 0x0 , 0x21,
49 | 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x11, 0x0 , 0x2 , 0x0 , 0x1 , 0x0 ,
50 | 0x0 , 0x0 , 0x11, 0x0 , 0x2 , 0x0 , 0x20, 0x0 , 0x0 , 0x0 , 0xb , 0x0 , 0x6 ,
51 | 0x0 , 0x1 , 0x0 , 0x0 , 0x0 , 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64,
52 | 0x2e, 0x34, 0x35, 0x30, 0x0 , 0x0 , 0x0 , 0x0 , 0xe , 0x0 , 0x3 , 0x0 , 0x0 ,
53 | 0x0 , 0x0 , 0x0 , 0x1 , 0x0 , 0x0 , 0x0 , 0xf , 0x0 , 0x9 , 0x0 , 0x0 , 0x0 ,
54 | 0x0 , 0x0 , 0x4 , 0x0 , 0x0 , 0x0 , 0x6d, 0x61, 0x69, 0x6e, 0x0 , 0x0 , 0x0 ,
55 | 0x0 , 0xd , 0x0 , 0x0 , 0x0 , 0x12, 0x0 , 0x0 , 0x0 , 0x1d, 0x0 , 0x0 , 0x0 ,
56 | 0x1f, 0x0 , 0x0 , 0x0 , 0x3 , 0x0 , 0x3 , 0x0 , 0x2 , 0x0 , 0x0 , 0x0 , 0x90,
57 | 0x1 , 0x0 , 0x0 , 0x4 , 0x0 , 0x9 , 0x0 , 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42,
58 | 0x5f, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x68, 0x61,
59 | 0x64, 0x65, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x0 , 0x0 ,
60 | 0x4 , 0x0 , 0x9 , 0x0 , 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, 0x68,
61 | 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67,
62 | 0x65, 0x5f, 0x34, 0x32, 0x30, 0x70, 0x61, 0x63, 0x6b, 0x0 , 0x5 , 0x0 , 0x4 ,
63 | 0x0 , 0x4 , 0x0 , 0x0 , 0x0 , 0x6d, 0x61, 0x69, 0x6e, 0x0 , 0x0 , 0x0 , 0x0 ,
64 | 0x5 , 0x0 , 0x6 , 0x0 , 0xb , 0x0 , 0x0 , 0x0 , 0x67, 0x6c, 0x5f, 0x50, 0x65,
65 | 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x0 , 0x0 , 0x0 , 0x0 , 0x6 , 0x0 ,
66 | 0x6 , 0x0 , 0xb , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x67, 0x6c, 0x5f,
67 | 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x0 , 0x6 , 0x0 , 0x7 , 0x0 ,
68 | 0xb , 0x0 , 0x0 , 0x0 , 0x1 , 0x0 , 0x0 , 0x0 , 0x67, 0x6c, 0x5f, 0x50, 0x6f,
69 | 0x69, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x0 , 0x0 , 0x0 , 0x0 , 0x6 , 0x0 ,
70 | 0x7 , 0x0 , 0xb , 0x0 , 0x0 , 0x0 , 0x2 , 0x0 , 0x0 , 0x0 , 0x67, 0x6c, 0x5f,
71 | 0x43, 0x6c, 0x69, 0x70, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x0 ,
72 | 0x5 , 0x0 , 0x3 , 0x0 , 0xd , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x5 ,
73 | 0x0 , 0x3 , 0x0 , 0x12, 0x0 , 0x0 , 0x0 , 0x70, 0x6f, 0x73, 0x0 , 0x5 , 0x0 ,
74 | 0x4 , 0x0 , 0x1d, 0x0 , 0x0 , 0x0 , 0x6f, 0x75, 0x74, 0x55, 0x76, 0x0 , 0x0 ,
75 | 0x0 , 0x5 , 0x0 , 0x4 , 0x0 , 0x1f, 0x0 , 0x0 , 0x0 , 0x69, 0x6e, 0x55, 0x76,
76 | 0x0 , 0x0 , 0x0 , 0x0 , 0x48, 0x0 , 0x5 , 0x0 , 0xb , 0x0 , 0x0 , 0x0 , 0x0 ,
77 | 0x0 , 0x0 , 0x0 , 0xb , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x48, 0x0 ,
78 | 0x5 , 0x0 , 0xb , 0x0 , 0x0 , 0x0 , 0x1 , 0x0 , 0x0 , 0x0 , 0xb , 0x0 , 0x0 ,
79 | 0x0 , 0x1 , 0x0 , 0x0 , 0x0 , 0x48, 0x0 , 0x5 , 0x0 , 0xb , 0x0 , 0x0 , 0x0 ,
80 | 0x2 , 0x0 , 0x0 , 0x0 , 0xb , 0x0 , 0x0 , 0x0 , 0x3 , 0x0 , 0x0 , 0x0 , 0x47,
81 | 0x0 , 0x3 , 0x0 , 0xb , 0x0 , 0x0 , 0x0 , 0x2 , 0x0 , 0x0 , 0x0 , 0x47, 0x0 ,
82 | 0x4 , 0x0 , 0x12, 0x0 , 0x0 , 0x0 , 0x1e, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
83 | 0x0 , 0x47, 0x0 , 0x4 , 0x0 , 0x1d, 0x0 , 0x0 , 0x0 , 0x1e, 0x0 , 0x0 , 0x0 ,
84 | 0x0 , 0x0 , 0x0 , 0x0 , 0x47, 0x0 , 0x4 , 0x0 , 0x1f, 0x0 , 0x0 , 0x0 , 0x1e,
85 | 0x0 , 0x0 , 0x0 , 0x1 , 0x0 , 0x0 , 0x0 , 0x13, 0x0 , 0x2 , 0x0 , 0x2 , 0x0 ,
86 | 0x0 , 0x0 , 0x21, 0x0 , 0x3 , 0x0 , 0x3 , 0x0 , 0x0 , 0x0 , 0x2 , 0x0 , 0x0 ,
87 | 0x0 , 0x16, 0x0 , 0x3 , 0x0 , 0x6 , 0x0 , 0x0 , 0x0 , 0x20, 0x0 , 0x0 , 0x0 ,
88 | 0x17, 0x0 , 0x4 , 0x0 , 0x7 , 0x0 , 0x0 , 0x0 , 0x6 , 0x0 , 0x0 , 0x0 , 0x4 ,
89 | 0x0 , 0x0 , 0x0 , 0x15, 0x0 , 0x4 , 0x0 , 0x8 , 0x0 , 0x0 , 0x0 , 0x20, 0x0 ,
90 | 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x2b, 0x0 , 0x4 , 0x0 , 0x8 , 0x0 , 0x0 ,
91 | 0x0 , 0x9 , 0x0 , 0x0 , 0x0 , 0x1 , 0x0 , 0x0 , 0x0 , 0x1c, 0x0 , 0x4 , 0x0 ,
92 | 0xa , 0x0 , 0x0 , 0x0 , 0x6 , 0x0 , 0x0 , 0x0 , 0x9 , 0x0 , 0x0 , 0x0 , 0x1e,
93 | 0x0 , 0x5 , 0x0 , 0xb , 0x0 , 0x0 , 0x0 , 0x7 , 0x0 , 0x0 , 0x0 , 0x6 , 0x0 ,
94 | 0x0 , 0x0 , 0xa , 0x0 , 0x0 , 0x0 , 0x20, 0x0 , 0x4 , 0x0 , 0xc , 0x0 , 0x0 ,
95 | 0x0 , 0x3 , 0x0 , 0x0 , 0x0 , 0xb , 0x0 , 0x0 , 0x0 , 0x3b, 0x0 , 0x4 , 0x0 ,
96 | 0xc , 0x0 , 0x0 , 0x0 , 0xd , 0x0 , 0x0 , 0x0 , 0x3 , 0x0 , 0x0 , 0x0 , 0x15,
97 | 0x0 , 0x4 , 0x0 , 0xe , 0x0 , 0x0 , 0x0 , 0x20, 0x0 , 0x0 , 0x0 , 0x1 , 0x0 ,
98 | 0x0 , 0x0 , 0x2b, 0x0 , 0x4 , 0x0 , 0xe , 0x0 , 0x0 , 0x0 , 0xf , 0x0 , 0x0 ,
99 | 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x17, 0x0 , 0x4 , 0x0 , 0x10, 0x0 , 0x0 , 0x0 ,
100 | 0x6 , 0x0 , 0x0 , 0x0 , 0x3 , 0x0 , 0x0 , 0x0 , 0x20, 0x0 , 0x4 , 0x0 , 0x11,
101 | 0x0 , 0x0 , 0x0 , 0x1 , 0x0 , 0x0 , 0x0 , 0x10, 0x0 , 0x0 , 0x0 , 0x3b, 0x0 ,
102 | 0x4 , 0x0 , 0x11, 0x0 , 0x0 , 0x0 , 0x12, 0x0 , 0x0 , 0x0 , 0x1 , 0x0 , 0x0 ,
103 | 0x0 , 0x2b, 0x0 , 0x4 , 0x0 , 0x6 , 0x0 , 0x0 , 0x0 , 0x14, 0x0 , 0x0 , 0x0 ,
104 | 0x0 , 0x0 , 0x80, 0x3f, 0x20, 0x0 , 0x4 , 0x0 , 0x19, 0x0 , 0x0 , 0x0 , 0x3 ,
105 | 0x0 , 0x0 , 0x0 , 0x7 , 0x0 , 0x0 , 0x0 , 0x17, 0x0 , 0x4 , 0x0 , 0x1b, 0x0 ,
106 | 0x0 , 0x0 , 0x6 , 0x0 , 0x0 , 0x0 , 0x2 , 0x0 , 0x0 , 0x0 , 0x20, 0x0 , 0x4 ,
107 | 0x0 , 0x1c, 0x0 , 0x0 , 0x0 , 0x3 , 0x0 , 0x0 , 0x0 , 0x1b, 0x0 , 0x0 , 0x0 ,
108 | 0x3b, 0x0 , 0x4 , 0x0 , 0x1c, 0x0 , 0x0 , 0x0 , 0x1d, 0x0 , 0x0 , 0x0 , 0x3 ,
109 | 0x0 , 0x0 , 0x0 , 0x20, 0x0 , 0x4 , 0x0 , 0x1e, 0x0 , 0x0 , 0x0 , 0x1 , 0x0 ,
110 | 0x0 , 0x0 , 0x1b, 0x0 , 0x0 , 0x0 , 0x3b, 0x0 , 0x4 , 0x0 , 0x1e, 0x0 , 0x0 ,
111 | 0x0 , 0x1f, 0x0 , 0x0 , 0x0 , 0x1 , 0x0 , 0x0 , 0x0 , 0x36, 0x0 , 0x5 , 0x0 ,
112 | 0x2 , 0x0 , 0x0 , 0x0 , 0x4 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x3 ,
113 | 0x0 , 0x0 , 0x0 , 0xf8, 0x0 , 0x2 , 0x0 , 0x5 , 0x0 , 0x0 , 0x0 , 0x3d, 0x0 ,
114 | 0x4 , 0x0 , 0x10, 0x0 , 0x0 , 0x0 , 0x13, 0x0 , 0x0 , 0x0 , 0x12, 0x0 , 0x0 ,
115 | 0x0 , 0x51, 0x0 , 0x5 , 0x0 , 0x6 , 0x0 , 0x0 , 0x0 , 0x15, 0x0 , 0x0 , 0x0 ,
116 | 0x13, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x51, 0x0 , 0x5 , 0x0 , 0x6 ,
117 | 0x0 , 0x0 , 0x0 , 0x16, 0x0 , 0x0 , 0x0 , 0x13, 0x0 , 0x0 , 0x0 , 0x1 , 0x0 ,
118 | 0x0 , 0x0 , 0x51, 0x0 , 0x5 , 0x0 , 0x6 , 0x0 , 0x0 , 0x0 , 0x17, 0x0 , 0x0 ,
119 | 0x0 , 0x13, 0x0 , 0x0 , 0x0 , 0x2 , 0x0 , 0x0 , 0x0 , 0x50, 0x0 , 0x7 , 0x0 ,
120 | 0x7 , 0x0 , 0x0 , 0x0 , 0x18, 0x0 , 0x0 , 0x0 , 0x15, 0x0 , 0x0 , 0x0 , 0x16,
121 | 0x0 , 0x0 , 0x0 , 0x17, 0x0 , 0x0 , 0x0 , 0x14, 0x0 , 0x0 , 0x0 , 0x41, 0x0 ,
122 | 0x5 , 0x0 , 0x19, 0x0 , 0x0 , 0x0 , 0x1a, 0x0 , 0x0 , 0x0 , 0xd , 0x0 , 0x0 ,
123 | 0x0 , 0xf , 0x0 , 0x0 , 0x0 , 0x3e, 0x0 , 0x3 , 0x0 , 0x1a, 0x0 , 0x0 , 0x0 ,
124 | 0x18, 0x0 , 0x0 , 0x0 , 0x3d, 0x0 , 0x4 , 0x0 , 0x1b, 0x0 , 0x0 , 0x0 , 0x20,
125 | 0x0 , 0x0 , 0x0 , 0x1f, 0x0 , 0x0 , 0x0 , 0x3e, 0x0 , 0x3 , 0x0 , 0x1d, 0x0 ,
126 | 0x0 , 0x0 , 0x20, 0x0 , 0x0 , 0x0 , 0xfd, 0x0 , 0x1 , 0x0 , 0x38, 0x0 , 0x1 ,
127 | 0x0 ,
128 | };
129 | const unsigned char TexturedFragmentShader [] = {
130 | 0x3 , 0x2 , 0x23, 0x7 , 0x0 , 0x0 , 0x1 , 0x0 , 0x1 , 0x0 , 0x8 , 0x0 , 0x19,
131 | 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x11, 0x0 , 0x2 , 0x0 , 0x1 , 0x0 ,
132 | 0x0 , 0x0 , 0xb , 0x0 , 0x6 , 0x0 , 0x1 , 0x0 , 0x0 , 0x0 , 0x47, 0x4c, 0x53,
133 | 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, 0x0 , 0x0 , 0x0 , 0x0 ,
134 | 0xe , 0x0 , 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x1 , 0x0 , 0x0 , 0x0 , 0xf ,
135 | 0x0 , 0x7 , 0x0 , 0x4 , 0x0 , 0x0 , 0x0 , 0x4 , 0x0 , 0x0 , 0x0 , 0x6d, 0x61,
136 | 0x69, 0x6e, 0x0 , 0x0 , 0x0 , 0x0 , 0x9 , 0x0 , 0x0 , 0x0 , 0x16, 0x0 , 0x0 ,
137 | 0x0 , 0x10, 0x0 , 0x3 , 0x0 , 0x4 , 0x0 , 0x0 , 0x0 , 0x7 , 0x0 , 0x0 , 0x0 ,
138 | 0x3 , 0x0 , 0x3 , 0x0 , 0x2 , 0x0 , 0x0 , 0x0 , 0x90, 0x1 , 0x0 , 0x0 , 0x4 ,
139 | 0x0 , 0x9 , 0x0 , 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, 0x65, 0x70,
140 | 0x61, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f,
141 | 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x0 , 0x0 , 0x4 , 0x0 , 0x9 , 0x0 ,
142 | 0x47, 0x4c, 0x5f, 0x41, 0x52, 0x42, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x69, 0x6e,
143 | 0x67, 0x5f, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x5f, 0x34, 0x32,
144 | 0x30, 0x70, 0x61, 0x63, 0x6b, 0x0 , 0x5 , 0x0 , 0x4 , 0x0 , 0x4 , 0x0 , 0x0 ,
145 | 0x0 , 0x6d, 0x61, 0x69, 0x6e, 0x0 , 0x0 , 0x0 , 0x0 , 0x5 , 0x0 , 0x5 , 0x0 ,
146 | 0x9 , 0x0 , 0x0 , 0x0 , 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x43, 0x6f, 0x6c,
147 | 0x6f, 0x72, 0x0 , 0x5 , 0x0 , 0x6 , 0x0 , 0xc , 0x0 , 0x0 , 0x0 , 0x63, 0x6f,
148 | 0x6c, 0x6f, 0x72, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x0 , 0x0 , 0x0 ,
149 | 0x0 , 0x5 , 0x0 , 0x6 , 0x0 , 0x10, 0x0 , 0x0 , 0x0 , 0x63, 0x6f, 0x6c, 0x6f,
150 | 0x72, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x0 , 0x0 , 0x0 , 0x0 , 0x5 ,
151 | 0x0 , 0x3 , 0x0 , 0x16, 0x0 , 0x0 , 0x0 , 0x75, 0x76, 0x0 , 0x0 , 0x47, 0x0 ,
152 | 0x4 , 0x0 , 0x9 , 0x0 , 0x0 , 0x0 , 0x1e, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
153 | 0x0 , 0x47, 0x0 , 0x4 , 0x0 , 0xc , 0x0 , 0x0 , 0x0 , 0x22, 0x0 , 0x0 , 0x0 ,
154 | 0x0 , 0x0 , 0x0 , 0x0 , 0x47, 0x0 , 0x4 , 0x0 , 0xc , 0x0 , 0x0 , 0x0 , 0x21,
155 | 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x47, 0x0 , 0x4 , 0x0 , 0x10, 0x0 ,
156 | 0x0 , 0x0 , 0x22, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x47, 0x0 , 0x4 ,
157 | 0x0 , 0x10, 0x0 , 0x0 , 0x0 , 0x21, 0x0 , 0x0 , 0x0 , 0x1 , 0x0 , 0x0 , 0x0 ,
158 | 0x47, 0x0 , 0x4 , 0x0 , 0x16, 0x0 , 0x0 , 0x0 , 0x1e, 0x0 , 0x0 , 0x0 , 0x0 ,
159 | 0x0 , 0x0 , 0x0 , 0x13, 0x0 , 0x2 , 0x0 , 0x2 , 0x0 , 0x0 , 0x0 , 0x21, 0x0 ,
160 | 0x3 , 0x0 , 0x3 , 0x0 , 0x0 , 0x0 , 0x2 , 0x0 , 0x0 , 0x0 , 0x16, 0x0 , 0x3 ,
161 | 0x0 , 0x6 , 0x0 , 0x0 , 0x0 , 0x20, 0x0 , 0x0 , 0x0 , 0x17, 0x0 , 0x4 , 0x0 ,
162 | 0x7 , 0x0 , 0x0 , 0x0 , 0x6 , 0x0 , 0x0 , 0x0 , 0x4 , 0x0 , 0x0 , 0x0 , 0x20,
163 | 0x0 , 0x4 , 0x0 , 0x8 , 0x0 , 0x0 , 0x0 , 0x3 , 0x0 , 0x0 , 0x0 , 0x7 , 0x0 ,
164 | 0x0 , 0x0 , 0x3b, 0x0 , 0x4 , 0x0 , 0x8 , 0x0 , 0x0 , 0x0 , 0x9 , 0x0 , 0x0 ,
165 | 0x0 , 0x3 , 0x0 , 0x0 , 0x0 , 0x19, 0x0 , 0x9 , 0x0 , 0xa , 0x0 , 0x0 , 0x0 ,
166 | 0x6 , 0x0 , 0x0 , 0x0 , 0x1 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
167 | 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x1 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
168 | 0x0 , 0x0 , 0x20, 0x0 , 0x4 , 0x0 , 0xb , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
169 | 0x0 , 0xa , 0x0 , 0x0 , 0x0 , 0x3b, 0x0 , 0x4 , 0x0 , 0xb , 0x0 , 0x0 , 0x0 ,
170 | 0xc , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x1a, 0x0 , 0x2 , 0x0 , 0xe ,
171 | 0x0 , 0x0 , 0x0 , 0x20, 0x0 , 0x4 , 0x0 , 0xf , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,
172 | 0x0 , 0x0 , 0xe , 0x0 , 0x0 , 0x0 , 0x3b, 0x0 , 0x4 , 0x0 , 0xf , 0x0 , 0x0 ,
173 | 0x0 , 0x10, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x1b, 0x0 , 0x3 , 0x0 ,
174 | 0x12, 0x0 , 0x0 , 0x0 , 0xa , 0x0 , 0x0 , 0x0 , 0x17, 0x0 , 0x4 , 0x0 , 0x14,
175 | 0x0 , 0x0 , 0x0 , 0x6 , 0x0 , 0x0 , 0x0 , 0x2 , 0x0 , 0x0 , 0x0 , 0x20, 0x0 ,
176 | 0x4 , 0x0 , 0x15, 0x0 , 0x0 , 0x0 , 0x1 , 0x0 , 0x0 , 0x0 , 0x14, 0x0 , 0x0 ,
177 | 0x0 , 0x3b, 0x0 , 0x4 , 0x0 , 0x15, 0x0 , 0x0 , 0x0 , 0x16, 0x0 , 0x0 , 0x0 ,
178 | 0x1 , 0x0 , 0x0 , 0x0 , 0x36, 0x0 , 0x5 , 0x0 , 0x2 , 0x0 , 0x0 , 0x0 , 0x4 ,
179 | 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x3 , 0x0 , 0x0 , 0x0 , 0xf8, 0x0 ,
180 | 0x2 , 0x0 , 0x5 , 0x0 , 0x0 , 0x0 , 0x3d, 0x0 , 0x4 , 0x0 , 0xa , 0x0 , 0x0 ,
181 | 0x0 , 0xd , 0x0 , 0x0 , 0x0 , 0xc , 0x0 , 0x0 , 0x0 , 0x3d, 0x0 , 0x4 , 0x0 ,
182 | 0xe , 0x0 , 0x0 , 0x0 , 0x11, 0x0 , 0x0 , 0x0 , 0x10, 0x0 , 0x0 , 0x0 , 0x56,
183 | 0x0 , 0x5 , 0x0 , 0x12, 0x0 , 0x0 , 0x0 , 0x13, 0x0 , 0x0 , 0x0 , 0xd , 0x0 ,
184 | 0x0 , 0x0 , 0x11, 0x0 , 0x0 , 0x0 , 0x3d, 0x0 , 0x4 , 0x0 , 0x14, 0x0 , 0x0 ,
185 | 0x0 , 0x17, 0x0 , 0x0 , 0x0 , 0x16, 0x0 , 0x0 , 0x0 , 0x57, 0x0 , 0x5 , 0x0 ,
186 | 0x7 , 0x0 , 0x0 , 0x0 , 0x18, 0x0 , 0x0 , 0x0 , 0x13, 0x0 , 0x0 , 0x0 , 0x17,
187 | 0x0 , 0x0 , 0x0 , 0x3e, 0x0 , 0x3 , 0x0 , 0x9 , 0x0 , 0x0 , 0x0 , 0x18, 0x0 ,
188 | 0x0 , 0x0 , 0xfd, 0x0 , 0x1 , 0x0 , 0x38, 0x0 , 0x1 , 0x0 ,
189 | };
190 |
--------------------------------------------------------------------------------
/hellovulkan/src/Utility.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #include "Utility.h"
24 |
25 | #include
26 |
27 | ///////////////////////////////////////////////////////////////////////////////
28 | std::vector ReadFile(const char* filename)
29 | {
30 | std::vector result;
31 | std::uint8_t buffer[4096];
32 |
33 | auto handle = std::fopen(filename, "rb");
34 |
35 | for (;;)
36 | {
37 | const auto bytesRead = std::fread(buffer, 1, sizeof(buffer), handle);
38 |
39 | result.insert(result.end(), buffer, buffer + bytesRead);
40 |
41 | if (bytesRead < sizeof(buffer))
42 | {
43 | break;
44 | }
45 | }
46 |
47 | std::fclose(handle);
48 |
49 | return result;
50 | }
51 |
--------------------------------------------------------------------------------
/hellovulkan/src/Utility.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #ifndef AMD_VULKAN_SAMPLE_UTILITY_H_
24 | #define AMD_VULKAN_SAMPLE_UTILITY_H_
25 |
26 | #include
27 | #include
28 |
29 | ///////////////////////////////////////////////////////////////////////////////
30 | template
31 | T RoundToNextMultiple(const T a, const T multiple)
32 | {
33 | return ((a + multiple - 1) / multiple) * multiple;
34 | }
35 |
36 | std::vector ReadFile(const char* filename);
37 |
38 | #endif
39 |
--------------------------------------------------------------------------------
/hellovulkan/src/VulkanQuad.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #include "VulkanQuad.h"
24 |
25 | #include "Shaders.h"
26 | #include "Utility.h"
27 | #include "Window.h"
28 |
29 | #include
30 |
31 | namespace AMD {
32 | ///////////////////////////////////////////////////////////////////////////////
33 | void VulkanQuad::ShutdownImpl ()
34 | {
35 | vkDestroyPipeline (device_, pipeline_, nullptr);
36 | vkDestroyPipelineLayout (device_, pipelineLayout_, nullptr);
37 |
38 | vkDestroyBuffer (device_, vertexBuffer_, nullptr);
39 | vkDestroyBuffer (device_, indexBuffer_, nullptr);
40 | vkFreeMemory (device_, deviceMemory_, nullptr);
41 |
42 | vkDestroyShaderModule (device_, vertexShader_, nullptr);
43 | vkDestroyShaderModule (device_, fragmentShader_, nullptr);
44 |
45 | VulkanSample::ShutdownImpl ();
46 | }
47 |
48 | ///////////////////////////////////////////////////////////////////////////////
49 | void VulkanQuad::RenderImpl (VkCommandBuffer commandBuffer)
50 | {
51 | VulkanSample::RenderImpl (commandBuffer);
52 |
53 | vkCmdBindPipeline (commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
54 | pipeline_);
55 | VkDeviceSize offsets [] = { 0 };
56 | vkCmdBindIndexBuffer (commandBuffer, indexBuffer_, 0, VK_INDEX_TYPE_UINT32);
57 | vkCmdBindVertexBuffers (commandBuffer, 0, 1, &vertexBuffer_, offsets);
58 | vkCmdDrawIndexed (commandBuffer, 6, 1, 0, 0, 0);
59 | }
60 |
61 | ///////////////////////////////////////////////////////////////////////////////
62 | void VulkanQuad::InitializeImpl (VkCommandBuffer uploadCommandBuffer)
63 | {
64 | VulkanSample::InitializeImpl (uploadCommandBuffer);
65 |
66 | CreatePipelineStateObject ();
67 | CreateMeshBuffers (uploadCommandBuffer);
68 | }
69 |
70 | namespace {
71 | struct MemoryTypeInfo
72 | {
73 | bool deviceLocal = false;
74 | bool hostVisible = false;
75 | bool hostCoherent = false;
76 | bool hostCached = false;
77 | bool lazilyAllocated = false;
78 |
79 | struct Heap
80 | {
81 | uint64_t size = 0;
82 | bool deviceLocal = false;
83 | };
84 |
85 | Heap heap;
86 | int index;
87 | };
88 |
89 | ///////////////////////////////////////////////////////////////////////////////
90 | std::vector EnumerateHeaps (VkPhysicalDevice device)
91 | {
92 | VkPhysicalDeviceMemoryProperties memoryProperties = {};
93 | vkGetPhysicalDeviceMemoryProperties (device, &memoryProperties);
94 |
95 | std::vector heaps;
96 |
97 | for (uint32_t i = 0; i < memoryProperties.memoryHeapCount; ++i)
98 | {
99 | MemoryTypeInfo::Heap info;
100 | info.size = memoryProperties.memoryHeaps [i].size;
101 | info.deviceLocal = (memoryProperties.memoryHeaps [i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) != 0;
102 |
103 | heaps.push_back (info);
104 | }
105 |
106 | std::vector result;
107 |
108 | for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i)
109 | {
110 | MemoryTypeInfo typeInfo;
111 |
112 | typeInfo.deviceLocal = (memoryProperties.memoryTypes [i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0;
113 | typeInfo.hostVisible = (memoryProperties.memoryTypes [i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0;
114 | typeInfo.hostCoherent = (memoryProperties.memoryTypes [i].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0;
115 | typeInfo.hostCached = (memoryProperties.memoryTypes [i].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) != 0;
116 | typeInfo.lazilyAllocated = (memoryProperties.memoryTypes [i].propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) != 0;
117 |
118 | typeInfo.heap = heaps [memoryProperties.memoryTypes [i].heapIndex];
119 |
120 | typeInfo.index = static_cast (i);
121 |
122 | result.push_back (typeInfo);
123 | }
124 |
125 | return result;
126 | }
127 |
128 | ///////////////////////////////////////////////////////////////////////////////
129 | VkDeviceMemory AllocateMemory (const std::vector& memoryInfos,
130 | VkDevice device, const int size, bool* isHostCoherent = nullptr)
131 | {
132 | // We take the first HOST_VISIBLE memory
133 | for (auto& memoryInfo : memoryInfos)
134 | {
135 | if (memoryInfo.hostVisible)
136 | {
137 | VkMemoryAllocateInfo memoryAllocateInfo = {};
138 | memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
139 | memoryAllocateInfo.memoryTypeIndex = memoryInfo.index;
140 | memoryAllocateInfo.allocationSize = size;
141 |
142 | VkDeviceMemory deviceMemory;
143 | vkAllocateMemory (device, &memoryAllocateInfo, nullptr,
144 | &deviceMemory);
145 |
146 | if (isHostCoherent)
147 | {
148 | *isHostCoherent = memoryInfo.hostCoherent;
149 | }
150 |
151 | return deviceMemory;
152 | }
153 | }
154 |
155 | return VK_NULL_HANDLE;
156 | }
157 |
158 | ///////////////////////////////////////////////////////////////////////////////
159 | VkBuffer AllocateBuffer (VkDevice device, const int size,
160 | const VkBufferUsageFlagBits bits)
161 | {
162 | VkBufferCreateInfo bufferCreateInfo = {};
163 | bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
164 | bufferCreateInfo.size = static_cast (size);
165 | bufferCreateInfo.usage = bits;
166 |
167 | VkBuffer result;
168 | vkCreateBuffer (device, &bufferCreateInfo, nullptr, &result);
169 | return result;
170 | }
171 |
172 | ///////////////////////////////////////////////////////////////////////////////
173 | VkPipelineLayout CreatePipelineLayout (VkDevice device)
174 | {
175 | VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {};
176 | pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
177 |
178 | VkPipelineLayout result;
179 | vkCreatePipelineLayout (device, &pipelineLayoutCreateInfo, nullptr,
180 | &result);
181 |
182 | return result;
183 | }
184 |
185 | ///////////////////////////////////////////////////////////////////////////////
186 | VkShaderModule LoadShader (VkDevice device, const void* shaderContents,
187 | const size_t size)
188 | {
189 | VkShaderModuleCreateInfo shaderModuleCreateInfo = {};
190 | shaderModuleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
191 |
192 | shaderModuleCreateInfo.pCode = static_cast (shaderContents);
193 | shaderModuleCreateInfo.codeSize = size;
194 |
195 | VkShaderModule result;
196 | vkCreateShaderModule (device, &shaderModuleCreateInfo, nullptr, &result);
197 |
198 | return result;
199 | }
200 |
201 | ///////////////////////////////////////////////////////////////////////////////
202 | VkPipeline CreatePipeline (VkDevice device, VkRenderPass renderPass, VkPipelineLayout layout,
203 | VkShaderModule vertexShader, VkShaderModule fragmentShader,
204 | VkExtent2D viewportSize)
205 | {
206 | VkVertexInputBindingDescription vertexInputBindingDescription;
207 | vertexInputBindingDescription.binding = 0;
208 | vertexInputBindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
209 | vertexInputBindingDescription.stride = sizeof (float) * 5;
210 |
211 | VkVertexInputAttributeDescription vertexInputAttributeDescription [2] = {};
212 | vertexInputAttributeDescription [0].binding = vertexInputBindingDescription.binding;
213 | vertexInputAttributeDescription [0].format = VK_FORMAT_R32G32B32_SFLOAT;
214 | vertexInputAttributeDescription [0].location = 0;
215 | vertexInputAttributeDescription [0].offset = 0;
216 |
217 | vertexInputAttributeDescription [1].binding = vertexInputBindingDescription.binding;
218 | vertexInputAttributeDescription [1].format = VK_FORMAT_R32G32_SFLOAT;
219 | vertexInputAttributeDescription [1].location = 1;
220 | vertexInputAttributeDescription [1].offset = sizeof (float) * 3;
221 |
222 | VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo = {};
223 | pipelineVertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
224 | pipelineVertexInputStateCreateInfo.vertexAttributeDescriptionCount = std::extent::value;
225 | pipelineVertexInputStateCreateInfo.pVertexAttributeDescriptions = vertexInputAttributeDescription;
226 | pipelineVertexInputStateCreateInfo.vertexBindingDescriptionCount = 1;
227 | pipelineVertexInputStateCreateInfo.pVertexBindingDescriptions = &vertexInputBindingDescription;
228 |
229 | VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateCreateInfo = {};
230 | pipelineInputAssemblyStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
231 | pipelineInputAssemblyStateCreateInfo.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
232 |
233 | VkPipelineViewportStateCreateInfo pipelineViewportStateCreateInfo = {};
234 | pipelineViewportStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
235 |
236 | VkViewport viewport;
237 | viewport.height = static_cast (viewportSize.height);
238 | viewport.width = static_cast (viewportSize.width);
239 | viewport.x = 0;
240 | viewport.y = 0;
241 | viewport.minDepth = 0;
242 | viewport.maxDepth = 1;
243 |
244 | pipelineViewportStateCreateInfo.viewportCount = 1;
245 | pipelineViewportStateCreateInfo.pViewports = &viewport;
246 |
247 | VkRect2D rect;
248 | rect.extent = viewportSize;
249 | rect.offset.x = 0;
250 | rect.offset.y = 0;
251 |
252 | pipelineViewportStateCreateInfo.scissorCount = 1;
253 | pipelineViewportStateCreateInfo.pScissors = ▭
254 |
255 | VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState = {};
256 | pipelineColorBlendAttachmentState.colorWriteMask = 0xF;
257 | pipelineColorBlendAttachmentState.blendEnable = VK_FALSE;
258 |
259 | VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateCreateInfo = {};
260 | pipelineColorBlendStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
261 |
262 | pipelineColorBlendStateCreateInfo.attachmentCount = 1;
263 | pipelineColorBlendStateCreateInfo.pAttachments = &pipelineColorBlendAttachmentState;
264 |
265 | VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateCreateInfo = {};
266 | pipelineRasterizationStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
267 | pipelineRasterizationStateCreateInfo.polygonMode = VK_POLYGON_MODE_FILL;
268 | pipelineRasterizationStateCreateInfo.cullMode = VK_CULL_MODE_NONE;
269 | pipelineRasterizationStateCreateInfo.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
270 | pipelineRasterizationStateCreateInfo.depthClampEnable = VK_FALSE;
271 | pipelineRasterizationStateCreateInfo.rasterizerDiscardEnable = VK_FALSE;
272 | pipelineRasterizationStateCreateInfo.depthBiasEnable = VK_FALSE;
273 | pipelineRasterizationStateCreateInfo.lineWidth = 1.0f;
274 |
275 | VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateCreateInfo = {};
276 | pipelineDepthStencilStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
277 | pipelineDepthStencilStateCreateInfo.depthTestEnable = VK_FALSE;
278 | pipelineDepthStencilStateCreateInfo.depthWriteEnable = VK_FALSE;
279 | pipelineDepthStencilStateCreateInfo.depthCompareOp = VK_COMPARE_OP_ALWAYS;
280 | pipelineDepthStencilStateCreateInfo.depthBoundsTestEnable = VK_FALSE;
281 | pipelineDepthStencilStateCreateInfo.back.failOp = VK_STENCIL_OP_KEEP;
282 | pipelineDepthStencilStateCreateInfo.back.passOp = VK_STENCIL_OP_KEEP;
283 | pipelineDepthStencilStateCreateInfo.back.compareOp = VK_COMPARE_OP_ALWAYS;
284 | pipelineDepthStencilStateCreateInfo.stencilTestEnable = VK_FALSE;
285 | pipelineDepthStencilStateCreateInfo.front = pipelineDepthStencilStateCreateInfo.back;
286 |
287 | VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo = {};
288 | pipelineMultisampleStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
289 | pipelineMultisampleStateCreateInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
290 |
291 | VkPipelineShaderStageCreateInfo pipelineShaderStageCreateInfos [2] = {};
292 | pipelineShaderStageCreateInfos [0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
293 | pipelineShaderStageCreateInfos [0].module = vertexShader;
294 | pipelineShaderStageCreateInfos [0].pName = "main";
295 | pipelineShaderStageCreateInfos [0].stage = VK_SHADER_STAGE_VERTEX_BIT;
296 |
297 | pipelineShaderStageCreateInfos [1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
298 | pipelineShaderStageCreateInfos [1].module = fragmentShader;
299 | pipelineShaderStageCreateInfos [1].pName = "main";
300 | pipelineShaderStageCreateInfos [1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
301 |
302 | VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = {};
303 | graphicsPipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
304 |
305 | graphicsPipelineCreateInfo.layout = layout;
306 | graphicsPipelineCreateInfo.pVertexInputState = &pipelineVertexInputStateCreateInfo;
307 | graphicsPipelineCreateInfo.pInputAssemblyState = &pipelineInputAssemblyStateCreateInfo;
308 | graphicsPipelineCreateInfo.renderPass = renderPass;
309 | graphicsPipelineCreateInfo.pViewportState = &pipelineViewportStateCreateInfo;
310 | graphicsPipelineCreateInfo.pColorBlendState = &pipelineColorBlendStateCreateInfo;
311 | graphicsPipelineCreateInfo.pRasterizationState = &pipelineRasterizationStateCreateInfo;
312 | graphicsPipelineCreateInfo.pDepthStencilState = &pipelineDepthStencilStateCreateInfo;
313 | graphicsPipelineCreateInfo.pMultisampleState = &pipelineMultisampleStateCreateInfo;
314 | graphicsPipelineCreateInfo.pStages = pipelineShaderStageCreateInfos;
315 | graphicsPipelineCreateInfo.stageCount = 2;
316 |
317 | VkPipeline pipeline;
318 | vkCreateGraphicsPipelines (device, VK_NULL_HANDLE, 1, &graphicsPipelineCreateInfo,
319 | nullptr, &pipeline);
320 |
321 | return pipeline;
322 | }
323 | }
324 |
325 | ///////////////////////////////////////////////////////////////////////////////
326 | void VulkanQuad::CreateMeshBuffers (VkCommandBuffer /*uploadCommandBuffer*/)
327 | {
328 | struct Vertex
329 | {
330 | float position[3];
331 | float uv[2];
332 | };
333 |
334 | static const Vertex vertices[4] = {
335 | // Upper Left
336 | { { -1.0f, 1.0f, 0 }, { 0, 0 } },
337 | // Upper Right
338 | { { 1.0f, 1.0f, 0 }, { 1, 0 } },
339 | // Bottom right
340 | { { 1.0f, -1.0f, 0 }, { 1, 1 } },
341 | // Bottom left
342 | { { -1.0f, -1.0f, 0 }, { 0, 1 } }
343 | };
344 |
345 | static const int indices[6] = {
346 | 0, 1, 2, 2, 3, 0
347 | };
348 |
349 | auto memoryHeaps = EnumerateHeaps (physicalDevice_);
350 | indexBuffer_ = AllocateBuffer(device_, sizeof(indices),
351 | VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
352 | vertexBuffer_ = AllocateBuffer (device_, sizeof (vertices),
353 | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
354 | VkMemoryRequirements vertexBufferMemoryRequirements = {};
355 | vkGetBufferMemoryRequirements(device_, vertexBuffer_,
356 | &vertexBufferMemoryRequirements);
357 | VkMemoryRequirements indexBufferMemoryRequirements = {};
358 | vkGetBufferMemoryRequirements(device_, indexBuffer_,
359 | &indexBufferMemoryRequirements);
360 |
361 | VkDeviceSize bufferSize = vertexBufferMemoryRequirements.size;
362 | // We want to place the index buffer behind the vertex buffer. Need to take
363 | // the alignment into account to find the next suitable location
364 | VkDeviceSize indexBufferOffset = RoundToNextMultiple(bufferSize,
365 | indexBufferMemoryRequirements.alignment);
366 |
367 | bufferSize = indexBufferOffset + indexBufferMemoryRequirements.size;
368 | bool memoryIsHostCoherent = false;
369 | deviceMemory_ = AllocateMemory(memoryHeaps, device_,
370 | static_cast(bufferSize), &memoryIsHostCoherent);
371 |
372 | vkBindBufferMemory (device_, vertexBuffer_, deviceMemory_, 0);
373 | vkBindBufferMemory (device_, indexBuffer_, deviceMemory_,
374 | indexBufferOffset);
375 |
376 | void* mapping = nullptr;
377 | vkMapMemory (device_, deviceMemory_, 0, VK_WHOLE_SIZE,
378 | 0, &mapping);
379 | ::memcpy (mapping, vertices, sizeof (vertices));
380 |
381 | ::memcpy (static_cast (mapping) + indexBufferOffset,
382 | indices, sizeof (indices));
383 |
384 | if (!memoryIsHostCoherent)
385 | {
386 | VkMappedMemoryRange mappedMemoryRange = {};
387 | mappedMemoryRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
388 | mappedMemoryRange.memory = deviceMemory_;
389 | mappedMemoryRange.offset = 0;
390 | mappedMemoryRange.size = VK_WHOLE_SIZE;
391 |
392 | vkFlushMappedMemoryRanges (device_, 1, &mappedMemoryRange);
393 | }
394 |
395 | vkUnmapMemory (device_, deviceMemory_);
396 | }
397 |
398 | ///////////////////////////////////////////////////////////////////////////////
399 | void VulkanQuad::CreatePipelineStateObject ()
400 | {
401 | vertexShader_ = LoadShader (device_, BasicVertexShader, sizeof (BasicVertexShader));
402 | fragmentShader_ = LoadShader (device_, BasicFragmentShader, sizeof (BasicFragmentShader));
403 |
404 | pipelineLayout_ = CreatePipelineLayout (device_);
405 | VkExtent2D extent = {
406 | static_cast (window_->GetWidth ()),
407 | static_cast (window_->GetHeight ())
408 | };
409 | pipeline_ = CreatePipeline(device_, renderPass_, pipelineLayout_,
410 | vertexShader_, fragmentShader_, extent);
411 | }
412 | }
413 |
--------------------------------------------------------------------------------
/hellovulkan/src/VulkanQuad.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #ifndef AMD_VULKAN_SAMPLE_QUAD_H_
24 | #define AMD_VULKAN_SAMPLE_QUAD_H_
25 |
26 | #include "VulkanSample.h"
27 |
28 | namespace AMD
29 | {
30 | class VulkanQuad : public VulkanSample
31 | {
32 | private:
33 | void CreatePipelineStateObject ();
34 | void CreateMeshBuffers (VkCommandBuffer uploadCommandList);
35 | void RenderImpl (VkCommandBuffer commandList) override;
36 | void InitializeImpl (VkCommandBuffer uploadCommandList) override;
37 | void ShutdownImpl () override;
38 |
39 | VkDeviceMemory deviceMemory_ = VK_NULL_HANDLE;
40 | VkBuffer vertexBuffer_ = VK_NULL_HANDLE;
41 | VkBuffer indexBuffer_ = VK_NULL_HANDLE;
42 |
43 | VkShaderModule vertexShader_ = VK_NULL_HANDLE;
44 | VkShaderModule fragmentShader_ = VK_NULL_HANDLE;
45 |
46 | VkPipeline pipeline_ = VK_NULL_HANDLE;
47 | VkPipelineLayout pipelineLayout_ = VK_NULL_HANDLE;
48 | };
49 | }
50 |
51 | #endif
52 |
--------------------------------------------------------------------------------
/hellovulkan/src/VulkanSample.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #include "VulkanSample.h"
24 |
25 | #include
26 | #include
27 |
28 | #include "Utility.h"
29 | #include "Window.h"
30 |
31 | #include
32 |
33 | #ifdef max
34 | #undef max
35 | #endif
36 |
37 | #ifdef min
38 | #undef min
39 | #endif
40 |
41 | #pragma warning( disable : 4100 ) // disable unreferenced formal parameter warnings
42 |
43 | namespace AMD
44 | {
45 | struct VulkanSample::ImportTable
46 | {
47 | #define GET_INSTANCE_ENTRYPOINT(i, w) w = reinterpret_cast(vkGetInstanceProcAddr(i, #w))
48 | #define GET_DEVICE_ENTRYPOINT(i, w) w = reinterpret_cast(vkGetDeviceProcAddr(i, #w))
49 |
50 | ImportTable() = default;
51 |
52 | ImportTable(VkInstance instance, VkDevice device)
53 | {
54 | #ifdef _DEBUG
55 | GET_INSTANCE_ENTRYPOINT(instance, vkCreateDebugReportCallbackEXT);
56 | GET_INSTANCE_ENTRYPOINT(instance, vkDebugReportMessageEXT);
57 | GET_INSTANCE_ENTRYPOINT(instance, vkDestroyDebugReportCallbackEXT);
58 | #endif
59 | }
60 |
61 | #undef GET_INSTANCE_ENTRYPOINT
62 | #undef GET_DEVICE_ENTRYPOINT
63 |
64 | #ifdef _DEBUG
65 | PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = nullptr;
66 | PFN_vkDebugReportMessageEXT vkDebugReportMessageEXT = nullptr;
67 | PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT = nullptr;
68 | #endif
69 | };
70 |
71 | namespace
72 | {
73 | ///////////////////////////////////////////////////////////////////////////////
74 | VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback(
75 | VkDebugReportFlagsEXT /*flags*/,
76 | VkDebugReportObjectTypeEXT /*objectType*/,
77 | uint64_t /*object*/,
78 | size_t /*location*/,
79 | int32_t /*messageCode*/,
80 | const char* /*pLayerPrefix*/,
81 | const char* pMessage,
82 | void* /*pUserData*/)
83 | {
84 | OutputDebugStringA(pMessage);
85 | OutputDebugStringA("\n");
86 | return VK_FALSE;
87 | }
88 |
89 | ///////////////////////////////////////////////////////////////////////////////
90 | std::vector GetDebugInstanceLayerNames()
91 | {
92 | uint32_t layerCount = 0;
93 | vkEnumerateInstanceLayerProperties(&layerCount,
94 | nullptr);
95 |
96 | std::vector instanceLayers{ layerCount };
97 | vkEnumerateInstanceLayerProperties(&layerCount,
98 | instanceLayers.data());
99 |
100 | std::vector result;
101 | for (const auto& p : instanceLayers)
102 | {
103 | if (strcmp(p.layerName, "VK_LAYER_LUNARG_standard_validation") == 0)
104 | {
105 | result.push_back("VK_LAYER_LUNARG_standard_validation");
106 | }
107 | }
108 |
109 | return result;
110 | }
111 |
112 | ///////////////////////////////////////////////////////////////////////////////
113 | std::vector GetDebugInstanceExtensionNames()
114 | {
115 | uint32_t extensionCount = 0;
116 | vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount,
117 | nullptr);
118 |
119 | std::vector instanceExtensions{ extensionCount };
120 | vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount,
121 | instanceExtensions.data());
122 |
123 | std::vector result;
124 | for (const auto& e : instanceExtensions)
125 | {
126 | if (strcmp(e.extensionName, "VK_EXT_debug_report") == 0)
127 | {
128 | result.push_back("VK_EXT_debug_report");
129 | }
130 | }
131 |
132 | return result;
133 | }
134 |
135 | ///////////////////////////////////////////////////////////////////////////////
136 | std::vector GetDebugDeviceLayerNames(VkPhysicalDevice device)
137 | {
138 | uint32_t layerCount = 0;
139 | vkEnumerateDeviceLayerProperties(device, &layerCount, nullptr);
140 |
141 | std::vector deviceLayers{ layerCount };
142 | vkEnumerateDeviceLayerProperties(device, &layerCount, deviceLayers.data());
143 |
144 | std::vector result;
145 | for (const auto& p : deviceLayers)
146 | {
147 | if (strcmp(p.layerName, "VK_LAYER_LUNARG_standard_validation") == 0)
148 | {
149 | result.push_back("VK_LAYER_LUNARG_standard_validation");
150 | }
151 | }
152 |
153 | return result;
154 | }
155 |
156 | ///////////////////////////////////////////////////////////////////////////////
157 | void FindPhysicalDeviceWithGraphicsQueue(const std::vector& physicalDevices,
158 | VkPhysicalDevice* outputDevice, int* outputGraphicsQueueIndex)
159 | {
160 | for (auto physicalDevice : physicalDevices)
161 | {
162 | uint32_t queueFamilyPropertyCount = 0;
163 |
164 | vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice,
165 | &queueFamilyPropertyCount, nullptr);
166 |
167 | std::vector queueFamilyProperties{ queueFamilyPropertyCount };
168 | vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice,
169 | &queueFamilyPropertyCount, queueFamilyProperties.data());
170 |
171 | int i = 0;
172 | for (const auto& queueFamilyProperty : queueFamilyProperties)
173 | {
174 | if (queueFamilyProperty.queueFlags & VK_QUEUE_GRAPHICS_BIT)
175 | {
176 | if (outputDevice)
177 | {
178 | *outputDevice = physicalDevice;
179 | }
180 |
181 | if (outputGraphicsQueueIndex)
182 | {
183 | *outputGraphicsQueueIndex = i;
184 | }
185 |
186 | return;
187 | }
188 |
189 | ++i;
190 | }
191 | }
192 | }
193 |
194 | ///////////////////////////////////////////////////////////////////////////////
195 | VkInstance CreateInstance()
196 | {
197 | VkInstanceCreateInfo instanceCreateInfo = {};
198 | instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
199 |
200 | std::vector instanceExtensions =
201 | {
202 | "VK_KHR_surface", "VK_KHR_win32_surface"
203 | };
204 |
205 | #ifdef _DEBUG
206 | auto debugInstanceExtensionNames = GetDebugInstanceExtensionNames();
207 | instanceExtensions.insert(instanceExtensions.end(),
208 | debugInstanceExtensionNames.begin(), debugInstanceExtensionNames.end());
209 | #endif
210 |
211 | instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.data();
212 | instanceCreateInfo.enabledExtensionCount = static_cast (instanceExtensions.size());
213 |
214 | std::vector instanceLayers;
215 |
216 | #ifdef _DEBUG
217 | auto debugInstanceLayerNames = GetDebugInstanceLayerNames();
218 | instanceLayers.insert(instanceLayers.end(),
219 | debugInstanceLayerNames.begin(), debugInstanceLayerNames.end());
220 | #endif
221 |
222 | instanceCreateInfo.ppEnabledLayerNames = instanceLayers.data();
223 | instanceCreateInfo.enabledLayerCount = static_cast (instanceLayers.size());
224 |
225 | VkApplicationInfo applicationInfo = {};
226 | applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
227 | applicationInfo.apiVersion = VK_API_VERSION_1_0;
228 | applicationInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
229 | applicationInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
230 | applicationInfo.pApplicationName = "AMD Vulkan Sample application";
231 | applicationInfo.pEngineName = "AMD Vulkan Sample Engine";
232 |
233 | instanceCreateInfo.pApplicationInfo = &applicationInfo;
234 |
235 | VkInstance instance = VK_NULL_HANDLE;
236 | vkCreateInstance(&instanceCreateInfo, nullptr, &instance);
237 |
238 | return instance;
239 | }
240 |
241 | ///////////////////////////////////////////////////////////////////////////////
242 | void CreateDeviceAndQueue(VkInstance instance, VkDevice* outputDevice,
243 | VkQueue* outputQueue, int* outputQueueIndex,
244 | VkPhysicalDevice* outputPhysicalDevice)
245 | {
246 | uint32_t physicalDeviceCount = 0;
247 | vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr);
248 |
249 | std::vector devices{ physicalDeviceCount };
250 | vkEnumeratePhysicalDevices(instance, &physicalDeviceCount,
251 | devices.data());
252 |
253 | VkPhysicalDevice physicalDevice = nullptr;
254 | int graphicsQueueIndex = -1;
255 |
256 | FindPhysicalDeviceWithGraphicsQueue(devices, &physicalDevice, &graphicsQueueIndex);
257 |
258 | assert(physicalDevice);
259 |
260 | VkDeviceQueueCreateInfo deviceQueueCreateInfo = {};
261 | deviceQueueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
262 | deviceQueueCreateInfo.queueCount = 1;
263 | deviceQueueCreateInfo.queueFamilyIndex = graphicsQueueIndex;
264 |
265 | static const float queuePriorities[] = { 1.0f };
266 | deviceQueueCreateInfo.pQueuePriorities = queuePriorities;
267 |
268 | VkDeviceCreateInfo deviceCreateInfo = {};
269 | deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
270 | deviceCreateInfo.queueCreateInfoCount = 1;
271 | deviceCreateInfo.pQueueCreateInfos = &deviceQueueCreateInfo;
272 |
273 | std::vector deviceLayers;
274 |
275 | #ifdef _DEBUG
276 | auto debugDeviceLayerNames = GetDebugDeviceLayerNames(physicalDevice);
277 | deviceLayers.insert(deviceLayers.end(),
278 | debugDeviceLayerNames.begin(), debugDeviceLayerNames.end());
279 | #endif
280 |
281 | deviceCreateInfo.ppEnabledLayerNames = deviceLayers.data();
282 | deviceCreateInfo.enabledLayerCount = static_cast (deviceLayers.size());
283 |
284 | // Our SPIR-V requests this, so we need to enable it here
285 | VkPhysicalDeviceFeatures enabledFeatures = {};
286 | enabledFeatures.shaderClipDistance = true;
287 |
288 | deviceCreateInfo.pEnabledFeatures = &enabledFeatures;
289 |
290 | std::vector deviceExtensions =
291 | {
292 | "VK_KHR_swapchain"
293 | };
294 |
295 | deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
296 | deviceCreateInfo.enabledExtensionCount = static_cast (deviceExtensions.size());
297 |
298 | VkDevice device = nullptr;
299 | vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device);
300 | assert(device);
301 |
302 | VkQueue queue = nullptr;
303 | vkGetDeviceQueue(device, graphicsQueueIndex, 0, &queue);
304 | assert(queue);
305 |
306 | if (outputQueue)
307 | {
308 | *outputQueue = queue;
309 | }
310 |
311 | if (outputDevice)
312 | {
313 | *outputDevice = device;
314 | }
315 |
316 | if (outputQueueIndex)
317 | {
318 | *outputQueueIndex = graphicsQueueIndex;
319 | }
320 |
321 | if (outputPhysicalDevice)
322 | {
323 | *outputPhysicalDevice = physicalDevice;
324 | }
325 | }
326 |
327 | struct SwapchainFormatColorSpace
328 | {
329 | VkFormat format;
330 | VkColorSpaceKHR colorSpace;
331 | };
332 |
333 | ///////////////////////////////////////////////////////////////////////////////
334 | SwapchainFormatColorSpace GetSwapchainFormatAndColorspace(VkPhysicalDevice physicalDevice,
335 | VkSurfaceKHR surface, VulkanSample::ImportTable* importTable)
336 | {
337 | uint32_t surfaceFormatCount = 0;
338 | vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice,
339 | surface, &surfaceFormatCount, nullptr);
340 |
341 | std::vector surfaceFormats{ surfaceFormatCount };
342 | vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice,
343 | surface, &surfaceFormatCount, surfaceFormats.data());
344 |
345 | SwapchainFormatColorSpace result;
346 |
347 | if (surfaceFormatCount == 1 && surfaceFormats.front().format == VK_FORMAT_UNDEFINED)
348 | {
349 | result.format = VK_FORMAT_R8G8B8A8_UNORM;
350 | }
351 | else
352 | {
353 | result.format = surfaceFormats.front().format;
354 | }
355 |
356 | result.colorSpace = surfaceFormats.front().colorSpace;
357 |
358 | return result;
359 | }
360 |
361 | ///////////////////////////////////////////////////////////////////////////////
362 | VkRenderPass CreateRenderPass(VkDevice device, VkFormat swapchainFormat)
363 | {
364 | VkAttachmentDescription attachmentDescription = {};
365 | attachmentDescription.samples = VK_SAMPLE_COUNT_1_BIT;
366 | attachmentDescription.format = swapchainFormat;
367 | attachmentDescription.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
368 | attachmentDescription.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
369 | attachmentDescription.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
370 | attachmentDescription.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
371 | attachmentDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
372 | attachmentDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
373 |
374 | VkAttachmentReference attachmentReference = {};
375 | attachmentReference.attachment = 0;
376 | attachmentReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
377 |
378 | VkSubpassDescription subpassDescription = {};
379 | subpassDescription.inputAttachmentCount = 0;
380 | subpassDescription.pColorAttachments = &attachmentReference;
381 | subpassDescription.colorAttachmentCount = 1;
382 | subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
383 |
384 | VkRenderPassCreateInfo renderPassCreateInfo = {};
385 | renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
386 | renderPassCreateInfo.attachmentCount = 1;
387 | renderPassCreateInfo.subpassCount = 1;
388 | renderPassCreateInfo.pSubpasses = &subpassDescription;
389 | renderPassCreateInfo.pAttachments = &attachmentDescription;
390 |
391 | VkRenderPass result = nullptr;
392 | vkCreateRenderPass(device, &renderPassCreateInfo, nullptr,
393 | &result);
394 |
395 | return result;
396 | }
397 |
398 | ///////////////////////////////////////////////////////////////////////////////
399 | void CreateFramebuffers(VkDevice device, VkRenderPass renderPass,
400 | const int width, const int height,
401 | const int count, const VkImageView* imageViews, VkFramebuffer* framebuffers)
402 | {
403 | for (int i = 0; i < count; ++i)
404 | {
405 | VkFramebufferCreateInfo framebufferCreateInfo = {};
406 | framebufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
407 | framebufferCreateInfo.attachmentCount = 1;
408 | framebufferCreateInfo.pAttachments = &imageViews[i];
409 | framebufferCreateInfo.height = height;
410 | framebufferCreateInfo.width = width;
411 | framebufferCreateInfo.layers = 1;
412 | framebufferCreateInfo.renderPass = renderPass;
413 |
414 | vkCreateFramebuffer(device, &framebufferCreateInfo, nullptr,
415 | &framebuffers[i]);
416 | }
417 | }
418 |
419 | ///////////////////////////////////////////////////////////////////////////////
420 | void CreateSwapchainImageViews(VkDevice device, VkFormat format,
421 | const int count, const VkImage* images, VkImageView* imageViews)
422 | {
423 | for (int i = 0; i < count; ++i)
424 | {
425 | VkImageViewCreateInfo imageViewCreateInfo = {};
426 | imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
427 | imageViewCreateInfo.image = images[i];
428 | imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
429 | imageViewCreateInfo.format = format;
430 | imageViewCreateInfo.subresourceRange.levelCount = 1;
431 | imageViewCreateInfo.subresourceRange.layerCount = 1;
432 | imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
433 |
434 | vkCreateImageView(device, &imageViewCreateInfo, nullptr,
435 | &imageViews[i]);
436 | }
437 | }
438 |
439 | ///////////////////////////////////////////////////////////////////////////////
440 | VkSwapchainKHR CreateSwapchain(VkPhysicalDevice physicalDevice, VkDevice device,
441 | VkSurfaceKHR surface, const int surfaceWidth, const int surfaceHeight,
442 | const int backbufferCount, VulkanSample::ImportTable* importTable,
443 | VkFormat* swapchainFormat)
444 | {
445 | VkSurfaceCapabilitiesKHR surfaceCapabilities;
446 | vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice,
447 | surface, &surfaceCapabilities);
448 |
449 | uint32_t presentModeCount;
450 | vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice,
451 | surface, &presentModeCount, nullptr);
452 |
453 | std::vector presentModes{ presentModeCount };
454 |
455 | vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice,
456 | surface, &presentModeCount, presentModes.data());
457 |
458 | VkExtent2D swapChainSize = {};
459 | swapChainSize = surfaceCapabilities.currentExtent;
460 | assert(static_cast (swapChainSize.width) == surfaceWidth);
461 | assert(static_cast (swapChainSize.height) == surfaceHeight);
462 |
463 | uint32_t swapChainImageCount = backbufferCount;
464 | assert(swapChainImageCount >= surfaceCapabilities.minImageCount);
465 |
466 | // 0 indicates unlimited number of images
467 | if (surfaceCapabilities.maxImageCount != 0)
468 | {
469 | assert(swapChainImageCount < surfaceCapabilities.maxImageCount);
470 | }
471 |
472 | VkSurfaceTransformFlagBitsKHR surfaceTransformFlags;
473 |
474 | if (surfaceCapabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR)
475 | {
476 | surfaceTransformFlags = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
477 | }
478 | else
479 | {
480 | surfaceTransformFlags = surfaceCapabilities.currentTransform;
481 | }
482 |
483 | auto swapchainFormatColorSpace = GetSwapchainFormatAndColorspace(physicalDevice, surface,
484 | importTable);
485 |
486 | VkSwapchainCreateInfoKHR swapchainCreateInfo = {};
487 | swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
488 | swapchainCreateInfo.surface = surface;
489 | swapchainCreateInfo.minImageCount = swapChainImageCount;
490 | swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
491 | swapchainCreateInfo.preTransform = surfaceTransformFlags;
492 | swapchainCreateInfo.imageColorSpace = swapchainFormatColorSpace.colorSpace;
493 | swapchainCreateInfo.imageFormat = swapchainFormatColorSpace.format;
494 | swapchainCreateInfo.pQueueFamilyIndices = nullptr;
495 | swapchainCreateInfo.queueFamilyIndexCount = 0;
496 | swapchainCreateInfo.clipped = VK_TRUE;
497 | swapchainCreateInfo.oldSwapchain = VK_NULL_HANDLE;
498 | swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
499 | swapchainCreateInfo.imageExtent = swapChainSize;
500 | swapchainCreateInfo.imageArrayLayers = 1;
501 | swapchainCreateInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;
502 |
503 | VkSwapchainKHR swapchain;
504 | vkCreateSwapchainKHR(device, &swapchainCreateInfo,
505 | nullptr, &swapchain);
506 |
507 | if (swapchainFormat)
508 | {
509 | *swapchainFormat = swapchainFormatColorSpace.format;
510 | }
511 |
512 | return swapchain;
513 | }
514 |
515 | ///////////////////////////////////////////////////////////////////////////////
516 | VkSurfaceKHR CreateSurface(VkInstance instance, HWND hwnd)
517 | {
518 | VkWin32SurfaceCreateInfoKHR win32surfaceCreateInfo = {};
519 | win32surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
520 | win32surfaceCreateInfo.hwnd = hwnd;
521 | win32surfaceCreateInfo.hinstance = ::GetModuleHandle(nullptr);
522 |
523 | VkSurfaceKHR surface = nullptr;
524 | vkCreateWin32SurfaceKHR(instance, &win32surfaceCreateInfo, nullptr,
525 | &surface);
526 |
527 | return surface;
528 | }
529 |
530 | #ifdef _DEBUG
531 | ///////////////////////////////////////////////////////////////////////////////
532 | VkDebugReportCallbackEXT SetupDebugCallback(VkInstance instance, VulkanSample::ImportTable* importTable)
533 | {
534 | if (importTable->vkCreateDebugReportCallbackEXT)
535 | {
536 | VkDebugReportCallbackCreateInfoEXT callbackCreateInfo = {};
537 | callbackCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
538 | callbackCreateInfo.flags =
539 | VK_DEBUG_REPORT_ERROR_BIT_EXT |
540 | VK_DEBUG_REPORT_WARNING_BIT_EXT |
541 | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
542 | callbackCreateInfo.pfnCallback = &DebugReportCallback;
543 |
544 | VkDebugReportCallbackEXT callback;
545 | importTable->vkCreateDebugReportCallbackEXT(instance, &callbackCreateInfo, nullptr, &callback);
546 | return callback;
547 | }
548 | else
549 | {
550 | return VK_NULL_HANDLE;
551 | }
552 | }
553 |
554 | ///////////////////////////////////////////////////////////////////////////////
555 | void CleanupDebugCallback(VkInstance instance, VkDebugReportCallbackEXT callback,
556 | VulkanSample::ImportTable* importTable)
557 | {
558 | if (importTable->vkDestroyDebugReportCallbackEXT)
559 | {
560 | importTable->vkDestroyDebugReportCallbackEXT(instance, callback, nullptr);
561 | }
562 | }
563 | #endif
564 |
565 | } // namespace
566 |
567 | ///////////////////////////////////////////////////////////////////////////////
568 | VulkanSample::VulkanSample()
569 | {
570 | instance_ = CreateInstance();
571 | if (instance_ == VK_NULL_HANDLE)
572 | {
573 | // just bail out if the user does not have a compatible Vulkan driver
574 | return;
575 | }
576 |
577 | VkPhysicalDevice physicalDevice;
578 | CreateDeviceAndQueue(instance_, &device_, &queue_, &queueFamilyIndex_,
579 | &physicalDevice);
580 | physicalDevice_ = physicalDevice;
581 |
582 | importTable_.reset(new ImportTable{ instance_, device_ });
583 |
584 | #ifdef _DEBUG
585 | debugCallback_ = SetupDebugCallback(instance_, importTable_.get());
586 | #endif
587 |
588 | window_.reset(new Window{ "Hello Vulkan", 1280, 720 });
589 |
590 | surface_ = CreateSurface(instance_, window_->GetHWND());
591 |
592 | VkBool32 presentSupported;
593 | vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice,
594 | 0, surface_, &presentSupported);
595 | assert(presentSupported);
596 |
597 | VkFormat swapchainFormat = VK_FORMAT_UNDEFINED;
598 | swapchain_ = CreateSwapchain(physicalDevice, device_, surface_,
599 | window_->GetWidth(), window_->GetHeight(), QUEUE_SLOT_COUNT,
600 | importTable_.get(), &swapchainFormat);
601 |
602 | assert(swapchain_);
603 |
604 | uint32_t swapchainImageCount = 0;
605 | vkGetSwapchainImagesKHR(device_, swapchain_,
606 | &swapchainImageCount, nullptr);
607 | assert(static_cast (swapchainImageCount) == QUEUE_SLOT_COUNT);
608 |
609 | vkGetSwapchainImagesKHR(device_, swapchain_,
610 | &swapchainImageCount, swapchainImages_);
611 |
612 | renderPass_ = CreateRenderPass(device_, swapchainFormat);
613 |
614 | CreateSwapchainImageViews(device_, swapchainFormat,
615 | QUEUE_SLOT_COUNT, swapchainImages_, swapChainImageViews_);
616 | CreateFramebuffers(device_, renderPass_, window_->GetWidth(), window_->GetHeight(),
617 | QUEUE_SLOT_COUNT, swapChainImageViews_, framebuffer_);
618 |
619 | VkCommandPoolCreateInfo commandPoolCreateInfo = {};
620 | commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
621 | commandPoolCreateInfo.queueFamilyIndex = queueFamilyIndex_;
622 | commandPoolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
623 |
624 | vkCreateCommandPool(device_, &commandPoolCreateInfo, nullptr,
625 | &commandPool_);
626 |
627 | VkCommandBufferAllocateInfo commandBufferAllocateInfo = {};
628 | commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
629 | commandBufferAllocateInfo.commandBufferCount = QUEUE_SLOT_COUNT + 1;
630 | commandBufferAllocateInfo.commandPool = commandPool_;
631 | commandBufferAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
632 |
633 | VkCommandBuffer commandBuffers[QUEUE_SLOT_COUNT + 1];
634 |
635 | vkAllocateCommandBuffers(device_, &commandBufferAllocateInfo,
636 | commandBuffers);
637 |
638 | for (int i = 0; i < QUEUE_SLOT_COUNT; ++i)
639 | {
640 | commandBuffers_[i] = commandBuffers[i];
641 | }
642 |
643 | setupCommandBuffer_ = commandBuffers[QUEUE_SLOT_COUNT];
644 |
645 | for (int i = 0; i < QUEUE_SLOT_COUNT; ++i)
646 | {
647 | VkFenceCreateInfo fenceCreateInfo = {};
648 | fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
649 | // We need this so we can wait for them on the first try
650 | fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
651 |
652 | vkCreateFence(device_, &fenceCreateInfo, nullptr, &frameFences_[i]);
653 | }
654 | }
655 |
656 | ///////////////////////////////////////////////////////////////////////////////
657 | VulkanSample::~VulkanSample()
658 | {
659 | }
660 |
661 | ///////////////////////////////////////////////////////////////////////////////
662 | void VulkanSample::ShutdownImpl()
663 | {
664 | for (int i = 0; i < QUEUE_SLOT_COUNT; ++i)
665 | {
666 | vkDestroyFence(device_, frameFences_[i], nullptr);
667 | }
668 |
669 | vkDestroyRenderPass(device_, renderPass_, nullptr);
670 |
671 | for (int i = 0; i < QUEUE_SLOT_COUNT; ++i)
672 | {
673 | vkDestroyFramebuffer(device_, framebuffer_[i], nullptr);
674 | vkDestroyImageView(device_, swapChainImageViews_[i], nullptr);
675 | }
676 |
677 | vkDestroyCommandPool(device_, commandPool_, nullptr);
678 |
679 | vkDestroySwapchainKHR(device_, swapchain_, nullptr);
680 | vkDestroySurfaceKHR(instance_, surface_, nullptr);
681 |
682 | #ifdef _DEBUG
683 | CleanupDebugCallback(instance_, debugCallback_, importTable_.get());
684 | #endif
685 |
686 | vkDestroyDevice(device_, nullptr);
687 | vkDestroyInstance(instance_, nullptr);
688 | }
689 |
690 | ///////////////////////////////////////////////////////////////////////////////
691 | void VulkanSample::Run(const int frameCount)
692 | {
693 | if (IsInitialized() == false)
694 | {
695 | // just bail out if the user does not have a compatible Vulkan driver
696 | return;
697 | }
698 |
699 | vkResetFences(device_, 1, &frameFences_[0]);
700 | {
701 | VkCommandBufferBeginInfo beginInfo = {};
702 | beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
703 |
704 | vkBeginCommandBuffer(setupCommandBuffer_, &beginInfo);
705 |
706 | InitializeImpl(setupCommandBuffer_);
707 |
708 | vkEndCommandBuffer(setupCommandBuffer_);
709 |
710 | VkSubmitInfo submitInfo = {};
711 | submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
712 | submitInfo.commandBufferCount = 1;
713 | submitInfo.pCommandBuffers = &setupCommandBuffer_;
714 | vkQueueSubmit(queue_, 1, &submitInfo, frameFences_[0]);
715 | }
716 |
717 | vkWaitForFences(device_, 1, &frameFences_[0], VK_TRUE, UINT64_MAX);
718 |
719 | VkSemaphoreCreateInfo semaphoreCreateInfo = {};
720 | semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
721 |
722 | VkSemaphore imageAcquiredSemaphore;
723 | vkCreateSemaphore(device_, &semaphoreCreateInfo,
724 | nullptr, &imageAcquiredSemaphore);
725 |
726 | VkSemaphore renderingCompleteSemaphore;
727 | vkCreateSemaphore(device_, &semaphoreCreateInfo,
728 | nullptr, &renderingCompleteSemaphore);
729 |
730 | for (int i = 0; i < frameCount; ++i)
731 | {
732 | vkAcquireNextImageKHR(
733 | device_, swapchain_, UINT64_MAX, imageAcquiredSemaphore,
734 | VK_NULL_HANDLE, ¤tBackBuffer_);
735 |
736 | vkWaitForFences(device_, 1, &frameFences_[currentBackBuffer_], VK_TRUE,
737 | UINT64_MAX);
738 | vkResetFences(device_, 1, &frameFences_[currentBackBuffer_]);
739 |
740 | VkCommandBufferBeginInfo beginInfo = {};
741 | beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
742 |
743 | vkBeginCommandBuffer(commandBuffers_[currentBackBuffer_], &beginInfo);
744 |
745 | VkRenderPassBeginInfo renderPassBeginInfo = {};
746 | renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
747 | renderPassBeginInfo.framebuffer = framebuffer_[currentBackBuffer_];
748 | renderPassBeginInfo.renderArea.extent.width = window_->GetWidth();
749 | renderPassBeginInfo.renderArea.extent.height = window_->GetHeight();
750 | renderPassBeginInfo.renderPass = renderPass_;
751 |
752 | VkClearValue clearValue = {};
753 |
754 | clearValue.color.float32[0] = 0.042f;
755 | clearValue.color.float32[1] = 0.042f;
756 | clearValue.color.float32[2] = 0.042f;
757 | clearValue.color.float32[3] = 1.0f;
758 |
759 | renderPassBeginInfo.pClearValues = &clearValue;
760 | renderPassBeginInfo.clearValueCount = 1;
761 |
762 | vkCmdBeginRenderPass(commandBuffers_[currentBackBuffer_],
763 | &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
764 |
765 | RenderImpl(commandBuffers_[currentBackBuffer_]);
766 |
767 | vkCmdEndRenderPass(commandBuffers_[currentBackBuffer_]);
768 | vkEndCommandBuffer(commandBuffers_[currentBackBuffer_]);
769 |
770 | // Submit rendering work to the graphics queue
771 | const VkPipelineStageFlags waitDstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
772 | VkSubmitInfo submitInfo = {};
773 | submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
774 | submitInfo.waitSemaphoreCount = 1;
775 | submitInfo.pWaitSemaphores = &imageAcquiredSemaphore;
776 | submitInfo.pWaitDstStageMask = &waitDstStageMask;
777 | submitInfo.commandBufferCount = 1;
778 | submitInfo.pCommandBuffers = &commandBuffers_[currentBackBuffer_];
779 | submitInfo.signalSemaphoreCount = 1;
780 | submitInfo.pSignalSemaphores = &renderingCompleteSemaphore;
781 | vkQueueSubmit(queue_, 1, &submitInfo, VK_NULL_HANDLE);
782 |
783 | // Submit present operation to present queue
784 | VkPresentInfoKHR presentInfo = {};
785 | presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
786 | presentInfo.waitSemaphoreCount = 1;
787 | presentInfo.pWaitSemaphores = &renderingCompleteSemaphore;
788 | presentInfo.swapchainCount = 1;
789 | presentInfo.pSwapchains = &swapchain_;
790 | presentInfo.pImageIndices = ¤tBackBuffer_;
791 | vkQueuePresentKHR(queue_, &presentInfo);
792 |
793 | vkQueueSubmit(queue_, 0, nullptr, frameFences_[currentBackBuffer_]);
794 | };
795 |
796 | // Wait for all rendering to finish
797 | vkWaitForFences(device_, 3, frameFences_, VK_TRUE, UINT64_MAX);
798 |
799 | vkDestroySemaphore(device_, imageAcquiredSemaphore, nullptr);
800 | vkDestroySemaphore(device_, renderingCompleteSemaphore, nullptr);
801 |
802 | ShutdownImpl();
803 | }
804 |
805 | ///////////////////////////////////////////////////////////////////////////////
806 | void VulkanSample::InitializeImpl(VkCommandBuffer /*commandBuffer*/)
807 | {
808 | }
809 |
810 | ///////////////////////////////////////////////////////////////////////////////
811 | void VulkanSample::RenderImpl(VkCommandBuffer /*commandBuffer*/)
812 | {
813 | }
814 |
815 | } // namespace AMD
816 |
--------------------------------------------------------------------------------
/hellovulkan/src/VulkanSample.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #ifndef AMD_VULKAN_SAMPLE_H_
24 | #define AMD_VULKAN_SAMPLE_H_
25 |
26 | #define VK_USE_PLATFORM_WIN32_KHR
27 | #include
28 | #include
29 |
30 | namespace AMD
31 | {
32 | class Window;
33 |
34 | ///////////////////////////////////////////////////////////////////////////////
35 | class VulkanSample
36 | {
37 | public:
38 | VulkanSample(const VulkanSample&) = delete;
39 | VulkanSample& operator= (const VulkanSample&) = delete;
40 |
41 | VulkanSample();
42 | virtual ~VulkanSample();
43 |
44 | bool IsInitialized() { return (instance_ != VK_NULL_HANDLE && device_ != VK_NULL_HANDLE); }
45 | void Run(const int frameCount);
46 | struct ImportTable;
47 |
48 | protected:
49 | int GetQueueSlot() const
50 | {
51 | return currentBackBuffer_;
52 | }
53 |
54 | static const int QUEUE_SLOT_COUNT = 3;
55 |
56 | static int GetQueueSlotCount()
57 | {
58 | return QUEUE_SLOT_COUNT;
59 | }
60 |
61 | VkViewport viewport_;
62 |
63 | VkSwapchainKHR swapchain_ = VK_NULL_HANDLE;
64 | VkInstance instance_ = VK_NULL_HANDLE;
65 | VkDevice device_ = VK_NULL_HANDLE;
66 | VkPhysicalDevice physicalDevice_ = VK_NULL_HANDLE;
67 | VkQueue queue_ = VK_NULL_HANDLE;
68 |
69 | VkSurfaceKHR surface_ = VK_NULL_HANDLE;
70 |
71 | std::unique_ptr importTable_;
72 |
73 | VkFence frameFences_[QUEUE_SLOT_COUNT];
74 | VkImage swapchainImages_[QUEUE_SLOT_COUNT];
75 | VkImageView swapChainImageViews_[QUEUE_SLOT_COUNT];
76 | VkFramebuffer framebuffer_[QUEUE_SLOT_COUNT];
77 |
78 | VkRenderPass renderPass_ = VK_NULL_HANDLE;
79 |
80 | int queueFamilyIndex_ = -1;
81 |
82 | std::unique_ptr window_;
83 |
84 | virtual void InitializeImpl(VkCommandBuffer commandBuffer);
85 | virtual void RenderImpl(VkCommandBuffer commandBuffer);
86 | virtual void ShutdownImpl();
87 |
88 | private:
89 | VkCommandPool commandPool_;
90 | VkCommandBuffer commandBuffers_[QUEUE_SLOT_COUNT];
91 | VkCommandBuffer setupCommandBuffer_;
92 | uint32_t currentBackBuffer_ = 0;
93 |
94 | #ifdef _DEBUG
95 | VkDebugReportCallbackEXT debugCallback_;
96 | #endif
97 | };
98 |
99 | } // namespace AMD
100 |
101 | #endif
102 |
--------------------------------------------------------------------------------
/hellovulkan/src/VulkanTexturedQuad.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #include "VulkanTexturedQuad.h"
24 |
25 | #include "Shaders.h"
26 | #include "Utility.h"
27 | #include "Window.h"
28 |
29 | #include "RubyTexture.h"
30 | #include "ImageIO.h"
31 |
32 | #include
33 |
34 | namespace AMD
35 | {
36 | ///////////////////////////////////////////////////////////////////////////////
37 | void VulkanTexturedQuad::ShutdownImpl()
38 | {
39 | vkDestroyPipeline(device_, pipeline_, nullptr);
40 | vkDestroyPipelineLayout(device_, pipelineLayout_, nullptr);
41 |
42 | vkDestroyBuffer(device_, vertexBuffer_, nullptr);
43 | vkDestroyBuffer(device_, indexBuffer_, nullptr);
44 | vkFreeMemory(device_, deviceBufferMemory_, nullptr);
45 |
46 | vkDestroyImageView (device_, rubyImageView_, nullptr);
47 | vkDestroyImage (device_, rubyImage_, nullptr);
48 | vkFreeMemory (device_, deviceImageMemory_, nullptr);
49 |
50 | vkDestroyBuffer (device_, uploadImageBuffer_, nullptr);
51 | vkFreeMemory (device_, uploadImageMemory_, nullptr);
52 |
53 | vkDestroyBuffer (device_, uploadBufferBuffer_, nullptr);
54 | vkFreeMemory (device_, uploadBufferMemory_, nullptr);
55 |
56 | vkDestroyDescriptorSetLayout (device_, descriptorSetLayout_, nullptr);
57 | vkDestroyDescriptorPool (device_, descriptorPool_, nullptr);
58 |
59 | vkDestroySampler (device_, sampler_, nullptr);
60 |
61 | vkDestroyShaderModule(device_, vertexShader_, nullptr);
62 | vkDestroyShaderModule(device_, fragmentShader_, nullptr);
63 |
64 | VulkanSample::ShutdownImpl();
65 | }
66 |
67 | ///////////////////////////////////////////////////////////////////////////////
68 | void VulkanTexturedQuad::RenderImpl(VkCommandBuffer commandBuffer)
69 | {
70 | VulkanSample::RenderImpl(commandBuffer);
71 |
72 | VkViewport viewports [1] = {};
73 | viewports [0].width = static_cast (window_->GetWidth ());
74 | viewports [0].height = static_cast (window_->GetHeight ());
75 | viewports [0].minDepth = 0;
76 | viewports [0].maxDepth = 1;
77 |
78 | vkCmdSetViewport (commandBuffer, 0, 1, viewports);
79 |
80 | VkRect2D scissors [1] = {};
81 | scissors [0].extent.width = window_->GetWidth ();
82 | scissors [0].extent.height = window_->GetHeight ();
83 | vkCmdSetScissor (commandBuffer, 0, 1, scissors);
84 |
85 | vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
86 | pipeline_);
87 | VkDeviceSize offsets[] = { 0 };
88 | vkCmdBindIndexBuffer(commandBuffer, indexBuffer_, 0, VK_INDEX_TYPE_UINT32);
89 | vkCmdBindVertexBuffers(commandBuffer, 0, 1, &vertexBuffer_, offsets);
90 |
91 | vkCmdBindDescriptorSets (commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
92 | pipelineLayout_, 0, 1, &descriptorSet_, 0, nullptr);
93 |
94 | vkCmdDrawIndexed(commandBuffer, 6, 1, 0, 0, 0);
95 | }
96 |
97 | ///////////////////////////////////////////////////////////////////////////////
98 | void VulkanTexturedQuad::InitializeImpl(VkCommandBuffer uploadCommandBuffer)
99 | {
100 | VulkanSample::InitializeImpl(uploadCommandBuffer);
101 |
102 | CreateSampler ();
103 | CreateTexture (uploadCommandBuffer);
104 | CreateDescriptors ();
105 | CreatePipelineStateObject();
106 | CreateMeshBuffers(uploadCommandBuffer);
107 | }
108 |
109 | namespace
110 | {
111 | struct MemoryTypeInfo
112 | {
113 | bool deviceLocal = false;
114 | bool hostVisible = false;
115 | bool hostCoherent = false;
116 | bool hostCached = false;
117 | bool lazilyAllocated = false;
118 |
119 | struct Heap
120 | {
121 | uint64_t size = 0;
122 | bool deviceLocal = false;
123 | };
124 |
125 | Heap heap;
126 | int index;
127 | };
128 |
129 | ///////////////////////////////////////////////////////////////////////////////
130 | std::vector EnumerateHeaps(VkPhysicalDevice device)
131 | {
132 | VkPhysicalDeviceMemoryProperties memoryProperties = {};
133 | vkGetPhysicalDeviceMemoryProperties(device, &memoryProperties);
134 |
135 | std::vector heaps;
136 |
137 | for (uint32_t i = 0; i < memoryProperties.memoryHeapCount; ++i)
138 | {
139 | MemoryTypeInfo::Heap info;
140 | info.size = memoryProperties.memoryHeaps[i].size;
141 | info.deviceLocal = (memoryProperties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) != 0;
142 |
143 | heaps.push_back(info);
144 | }
145 |
146 | std::vector result;
147 |
148 | for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i)
149 | {
150 | MemoryTypeInfo typeInfo;
151 |
152 | typeInfo.deviceLocal = (memoryProperties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0;
153 | typeInfo.hostVisible = (memoryProperties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0;
154 | typeInfo.hostCoherent = (memoryProperties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0;
155 | typeInfo.hostCached = (memoryProperties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) != 0;
156 | typeInfo.lazilyAllocated = (memoryProperties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) != 0;
157 |
158 | typeInfo.heap = heaps[memoryProperties.memoryTypes[i].heapIndex];
159 |
160 | typeInfo.index = static_cast (i);
161 |
162 | result.push_back(typeInfo);
163 | }
164 |
165 | return result;
166 | }
167 |
168 | enum MemoryProperties
169 | {
170 | MT_DeviceLocal = 1,
171 | MT_HostVisible = 2
172 | };
173 |
174 | ///////////////////////////////////////////////////////////////////////////////
175 | VkDeviceMemory AllocateMemory(const std::vector& memoryInfos,
176 | VkDevice device, const int size, const uint32_t memoryBits,
177 | unsigned int memoryProperties, bool* isHostCoherent = nullptr)
178 | {
179 | for (auto& memoryInfo : memoryInfos)
180 | {
181 | if (((1 << memoryInfo.index) & memoryBits) == 0) {
182 | continue;
183 | }
184 |
185 | if ((memoryProperties & MT_DeviceLocal) && !memoryInfo.deviceLocal)
186 | {
187 | continue;
188 | }
189 |
190 | if ((memoryProperties & MT_HostVisible) && !memoryInfo.hostVisible)
191 | {
192 | continue;
193 | }
194 |
195 | if (isHostCoherent)
196 | {
197 | *isHostCoherent = memoryInfo.hostCoherent;
198 | }
199 |
200 | VkMemoryAllocateInfo memoryAllocateInfo = {};
201 | memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
202 | memoryAllocateInfo.memoryTypeIndex = memoryInfo.index;
203 | memoryAllocateInfo.allocationSize = size;
204 |
205 | VkDeviceMemory deviceMemory;
206 | vkAllocateMemory(device, &memoryAllocateInfo, nullptr,
207 | &deviceMemory);
208 | return deviceMemory;
209 | }
210 |
211 | return VK_NULL_HANDLE;
212 | }
213 |
214 | ///////////////////////////////////////////////////////////////////////////////
215 | VkBuffer AllocateBuffer(VkDevice device, const int size,
216 | const VkBufferUsageFlags bits)
217 | {
218 | VkBufferCreateInfo bufferCreateInfo = {};
219 | bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
220 | bufferCreateInfo.size = static_cast (size);
221 | bufferCreateInfo.usage = bits;
222 |
223 | VkBuffer result;
224 | vkCreateBuffer(device, &bufferCreateInfo, nullptr, &result);
225 | return result;
226 | }
227 |
228 | ///////////////////////////////////////////////////////////////////////////////
229 | VkPipelineLayout CreatePipelineLayout(VkDevice device)
230 | {
231 | VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {};
232 | pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
233 |
234 | VkPipelineLayout result;
235 | vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr,
236 | &result);
237 |
238 | return result;
239 | }
240 |
241 | ///////////////////////////////////////////////////////////////////////////////
242 | VkShaderModule LoadShader(VkDevice device, const void* shaderContents,
243 | const size_t size)
244 | {
245 | VkShaderModuleCreateInfo shaderModuleCreateInfo = {};
246 | shaderModuleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
247 |
248 | shaderModuleCreateInfo.pCode = static_cast (shaderContents);
249 | shaderModuleCreateInfo.codeSize = size;
250 |
251 | VkShaderModule result;
252 | vkCreateShaderModule(device, &shaderModuleCreateInfo, nullptr, &result);
253 |
254 | return result;
255 | }
256 |
257 | ///////////////////////////////////////////////////////////////////////////////
258 | VkPipeline CreatePipeline(VkDevice device, VkRenderPass renderPass, VkPipelineLayout layout,
259 | VkShaderModule vertexShader, VkShaderModule fragmentShader)
260 | {
261 | VkVertexInputBindingDescription vertexInputBindingDescription;
262 | vertexInputBindingDescription.binding = 0;
263 | vertexInputBindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
264 | vertexInputBindingDescription.stride = sizeof(float) * 5;
265 |
266 | VkVertexInputAttributeDescription vertexInputAttributeDescription[2] = {};
267 | vertexInputAttributeDescription[0].binding = vertexInputBindingDescription.binding;
268 | vertexInputAttributeDescription[0].format = VK_FORMAT_R32G32B32_SFLOAT;
269 | vertexInputAttributeDescription[0].location = 0;
270 | vertexInputAttributeDescription[0].offset = 0;
271 |
272 | vertexInputAttributeDescription[1].binding = vertexInputBindingDescription.binding;
273 | vertexInputAttributeDescription[1].format = VK_FORMAT_R32G32_SFLOAT;
274 | vertexInputAttributeDescription[1].location = 1;
275 | vertexInputAttributeDescription[1].offset = sizeof(float) * 3;
276 |
277 | VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo = {};
278 | pipelineVertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
279 | pipelineVertexInputStateCreateInfo.vertexAttributeDescriptionCount = std::extent::value;
280 | pipelineVertexInputStateCreateInfo.pVertexAttributeDescriptions = vertexInputAttributeDescription;
281 | pipelineVertexInputStateCreateInfo.vertexBindingDescriptionCount = 1;
282 | pipelineVertexInputStateCreateInfo.pVertexBindingDescriptions = &vertexInputBindingDescription;
283 |
284 | VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateCreateInfo = {};
285 | pipelineInputAssemblyStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
286 | pipelineInputAssemblyStateCreateInfo.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
287 |
288 | VkDynamicState dynamicStates [] = {
289 | VK_DYNAMIC_STATE_VIEWPORT,
290 | VK_DYNAMIC_STATE_SCISSOR
291 | };
292 |
293 | VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = {};
294 | dynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
295 | dynamicStateCreateInfo.dynamicStateCount = 2;
296 | dynamicStateCreateInfo.pDynamicStates = dynamicStates;
297 |
298 | VkPipelineViewportStateCreateInfo pipelineViewportStateCreateInfo = {};
299 | pipelineViewportStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
300 | pipelineViewportStateCreateInfo.viewportCount = 1;
301 | pipelineViewportStateCreateInfo.scissorCount = 1;
302 |
303 | VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState = {};
304 | pipelineColorBlendAttachmentState.colorWriteMask = 0xF;
305 | pipelineColorBlendAttachmentState.blendEnable = VK_FALSE;
306 |
307 | VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateCreateInfo = {};
308 | pipelineColorBlendStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
309 |
310 | pipelineColorBlendStateCreateInfo.attachmentCount = 1;
311 | pipelineColorBlendStateCreateInfo.pAttachments = &pipelineColorBlendAttachmentState;
312 |
313 | VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateCreateInfo = {};
314 | pipelineRasterizationStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
315 | pipelineRasterizationStateCreateInfo.polygonMode = VK_POLYGON_MODE_FILL;
316 | pipelineRasterizationStateCreateInfo.cullMode = VK_CULL_MODE_NONE;
317 | pipelineRasterizationStateCreateInfo.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
318 | pipelineRasterizationStateCreateInfo.depthClampEnable = VK_FALSE;
319 | pipelineRasterizationStateCreateInfo.rasterizerDiscardEnable = VK_FALSE;
320 | pipelineRasterizationStateCreateInfo.depthBiasEnable = VK_FALSE;
321 | pipelineRasterizationStateCreateInfo.lineWidth = 1.0f;
322 |
323 | VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateCreateInfo = {};
324 | pipelineDepthStencilStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
325 | pipelineDepthStencilStateCreateInfo.depthTestEnable = VK_FALSE;
326 | pipelineDepthStencilStateCreateInfo.depthWriteEnable = VK_FALSE;
327 | pipelineDepthStencilStateCreateInfo.depthCompareOp = VK_COMPARE_OP_ALWAYS;
328 | pipelineDepthStencilStateCreateInfo.depthBoundsTestEnable = VK_FALSE;
329 | pipelineDepthStencilStateCreateInfo.back.failOp = VK_STENCIL_OP_KEEP;
330 | pipelineDepthStencilStateCreateInfo.back.passOp = VK_STENCIL_OP_KEEP;
331 | pipelineDepthStencilStateCreateInfo.back.compareOp = VK_COMPARE_OP_ALWAYS;
332 | pipelineDepthStencilStateCreateInfo.stencilTestEnable = VK_FALSE;
333 | pipelineDepthStencilStateCreateInfo.front = pipelineDepthStencilStateCreateInfo.back;
334 |
335 | VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo = {};
336 | pipelineMultisampleStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
337 | pipelineMultisampleStateCreateInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
338 |
339 | VkPipelineShaderStageCreateInfo pipelineShaderStageCreateInfos[2] = {};
340 | pipelineShaderStageCreateInfos[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
341 | pipelineShaderStageCreateInfos[0].module = vertexShader;
342 | pipelineShaderStageCreateInfos[0].pName = "main";
343 | pipelineShaderStageCreateInfos[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
344 |
345 | pipelineShaderStageCreateInfos[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
346 | pipelineShaderStageCreateInfos[1].module = fragmentShader;
347 | pipelineShaderStageCreateInfos[1].pName = "main";
348 | pipelineShaderStageCreateInfos[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
349 |
350 | VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = {};
351 | graphicsPipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
352 |
353 | graphicsPipelineCreateInfo.layout = layout;
354 | graphicsPipelineCreateInfo.pVertexInputState = &pipelineVertexInputStateCreateInfo;
355 | graphicsPipelineCreateInfo.pInputAssemblyState = &pipelineInputAssemblyStateCreateInfo;
356 | graphicsPipelineCreateInfo.renderPass = renderPass;
357 | graphicsPipelineCreateInfo.pViewportState = &pipelineViewportStateCreateInfo;
358 | graphicsPipelineCreateInfo.pColorBlendState = &pipelineColorBlendStateCreateInfo;
359 | graphicsPipelineCreateInfo.pRasterizationState = &pipelineRasterizationStateCreateInfo;
360 | graphicsPipelineCreateInfo.pDepthStencilState = &pipelineDepthStencilStateCreateInfo;
361 | graphicsPipelineCreateInfo.pMultisampleState = &pipelineMultisampleStateCreateInfo;
362 | graphicsPipelineCreateInfo.pDynamicState = &dynamicStateCreateInfo;
363 | graphicsPipelineCreateInfo.pStages = pipelineShaderStageCreateInfos;
364 | graphicsPipelineCreateInfo.stageCount = 2;
365 |
366 | VkPipeline pipeline;
367 | vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &graphicsPipelineCreateInfo,
368 | nullptr, &pipeline);
369 |
370 | return pipeline;
371 | }
372 | } // namespace
373 |
374 | ///////////////////////////////////////////////////////////////////////////////
375 | void VulkanTexturedQuad::CreateMeshBuffers(VkCommandBuffer uploadCommandBuffer)
376 | {
377 | struct Vertex
378 | {
379 | float position[3];
380 | float uv[2];
381 | };
382 |
383 | static const Vertex vertices[4] =
384 | {
385 | // Upper Left
386 | { { -1.0f, 1.0f, 0 }, { 0, 1 } },
387 | // Upper Right
388 | { { 1.0f, 1.0f, 0 }, { 1, 1 } },
389 | // Bottom right
390 | { { 1.0f, -1.0f, 0 }, { 1, 0 } },
391 | // Bottom left
392 | { { -1.0f, -1.0f, 0 }, { 0, 0 } }
393 | };
394 |
395 | static const int indices[6] =
396 | {
397 | 0, 1, 2, 2, 3, 0
398 | };
399 |
400 | auto memoryHeaps = EnumerateHeaps(physicalDevice_);
401 |
402 | indexBuffer_ = AllocateBuffer(device_, sizeof(indices),
403 | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
404 | vertexBuffer_ = AllocateBuffer(device_, sizeof(vertices),
405 | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
406 |
407 | VkMemoryRequirements vertexBufferMemoryRequirements = {};
408 | vkGetBufferMemoryRequirements(device_, vertexBuffer_,
409 | &vertexBufferMemoryRequirements);
410 | VkMemoryRequirements indexBufferMemoryRequirements = {};
411 | vkGetBufferMemoryRequirements(device_, indexBuffer_,
412 | &indexBufferMemoryRequirements);
413 |
414 | VkDeviceSize bufferSize = vertexBufferMemoryRequirements.size;
415 | // We want to place the index buffer behind the vertex buffer. Need to take
416 | // the alignment into account to find the next suitable location
417 | VkDeviceSize indexBufferOffset = RoundToNextMultiple(bufferSize,
418 | indexBufferMemoryRequirements.alignment);
419 |
420 | bufferSize = indexBufferOffset + indexBufferMemoryRequirements.size;
421 | deviceBufferMemory_ = AllocateMemory(memoryHeaps, device_,
422 | static_cast(bufferSize),
423 | vertexBufferMemoryRequirements.memoryTypeBits & indexBufferMemoryRequirements.memoryTypeBits,
424 | MT_DeviceLocal);
425 |
426 | vkBindBufferMemory(device_, vertexBuffer_, deviceBufferMemory_, 0);
427 | vkBindBufferMemory(device_, indexBuffer_, deviceBufferMemory_,
428 | indexBufferOffset);
429 |
430 | uploadBufferBuffer_ = AllocateBuffer (device_, static_cast (bufferSize),
431 | VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
432 | VkMemoryRequirements uploadBufferMemoryRequirements = {};
433 | vkGetBufferMemoryRequirements (device_, uploadBufferBuffer_,
434 | &uploadBufferMemoryRequirements);
435 |
436 | bool memoryIsHostCoherent = false;
437 | uploadBufferMemory_ = AllocateMemory(memoryHeaps, device_,
438 | static_cast(uploadBufferMemoryRequirements.size),
439 | vertexBufferMemoryRequirements.memoryTypeBits & indexBufferMemoryRequirements.memoryTypeBits,
440 | MT_HostVisible, &memoryIsHostCoherent);
441 |
442 | vkBindBufferMemory (device_, uploadBufferBuffer_, uploadBufferMemory_, 0);
443 |
444 | void* mapping = nullptr;
445 | vkMapMemory(device_, uploadBufferMemory_, 0, VK_WHOLE_SIZE,
446 | 0, &mapping);
447 | ::memcpy(mapping, vertices, sizeof(vertices));
448 |
449 | ::memcpy(static_cast (mapping) + indexBufferOffset,
450 | indices, sizeof(indices));
451 |
452 | if (!memoryIsHostCoherent)
453 | {
454 | VkMappedMemoryRange mappedMemoryRange = {};
455 | mappedMemoryRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
456 | mappedMemoryRange.memory = uploadBufferMemory_;
457 | mappedMemoryRange.offset = 0;
458 | mappedMemoryRange.size = VK_WHOLE_SIZE;
459 |
460 | vkFlushMappedMemoryRanges (device_, 1, &mappedMemoryRange);
461 | }
462 |
463 | vkUnmapMemory(device_, uploadBufferMemory_);
464 |
465 | VkBufferCopy vertexCopy = {};
466 | vertexCopy.size = sizeof (vertices);
467 |
468 | VkBufferCopy indexCopy = {};
469 | indexCopy.size = sizeof (indices);
470 | indexCopy.srcOffset = indexBufferOffset;
471 |
472 | vkCmdCopyBuffer (uploadCommandBuffer, uploadBufferBuffer_, vertexBuffer_,
473 | 1, &vertexCopy);
474 | vkCmdCopyBuffer (uploadCommandBuffer, uploadBufferBuffer_, indexBuffer_,
475 | 1, &indexCopy);
476 |
477 | VkBufferMemoryBarrier uploadBarriers[2] = {};
478 | uploadBarriers[0].sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
479 | uploadBarriers[0].buffer = vertexBuffer_;
480 | uploadBarriers[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
481 | uploadBarriers[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
482 | uploadBarriers[0].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
483 | uploadBarriers[0].dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
484 | uploadBarriers[0].size = VK_WHOLE_SIZE;
485 |
486 | uploadBarriers[1].sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
487 | uploadBarriers[1].buffer = indexBuffer_;
488 | uploadBarriers[1].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
489 | uploadBarriers[1].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
490 | uploadBarriers[1].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
491 | uploadBarriers[1].dstAccessMask = VK_ACCESS_INDEX_READ_BIT;
492 | uploadBarriers[1].size = VK_WHOLE_SIZE;
493 |
494 | vkCmdPipelineBarrier (uploadCommandBuffer,
495 | VK_PIPELINE_STAGE_TRANSFER_BIT,
496 | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
497 | 0, 0, nullptr, 2, uploadBarriers,
498 | 0, nullptr);
499 | }
500 |
501 | ///////////////////////////////////////////////////////////////////////////////
502 | void VulkanTexturedQuad::CreateTexture (VkCommandBuffer uploadCommandList)
503 | {
504 | int width, height;
505 | auto image = LoadImageFromMemory (RubyTexture, sizeof (RubyTexture),
506 | 1, &width, &height);
507 |
508 | VkImageCreateInfo imageCreateInfo = {};
509 | imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
510 | imageCreateInfo.pNext = nullptr;
511 | imageCreateInfo.queueFamilyIndexCount = 1;
512 | uint32_t queueFamilyIndex = static_cast (queueFamilyIndex_);
513 | imageCreateInfo.pQueueFamilyIndices = &queueFamilyIndex;
514 | imageCreateInfo.mipLevels = 1;
515 | imageCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
516 | imageCreateInfo.arrayLayers = 1;
517 | imageCreateInfo.extent.depth = 1;
518 | imageCreateInfo.extent.height = height;
519 | imageCreateInfo.extent.width = width;
520 | imageCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
521 | imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
522 | imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
523 | imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
524 | imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
525 |
526 | vkCreateImage (device_, &imageCreateInfo, nullptr, &rubyImage_);
527 |
528 | VkMemoryRequirements requirements = {};
529 | vkGetImageMemoryRequirements (device_, rubyImage_,
530 | &requirements);
531 |
532 | VkDeviceSize requiredSizeForImage = requirements.size;
533 |
534 | auto memoryHeaps = EnumerateHeaps (physicalDevice_);
535 | deviceImageMemory_ = AllocateMemory (memoryHeaps, device_, static_cast (requiredSizeForImage),
536 | requirements.memoryTypeBits,
537 | MT_DeviceLocal);
538 |
539 | vkBindImageMemory (device_, rubyImage_, deviceImageMemory_, 0);
540 |
541 | VkBufferCreateInfo bufferCreateInfo = {};
542 | bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
543 | bufferCreateInfo.pNext = nullptr;
544 | bufferCreateInfo.queueFamilyIndexCount = 1;
545 | bufferCreateInfo.pQueueFamilyIndices = &queueFamilyIndex;
546 | bufferCreateInfo.size = requiredSizeForImage;
547 | bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
548 |
549 | vkCreateBuffer (device_, &bufferCreateInfo, nullptr, &uploadImageBuffer_);
550 |
551 | vkGetBufferMemoryRequirements (device_, uploadImageBuffer_, &requirements);
552 |
553 | VkDeviceSize requiredSizeForBuffer = requirements.size;
554 |
555 | bool memoryIsHostCoherent = false;
556 | uploadImageMemory_ = AllocateMemory (memoryHeaps, device_,
557 | static_cast (requiredSizeForBuffer), requirements.memoryTypeBits,
558 | MT_HostVisible, &memoryIsHostCoherent);
559 |
560 | vkBindBufferMemory (device_, uploadImageBuffer_, uploadImageMemory_, 0);
561 |
562 | void* data = nullptr;
563 | vkMapMemory (device_, uploadImageMemory_, 0, VK_WHOLE_SIZE,
564 | 0, &data);
565 | ::memcpy (data, image.data (), image.size ());
566 |
567 | if (!memoryIsHostCoherent)
568 | {
569 | VkMappedMemoryRange mappedMemoryRange = {};
570 | mappedMemoryRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
571 | mappedMemoryRange.memory = uploadImageMemory_;
572 | mappedMemoryRange.offset = 0;
573 | mappedMemoryRange.size = VK_WHOLE_SIZE;
574 |
575 | vkFlushMappedMemoryRanges (device_, 1, &mappedMemoryRange);
576 | }
577 |
578 | vkUnmapMemory (device_, uploadImageMemory_);
579 |
580 | VkBufferImageCopy bufferImageCopy = {};
581 | bufferImageCopy.imageExtent.width = width;
582 | bufferImageCopy.imageExtent.height = height;
583 | bufferImageCopy.imageExtent.depth = 1;
584 | bufferImageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
585 | bufferImageCopy.imageSubresource.mipLevel = 0;
586 | bufferImageCopy.imageSubresource.layerCount = 1;
587 |
588 | VkImageMemoryBarrier imageBarrier = {};
589 | imageBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
590 | imageBarrier.pNext = nullptr;
591 | imageBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
592 | imageBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
593 | imageBarrier.srcAccessMask = 0;
594 | imageBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
595 | imageBarrier.image = rubyImage_;
596 | imageBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
597 | imageBarrier.subresourceRange.layerCount = 1;
598 | imageBarrier.subresourceRange.levelCount = 1;
599 |
600 | vkCmdPipelineBarrier (uploadCommandList,
601 | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
602 | VK_PIPELINE_STAGE_TRANSFER_BIT,
603 | 0, 0, nullptr, 0, nullptr,
604 | 1, &imageBarrier);
605 |
606 | vkCmdCopyBufferToImage (uploadCommandList, uploadImageBuffer_,
607 | rubyImage_, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
608 | 1, &bufferImageCopy);
609 |
610 | imageBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
611 | imageBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
612 | imageBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
613 | imageBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
614 |
615 | vkCmdPipelineBarrier (uploadCommandList,
616 | VK_PIPELINE_STAGE_TRANSFER_BIT,
617 | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
618 | 0, 0, nullptr, 0, nullptr,
619 | 1, &imageBarrier);
620 |
621 | VkImageViewCreateInfo imageViewCreateInfo = {};
622 | imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
623 | imageViewCreateInfo.format = imageCreateInfo.format;
624 | imageViewCreateInfo.image = rubyImage_;
625 | imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
626 | imageViewCreateInfo.subresourceRange.levelCount = 1;
627 | imageViewCreateInfo.subresourceRange.layerCount = 1;
628 | imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
629 |
630 | vkCreateImageView (device_, &imageViewCreateInfo, nullptr, &rubyImageView_);
631 | }
632 |
633 | ///////////////////////////////////////////////////////////////////////////////
634 | void VulkanTexturedQuad::CreateSampler ()
635 | {
636 | VkSamplerCreateInfo samplerCreateInfo = {};
637 | samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
638 | samplerCreateInfo.magFilter = VK_FILTER_LINEAR;
639 | samplerCreateInfo.minFilter = VK_FILTER_LINEAR;
640 |
641 | vkCreateSampler (device_, &samplerCreateInfo, nullptr, &sampler_);
642 | }
643 |
644 | ///////////////////////////////////////////////////////////////////////////////
645 | void VulkanTexturedQuad::CreateDescriptors ()
646 | {
647 | VkDescriptorSetLayoutBinding descriptorSetLayoutBinding[2] = {};
648 | descriptorSetLayoutBinding[0].binding = 0;
649 | descriptorSetLayoutBinding[0].descriptorCount = 1;
650 | descriptorSetLayoutBinding[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
651 | descriptorSetLayoutBinding[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
652 | descriptorSetLayoutBinding[1].binding = 1;
653 | descriptorSetLayoutBinding[1].descriptorCount = 1;
654 | descriptorSetLayoutBinding[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
655 | descriptorSetLayoutBinding[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
656 | descriptorSetLayoutBinding[1].pImmutableSamplers = &sampler_;
657 |
658 | VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo[1] = {};
659 | descriptorSetLayoutCreateInfo[0].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
660 | descriptorSetLayoutCreateInfo[0].bindingCount = 2;
661 | descriptorSetLayoutCreateInfo[0].pBindings = descriptorSetLayoutBinding;
662 |
663 | vkCreateDescriptorSetLayout (
664 | device_, descriptorSetLayoutCreateInfo,
665 | nullptr, &descriptorSetLayout_);
666 |
667 | VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {};
668 | pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
669 | pipelineLayoutCreateInfo.pSetLayouts = &descriptorSetLayout_;
670 | pipelineLayoutCreateInfo.setLayoutCount = 1;
671 |
672 | vkCreatePipelineLayout (device_, &pipelineLayoutCreateInfo,
673 | nullptr, &pipelineLayout_);
674 |
675 | VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {};
676 | descriptorPoolCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
677 | descriptorPoolCreateInfo.maxSets = 1;
678 |
679 | VkDescriptorPoolSize descriptorPoolSize [2] = {};
680 | descriptorPoolSize[0].descriptorCount = 1;
681 | descriptorPoolSize[0].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
682 | descriptorPoolSize[1].descriptorCount = 1;
683 | descriptorPoolSize[1].type = VK_DESCRIPTOR_TYPE_SAMPLER;
684 |
685 | descriptorPoolCreateInfo.poolSizeCount = 2;
686 | descriptorPoolCreateInfo.pPoolSizes = descriptorPoolSize;
687 |
688 | vkCreateDescriptorPool (device_, &descriptorPoolCreateInfo,
689 | nullptr, &descriptorPool_);
690 |
691 | VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {};
692 | descriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
693 | descriptorSetAllocateInfo.pSetLayouts = &descriptorSetLayout_;
694 | descriptorSetAllocateInfo.descriptorSetCount = 1;
695 | descriptorSetAllocateInfo.descriptorPool = descriptorPool_;
696 |
697 | vkAllocateDescriptorSets (device_, &descriptorSetAllocateInfo, &descriptorSet_);
698 |
699 | VkWriteDescriptorSet writeDescriptorSets[1] = {};
700 | writeDescriptorSets[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
701 | writeDescriptorSets[0].dstSet = descriptorSet_;
702 | writeDescriptorSets[0].descriptorCount = 1;
703 | writeDescriptorSets[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
704 | writeDescriptorSets[0].dstBinding = 0;
705 |
706 | VkDescriptorImageInfo descriptorImageInfo[1] = {};
707 | descriptorImageInfo[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
708 | descriptorImageInfo[0].imageView = rubyImageView_;
709 |
710 | writeDescriptorSets[0].pImageInfo = &descriptorImageInfo[0];
711 |
712 | vkUpdateDescriptorSets (device_, 1, writeDescriptorSets, 0, nullptr);
713 | }
714 |
715 | ///////////////////////////////////////////////////////////////////////////////
716 | void VulkanTexturedQuad::CreatePipelineStateObject()
717 | {
718 | vertexShader_ = LoadShader(device_, BasicVertexShader, sizeof(BasicVertexShader));
719 | fragmentShader_ = LoadShader(device_, TexturedFragmentShader, sizeof(TexturedFragmentShader));
720 |
721 | pipeline_ = CreatePipeline(device_, renderPass_, pipelineLayout_,
722 | vertexShader_, fragmentShader_);
723 | }
724 | } // namespace AMD
725 |
--------------------------------------------------------------------------------
/hellovulkan/src/VulkanTexturedQuad.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #ifndef AMD_VULKAN_SAMPLE_TEXTURED_QUAD_H_
24 | #define AMD_VULKAN_SAMPLE_TEXTURED_QUAD_H_
25 |
26 | #include "VulkanSample.h"
27 |
28 | namespace AMD
29 | {
30 | class VulkanTexturedQuad : public VulkanSample
31 | {
32 | private:
33 | void CreatePipelineStateObject();
34 | void CreateMeshBuffers(VkCommandBuffer uploadCommandList);
35 | void CreateTexture(VkCommandBuffer uploadCommandList);
36 | void CreateDescriptors ();
37 | void CreateSampler ();
38 | void RenderImpl(VkCommandBuffer commandList) override;
39 | void InitializeImpl(VkCommandBuffer uploadCommandList) override;
40 | void ShutdownImpl() override;
41 |
42 | VkDeviceMemory deviceBufferMemory_ = VK_NULL_HANDLE;
43 | VkBuffer vertexBuffer_ = VK_NULL_HANDLE;
44 | VkBuffer indexBuffer_ = VK_NULL_HANDLE;
45 |
46 | VkDeviceMemory uploadBufferMemory_ = VK_NULL_HANDLE;
47 | VkBuffer uploadBufferBuffer_ = VK_NULL_HANDLE;
48 |
49 | VkShaderModule vertexShader_ = VK_NULL_HANDLE;
50 | VkShaderModule fragmentShader_ = VK_NULL_HANDLE;
51 |
52 | VkPipeline pipeline_ = VK_NULL_HANDLE;
53 | VkPipelineLayout pipelineLayout_ = VK_NULL_HANDLE;
54 |
55 | VkDeviceMemory deviceImageMemory_ = VK_NULL_HANDLE;
56 | VkImage rubyImage_ = VK_NULL_HANDLE;
57 | VkImageView rubyImageView_ = VK_NULL_HANDLE;
58 |
59 | VkDeviceMemory uploadImageMemory_ = VK_NULL_HANDLE;
60 | VkBuffer uploadImageBuffer_ = VK_NULL_HANDLE;
61 |
62 | VkDescriptorPool descriptorPool_ = VK_NULL_HANDLE;
63 | VkDescriptorSet descriptorSet_ = VK_NULL_HANDLE;
64 | VkDescriptorSetLayout descriptorSetLayout_ = VK_NULL_HANDLE;
65 |
66 | VkSampler sampler_ = VK_NULL_HANDLE;
67 | };
68 | }
69 |
70 | #endif
71 |
--------------------------------------------------------------------------------
/hellovulkan/src/Window.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #include "Window.h"
24 |
25 | namespace AMD
26 | {
27 | namespace
28 | {
29 | ///////////////////////////////////////////////////////////////////////////////
30 | LRESULT CALLBACK amdWndProc(
31 | HWND hwnd,
32 | UINT uMsg,
33 | WPARAM wParam,
34 | LPARAM lParam
35 | )
36 | {
37 | auto ptr = ::GetWindowLongPtr(hwnd, GWLP_USERDATA);
38 | auto window = reinterpret_cast (ptr);
39 |
40 | switch (uMsg)
41 | {
42 | case WM_CLOSE:
43 | window->OnClose();
44 | return 0;
45 | }
46 |
47 | return ::DefWindowProcA(hwnd, uMsg, wParam, lParam);
48 | }
49 | } // namespace
50 |
51 | ///////////////////////////////////////////////////////////////////////////////
52 | IWindow::~IWindow()
53 | {
54 | }
55 |
56 | ///////////////////////////////////////////////////////////////////////////////
57 | int IWindow::GetWidth() const
58 | {
59 | return GetWidthImpl();
60 | }
61 |
62 | ///////////////////////////////////////////////////////////////////////////////
63 | int IWindow::GetHeight() const
64 | {
65 | return GetHeightImpl();
66 | }
67 |
68 | ///////////////////////////////////////////////////////////////////////////////
69 | Window::Window(const std::string& title, const int width, const int height)
70 | : width_ (width)
71 | , height_ (height)
72 | {
73 | DWORD style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
74 |
75 | ::RECT rect;
76 | ::SetRect(&rect, 0, 0, width, height);
77 | ::AdjustWindowRect(&rect, style, FALSE);
78 |
79 | windowClass_.reset(new WindowClass("VulkanSampleWindowClass", amdWndProc));
80 |
81 | // Create the main window.
82 | hwnd_ = ::CreateWindowA(windowClass_->GetName().c_str(),
83 | title.c_str(),
84 | style, CW_USEDEFAULT, CW_USEDEFAULT,
85 | rect.right - rect.left, rect.bottom - rect.top, (HWND)NULL,
86 | (HMENU)NULL, NULL, (LPVOID)NULL);
87 |
88 | ::SetWindowLongPtr(hwnd_, GWLP_USERDATA, reinterpret_cast (this));
89 |
90 | // Show the window and paint its contents.
91 | ::ShowWindow(hwnd_, SW_SHOWDEFAULT);
92 | ::UpdateWindow(hwnd_);
93 | }
94 |
95 | ///////////////////////////////////////////////////////////////////////////////
96 | bool IWindow::IsClosed() const
97 | {
98 | return IsClosedImpl();
99 | }
100 |
101 | ///////////////////////////////////////////////////////////////////////////////
102 | HWND Window::GetHWND () const
103 | {
104 | return hwnd_;
105 | }
106 |
107 | /////////////////////////////////////////////////////////////////////////
108 | WindowClass::WindowClass(const std::string& name, ::WNDPROC procedure)
109 | : name_(name)
110 | {
111 | ::WNDCLASSA wc;
112 |
113 | // Register the window class for the main window.
114 | wc.style = 0;
115 | wc.lpfnWndProc = procedure;
116 | wc.cbClsExtra = 0;
117 | wc.cbWndExtra = 0;
118 | wc.hInstance = NULL;
119 | wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
120 | wc.hCursor = LoadCursor(NULL, IDC_ARROW);
121 | wc.hbrBackground = NULL;
122 | wc.lpszMenuName = NULL;
123 | wc.lpszClassName = name_.c_str();
124 |
125 | ::RegisterClassA(&wc);
126 | }
127 |
128 | /////////////////////////////////////////////////////////////////////////
129 | const std::string& WindowClass::GetName() const
130 | {
131 | return name_;
132 | }
133 |
134 | /////////////////////////////////////////////////////////////////////////
135 | WindowClass::~WindowClass()
136 | {
137 | ::UnregisterClassA(name_.c_str(),
138 | (HINSTANCE)::GetModuleHandle(NULL));
139 | }
140 |
141 | } // namespace AMD
142 |
--------------------------------------------------------------------------------
/hellovulkan/src/Window.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #ifndef AMD_VULKAN_SAMPLE_WINDOW_H_
24 | #define AMD_VULKAN_SAMPLE_WINDOW_H_
25 |
26 | #include
27 | #include
28 | #include
29 |
30 | namespace AMD
31 | {
32 | /**
33 | * Encapsulate a window class.
34 | *
35 | * Calls ::RegisterClass() on create, and ::UnregisterClass()
36 | * on destruction.
37 | */
38 | struct WindowClass final
39 | {
40 | public:
41 | WindowClass(const std::string& name,
42 | ::WNDPROC procedure = ::DefWindowProc);
43 | ~WindowClass();
44 |
45 | const std::string& GetName() const;
46 |
47 | WindowClass(const WindowClass&) = delete;
48 | WindowClass& operator= (const WindowClass&) = delete;
49 |
50 | private:
51 | std::string name_;
52 | };
53 |
54 | struct IWindow
55 | {
56 | public:
57 | IWindow() = default;
58 | IWindow(const IWindow&) = delete;
59 | IWindow& operator=(const IWindow&) = delete;
60 |
61 | virtual ~IWindow();
62 |
63 | bool IsClosed() const;
64 | virtual void OnClose() = 0;
65 |
66 | int GetWidth() const;
67 | int GetHeight() const;
68 |
69 | private:
70 | virtual bool IsClosedImpl() const = 0;
71 | virtual int GetWidthImpl() const = 0;
72 | virtual int GetHeightImpl() const = 0;
73 | };
74 |
75 | class Window : public IWindow
76 | {
77 | public:
78 | Window(const std::string& title, int width, int height);
79 |
80 | HWND GetHWND() const;
81 |
82 | void OnClose() override
83 | {
84 | isClosed_ = true;
85 | }
86 |
87 | private:
88 | bool IsClosedImpl() const override
89 | {
90 | return isClosed_;
91 | }
92 |
93 | int GetWidthImpl() const override
94 | {
95 | return width_;
96 | }
97 |
98 | int GetHeightImpl() const override
99 | {
100 | return height_;
101 | }
102 |
103 | std::unique_ptr windowClass_;
104 | HWND hwnd_ = 0;
105 | bool isClosed_ = false;
106 | int width_ = -1, height_ = -1;
107 | };
108 |
109 | } // namespace AMD
110 |
111 | #endif
112 |
--------------------------------------------------------------------------------
/hellovulkan/src/basic.frag:
--------------------------------------------------------------------------------
1 | #version 400
2 | #extension GL_ARB_separate_shader_objects : enable
3 | #extension GL_ARB_shading_language_420pack : enable
4 | layout (location = 0) in vec2 uv;
5 | layout (location = 0) out vec4 outputColor;
6 |
7 | void main() {
8 | outputColor = vec4 (uv,0,1);
9 | }
10 |
--------------------------------------------------------------------------------
/hellovulkan/src/basic.spv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GPUOpen-LibrariesAndSDKs/HelloVulkan/2575360ce8cf0393d5797fc80ca4b749a1b01d08/hellovulkan/src/basic.spv
--------------------------------------------------------------------------------
/hellovulkan/src/textured.frag:
--------------------------------------------------------------------------------
1 | #version 400
2 | #extension GL_ARB_separate_shader_objects : enable
3 | #extension GL_ARB_shading_language_420pack : enable
4 | layout (location = 0) in vec2 uv;
5 | layout (location = 0) out vec4 outputColor;
6 |
7 | layout (binding = 0) uniform texture2D colorTexture;
8 | layout (binding = 1) uniform sampler colorSampler;
9 |
10 | void main() {
11 | outputColor = texture (sampler2D (colorTexture, colorSampler), uv);
12 | }
13 |
--------------------------------------------------------------------------------
/hellovulkan/src/textured.spv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GPUOpen-LibrariesAndSDKs/HelloVulkan/2575360ce8cf0393d5797fc80ca4b749a1b01d08/hellovulkan/src/textured.spv
--------------------------------------------------------------------------------
/hellovulkan/src/tri.vert:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #version 400
24 | #extension GL_ARB_separate_shader_objects : enable
25 | #extension GL_ARB_shading_language_420pack : enable
26 | layout (location = 0) in vec3 pos;
27 | layout (location = 1) in vec2 inUv;
28 | layout (location = 0) out vec2 outUv;
29 |
30 | out gl_PerVertex {
31 | vec4 gl_Position;
32 | };
33 |
34 | void main() {
35 | gl_Position = vec4(pos,1);
36 | outUv = inUv;
37 | }
38 |
--------------------------------------------------------------------------------
/hellovulkan/src/vs.spv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GPUOpen-LibrariesAndSDKs/HelloVulkan/2575360ce8cf0393d5797fc80ca4b749a1b01d08/hellovulkan/src/vs.spv
--------------------------------------------------------------------------------
/hellovulkan/tools/binaryToHeader.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 | import os
3 | import sys
4 |
5 | def BinaryToHeader (binary, variablename):
6 | bytesPerLine = 80 // 6
7 | print ('const unsigned char {} [] = {{'.format (variablename))
8 |
9 | for i in range (0, len (binary), bytesPerLine):
10 | print ('\t', end='')
11 | # This will automatically cut off at the end
12 | bytesForLine = binary [i:i+bytesPerLine]
13 | for byte in bytesForLine:
14 | print ('{0:4}, '.format (hex (byte)), end='')
15 | print ()
16 | print ('};')
17 |
18 | if __name__=='__main__':
19 | BinaryToHeader (open (sys.argv[1], 'rb').read (), sys.argv[2])
20 |
--------------------------------------------------------------------------------
/hellovulkan/tools/sourceToHeader.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 | def escape(line):
4 | line = line.replace ('"', '\\"')
5 | line = line.replace ('\n', '\\n')
6 | return line
7 |
8 | if __name__=='__main__':
9 | print ('const char {}[] = '.format (sys.argv[2]))
10 | for l in open(sys.argv[1], 'r').readlines():
11 | print ('"{}"'.format (escape (l)))
12 | print (';')
13 |
--------------------------------------------------------------------------------
/premake/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2003-2015 Jason Perkins and individual contributors.
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice,
8 | this list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | 3. Neither the name of Premake nor the names of its contributors may be
15 | used to endorse or promote products derived from this software without
16 | specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/premake/amd_premake_util.lua:
--------------------------------------------------------------------------------
1 | -- amd_premake_util.lua
2 | -- utility code shared by AMD build scripts
3 |
4 | -- _ACTION is a premake global variable and for our usage will be vs2012, vs2013, etc.
5 | -- Strip "vs" from this string to make a suffix for solution and project files.
6 | _AMD_VS_SUFFIX = "_" .. string.gsub(_ACTION, "vs", "")
7 |
8 | -- Specify build output directory structure here: e.g. Desktop_2012\x64\DLL_Debug
9 | _AMD_SAMPLE_DIR_LAYOUT = "Desktop%{_AMD_VS_SUFFIX}/%{cfg.platform}/%{cfg.buildcfg}"
10 |
11 | -- Specify WindowsTargetPlatformVersion here for VS2015
12 | _AMD_WIN_SDK_VERSION = "8.1"
13 |
14 |
--------------------------------------------------------------------------------
/premake/premake5.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GPUOpen-LibrariesAndSDKs/HelloVulkan/2575360ce8cf0393d5797fc80ca4b749a1b01d08/premake/premake5.exe
--------------------------------------------------------------------------------