Initial vulkan context and immediate drawer.

Extremely rough, just checking in so DrChat can snoop.
This commit is contained in:
Ben Vanik 2016-02-17 17:42:25 -08:00
parent d52d2c4837
commit 9f52f2e819
64 changed files with 24379 additions and 935 deletions

View File

@ -169,6 +169,7 @@ solution("xenia")
include("third_party/libav.lua") include("third_party/libav.lua")
include("third_party/snappy.lua") include("third_party/snappy.lua")
include("third_party/spirv-tools.lua") include("third_party/spirv-tools.lua")
include("third_party/vulkan/loader")
include("third_party/xxhash.lua") include("third_party/xxhash.lua")
include("third_party/yaml-cpp.lua") include("third_party/yaml-cpp.lua")
@ -188,6 +189,7 @@ solution("xenia")
include("src/xenia/ui") include("src/xenia/ui")
include("src/xenia/ui/gl") include("src/xenia/ui/gl")
include("src/xenia/ui/spirv") include("src/xenia/ui/spirv")
include("src/xenia/ui/vulkan")
include("src/xenia/vfs") include("src/xenia/vfs")
if os.is("windows") then if os.is("windows") then

View File

@ -24,7 +24,7 @@ void SpirvShaderTranslator::StartTranslation() {
auto fn = e.MakeMainEntry(); auto fn = e.MakeMainEntry();
auto float_1_0 = e.MakeFloatConstant(1.0f); auto float_1_0 = e.MakeFloatConstant(1.0f);
auto acos = e.CreateGlslStd450InstructionCall( auto acos = e.CreateGlslStd450InstructionCall(
spv::Decoration::Invariant, e.MakeFloatType(32), spv::GLSLstd450::Acos, spv::Decoration::Invariant, e.MakeFloatType(32), spv::GLSLstd450::kAcos,
{float_1_0}); {float_1_0});
e.MakeReturn(true); e.MakeReturn(true);
} }
@ -188,7 +188,7 @@ spv::Id SpirvShaderTranslator::LoadFromOperand(const InstructionOperand& op) {
if (op.is_absolute_value) { if (op.is_absolute_value) {
current_value_id = e.CreateGlslStd450InstructionCall( current_value_id = e.CreateGlslStd450InstructionCall(
spv::Decoration::RelaxedPrecision, current_type_id, spv::Decoration::RelaxedPrecision, current_type_id,
spv::GLSLstd450::FAbs, {current_value_id}); spv::GLSLstd450::kFAbs, {current_value_id});
} }
if (op.is_negated) { if (op.is_negated) {
current_value_id = current_value_id =

View File

@ -9,7 +9,7 @@
#include "xenia/ui/spirv/spirv_assembler.h" #include "xenia/ui/spirv/spirv_assembler.h"
#include "third_party/spirv-tools/include/libspirv/libspirv.h" #include "third_party/spirv-tools/include/spirv-tools/libspirv.h"
#include "xenia/base/logging.h" #include "xenia/base/logging.h"
namespace xe { namespace xe {

View File

@ -9,7 +9,7 @@
#include "xenia/ui/spirv/spirv_disassembler.h" #include "xenia/ui/spirv/spirv_disassembler.h"
#include "third_party/spirv-tools/include/libspirv/libspirv.h" #include "third_party/spirv-tools/include/spirv-tools/libspirv.h"
#include "xenia/base/logging.h" #include "xenia/base/logging.h"
namespace xe { namespace xe {

View File

@ -10,8 +10,8 @@
#ifndef XENIA_UI_SPIRV_SPIRV_UTIL_H_ #ifndef XENIA_UI_SPIRV_SPIRV_UTIL_H_
#define XENIA_UI_SPIRV_SPIRV_UTIL_H_ #define XENIA_UI_SPIRV_SPIRV_UTIL_H_
#include "third_party/spirv/GLSL.std.450.h" #include "third_party/spirv/GLSL.std.450.hpp11"
#include "third_party/spirv/spirv.h" #include "third_party/spirv/spirv.hpp11"
// Forward declarations from SPIRV-Tools so we don't pollute /so/ much. // Forward declarations from SPIRV-Tools so we don't pollute /so/ much.
struct spv_binary_t; struct spv_binary_t;

View File

@ -0,0 +1,53 @@
project_root = "../../../.."
include(project_root.."/tools/build")
group("src")
project("xenia-ui-vulkan")
uuid("4933d81e-1c2c-4d5d-b104-3c0eb9dc2f00")
kind("StaticLib")
language("C++")
links({
"xenia-base",
"xenia-ui",
"xenia-ui-spirv",
})
defines({
})
includedirs({
project_root.."/third_party/gflags/src",
project_root.."/third_party/vulkan/",
})
local_platform_files()
removefiles({"*_demo.cc"})
group("demos")
project("xenia-ui-window-vulkan-demo")
uuid("97598f13-3177-454c-8e58-c59e2b6ede27")
kind("WindowedApp")
language("C++")
links({
"gflags",
"imgui",
"vulkan-loader",
"xenia-base",
"xenia-ui",
"xenia-ui-spirv",
"xenia-ui-vulkan",
})
flags({
"WinMain", -- Use WinMain instead of main.
})
defines({
})
includedirs({
project_root.."/third_party/gflags/src",
project_root.."/third_party/vulkan/",
})
files({
"../window_demo.cc",
"vulkan_window_demo.cc",
project_root.."/src/xenia/base/main_"..platform_suffix..".cc",
})
resincludedirs({
project_root,
})

View File

@ -0,0 +1,2 @@
glslangValidator -V immediate.vert -o immediate.vert.spv
glslangValidator -V immediate.frag -o immediate.frag.spv

View File

@ -0,0 +1,23 @@
#version 450 core
precision highp float;
layout(push_constant) uniform PushConstants {
mat4 projection_matrix;
int restrict_texture_samples;
} push_constants;
layout(set = 0, binding = 0) uniform sampler2D texture_sampler;
layout(location = 0) in vec2 vtx_uv;
layout(location = 1) in vec4 vtx_color;
layout(location = 0) out vec4 out_color;
void main() {
out_color = vtx_color;
if (push_constants.restrict_texture_samples == 0 || vtx_uv.x <= 1.0) {
vec4 tex_color = texture(texture_sampler, vtx_uv);
out_color *= tex_color;
// TODO(benvanik): microprofiler shadows.
}
}

View File

@ -0,0 +1,124 @@
const uint8_t immediate_frag_spv[] = {
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00,
0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x10, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xC2, 0x01, 0x00, 0x00,
0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00,
0x6F, 0x75, 0x74, 0x5F, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x00, 0x00, 0x00,
0x05, 0x00, 0x05, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x76, 0x74, 0x78, 0x5F,
0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00,
0x10, 0x00, 0x00, 0x00, 0x50, 0x75, 0x73, 0x68, 0x43, 0x6F, 0x6E, 0x73,
0x74, 0x61, 0x6E, 0x74, 0x73, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x00,
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x72, 0x6F, 0x6A,
0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x5F, 0x6D, 0x61, 0x74, 0x72, 0x69,
0x78, 0x00, 0x00, 0x00, 0x06, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74,
0x5F, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5F, 0x73, 0x61, 0x6D,
0x70, 0x6C, 0x65, 0x73, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00,
0x12, 0x00, 0x00, 0x00, 0x70, 0x75, 0x73, 0x68, 0x5F, 0x63, 0x6F, 0x6E,
0x73, 0x74, 0x61, 0x6E, 0x74, 0x73, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x76, 0x74, 0x78, 0x5F, 0x75, 0x76, 0x00, 0x00,
0x05, 0x00, 0x05, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x5F,
0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00,
0x2E, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5F,
0x73, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x72, 0x00, 0x47, 0x00, 0x04, 0x00,
0x09, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x47, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x48, 0x00, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x23, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00,
0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
0x12, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x47, 0x00, 0x04, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x2E, 0x00, 0x00, 0x00,
0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
0x2E, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00,
0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00,
0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00,
0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00, 0x0D, 0x00, 0x00, 0x00,
0x18, 0x00, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x0F, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x04, 0x00,
0x10, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00,
0x12, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x0F, 0x00, 0x00, 0x00,
0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00,
0x1C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x1C, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x1D, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00,
0x1F, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x04, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00,
0x06, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F,
0x20, 0x00, 0x04, 0x00, 0x29, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0x2B, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x03, 0x00, 0x2C, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x2D, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
0x2D, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
0x05, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x29, 0x00, 0x00, 0x00,
0x2A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0xAA, 0x00, 0x05, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0xA8, 0x00, 0x04, 0x00,
0x0D, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0xF7, 0x00, 0x03, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFA, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00,
0x1B, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x1A, 0x00, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x06, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
0xBC, 0x00, 0x05, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
0x23, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
0x1B, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x1B, 0x00, 0x00, 0x00,
0xF5, 0x00, 0x07, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
0x1A, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x03, 0x00, 0x28, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x04, 0x00, 0x26, 0x00, 0x00, 0x00,
0x27, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
0x27, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x2C, 0x00, 0x00, 0x00,
0x2F, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x1C, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x57, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00,
0x2F, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
0x2A, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x07, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00,
0x34, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
0xF9, 0x00, 0x02, 0x00, 0x28, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
0x28, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
};

Binary file not shown.

View File

@ -0,0 +1,21 @@
#version 450 core
precision highp float;
layout(push_constant) uniform PushConstants {
mat4 projection_matrix;
int restrict_texture_samples;
} push_constants;
layout(location = 0) in vec2 in_pos;
layout(location = 1) in vec2 in_uv;
layout(location = 2) in vec4 in_color;
layout(location = 0) out vec2 vtx_uv;
layout(location = 1) out vec4 vtx_color;
void main() {
gl_Position = push_constants.projection_matrix * vec4(in_pos.xy, 0.0, 1.0);
gl_Position.y = -gl_Position.y;
vtx_uv = in_uv;
vtx_color = in_color;
}

View File

@ -0,0 +1,136 @@
const uint8_t immediate_vert_spv[] = {
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00,
0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00,
0x11, 0x00, 0x02, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64,
0x2E, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0B, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E,
0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
0x29, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,
0x2E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00,
0xC2, 0x01, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00,
0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50, 0x65, 0x72, 0x56, 0x65,
0x72, 0x74, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50,
0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x06, 0x00, 0x07, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50,
0x6F, 0x69, 0x6E, 0x74, 0x53, 0x69, 0x7A, 0x65, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x07, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x67, 0x6C, 0x5F, 0x43, 0x6C, 0x69, 0x70, 0x44, 0x69, 0x73, 0x74, 0x61,
0x6E, 0x63, 0x65, 0x00, 0x06, 0x00, 0x07, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x43, 0x75, 0x6C, 0x6C, 0x44,
0x69, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x00, 0x05, 0x00, 0x03, 0x00,
0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00,
0x11, 0x00, 0x00, 0x00, 0x50, 0x75, 0x73, 0x68, 0x43, 0x6F, 0x6E, 0x73,
0x74, 0x61, 0x6E, 0x74, 0x73, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x00,
0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x72, 0x6F, 0x6A,
0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x5F, 0x6D, 0x61, 0x74, 0x72, 0x69,
0x78, 0x00, 0x00, 0x00, 0x06, 0x00, 0x0A, 0x00, 0x11, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74,
0x5F, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5F, 0x73, 0x61, 0x6D,
0x70, 0x6C, 0x65, 0x73, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00,
0x13, 0x00, 0x00, 0x00, 0x70, 0x75, 0x73, 0x68, 0x5F, 0x63, 0x6F, 0x6E,
0x73, 0x74, 0x61, 0x6E, 0x74, 0x73, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
0x19, 0x00, 0x00, 0x00, 0x69, 0x6E, 0x5F, 0x70, 0x6F, 0x73, 0x00, 0x00,
0x05, 0x00, 0x04, 0x00, 0x29, 0x00, 0x00, 0x00, 0x76, 0x74, 0x78, 0x5F,
0x75, 0x76, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x2A, 0x00, 0x00, 0x00,
0x69, 0x6E, 0x5F, 0x75, 0x76, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00,
0x2C, 0x00, 0x00, 0x00, 0x76, 0x74, 0x78, 0x5F, 0x63, 0x6F, 0x6C, 0x6F,
0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x2E, 0x00, 0x00, 0x00,
0x69, 0x6E, 0x5F, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x00, 0x00, 0x00, 0x00,
0x48, 0x00, 0x05, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x48, 0x00, 0x05, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x04, 0x00,
0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x48, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x47, 0x00, 0x03, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x47, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
0x29, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x47, 0x00, 0x04, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x2C, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
0x2E, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00,
0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00,
0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00,
0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x15, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00,
0x0A, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x06, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x00, 0x00,
0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00,
0x0E, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x04, 0x00,
0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x11, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00,
0x13, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x14, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x17, 0x00, 0x04, 0x00, 0x17, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x20, 0x00, 0x04, 0x00,
0x21, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
0x28, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00,
0x2C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x2D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0xF8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00,
0x16, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x17, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00,
0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00,
0x06, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00,
0x1F, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x1B, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x91, 0x00, 0x05, 0x00,
0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
0x1F, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x21, 0x00, 0x00, 0x00,
0x22, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x22, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x41, 0x00, 0x06, 0x00, 0x23, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x3D, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
0x26, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
0x23, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
0x27, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x17, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,
0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00,
0x2E, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x2C, 0x00, 0x00, 0x00,
0x2F, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
};

Binary file not shown.

View File

@ -0,0 +1,12 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/ui/vulkan/vulkan.h"
DEFINE_bool(vulkan_validation, false, "Enable Vulkan validation layers.");

View File

@ -0,0 +1,34 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_UI_VULKAN_VULKAN_H_
#define XENIA_UI_VULKAN_VULKAN_H_
#include <gflags/gflags.h>
#include "xenia/base/platform.h"
#if XE_PLATFORM_WIN32
#define VK_USE_PLATFORM_WIN32_KHR 1
#else
#error Platform not yet supported.
#endif // XE_PLATFORM_WIN32
// We are statically linked with the loader, so use function prototypes.
#define VK_PROTOTYPES
#include "third_party/vulkan/vulkan.h"
// NOTE: header order matters here, unfortunately:
#include "third_party/vulkan/vk_lunarg_debug_marker.h"
#define XELOGVK XELOGI
DECLARE_bool(vulkan_validation);
#endif // XENIA_UI_VULKAN_VULKAN_H_

View File

@ -0,0 +1,148 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/ui/vulkan/vulkan_context.h"
#include <mutex>
#include <string>
#include "xenia/base/assert.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/base/profiling.h"
#include "xenia/ui/vulkan/vulkan.h"
#include "xenia/ui/vulkan/vulkan_device.h"
#include "xenia/ui/vulkan/vulkan_immediate_drawer.h"
#include "xenia/ui/vulkan/vulkan_instance.h"
#include "xenia/ui/vulkan/vulkan_provider.h"
#include "xenia/ui/vulkan/vulkan_swap_chain.h"
#include "xenia/ui/vulkan/vulkan_util.h"
#include "xenia/ui/window.h"
namespace xe {
namespace ui {
namespace vulkan {
VulkanContext::VulkanContext(VulkanProvider* provider, Window* target_window)
: GraphicsContext(provider, target_window) {}
VulkanContext::~VulkanContext() {
auto provider = static_cast<VulkanProvider*>(provider_);
auto device = provider->device();
vkQueueWaitIdle(device->primary_queue());
immediate_drawer_.reset();
swap_chain_.reset();
if (cmd_pool_) {
vkDestroyCommandPool(*device, cmd_pool_, nullptr);
}
}
bool VulkanContext::Initialize() {
auto provider = static_cast<VulkanProvider*>(provider_);
auto device = provider->device();
// All context-specific commands will be allocated from this.
// We may want to have additional pools for different rendering subsystems.
VkCommandPoolCreateInfo cmd_pool_info;
cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
cmd_pool_info.pNext = nullptr;
cmd_pool_info.queueFamilyIndex = device->queue_family_index();
cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
auto err = vkCreateCommandPool(*device, &cmd_pool_info, nullptr, &cmd_pool_);
CheckResult(err, "vkCreateCommandPool");
if (target_window_) {
// Create swap chain used to present to the window.
VkSurfaceKHR surface = nullptr;
#if XE_PLATFORM_WIN32
VkWin32SurfaceCreateInfoKHR create_info;
create_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
create_info.pNext = nullptr;
create_info.flags = 0;
create_info.hinstance =
static_cast<HINSTANCE>(target_window_->native_platform_handle());
create_info.hwnd = static_cast<HWND>(target_window_->native_handle());
err = vkCreateWin32SurfaceKHR(*provider->instance(), &create_info, nullptr,
&surface);
CheckResult(err, "vkCreateWin32SurfaceKHR");
#else
#error Platform not yet implemented.
#endif // XE_PLATFORM_WIN32
swap_chain_ = std::make_unique<VulkanSwapChain>(provider->instance(),
provider->device());
if (!swap_chain_->Initialize(surface)) {
XELOGE("Unable to initialize swap chain");
vkDestroySurfaceKHR(*provider->instance(), surface, nullptr);
return false;
}
// Only initialize immediate mode drawer if we are not an offscreen context.
immediate_drawer_ = std::make_unique<VulkanImmediateDrawer>(this);
}
return true;
}
ImmediateDrawer* VulkanContext::immediate_drawer() {
return immediate_drawer_.get();
}
VulkanInstance* VulkanContext::instance() const {
return static_cast<VulkanProvider*>(provider_)->instance();
}
VulkanDevice* VulkanContext::device() const {
return static_cast<VulkanProvider*>(provider_)->device();
}
bool VulkanContext::is_current() { return false; }
bool VulkanContext::MakeCurrent() {
SCOPE_profile_cpu_f("gpu");
return true;
}
void VulkanContext::ClearCurrent() {}
void VulkanContext::BeginSwap() {
SCOPE_profile_cpu_f("gpu");
auto provider = static_cast<VulkanProvider*>(provider_);
auto device = provider->device();
// Acquire the next image and set it up for use.
swap_chain_->Begin();
// TODO(benvanik): use a fence instead? May not be possible with target image.
auto err = vkQueueWaitIdle(device->primary_queue());
CheckResult(err, "vkQueueWaitIdle");
}
void VulkanContext::EndSwap() {
SCOPE_profile_cpu_f("gpu");
auto provider = static_cast<VulkanProvider*>(provider_);
auto device = provider->device();
// Notify the presentation engine the image is ready.
// The contents must be in a coherent state.
swap_chain_->End();
// Wait until the queue is idle.
// TODO(benvanik): is this required?
auto err = vkQueueWaitIdle(device->primary_queue());
CheckResult(err, "vkQueueWaitIdle");
}
std::unique_ptr<RawImage> VulkanContext::Capture() {
assert_always();
return nullptr;
}
} // namespace vulkan
} // namespace ui
} // namespace xe

View File

@ -0,0 +1,63 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_UI_VULKAN_VULKAN_CONTEXT_H_
#define XENIA_UI_VULKAN_VULKAN_CONTEXT_H_
#include <memory>
#include "xenia/ui/graphics_context.h"
#include "xenia/ui/vulkan/vulkan.h"
namespace xe {
namespace ui {
namespace vulkan {
class VulkanDevice;
class VulkanImmediateDrawer;
class VulkanInstance;
class VulkanProvider;
class VulkanSwapChain;
class VulkanContext : public GraphicsContext {
public:
~VulkanContext() override;
ImmediateDrawer* immediate_drawer() override;
VulkanSwapChain* swap_chain() const { return swap_chain_.get(); }
VulkanInstance* instance() const;
VulkanDevice* device() const;
bool is_current() override;
bool MakeCurrent() override;
void ClearCurrent() override;
void BeginSwap() override;
void EndSwap() override;
std::unique_ptr<RawImage> Capture() override;
private:
friend class VulkanProvider;
explicit VulkanContext(VulkanProvider* provider, Window* target_window);
private:
bool Initialize();
std::unique_ptr<VulkanSwapChain> swap_chain_;
std::unique_ptr<VulkanImmediateDrawer> immediate_drawer_;
VkCommandPool cmd_pool_ = nullptr;
};
} // namespace vulkan
} // namespace ui
} // namespace xe
#endif // XENIA_UI_VULKAN_VULKAN_CONTEXT_H_

View File

@ -0,0 +1,222 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/ui/vulkan/vulkan_device.h"
#include <gflags/gflags.h>
#include <cinttypes>
#include <mutex>
#include <string>
#include "xenia/base/assert.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/base/profiling.h"
#include "xenia/ui/vulkan/vulkan.h"
#include "xenia/ui/vulkan/vulkan_immediate_drawer.h"
#include "xenia/ui/vulkan/vulkan_util.h"
#include "xenia/ui/window.h"
namespace xe {
namespace ui {
namespace vulkan {
VulkanDevice::VulkanDevice(VulkanInstance* instance) : instance_(instance) {
if (FLAGS_vulkan_validation) {
/*DeclareRequiredLayer("VK_LAYER_GOOGLE_unique_objects",
Version::Make(0, 0, 0), true);*/
DeclareRequiredLayer("VK_LAYER_LUNARG_threading", Version::Make(0, 0, 0),
true);
/*DeclareRequiredLayer("VK_LAYER_LUNARG_mem_tracker", Version::Make(0, 0,
0),
true);*/
DeclareRequiredLayer("VK_LAYER_LUNARG_object_tracker",
Version::Make(0, 0, 0), true);
DeclareRequiredLayer("VK_LAYER_LUNARG_draw_state", Version::Make(0, 0, 0),
true);
DeclareRequiredLayer("VK_LAYER_LUNARG_param_checker",
Version::Make(0, 0, 0), true);
DeclareRequiredLayer("VK_LAYER_LUNARG_swapchain", Version::Make(0, 0, 0),
true);
DeclareRequiredLayer("VK_LAYER_LUNARG_device_limits",
Version::Make(0, 0, 0), true);
DeclareRequiredLayer("VK_LAYER_LUNARG_image", Version::Make(0, 0, 0), true);
}
}
VulkanDevice::~VulkanDevice() {
if (handle) {
vkDestroyDevice(handle, nullptr);
handle = nullptr;
}
}
bool VulkanDevice::Initialize(DeviceInfo device_info) {
// Gather list of enabled layer names.
auto layers_result = CheckRequirements(required_layers_, device_info.layers);
auto& enabled_layers = layers_result.second;
// Gather list of enabled extension names.
auto extensions_result =
CheckRequirements(required_extensions_, device_info.extensions);
auto& enabled_extensions = extensions_result.second;
// We wait until both extensions and layers are checked before failing out so
// that the user gets a complete list of what they have/don't.
if (!extensions_result.first || !layers_result.first) {
FatalVulkanError(
"Layer and extension verification failed; aborting initialization");
return false;
}
// Query supported features so we can make sure we have what we need.
VkPhysicalDeviceFeatures supported_features;
vkGetPhysicalDeviceFeatures(device_info.handle, &supported_features);
VkPhysicalDeviceFeatures enabled_features = {0};
bool any_features_missing = false;
#define ENABLE_AND_EXPECT(name) \
if (!supported_features.name) { \
any_features_missing = true; \
FatalVulkanError("Vulkan device is missing feature " #name); \
} else { \
enabled_features.name = VK_TRUE; \
}
ENABLE_AND_EXPECT(geometryShader);
ENABLE_AND_EXPECT(depthClamp);
ENABLE_AND_EXPECT(alphaToOne);
ENABLE_AND_EXPECT(multiViewport);
// TODO(benvanik): add other features.
if (any_features_missing) {
XELOGE(
"One or more required device features are missing; aborting "
"initialization");
return false;
}
// Pick a queue.
// Any queue we use must support both graphics and presentation.
// TODO(benvanik): use multiple queues (DMA-only, compute-only, etc).
if (device_info.queue_family_properties.empty()) {
FatalVulkanError("No queue families available");
return false;
}
uint32_t ideal_queue_family_index = UINT_MAX;
uint32_t queue_count = 1;
for (size_t i = 0; i < device_info.queue_family_properties.size(); ++i) {
auto queue_flags = device_info.queue_family_properties[i].queueFlags;
if (!device_info.queue_family_supports_present[i]) {
// Can't present from this queue, so ignore it.
continue;
}
if (queue_flags & VK_QUEUE_GRAPHICS_BIT) {
// Can do graphics and present - good!
ideal_queue_family_index = static_cast<uint32_t>(i);
// TODO(benvanik): pick a higher queue count?
queue_count = 1;
break;
}
}
if (ideal_queue_family_index == UINT_MAX) {
FatalVulkanError(
"No queue families available that can both do graphics and present");
return false;
}
VkDeviceQueueCreateInfo queue_info;
queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue_info.pNext = nullptr;
queue_info.flags = 0;
queue_info.queueFamilyIndex = ideal_queue_family_index;
queue_info.queueCount = queue_count;
std::vector<float> queue_priorities(queue_count);
queue_info.pQueuePriorities = queue_priorities.data();
VkDeviceCreateInfo create_info;
create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
create_info.pNext = nullptr;
create_info.flags = 0;
create_info.queueCreateInfoCount = 1;
create_info.pQueueCreateInfos = &queue_info;
create_info.enabledLayerCount = static_cast<uint32_t>(enabled_layers.size());
create_info.ppEnabledLayerNames = enabled_layers.data();
create_info.enabledExtensionCount =
static_cast<uint32_t>(enabled_extensions.size());
create_info.ppEnabledExtensionNames = enabled_extensions.data();
create_info.pEnabledFeatures = &enabled_features;
auto err = vkCreateDevice(device_info.handle, &create_info, nullptr, &handle);
switch (err) {
case VK_SUCCESS:
// Ok!
break;
case VK_ERROR_INITIALIZATION_FAILED:
FatalVulkanError("Device initialization failed; generic");
return false;
case VK_ERROR_EXTENSION_NOT_PRESENT:
FatalVulkanError(
"Device initialization failed; requested extension not present");
return false;
case VK_ERROR_LAYER_NOT_PRESENT:
FatalVulkanError(
"Device initialization failed; requested layer not present");
return false;
default:
FatalVulkanError(std::string("Device initialization failed; unknown: ") +
to_string(err));
return false;
}
device_info_ = std::move(device_info);
queue_family_index_ = ideal_queue_family_index;
// Get the primary queue used for most submissions/etc.
vkGetDeviceQueue(handle, queue_family_index_, 0, &primary_queue_);
XELOGVK("Device initialized successfully!");
return true;
}
VkDeviceMemory VulkanDevice::AllocateMemory(
const VkMemoryRequirements& requirements, VkFlags required_properties) {
// Search memory types to find one matching our requirements and our
// properties.
uint32_t type_index = UINT_MAX;
for (uint32_t i = 0; i < device_info_.memory_properties.memoryTypeCount;
++i) {
const auto& memory_type = device_info_.memory_properties.memoryTypes[i];
if (((requirements.memoryTypeBits >> i) & 1) == 1) {
// Type is available for use; check for a match on properties.
if ((memory_type.propertyFlags & required_properties) ==
required_properties) {
type_index = i;
break;
}
}
}
if (type_index == UINT_MAX) {
XELOGE("Unable to find a matching memory type");
return nullptr;
}
// Allocate the memory.
VkMemoryAllocateInfo memory_info;
memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
memory_info.pNext = nullptr;
memory_info.allocationSize = requirements.size;
memory_info.memoryTypeIndex = type_index;
VkDeviceMemory memory = nullptr;
auto err = vkAllocateMemory(handle, &memory_info, nullptr, &memory);
CheckResult(err, "vkAllocateMemory");
return memory;
}
} // namespace vulkan
} // namespace ui
} // namespace xe

View File

@ -0,0 +1,83 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_UI_VULKAN_VULKAN_DEVICE_H_
#define XENIA_UI_VULKAN_VULKAN_DEVICE_H_
#include <memory>
#include <string>
#include <vector>
#include "xenia/ui/vulkan/vulkan.h"
#include "xenia/ui/vulkan/vulkan_util.h"
namespace xe {
namespace ui {
namespace vulkan {
class VulkanInstance;
// Wrapper and utilities for VkDevice.
// Prefer passing this around over a VkDevice and casting as needed to call
// APIs.
class VulkanDevice {
public:
VulkanDevice(VulkanInstance* instance);
~VulkanDevice();
VkDevice handle = nullptr;
operator VkDevice() const { return handle; }
operator VkPhysicalDevice() const { return device_info_.handle; }
// Declares a layer to verify and enable upon initialization.
// Must be called before Initialize.
void DeclareRequiredLayer(std::string name, uint32_t min_version,
bool is_optional) {
required_layers_.push_back({name, min_version, is_optional});
}
// Declares an extension to verify and enable upon initialization.
// Must be called before Initialize.
void DeclareRequiredExtension(std::string name, uint32_t min_version,
bool is_optional) {
required_extensions_.push_back({name, min_version, is_optional});
}
// Initializes the device, querying and enabling extensions and layers and
// preparing the device for general use.
// If initialization succeeds it's likely that no more failures beyond runtime
// issues will occur.
bool Initialize(DeviceInfo device_info);
uint32_t queue_family_index() const { return queue_family_index_; }
VkQueue primary_queue() const { return primary_queue_; }
const DeviceInfo& device_info() const { return device_info_; }
// Allocates memory of the given size matching the required properties.
VkDeviceMemory AllocateMemory(
const VkMemoryRequirements& requirements,
VkFlags required_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
private:
VulkanInstance* instance_ = nullptr;
std::vector<Requirement> required_layers_;
std::vector<Requirement> required_extensions_;
DeviceInfo device_info_;
uint32_t queue_family_index_ = 0;
VkQueue primary_queue_ = nullptr;
};
} // namespace vulkan
} // namespace ui
} // namespace xe
#endif // XENIA_UI_VULKAN_VULKAN_DEVICE_H_

View File

@ -0,0 +1,734 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/ui/vulkan/vulkan_immediate_drawer.h"
#include "xenia/base/assert.h"
#include "xenia/base/math.h"
#include "xenia/ui/graphics_context.h"
#include "xenia/ui/vulkan/vulkan_context.h"
#include "xenia/ui/vulkan/vulkan_device.h"
#include "xenia/ui/vulkan/vulkan_swap_chain.h"
namespace xe {
namespace ui {
namespace vulkan {
#include "xenia/ui/vulkan/shaders/immediate.frag.h"
#include "xenia/ui/vulkan/shaders/immediate.vert.h"
constexpr uint32_t kCircularBufferCapacity = 2 * 1024 * 1024;
class LightweightCircularBuffer {
public:
LightweightCircularBuffer(VulkanDevice* device) : device_(*device) {
buffer_capacity_ = xe::round_up(kCircularBufferCapacity, 4096);
// Index buffer.
VkBufferCreateInfo index_buffer_info;
index_buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
index_buffer_info.pNext = nullptr;
index_buffer_info.flags = 0;
index_buffer_info.size = buffer_capacity_;
index_buffer_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
index_buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
index_buffer_info.queueFamilyIndexCount = 0;
index_buffer_info.pQueueFamilyIndices = nullptr;
auto err =
vkCreateBuffer(device_, &index_buffer_info, nullptr, &index_buffer_);
CheckResult(err, "vkCreateBuffer");
// Vertex buffer.
VkBufferCreateInfo vertex_buffer_info;
vertex_buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
vertex_buffer_info.pNext = nullptr;
vertex_buffer_info.flags = 0;
vertex_buffer_info.size = buffer_capacity_;
vertex_buffer_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
vertex_buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
vertex_buffer_info.queueFamilyIndexCount = 0;
vertex_buffer_info.pQueueFamilyIndices = nullptr;
err =
vkCreateBuffer(*device, &vertex_buffer_info, nullptr, &vertex_buffer_);
CheckResult(err, "vkCreateBuffer");
// Allocate underlying buffer.
// We alias it for both vertices and indices.
VkMemoryRequirements buffer_requirements;
vkGetBufferMemoryRequirements(device_, index_buffer_, &buffer_requirements);
buffer_memory_ = device->AllocateMemory(
buffer_requirements, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
vkBindBufferMemory(*device, index_buffer_, buffer_memory_, 0);
vkBindBufferMemory(*device, vertex_buffer_, buffer_memory_, 0);
// Persistent mapping.
err = vkMapMemory(device_, buffer_memory_, 0, VK_WHOLE_SIZE, 0,
&buffer_data_);
CheckResult(err, "vkMapMemory");
}
~LightweightCircularBuffer() {
vkUnmapMemory(device_, buffer_memory_);
vkDestroyBuffer(device_, index_buffer_, nullptr);
vkDestroyBuffer(device_, vertex_buffer_, nullptr);
vkFreeMemory(device_, buffer_memory_, nullptr);
}
VkBuffer vertex_buffer() const { return vertex_buffer_; }
VkBuffer index_buffer() const { return index_buffer_; }
// Allocates space for data and copies it into the buffer.
// Returns the offset in the buffer of the data or VK_WHOLE_SIZE if the buffer
// is full.
VkDeviceSize Emplace(const void* source_data, size_t source_length) {
// TODO(benvanik): query actual alignment.
source_length = xe::round_up(source_length, 256);
// Run down old fences to free up space.
// Check to see if we have space.
// return VK_WHOLE_SIZE;
// Compute new range and mark as in use.
if (current_offset_ + source_length > buffer_capacity_) {
// Wraps around.
current_offset_ = 0;
}
VkDeviceSize offset = current_offset_;
current_offset_ += source_length;
// Copy data.
auto dest_ptr = reinterpret_cast<uint8_t*>(buffer_data_) + offset;
std::memcpy(dest_ptr, source_data, source_length);
// Insert fence.
// TODO(benvanik): coarse-grained fences, these may be too fine.
// Flush memory.
// TODO(benvanik): do only in large batches? can barrier it.
VkMappedMemoryRange dirty_range;
dirty_range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
dirty_range.pNext = nullptr;
dirty_range.memory = buffer_memory_;
dirty_range.offset = offset;
dirty_range.size = source_length;
vkFlushMappedMemoryRanges(device_, 1, &dirty_range);
return offset;
}
private:
VkDevice device_ = nullptr;
VkBuffer index_buffer_ = nullptr;
VkBuffer vertex_buffer_ = nullptr;
VkDeviceMemory buffer_memory_ = nullptr;
void* buffer_data_ = nullptr;
size_t buffer_capacity_ = 0;
size_t current_offset_ = 0;
};
class VulkanImmediateTexture : public ImmediateTexture {
public:
VulkanImmediateTexture(VulkanDevice* device, VkDescriptorPool descriptor_pool,
VkDescriptorSetLayout descriptor_set_layout,
VkSampler sampler, uint32_t width, uint32_t height)
: ImmediateTexture(width, height),
device_(*device),
descriptor_pool_(descriptor_pool),
sampler_(sampler) {
handle = reinterpret_cast<uintptr_t>(this);
// Create image object.
VkImageCreateInfo image_info;
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
image_info.pNext = nullptr;
image_info.flags = 0;
image_info.imageType = VK_IMAGE_TYPE_2D;
image_info.format = VK_FORMAT_R8G8B8A8_UNORM;
image_info.extent = {width, height, 1};
image_info.mipLevels = 1;
image_info.arrayLayers = 1;
image_info.samples = VK_SAMPLE_COUNT_1_BIT;
image_info.tiling = VK_IMAGE_TILING_LINEAR;
image_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
image_info.queueFamilyIndexCount = 0;
image_info.pQueueFamilyIndices = nullptr;
image_info.initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
auto err = vkCreateImage(device_, &image_info, nullptr, &image_);
CheckResult(err, "vkCreateImage");
// Allocate memory for the image.
VkMemoryRequirements memory_requirements;
vkGetImageMemoryRequirements(device_, image_, &memory_requirements);
device_memory_ = device->AllocateMemory(
memory_requirements, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
// Bind memory and the image together.
err = vkBindImageMemory(device_, image_, device_memory_, 0);
CheckResult(err, "vkBindImageMemory");
// Create image view used by the shader.
VkImageViewCreateInfo view_info;
view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
view_info.pNext = nullptr;
view_info.flags = 0;
view_info.image = image_;
view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
view_info.format = VK_FORMAT_R8G8B8A8_UNORM;
view_info.components = {
VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B,
VK_COMPONENT_SWIZZLE_A,
};
view_info.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
err = vkCreateImageView(device_, &view_info, nullptr, &image_view_);
CheckResult(err, "vkCreateImageView");
// Create descriptor set used just for this texture.
// It never changes, so we can reuse it and not worry with updates.
VkDescriptorSetAllocateInfo set_alloc_info;
set_alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
set_alloc_info.pNext = nullptr;
set_alloc_info.descriptorPool = descriptor_pool_;
set_alloc_info.descriptorSetCount = 1;
set_alloc_info.pSetLayouts = &descriptor_set_layout;
err = vkAllocateDescriptorSets(device_, &set_alloc_info, &descriptor_set_);
CheckResult(err, "vkAllocateDescriptorSets");
// Initialize descriptor with our texture.
VkDescriptorImageInfo texture_info;
texture_info.sampler = sampler_;
texture_info.imageView = image_view_;
texture_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
VkWriteDescriptorSet descriptor_write;
descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptor_write.pNext = nullptr;
descriptor_write.dstSet = descriptor_set_;
descriptor_write.dstBinding = 0;
descriptor_write.dstArrayElement = 0;
descriptor_write.descriptorCount = 1;
descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptor_write.pImageInfo = &texture_info;
vkUpdateDescriptorSets(device_, 1, &descriptor_write, 0, nullptr);
}
~VulkanImmediateTexture() override {
vkFreeDescriptorSets(device_, descriptor_pool_, 1, &descriptor_set_);
vkDestroyImageView(device_, image_view_, nullptr);
vkDestroyImage(device_, image_, nullptr);
vkFreeMemory(device_, device_memory_, nullptr);
}
void Upload(const uint8_t* src_data) {
// TODO(benvanik): assert not in use? textures aren't dynamic right now.
// Get device image layout.
VkImageSubresource subresource;
subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
subresource.mipLevel = 0;
subresource.arrayLayer = 0;
VkSubresourceLayout layout;
vkGetImageSubresourceLayout(device_, image_, &subresource, &layout);
// Map memory for upload.
void* gpu_data = nullptr;
auto err =
vkMapMemory(device_, device_memory_, 0, layout.size, 0, &gpu_data);
CheckResult(err, "vkMapMemory");
// Copy the entire texture, hoping its layout matches what we expect.
std::memcpy(gpu_data, src_data, layout.size);
vkUnmapMemory(device_, device_memory_);
}
VkDescriptorSet descriptor_set() const { return descriptor_set_; }
private:
VkDevice device_ = nullptr;
VkDescriptorPool descriptor_pool_ = nullptr;
VkSampler sampler_ = nullptr; // Not owned.
VkImage image_ = nullptr;
VkImageLayout image_layout_ = VK_IMAGE_LAYOUT_UNDEFINED;
VkDeviceMemory device_memory_ = nullptr;
VkImageView image_view_ = nullptr;
VkDescriptorSet descriptor_set_ = nullptr;
};
VulkanImmediateDrawer::VulkanImmediateDrawer(VulkanContext* graphics_context)
: ImmediateDrawer(graphics_context), context_(graphics_context) {
auto device = context_->device();
// NEAREST + CLAMP
VkSamplerCreateInfo sampler_info;
sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
sampler_info.pNext = nullptr;
sampler_info.magFilter = VK_FILTER_NEAREST;
sampler_info.minFilter = VK_FILTER_NEAREST;
sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
sampler_info.mipLodBias = 0.0f;
sampler_info.anisotropyEnable = VK_FALSE;
sampler_info.maxAnisotropy = 1;
sampler_info.compareOp = VK_COMPARE_OP_NEVER;
sampler_info.minLod = 0.0f;
sampler_info.maxLod = 0.0f;
sampler_info.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
sampler_info.unnormalizedCoordinates = VK_FALSE;
auto err = vkCreateSampler(*device, &sampler_info, nullptr,
&samplers_.nearest_clamp);
CheckResult(err, "vkCreateSampler");
// NEAREST + REPEAT
sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
err = vkCreateSampler(*device, &sampler_info, nullptr,
&samplers_.nearest_repeat);
CheckResult(err, "vkCreateSampler");
// LINEAR + CLAMP
sampler_info.magFilter = VK_FILTER_LINEAR;
sampler_info.minFilter = VK_FILTER_LINEAR;
sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
err =
vkCreateSampler(*device, &sampler_info, nullptr, &samplers_.linear_clamp);
CheckResult(err, "vkCreateSampler");
// LINEAR + REPEAT
sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
err = vkCreateSampler(*device, &sampler_info, nullptr,
&samplers_.linear_repeat);
CheckResult(err, "vkCreateSampler");
// Create the descriptor set layout used for our texture sampler.
// As it changes almost every draw we keep it separate from the uniform buffer
// and cache it on the textures.
VkDescriptorSetLayoutCreateInfo texture_set_layout_info;
texture_set_layout_info.sType =
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
texture_set_layout_info.pNext = nullptr;
texture_set_layout_info.flags = 0;
texture_set_layout_info.bindingCount = 1;
VkDescriptorSetLayoutBinding texture_binding;
texture_binding.binding = 0;
texture_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
texture_binding.descriptorCount = 1;
texture_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
texture_binding.pImmutableSamplers = nullptr;
texture_set_layout_info.pBindings = &texture_binding;
err = vkCreateDescriptorSetLayout(*device, &texture_set_layout_info, nullptr,
&texture_set_layout_);
CheckResult(err, "vkCreateDescriptorSetLayout");
// Descriptor pool used for all of our cached descriptors.
// In the steady state we don't allocate anything, so these are all manually
// managed.
VkDescriptorPoolCreateInfo descriptor_pool_info;
descriptor_pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
descriptor_pool_info.pNext = nullptr;
descriptor_pool_info.flags =
VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
descriptor_pool_info.maxSets = 128;
VkDescriptorPoolSize pool_sizes[1];
pool_sizes[0].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
pool_sizes[0].descriptorCount = 128;
descriptor_pool_info.poolSizeCount = 1;
descriptor_pool_info.pPoolSizes = pool_sizes;
err = vkCreateDescriptorPool(*device, &descriptor_pool_info, nullptr,
&descriptor_pool_);
CheckResult(err, "vkCreateDescriptorPool");
// Create the pipeline layout used for our pipeline.
// If we had multiple pipelines they would share this.
VkPipelineLayoutCreateInfo pipeline_layout_info;
pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipeline_layout_info.pNext = nullptr;
pipeline_layout_info.flags = 0;
VkDescriptorSetLayout set_layouts[] = {texture_set_layout_};
pipeline_layout_info.setLayoutCount =
static_cast<uint32_t>(xe::countof(set_layouts));
pipeline_layout_info.pSetLayouts = set_layouts;
VkPushConstantRange push_constant_ranges[2];
push_constant_ranges[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
push_constant_ranges[0].offset = 0;
push_constant_ranges[0].size = sizeof(float) * 16;
push_constant_ranges[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
push_constant_ranges[1].offset = sizeof(float) * 16;
push_constant_ranges[1].size = sizeof(int);
pipeline_layout_info.pushConstantRangeCount =
static_cast<uint32_t>(xe::countof(push_constant_ranges));
pipeline_layout_info.pPushConstantRanges = push_constant_ranges;
err = vkCreatePipelineLayout(*device, &pipeline_layout_info, nullptr,
&pipeline_layout_);
CheckResult(err, "vkCreatePipelineLayout");
// Vertex and fragment shaders.
VkShaderModuleCreateInfo vertex_shader_info;
vertex_shader_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
vertex_shader_info.pNext = nullptr;
vertex_shader_info.flags = 0;
vertex_shader_info.codeSize = sizeof(immediate_vert_spv);
vertex_shader_info.pCode =
reinterpret_cast<const uint32_t*>(immediate_vert_spv);
VkShaderModule vertex_shader;
err = vkCreateShaderModule(*device, &vertex_shader_info, nullptr,
&vertex_shader);
CheckResult(err, "vkCreateShaderModule");
VkShaderModuleCreateInfo fragment_shader_info;
fragment_shader_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
fragment_shader_info.pNext = nullptr;
fragment_shader_info.flags = 0;
fragment_shader_info.codeSize = sizeof(immediate_frag_spv);
fragment_shader_info.pCode =
reinterpret_cast<const uint32_t*>(immediate_frag_spv);
VkShaderModule fragment_shader;
err = vkCreateShaderModule(*device, &fragment_shader_info, nullptr,
&fragment_shader);
CheckResult(err, "vkCreateShaderModule");
// Pipeline used when rendering triangles.
VkGraphicsPipelineCreateInfo pipeline_info;
pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
pipeline_info.pNext = nullptr;
pipeline_info.flags = VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT;
VkPipelineShaderStageCreateInfo pipeline_stages[2];
pipeline_stages[0].sType =
VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
pipeline_stages[0].pNext = nullptr;
pipeline_stages[0].flags = 0;
pipeline_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
pipeline_stages[0].module = vertex_shader;
pipeline_stages[0].pName = "main";
pipeline_stages[0].pSpecializationInfo = nullptr;
pipeline_stages[1].sType =
VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
pipeline_stages[1].pNext = nullptr;
pipeline_stages[1].flags = 0;
pipeline_stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
pipeline_stages[1].module = fragment_shader;
pipeline_stages[1].pName = "main";
pipeline_stages[1].pSpecializationInfo = nullptr;
pipeline_info.stageCount = 2;
pipeline_info.pStages = pipeline_stages;
VkPipelineVertexInputStateCreateInfo vertex_state_info;
vertex_state_info.sType =
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertex_state_info.pNext = nullptr;
VkVertexInputBindingDescription vertex_binding_descrs[1];
vertex_binding_descrs[0].binding = 0;
vertex_binding_descrs[0].stride = sizeof(ImmediateVertex);
vertex_binding_descrs[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
vertex_state_info.vertexBindingDescriptionCount =
static_cast<uint32_t>(xe::countof(vertex_binding_descrs));
vertex_state_info.pVertexBindingDescriptions = vertex_binding_descrs;
VkVertexInputAttributeDescription vertex_attrib_descrs[3];
vertex_attrib_descrs[0].location = 0;
vertex_attrib_descrs[0].binding = 0;
vertex_attrib_descrs[0].format = VK_FORMAT_R32G32_SFLOAT;
vertex_attrib_descrs[0].offset = offsetof(ImmediateVertex, x);
vertex_attrib_descrs[1].location = 1;
vertex_attrib_descrs[1].binding = 0;
vertex_attrib_descrs[1].format = VK_FORMAT_R32G32_SFLOAT;
vertex_attrib_descrs[1].offset = offsetof(ImmediateVertex, u);
vertex_attrib_descrs[2].location = 2;
vertex_attrib_descrs[2].binding = 0;
vertex_attrib_descrs[2].format = VK_FORMAT_R8G8B8A8_UNORM;
vertex_attrib_descrs[2].offset = offsetof(ImmediateVertex, color);
vertex_state_info.vertexAttributeDescriptionCount =
static_cast<uint32_t>(xe::countof(vertex_attrib_descrs));
vertex_state_info.pVertexAttributeDescriptions = vertex_attrib_descrs;
pipeline_info.pVertexInputState = &vertex_state_info;
VkPipelineInputAssemblyStateCreateInfo input_info;
input_info.sType =
VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
input_info.pNext = nullptr;
input_info.flags = 0;
input_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
input_info.primitiveRestartEnable = VK_FALSE;
pipeline_info.pInputAssemblyState = &input_info;
pipeline_info.pTessellationState = nullptr;
VkPipelineViewportStateCreateInfo viewport_state_info;
viewport_state_info.sType =
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
viewport_state_info.pNext = nullptr;
viewport_state_info.flags = 0;
viewport_state_info.viewportCount = 1;
viewport_state_info.pViewports = nullptr;
viewport_state_info.scissorCount = 1;
viewport_state_info.pScissors = nullptr;
pipeline_info.pViewportState = &viewport_state_info;
VkPipelineRasterizationStateCreateInfo rasterization_info;
rasterization_info.sType =
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
rasterization_info.pNext = nullptr;
rasterization_info.flags = 0;
rasterization_info.depthClampEnable = VK_FALSE;
rasterization_info.rasterizerDiscardEnable = VK_FALSE;
rasterization_info.polygonMode = VK_POLYGON_MODE_FILL;
rasterization_info.cullMode = VK_CULL_MODE_BACK_BIT;
rasterization_info.frontFace = VK_FRONT_FACE_CLOCKWISE;
rasterization_info.depthBiasEnable = VK_FALSE;
rasterization_info.depthBiasConstantFactor = 0;
rasterization_info.depthBiasClamp = 0;
rasterization_info.depthBiasSlopeFactor = 0;
rasterization_info.lineWidth = 1.0f;
pipeline_info.pRasterizationState = &rasterization_info;
VkPipelineMultisampleStateCreateInfo multisample_info;
multisample_info.sType =
VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
multisample_info.pNext = nullptr;
multisample_info.flags = 0;
multisample_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
multisample_info.sampleShadingEnable = VK_FALSE;
multisample_info.minSampleShading = 0;
multisample_info.pSampleMask = nullptr;
multisample_info.alphaToCoverageEnable = VK_FALSE;
multisample_info.alphaToOneEnable = VK_FALSE;
pipeline_info.pMultisampleState = &multisample_info;
pipeline_info.pDepthStencilState = nullptr;
VkPipelineColorBlendStateCreateInfo blend_info;
blend_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
blend_info.pNext = nullptr;
blend_info.flags = 0;
blend_info.logicOpEnable = VK_FALSE;
blend_info.logicOp = VK_LOGIC_OP_NO_OP;
VkPipelineColorBlendAttachmentState blend_attachments[1];
blend_attachments[0].blendEnable = VK_TRUE;
blend_attachments[0].srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
blend_attachments[0].dstColorBlendFactor =
VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
blend_attachments[0].colorBlendOp = VK_BLEND_OP_ADD;
blend_attachments[0].srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
blend_attachments[0].dstAlphaBlendFactor =
VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
blend_attachments[0].alphaBlendOp = VK_BLEND_OP_ADD;
blend_attachments[0].colorWriteMask = 0xF;
blend_info.attachmentCount =
static_cast<uint32_t>(xe::countof(blend_attachments));
blend_info.pAttachments = blend_attachments;
std::memset(blend_info.blendConstants, 0, sizeof(blend_info.blendConstants));
pipeline_info.pColorBlendState = &blend_info;
VkPipelineDynamicStateCreateInfo dynamic_state_info;
dynamic_state_info.sType =
VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
dynamic_state_info.pNext = nullptr;
dynamic_state_info.flags = 0;
VkDynamicState dynamic_states[] = {
VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR,
};
dynamic_state_info.dynamicStateCount =
static_cast<uint32_t>(xe::countof(dynamic_states));
dynamic_state_info.pDynamicStates = dynamic_states;
pipeline_info.pDynamicState = &dynamic_state_info;
pipeline_info.layout = pipeline_layout_;
pipeline_info.renderPass = context_->swap_chain()->render_pass();
pipeline_info.subpass = 0;
pipeline_info.basePipelineHandle = nullptr;
pipeline_info.basePipelineIndex = 0;
err = vkCreateGraphicsPipelines(*device, nullptr, 1, &pipeline_info, nullptr,
&triangle_pipeline_);
CheckResult(err, "vkCreateGraphicsPipelines");
// Silly, but let's make a pipeline just for drawing lines.
pipeline_info.flags = VK_PIPELINE_CREATE_DERIVATIVE_BIT;
input_info.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
pipeline_info.basePipelineHandle = triangle_pipeline_;
pipeline_info.basePipelineIndex = 0;
err = vkCreateGraphicsPipelines(*device, nullptr, 1, &pipeline_info, nullptr,
&line_pipeline_);
CheckResult(err, "vkCreateGraphicsPipelines");
vkDestroyShaderModule(*device, vertex_shader, nullptr);
vkDestroyShaderModule(*device, fragment_shader, nullptr);
// Allocate the buffer we'll use for our vertex and index data.
circular_buffer_ = std::make_unique<LightweightCircularBuffer>(device);
}
VulkanImmediateDrawer::~VulkanImmediateDrawer() {
auto device = context_->device();
circular_buffer_.reset();
vkDestroyPipeline(*device, line_pipeline_, nullptr);
vkDestroyPipeline(*device, triangle_pipeline_, nullptr);
vkDestroyPipelineLayout(*device, pipeline_layout_, nullptr);
vkDestroyDescriptorPool(*device, descriptor_pool_, nullptr);
vkDestroyDescriptorSetLayout(*device, texture_set_layout_, nullptr);
vkDestroySampler(*device, samplers_.nearest_clamp, nullptr);
vkDestroySampler(*device, samplers_.nearest_repeat, nullptr);
vkDestroySampler(*device, samplers_.linear_clamp, nullptr);
vkDestroySampler(*device, samplers_.linear_repeat, nullptr);
}
std::unique_ptr<ImmediateTexture> VulkanImmediateDrawer::CreateTexture(
uint32_t width, uint32_t height, ImmediateTextureFilter filter, bool repeat,
const uint8_t* data) {
auto device = context_->device();
VkSampler sampler = nullptr;
switch (filter) {
case ImmediateTextureFilter::kNearest:
sampler = repeat ? samplers_.nearest_repeat : samplers_.nearest_clamp;
break;
case ImmediateTextureFilter::kLinear:
sampler = repeat ? samplers_.linear_repeat : samplers_.linear_clamp;
break;
default:
assert_unhandled_case(filter);
sampler = samplers_.nearest_clamp;
break;
}
auto texture = std::make_unique<VulkanImmediateTexture>(
device, descriptor_pool_, texture_set_layout_, sampler, width, height);
if (data) {
UpdateTexture(texture.get(), data);
}
return std::unique_ptr<ImmediateTexture>(texture.release());
}
void VulkanImmediateDrawer::UpdateTexture(ImmediateTexture* texture,
const uint8_t* data) {
static_cast<VulkanImmediateTexture*>(texture)->Upload(data);
}
void VulkanImmediateDrawer::Begin(int render_target_width,
int render_target_height) {
auto device = context_->device();
auto swap_chain = context_->swap_chain();
assert_null(current_cmd_buffer_);
current_cmd_buffer_ = swap_chain->render_cmd_buffer();
// Viewport changes only once per batch.
VkViewport viewport;
viewport.x = 0.0f;
viewport.y = 0.0f;
viewport.width = static_cast<float>(render_target_width);
viewport.height = static_cast<float>(render_target_height);
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
vkCmdSetViewport(current_cmd_buffer_, 0, 1, &viewport);
// Update projection matrix.
const float ortho_projection[4][4] = {
{2.0f / render_target_width, 0.0f, 0.0f, 0.0f},
{0.0f, 2.0f / -render_target_height, 0.0f, 0.0f},
{0.0f, 0.0f, -1.0f, 0.0f},
{-1.0f, 1.0f, 0.0f, 1.0f},
};
vkCmdPushConstants(current_cmd_buffer_, pipeline_layout_,
VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(float) * 16,
ortho_projection);
}
void VulkanImmediateDrawer::BeginDrawBatch(const ImmediateDrawBatch& batch) {
auto device = context_->device();
// Upload vertices.
VkDeviceSize vertices_offset = circular_buffer_->Emplace(
batch.vertices, batch.vertex_count * sizeof(ImmediateVertex));
if (vertices_offset == VK_WHOLE_SIZE) {
// TODO(benvanik): die?
return;
}
auto vertex_buffer = circular_buffer_->vertex_buffer();
vkCmdBindVertexBuffers(current_cmd_buffer_, 0, 1, &vertex_buffer,
&vertices_offset);
// Upload indices.
if (batch.indices) {
VkDeviceSize indices_offset = circular_buffer_->Emplace(
batch.indices, batch.index_count * sizeof(uint16_t));
if (indices_offset == VK_WHOLE_SIZE) {
// TODO(benvanik): die?
return;
}
vkCmdBindIndexBuffer(current_cmd_buffer_, circular_buffer_->index_buffer(),
indices_offset, VK_INDEX_TYPE_UINT16);
}
batch_has_index_buffer_ = !!batch.indices;
}
void VulkanImmediateDrawer::Draw(const ImmediateDraw& draw) {
auto swap_chain = context_->swap_chain();
if (draw.primitive_type != ImmediatePrimitiveType::kTriangles) {
return;
}
switch (draw.primitive_type) {
case ImmediatePrimitiveType::kLines:
vkCmdBindPipeline(current_cmd_buffer_, VK_PIPELINE_BIND_POINT_GRAPHICS,
line_pipeline_);
break;
case ImmediatePrimitiveType::kTriangles:
vkCmdBindPipeline(current_cmd_buffer_, VK_PIPELINE_BIND_POINT_GRAPHICS,
triangle_pipeline_);
break;
}
// Setup texture binding.
VkDescriptorSet texture_set = nullptr;
auto texture = reinterpret_cast<VulkanImmediateTexture*>(draw.texture_handle);
if (texture) {
texture_set = texture->descriptor_set();
}
vkCmdBindDescriptorSets(current_cmd_buffer_, VK_PIPELINE_BIND_POINT_GRAPHICS,
pipeline_layout_, 0, 1, &texture_set, 0, nullptr);
// Use push constants for our per-draw changes.
// Here, the restrict_texture_samples uniform.
int restrict_texture_samples = draw.restrict_texture_samples ? 1 : 0;
vkCmdPushConstants(current_cmd_buffer_, pipeline_layout_,
VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(float) * 16,
sizeof(int), &restrict_texture_samples);
// Scissor, if enabled.
// Scissor can be disabled by making it the full screen.
VkRect2D scissor;
if (draw.scissor) {
scissor.offset.x = draw.scissor_rect[0];
scissor.offset.y = swap_chain->surface_height() -
(draw.scissor_rect[1] + draw.scissor_rect[3]);
scissor.extent.width = draw.scissor_rect[2];
scissor.extent.height = draw.scissor_rect[3];
} else {
scissor.offset.x = 0;
scissor.offset.y = 0;
scissor.extent.width = swap_chain->surface_width();
scissor.extent.height = swap_chain->surface_height();
}
vkCmdSetScissor(current_cmd_buffer_, 0, 1, &scissor);
// Issue draw.
if (batch_has_index_buffer_) {
vkCmdDrawIndexed(current_cmd_buffer_, draw.count, 1, draw.index_offset,
draw.base_vertex, 0);
} else {
vkCmdDraw(current_cmd_buffer_, draw.count, 1, draw.base_vertex, 0);
}
}
void VulkanImmediateDrawer::EndDrawBatch() {}
void VulkanImmediateDrawer::End() { current_cmd_buffer_ = nullptr; }
} // namespace vulkan
} // namespace ui
} // namespace xe

View File

@ -0,0 +1,69 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_UI_VULKAN_VULKAN_IMMEDIATE_DRAWER_H_
#define XENIA_UI_VULKAN_VULKAN_IMMEDIATE_DRAWER_H_
#include <memory>
#include "xenia/ui/immediate_drawer.h"
#include "xenia/ui/vulkan/vulkan.h"
namespace xe {
namespace ui {
namespace vulkan {
class LightweightCircularBuffer;
class VulkanContext;
class VulkanImmediateDrawer : public ImmediateDrawer {
public:
VulkanImmediateDrawer(VulkanContext* graphics_context);
~VulkanImmediateDrawer() override;
std::unique_ptr<ImmediateTexture> CreateTexture(uint32_t width,
uint32_t height,
ImmediateTextureFilter filter,
bool repeat,
const uint8_t* data) override;
void UpdateTexture(ImmediateTexture* texture, const uint8_t* data) override;
void Begin(int render_target_width, int render_target_height) override;
void BeginDrawBatch(const ImmediateDrawBatch& batch) override;
void Draw(const ImmediateDraw& draw) override;
void EndDrawBatch() override;
void End() override;
private:
VulkanContext* context_ = nullptr;
struct {
VkSampler nearest_clamp = nullptr;
VkSampler nearest_repeat = nullptr;
VkSampler linear_clamp = nullptr;
VkSampler linear_repeat = nullptr;
} samplers_;
VkDescriptorSetLayout texture_set_layout_ = nullptr;
VkDescriptorPool descriptor_pool_ = nullptr;
VkPipelineLayout pipeline_layout_ = nullptr;
VkPipeline triangle_pipeline_ = nullptr;
VkPipeline line_pipeline_ = nullptr;
std::unique_ptr<LightweightCircularBuffer> circular_buffer_;
bool batch_has_index_buffer_ = false;
VkCommandBuffer current_cmd_buffer_ = nullptr;
};
} // namespace vulkan
} // namespace ui
} // namespace xe
#endif // XENIA_UI_VULKAN_VULKAN_IMMEDIATE_DRAWER_H_

View File

@ -0,0 +1,486 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/ui/vulkan/vulkan_instance.h"
#include <gflags/gflags.h>
#include <cinttypes>
#include <mutex>
#include <string>
#include "xenia/base/assert.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/base/profiling.h"
#include "xenia/ui/vulkan/vulkan.h"
#include "xenia/ui/vulkan/vulkan_immediate_drawer.h"
#include "xenia/ui/vulkan/vulkan_util.h"
#include "xenia/ui/window.h"
namespace xe {
namespace ui {
namespace vulkan {
VulkanInstance::VulkanInstance() {
if (FLAGS_vulkan_validation) {
// DeclareRequiredLayer("VK_LAYER_GOOGLE_unique_objects", Version::Make(0,
// 0, 0), true);
DeclareRequiredLayer("VK_LAYER_LUNARG_threading", Version::Make(0, 0, 0),
true);
// DeclareRequiredLayer("VK_LAYER_LUNARG_mem_tracker", Version::Make(0, 0,
// 0), true);
DeclareRequiredLayer("VK_LAYER_LUNARG_object_tracker",
Version::Make(0, 0, 0), true);
DeclareRequiredLayer("VK_LAYER_LUNARG_draw_state", Version::Make(0, 0, 0),
true);
DeclareRequiredLayer("VK_LAYER_LUNARG_param_checker",
Version::Make(0, 0, 0), true);
DeclareRequiredLayer("VK_LAYER_LUNARG_swapchain", Version::Make(0, 0, 0),
true);
DeclareRequiredLayer("VK_LAYER_LUNARG_device_limits",
Version::Make(0, 0, 0), true);
DeclareRequiredLayer("VK_LAYER_LUNARG_image", Version::Make(0, 0, 0), true);
DeclareRequiredExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
Version::Make(0, 0, 0), true);
}
}
VulkanInstance::~VulkanInstance() { DestroyInstance(); }
bool VulkanInstance::Initialize(Window* any_target_window) {
auto version = Version::Parse(VK_API_VERSION);
XELOGVK("Initializing Vulkan %s...", version.pretty_string.c_str());
// Get all of the global layers and extensions provided by the system.
if (!QueryGlobals()) {
XELOGE("Failed to query instance globals");
return false;
}
// Create the vulkan instance used by the application with our required
// extensions and layers.
if (!CreateInstance()) {
XELOGE("Failed to create instance");
return false;
}
// Query available devices so that we can pick one.
if (!QueryDevices(any_target_window)) {
XELOGE("Failed to query devices");
return false;
}
XELOGVK("Instance initialized successfully!");
return true;
}
bool VulkanInstance::QueryGlobals() {
// Scan global layers and accumulate properties.
// We do this in a loop so that we can allocate the required amount of
// memory and handle race conditions while querying.
uint32_t count = 0;
std::vector<VkLayerProperties> global_layer_properties;
VkResult err;
do {
err = vkEnumerateInstanceLayerProperties(&count, nullptr);
CheckResult(err, "vkEnumerateInstanceLayerProperties");
global_layer_properties.resize(count);
err = vkEnumerateInstanceLayerProperties(&count,
global_layer_properties.data());
} while (err == VK_INCOMPLETE);
CheckResult(err, "vkEnumerateInstanceLayerProperties");
global_layers_.resize(count);
for (size_t i = 0; i < global_layers_.size(); ++i) {
auto& global_layer = global_layers_[i];
global_layer.properties = global_layer_properties[i];
// Get all extensions available for the layer.
do {
err = vkEnumerateInstanceExtensionProperties(
global_layer.properties.layerName, &count, nullptr);
CheckResult(err, "vkEnumerateInstanceExtensionProperties");
global_layer.extensions.resize(count);
err = vkEnumerateInstanceExtensionProperties(
global_layer.properties.layerName, &count,
global_layer.extensions.data());
} while (err == VK_INCOMPLETE);
CheckResult(err, "vkEnumerateInstanceExtensionProperties");
}
XELOGVK("Found %d global layers:", global_layers_.size());
for (size_t i = 0; i < global_layers_.size(); ++i) {
auto& global_layer = global_layers_[i];
auto spec_version = Version::Parse(global_layer.properties.specVersion);
auto impl_version =
Version::Parse(global_layer.properties.implementationVersion);
XELOGVK("- %s (spec: %s, impl: %s)", global_layer.properties.layerName,
spec_version.pretty_string.c_str(),
impl_version.pretty_string.c_str());
XELOGVK(" %s", global_layer.properties.description);
if (!global_layer.extensions.empty()) {
XELOGVK(" %d extensions:", global_layer.extensions.size());
DumpExtensions(global_layer.extensions, " ");
}
}
// Scan global extensions.
do {
err = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
CheckResult(err, "vkEnumerateInstanceExtensionProperties");
global_extensions_.resize(count);
err = vkEnumerateInstanceExtensionProperties(nullptr, &count,
global_extensions_.data());
} while (err == VK_INCOMPLETE);
CheckResult(err, "vkEnumerateInstanceExtensionProperties");
XELOGVK("Found %d global extensions:", global_extensions_.size());
DumpExtensions(global_extensions_, "");
return true;
}
bool VulkanInstance::CreateInstance() {
XELOGVK("Verifying layers and extensions...");
// Gather list of enabled layer names.
auto layers_result = CheckRequirements(required_layers_, global_layers_);
auto& enabled_layers = layers_result.second;
// Gather list of enabled extension names.
auto extensions_result =
CheckRequirements(required_extensions_, global_extensions_);
auto& enabled_extensions = extensions_result.second;
// We wait until both extensions and layers are checked before failing out so
// that the user gets a complete list of what they have/don't.
if (!extensions_result.first || !layers_result.first) {
XELOGE("Layer and extension verification failed; aborting initialization");
return false;
}
XELOGVK("Initializing application instance...");
// TODO(benvanik): use GetEntryInfo?
VkApplicationInfo application_info;
application_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
application_info.pNext = nullptr;
application_info.pApplicationName = "xenia";
application_info.applicationVersion = 1;
application_info.pEngineName = "xenia";
application_info.engineVersion = 1;
application_info.apiVersion = VK_API_VERSION;
VkInstanceCreateInfo instance_info;
instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instance_info.pNext = nullptr;
instance_info.flags = 0;
instance_info.pApplicationInfo = &application_info;
instance_info.enabledLayerCount =
static_cast<uint32_t>(enabled_layers.size());
instance_info.ppEnabledLayerNames = enabled_layers.data();
instance_info.enabledExtensionCount =
static_cast<uint32_t>(enabled_extensions.size());
instance_info.ppEnabledExtensionNames = enabled_extensions.data();
auto err = vkCreateInstance(&instance_info, nullptr, &handle);
switch (err) {
case VK_SUCCESS:
// Ok!
break;
case VK_ERROR_INITIALIZATION_FAILED:
XELOGE("Instance initialization failed; generic");
return false;
case VK_ERROR_INCOMPATIBLE_DRIVER:
XELOGE(
"Instance initialization failed; cannot find a compatible Vulkan "
"installable client driver (ICD)");
return false;
case VK_ERROR_EXTENSION_NOT_PRESENT:
XELOGE("Instance initialization failed; requested extension not present");
return false;
case VK_ERROR_LAYER_NOT_PRESENT:
XELOGE("Instance initialization failed; requested layer not present");
return false;
default:
XELOGE("Instance initialization failed; unknown: %s", to_string(err));
return false;
}
// Enable debug validation, if needed.
EnableDebugValidation();
return true;
}
void VulkanInstance::DestroyInstance() {
if (!handle) {
return;
}
DisableDebugValidation();
vkDestroyInstance(handle, nullptr);
handle = nullptr;
}
VkBool32 VKAPI_PTR DebugMessageCallback(VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objectType,
uint64_t object, size_t location,
int32_t messageCode,
const char* pLayerPrefix,
const char* pMessage, void* pUserData) {
auto instance = reinterpret_cast<VulkanInstance*>(pUserData);
const char* message_type = "UNKNOWN";
if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
message_type = "ERROR";
} else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
message_type = "WARN";
} else if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
message_type = "PERF WARN";
} else if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
message_type = "INFO";
} else if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
message_type = "DEBUG";
}
XELOGVK("[%s/%s:%d] %s", pLayerPrefix, message_type, messageCode, pMessage);
return false;
}
void VulkanInstance::EnableDebugValidation() {
if (dbg_report_callback_) {
DisableDebugValidation();
}
auto vk_create_debug_report_callback_ext =
reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(
vkGetInstanceProcAddr(handle, "vkCreateDebugReportCallbackEXT"));
if (!vk_create_debug_report_callback_ext) {
XELOGVK("Debug validation layer not installed; ignoring");
return;
}
VkDebugReportCallbackCreateInfoEXT create_info;
create_info.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
create_info.pNext = nullptr;
// TODO(benvanik): flags to set these.
create_info.flags =
VK_DEBUG_REPORT_INFORMATION_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT |
VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT |
VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_DEBUG_BIT_EXT;
create_info.pfnCallback = &DebugMessageCallback;
create_info.pUserData = this;
auto err = vk_create_debug_report_callback_ext(handle, &create_info, nullptr,
&dbg_report_callback_);
CheckResult(err, "vkCreateDebugReportCallbackEXT");
XELOGVK("Debug validation layer enabled");
}
void VulkanInstance::DisableDebugValidation() {
if (!dbg_report_callback_) {
return;
}
auto vk_destroy_debug_report_callback_ext =
reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(
vkGetInstanceProcAddr(handle, "vkDestroyDebugReportCallbackEXT"));
if (!vk_destroy_debug_report_callback_ext) {
return;
}
vk_destroy_debug_report_callback_ext(handle, dbg_report_callback_, nullptr);
dbg_report_callback_ = nullptr;
}
bool VulkanInstance::QueryDevices(Window* any_target_window) {
// Get handles to all devices.
uint32_t count = 0;
std::vector<VkPhysicalDevice> device_handles;
auto err = vkEnumeratePhysicalDevices(handle, &count, nullptr);
CheckResult(err, "vkEnumeratePhysicalDevices");
device_handles.resize(count);
err = vkEnumeratePhysicalDevices(handle, &count, device_handles.data());
CheckResult(err, "vkEnumeratePhysicalDevices");
// Query device info.
for (size_t i = 0; i < device_handles.size(); ++i) {
auto device_handle = device_handles[i];
DeviceInfo device_info;
device_info.handle = device_handle;
// Query general attributes.
vkGetPhysicalDeviceProperties(device_handle, &device_info.properties);
vkGetPhysicalDeviceFeatures(device_handle, &device_info.features);
vkGetPhysicalDeviceMemoryProperties(device_handle,
&device_info.memory_properties);
// Gather queue family properties.
vkGetPhysicalDeviceQueueFamilyProperties(device_handle, &count, nullptr);
device_info.queue_family_properties.resize(count);
vkGetPhysicalDeviceQueueFamilyProperties(
device_handle, &count, device_info.queue_family_properties.data());
// Gather queue family presentation support.
// TODO(benvanik): move to swap chain?
VkSurfaceKHR any_surface = nullptr;
#if XE_PLATFORM_WIN32
VkWin32SurfaceCreateInfoKHR create_info;
create_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
create_info.pNext = nullptr;
create_info.flags = 0;
create_info.hinstance =
static_cast<HINSTANCE>(any_target_window->native_platform_handle());
create_info.hwnd = static_cast<HWND>(any_target_window->native_handle());
err = vkCreateWin32SurfaceKHR(handle, &create_info, nullptr, &any_surface);
CheckResult(err, "vkCreateWin32SurfaceKHR");
#else
#error Platform not yet implemented.
#endif // XE_PLATFORM_WIN32
device_info.queue_family_supports_present.resize(
device_info.queue_family_properties.size());
for (size_t j = 0; j < device_info.queue_family_supports_present.size();
++j) {
err = vkGetPhysicalDeviceSurfaceSupportKHR(
device_handle, static_cast<uint32_t>(j), any_surface,
&device_info.queue_family_supports_present[j]);
CheckResult(err, "vkGetPhysicalDeviceSurfaceSupportKHR");
}
vkDestroySurfaceKHR(handle, any_surface, nullptr);
// Gather layers.
std::vector<VkLayerProperties> layer_properties;
err = vkEnumerateDeviceLayerProperties(device_handle, &count, nullptr);
CheckResult(err, "vkEnumerateDeviceLayerProperties");
layer_properties.resize(count);
err = vkEnumerateDeviceLayerProperties(device_handle, &count,
layer_properties.data());
CheckResult(err, "vkEnumerateDeviceLayerProperties");
for (size_t j = 0; j < layer_properties.size(); ++j) {
LayerInfo layer_info;
layer_info.properties = layer_properties[j];
err = vkEnumerateDeviceExtensionProperties(
device_handle, layer_info.properties.layerName, &count, nullptr);
CheckResult(err, "vkEnumerateDeviceExtensionProperties");
layer_info.extensions.resize(count);
err = vkEnumerateDeviceExtensionProperties(
device_handle, layer_info.properties.layerName, &count,
layer_info.extensions.data());
CheckResult(err, "vkEnumerateDeviceExtensionProperties");
device_info.layers.push_back(std::move(layer_info));
}
// Gather extensions.
err = vkEnumerateDeviceExtensionProperties(device_handle, nullptr, &count,
nullptr);
CheckResult(err, "vkEnumerateDeviceExtensionProperties");
device_info.extensions.resize(count);
err = vkEnumerateDeviceExtensionProperties(device_handle, nullptr, &count,
device_info.extensions.data());
CheckResult(err, "vkEnumerateDeviceExtensionProperties");
available_devices_.push_back(std::move(device_info));
}
XELOGVK("Found %d physical devices:", available_devices_.size());
for (size_t i = 0; i < available_devices_.size(); ++i) {
auto& device_info = available_devices_[i];
XELOGVK("- Device %d:", i);
DumpDeviceInfo(device_info);
}
return true;
}
void VulkanInstance::DumpLayers(const std::vector<LayerInfo>& layers,
const char* indent) {
for (size_t i = 0; i < layers.size(); ++i) {
auto& layer = layers[i];
auto spec_version = Version::Parse(layer.properties.specVersion);
auto impl_version = Version::Parse(layer.properties.implementationVersion);
XELOGVK("%s- %s (spec: %s, impl: %s)", indent, layer.properties.layerName,
spec_version.pretty_string.c_str(),
impl_version.pretty_string.c_str());
XELOGVK("%s %s", indent, layer.properties.description);
if (!layer.extensions.empty()) {
XELOGVK("%s %d extensions:", indent, layer.extensions.size());
DumpExtensions(layer.extensions, std::strlen(indent) ? " " : " ");
}
}
}
void VulkanInstance::DumpExtensions(
const std::vector<VkExtensionProperties>& extensions, const char* indent) {
for (size_t i = 0; i < extensions.size(); ++i) {
auto& extension = extensions[i];
auto version = Version::Parse(extension.specVersion);
XELOGVK("%s- %s (%s)", indent, extension.extensionName,
version.pretty_string.c_str());
}
}
void VulkanInstance::DumpDeviceInfo(const DeviceInfo& device_info) {
auto& properties = device_info.properties;
auto api_version = Version::Parse(properties.apiVersion);
auto driver_version = Version::Parse(properties.driverVersion);
XELOGVK(" apiVersion = %s", api_version.pretty_string.c_str());
XELOGVK(" driverVersion = %s", driver_version.pretty_string.c_str());
XELOGVK(" vendorId = 0x%04x", properties.vendorID);
XELOGVK(" deviceId = 0x%04x", properties.deviceID);
XELOGVK(" deviceType = %s", to_string(properties.deviceType));
XELOGVK(" deviceName = %s", properties.deviceName);
auto& memory_props = device_info.memory_properties;
XELOGVK(" Memory Heaps:");
for (size_t j = 0; j < memory_props.memoryHeapCount; ++j) {
XELOGVK(" - Heap %u: %" PRIu64 " bytes", j,
memory_props.memoryHeaps[j].size);
for (size_t k = 0; k < memory_props.memoryTypeCount; ++k) {
if (memory_props.memoryTypes[k].heapIndex == j) {
XELOGVK(" - Type %u:", k);
auto type_flags = memory_props.memoryTypes[k].propertyFlags;
if (!type_flags) {
XELOGVK(" VK_MEMORY_PROPERTY_DEVICE_ONLY");
}
if (type_flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
XELOGVK(" VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT");
}
if (type_flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
XELOGVK(" VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT");
}
if (type_flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) {
XELOGVK(" VK_MEMORY_PROPERTY_HOST_COHERENT_BIT");
}
if (type_flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) {
XELOGVK(" VK_MEMORY_PROPERTY_HOST_CACHED_BIT");
}
if (type_flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) {
XELOGVK(" VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT");
}
}
}
}
XELOGVK(" Queue Families:");
for (size_t j = 0; j < device_info.queue_family_properties.size(); ++j) {
auto& queue_props = device_info.queue_family_properties[j];
XELOGVK(" - Queue %d:", j);
XELOGVK(
" queueFlags = %s, %s, %s, %s",
(queue_props.queueFlags & VK_QUEUE_GRAPHICS_BIT) ? "graphics" : "",
(queue_props.queueFlags & VK_QUEUE_COMPUTE_BIT) ? "compute" : "",
(queue_props.queueFlags & VK_QUEUE_TRANSFER_BIT) ? "transfer" : "",
(queue_props.queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) ? "sparse" : "");
XELOGVK(" queueCount = %u", queue_props.queueCount);
XELOGVK(" timestampValidBits = %u", queue_props.timestampValidBits);
XELOGVK(" supportsPresent = %s",
device_info.queue_family_supports_present[j] ? "true" : "false");
}
XELOGVK(" Layers:");
DumpLayers(device_info.layers, " ");
XELOGVK(" Extensions:");
DumpExtensions(device_info.extensions, " ");
}
} // namespace vulkan
} // namespace ui
} // namespace xe

View File

@ -0,0 +1,95 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_UI_VULKAN_VULKAN_INSTANCE_H_
#define XENIA_UI_VULKAN_VULKAN_INSTANCE_H_
#include <memory>
#include <string>
#include <vector>
#include "xenia/ui/vulkan/vulkan.h"
#include "xenia/ui/vulkan/vulkan_util.h"
#include "xenia/ui/window.h"
namespace xe {
namespace ui {
namespace vulkan {
// Wrappers and utilities for VkInstance.
class VulkanInstance {
public:
VulkanInstance();
~VulkanInstance();
VkInstance handle = nullptr;
operator VkInstance() const { return handle; }
// Declares a layer to verify and enable upon initialization.
// Must be called before Initialize.
void DeclareRequiredLayer(std::string name, uint32_t min_version,
bool is_optional) {
required_layers_.push_back({name, min_version, is_optional});
}
// Declares an extension to verify and enable upon initialization.
// Must be called before Initialize.
void DeclareRequiredExtension(std::string name, uint32_t min_version,
bool is_optional) {
required_extensions_.push_back({name, min_version, is_optional});
}
// Initializes the instance, querying and enabling extensions and layers and
// preparing the instance for general use.
// If initialization succeeds it's likely that no more failures beyond runtime
// issues will occur.
// TODO(benvanik): remove need for any_target_window - it's just for queries.
bool Initialize(Window* any_target_window);
// Returns a list of all available devices as detected during initialization.
const std::vector<DeviceInfo>& available_devices() const {
return available_devices_;
}
private:
// Queries the system to find global extensions and layers.
bool QueryGlobals();
// Creates the instance, enabling required extensions and layers.
bool CreateInstance();
void DestroyInstance();
// Enables debugging info and callbacks for supported layers.
void EnableDebugValidation();
void DisableDebugValidation();
// Queries all available physical devices.
bool QueryDevices(Window* any_target_window);
void DumpLayers(const std::vector<LayerInfo>& layers, const char* indent);
void DumpExtensions(const std::vector<VkExtensionProperties>& extensions,
const char* indent);
void DumpDeviceInfo(const DeviceInfo& device_info);
std::vector<Requirement> required_layers_;
std::vector<Requirement> required_extensions_;
std::vector<LayerInfo> global_layers_;
std::vector<VkExtensionProperties> global_extensions_;
std::vector<DeviceInfo> available_devices_;
VkDebugReportCallbackEXT dbg_report_callback_ = nullptr;
};
} // namespace vulkan
} // namespace ui
} // namespace xe
#endif // XENIA_UI_VULKAN_VULKAN_INSTANCE_H_

View File

@ -0,0 +1,107 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/ui/vulkan/vulkan_provider.h"
#include <gflags/gflags.h>
#include <algorithm>
#include "xenia/base/logging.h"
#include "xenia/ui/vulkan/vulkan_context.h"
#include "xenia/ui/vulkan/vulkan_device.h"
#include "xenia/ui/vulkan/vulkan_instance.h"
#include "xenia/ui/vulkan/vulkan_util.h"
DEFINE_uint64(vulkan_device_index, 0, "Index of the physical device to use.");
namespace xe {
namespace ui {
namespace vulkan {
std::unique_ptr<GraphicsProvider> VulkanProvider::Create(Window* main_window) {
std::unique_ptr<VulkanProvider> provider(new VulkanProvider(main_window));
if (!provider->Initialize()) {
xe::FatalError(
"Unable to initialize Vulkan graphics subsystem.\n"
"Ensure you have the latest drivers for your GPU and that it "
"supports Vulkan. See http://xenia.jp/faq/ for more information and a "
"list of supported GPUs.");
return nullptr;
}
return std::unique_ptr<GraphicsProvider>(provider.release());
}
VulkanProvider::VulkanProvider(Window* main_window)
: GraphicsProvider(main_window) {}
VulkanProvider::~VulkanProvider() {
device_.reset();
instance_.reset();
}
bool VulkanProvider::Initialize() {
instance_ = std::make_unique<VulkanInstance>();
// Always enable the swapchain.
instance_->DeclareRequiredExtension("VK_KHR_surface", Version::Make(0, 0, 0),
false);
instance_->DeclareRequiredExtension("VK_KHR_win32_surface",
Version::Make(0, 0, 0), false);
// Attempt initialization and device query.
if (!instance_->Initialize(main_window_)) {
XELOGE("Failed to initialize vulkan instance");
return false;
}
// Pick the device to use.
auto available_devices = instance_->available_devices();
if (available_devices.empty()) {
XELOGE("No devices available for use");
return false;
}
size_t device_index =
std::min(available_devices.size(), FLAGS_vulkan_device_index);
auto& device_info = available_devices[device_index];
// Create the device.
device_ = std::make_unique<VulkanDevice>(instance_.get());
device_->DeclareRequiredExtension("VK_KHR_swapchain", Version::Make(0, 0, 0),
false);
if (!device_->Initialize(device_info)) {
XELOGE("Unable to initialize device");
return false;
}
return true;
}
std::unique_ptr<GraphicsContext> VulkanProvider::CreateContext(
Window* target_window) {
auto new_context =
std::unique_ptr<VulkanContext>(new VulkanContext(this, target_window));
if (!new_context->Initialize()) {
return nullptr;
}
return std::unique_ptr<GraphicsContext>(new_context.release());
}
std::unique_ptr<GraphicsContext> VulkanProvider::CreateOffscreenContext() {
auto new_context =
std::unique_ptr<VulkanContext>(new VulkanContext(this, nullptr));
if (!new_context->Initialize()) {
return nullptr;
}
return std::unique_ptr<GraphicsContext>(new_context.release());
}
} // namespace vulkan
} // namespace ui
} // namespace xe

View File

@ -0,0 +1,50 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_UI_VULKAN_VULKAN_PROVIDER_H_
#define XENIA_UI_VULKAN_VULKAN_PROVIDER_H_
#include <memory>
#include "xenia/ui/graphics_provider.h"
namespace xe {
namespace ui {
namespace vulkan {
class VulkanDevice;
class VulkanInstance;
class VulkanProvider : public GraphicsProvider {
public:
~VulkanProvider() override;
static std::unique_ptr<GraphicsProvider> Create(Window* main_window);
VulkanInstance* instance() const { return instance_.get(); }
VulkanDevice* device() const { return device_.get(); }
std::unique_ptr<GraphicsContext> CreateContext(
Window* target_window) override;
std::unique_ptr<GraphicsContext> CreateOffscreenContext() override;
protected:
explicit VulkanProvider(Window* main_window);
bool Initialize();
std::unique_ptr<VulkanInstance> instance_;
std::unique_ptr<VulkanDevice> device_;
};
} // namespace vulkan
} // namespace ui
} // namespace xe
#endif // XENIA_UI_VULKAN_VULKAN_PROVIDER_H_

View File

@ -0,0 +1,510 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/ui/vulkan/vulkan_swap_chain.h"
#include <gflags/gflags.h>
#include <mutex>
#include <string>
#include "xenia/base/assert.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/ui/vulkan/vulkan.h"
#include "xenia/ui/vulkan/vulkan_device.h"
#include "xenia/ui/vulkan/vulkan_instance.h"
#include "xenia/ui/vulkan/vulkan_util.h"
DEFINE_bool(vulkan_random_clear_color, false,
"Randomizes framebuffer clear color.");
namespace xe {
namespace ui {
namespace vulkan {
VulkanSwapChain::VulkanSwapChain(VulkanInstance* instance, VulkanDevice* device)
: instance_(instance), device_(device) {}
VulkanSwapChain::~VulkanSwapChain() {
for (auto& buffer : buffers_) {
DestroyBuffer(&buffer);
}
if (image_available_semaphore_) {
vkDestroySemaphore(*device_, image_available_semaphore_, nullptr);
}
if (render_pass_) {
vkDestroyRenderPass(*device_, render_pass_, nullptr);
}
if (render_cmd_buffer_) {
vkFreeCommandBuffers(*device_, cmd_pool_, 1, &render_cmd_buffer_);
}
if (cmd_pool_) {
vkDestroyCommandPool(*device_, cmd_pool_, nullptr);
}
// images_ doesn't need to be cleaned up as the swapchain does it implicitly.
if (handle) {
vkDestroySwapchainKHR(*device_, handle, nullptr);
handle = nullptr;
}
if (surface_) {
vkDestroySurfaceKHR(*instance_, surface_, nullptr);
}
}
bool VulkanSwapChain::Initialize(VkSurfaceKHR surface) {
surface_ = surface;
// Query supported target formats.
uint32_t count = 0;
auto err =
vkGetPhysicalDeviceSurfaceFormatsKHR(*device_, surface_, &count, nullptr);
CheckResult(err, "vkGetPhysicalDeviceSurfaceFormatsKHR");
std::vector<VkSurfaceFormatKHR> surface_formats;
surface_formats.resize(count);
err = vkGetPhysicalDeviceSurfaceFormatsKHR(*device_, surface_, &count,
surface_formats.data());
CheckResult(err, "vkGetPhysicalDeviceSurfaceFormatsKHR");
// If the format list includes just one entry of VK_FORMAT_UNDEFINED the
// surface has no preferred format.
// Otherwise, at least one supported format will be returned.
assert_true(surface_formats.size() >= 1);
if (surface_formats.size() == 1 &&
surface_formats[0].format == VK_FORMAT_UNDEFINED) {
// Fallback to common RGBA.
surface_format_ = VK_FORMAT_R8G8B8A8_UNORM;
} else {
// Use first defined format.
surface_format_ = surface_formats[0].format;
}
// Query surface min/max/caps.
VkSurfaceCapabilitiesKHR surface_caps;
err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(*device_, surface_,
&surface_caps);
CheckResult(err, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
// Query surface properties so we can configure ourselves within bounds.
std::vector<VkPresentModeKHR> present_modes;
err = vkGetPhysicalDeviceSurfacePresentModesKHR(*device_, surface_, &count,
nullptr);
CheckResult(err, "vkGetPhysicalDeviceSurfacePresentModesKHR");
present_modes.resize(count);
err = vkGetPhysicalDeviceSurfacePresentModesKHR(*device_, surface_, &count,
present_modes.data());
CheckResult(err, "vkGetPhysicalDeviceSurfacePresentModesKHR");
// Calculate swapchain target dimensions.
VkExtent2D extent = surface_caps.currentExtent;
if (surface_caps.currentExtent.width == -1) {
assert_true(surface_caps.currentExtent.height == -1);
// Undefined extents, so we need to pick something.
XELOGI("Swap chain target surface extents undefined; guessing value");
extent.width = 1280;
extent.height = 720;
}
surface_width_ = extent.width;
surface_height_ = extent.height;
// Always prefer mailbox mode (non-tearing, low-latency).
// If it's not available we'll use immediate (tearing, low-latency).
// If not even that we fall back to FIFO, which sucks.
VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR;
for (size_t i = 0; i < present_modes.size(); ++i) {
if (present_modes[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
// This is the best, so early-out.
present_mode = VK_PRESENT_MODE_MAILBOX_KHR;
break;
} else if (present_modes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR) {
present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR;
}
}
// Determine the number of images (1 + number queued).
uint32_t image_count = surface_caps.minImageCount + 1;
if (surface_caps.maxImageCount > 0 &&
image_count > surface_caps.maxImageCount) {
// Too many requested - use whatever we can.
XELOGI("Requested number of swapchain images (%d) exceeds maximum (%d)",
image_count, surface_caps.maxImageCount);
image_count = surface_caps.maxImageCount;
}
// Always pass through whatever transform the surface started with (so long
// as it's supported).
VkSurfaceTransformFlagBitsKHR pre_transform = surface_caps.currentTransform;
VkSwapchainCreateInfoKHR create_info;
create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
create_info.pNext = nullptr;
create_info.flags = 0;
create_info.surface = surface_;
create_info.minImageCount = image_count;
create_info.imageFormat = surface_format_;
create_info.imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
create_info.imageExtent.width = extent.width;
create_info.imageExtent.height = extent.height;
create_info.imageArrayLayers = 1;
create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
create_info.queueFamilyIndexCount = 0;
create_info.pQueueFamilyIndices = nullptr;
create_info.preTransform = pre_transform;
create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
create_info.presentMode = present_mode;
create_info.clipped = VK_TRUE;
create_info.oldSwapchain = nullptr;
XELOGVK("Creating swap chain:");
XELOGVK(" minImageCount = %u", create_info.minImageCount);
XELOGVK(" imageFormat = %s", to_string(create_info.imageFormat));
XELOGVK(" imageExtent = %d x %d", create_info.imageExtent.width,
create_info.imageExtent.height);
auto pre_transform_str = to_flags_string(create_info.preTransform);
XELOGVK(" preTransform = %s", pre_transform_str.c_str());
XELOGVK(" imageArrayLayers = %u", create_info.imageArrayLayers);
XELOGVK(" presentMode = %s", to_string(create_info.presentMode));
XELOGVK(" clipped = %s", create_info.clipped ? "true" : "false");
XELOGVK(" imageColorSpace = %s", to_string(create_info.imageColorSpace));
auto image_usage_flags_str = to_flags_string(create_info.imageUsage);
XELOGVK(" imageUsageFlags = %s", image_usage_flags_str.c_str());
XELOGVK(" imageSharingMode = %s", to_string(create_info.imageSharingMode));
XELOGVK(" queueFamilyCount = %u", create_info.queueFamilyIndexCount);
err = vkCreateSwapchainKHR(*device_, &create_info, nullptr, &handle);
if (err) {
XELOGE("Failed to create swapchain: %s", to_string(err));
return false;
}
// Create the pool used for transient buffers, so we can reset them all at
// once.
VkCommandPoolCreateInfo cmd_pool_info;
cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
cmd_pool_info.pNext = nullptr;
cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
cmd_pool_info.queueFamilyIndex = device_->queue_family_index();
err = vkCreateCommandPool(*device_, &cmd_pool_info, nullptr, &cmd_pool_);
CheckResult(err, "vkCreateCommandPool");
// Make a command buffer we'll do all our primary rendering from.
VkCommandBufferAllocateInfo cmd_buffer_info;
cmd_buffer_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
cmd_buffer_info.pNext = nullptr;
cmd_buffer_info.commandPool = cmd_pool_;
cmd_buffer_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
cmd_buffer_info.commandBufferCount = 1;
err =
vkAllocateCommandBuffers(*device_, &cmd_buffer_info, &render_cmd_buffer_);
CheckResult(err, "vkCreateCommandBuffer");
// Create the render pass used to draw to the swap chain.
// The actual framebuffer attached will depend on which image we are drawing
// into.
VkAttachmentDescription color_attachment;
color_attachment.flags = 0;
color_attachment.format = surface_format_;
color_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
color_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
color_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
color_attachment.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
color_attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentReference color_reference;
color_reference.attachment = 0;
color_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentReference depth_reference;
depth_reference.attachment = VK_ATTACHMENT_UNUSED;
depth_reference.layout = VK_IMAGE_LAYOUT_UNDEFINED;
VkSubpassDescription render_subpass;
render_subpass.flags = 0;
render_subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
render_subpass.inputAttachmentCount = 0;
render_subpass.pInputAttachments = nullptr;
render_subpass.colorAttachmentCount = 1;
render_subpass.pColorAttachments = &color_reference;
render_subpass.pResolveAttachments = nullptr;
render_subpass.pDepthStencilAttachment = &depth_reference;
render_subpass.preserveAttachmentCount = 0,
render_subpass.pPreserveAttachments = nullptr;
VkRenderPassCreateInfo render_pass_info;
render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
render_pass_info.pNext = nullptr;
render_pass_info.attachmentCount = 1;
render_pass_info.pAttachments = &color_attachment;
render_pass_info.subpassCount = 1;
render_pass_info.pSubpasses = &render_subpass;
render_pass_info.dependencyCount = 0;
render_pass_info.pDependencies = nullptr;
err = vkCreateRenderPass(*device_, &render_pass_info, nullptr, &render_pass_);
CheckResult(err, "vkCreateRenderPass");
// Create a semaphore we'll use to synchronize with the swapchain.
VkSemaphoreCreateInfo semaphore_info;
semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
semaphore_info.pNext = nullptr;
semaphore_info.flags = 0;
err = vkCreateSemaphore(*device_, &semaphore_info, nullptr,
&image_available_semaphore_);
CheckResult(err, "vkCreateSemaphore");
// Get images we will be presenting to.
// Note that this may differ from our requested amount.
uint32_t actual_image_count = 0;
std::vector<VkImage> images;
err = vkGetSwapchainImagesKHR(*device_, handle, &actual_image_count, nullptr);
CheckResult(err, "vkGetSwapchainImagesKHR");
images.resize(actual_image_count);
err = vkGetSwapchainImagesKHR(*device_, handle, &actual_image_count,
images.data());
CheckResult(err, "vkGetSwapchainImagesKHR");
// Create all buffers.
buffers_.resize(images.size());
for (size_t i = 0; i < buffers_.size(); ++i) {
if (!InitializeBuffer(&buffers_[i], images[i])) {
XELOGE("Failed to initialize a swapchain buffer");
return false;
}
}
XELOGVK("Swap chain initialized successfully!");
return true;
}
bool VulkanSwapChain::InitializeBuffer(Buffer* buffer, VkImage target_image) {
DestroyBuffer(buffer);
buffer->image = target_image;
// Create an image view for the presentation image.
// This will be used as a framebuffer attachment.
VkImageViewCreateInfo image_view_info;
image_view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
image_view_info.pNext = nullptr;
image_view_info.flags = 0;
image_view_info.image = buffer->image;
image_view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
image_view_info.format = surface_format_;
image_view_info.components.r = VK_COMPONENT_SWIZZLE_R;
image_view_info.components.g = VK_COMPONENT_SWIZZLE_G;
image_view_info.components.b = VK_COMPONENT_SWIZZLE_B;
image_view_info.components.a = VK_COMPONENT_SWIZZLE_A;
image_view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
image_view_info.subresourceRange.baseMipLevel = 0;
image_view_info.subresourceRange.levelCount = 1;
image_view_info.subresourceRange.baseArrayLayer = 0;
image_view_info.subresourceRange.layerCount = 1;
auto err = vkCreateImageView(*device_, &image_view_info, nullptr,
&buffer->image_view);
CheckResult(err, "vkCreateImageView");
// Create the framebuffer used to render into this image.
VkImageView attachments[] = {buffer->image_view};
VkFramebufferCreateInfo framebuffer_info;
framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebuffer_info.pNext = nullptr;
framebuffer_info.renderPass = render_pass_;
framebuffer_info.attachmentCount =
static_cast<uint32_t>(xe::countof(attachments));
framebuffer_info.pAttachments = attachments;
framebuffer_info.width = surface_width_;
framebuffer_info.height = surface_height_;
framebuffer_info.layers = 1;
err = vkCreateFramebuffer(*device_, &framebuffer_info, nullptr,
&buffer->framebuffer);
CheckResult(err, "vkCreateFramebuffer");
return true;
}
void VulkanSwapChain::DestroyBuffer(Buffer* buffer) {
if (buffer->framebuffer) {
vkDestroyFramebuffer(*device_, buffer->framebuffer, nullptr);
buffer->framebuffer = nullptr;
}
if (buffer->image_view) {
vkDestroyImageView(*device_, buffer->image_view, nullptr);
buffer->image_view = nullptr;
}
// Image is taken care of by the presentation engine.
buffer->image = nullptr;
}
bool VulkanSwapChain::Begin() {
// Get the index of the next available swapchain image.
auto err =
vkAcquireNextImageKHR(*device_, handle, 0, image_available_semaphore_,
nullptr, &current_buffer_index_);
CheckResult(err, "vkAcquireNextImageKHR");
// Wait for the acquire semaphore to be signaled so that the following
// operations know they can start modifying the image.
VkSubmitInfo wait_submit_info;
wait_submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
wait_submit_info.pNext = nullptr;
wait_submit_info.waitSemaphoreCount = 1;
wait_submit_info.pWaitSemaphores = &image_available_semaphore_;
wait_submit_info.commandBufferCount = 0;
wait_submit_info.pCommandBuffers = nullptr;
wait_submit_info.signalSemaphoreCount = 0;
wait_submit_info.pSignalSemaphores = nullptr;
err = vkQueueSubmit(device_->primary_queue(), 1, &wait_submit_info, nullptr);
CheckResult(err, "vkQueueSubmit");
// Reset all command buffers.
vkResetCommandBuffer(render_cmd_buffer_,
VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
auto& current_buffer = buffers_[current_buffer_index_];
// Build the command buffer that will execute all queued rendering buffers.
VkCommandBufferBeginInfo begin_info;
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
begin_info.pNext = nullptr;
begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
begin_info.pInheritanceInfo = nullptr;
err = vkBeginCommandBuffer(render_cmd_buffer_, &begin_info);
CheckResult(err, "vkBeginCommandBuffer");
// Transition the image to a format we can render to.
VkImageMemoryBarrier pre_image_memory_barrier;
pre_image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
pre_image_memory_barrier.pNext = nullptr;
pre_image_memory_barrier.srcAccessMask = 0;
pre_image_memory_barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
pre_image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
pre_image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
pre_image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
pre_image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
pre_image_memory_barrier.image = current_buffer.image;
pre_image_memory_barrier.subresourceRange.aspectMask =
VK_IMAGE_ASPECT_COLOR_BIT;
pre_image_memory_barrier.subresourceRange.baseMipLevel = 0;
pre_image_memory_barrier.subresourceRange.levelCount = 1;
pre_image_memory_barrier.subresourceRange.baseArrayLayer = 0;
pre_image_memory_barrier.subresourceRange.layerCount = 1;
vkCmdPipelineBarrier(render_cmd_buffer_, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0,
nullptr, 1, &pre_image_memory_barrier);
// Begin render pass.
VkClearValue color_clear_value;
color_clear_value.color.float32[0] = 238 / 255.0f;
color_clear_value.color.float32[1] = 238 / 255.0f;
color_clear_value.color.float32[2] = 238 / 255.0f;
color_clear_value.color.float32[3] = 1.0f;
if (FLAGS_vulkan_random_clear_color) {
color_clear_value.color.float32[0] =
rand() / static_cast<float>(RAND_MAX); // NOLINT(runtime/threadsafe_fn)
color_clear_value.color.float32[1] = 1.0f;
color_clear_value.color.float32[2] = 0.0f;
}
VkClearValue clear_values[] = {color_clear_value};
VkRenderPassBeginInfo render_pass_begin_info;
render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
render_pass_begin_info.pNext = nullptr;
render_pass_begin_info.renderPass = render_pass_;
render_pass_begin_info.framebuffer = current_buffer.framebuffer;
render_pass_begin_info.renderArea.offset.x = 0;
render_pass_begin_info.renderArea.offset.y = 0;
render_pass_begin_info.renderArea.extent.width = surface_width_;
render_pass_begin_info.renderArea.extent.height = surface_height_;
render_pass_begin_info.clearValueCount =
static_cast<uint32_t>(xe::countof(clear_values));
render_pass_begin_info.pClearValues = clear_values;
vkCmdBeginRenderPass(render_cmd_buffer_, &render_pass_begin_info,
VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
return true;
}
bool VulkanSwapChain::End() {
auto& current_buffer = buffers_[current_buffer_index_];
// End render pass.
vkCmdEndRenderPass(render_cmd_buffer_);
// Transition the image to a format the presentation engine can source from.
VkImageMemoryBarrier post_image_memory_barrier;
post_image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
post_image_memory_barrier.pNext = nullptr;
post_image_memory_barrier.srcAccessMask =
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
post_image_memory_barrier.dstAccessMask = 0;
post_image_memory_barrier.oldLayout =
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
post_image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
post_image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
post_image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
post_image_memory_barrier.image = current_buffer.image;
post_image_memory_barrier.subresourceRange.aspectMask =
VK_IMAGE_ASPECT_COLOR_BIT;
post_image_memory_barrier.subresourceRange.baseMipLevel = 0;
post_image_memory_barrier.subresourceRange.levelCount = 1;
post_image_memory_barrier.subresourceRange.baseArrayLayer = 0;
post_image_memory_barrier.subresourceRange.layerCount = 1;
vkCmdPipelineBarrier(render_cmd_buffer_, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0,
nullptr, 1, &post_image_memory_barrier);
auto err = vkEndCommandBuffer(render_cmd_buffer_);
CheckResult(err, "vkEndCommandBuffer");
// Submit rendering.
VkSubmitInfo render_submit_info;
render_submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
render_submit_info.pNext = nullptr;
render_submit_info.waitSemaphoreCount = 0;
render_submit_info.pWaitSemaphores = nullptr;
render_submit_info.commandBufferCount = 1;
render_submit_info.pCommandBuffers = &render_cmd_buffer_;
render_submit_info.signalSemaphoreCount = 0;
render_submit_info.pSignalSemaphores = nullptr;
err =
vkQueueSubmit(device_->primary_queue(), 1, &render_submit_info, nullptr);
CheckResult(err, "vkQueueSubmit");
// Queue the present of our current image.
const VkSwapchainKHR swap_chains[] = {handle};
const uint32_t swap_chain_image_indices[] = {current_buffer_index_};
VkPresentInfoKHR present_info;
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
present_info.pNext = nullptr;
present_info.waitSemaphoreCount = 0;
present_info.pWaitSemaphores = nullptr;
present_info.swapchainCount = static_cast<uint32_t>(xe::countof(swap_chains));
present_info.pSwapchains = swap_chains;
present_info.pImageIndices = swap_chain_image_indices;
present_info.pResults = nullptr;
err = vkQueuePresentKHR(device_->primary_queue(), &present_info);
switch (err) {
case VK_SUCCESS:
break;
case VK_SUBOPTIMAL_KHR:
// We are not rendering at the right size - but the presentation engine
// will scale the output for us.
break;
case VK_ERROR_OUT_OF_DATE_KHR:
// Lost presentation ability; need to recreate the swapchain.
// TODO(benvanik): recreate swapchain.
assert_always("Swapchain recreation not implemented");
break;
default:
XELOGE("Failed to queue present: %s", to_string(err));
assert_always("Unexpected queue present failure");
return false;
}
return true;
}
} // namespace vulkan
} // namespace ui
} // namespace xe

View File

@ -0,0 +1,80 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_UI_VULKAN_VULKAN_SWAP_CHAIN_H_
#define XENIA_UI_VULKAN_VULKAN_SWAP_CHAIN_H_
#include <memory>
#include <string>
#include <vector>
#include "xenia/ui/vulkan/vulkan.h"
#include "xenia/ui/vulkan/vulkan_util.h"
namespace xe {
namespace ui {
namespace vulkan {
class VulkanDevice;
class VulkanInstance;
class VulkanSwapChain {
public:
VulkanSwapChain(VulkanInstance* instance, VulkanDevice* device);
~VulkanSwapChain();
VkSwapchainKHR handle = nullptr;
operator VkSwapchainKHR() const { return handle; }
uint32_t surface_width() const { return surface_width_; }
uint32_t surface_height() const { return surface_height_; }
// Render pass used for compositing.
VkRenderPass render_pass() const { return render_pass_; }
// Render command buffer, active inside the render pass from Begin to End.
VkCommandBuffer render_cmd_buffer() const { return render_cmd_buffer_; }
bool Initialize(VkSurfaceKHR surface);
// Begins the swap operation, preparing state for rendering.
bool Begin();
// Ends the swap operation, finalizing rendering and presenting the results.
bool End();
private:
struct Buffer {
VkImage image = nullptr;
VkImageView image_view = nullptr;
VkFramebuffer framebuffer = nullptr;
};
bool InitializeBuffer(Buffer* buffer, VkImage target_image);
void DestroyBuffer(Buffer* buffer);
VulkanInstance* instance_ = nullptr;
VulkanDevice* device_ = nullptr;
VkSurfaceKHR surface_ = nullptr;
uint32_t surface_width_ = 0;
uint32_t surface_height_ = 0;
VkFormat surface_format_ = VK_FORMAT_UNDEFINED;
VkCommandPool cmd_pool_ = nullptr;
VkCommandBuffer render_cmd_buffer_ = nullptr;
VkRenderPass render_pass_ = nullptr;
VkSemaphore image_available_semaphore_ = nullptr;
uint32_t current_buffer_index_ = 0;
std::vector<Buffer> buffers_;
};
} // namespace vulkan
} // namespace ui
} // namespace xe
#endif // XENIA_UI_VULKAN_VULKAN_SWAP_CHAIN_H_

View File

@ -0,0 +1,464 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/ui/vulkan/vulkan_util.h"
#include "xenia/base/assert.h"
#include "xenia/base/logging.h"
namespace xe {
namespace ui {
namespace vulkan {
uint32_t Version::Make(uint32_t major, uint32_t minor, uint32_t patch) {
return VK_MAKE_VERSION(major, minor, patch);
}
Version Version::Parse(uint32_t value) {
Version version;
version.major = VK_VERSION_MAJOR(value);
version.minor = VK_VERSION_MINOR(value);
version.patch = VK_VERSION_PATCH(value);
version.pretty_string = xe::format_string("%u.%u.%u", version.major,
version.minor, version.patch);
return version;
}
const char* to_string(VkFormat format) {
switch (format) {
#define STR(r) \
case r: \
return #r
STR(VK_FORMAT_UNDEFINED);
STR(VK_FORMAT_R4G4_UNORM_PACK8);
STR(VK_FORMAT_R4G4B4A4_UNORM_PACK16);
STR(VK_FORMAT_B4G4R4A4_UNORM_PACK16);
STR(VK_FORMAT_R5G6B5_UNORM_PACK16);
STR(VK_FORMAT_B5G6R5_UNORM_PACK16);
STR(VK_FORMAT_R5G5B5A1_UNORM_PACK16);
STR(VK_FORMAT_B5G5R5A1_UNORM_PACK16);
STR(VK_FORMAT_A1R5G5B5_UNORM_PACK16);
STR(VK_FORMAT_R8_UNORM);
STR(VK_FORMAT_R8_SNORM);
STR(VK_FORMAT_R8_USCALED);
STR(VK_FORMAT_R8_SSCALED);
STR(VK_FORMAT_R8_UINT);
STR(VK_FORMAT_R8_SINT);
STR(VK_FORMAT_R8_SRGB);
STR(VK_FORMAT_R8G8_UNORM);
STR(VK_FORMAT_R8G8_SNORM);
STR(VK_FORMAT_R8G8_USCALED);
STR(VK_FORMAT_R8G8_SSCALED);
STR(VK_FORMAT_R8G8_UINT);
STR(VK_FORMAT_R8G8_SINT);
STR(VK_FORMAT_R8G8_SRGB);
STR(VK_FORMAT_R8G8B8_UNORM);
STR(VK_FORMAT_R8G8B8_SNORM);
STR(VK_FORMAT_R8G8B8_USCALED);
STR(VK_FORMAT_R8G8B8_SSCALED);
STR(VK_FORMAT_R8G8B8_UINT);
STR(VK_FORMAT_R8G8B8_SINT);
STR(VK_FORMAT_R8G8B8_SRGB);
STR(VK_FORMAT_B8G8R8_UNORM);
STR(VK_FORMAT_B8G8R8_SNORM);
STR(VK_FORMAT_B8G8R8_USCALED);
STR(VK_FORMAT_B8G8R8_SSCALED);
STR(VK_FORMAT_B8G8R8_UINT);
STR(VK_FORMAT_B8G8R8_SINT);
STR(VK_FORMAT_B8G8R8_SRGB);
STR(VK_FORMAT_R8G8B8A8_UNORM);
STR(VK_FORMAT_R8G8B8A8_SNORM);
STR(VK_FORMAT_R8G8B8A8_USCALED);
STR(VK_FORMAT_R8G8B8A8_SSCALED);
STR(VK_FORMAT_R8G8B8A8_UINT);
STR(VK_FORMAT_R8G8B8A8_SINT);
STR(VK_FORMAT_R8G8B8A8_SRGB);
STR(VK_FORMAT_B8G8R8A8_UNORM);
STR(VK_FORMAT_B8G8R8A8_SNORM);
STR(VK_FORMAT_B8G8R8A8_USCALED);
STR(VK_FORMAT_B8G8R8A8_SSCALED);
STR(VK_FORMAT_B8G8R8A8_UINT);
STR(VK_FORMAT_B8G8R8A8_SINT);
STR(VK_FORMAT_B8G8R8A8_SRGB);
STR(VK_FORMAT_A8B8G8R8_UNORM_PACK32);
STR(VK_FORMAT_A8B8G8R8_SNORM_PACK32);
STR(VK_FORMAT_A8B8G8R8_USCALED_PACK32);
STR(VK_FORMAT_A8B8G8R8_SSCALED_PACK32);
STR(VK_FORMAT_A8B8G8R8_UINT_PACK32);
STR(VK_FORMAT_A8B8G8R8_SINT_PACK32);
STR(VK_FORMAT_A8B8G8R8_SRGB_PACK32);
STR(VK_FORMAT_A2R10G10B10_UNORM_PACK32);
STR(VK_FORMAT_A2R10G10B10_SNORM_PACK32);
STR(VK_FORMAT_A2R10G10B10_USCALED_PACK32);
STR(VK_FORMAT_A2R10G10B10_SSCALED_PACK32);
STR(VK_FORMAT_A2R10G10B10_UINT_PACK32);
STR(VK_FORMAT_A2R10G10B10_SINT_PACK32);
STR(VK_FORMAT_A2B10G10R10_UNORM_PACK32);
STR(VK_FORMAT_A2B10G10R10_SNORM_PACK32);
STR(VK_FORMAT_A2B10G10R10_USCALED_PACK32);
STR(VK_FORMAT_A2B10G10R10_SSCALED_PACK32);
STR(VK_FORMAT_A2B10G10R10_UINT_PACK32);
STR(VK_FORMAT_A2B10G10R10_SINT_PACK32);
STR(VK_FORMAT_R16_UNORM);
STR(VK_FORMAT_R16_SNORM);
STR(VK_FORMAT_R16_USCALED);
STR(VK_FORMAT_R16_SSCALED);
STR(VK_FORMAT_R16_UINT);
STR(VK_FORMAT_R16_SINT);
STR(VK_FORMAT_R16_SFLOAT);
STR(VK_FORMAT_R16G16_UNORM);
STR(VK_FORMAT_R16G16_SNORM);
STR(VK_FORMAT_R16G16_USCALED);
STR(VK_FORMAT_R16G16_SSCALED);
STR(VK_FORMAT_R16G16_UINT);
STR(VK_FORMAT_R16G16_SINT);
STR(VK_FORMAT_R16G16_SFLOAT);
STR(VK_FORMAT_R16G16B16_UNORM);
STR(VK_FORMAT_R16G16B16_SNORM);
STR(VK_FORMAT_R16G16B16_USCALED);
STR(VK_FORMAT_R16G16B16_SSCALED);
STR(VK_FORMAT_R16G16B16_UINT);
STR(VK_FORMAT_R16G16B16_SINT);
STR(VK_FORMAT_R16G16B16_SFLOAT);
STR(VK_FORMAT_R16G16B16A16_UNORM);
STR(VK_FORMAT_R16G16B16A16_SNORM);
STR(VK_FORMAT_R16G16B16A16_USCALED);
STR(VK_FORMAT_R16G16B16A16_SSCALED);
STR(VK_FORMAT_R16G16B16A16_UINT);
STR(VK_FORMAT_R16G16B16A16_SINT);
STR(VK_FORMAT_R16G16B16A16_SFLOAT);
STR(VK_FORMAT_R32_UINT);
STR(VK_FORMAT_R32_SINT);
STR(VK_FORMAT_R32_SFLOAT);
STR(VK_FORMAT_R32G32_UINT);
STR(VK_FORMAT_R32G32_SINT);
STR(VK_FORMAT_R32G32_SFLOAT);
STR(VK_FORMAT_R32G32B32_UINT);
STR(VK_FORMAT_R32G32B32_SINT);
STR(VK_FORMAT_R32G32B32_SFLOAT);
STR(VK_FORMAT_R32G32B32A32_UINT);
STR(VK_FORMAT_R32G32B32A32_SINT);
STR(VK_FORMAT_R32G32B32A32_SFLOAT);
STR(VK_FORMAT_R64_UINT);
STR(VK_FORMAT_R64_SINT);
STR(VK_FORMAT_R64_SFLOAT);
STR(VK_FORMAT_R64G64_UINT);
STR(VK_FORMAT_R64G64_SINT);
STR(VK_FORMAT_R64G64_SFLOAT);
STR(VK_FORMAT_R64G64B64_UINT);
STR(VK_FORMAT_R64G64B64_SINT);
STR(VK_FORMAT_R64G64B64_SFLOAT);
STR(VK_FORMAT_R64G64B64A64_UINT);
STR(VK_FORMAT_R64G64B64A64_SINT);
STR(VK_FORMAT_R64G64B64A64_SFLOAT);
STR(VK_FORMAT_B10G11R11_UFLOAT_PACK32);
STR(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32);
STR(VK_FORMAT_D16_UNORM);
STR(VK_FORMAT_X8_D24_UNORM_PACK32);
STR(VK_FORMAT_D32_SFLOAT);
STR(VK_FORMAT_S8_UINT);
STR(VK_FORMAT_D16_UNORM_S8_UINT);
STR(VK_FORMAT_D24_UNORM_S8_UINT);
STR(VK_FORMAT_D32_SFLOAT_S8_UINT);
STR(VK_FORMAT_BC1_RGB_UNORM_BLOCK);
STR(VK_FORMAT_BC1_RGB_SRGB_BLOCK);
STR(VK_FORMAT_BC1_RGBA_UNORM_BLOCK);
STR(VK_FORMAT_BC1_RGBA_SRGB_BLOCK);
STR(VK_FORMAT_BC2_UNORM_BLOCK);
STR(VK_FORMAT_BC2_SRGB_BLOCK);
STR(VK_FORMAT_BC3_UNORM_BLOCK);
STR(VK_FORMAT_BC3_SRGB_BLOCK);
STR(VK_FORMAT_BC4_UNORM_BLOCK);
STR(VK_FORMAT_BC4_SNORM_BLOCK);
STR(VK_FORMAT_BC5_UNORM_BLOCK);
STR(VK_FORMAT_BC5_SNORM_BLOCK);
STR(VK_FORMAT_BC6H_UFLOAT_BLOCK);
STR(VK_FORMAT_BC6H_SFLOAT_BLOCK);
STR(VK_FORMAT_BC7_UNORM_BLOCK);
STR(VK_FORMAT_BC7_SRGB_BLOCK);
STR(VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK);
STR(VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK);
STR(VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK);
STR(VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK);
STR(VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK);
STR(VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK);
STR(VK_FORMAT_EAC_R11_UNORM_BLOCK);
STR(VK_FORMAT_EAC_R11_SNORM_BLOCK);
STR(VK_FORMAT_EAC_R11G11_UNORM_BLOCK);
STR(VK_FORMAT_EAC_R11G11_SNORM_BLOCK);
STR(VK_FORMAT_ASTC_4x4_UNORM_BLOCK);
STR(VK_FORMAT_ASTC_4x4_SRGB_BLOCK);
STR(VK_FORMAT_ASTC_5x4_UNORM_BLOCK);
STR(VK_FORMAT_ASTC_5x4_SRGB_BLOCK);
STR(VK_FORMAT_ASTC_5x5_UNORM_BLOCK);
STR(VK_FORMAT_ASTC_5x5_SRGB_BLOCK);
STR(VK_FORMAT_ASTC_6x5_UNORM_BLOCK);
STR(VK_FORMAT_ASTC_6x5_SRGB_BLOCK);
STR(VK_FORMAT_ASTC_6x6_UNORM_BLOCK);
STR(VK_FORMAT_ASTC_6x6_SRGB_BLOCK);
STR(VK_FORMAT_ASTC_8x5_UNORM_BLOCK);
STR(VK_FORMAT_ASTC_8x5_SRGB_BLOCK);
STR(VK_FORMAT_ASTC_8x6_UNORM_BLOCK);
STR(VK_FORMAT_ASTC_8x6_SRGB_BLOCK);
STR(VK_FORMAT_ASTC_8x8_UNORM_BLOCK);
STR(VK_FORMAT_ASTC_8x8_SRGB_BLOCK);
STR(VK_FORMAT_ASTC_10x5_UNORM_BLOCK);
STR(VK_FORMAT_ASTC_10x5_SRGB_BLOCK);
STR(VK_FORMAT_ASTC_10x6_UNORM_BLOCK);
STR(VK_FORMAT_ASTC_10x6_SRGB_BLOCK);
STR(VK_FORMAT_ASTC_10x8_UNORM_BLOCK);
STR(VK_FORMAT_ASTC_10x8_SRGB_BLOCK);
STR(VK_FORMAT_ASTC_10x10_UNORM_BLOCK);
STR(VK_FORMAT_ASTC_10x10_SRGB_BLOCK);
STR(VK_FORMAT_ASTC_12x10_UNORM_BLOCK);
STR(VK_FORMAT_ASTC_12x10_SRGB_BLOCK);
STR(VK_FORMAT_ASTC_12x12_UNORM_BLOCK);
STR(VK_FORMAT_ASTC_12x12_SRGB_BLOCK);
#undef STR
default:
return "UNKNOWN_FORMAT";
}
}
const char* to_string(VkPhysicalDeviceType type) {
switch (type) {
#define STR(r) \
case r: \
return #r
STR(VK_PHYSICAL_DEVICE_TYPE_OTHER);
STR(VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU);
STR(VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU);
STR(VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU);
STR(VK_PHYSICAL_DEVICE_TYPE_CPU);
#undef STR
default:
return "UNKNOWN_DEVICE";
}
}
const char* to_string(VkSharingMode sharing_mode) {
switch (sharing_mode) {
#define STR(r) \
case r: \
return #r
STR(VK_SHARING_MODE_EXCLUSIVE);
STR(VK_SHARING_MODE_CONCURRENT);
#undef STR
default:
return "UNKNOWN_SHARING_MODE";
}
}
const char* to_string(VkResult result) {
switch (result) {
#define STR(r) \
case r: \
return #r
STR(VK_SUCCESS);
STR(VK_NOT_READY);
STR(VK_TIMEOUT);
STR(VK_EVENT_SET);
STR(VK_EVENT_RESET);
STR(VK_INCOMPLETE);
STR(VK_ERROR_OUT_OF_HOST_MEMORY);
STR(VK_ERROR_OUT_OF_DEVICE_MEMORY);
STR(VK_ERROR_INITIALIZATION_FAILED);
STR(VK_ERROR_DEVICE_LOST);
STR(VK_ERROR_MEMORY_MAP_FAILED);
STR(VK_ERROR_LAYER_NOT_PRESENT);
STR(VK_ERROR_EXTENSION_NOT_PRESENT);
STR(VK_ERROR_FEATURE_NOT_PRESENT);
STR(VK_ERROR_INCOMPATIBLE_DRIVER);
STR(VK_ERROR_TOO_MANY_OBJECTS);
STR(VK_ERROR_FORMAT_NOT_SUPPORTED);
STR(VK_ERROR_SURFACE_LOST_KHR);
STR(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR);
STR(VK_SUBOPTIMAL_KHR);
STR(VK_ERROR_OUT_OF_DATE_KHR);
STR(VK_ERROR_INCOMPATIBLE_DISPLAY_KHR);
STR(VK_ERROR_VALIDATION_FAILED_EXT);
#undef STR
default:
return "UNKNOWN_RESULT";
}
}
std::string to_flags_string(VkImageUsageFlags flags) {
std::string result;
#define OR_FLAG(f) \
if (flags & f) { \
if (!result.empty()) { \
result += " | "; \
} \
result += #f; \
}
OR_FLAG(VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
OR_FLAG(VK_IMAGE_USAGE_TRANSFER_DST_BIT);
OR_FLAG(VK_IMAGE_USAGE_SAMPLED_BIT);
OR_FLAG(VK_IMAGE_USAGE_STORAGE_BIT);
OR_FLAG(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
OR_FLAG(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
OR_FLAG(VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT);
OR_FLAG(VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
#undef OR_FLAG
return result;
}
std::string to_flags_string(VkSurfaceTransformFlagBitsKHR flags) {
std::string result;
#define OR_FLAG(f) \
if (flags & f) { \
if (!result.empty()) { \
result += " | "; \
} \
result += #f; \
}
OR_FLAG(VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR);
OR_FLAG(VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR);
OR_FLAG(VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR);
OR_FLAG(VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR);
OR_FLAG(VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR);
OR_FLAG(VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR);
OR_FLAG(VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR);
OR_FLAG(VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR);
OR_FLAG(VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR);
#undef OR_FLAG
return result;
}
const char* to_string(VkColorSpaceKHR color_space) {
switch (color_space) {
#define STR(r) \
case r: \
return #r
STR(VK_COLORSPACE_SRGB_NONLINEAR_KHR);
#undef STR
default:
return "UNKNOWN_COLORSPACE";
}
}
const char* to_string(VkPresentModeKHR present_mode) {
switch (present_mode) {
#define STR(r) \
case r: \
return #r
STR(VK_PRESENT_MODE_IMMEDIATE_KHR);
STR(VK_PRESENT_MODE_MAILBOX_KHR);
STR(VK_PRESENT_MODE_FIFO_KHR);
STR(VK_PRESENT_MODE_FIFO_RELAXED_KHR);
#undef STR
default:
return "UNKNOWN_PRESENT_MODE";
}
}
void FatalVulkanError(std::string error) {
xe::FatalError(
error +
"\nEnsure you have the latest drivers for your GPU and that it supports "
"Vulkan. See http://xenia.jp/faq/ for more information and a list"
"of supported GPUs.");
}
void CheckResult(VkResult result, const char* action) {
if (result) {
XELOGE("Vulkan check: %s returned %s", action, to_string(result));
}
assert_true(result == VK_SUCCESS, action);
}
std::pair<bool, std::vector<const char*>> CheckRequirements(
const std::vector<Requirement>& requirements,
const std::vector<LayerInfo>& layer_infos) {
bool any_missing = false;
std::vector<const char*> enabled_layers;
for (auto& requirement : requirements) {
bool found = false;
for (size_t j = 0; j < layer_infos.size(); ++j) {
auto layer_name = layer_infos[j].properties.layerName;
auto layer_version =
Version::Parse(layer_infos[j].properties.specVersion);
if (requirement.name == layer_name) {
found = true;
if (requirement.min_version > layer_infos[j].properties.specVersion) {
if (requirement.is_optional) {
XELOGVK("- optional layer %s (%s) version mismatch", layer_name,
layer_version.pretty_string.c_str());
continue;
}
XELOGE("ERROR: required layer %s (%s) version mismatch", layer_name,
layer_version.pretty_string.c_str());
any_missing = true;
break;
}
XELOGVK("- enabling layer %s (%s)", layer_name,
layer_version.pretty_string.c_str());
enabled_layers.push_back(layer_name);
break;
}
}
if (!found) {
if (requirement.is_optional) {
XELOGVK("- optional layer %s not found", requirement.name.c_str());
} else {
XELOGE("ERROR: required layer %s not found", requirement.name.c_str());
any_missing = true;
}
}
}
return {!any_missing, enabled_layers};
}
std::pair<bool, std::vector<const char*>> CheckRequirements(
const std::vector<Requirement>& requirements,
const std::vector<VkExtensionProperties>& extension_properties) {
bool any_missing = false;
std::vector<const char*> enabled_extensions;
for (auto& requirement : requirements) {
bool found = false;
for (size_t j = 0; j < extension_properties.size(); ++j) {
auto extension_name = extension_properties[j].extensionName;
auto extension_version =
Version::Parse(extension_properties[j].specVersion);
if (requirement.name == extension_name) {
found = true;
if (requirement.min_version > extension_properties[j].specVersion) {
if (requirement.is_optional) {
XELOGVK("- optional extension %s (%s) version mismatch",
extension_name, extension_version.pretty_string.c_str());
continue;
}
XELOGE("ERROR: required extension %s (%s) version mismatch",
extension_name, extension_version.pretty_string.c_str());
any_missing = true;
break;
}
XELOGVK("- enabling extension %s (%s)", extension_name,
extension_version.pretty_string.c_str());
enabled_extensions.push_back(extension_name);
break;
}
}
if (!found) {
if (requirement.is_optional) {
XELOGVK("- optional extension %s not found", requirement.name.c_str());
} else {
XELOGE("ERROR: required extension %s not found",
requirement.name.c_str());
any_missing = true;
}
}
}
return {!any_missing, enabled_extensions};
}
} // namespace vulkan
} // namespace ui
} // namespace xe

View File

@ -0,0 +1,101 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_UI_VULKAN_VULKAN_UTIL_H_
#define XENIA_UI_VULKAN_VULKAN_UTIL_H_
#include <memory>
#include <string>
#include "xenia/ui/vulkan/vulkan.h"
namespace xe {
namespace ui {
class Window;
} // namespace ui
} // namespace xe
namespace xe {
namespace ui {
namespace vulkan {
struct Version {
uint32_t major;
uint32_t minor;
uint32_t patch;
std::string pretty_string;
static uint32_t Make(uint32_t major, uint32_t minor, uint32_t patch);
static Version Parse(uint32_t value);
};
const char* to_string(VkFormat format);
const char* to_string(VkPhysicalDeviceType type);
const char* to_string(VkSharingMode sharing_mode);
const char* to_string(VkResult result);
std::string to_flags_string(VkImageUsageFlags flags);
std::string to_flags_string(VkSurfaceTransformFlagBitsKHR flags);
const char* to_string(VkColorSpaceKHR color_space);
const char* to_string(VkPresentModeKHR present_mode);
// Throws a fatal error with some Vulkan help text.
void FatalVulkanError(std::string error);
// Logs and assets expecting the result to be VK_SUCCESS.
void CheckResult(VkResult result, const char* action);
struct LayerInfo {
VkLayerProperties properties;
std::vector<VkExtensionProperties> extensions;
};
struct DeviceInfo {
VkPhysicalDevice handle;
VkPhysicalDeviceProperties properties;
VkPhysicalDeviceFeatures features;
VkPhysicalDeviceMemoryProperties memory_properties;
std::vector<VkQueueFamilyProperties> queue_family_properties;
std::vector<VkBool32> queue_family_supports_present;
std::vector<LayerInfo> layers;
std::vector<VkExtensionProperties> extensions;
};
// Defines a requirement for a layer or extension, used to both verify and
// enable them on initialization.
struct Requirement {
// Layer or extension name.
std::string name;
// Minimum required spec version of the layer or extension.
uint32_t min_version;
// True if the requirement is optional (will not cause verification to fail).
bool is_optional;
};
// Gets a list of enabled layer names based on the given layer requirements and
// available layer info.
// Returns a boolean indicating whether all required layers are present.
std::pair<bool, std::vector<const char*>> CheckRequirements(
const std::vector<Requirement>& requirements,
const std::vector<LayerInfo>& layer_infos);
// Gets a list of enabled extension names based on the given extension
// requirements and available extensions.
// Returns a boolean indicating whether all required extensions are present.
std::pair<bool, std::vector<const char*>> CheckRequirements(
const std::vector<Requirement>& requirements,
const std::vector<VkExtensionProperties>& extension_properties);
} // namespace vulkan
} // namespace ui
} // namespace xe
#endif // XENIA_UI_VULKAN_VULKAN_UTIL_H_

View File

@ -0,0 +1,30 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <string>
#include <vector>
#include "xenia/base/main.h"
#include "xenia/ui/vulkan/vulkan_provider.h"
#include "xenia/ui/window.h"
namespace xe {
namespace ui {
int window_demo_main(const std::vector<std::wstring>& args);
std::unique_ptr<GraphicsProvider> CreateDemoGraphicsProvider(Window* window) {
return xe::ui::vulkan::VulkanProvider::Create(window);
}
} // namespace ui
} // namespace xe
DEFINE_ENTRY_POINT(L"xenia-ui-window-vulkan-demo",
L"xenia-ui-window-vulkan-demo", xe::ui::window_demo_main);

View File

@ -87,11 +87,10 @@ int window_demo_main(const std::vector<std::wstring>& args) {
}); });
window->on_closed.AddListener( window->on_closed.AddListener(
[&loop, &graphics_provider](xe::ui::UIEvent* e) { [&loop, &window, &graphics_provider](xe::ui::UIEvent* e) {
loop->Quit(); loop->Quit();
Profiler::Shutdown();
XELOGI("User-initiated death!"); XELOGI("User-initiated death!");
graphics_provider.reset();
exit(1);
}); });
loop->on_quit.AddListener([&window](xe::ui::UIEvent* e) { window.reset(); }); loop->on_quit.AddListener([&window](xe::ui::UIEvent* e) { window.reset(); });
@ -116,11 +115,9 @@ int window_demo_main(const std::vector<std::wstring>& args) {
// Wait until we are exited. // Wait until we are exited.
loop->AwaitQuit(); loop->AwaitQuit();
loop->PostSynchronous([&graphics_provider]() { graphics_provider.reset(); });
window.reset(); window.reset();
loop.reset(); loop.reset();
Profiler::Dump(); graphics_provider.reset();
Profiler::Shutdown();
return 0; return 0;
} }

@ -1 +1 @@
Subproject commit 224348faf0616b5bea635141f4b28ee0faab3002 Subproject commit 4d2f2239bf896dc14127e25011f41ac79d687052

View File

@ -16,9 +16,7 @@ project("spirv-tools")
"spirv-tools/external/include/headers/GLSL.std.450.h", "spirv-tools/external/include/headers/GLSL.std.450.h",
"spirv-tools/external/include/headers/OpenCL.std.h", "spirv-tools/external/include/headers/OpenCL.std.h",
"spirv-tools/external/include/headers/spirv.h", "spirv-tools/external/include/headers/spirv.h",
"spirv-tools/include/libspirv/libspirv.h", "spirv-tools/include/spirv-tools/libspirv.h",
"spirv-tools/include/util/bitutils.h",
"spirv-tools/include/util/hex_float.h",
"spirv-tools/source/assembly_grammar.cpp", "spirv-tools/source/assembly_grammar.cpp",
"spirv-tools/source/assembly_grammar.h", "spirv-tools/source/assembly_grammar.h",
"spirv-tools/source/binary.cpp", "spirv-tools/source/binary.cpp",
@ -26,10 +24,9 @@ project("spirv-tools")
"spirv-tools/source/diagnostic.cpp", "spirv-tools/source/diagnostic.cpp",
"spirv-tools/source/diagnostic.h", "spirv-tools/source/diagnostic.h",
"spirv-tools/source/disassemble.cpp", "spirv-tools/source/disassemble.cpp",
"spirv-tools/source/endian.cpp",
"spirv-tools/source/endian.h",
"spirv-tools/source/ext_inst.cpp", "spirv-tools/source/ext_inst.cpp",
"spirv-tools/source/ext_inst.h", "spirv-tools/source/ext_inst.h",
"spirv-tools/source/instruction.cpp",
"spirv-tools/source/instruction.h", "spirv-tools/source/instruction.h",
"spirv-tools/source/opcode.cpp", "spirv-tools/source/opcode.cpp",
"spirv-tools/source/opcode.h", "spirv-tools/source/opcode.h",
@ -41,6 +38,8 @@ project("spirv-tools")
"spirv-tools/source/print.h", "spirv-tools/source/print.h",
"spirv-tools/source/spirv_constant.h", "spirv-tools/source/spirv_constant.h",
"spirv-tools/source/spirv_definition.h", "spirv-tools/source/spirv_definition.h",
"spirv-tools/source/spirv_endian.cpp",
"spirv-tools/source/spirv_endian.h",
"spirv-tools/source/spirv_operands.h", "spirv-tools/source/spirv_operands.h",
"spirv-tools/source/table.cpp", "spirv-tools/source/table.cpp",
"spirv-tools/source/table.h", "spirv-tools/source/table.h",
@ -50,5 +49,13 @@ project("spirv-tools")
"spirv-tools/source/text_handler.h", "spirv-tools/source/text_handler.h",
"spirv-tools/source/validate.cpp", "spirv-tools/source/validate.cpp",
"spirv-tools/source/validate.h", "spirv-tools/source/validate.h",
"spirv-tools/source/validate_cfg.cpp",
"spirv-tools/source/validate_id.cpp", "spirv-tools/source/validate_id.cpp",
"spirv-tools/source/validate_instruction.cpp",
"spirv-tools/source/validate_layout.cpp",
"spirv-tools/source/validate_passes.h",
"spirv-tools/source/validate_ssa.cpp",
"spirv-tools/source/validate_types.cpp",
"spirv-tools/source/util/bitutils.h",
"spirv-tools/source/util/hex_float.h",
}) })

View File

@ -1,5 +1,5 @@
/* /*
** Copyright (c) 2014-2015 The Khronos Group Inc. ** Copyright (c) 2014-2016 The Khronos Group Inc.
** **
** Permission is hereby granted, free of charge, to any person obtaining a copy ** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and/or associated documentation files (the "Materials"), ** of this software and/or associated documentation files (the "Materials"),
@ -27,105 +27,105 @@
#ifndef GLSLstd450_H #ifndef GLSLstd450_H
#define GLSLstd450_H #define GLSLstd450_H
namespace spv { static const int GLSLstd450Version = 100;
static const int GLSLstd450Revision = 1;
const int GLSLstd450Version = 99; enum GLSLstd450 {
const int GLSLstd450Revision = 3; GLSLstd450Bad = 0, // Don't use
enum class GLSLstd450 : unsigned { GLSLstd450Round = 1,
Bad = 0, // Don't use GLSLstd450RoundEven = 2,
GLSLstd450Trunc = 3,
GLSLstd450FAbs = 4,
GLSLstd450SAbs = 5,
GLSLstd450FSign = 6,
GLSLstd450SSign = 7,
GLSLstd450Floor = 8,
GLSLstd450Ceil = 9,
GLSLstd450Fract = 10,
Round = 1, GLSLstd450Radians = 11,
RoundEven = 2, GLSLstd450Degrees = 12,
Trunc = 3, GLSLstd450Sin = 13,
FAbs = 4, GLSLstd450Cos = 14,
SAbs = 5, GLSLstd450Tan = 15,
FSign = 6, GLSLstd450Asin = 16,
SSign = 7, GLSLstd450Acos = 17,
Floor = 8, GLSLstd450Atan = 18,
Ceil = 9, GLSLstd450Sinh = 19,
Fract = 10, GLSLstd450Cosh = 20,
GLSLstd450Tanh = 21,
GLSLstd450Asinh = 22,
GLSLstd450Acosh = 23,
GLSLstd450Atanh = 24,
GLSLstd450Atan2 = 25,
Radians = 11, GLSLstd450Pow = 26,
Degrees = 12, GLSLstd450Exp = 27,
Sin = 13, GLSLstd450Log = 28,
Cos = 14, GLSLstd450Exp2 = 29,
Tan = 15, GLSLstd450Log2 = 30,
Asin = 16, GLSLstd450Sqrt = 31,
Acos = 17, GLSLstd450InverseSqrt = 32,
Atan = 18,
Sinh = 19,
Cosh = 20,
Tanh = 21,
Asinh = 22,
Acosh = 23,
Atanh = 24,
Atan2 = 25,
Pow = 26, GLSLstd450Determinant = 33,
Exp = 27, GLSLstd450MatrixInverse = 34,
Log = 28,
Exp2 = 29,
Log2 = 30,
Sqrt = 31,
InverseSqrt = 32,
Determinant = 33, GLSLstd450Modf = 35, // second operand needs an OpVariable to write to
MatrixInverse = 34, GLSLstd450ModfStruct = 36, // no OpVariable operand
GLSLstd450FMin = 37,
GLSLstd450UMin = 38,
GLSLstd450SMin = 39,
GLSLstd450FMax = 40,
GLSLstd450UMax = 41,
GLSLstd450SMax = 42,
GLSLstd450FClamp = 43,
GLSLstd450UClamp = 44,
GLSLstd450SClamp = 45,
GLSLstd450FMix = 46,
GLSLstd450IMix = 47, // Reserved
GLSLstd450Step = 48,
GLSLstd450SmoothStep = 49,
Modf = 35, // second operand needs an OpVariable to write to GLSLstd450Fma = 50,
ModfStruct = 36, // no OpVariable operand GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to
FMin = 37, GLSLstd450FrexpStruct = 52, // no OpVariable operand
UMin = 38, GLSLstd450Ldexp = 53,
SMin = 39,
FMax = 40,
UMax = 41,
SMax = 42,
FClamp = 43,
UClamp = 44,
SClamp = 45,
FMix = 46,
IMix = 47,
Step = 48,
SmoothStep = 49,
Fma = 50, GLSLstd450PackSnorm4x8 = 54,
Frexp = 51, // second operand needs an OpVariable to write to GLSLstd450PackUnorm4x8 = 55,
FrexpStruct = 52, // no OpVariable operand GLSLstd450PackSnorm2x16 = 56,
Ldexp = 53, GLSLstd450PackUnorm2x16 = 57,
GLSLstd450PackHalf2x16 = 58,
GLSLstd450PackDouble2x32 = 59,
GLSLstd450UnpackSnorm2x16 = 60,
GLSLstd450UnpackUnorm2x16 = 61,
GLSLstd450UnpackHalf2x16 = 62,
GLSLstd450UnpackSnorm4x8 = 63,
GLSLstd450UnpackUnorm4x8 = 64,
GLSLstd450UnpackDouble2x32 = 65,
PackSnorm4x8 = 54, GLSLstd450Length = 66,
PackUnorm4x8 = 55, GLSLstd450Distance = 67,
PackSnorm2x16 = 56, GLSLstd450Cross = 68,
PackUnorm2x16 = 57, GLSLstd450Normalize = 69,
PackHalf2x16 = 58, GLSLstd450FaceForward = 70,
PackDouble2x32 = 59, GLSLstd450Reflect = 71,
UnpackSnorm2x16 = 60, GLSLstd450Refract = 72,
UnpackUnorm2x16 = 61,
UnpackHalf2x16 = 62,
UnpackSnorm4x8 = 63,
UnpackUnorm4x8 = 64,
UnpackDouble2x32 = 65,
Length = 66, GLSLstd450FindILsb = 73,
Distance = 67, GLSLstd450FindSMsb = 74,
Cross = 68, GLSLstd450FindUMsb = 75,
Normalize = 69,
FaceForward = 70,
Reflect = 71,
Refract = 72,
FindILsb = 73, GLSLstd450InterpolateAtCentroid = 76,
FindSMsb = 74, GLSLstd450InterpolateAtSample = 77,
FindUMsb = 75, GLSLstd450InterpolateAtOffset = 78,
InterpolateAtCentroid = 76, GLSLstd450NMin = 79,
InterpolateAtSample = 77, GLSLstd450NMax = 80,
InterpolateAtOffset = 78, GLSLstd450NClamp = 81,
Count GLSLstd450Count
}; };
} // end namespace spv
#endif // #ifndef GLSLstd450_H #endif // #ifndef GLSLstd450_H

135
third_party/spirv/GLSL.std.450.hpp11 vendored Normal file
View File

@ -0,0 +1,135 @@
/*
** Copyright (c) 2014-2016 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and/or associated documentation files (the "Materials"),
** to deal in the Materials without restriction, including without limitation
** the rights to use, copy, modify, merge, publish, distribute, sublicense,
** and/or sell copies of the Materials, and to permit persons to whom the
** Materials are furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in
** all copies or substantial portions of the Materials.
**
** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
** IN THE MATERIALS.
*/
#ifndef GLSLstd450_HPP
#define GLSLstd450_HPP
namespace spv {
constexpr int GLSLstd450Version = 100;
constexpr int GLSLstd450Revision = 1;
enum class GLSLstd450 {
kBad = 0, // Don't use
kRound = 1,
kRoundEven = 2,
kTrunc = 3,
kFAbs = 4,
kSAbs = 5,
kFSign = 6,
kSSign = 7,
kFloor = 8,
kCeil = 9,
kFract = 10,
kRadians = 11,
kDegrees = 12,
kSin = 13,
kCos = 14,
kTan = 15,
kAsin = 16,
kAcos = 17,
kAtan = 18,
kSinh = 19,
kCosh = 20,
kTanh = 21,
kAsinh = 22,
kAcosh = 23,
kAtanh = 24,
kAtan2 = 25,
kPow = 26,
kExp = 27,
kLog = 28,
kExp2 = 29,
kLog2 = 30,
kSqrt = 31,
kInverseSqrt = 32,
kDeterminant = 33,
kMatrixInverse = 34,
kModf = 35, // second operand needs an OpVariable to write to
kModfStruct = 36, // no OpVariable operand
kFMin = 37,
kUMin = 38,
kSMin = 39,
kFMax = 40,
kUMax = 41,
kSMax = 42,
kFClamp = 43,
kUClamp = 44,
kSClamp = 45,
kFMix = 46,
kIMix = 47, // Reserved
kStep = 48,
kSmoothStep = 49,
kFma = 50,
kFrexp = 51, // second operand needs an OpVariable to write to
kFrexpStruct = 52, // no OpVariable operand
kLdexp = 53,
kPackSnorm4x8 = 54,
kPackUnorm4x8 = 55,
kPackSnorm2x16 = 56,
kPackUnorm2x16 = 57,
kPackHalf2x16 = 58,
kPackDouble2x32 = 59,
kUnpackSnorm2x16 = 60,
kUnpackUnorm2x16 = 61,
kUnpackHalf2x16 = 62,
kUnpackSnorm4x8 = 63,
kUnpackUnorm4x8 = 64,
kUnpackDouble2x32 = 65,
kLength = 66,
kDistance = 67,
kCross = 68,
kNormalize = 69,
kFaceForward = 70,
kReflect = 71,
kRefract = 72,
kFindILsb = 73,
kFindSMsb = 74,
kFindUMsb = 75,
kInterpolateAtCentroid = 76,
kInterpolateAtSample = 77,
kInterpolateAtOffset = 78,
kNMin = 79,
kNMax = 80,
kNClamp = 81,
kCount
};
} // namespace spv
#endif // #ifndef GLSLstd450_HPP

272
third_party/spirv/OpenCL.std.h vendored Normal file
View File

@ -0,0 +1,272 @@
/*
** Copyright (c) 2015-2016 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and/or associated documentation files (the "Materials"),
** to deal in the Materials without restriction, including without limitation
** the rights to use, copy, modify, merge, publish, distribute, sublicense,
** and/or sell copies of the Materials, and to permit persons to whom the
** Materials are furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in
** all copies or substantial portions of the Materials.
**
** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
** IN THE MATERIALS.
*/
//
// Author: Boaz Ouriel, Intel
//
namespace OpenCLLIB {
enum Entrypoints {
// math functions
Acos = 0,
Acosh = 1,
Acospi = 2,
Asin = 3,
Asinh = 4,
Asinpi = 5,
Atan = 6,
Atan2 = 7,
Atanh = 8,
Atanpi = 9,
Atan2pi = 10,
Cbrt = 11,
Ceil = 12,
Copysign = 13,
Cos = 14,
Cosh = 15,
Cospi = 16,
Erfc = 17,
Erf = 18,
Exp = 19,
Exp2 = 20,
Exp10 = 21,
Expm1 = 22,
Fabs = 23,
Fdim = 24,
Floor = 25,
Fma = 26,
Fmax = 27,
Fmin = 28,
Fmod = 29,
Fract = 30,
Frexp = 31,
Hypot = 32,
Ilogb = 33,
Ldexp = 34,
Lgamma = 35,
Lgamma_r = 36,
Log = 37,
Log2 = 38,
Log10 = 39,
Log1p = 40,
Logb = 41,
Mad = 42,
Maxmag = 43,
Minmag = 44,
Modf = 45,
Nan = 46,
Nextafter = 47,
Pow = 48,
Pown = 49,
Powr = 50,
Remainder = 51,
Remquo = 52,
Rint = 53,
Rootn = 54,
Round = 55,
Rsqrt = 56,
Sin = 57,
Sincos = 58,
Sinh = 59,
Sinpi = 60,
Sqrt = 61,
Tan = 62,
Tanh = 63,
Tanpi = 64,
Tgamma = 65,
Trunc = 66,
Half_cos = 67,
Half_divide = 68,
Half_exp = 69,
Half_exp2 = 70,
Half_exp10 = 71,
Half_log = 72,
Half_log2 = 73,
Half_log10 = 74,
Half_powr = 75,
Half_recip = 76,
Half_rsqrt = 77,
Half_sin = 78,
Half_sqrt = 79,
Half_tan = 80,
Native_cos = 81,
Native_divide = 82,
Native_exp = 83,
Native_exp2 = 84,
Native_exp10 = 85,
Native_log = 86,
Native_log2 = 87,
Native_log10 = 88,
Native_powr = 89,
Native_recip = 90,
Native_rsqrt = 91,
Native_sin = 92,
Native_sqrt = 93,
Native_tan = 94,
// Common
FClamp = 95,
Degrees = 96,
FMax_common = 97,
FMin_common = 98,
Mix = 99,
Radians = 100,
Step = 101,
Smoothstep = 102,
Sign = 103,
// Geometrics
Cross = 104,
Distance = 105,
Length = 106,
Normalize = 107,
Fast_distance = 108,
Fast_length = 109,
Fast_normalize = 110,
// Images - Deprecated
Read_imagef = 111,
Read_imagei = 112,
Read_imageui = 113,
Read_imageh = 114,
Read_imagef_samplerless = 115,
Read_imagei_samplerless = 116,
Read_imageui_samplerless = 117,
Read_imageh_samplerless = 118,
Write_imagef = 119,
Write_imagei = 120,
Write_imageui = 121,
Write_imageh = 122,
Read_imagef_mipmap_lod = 123,
Read_imagei_mipmap_lod = 124,
Read_imageui_mipmap_lod = 125,
Read_imagef_mipmap_grad = 126,
Read_imagei_mipmap_grad = 127,
Read_imageui_mipmap_grad = 128,
// Image write with LOD
Write_imagef_mipmap_lod = 129,
Write_imagei_mipmap_lod = 130,
Write_imageui_mipmap_lod = 131,
// Images - Deprecated
Get_image_width = 132,
Get_image_height = 133,
Get_image_depth = 134,
Get_image_channel_data_type = 135,
Get_image_channel_order = 136,
Get_image_dim = 137,
Get_image_array_size = 138,
Get_image_num_samples = 139,
Get_image_num_mip_levels = 140,
// Integers
SAbs = 141,
SAbs_diff = 142,
SAdd_sat = 143,
UAdd_sat = 144,
SHadd = 145,
UHadd = 146,
SRhadd = 147,
URhadd = 148,
SClamp = 149,
UClamp = 150,
Clz = 151,
Ctz = 152,
SMad_hi = 153,
UMad_sat = 154,
SMad_sat = 155,
SMax = 156,
UMax = 157,
SMin = 158,
UMin = 159,
SMul_hi = 160,
Rotate = 161,
SSub_sat = 162,
USub_sat = 163,
U_Upsample = 164,
S_Upsample = 165,
Popcount = 166,
SMad24 = 167,
UMad24 = 168,
SMul24 = 169,
UMul24 = 170,
// Vector Loads/Stores
Vloadn = 171,
Vstoren = 172,
Vload_half = 173,
Vload_halfn = 174,
Vstore_half = 175,
Vstore_half_r = 176,
Vstore_halfn = 177,
Vstore_halfn_r = 178,
Vloada_halfn = 179,
Vstorea_halfn = 180,
Vstorea_halfn_r = 181,
// Vector Misc
Shuffle = 182,
Shuffle2 = 183,
//
Printf = 184,
Prefetch = 185,
// Relationals
Bitselect = 186,
Select = 187,
// pipes
Read_pipe = 188,
Write_pipe = 189,
Reserve_read_pipe = 190,
Reserve_write_pipe = 191,
Commit_read_pipe = 192,
Commit_write_pipe = 193,
Is_valid_reserve_id = 194,
Work_group_reserve_read_pipe = 195,
Work_group_reserve_write_pipe = 196,
Work_group_commit_read_pipe = 197,
Work_group_commit_write_pipe = 198,
Get_pipe_num_packets = 199,
Get_pipe_max_packets = 200,
// more integers
UAbs = 201,
UAbs_diff = 202,
UMul_hi = 203,
UMad_hi = 204,
};
}; // end namespace OpenCL20

File diff suppressed because it is too large Load Diff

880
third_party/spirv/spirv.hpp11 vendored Normal file
View File

@ -0,0 +1,880 @@
// Copyright (c) 2014-2016 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and/or associated documentation files (the "Materials"),
// to deal in the Materials without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Materials, and to permit persons to whom the
// Materials are furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Materials.
//
// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
//
// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
// IN THE MATERIALS.
// This header is automatically generated by the same tool that creates
// the Binary Section of the SPIR-V specification.
// Enumeration tokens for SPIR-V, in various styles:
// C, C++, C++11, JSON, Lua, Python
//
// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL
// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL
// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL
// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL
// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']
//
// Some tokens act like mask values, which can be OR'd together,
// while others are mutually exclusive. The mask-like ones have
// "Mask" in their name, and a parallel enum that has the shift
// amount (1 << x) for each corresponding enumerant.
#ifndef spirv_HPP
#define spirv_HPP
namespace spv {
typedef unsigned int Id;
#define SPV_VERSION 0x10000
#define SPV_REVISION 3
static const unsigned int MagicNumber = 0x07230203;
static const unsigned int Version = 0x00010000;
static const unsigned int Revision = 3;
static const unsigned int OpCodeMask = 0xffff;
static const unsigned int WordCountShift = 16;
enum class SourceLanguage : unsigned {
Unknown = 0,
ESSL = 1,
GLSL = 2,
OpenCL_C = 3,
OpenCL_CPP = 4,
};
enum class ExecutionModel : unsigned {
Vertex = 0,
TessellationControl = 1,
TessellationEvaluation = 2,
Geometry = 3,
Fragment = 4,
GLCompute = 5,
Kernel = 6,
};
enum class AddressingModel : unsigned {
Logical = 0,
Physical32 = 1,
Physical64 = 2,
};
enum class MemoryModel : unsigned {
Simple = 0,
GLSL450 = 1,
OpenCL = 2,
};
enum class ExecutionMode : unsigned {
Invocations = 0,
SpacingEqual = 1,
SpacingFractionalEven = 2,
SpacingFractionalOdd = 3,
VertexOrderCw = 4,
VertexOrderCcw = 5,
PixelCenterInteger = 6,
OriginUpperLeft = 7,
OriginLowerLeft = 8,
EarlyFragmentTests = 9,
PointMode = 10,
Xfb = 11,
DepthReplacing = 12,
DepthGreater = 14,
DepthLess = 15,
DepthUnchanged = 16,
LocalSize = 17,
LocalSizeHint = 18,
InputPoints = 19,
InputLines = 20,
InputLinesAdjacency = 21,
Triangles = 22,
InputTrianglesAdjacency = 23,
Quads = 24,
Isolines = 25,
OutputVertices = 26,
OutputPoints = 27,
OutputLineStrip = 28,
OutputTriangleStrip = 29,
VecTypeHint = 30,
ContractionOff = 31,
};
enum class StorageClass : unsigned {
UniformConstant = 0,
Input = 1,
Uniform = 2,
Output = 3,
Workgroup = 4,
CrossWorkgroup = 5,
Private = 6,
Function = 7,
Generic = 8,
PushConstant = 9,
AtomicCounter = 10,
Image = 11,
};
enum class Dim : unsigned {
Dim1D = 0,
Dim2D = 1,
Dim3D = 2,
Cube = 3,
Rect = 4,
Buffer = 5,
SubpassData = 6,
};
enum class SamplerAddressingMode : unsigned {
None = 0,
ClampToEdge = 1,
Clamp = 2,
Repeat = 3,
RepeatMirrored = 4,
};
enum class SamplerFilterMode : unsigned {
Nearest = 0,
Linear = 1,
};
enum class ImageFormat : unsigned {
Unknown = 0,
Rgba32f = 1,
Rgba16f = 2,
R32f = 3,
Rgba8 = 4,
Rgba8Snorm = 5,
Rg32f = 6,
Rg16f = 7,
R11fG11fB10f = 8,
R16f = 9,
Rgba16 = 10,
Rgb10A2 = 11,
Rg16 = 12,
Rg8 = 13,
R16 = 14,
R8 = 15,
Rgba16Snorm = 16,
Rg16Snorm = 17,
Rg8Snorm = 18,
R16Snorm = 19,
R8Snorm = 20,
Rgba32i = 21,
Rgba16i = 22,
Rgba8i = 23,
R32i = 24,
Rg32i = 25,
Rg16i = 26,
Rg8i = 27,
R16i = 28,
R8i = 29,
Rgba32ui = 30,
Rgba16ui = 31,
Rgba8ui = 32,
R32ui = 33,
Rgb10a2ui = 34,
Rg32ui = 35,
Rg16ui = 36,
Rg8ui = 37,
R16ui = 38,
R8ui = 39,
};
enum class ImageChannelOrder : unsigned {
R = 0,
A = 1,
RG = 2,
RA = 3,
RGB = 4,
RGBA = 5,
BGRA = 6,
ARGB = 7,
Intensity = 8,
Luminance = 9,
Rx = 10,
RGx = 11,
RGBx = 12,
Depth = 13,
DepthStencil = 14,
sRGB = 15,
sRGBx = 16,
sRGBA = 17,
sBGRA = 18,
};
enum class ImageChannelDataType : unsigned {
SnormInt8 = 0,
SnormInt16 = 1,
UnormInt8 = 2,
UnormInt16 = 3,
UnormShort565 = 4,
UnormShort555 = 5,
UnormInt101010 = 6,
SignedInt8 = 7,
SignedInt16 = 8,
SignedInt32 = 9,
UnsignedInt8 = 10,
UnsignedInt16 = 11,
UnsignedInt32 = 12,
HalfFloat = 13,
Float = 14,
UnormInt24 = 15,
UnormInt101010_2 = 16,
};
enum class ImageOperandsShift : unsigned {
Bias = 0,
Lod = 1,
Grad = 2,
ConstOffset = 3,
Offset = 4,
ConstOffsets = 5,
Sample = 6,
MinLod = 7,
};
enum class ImageOperandsMask : unsigned {
MaskNone = 0,
Bias = 0x00000001,
Lod = 0x00000002,
Grad = 0x00000004,
ConstOffset = 0x00000008,
Offset = 0x00000010,
ConstOffsets = 0x00000020,
Sample = 0x00000040,
MinLod = 0x00000080,
};
enum class FPFastMathModeShift : unsigned {
NotNaN = 0,
NotInf = 1,
NSZ = 2,
AllowRecip = 3,
Fast = 4,
};
enum class FPFastMathModeMask : unsigned {
MaskNone = 0,
NotNaN = 0x00000001,
NotInf = 0x00000002,
NSZ = 0x00000004,
AllowRecip = 0x00000008,
Fast = 0x00000010,
};
enum class FPRoundingMode : unsigned {
RTE = 0,
RTZ = 1,
RTP = 2,
RTN = 3,
};
enum class LinkageType : unsigned {
Export = 0,
Import = 1,
};
enum class AccessQualifier : unsigned {
ReadOnly = 0,
WriteOnly = 1,
ReadWrite = 2,
};
enum class FunctionParameterAttribute : unsigned {
Zext = 0,
Sext = 1,
ByVal = 2,
Sret = 3,
NoAlias = 4,
NoCapture = 5,
NoWrite = 6,
NoReadWrite = 7,
};
enum class Decoration : unsigned {
RelaxedPrecision = 0,
SpecId = 1,
Block = 2,
BufferBlock = 3,
RowMajor = 4,
ColMajor = 5,
ArrayStride = 6,
MatrixStride = 7,
GLSLShared = 8,
GLSLPacked = 9,
CPacked = 10,
BuiltIn = 11,
NoPerspective = 13,
Flat = 14,
Patch = 15,
Centroid = 16,
Sample = 17,
Invariant = 18,
Restrict = 19,
Aliased = 20,
Volatile = 21,
Constant = 22,
Coherent = 23,
NonWritable = 24,
NonReadable = 25,
Uniform = 26,
SaturatedConversion = 28,
Stream = 29,
Location = 30,
Component = 31,
Index = 32,
Binding = 33,
DescriptorSet = 34,
Offset = 35,
XfbBuffer = 36,
XfbStride = 37,
FuncParamAttr = 38,
FPRoundingMode = 39,
FPFastMathMode = 40,
LinkageAttributes = 41,
NoContraction = 42,
InputAttachmentIndex = 43,
Alignment = 44,
};
enum class BuiltIn : unsigned {
Position = 0,
PointSize = 1,
ClipDistance = 3,
CullDistance = 4,
VertexId = 5,
InstanceId = 6,
PrimitiveId = 7,
InvocationId = 8,
Layer = 9,
ViewportIndex = 10,
TessLevelOuter = 11,
TessLevelInner = 12,
TessCoord = 13,
PatchVertices = 14,
FragCoord = 15,
PointCoord = 16,
FrontFacing = 17,
SampleId = 18,
SamplePosition = 19,
SampleMask = 20,
FragDepth = 22,
HelperInvocation = 23,
NumWorkgroups = 24,
WorkgroupSize = 25,
WorkgroupId = 26,
LocalInvocationId = 27,
GlobalInvocationId = 28,
LocalInvocationIndex = 29,
WorkDim = 30,
GlobalSize = 31,
EnqueuedWorkgroupSize = 32,
GlobalOffset = 33,
GlobalLinearId = 34,
SubgroupSize = 36,
SubgroupMaxSize = 37,
NumSubgroups = 38,
NumEnqueuedSubgroups = 39,
SubgroupId = 40,
SubgroupLocalInvocationId = 41,
VertexIndex = 42,
InstanceIndex = 43,
};
enum class SelectionControlShift : unsigned {
Flatten = 0,
DontFlatten = 1,
};
enum class SelectionControlMask : unsigned {
MaskNone = 0,
Flatten = 0x00000001,
DontFlatten = 0x00000002,
};
enum class LoopControlShift : unsigned {
Unroll = 0,
DontUnroll = 1,
};
enum class LoopControlMask : unsigned {
MaskNone = 0,
Unroll = 0x00000001,
DontUnroll = 0x00000002,
};
enum class FunctionControlShift : unsigned {
Inline = 0,
DontInline = 1,
Pure = 2,
Const = 3,
};
enum class FunctionControlMask : unsigned {
MaskNone = 0,
Inline = 0x00000001,
DontInline = 0x00000002,
Pure = 0x00000004,
Const = 0x00000008,
};
enum class MemorySemanticsShift : unsigned {
Acquire = 1,
Release = 2,
AcquireRelease = 3,
SequentiallyConsistent = 4,
UniformMemory = 6,
SubgroupMemory = 7,
WorkgroupMemory = 8,
CrossWorkgroupMemory = 9,
AtomicCounterMemory = 10,
ImageMemory = 11,
};
enum class MemorySemanticsMask : unsigned {
MaskNone = 0,
Acquire = 0x00000002,
Release = 0x00000004,
AcquireRelease = 0x00000008,
SequentiallyConsistent = 0x00000010,
UniformMemory = 0x00000040,
SubgroupMemory = 0x00000080,
WorkgroupMemory = 0x00000100,
CrossWorkgroupMemory = 0x00000200,
AtomicCounterMemory = 0x00000400,
ImageMemory = 0x00000800,
};
enum class MemoryAccessShift : unsigned {
Volatile = 0,
Aligned = 1,
Nontemporal = 2,
};
enum class MemoryAccessMask : unsigned {
MaskNone = 0,
Volatile = 0x00000001,
Aligned = 0x00000002,
Nontemporal = 0x00000004,
};
enum class Scope : unsigned {
CrossDevice = 0,
Device = 1,
Workgroup = 2,
Subgroup = 3,
Invocation = 4,
};
enum class GroupOperation : unsigned {
Reduce = 0,
InclusiveScan = 1,
ExclusiveScan = 2,
};
enum class KernelEnqueueFlags : unsigned {
NoWait = 0,
WaitKernel = 1,
WaitWorkGroup = 2,
};
enum class KernelProfilingInfoShift : unsigned {
CmdExecTime = 0,
};
enum class KernelProfilingInfoMask : unsigned {
MaskNone = 0,
CmdExecTime = 0x00000001,
};
enum class Capability : unsigned {
Matrix = 0,
Shader = 1,
Geometry = 2,
Tessellation = 3,
Addresses = 4,
Linkage = 5,
Kernel = 6,
Vector16 = 7,
Float16Buffer = 8,
Float16 = 9,
Float64 = 10,
Int64 = 11,
Int64Atomics = 12,
ImageBasic = 13,
ImageReadWrite = 14,
ImageMipmap = 15,
Pipes = 17,
Groups = 18,
DeviceEnqueue = 19,
LiteralSampler = 20,
AtomicStorage = 21,
Int16 = 22,
TessellationPointSize = 23,
GeometryPointSize = 24,
ImageGatherExtended = 25,
StorageImageMultisample = 27,
UniformBufferArrayDynamicIndexing = 28,
SampledImageArrayDynamicIndexing = 29,
StorageBufferArrayDynamicIndexing = 30,
StorageImageArrayDynamicIndexing = 31,
ClipDistance = 32,
CullDistance = 33,
ImageCubeArray = 34,
SampleRateShading = 35,
ImageRect = 36,
SampledRect = 37,
GenericPointer = 38,
Int8 = 39,
InputAttachment = 40,
SparseResidency = 41,
MinLod = 42,
Sampled1D = 43,
Image1D = 44,
SampledCubeArray = 45,
SampledBuffer = 46,
ImageBuffer = 47,
ImageMSArray = 48,
StorageImageExtendedFormats = 49,
ImageQuery = 50,
DerivativeControl = 51,
InterpolationFunction = 52,
TransformFeedback = 53,
GeometryStreams = 54,
StorageImageReadWithoutFormat = 55,
StorageImageWriteWithoutFormat = 56,
MultiViewport = 57,
};
enum class Op : unsigned {
OpNop = 0,
OpUndef = 1,
OpSourceContinued = 2,
OpSource = 3,
OpSourceExtension = 4,
OpName = 5,
OpMemberName = 6,
OpString = 7,
OpLine = 8,
OpExtension = 10,
OpExtInstImport = 11,
OpExtInst = 12,
OpMemoryModel = 14,
OpEntryPoint = 15,
OpExecutionMode = 16,
OpCapability = 17,
OpTypeVoid = 19,
OpTypeBool = 20,
OpTypeInt = 21,
OpTypeFloat = 22,
OpTypeVector = 23,
OpTypeMatrix = 24,
OpTypeImage = 25,
OpTypeSampler = 26,
OpTypeSampledImage = 27,
OpTypeArray = 28,
OpTypeRuntimeArray = 29,
OpTypeStruct = 30,
OpTypeOpaque = 31,
OpTypePointer = 32,
OpTypeFunction = 33,
OpTypeEvent = 34,
OpTypeDeviceEvent = 35,
OpTypeReserveId = 36,
OpTypeQueue = 37,
OpTypePipe = 38,
OpTypeForwardPointer = 39,
OpConstantTrue = 41,
OpConstantFalse = 42,
OpConstant = 43,
OpConstantComposite = 44,
OpConstantSampler = 45,
OpConstantNull = 46,
OpSpecConstantTrue = 48,
OpSpecConstantFalse = 49,
OpSpecConstant = 50,
OpSpecConstantComposite = 51,
OpSpecConstantOp = 52,
OpFunction = 54,
OpFunctionParameter = 55,
OpFunctionEnd = 56,
OpFunctionCall = 57,
OpVariable = 59,
OpImageTexelPointer = 60,
OpLoad = 61,
OpStore = 62,
OpCopyMemory = 63,
OpCopyMemorySized = 64,
OpAccessChain = 65,
OpInBoundsAccessChain = 66,
OpPtrAccessChain = 67,
OpArrayLength = 68,
OpGenericPtrMemSemantics = 69,
OpInBoundsPtrAccessChain = 70,
OpDecorate = 71,
OpMemberDecorate = 72,
OpDecorationGroup = 73,
OpGroupDecorate = 74,
OpGroupMemberDecorate = 75,
OpVectorExtractDynamic = 77,
OpVectorInsertDynamic = 78,
OpVectorShuffle = 79,
OpCompositeConstruct = 80,
OpCompositeExtract = 81,
OpCompositeInsert = 82,
OpCopyObject = 83,
OpTranspose = 84,
OpSampledImage = 86,
OpImageSampleImplicitLod = 87,
OpImageSampleExplicitLod = 88,
OpImageSampleDrefImplicitLod = 89,
OpImageSampleDrefExplicitLod = 90,
OpImageSampleProjImplicitLod = 91,
OpImageSampleProjExplicitLod = 92,
OpImageSampleProjDrefImplicitLod = 93,
OpImageSampleProjDrefExplicitLod = 94,
OpImageFetch = 95,
OpImageGather = 96,
OpImageDrefGather = 97,
OpImageRead = 98,
OpImageWrite = 99,
OpImage = 100,
OpImageQueryFormat = 101,
OpImageQueryOrder = 102,
OpImageQuerySizeLod = 103,
OpImageQuerySize = 104,
OpImageQueryLod = 105,
OpImageQueryLevels = 106,
OpImageQuerySamples = 107,
OpConvertFToU = 109,
OpConvertFToS = 110,
OpConvertSToF = 111,
OpConvertUToF = 112,
OpUConvert = 113,
OpSConvert = 114,
OpFConvert = 115,
OpQuantizeToF16 = 116,
OpConvertPtrToU = 117,
OpSatConvertSToU = 118,
OpSatConvertUToS = 119,
OpConvertUToPtr = 120,
OpPtrCastToGeneric = 121,
OpGenericCastToPtr = 122,
OpGenericCastToPtrExplicit = 123,
OpBitcast = 124,
OpSNegate = 126,
OpFNegate = 127,
OpIAdd = 128,
OpFAdd = 129,
OpISub = 130,
OpFSub = 131,
OpIMul = 132,
OpFMul = 133,
OpUDiv = 134,
OpSDiv = 135,
OpFDiv = 136,
OpUMod = 137,
OpSRem = 138,
OpSMod = 139,
OpFRem = 140,
OpFMod = 141,
OpVectorTimesScalar = 142,
OpMatrixTimesScalar = 143,
OpVectorTimesMatrix = 144,
OpMatrixTimesVector = 145,
OpMatrixTimesMatrix = 146,
OpOuterProduct = 147,
OpDot = 148,
OpIAddCarry = 149,
OpISubBorrow = 150,
OpUMulExtended = 151,
OpSMulExtended = 152,
OpAny = 154,
OpAll = 155,
OpIsNan = 156,
OpIsInf = 157,
OpIsFinite = 158,
OpIsNormal = 159,
OpSignBitSet = 160,
OpLessOrGreater = 161,
OpOrdered = 162,
OpUnordered = 163,
OpLogicalEqual = 164,
OpLogicalNotEqual = 165,
OpLogicalOr = 166,
OpLogicalAnd = 167,
OpLogicalNot = 168,
OpSelect = 169,
OpIEqual = 170,
OpINotEqual = 171,
OpUGreaterThan = 172,
OpSGreaterThan = 173,
OpUGreaterThanEqual = 174,
OpSGreaterThanEqual = 175,
OpULessThan = 176,
OpSLessThan = 177,
OpULessThanEqual = 178,
OpSLessThanEqual = 179,
OpFOrdEqual = 180,
OpFUnordEqual = 181,
OpFOrdNotEqual = 182,
OpFUnordNotEqual = 183,
OpFOrdLessThan = 184,
OpFUnordLessThan = 185,
OpFOrdGreaterThan = 186,
OpFUnordGreaterThan = 187,
OpFOrdLessThanEqual = 188,
OpFUnordLessThanEqual = 189,
OpFOrdGreaterThanEqual = 190,
OpFUnordGreaterThanEqual = 191,
OpShiftRightLogical = 194,
OpShiftRightArithmetic = 195,
OpShiftLeftLogical = 196,
OpBitwiseOr = 197,
OpBitwiseXor = 198,
OpBitwiseAnd = 199,
OpNot = 200,
OpBitFieldInsert = 201,
OpBitFieldSExtract = 202,
OpBitFieldUExtract = 203,
OpBitReverse = 204,
OpBitCount = 205,
OpDPdx = 207,
OpDPdy = 208,
OpFwidth = 209,
OpDPdxFine = 210,
OpDPdyFine = 211,
OpFwidthFine = 212,
OpDPdxCoarse = 213,
OpDPdyCoarse = 214,
OpFwidthCoarse = 215,
OpEmitVertex = 218,
OpEndPrimitive = 219,
OpEmitStreamVertex = 220,
OpEndStreamPrimitive = 221,
OpControlBarrier = 224,
OpMemoryBarrier = 225,
OpAtomicLoad = 227,
OpAtomicStore = 228,
OpAtomicExchange = 229,
OpAtomicCompareExchange = 230,
OpAtomicCompareExchangeWeak = 231,
OpAtomicIIncrement = 232,
OpAtomicIDecrement = 233,
OpAtomicIAdd = 234,
OpAtomicISub = 235,
OpAtomicSMin = 236,
OpAtomicUMin = 237,
OpAtomicSMax = 238,
OpAtomicUMax = 239,
OpAtomicAnd = 240,
OpAtomicOr = 241,
OpAtomicXor = 242,
OpPhi = 245,
OpLoopMerge = 246,
OpSelectionMerge = 247,
OpLabel = 248,
OpBranch = 249,
OpBranchConditional = 250,
OpSwitch = 251,
OpKill = 252,
OpReturn = 253,
OpReturnValue = 254,
OpUnreachable = 255,
OpLifetimeStart = 256,
OpLifetimeStop = 257,
OpGroupAsyncCopy = 259,
OpGroupWaitEvents = 260,
OpGroupAll = 261,
OpGroupAny = 262,
OpGroupBroadcast = 263,
OpGroupIAdd = 264,
OpGroupFAdd = 265,
OpGroupFMin = 266,
OpGroupUMin = 267,
OpGroupSMin = 268,
OpGroupFMax = 269,
OpGroupUMax = 270,
OpGroupSMax = 271,
OpReadPipe = 274,
OpWritePipe = 275,
OpReservedReadPipe = 276,
OpReservedWritePipe = 277,
OpReserveReadPipePackets = 278,
OpReserveWritePipePackets = 279,
OpCommitReadPipe = 280,
OpCommitWritePipe = 281,
OpIsValidReserveId = 282,
OpGetNumPipePackets = 283,
OpGetMaxPipePackets = 284,
OpGroupReserveReadPipePackets = 285,
OpGroupReserveWritePipePackets = 286,
OpGroupCommitReadPipe = 287,
OpGroupCommitWritePipe = 288,
OpEnqueueMarker = 291,
OpEnqueueKernel = 292,
OpGetKernelNDrangeSubGroupCount = 293,
OpGetKernelNDrangeMaxSubGroupSize = 294,
OpGetKernelWorkGroupSize = 295,
OpGetKernelPreferredWorkGroupSizeMultiple = 296,
OpRetainEvent = 297,
OpReleaseEvent = 298,
OpCreateUserEvent = 299,
OpIsValidEvent = 300,
OpSetUserEventStatus = 301,
OpCaptureEventProfilingInfo = 302,
OpGetDefaultQueue = 303,
OpBuildNDRange = 304,
OpImageSparseSampleImplicitLod = 305,
OpImageSparseSampleExplicitLod = 306,
OpImageSparseSampleDrefImplicitLod = 307,
OpImageSparseSampleDrefExplicitLod = 308,
OpImageSparseSampleProjImplicitLod = 309,
OpImageSparseSampleProjExplicitLod = 310,
OpImageSparseSampleProjDrefImplicitLod = 311,
OpImageSparseSampleProjDrefExplicitLod = 312,
OpImageSparseFetch = 313,
OpImageSparseGather = 314,
OpImageSparseDrefGather = 315,
OpImageSparseTexelsResident = 316,
OpNoLine = 317,
OpAtomicFlagTestAndSet = 318,
OpAtomicFlagClear = 319,
OpImageSparseRead = 320,
};
// Overload operator| for mask bit combining
inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); }
inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); }
inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); }
inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); }
inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); }
inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); }
inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); }
inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); }
} // end namespace spv
#endif // #ifndef spirv_HPP

42
third_party/vulkan/icd-spv.h vendored Normal file
View File

@ -0,0 +1,42 @@
/*
*
* Copyright (C) 2015-2016 Valve Corporation
* Copyright (C) 2015-2016 LunarG, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Author: Cody Northrop <cody@lunarg.com>
*
*/
#ifndef ICD_SPV_H
#define ICD_SPV_H
#include <stdint.h>
#define ICD_SPV_MAGIC 0x07230203
#define ICD_SPV_VERSION 99
struct icd_spv_header {
uint32_t magic;
uint32_t version;
uint32_t gen_magic; // Generator's magic number
};
#endif /* ICD_SPV_H */

1358
third_party/vulkan/loader/cJSON.c vendored Normal file

File diff suppressed because it is too large Load Diff

189
third_party/vulkan/loader/cJSON.h vendored Normal file
View File

@ -0,0 +1,189 @@
/*
Copyright (c) 2009 Dave Gamble
Copyright (c) 2015-2016 The Khronos Group Inc.
Copyright (c) 2015-2016 Valve Corporation
Copyright (c) 2015-2016 LunarG, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef cJSON__h
#define cJSON__h
#ifdef __cplusplus
extern "C" {
#endif
/* cJSON Types: */
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3
#define cJSON_String 4
#define cJSON_Array 5
#define cJSON_Object 6
#define cJSON_IsReference 256
#define cJSON_StringIsConst 512
/* The cJSON structure: */
typedef struct cJSON {
struct cJSON *next, *prev; /* next/prev allow you to walk array/object
chains. Alternatively, use
GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *child; /* An array or object item will have a child pointer
pointing to a chain of the items in the
array/object. */
int type; /* The type of the item, as above. */
char *valuestring; /* The item's string, if type==cJSON_String */
int valueint; /* The item's number, if type==cJSON_Number */
double valuedouble; /* The item's number, if type==cJSON_Number */
char *
string; /* The item's name string, if this item is the child of, or is
in the list of subitems of an object. */
} cJSON;
typedef struct cJSON_Hooks {
void *(*malloc_fn)(size_t sz);
void (*free_fn)(void *ptr);
} cJSON_Hooks;
/* Supply malloc, realloc and free functions to cJSON */
extern void cJSON_InitHooks(cJSON_Hooks *hooks);
/* Supply a block of JSON, and this returns a cJSON object you can interrogate.
* Call cJSON_Delete when finished. */
extern cJSON *cJSON_Parse(const char *value);
/* Render a cJSON entity to text for transfer/storage. Free the char* when
* finished. */
extern char *cJSON_Print(cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting.
* Free the char* when finished. */
extern char *cJSON_PrintUnformatted(cJSON *item);
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess
* at the final size. guessing well reduces reallocation. fmt=0 gives
* unformatted, =1 gives formatted */
extern char *cJSON_PrintBuffered(cJSON *item, int prebuffer, int fmt);
/* Delete a cJSON entity and all subentities. */
extern void cJSON_Delete(cJSON *c);
/* Returns the number of items in an array (or object). */
extern int cJSON_GetArraySize(cJSON *array);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful.
*/
extern cJSON *cJSON_GetArrayItem(cJSON *array, int item);
/* Get item "string" from object. Case insensitive. */
extern cJSON *cJSON_GetObjectItem(cJSON *object, const char *string);
/* For analysing failed parses. This returns a pointer to the parse error.
* You'll probably need to look a few chars back to make sense of it. Defined
* when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
extern const char *cJSON_GetErrorPtr(void);
/* These calls create a cJSON item of the appropriate type. */
extern cJSON *cJSON_CreateNull(void);
extern cJSON *cJSON_CreateTrue(void);
extern cJSON *cJSON_CreateFalse(void);
extern cJSON *cJSON_CreateBool(int b);
extern cJSON *cJSON_CreateNumber(double num);
extern cJSON *cJSON_CreateString(const char *string);
extern cJSON *cJSON_CreateArray(void);
extern cJSON *cJSON_CreateObject(void);
/* These utilities create an Array of count items. */
extern cJSON *cJSON_CreateIntArray(const int *numbers, int count);
extern cJSON *cJSON_CreateFloatArray(const float *numbers, int count);
extern cJSON *cJSON_CreateDoubleArray(const double *numbers, int count);
extern cJSON *cJSON_CreateStringArray(const char **strings, int count);
/* Append item to the specified array/object. */
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
extern void cJSON_AddItemToObject(cJSON *object, const char *string,
cJSON *item);
extern void cJSON_AddItemToObjectCS(
cJSON *object, const char *string,
cJSON *item); /* Use this when string is definitely const (i.e. a literal,
or as good as), and will definitely survive the cJSON
object */
/* Append reference to item to the specified array/object. Use this when you
* want to add an existing cJSON to a new cJSON, but don't want to corrupt your
* existing cJSON. */
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
extern void cJSON_AddItemReferenceToObject(cJSON *object, const char *string,
cJSON *item);
/* Remove/Detatch items from Arrays/Objects. */
extern cJSON *cJSON_DetachItemFromArray(cJSON *array, int which);
extern void cJSON_DeleteItemFromArray(cJSON *array, int which);
extern cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string);
extern void cJSON_DeleteItemFromObject(cJSON *object, const char *string);
/* Update array items. */
extern void cJSON_InsertItemInArray(
cJSON *array, int which,
cJSON *newitem); /* Shifts pre-existing items to the right. */
extern void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
extern void cJSON_ReplaceItemInObject(cJSON *object, const char *string,
cJSON *newitem);
/* Duplicate a cJSON item */
extern cJSON *cJSON_Duplicate(cJSON *item, int recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new
memory that will
need to be released. With recurse!=0, it will duplicate any children connected
to the item.
The item->next and ->prev pointers are always zero on return from Duplicate. */
/* ParseWithOpts allows you to require (and check) that the JSON is null
* terminated, and to retrieve the pointer to the final byte parsed. */
extern cJSON *cJSON_ParseWithOpts(const char *value,
const char **return_parse_end,
int require_null_terminated);
extern void cJSON_Minify(char *json);
/* Macros for creating things quickly. */
#define cJSON_AddNullToObject(object, name) \
cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object, name) \
cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object, name) \
cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddBoolToObject(object, name, b) \
cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
#define cJSON_AddNumberToObject(object, name, n) \
cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object, name, s) \
cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
/* When assigning an integer value, it needs to be propagated to valuedouble
* too. */
#define cJSON_SetIntValue(object, val) \
((object) ? (object)->valueint = (object)->valuedouble = (val) : (val))
#define cJSON_SetNumberValue(object, val) \
((object) ? (object)->valueint = (object)->valuedouble = (val) : (val))
#ifdef __cplusplus
}
#endif
#endif

319
third_party/vulkan/loader/debug_report.c vendored Normal file
View File

@ -0,0 +1,319 @@
/*
* Copyright (c) 2015-2016 The Khronos Group Inc.
* Copyright (c) 2015-2016 Valve Corporation
* Copyright (c) 2015-2016 LunarG, Inc.
* Copyright (C) 2015-2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and/or associated documentation files (the "Materials"), to
* deal in the Materials without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Materials, and to permit persons to whom the Materials are
* furnished to do so, subject to the following conditions:
*
* The above copyright notice(s) and this permission notice shall be included in
* all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
* USE OR OTHER DEALINGS IN THE MATERIALS.
*
* Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
* Author: Jon Ashburn <jon@LunarG.com>
*
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#ifndef WIN32
#include <signal.h>
#else
#endif
#include "vk_loader_platform.h"
#include "debug_report.h"
#include "vulkan/vk_layer.h"
typedef void(VKAPI_PTR *PFN_stringCallback)(char *message);
static const VkExtensionProperties debug_report_extension_info = {
.extensionName = VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
.specVersion = VK_EXT_DEBUG_REPORT_SPEC_VERSION,
};
void debug_report_add_instance_extensions(
const struct loader_instance *inst,
struct loader_extension_list *ext_list) {
loader_add_to_ext_list(inst, ext_list, 1, &debug_report_extension_info);
}
void debug_report_create_instance(struct loader_instance *ptr_instance,
const VkInstanceCreateInfo *pCreateInfo) {
ptr_instance->debug_report_enabled = false;
for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
if (strcmp(pCreateInfo->ppEnabledExtensionNames[i],
VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0) {
ptr_instance->debug_report_enabled = true;
return;
}
}
}
VkResult
util_CreateDebugReportCallback(struct loader_instance *inst,
VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkDebugReportCallbackEXT callback) {
VkLayerDbgFunctionNode *pNewDbgFuncNode;
if (pAllocator != NULL) {
pNewDbgFuncNode = (VkLayerDbgFunctionNode *)pAllocator->pfnAllocation(
pAllocator->pUserData, sizeof(VkLayerDbgFunctionNode),
sizeof(int *), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
} else {
pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_heap_alloc(
inst, sizeof(VkLayerDbgFunctionNode),
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
}
if (!pNewDbgFuncNode)
return VK_ERROR_OUT_OF_HOST_MEMORY;
pNewDbgFuncNode->msgCallback = callback;
pNewDbgFuncNode->pfnMsgCallback = pCreateInfo->pfnCallback;
pNewDbgFuncNode->msgFlags = pCreateInfo->flags;
pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
inst->DbgFunctionHead = pNewDbgFuncNode;
return VK_SUCCESS;
}
static VKAPI_ATTR VkResult VKAPI_CALL debug_report_CreateDebugReportCallback(
VkInstance instance, VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback) {
struct loader_instance *inst = loader_get_instance(instance);
loader_platform_thread_lock_mutex(&loader_lock);
VkResult result = inst->disp->CreateDebugReportCallbackEXT(
instance, pCreateInfo, pAllocator, pCallback);
if (result == VK_SUCCESS) {
result = util_CreateDebugReportCallback(inst, pCreateInfo, pAllocator,
*pCallback);
}
loader_platform_thread_unlock_mutex(&loader_lock);
return result;
}
// Utility function to handle reporting
VkBool32 util_DebugReportMessage(const struct loader_instance *inst,
VkFlags msgFlags,
VkDebugReportObjectTypeEXT objectType,
uint64_t srcObject, size_t location,
int32_t msgCode, const char *pLayerPrefix,
const char *pMsg) {
VkBool32 bail = false;
VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
while (pTrav) {
if (pTrav->msgFlags & msgFlags) {
if (pTrav->pfnMsgCallback(msgFlags, objectType, srcObject, location,
msgCode, pLayerPrefix, pMsg,
pTrav->pUserData)) {
bail = true;
}
}
pTrav = pTrav->pNext;
}
return bail;
}
void util_DestroyDebugReportCallback(struct loader_instance *inst,
VkDebugReportCallbackEXT callback,
const VkAllocationCallbacks *pAllocator) {
VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
VkLayerDbgFunctionNode *pPrev = pTrav;
while (pTrav) {
if (pTrav->msgCallback == callback) {
pPrev->pNext = pTrav->pNext;
if (inst->DbgFunctionHead == pTrav)
inst->DbgFunctionHead = pTrav->pNext;
if (pAllocator != NULL) {
pAllocator->pfnFree(pAllocator->pUserData, pTrav);
} else {
loader_heap_free(inst, pTrav);
}
break;
}
pPrev = pTrav;
pTrav = pTrav->pNext;
}
}
static VKAPI_ATTR void VKAPI_CALL
debug_report_DestroyDebugReportCallback(VkInstance instance,
VkDebugReportCallbackEXT callback,
VkAllocationCallbacks *pAllocator) {
struct loader_instance *inst = loader_get_instance(instance);
loader_platform_thread_lock_mutex(&loader_lock);
inst->disp->DestroyDebugReportCallbackEXT(instance, callback, pAllocator);
util_DestroyDebugReportCallback(inst, callback, pAllocator);
loader_platform_thread_unlock_mutex(&loader_lock);
}
static VKAPI_ATTR void VKAPI_CALL debug_report_DebugReportMessage(
VkInstance instance, VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
struct loader_instance *inst = loader_get_instance(instance);
inst->disp->DebugReportMessageEXT(instance, flags, objType, object,
location, msgCode, pLayerPrefix, pMsg);
}
/*
* This is the instance chain terminator function
* for CreateDebugReportCallback
*/
VKAPI_ATTR VkResult VKAPI_CALL loader_CreateDebugReportCallback(
VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkDebugReportCallbackEXT *pCallback) {
VkDebugReportCallbackEXT *icd_info;
const struct loader_icd *icd;
struct loader_instance *inst = (struct loader_instance *)instance;
VkResult res;
uint32_t storage_idx;
icd_info = calloc(sizeof(VkDebugReportCallbackEXT), inst->total_icd_count);
if (!icd_info) {
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
storage_idx = 0;
for (icd = inst->icds; icd; icd = icd->next) {
if (!icd->CreateDebugReportCallbackEXT) {
continue;
}
res = icd->CreateDebugReportCallbackEXT(
icd->instance, pCreateInfo, pAllocator, &icd_info[storage_idx]);
if (res != VK_SUCCESS) {
break;
}
storage_idx++;
}
/* roll back on errors */
if (icd) {
storage_idx = 0;
for (icd = inst->icds; icd; icd = icd->next) {
if (icd_info[storage_idx]) {
icd->DestroyDebugReportCallbackEXT(
icd->instance, icd_info[storage_idx], pAllocator);
}
storage_idx++;
}
return res;
}
*(VkDebugReportCallbackEXT **)pCallback = icd_info;
return VK_SUCCESS;
}
/*
* This is the instance chain terminator function
* for DestroyDebugReportCallback
*/
VKAPI_ATTR void VKAPI_CALL
loader_DestroyDebugReportCallback(VkInstance instance,
VkDebugReportCallbackEXT callback,
const VkAllocationCallbacks *pAllocator) {
uint32_t storage_idx;
VkDebugReportCallbackEXT *icd_info;
const struct loader_icd *icd;
struct loader_instance *inst = (struct loader_instance *)instance;
icd_info = *(VkDebugReportCallbackEXT **)&callback;
storage_idx = 0;
for (icd = inst->icds; icd; icd = icd->next) {
if (icd_info[storage_idx]) {
icd->DestroyDebugReportCallbackEXT(
icd->instance, icd_info[storage_idx], pAllocator);
}
storage_idx++;
}
}
/*
* This is the instance chain terminator function
* for DebugReportMessage
*/
VKAPI_ATTR void VKAPI_CALL
loader_DebugReportMessage(VkInstance instance, VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objType, uint64_t object,
size_t location, int32_t msgCode,
const char *pLayerPrefix, const char *pMsg) {
const struct loader_icd *icd;
struct loader_instance *inst = (struct loader_instance *)instance;
loader_platform_thread_lock_mutex(&loader_lock);
for (icd = inst->icds; icd; icd = icd->next) {
if (icd->DebugReportMessageEXT != NULL) {
icd->DebugReportMessageEXT(icd->instance, flags, objType, object,
location, msgCode, pLayerPrefix, pMsg);
}
}
/*
* Now that all ICDs have seen the message, call the necessary callbacks.
* Ignoring "bail" return value as there is nothing to bail from at this
* point.
*/
util_DebugReportMessage(inst, flags, objType, object, location, msgCode,
pLayerPrefix, pMsg);
loader_platform_thread_unlock_mutex(&loader_lock);
}
bool debug_report_instance_gpa(struct loader_instance *ptr_instance,
const char *name, void **addr) {
// debug_report is currently advertised to be supported by the loader,
// so always return the entry points if name matches and it's enabled
*addr = NULL;
if (!strcmp("vkCreateDebugReportCallbackEXT", name)) {
*addr = ptr_instance->debug_report_enabled
? (void *)debug_report_CreateDebugReportCallback
: NULL;
return true;
}
if (!strcmp("vkDestroyDebugReportCallbackEXT", name)) {
*addr = ptr_instance->debug_report_enabled
? (void *)debug_report_DestroyDebugReportCallback
: NULL;
return true;
}
if (!strcmp("vkDebugReportMessageEXT", name)) {
*addr = ptr_instance->debug_report_enabled
? (void *)debug_report_DebugReportMessage
: NULL;
return true;
}
return false;
}

150
third_party/vulkan/loader/debug_report.h vendored Normal file
View File

@ -0,0 +1,150 @@
/*
* Copyright (c) 2015-2016 The Khronos Group Inc.
* Copyright (c) 2015-2016 Valve Corporation
* Copyright (c) 2015-2016 LunarG, Inc.
* Copyright (C) 2015-2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and/or associated documentation files (the "Materials"), to
* deal in the Materials without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Materials, and to permit persons to whom the Materials are
* furnished to do so, subject to the following conditions:
*
* The above copyright notice(s) and this permission notice shall be included in
* all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
* USE OR OTHER DEALINGS IN THE MATERIALS.
*
* Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
* Author: Jon Ashburn <jon@lunarg.com>
*
*/
#include "vk_loader_platform.h"
#include "loader.h"
/*
* CreateMsgCallback is global and needs to be
* applied to all layers and ICDs.
* What happens if a layer is enabled on both the instance chain
* as well as the device chain and a call to CreateMsgCallback is made?
* Do we need to make sure that each layer / driver only gets called once?
* Should a layer implementing support for CreateMsgCallback only be allowed (?)
* to live on one chain? Or maybe make it the application's responsibility.
* If the app enables DRAW_STATE on at both CreateInstance time and CreateDevice
* time, CreateMsgCallback will call the DRAW_STATE layer twice. Once via
* the instance chain and once via the device chain.
* The loader should only return the DEBUG_REPORT extension as supported
* for the GetGlobalExtensionSupport call. That should help eliminate one
* duplication.
* Since the instance chain requires us iterating over the available ICDs
* and each ICD will have it's own unique MsgCallback object we need to
* track those objects to give back the right one.
* This also implies that the loader has to intercept vkDestroyObject and
* if the extension is enabled and the object type is a MsgCallback then
* we must translate the object into the proper ICD specific ones.
* DestroyObject works on a device chain. Should not be what's destroying
* the MsgCallback object. That needs to be an instance thing. So, since
* we used an instance to create it, we need a custom Destroy that also
* takes an instance. That way we can iterate over the ICDs properly.
* Example use:
* CreateInstance: DEBUG_REPORT
* Loader will create instance chain with enabled extensions.
* TODO: Should validation layers be enabled here? If not, they will not be in
* the instance chain.
* fn = GetProcAddr(INSTANCE, "vkCreateMsgCallback") -> point to loader's
* vkCreateMsgCallback
* App creates a callback object: fn(..., &MsgCallbackObject1)
* Have only established the instance chain so far. Loader will call the
* instance chain.
* Each layer in the instance chain will call down to the next layer,
* terminating with
* the CreateMsgCallback loader terminator function that creates the actual
* MsgCallbackObject1 object.
* The loader CreateMsgCallback terminator will iterate over the ICDs.
* Calling each ICD that supports vkCreateMsgCallback and collect answers in
* icd_msg_callback_map here.
* As result is sent back up the chain each layer has opportunity to record the
* callback operation and
* appropriate MsgCallback object.
* ...
* Any reports matching the flags set in MsgCallbackObject1 will generate the
* defined callback behavior
* in the layer / ICD that initiated that report.
* ...
* CreateDevice: MemTracker:...
* App does not include DEBUG_REPORT as that is a global extension.
* TODO: GetExtensionSupport must not report DEBUG_REPORT when using instance.
* App MUST include any desired validation layers or they will not participate
* in the device call chain.
* App creates a callback object: fn(..., &MsgCallbackObject2)
* Loader's vkCreateMsgCallback is called.
* Loader sends call down instance chain - this is a global extension - any
* validation layer that was
* enabled at CreateInstance will be able to register the callback. Loader will
* iterate over the ICDs and
* will record the ICD's version of the MsgCallback2 object here.
* ...
* Any report will go to the layer's report function and it will check the flags
* for MsgCallbackObject1
* and MsgCallbackObject2 and take the appropriate action as indicated by the
* app.
* ...
* App calls vkDestroyMsgCallback( MsgCallbackObject1 )
* Loader's DestroyMsgCallback is where call starts. DestroyMsgCallback will be
* sent down instance chain
* ending in the loader's DestroyMsgCallback terminator which will iterate over
* the ICD's destroying each
* ICD version of that MsgCallback object and then destroy the loader's version
* of the object.
* Any reports generated after this will only have MsgCallbackObject2 available.
*/
void debug_report_add_instance_extensions(
const struct loader_instance *inst, struct loader_extension_list *ext_list);
void debug_report_create_instance(struct loader_instance *ptr_instance,
const VkInstanceCreateInfo *pCreateInfo);
bool debug_report_instance_gpa(struct loader_instance *ptr_instance,
const char *name, void **addr);
VKAPI_ATTR VkResult VKAPI_CALL loader_CreateDebugReportCallback(
VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkDebugReportCallbackEXT *pCallback);
VKAPI_ATTR void VKAPI_CALL
loader_DestroyDebugReportCallback(VkInstance instance,
VkDebugReportCallbackEXT callback,
const VkAllocationCallbacks *pAllocator);
VKAPI_ATTR void VKAPI_CALL
loader_DebugReportMessage(VkInstance instance, VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objType, uint64_t object,
size_t location, int32_t msgCode,
const char *pLayerPrefix, const char *pMsg);
VkResult
util_CreateDebugReportCallback(struct loader_instance *inst,
VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkDebugReportCallbackEXT callback);
void util_DestroyDebugReportCallback(struct loader_instance *inst,
VkDebugReportCallbackEXT callback,
const VkAllocationCallbacks *pAllocator);
VkBool32 util_DebugReportMessage(const struct loader_instance *inst,
VkFlags msgFlags,
VkDebugReportObjectTypeEXT objectType,
uint64_t srcObject, size_t location,
int32_t msgCode, const char *pLayerPrefix,
const char *pMsg);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,130 @@
/*
Implementation of POSIX directory browsing functions and types for Win32.
Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com)
History: Created March 1997. Updated June 2003 and July 2012.
Rights: See end of file.
*/
#include <dirent_on_windows.h>
#include <errno.h>
#include <io.h> /* _findfirst and _findnext set errno iff they return -1 */
#include <stdlib.h>
#include <string.h>
#include "vk_loader_platform.h"
#include "loader.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef ptrdiff_t handle_type; /* C99's intptr_t not sufficiently portable */
struct DIR {
handle_type handle; /* -1 for failed rewind */
struct _finddata_t info;
struct dirent result; /* d_name null iff first time */
char *name; /* null-terminated char string */
};
DIR *opendir(const char *name) {
DIR *dir = 0;
if (name && name[0]) {
size_t base_length = strlen(name);
const char *all = /* search pattern must end with suitable wildcard */
strchr("/\\", name[base_length - 1]) ? "*" : "/*";
if ((dir = (DIR *)loader_tls_heap_alloc(sizeof *dir)) != 0 &&
(dir->name = (char *)loader_tls_heap_alloc(base_length +
strlen(all) + 1)) != 0) {
strcat(strcpy(dir->name, name), all);
if ((dir->handle =
(handle_type)_findfirst(dir->name, &dir->info)) != -1) {
dir->result.d_name = 0;
} else /* rollback */
{
loader_tls_heap_free(dir->name);
loader_tls_heap_free(dir);
dir = 0;
}
} else /* rollback */
{
loader_tls_heap_free(dir);
dir = 0;
errno = ENOMEM;
}
} else {
errno = EINVAL;
}
return dir;
}
int closedir(DIR *dir) {
int result = -1;
if (dir) {
if (dir->handle != -1) {
result = _findclose(dir->handle);
}
loader_tls_heap_free(dir->name);
loader_tls_heap_free(dir);
}
if (result == -1) /* map all errors to EBADF */
{
errno = EBADF;
}
return result;
}
struct dirent *readdir(DIR *dir) {
struct dirent *result = 0;
if (dir && dir->handle != -1) {
if (!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) {
result = &dir->result;
result->d_name = dir->info.name;
}
} else {
errno = EBADF;
}
return result;
}
void rewinddir(DIR *dir) {
if (dir && dir->handle != -1) {
_findclose(dir->handle);
dir->handle = (handle_type)_findfirst(dir->name, &dir->info);
dir->result.d_name = 0;
} else {
errno = EBADF;
}
}
#ifdef __cplusplus
}
#endif
/*
Copyright Kevlin Henney, 1997, 2003, 2012. All rights reserved.
Copyright (c) 2015 The Khronos Group Inc.
Copyright (c) 2015 Valve Corporation
Copyright (c) 2015 LunarG, Inc.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose is hereby granted without fee, provided
that this copyright and permissions notice appear in all copies and
derivatives.
This software is supplied "as is" without express or implied warranty.
But that said, if there are any problems please get in touch.
*/

View File

@ -0,0 +1,51 @@
#ifndef DIRENT_INCLUDED
#define DIRENT_INCLUDED
/*
Declaration of POSIX directory browsing functions and types for Win32.
Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com)
History: Created March 1997. Updated June 2003.
Rights: See end of file.
*/
#ifdef __cplusplus
extern "C" {
#endif
typedef struct DIR DIR;
struct dirent {
char *d_name;
};
DIR *opendir(const char *);
int closedir(DIR *);
struct dirent *readdir(DIR *);
void rewinddir(DIR *);
/*
Copyright Kevlin Henney, 1997, 2003. All rights reserved.
Copyright (c) 2015 The Khronos Group Inc.
Copyright (c) 2015 Valve Corporation
Copyright (c) 2015 LunarG, Inc.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose is hereby granted without fee, provided
that this copyright and permissions notice appear in all copies and
derivatives.
This software is supplied "as is" without express or implied warranty.
But that said, if there are any problems please get in touch.
*/
#ifdef __cplusplus
}
#endif
#endif

379
third_party/vulkan/loader/gpa_helper.h vendored Normal file
View File

@ -0,0 +1,379 @@
/*
*
* Copyright (c) 2015 The Khronos Group Inc.
* Copyright (c) 2015 Valve Corporation
* Copyright (c) 2015 LunarG, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and/or associated documentation files (the "Materials"), to
* deal in the Materials without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Materials, and to permit persons to whom the Materials are
* furnished to do so, subject to the following conditions:
*
* The above copyright notice(s) and this permission notice shall be included in
* all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
* USE OR OTHER DEALINGS IN THE MATERIALS.
*
* Author: Jon Ashburn <jon@lunarg.com>
*/
#include <string.h>
#include "debug_report.h"
#include "wsi.h"
static inline void *trampolineGetProcAddr(struct loader_instance *inst,
const char *funcName) {
// Don't include or check global functions
if (!strcmp(funcName, "vkGetInstanceProcAddr"))
return (PFN_vkVoidFunction)vkGetInstanceProcAddr;
if (!strcmp(funcName, "vkDestroyInstance"))
return (PFN_vkVoidFunction)vkDestroyInstance;
if (!strcmp(funcName, "vkEnumeratePhysicalDevices"))
return (PFN_vkVoidFunction)vkEnumeratePhysicalDevices;
if (!strcmp(funcName, "vkGetPhysicalDeviceFeatures"))
return (PFN_vkVoidFunction)vkGetPhysicalDeviceFeatures;
if (!strcmp(funcName, "vkGetPhysicalDeviceFormatProperties"))
return (PFN_vkVoidFunction)vkGetPhysicalDeviceFormatProperties;
if (!strcmp(funcName, "vkGetPhysicalDeviceImageFormatProperties"))
return (PFN_vkVoidFunction)vkGetPhysicalDeviceImageFormatProperties;
if (!strcmp(funcName, "vkGetPhysicalDeviceSparseImageFormatProperties"))
return (
PFN_vkVoidFunction)vkGetPhysicalDeviceSparseImageFormatProperties;
if (!strcmp(funcName, "vkGetPhysicalDeviceProperties"))
return (PFN_vkVoidFunction)vkGetPhysicalDeviceProperties;
if (!strcmp(funcName, "vkGetPhysicalDeviceQueueFamilyProperties"))
return (PFN_vkVoidFunction)vkGetPhysicalDeviceQueueFamilyProperties;
if (!strcmp(funcName, "vkGetPhysicalDeviceMemoryProperties"))
return (PFN_vkVoidFunction)vkGetPhysicalDeviceMemoryProperties;
if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
return (PFN_vkVoidFunction)vkEnumerateDeviceLayerProperties;
if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
return (PFN_vkVoidFunction)vkEnumerateDeviceExtensionProperties;
if (!strcmp(funcName, "vkCreateDevice"))
return (PFN_vkVoidFunction)vkCreateDevice;
if (!strcmp(funcName, "vkGetDeviceProcAddr"))
return (PFN_vkVoidFunction)vkGetDeviceProcAddr;
if (!strcmp(funcName, "vkDestroyDevice"))
return (PFN_vkVoidFunction)vkDestroyDevice;
if (!strcmp(funcName, "vkGetDeviceQueue"))
return (PFN_vkVoidFunction)vkGetDeviceQueue;
if (!strcmp(funcName, "vkQueueSubmit"))
return (PFN_vkVoidFunction)vkQueueSubmit;
if (!strcmp(funcName, "vkQueueWaitIdle"))
return (PFN_vkVoidFunction)vkQueueWaitIdle;
if (!strcmp(funcName, "vkDeviceWaitIdle"))
return (PFN_vkVoidFunction)vkDeviceWaitIdle;
if (!strcmp(funcName, "vkAllocateMemory"))
return (PFN_vkVoidFunction)vkAllocateMemory;
if (!strcmp(funcName, "vkFreeMemory"))
return (PFN_vkVoidFunction)vkFreeMemory;
if (!strcmp(funcName, "vkMapMemory"))
return (PFN_vkVoidFunction)vkMapMemory;
if (!strcmp(funcName, "vkUnmapMemory"))
return (PFN_vkVoidFunction)vkUnmapMemory;
if (!strcmp(funcName, "vkFlushMappedMemoryRanges"))
return (PFN_vkVoidFunction)vkFlushMappedMemoryRanges;
if (!strcmp(funcName, "vkInvalidateMappedMemoryRanges"))
return (PFN_vkVoidFunction)vkInvalidateMappedMemoryRanges;
if (!strcmp(funcName, "vkGetDeviceMemoryCommitment"))
return (PFN_vkVoidFunction)vkGetDeviceMemoryCommitment;
if (!strcmp(funcName, "vkGetImageSparseMemoryRequirements"))
return (PFN_vkVoidFunction)vkGetImageSparseMemoryRequirements;
if (!strcmp(funcName, "vkGetImageMemoryRequirements"))
return (PFN_vkVoidFunction)vkGetImageMemoryRequirements;
if (!strcmp(funcName, "vkGetBufferMemoryRequirements"))
return (PFN_vkVoidFunction)vkGetBufferMemoryRequirements;
if (!strcmp(funcName, "vkBindImageMemory"))
return (PFN_vkVoidFunction)vkBindImageMemory;
if (!strcmp(funcName, "vkBindBufferMemory"))
return (PFN_vkVoidFunction)vkBindBufferMemory;
if (!strcmp(funcName, "vkQueueBindSparse"))
return (PFN_vkVoidFunction)vkQueueBindSparse;
if (!strcmp(funcName, "vkCreateFence"))
return (PFN_vkVoidFunction)vkCreateFence;
if (!strcmp(funcName, "vkDestroyFence"))
return (PFN_vkVoidFunction)vkDestroyFence;
if (!strcmp(funcName, "vkGetFenceStatus"))
return (PFN_vkVoidFunction)vkGetFenceStatus;
if (!strcmp(funcName, "vkResetFences"))
return (PFN_vkVoidFunction)vkResetFences;
if (!strcmp(funcName, "vkWaitForFences"))
return (PFN_vkVoidFunction)vkWaitForFences;
if (!strcmp(funcName, "vkCreateSemaphore"))
return (PFN_vkVoidFunction)vkCreateSemaphore;
if (!strcmp(funcName, "vkDestroySemaphore"))
return (PFN_vkVoidFunction)vkDestroySemaphore;
if (!strcmp(funcName, "vkCreateEvent"))
return (PFN_vkVoidFunction)vkCreateEvent;
if (!strcmp(funcName, "vkDestroyEvent"))
return (PFN_vkVoidFunction)vkDestroyEvent;
if (!strcmp(funcName, "vkGetEventStatus"))
return (PFN_vkVoidFunction)vkGetEventStatus;
if (!strcmp(funcName, "vkSetEvent"))
return (PFN_vkVoidFunction)vkSetEvent;
if (!strcmp(funcName, "vkResetEvent"))
return (PFN_vkVoidFunction)vkResetEvent;
if (!strcmp(funcName, "vkCreateQueryPool"))
return (PFN_vkVoidFunction)vkCreateQueryPool;
if (!strcmp(funcName, "vkDestroyQueryPool"))
return (PFN_vkVoidFunction)vkDestroyQueryPool;
if (!strcmp(funcName, "vkGetQueryPoolResults"))
return (PFN_vkVoidFunction)vkGetQueryPoolResults;
if (!strcmp(funcName, "vkCreateBuffer"))
return (PFN_vkVoidFunction)vkCreateBuffer;
if (!strcmp(funcName, "vkDestroyBuffer"))
return (PFN_vkVoidFunction)vkDestroyBuffer;
if (!strcmp(funcName, "vkCreateBufferView"))
return (PFN_vkVoidFunction)vkCreateBufferView;
if (!strcmp(funcName, "vkDestroyBufferView"))
return (PFN_vkVoidFunction)vkDestroyBufferView;
if (!strcmp(funcName, "vkCreateImage"))
return (PFN_vkVoidFunction)vkCreateImage;
if (!strcmp(funcName, "vkDestroyImage"))
return (PFN_vkVoidFunction)vkDestroyImage;
if (!strcmp(funcName, "vkGetImageSubresourceLayout"))
return (PFN_vkVoidFunction)vkGetImageSubresourceLayout;
if (!strcmp(funcName, "vkCreateImageView"))
return (PFN_vkVoidFunction)vkCreateImageView;
if (!strcmp(funcName, "vkDestroyImageView"))
return (PFN_vkVoidFunction)vkDestroyImageView;
if (!strcmp(funcName, "vkCreateShaderModule"))
return (PFN_vkVoidFunction)vkCreateShaderModule;
if (!strcmp(funcName, "vkDestroyShaderModule"))
return (PFN_vkVoidFunction)vkDestroyShaderModule;
if (!strcmp(funcName, "vkCreatePipelineCache"))
return (PFN_vkVoidFunction)vkCreatePipelineCache;
if (!strcmp(funcName, "vkDestroyPipelineCache"))
return (PFN_vkVoidFunction)vkDestroyPipelineCache;
if (!strcmp(funcName, "vkGetPipelineCacheData"))
return (PFN_vkVoidFunction)vkGetPipelineCacheData;
if (!strcmp(funcName, "vkMergePipelineCaches"))
return (PFN_vkVoidFunction)vkMergePipelineCaches;
if (!strcmp(funcName, "vkCreateGraphicsPipelines"))
return (PFN_vkVoidFunction)vkCreateGraphicsPipelines;
if (!strcmp(funcName, "vkCreateComputePipelines"))
return (PFN_vkVoidFunction)vkCreateComputePipelines;
if (!strcmp(funcName, "vkDestroyPipeline"))
return (PFN_vkVoidFunction)vkDestroyPipeline;
if (!strcmp(funcName, "vkCreatePipelineLayout"))
return (PFN_vkVoidFunction)vkCreatePipelineLayout;
if (!strcmp(funcName, "vkDestroyPipelineLayout"))
return (PFN_vkVoidFunction)vkDestroyPipelineLayout;
if (!strcmp(funcName, "vkCreateSampler"))
return (PFN_vkVoidFunction)vkCreateSampler;
if (!strcmp(funcName, "vkDestroySampler"))
return (PFN_vkVoidFunction)vkDestroySampler;
if (!strcmp(funcName, "vkCreateDescriptorSetLayout"))
return (PFN_vkVoidFunction)vkCreateDescriptorSetLayout;
if (!strcmp(funcName, "vkDestroyDescriptorSetLayout"))
return (PFN_vkVoidFunction)vkDestroyDescriptorSetLayout;
if (!strcmp(funcName, "vkCreateDescriptorPool"))
return (PFN_vkVoidFunction)vkCreateDescriptorPool;
if (!strcmp(funcName, "vkDestroyDescriptorPool"))
return (PFN_vkVoidFunction)vkDestroyDescriptorPool;
if (!strcmp(funcName, "vkResetDescriptorPool"))
return (PFN_vkVoidFunction)vkResetDescriptorPool;
if (!strcmp(funcName, "vkAllocateDescriptorSets"))
return (PFN_vkVoidFunction)vkAllocateDescriptorSets;
if (!strcmp(funcName, "vkFreeDescriptorSets"))
return (PFN_vkVoidFunction)vkFreeDescriptorSets;
if (!strcmp(funcName, "vkUpdateDescriptorSets"))
return (PFN_vkVoidFunction)vkUpdateDescriptorSets;
if (!strcmp(funcName, "vkCreateFramebuffer"))
return (PFN_vkVoidFunction)vkCreateFramebuffer;
if (!strcmp(funcName, "vkDestroyFramebuffer"))
return (PFN_vkVoidFunction)vkDestroyFramebuffer;
if (!strcmp(funcName, "vkCreateRenderPass"))
return (PFN_vkVoidFunction)vkCreateRenderPass;
if (!strcmp(funcName, "vkDestroyRenderPass"))
return (PFN_vkVoidFunction)vkDestroyRenderPass;
if (!strcmp(funcName, "vkGetRenderAreaGranularity"))
return (PFN_vkVoidFunction)vkGetRenderAreaGranularity;
if (!strcmp(funcName, "vkCreateCommandPool"))
return (PFN_vkVoidFunction)vkCreateCommandPool;
if (!strcmp(funcName, "vkDestroyCommandPool"))
return (PFN_vkVoidFunction)vkDestroyCommandPool;
if (!strcmp(funcName, "vkResetCommandPool"))
return (PFN_vkVoidFunction)vkResetCommandPool;
if (!strcmp(funcName, "vkAllocateCommandBuffers"))
return (PFN_vkVoidFunction)vkAllocateCommandBuffers;
if (!strcmp(funcName, "vkFreeCommandBuffers"))
return (PFN_vkVoidFunction)vkFreeCommandBuffers;
if (!strcmp(funcName, "vkBeginCommandBuffer"))
return (PFN_vkVoidFunction)vkBeginCommandBuffer;
if (!strcmp(funcName, "vkEndCommandBuffer"))
return (PFN_vkVoidFunction)vkEndCommandBuffer;
if (!strcmp(funcName, "vkResetCommandBuffer"))
return (PFN_vkVoidFunction)vkResetCommandBuffer;
if (!strcmp(funcName, "vkCmdBindPipeline"))
return (PFN_vkVoidFunction)vkCmdBindPipeline;
if (!strcmp(funcName, "vkCmdBindDescriptorSets"))
return (PFN_vkVoidFunction)vkCmdBindDescriptorSets;
if (!strcmp(funcName, "vkCmdBindVertexBuffers"))
return (PFN_vkVoidFunction)vkCmdBindVertexBuffers;
if (!strcmp(funcName, "vkCmdBindIndexBuffer"))
return (PFN_vkVoidFunction)vkCmdBindIndexBuffer;
if (!strcmp(funcName, "vkCmdSetViewport"))
return (PFN_vkVoidFunction)vkCmdSetViewport;
if (!strcmp(funcName, "vkCmdSetScissor"))
return (PFN_vkVoidFunction)vkCmdSetScissor;
if (!strcmp(funcName, "vkCmdSetLineWidth"))
return (PFN_vkVoidFunction)vkCmdSetLineWidth;
if (!strcmp(funcName, "vkCmdSetDepthBias"))
return (PFN_vkVoidFunction)vkCmdSetDepthBias;
if (!strcmp(funcName, "vkCmdSetBlendConstants"))
return (PFN_vkVoidFunction)vkCmdSetBlendConstants;
if (!strcmp(funcName, "vkCmdSetDepthBounds"))
return (PFN_vkVoidFunction)vkCmdSetDepthBounds;
if (!strcmp(funcName, "vkCmdSetStencilCompareMask"))
return (PFN_vkVoidFunction)vkCmdSetStencilCompareMask;
if (!strcmp(funcName, "vkCmdSetStencilWriteMask"))
return (PFN_vkVoidFunction)vkCmdSetStencilWriteMask;
if (!strcmp(funcName, "vkCmdSetStencilReference"))
return (PFN_vkVoidFunction)vkCmdSetStencilReference;
if (!strcmp(funcName, "vkCmdDraw"))
return (PFN_vkVoidFunction)vkCmdDraw;
if (!strcmp(funcName, "vkCmdDrawIndexed"))
return (PFN_vkVoidFunction)vkCmdDrawIndexed;
if (!strcmp(funcName, "vkCmdDrawIndirect"))
return (PFN_vkVoidFunction)vkCmdDrawIndirect;
if (!strcmp(funcName, "vkCmdDrawIndexedIndirect"))
return (PFN_vkVoidFunction)vkCmdDrawIndexedIndirect;
if (!strcmp(funcName, "vkCmdDispatch"))
return (PFN_vkVoidFunction)vkCmdDispatch;
if (!strcmp(funcName, "vkCmdDispatchIndirect"))
return (PFN_vkVoidFunction)vkCmdDispatchIndirect;
if (!strcmp(funcName, "vkCmdCopyBuffer"))
return (PFN_vkVoidFunction)vkCmdCopyBuffer;
if (!strcmp(funcName, "vkCmdCopyImage"))
return (PFN_vkVoidFunction)vkCmdCopyImage;
if (!strcmp(funcName, "vkCmdBlitImage"))
return (PFN_vkVoidFunction)vkCmdBlitImage;
if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
return (PFN_vkVoidFunction)vkCmdCopyBufferToImage;
if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
return (PFN_vkVoidFunction)vkCmdCopyImageToBuffer;
if (!strcmp(funcName, "vkCmdUpdateBuffer"))
return (PFN_vkVoidFunction)vkCmdUpdateBuffer;
if (!strcmp(funcName, "vkCmdFillBuffer"))
return (PFN_vkVoidFunction)vkCmdFillBuffer;
if (!strcmp(funcName, "vkCmdClearColorImage"))
return (PFN_vkVoidFunction)vkCmdClearColorImage;
if (!strcmp(funcName, "vkCmdClearDepthStencilImage"))
return (PFN_vkVoidFunction)vkCmdClearDepthStencilImage;
if (!strcmp(funcName, "vkCmdClearAttachments"))
return (PFN_vkVoidFunction)vkCmdClearAttachments;
if (!strcmp(funcName, "vkCmdResolveImage"))
return (PFN_vkVoidFunction)vkCmdResolveImage;
if (!strcmp(funcName, "vkCmdSetEvent"))
return (PFN_vkVoidFunction)vkCmdSetEvent;
if (!strcmp(funcName, "vkCmdResetEvent"))
return (PFN_vkVoidFunction)vkCmdResetEvent;
if (!strcmp(funcName, "vkCmdWaitEvents"))
return (PFN_vkVoidFunction)vkCmdWaitEvents;
if (!strcmp(funcName, "vkCmdPipelineBarrier"))
return (PFN_vkVoidFunction)vkCmdPipelineBarrier;
if (!strcmp(funcName, "vkCmdBeginQuery"))
return (PFN_vkVoidFunction)vkCmdBeginQuery;
if (!strcmp(funcName, "vkCmdEndQuery"))
return (PFN_vkVoidFunction)vkCmdEndQuery;
if (!strcmp(funcName, "vkCmdResetQueryPool"))
return (PFN_vkVoidFunction)vkCmdResetQueryPool;
if (!strcmp(funcName, "vkCmdWriteTimestamp"))
return (PFN_vkVoidFunction)vkCmdWriteTimestamp;
if (!strcmp(funcName, "vkCmdCopyQueryPoolResults"))
return (PFN_vkVoidFunction)vkCmdCopyQueryPoolResults;
if (!strcmp(funcName, "vkCmdPushConstants"))
return (PFN_vkVoidFunction)vkCmdPushConstants;
if (!strcmp(funcName, "vkCmdBeginRenderPass"))
return (PFN_vkVoidFunction)vkCmdBeginRenderPass;
if (!strcmp(funcName, "vkCmdNextSubpass"))
return (PFN_vkVoidFunction)vkCmdNextSubpass;
if (!strcmp(funcName, "vkCmdEndRenderPass"))
return (PFN_vkVoidFunction)vkCmdEndRenderPass;
if (!strcmp(funcName, "vkCmdExecuteCommands"))
return (PFN_vkVoidFunction)vkCmdExecuteCommands;
// Instance extensions
void *addr;
if (debug_report_instance_gpa(inst, funcName, &addr))
return addr;
if (wsi_swapchain_instance_gpa(inst, funcName, &addr))
return addr;
addr = loader_dev_ext_gpa(inst, funcName);
return addr;
}
static inline void *globalGetProcAddr(const char *name) {
if (!name || name[0] != 'v' || name[1] != 'k')
return NULL;
name += 2;
if (!strcmp(name, "CreateInstance"))
return (void *)vkCreateInstance;
if (!strcmp(name, "EnumerateInstanceExtensionProperties"))
return (void *)vkEnumerateInstanceExtensionProperties;
if (!strcmp(name, "EnumerateInstanceLayerProperties"))
return (void *)vkEnumerateInstanceLayerProperties;
return NULL;
}
/* These functions require special handling by the loader.
* They are not just generic trampoline code entrypoints.
* Thus GPA must return loader entrypoint for these instead of first function
* in the chain. */
static inline void *loader_non_passthrough_gipa(const char *name) {
if (!name || name[0] != 'v' || name[1] != 'k')
return NULL;
name += 2;
if (!strcmp(name, "CreateInstance"))
return (void *)vkCreateInstance;
if (!strcmp(name, "DestroyInstance"))
return (void *)vkDestroyInstance;
if (!strcmp(name, "GetDeviceProcAddr"))
return (void *)vkGetDeviceProcAddr;
// remove once no longer locks
if (!strcmp(name, "EnumeratePhysicalDevices"))
return (void *)vkEnumeratePhysicalDevices;
if (!strcmp(name, "EnumerateDeviceExtensionProperties"))
return (void *)vkEnumerateDeviceExtensionProperties;
if (!strcmp(name, "EnumerateDeviceLayerProperties"))
return (void *)vkEnumerateDeviceLayerProperties;
if (!strcmp(name, "GetInstanceProcAddr"))
return (void *)vkGetInstanceProcAddr;
if (!strcmp(name, "CreateDevice"))
return (void *)vkCreateDevice;
return NULL;
}
static inline void *loader_non_passthrough_gdpa(const char *name) {
if (!name || name[0] != 'v' || name[1] != 'k')
return NULL;
name += 2;
if (!strcmp(name, "GetDeviceProcAddr"))
return (void *)vkGetDeviceProcAddr;
if (!strcmp(name, "DestroyDevice"))
return (void *)vkDestroyDevice;
if (!strcmp(name, "GetDeviceQueue"))
return (void *)vkGetDeviceQueue;
if (!strcmp(name, "AllocateCommandBuffers"))
return (void *)vkAllocateCommandBuffers;
return NULL;
}

4504
third_party/vulkan/loader/loader.c vendored Normal file

File diff suppressed because it is too large Load Diff

551
third_party/vulkan/loader/loader.h vendored Normal file
View File

@ -0,0 +1,551 @@
/*
*
* Copyright (c) 2014-2016 The Khronos Group Inc.
* Copyright (c) 2014-2016 Valve Corporation
* Copyright (c) 2014-2016 LunarG, Inc.
* Copyright (C) 2015 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and/or associated documentation files (the "Materials"), to
* deal in the Materials without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Materials, and to permit persons to whom the Materials are
* furnished to do so, subject to the following conditions:
*
* The above copyright notice(s) and this permission notice shall be included in
* all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
* USE OR OTHER DEALINGS IN THE MATERIALS.
*
* Author: Jon Ashburn <jon@lunarg.com>
* Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
* Author: Chia-I Wu <olvaffe@gmail.com>
* Author: Chia-I Wu <olv@lunarg.com>
* Author: Mark Lobodzinski <mark@LunarG.com>
*
*/
#ifndef LOADER_H
#define LOADER_H
#include <vulkan/vulkan.h>
#include <vk_loader_platform.h>
#include <vulkan/vk_layer.h>
#include <vulkan/vk_icd.h>
#include <assert.h>
#if defined(__GNUC__) && __GNUC__ >= 4
#define LOADER_EXPORT __attribute__((visibility("default")))
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)
#define LOADER_EXPORT __attribute__((visibility("default")))
#else
#define LOADER_EXPORT
#endif
#define MAX_STRING_SIZE 1024
#define VK_MAJOR(version) (version >> 22)
#define VK_MINOR(version) ((version >> 12) & 0x3ff)
#define VK_PATCH(version) (version & 0xfff)
enum layer_type {
VK_LAYER_TYPE_DEVICE_EXPLICIT = 0x1,
VK_LAYER_TYPE_INSTANCE_EXPLICIT = 0x2,
VK_LAYER_TYPE_GLOBAL_EXPLICIT = 0x3, // instance and device layer, bitwise
VK_LAYER_TYPE_DEVICE_IMPLICIT = 0x4,
VK_LAYER_TYPE_INSTANCE_IMPLICIT = 0x8,
VK_LAYER_TYPE_GLOBAL_IMPLICIT = 0xc, // instance and device layer, bitwise
VK_LAYER_TYPE_META_EXPLICT = 0x10,
};
typedef enum VkStringErrorFlagBits {
VK_STRING_ERROR_NONE = 0x00000000,
VK_STRING_ERROR_LENGTH = 0x00000001,
VK_STRING_ERROR_BAD_DATA = 0x00000002,
} VkStringErrorFlagBits;
typedef VkFlags VkStringErrorFlags;
static const int MaxLoaderStringLength = 256;
static const char UTF8_ONE_BYTE_CODE = 0xC0;
static const char UTF8_ONE_BYTE_MASK = 0xE0;
static const char UTF8_TWO_BYTE_CODE = 0xE0;
static const char UTF8_TWO_BYTE_MASK = 0xF0;
static const char UTF8_THREE_BYTE_CODE = 0xF0;
static const char UTF8_THREE_BYTE_MASK = 0xF8;
static const char UTF8_DATA_BYTE_CODE = 0x80;
static const char UTF8_DATA_BYTE_MASK = 0xC0;
static const char std_validation_names[9][VK_MAX_EXTENSION_NAME_SIZE] = {
"VK_LAYER_LUNARG_threading", "VK_LAYER_LUNARG_param_checker",
"VK_LAYER_LUNARG_device_limits", "VK_LAYER_LUNARG_object_tracker",
"VK_LAYER_LUNARG_image", "VK_LAYER_LUNARG_mem_tracker",
"VK_LAYER_LUNARG_draw_state", "VK_LAYER_LUNARG_swapchain",
"VK_LAYER_GOOGLE_unique_objects"};
// form of all dynamic lists/arrays
// only the list element should be changed
struct loader_generic_list {
size_t capacity;
uint32_t count;
void *list;
};
struct loader_extension_list {
size_t capacity;
uint32_t count;
VkExtensionProperties *list;
};
struct loader_dev_ext_props {
VkExtensionProperties props;
uint32_t entrypoint_count;
char **entrypoints;
};
struct loader_device_extension_list {
size_t capacity;
uint32_t count;
struct loader_dev_ext_props *list;
};
struct loader_name_value {
char name[MAX_STRING_SIZE];
char value[MAX_STRING_SIZE];
};
struct loader_lib_info {
char lib_name[MAX_STRING_SIZE];
uint32_t ref_count;
loader_platform_dl_handle lib_handle;
};
struct loader_layer_functions {
char str_gipa[MAX_STRING_SIZE];
char str_gdpa[MAX_STRING_SIZE];
PFN_vkGetInstanceProcAddr get_instance_proc_addr;
PFN_vkGetDeviceProcAddr get_device_proc_addr;
};
struct loader_layer_properties {
VkLayerProperties info;
enum layer_type type;
char lib_name[MAX_STRING_SIZE];
struct loader_layer_functions functions;
struct loader_extension_list instance_extension_list;
struct loader_device_extension_list device_extension_list;
struct loader_name_value disable_env_var;
struct loader_name_value enable_env_var;
};
struct loader_layer_list {
size_t capacity;
uint32_t count;
struct loader_layer_properties *list;
};
struct loader_layer_library_list {
size_t capacity;
uint32_t count;
struct loader_lib_info *list;
};
struct loader_dispatch_hash_list {
size_t capacity;
uint32_t count;
uint32_t *index; // index into the dev_ext dispatch table
};
#define MAX_NUM_DEV_EXTS 250
// loader_dispatch_hash_entry and loader_dev_ext_dispatch_table.DevExt have one
// to one
// correspondence; one loader_dispatch_hash_entry for one DevExt dispatch entry.
// Also have a one to one correspondence with functions in dev_ext_trampoline.c
struct loader_dispatch_hash_entry {
char *func_name;
struct loader_dispatch_hash_list list; // to handle hashing collisions
};
typedef void(VKAPI_PTR *PFN_vkDevExt)(VkDevice device);
struct loader_dev_ext_dispatch_table {
PFN_vkDevExt DevExt[MAX_NUM_DEV_EXTS];
};
struct loader_dev_dispatch_table {
VkLayerDispatchTable core_dispatch;
struct loader_dev_ext_dispatch_table ext_dispatch;
};
/* per CreateDevice structure */
struct loader_device {
struct loader_dev_dispatch_table loader_dispatch;
VkDevice device; // device object from the icd
uint32_t app_extension_count;
VkExtensionProperties *app_extension_props;
struct loader_layer_list activated_layer_list;
struct loader_device *next;
};
/* per ICD structure */
struct loader_icd {
// pointers to find other structs
const struct loader_scanned_icds *this_icd_lib;
const struct loader_instance *this_instance;
struct loader_device *logical_device_list;
VkInstance instance; // instance object from the icd
PFN_vkGetDeviceProcAddr GetDeviceProcAddr;
PFN_vkDestroyInstance DestroyInstance;
PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices;
PFN_vkGetPhysicalDeviceFeatures GetPhysicalDeviceFeatures;
PFN_vkGetPhysicalDeviceFormatProperties GetPhysicalDeviceFormatProperties;
PFN_vkGetPhysicalDeviceImageFormatProperties
GetPhysicalDeviceImageFormatProperties;
PFN_vkCreateDevice CreateDevice;
PFN_vkGetPhysicalDeviceProperties GetPhysicalDeviceProperties;
PFN_vkGetPhysicalDeviceQueueFamilyProperties
GetPhysicalDeviceQueueFamilyProperties;
PFN_vkGetPhysicalDeviceMemoryProperties GetPhysicalDeviceMemoryProperties;
PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties;
PFN_vkGetPhysicalDeviceSparseImageFormatProperties
GetPhysicalDeviceSparseImageFormatProperties;
PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT;
PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT;
PFN_vkDebugReportMessageEXT DebugReportMessageEXT;
PFN_vkGetPhysicalDeviceSurfaceSupportKHR GetPhysicalDeviceSurfaceSupportKHR;
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR
GetPhysicalDeviceSurfaceCapabilitiesKHR;
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR GetPhysicalDeviceSurfaceFormatsKHR;
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR
GetPhysicalDeviceSurfacePresentModesKHR;
#ifdef VK_USE_PLATFORM_WIN32_KHR
PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR
GetPhysicalDeviceWin32PresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_MIR_KHR
PFN_vkGetPhysicalDeviceMirPresentationSupportKHR
GetPhysicalDeviceMirPresentvationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
GetPhysicalDeviceWaylandPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR
GetPhysicalDeviceXcbPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR
PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR
GetPhysicalDeviceXlibPresentationSupportKHR;
#endif
struct loader_icd *next;
};
/* per ICD library structure */
struct loader_icd_libs {
size_t capacity;
uint32_t count;
struct loader_scanned_icds *list;
};
/* per instance structure */
struct loader_instance {
VkLayerInstanceDispatchTable *disp; // must be first entry in structure
uint32_t total_gpu_count;
struct loader_physical_device *phys_devs;
uint32_t total_icd_count;
struct loader_icd *icds;
struct loader_instance *next;
struct loader_extension_list ext_list; // icds and loaders extensions
struct loader_icd_libs icd_libs;
struct loader_layer_list instance_layer_list;
struct loader_layer_list device_layer_list;
struct loader_dispatch_hash_entry disp_hash[MAX_NUM_DEV_EXTS];
struct loader_msg_callback_map_entry *icd_msg_callback_map;
struct loader_layer_list activated_layer_list;
VkInstance instance;
bool debug_report_enabled;
VkLayerDbgFunctionNode *DbgFunctionHead;
VkAllocationCallbacks alloc_callbacks;
bool wsi_surface_enabled;
#ifdef VK_USE_PLATFORM_WIN32_KHR
bool wsi_win32_surface_enabled;
#endif
#ifdef VK_USE_PLATFORM_MIR_KHR
bool wsi_mir_surface_enabled;
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
bool wsi_wayland_surface_enabled;
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
bool wsi_xcb_surface_enabled;
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR
bool wsi_xlib_surface_enabled;
#endif
#ifdef VK_USE_PLATFORM_ANDROID_KHR
bool wsi_android_surface_enabled;
#endif
};
/* per enumerated PhysicalDevice structure */
struct loader_physical_device {
VkLayerInstanceDispatchTable *disp; // must be first entry in structure
struct loader_instance *this_instance;
struct loader_icd *this_icd;
VkPhysicalDevice phys_dev; // object from ICD
/*
* Fill in the cache of available device extensions from
* this physical device. This cache can be used during CreateDevice
*/
struct loader_extension_list device_extension_cache;
};
struct loader_struct {
struct loader_instance *instances;
unsigned int loaded_layer_lib_count;
size_t loaded_layer_lib_capacity;
struct loader_lib_info *loaded_layer_lib_list;
// TODO add ref counting of ICD libraries
// TODO use this struct loader_layer_library_list scanned_layer_libraries;
// TODO add list of icd libraries for ref counting them for closure
};
struct loader_scanned_icds {
char *lib_name;
loader_platform_dl_handle handle;
uint32_t api_version;
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
PFN_vkCreateInstance CreateInstance;
PFN_vkEnumerateInstanceExtensionProperties
EnumerateInstanceExtensionProperties;
};
static inline struct loader_instance *loader_instance(VkInstance instance) {
return (struct loader_instance *)instance;
}
static inline void loader_set_dispatch(void *obj, const void *data) {
*((const void **)obj) = data;
}
static inline VkLayerDispatchTable *loader_get_dispatch(const void *obj) {
return *((VkLayerDispatchTable **)obj);
}
static inline struct loader_dev_dispatch_table *
loader_get_dev_dispatch(const void *obj) {
return *((struct loader_dev_dispatch_table **)obj);
}
static inline VkLayerInstanceDispatchTable *
loader_get_instance_dispatch(const void *obj) {
return *((VkLayerInstanceDispatchTable **)obj);
}
static inline void loader_init_dispatch(void *obj, const void *data) {
#ifdef DEBUG
assert(valid_loader_magic_value(obj) &&
"Incompatible ICD, first dword must be initialized to "
"ICD_LOADER_MAGIC. See loader/README.md for details.");
#endif
loader_set_dispatch(obj, data);
}
/* global variables used across files */
extern struct loader_struct loader;
extern THREAD_LOCAL_DECL struct loader_instance *tls_instance;
extern LOADER_PLATFORM_THREAD_ONCE_DEFINITION(once_init);
extern loader_platform_thread_mutex loader_lock;
extern loader_platform_thread_mutex loader_json_lock;
extern const VkLayerInstanceDispatchTable instance_disp;
extern const char *std_validation_str;
struct loader_msg_callback_map_entry {
VkDebugReportCallbackEXT icd_obj;
VkDebugReportCallbackEXT loader_obj;
};
void loader_log(const struct loader_instance *inst, VkFlags msg_type,
int32_t msg_code, const char *format, ...);
bool compare_vk_extension_properties(const VkExtensionProperties *op1,
const VkExtensionProperties *op2);
VkResult loader_validate_layers(const struct loader_instance *inst,
const uint32_t layer_count,
const char *const *ppEnabledLayerNames,
const struct loader_layer_list *list);
VkResult loader_validate_instance_extensions(
const struct loader_instance *inst,
const struct loader_extension_list *icd_exts,
const struct loader_layer_list *instance_layer,
const VkInstanceCreateInfo *pCreateInfo);
/* instance layer chain termination entrypoint definitions */
VKAPI_ATTR VkResult VKAPI_CALL
loader_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkInstance *pInstance);
VKAPI_ATTR void VKAPI_CALL
loader_DestroyInstance(VkInstance instance,
const VkAllocationCallbacks *pAllocator);
VKAPI_ATTR VkResult VKAPI_CALL
loader_EnumeratePhysicalDevices(VkInstance instance,
uint32_t *pPhysicalDeviceCount,
VkPhysicalDevice *pPhysicalDevices);
VKAPI_ATTR void VKAPI_CALL
loader_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
VkPhysicalDeviceFeatures *pFeatures);
VKAPI_ATTR void VKAPI_CALL
loader_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice,
VkFormat format,
VkFormatProperties *pFormatInfo);
VKAPI_ATTR VkResult VKAPI_CALL loader_GetPhysicalDeviceImageFormatProperties(
VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
VkImageFormatProperties *pImageFormatProperties);
VKAPI_ATTR void VKAPI_CALL loader_GetPhysicalDeviceSparseImageFormatProperties(
VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
VkSampleCountFlagBits samples, VkImageUsageFlags usage,
VkImageTiling tiling, uint32_t *pNumProperties,
VkSparseImageFormatProperties *pProperties);
VKAPI_ATTR void VKAPI_CALL
loader_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
VkPhysicalDeviceProperties *pProperties);
VKAPI_ATTR VkResult VKAPI_CALL
loader_EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
const char *pLayerName,
uint32_t *pCount,
VkExtensionProperties *pProperties);
VKAPI_ATTR VkResult VKAPI_CALL
loader_EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
uint32_t *pCount,
VkLayerProperties *pProperties);
VKAPI_ATTR void VKAPI_CALL loader_GetPhysicalDeviceQueueFamilyProperties(
VkPhysicalDevice physicalDevice, uint32_t *pCount,
VkQueueFamilyProperties *pProperties);
VKAPI_ATTR void VKAPI_CALL loader_GetPhysicalDeviceMemoryProperties(
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceMemoryProperties *pProperties);
VKAPI_ATTR VkResult VKAPI_CALL
loader_create_device_terminator(VkPhysicalDevice physicalDevice,
const VkDeviceCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkDevice *pDevice);
VKAPI_ATTR VkResult VKAPI_CALL
loader_CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkDevice *pDevice);
/* helper function definitions */
void loader_initialize(void);
bool has_vk_extension_property_array(const VkExtensionProperties *vk_ext_prop,
const uint32_t count,
const VkExtensionProperties *ext_array);
bool has_vk_extension_property(const VkExtensionProperties *vk_ext_prop,
const struct loader_extension_list *ext_list);
VkResult loader_add_to_ext_list(const struct loader_instance *inst,
struct loader_extension_list *ext_list,
uint32_t prop_list_count,
const VkExtensionProperties *props);
void loader_destroy_generic_list(const struct loader_instance *inst,
struct loader_generic_list *list);
void loader_delete_layer_properties(const struct loader_instance *inst,
struct loader_layer_list *layer_list);
void loader_expand_layer_names(
const struct loader_instance *inst, const char *key_name,
uint32_t expand_count,
const char expand_names[][VK_MAX_EXTENSION_NAME_SIZE],
uint32_t *layer_count, char ***ppp_layer_names);
void loader_unexpand_dev_layer_names(const struct loader_instance *inst,
uint32_t layer_count, char **layer_names,
char **layer_ptr,
const VkDeviceCreateInfo *pCreateInfo);
void loader_unexpand_inst_layer_names(const struct loader_instance *inst,
uint32_t layer_count, char **layer_names,
char **layer_ptr,
const VkInstanceCreateInfo *pCreateInfo);
void loader_add_to_layer_list(const struct loader_instance *inst,
struct loader_layer_list *list,
uint32_t prop_list_count,
const struct loader_layer_properties *props);
void loader_scanned_icd_clear(const struct loader_instance *inst,
struct loader_icd_libs *icd_libs);
void loader_icd_scan(const struct loader_instance *inst,
struct loader_icd_libs *icds);
void loader_layer_scan(const struct loader_instance *inst,
struct loader_layer_list *instance_layers,
struct loader_layer_list *device_layers);
void loader_get_icd_loader_instance_extensions(
const struct loader_instance *inst, struct loader_icd_libs *icd_libs,
struct loader_extension_list *inst_exts);
struct loader_icd *loader_get_icd_and_device(const VkDevice device,
struct loader_device **found_dev);
void *loader_dev_ext_gpa(struct loader_instance *inst, const char *funcName);
void *loader_get_dev_ext_trampoline(uint32_t index);
struct loader_instance *loader_get_instance(const VkInstance instance);
void loader_remove_logical_device(const struct loader_instance *inst,
struct loader_icd *icd,
struct loader_device *found_dev);
VkResult
loader_enable_instance_layers(struct loader_instance *inst,
const VkInstanceCreateInfo *pCreateInfo,
const struct loader_layer_list *instance_layers);
void loader_deactivate_instance_layers(struct loader_instance *instance);
VkResult loader_create_instance_chain(const VkInstanceCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
struct loader_instance *inst,
VkInstance *created_instance);
void loader_activate_instance_layer_extensions(struct loader_instance *inst,
VkInstance created_inst);
void *loader_heap_alloc(const struct loader_instance *instance, size_t size,
VkSystemAllocationScope allocationScope);
void loader_heap_free(const struct loader_instance *instance, void *pMemory);
void *loader_tls_heap_alloc(size_t size);
void loader_tls_heap_free(void *pMemory);
VkStringErrorFlags vk_string_validate(const int max_length,
const char *char_array);
#endif /* LOADER_H */

97
third_party/vulkan/loader/murmurhash.c vendored Normal file
View File

@ -0,0 +1,97 @@
/**
* `murmurhash.h' - murmurhash
*
* copyright (c) 2014 joseph werle <joseph.werle@gmail.com>
* Copyright (c) 2015-2016 The Khronos Group Inc.
* Copyright (c) 2015-2016 Valve Corporation
* Copyright (c) 2015-2016 LunarG, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and/or associated documentation files (the "Materials"), to
* deal in the Materials without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Materials, and to permit persons to whom the Materials are
* furnished to do so, subject to the following conditions:
*
* The above copyright notice(s) and this permission notice shall be included in
* all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
* USE OR OTHER DEALINGS IN THE MATERIALS.
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include "murmurhash.h"
uint32_t murmurhash(const char *key, size_t len, uint32_t seed) {
uint32_t c1 = 0xcc9e2d51;
uint32_t c2 = 0x1b873593;
uint32_t r1 = 15;
uint32_t r2 = 13;
uint32_t m = 5;
uint32_t n = 0xe6546b64;
uint32_t h = 0;
uint32_t k = 0;
uint8_t *d = (uint8_t *)key; // 32 bit extract from `key'
const uint32_t *chunks = NULL;
const uint8_t *tail = NULL; // tail - last 8 bytes
int i = 0;
int l = (int)len / 4; // chunk length
h = seed;
chunks = (const uint32_t *)(d + l * 4); // body
tail = (const uint8_t *)(d + l * 4); // last 8 byte chunk of `key'
// for each 4 byte chunk of `key'
for (i = -l; i != 0; ++i) {
// next 4 byte chunk of `key'
k = chunks[i];
// encode next 4 byte chunk of `key'
k *= c1;
k = (k << r1) | (k >> (32 - r1));
k *= c2;
// append to hash
h ^= k;
h = (h << r2) | (h >> (32 - r2));
h = h * m + n;
}
k = 0;
// remainder
switch (len & 3) { // `len % 4'
case 3:
k ^= (tail[2] << 16);
case 2:
k ^= (tail[1] << 8);
case 1:
k ^= tail[0];
k *= c1;
k = (k << r1) | (k >> (32 - r1));
k *= c2;
h ^= k;
}
h ^= len;
h ^= (h >> 16);
h *= 0x85ebca6b;
h ^= (h >> 13);
h *= 0xc2b2ae35;
h ^= (h >> 16);
return h;
}

52
third_party/vulkan/loader/murmurhash.h vendored Normal file
View File

@ -0,0 +1,52 @@
/**
* `murmurhash.h' - murmurhash
*
* copyright (c) 2014 joseph werle <joseph.werle@gmail.com>
* Copyright (c) 2015-2016 The Khronos Group Inc.
* Copyright (c) 2015-2016 Valve Corporation
* Copyright (c) 2015-2016 LunarG, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and/or associated documentation files (the "Materials"), to
* deal in the Materials without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Materials, and to permit persons to whom the Materials are
* furnished to do so, subject to the following conditions:
*
* The above copyright notice(s) and this permission notice shall be included in
* all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
* USE OR OTHER DEALINGS IN THE MATERIALS.
*/
#ifndef MURMURHASH_H
#define MURMURHASH_H 1
#include <stdint.h>
#define MURMURHASH_VERSION "0.0.3"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Returns a murmur hash of `key' based on `seed'
* using the MurmurHash3 algorithm
*/
uint32_t murmurhash(const char *key, size_t len, uint32_t seed);
#ifdef __cplusplus
}
#endif
#endif

24
third_party/vulkan/loader/premake5.lua vendored Normal file
View File

@ -0,0 +1,24 @@
group("third_party")
project("vulkan-loader")
uuid("07d77359-1618-43e6-8a4a-0ee9ddc5fa6a")
kind("StaticLib")
language("C++")
defines({
"_LIB",
})
removedefines({
"_UNICODE",
"UNICODE",
})
includedirs({
".",
})
recursive_platform_files()
filter("platforms:Windows")
warnings("Off") -- Too many warnings.
characterset("MBCS")
defines({
"VK_USE_PLATFORM_WIN32_KHR",
})

710
third_party/vulkan/loader/table_ops.h vendored Normal file
View File

@ -0,0 +1,710 @@
/*
*
* Copyright (c) 2015-2016 The Khronos Group Inc.
* Copyright (c) 2015-2016 Valve Corporation
* Copyright (c) 2015-2016 LunarG, Inc.
* Copyright (C) 2016 Google Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and/or associated documentation files (the "Materials"), to
* deal in the Materials without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Materials, and to permit persons to whom the Materials are
* furnished to do so, subject to the following conditions:
*
* The above copyright notice(s) and this permission notice shall be included in
* all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
* USE OR OTHER DEALINGS IN THE MATERIALS.
*
* Author: Courtney Goeltzenleuchter <courtney@lunarg.com>
* Author: Jon Ashburn <jon@lunarg.com>
* Author: Ian Elliott <ian@LunarG.com>
* Author: Tony Barbour <tony@LunarG.com>
*/
#include <vulkan/vulkan.h>
#include <vulkan/vk_layer.h>
#include <string.h>
#include "loader.h"
#include "vk_loader_platform.h"
static VkResult vkDevExtError(VkDevice dev) {
struct loader_device *found_dev;
struct loader_icd *icd = loader_get_icd_and_device(dev, &found_dev);
if (icd)
loader_log(icd->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
"Bad destination in loader trampoline dispatch,"
"Are layers and extensions that you are calling enabled?");
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
static inline void
loader_init_device_dispatch_table(struct loader_dev_dispatch_table *dev_table,
PFN_vkGetDeviceProcAddr gpa, VkDevice dev) {
VkLayerDispatchTable *table = &dev_table->core_dispatch;
for (uint32_t i = 0; i < MAX_NUM_DEV_EXTS; i++)
dev_table->ext_dispatch.DevExt[i] = (PFN_vkDevExt)vkDevExtError;
table->GetDeviceProcAddr =
(PFN_vkGetDeviceProcAddr)gpa(dev, "vkGetDeviceProcAddr");
table->DestroyDevice = (PFN_vkDestroyDevice)gpa(dev, "vkDestroyDevice");
table->GetDeviceQueue = (PFN_vkGetDeviceQueue)gpa(dev, "vkGetDeviceQueue");
table->QueueSubmit = (PFN_vkQueueSubmit)gpa(dev, "vkQueueSubmit");
table->QueueWaitIdle = (PFN_vkQueueWaitIdle)gpa(dev, "vkQueueWaitIdle");
table->DeviceWaitIdle = (PFN_vkDeviceWaitIdle)gpa(dev, "vkDeviceWaitIdle");
table->AllocateMemory = (PFN_vkAllocateMemory)gpa(dev, "vkAllocateMemory");
table->FreeMemory = (PFN_vkFreeMemory)gpa(dev, "vkFreeMemory");
table->MapMemory = (PFN_vkMapMemory)gpa(dev, "vkMapMemory");
table->UnmapMemory = (PFN_vkUnmapMemory)gpa(dev, "vkUnmapMemory");
table->FlushMappedMemoryRanges =
(PFN_vkFlushMappedMemoryRanges)gpa(dev, "vkFlushMappedMemoryRanges");
table->InvalidateMappedMemoryRanges =
(PFN_vkInvalidateMappedMemoryRanges)gpa(
dev, "vkInvalidateMappedMemoryRanges");
table->GetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment)gpa(
dev, "vkGetDeviceMemoryCommitment");
table->GetImageSparseMemoryRequirements =
(PFN_vkGetImageSparseMemoryRequirements)gpa(
dev, "vkGetImageSparseMemoryRequirements");
table->GetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements)gpa(
dev, "vkGetBufferMemoryRequirements");
table->GetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements)gpa(
dev, "vkGetImageMemoryRequirements");
table->BindBufferMemory =
(PFN_vkBindBufferMemory)gpa(dev, "vkBindBufferMemory");
table->BindImageMemory =
(PFN_vkBindImageMemory)gpa(dev, "vkBindImageMemory");
table->QueueBindSparse =
(PFN_vkQueueBindSparse)gpa(dev, "vkQueueBindSparse");
table->CreateFence = (PFN_vkCreateFence)gpa(dev, "vkCreateFence");
table->DestroyFence = (PFN_vkDestroyFence)gpa(dev, "vkDestroyFence");
table->ResetFences = (PFN_vkResetFences)gpa(dev, "vkResetFences");
table->GetFenceStatus = (PFN_vkGetFenceStatus)gpa(dev, "vkGetFenceStatus");
table->WaitForFences = (PFN_vkWaitForFences)gpa(dev, "vkWaitForFences");
table->CreateSemaphore =
(PFN_vkCreateSemaphore)gpa(dev, "vkCreateSemaphore");
table->DestroySemaphore =
(PFN_vkDestroySemaphore)gpa(dev, "vkDestroySemaphore");
table->CreateEvent = (PFN_vkCreateEvent)gpa(dev, "vkCreateEvent");
table->DestroyEvent = (PFN_vkDestroyEvent)gpa(dev, "vkDestroyEvent");
table->GetEventStatus = (PFN_vkGetEventStatus)gpa(dev, "vkGetEventStatus");
table->SetEvent = (PFN_vkSetEvent)gpa(dev, "vkSetEvent");
table->ResetEvent = (PFN_vkResetEvent)gpa(dev, "vkResetEvent");
table->CreateQueryPool =
(PFN_vkCreateQueryPool)gpa(dev, "vkCreateQueryPool");
table->DestroyQueryPool =
(PFN_vkDestroyQueryPool)gpa(dev, "vkDestroyQueryPool");
table->GetQueryPoolResults =
(PFN_vkGetQueryPoolResults)gpa(dev, "vkGetQueryPoolResults");
table->CreateBuffer = (PFN_vkCreateBuffer)gpa(dev, "vkCreateBuffer");
table->DestroyBuffer = (PFN_vkDestroyBuffer)gpa(dev, "vkDestroyBuffer");
table->CreateBufferView =
(PFN_vkCreateBufferView)gpa(dev, "vkCreateBufferView");
table->DestroyBufferView =
(PFN_vkDestroyBufferView)gpa(dev, "vkDestroyBufferView");
table->CreateImage = (PFN_vkCreateImage)gpa(dev, "vkCreateImage");
table->DestroyImage = (PFN_vkDestroyImage)gpa(dev, "vkDestroyImage");
table->GetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout)gpa(
dev, "vkGetImageSubresourceLayout");
table->CreateImageView =
(PFN_vkCreateImageView)gpa(dev, "vkCreateImageView");
table->DestroyImageView =
(PFN_vkDestroyImageView)gpa(dev, "vkDestroyImageView");
table->CreateShaderModule =
(PFN_vkCreateShaderModule)gpa(dev, "vkCreateShaderModule");
table->DestroyShaderModule =
(PFN_vkDestroyShaderModule)gpa(dev, "vkDestroyShaderModule");
table->CreatePipelineCache =
(PFN_vkCreatePipelineCache)gpa(dev, "vkCreatePipelineCache");
table->DestroyPipelineCache =
(PFN_vkDestroyPipelineCache)gpa(dev, "vkDestroyPipelineCache");
table->GetPipelineCacheData =
(PFN_vkGetPipelineCacheData)gpa(dev, "vkGetPipelineCacheData");
table->MergePipelineCaches =
(PFN_vkMergePipelineCaches)gpa(dev, "vkMergePipelineCaches");
table->CreateGraphicsPipelines =
(PFN_vkCreateGraphicsPipelines)gpa(dev, "vkCreateGraphicsPipelines");
table->CreateComputePipelines =
(PFN_vkCreateComputePipelines)gpa(dev, "vkCreateComputePipelines");
table->DestroyPipeline =
(PFN_vkDestroyPipeline)gpa(dev, "vkDestroyPipeline");
table->CreatePipelineLayout =
(PFN_vkCreatePipelineLayout)gpa(dev, "vkCreatePipelineLayout");
table->DestroyPipelineLayout =
(PFN_vkDestroyPipelineLayout)gpa(dev, "vkDestroyPipelineLayout");
table->CreateSampler = (PFN_vkCreateSampler)gpa(dev, "vkCreateSampler");
table->DestroySampler = (PFN_vkDestroySampler)gpa(dev, "vkDestroySampler");
table->CreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout)gpa(
dev, "vkCreateDescriptorSetLayout");
table->DestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout)gpa(
dev, "vkDestroyDescriptorSetLayout");
table->CreateDescriptorPool =
(PFN_vkCreateDescriptorPool)gpa(dev, "vkCreateDescriptorPool");
table->DestroyDescriptorPool =
(PFN_vkDestroyDescriptorPool)gpa(dev, "vkDestroyDescriptorPool");
table->ResetDescriptorPool =
(PFN_vkResetDescriptorPool)gpa(dev, "vkResetDescriptorPool");
table->AllocateDescriptorSets =
(PFN_vkAllocateDescriptorSets)gpa(dev, "vkAllocateDescriptorSets");
table->FreeDescriptorSets =
(PFN_vkFreeDescriptorSets)gpa(dev, "vkFreeDescriptorSets");
table->UpdateDescriptorSets =
(PFN_vkUpdateDescriptorSets)gpa(dev, "vkUpdateDescriptorSets");
table->CreateFramebuffer =
(PFN_vkCreateFramebuffer)gpa(dev, "vkCreateFramebuffer");
table->DestroyFramebuffer =
(PFN_vkDestroyFramebuffer)gpa(dev, "vkDestroyFramebuffer");
table->CreateRenderPass =
(PFN_vkCreateRenderPass)gpa(dev, "vkCreateRenderPass");
table->DestroyRenderPass =
(PFN_vkDestroyRenderPass)gpa(dev, "vkDestroyRenderPass");
table->GetRenderAreaGranularity =
(PFN_vkGetRenderAreaGranularity)gpa(dev, "vkGetRenderAreaGranularity");
table->CreateCommandPool =
(PFN_vkCreateCommandPool)gpa(dev, "vkCreateCommandPool");
table->DestroyCommandPool =
(PFN_vkDestroyCommandPool)gpa(dev, "vkDestroyCommandPool");
table->ResetCommandPool =
(PFN_vkResetCommandPool)gpa(dev, "vkResetCommandPool");
table->AllocateCommandBuffers =
(PFN_vkAllocateCommandBuffers)gpa(dev, "vkAllocateCommandBuffers");
table->FreeCommandBuffers =
(PFN_vkFreeCommandBuffers)gpa(dev, "vkFreeCommandBuffers");
table->BeginCommandBuffer =
(PFN_vkBeginCommandBuffer)gpa(dev, "vkBeginCommandBuffer");
table->EndCommandBuffer =
(PFN_vkEndCommandBuffer)gpa(dev, "vkEndCommandBuffer");
table->ResetCommandBuffer =
(PFN_vkResetCommandBuffer)gpa(dev, "vkResetCommandBuffer");
table->CmdBindPipeline =
(PFN_vkCmdBindPipeline)gpa(dev, "vkCmdBindPipeline");
table->CmdSetViewport = (PFN_vkCmdSetViewport)gpa(dev, "vkCmdSetViewport");
table->CmdSetScissor = (PFN_vkCmdSetScissor)gpa(dev, "vkCmdSetScissor");
table->CmdSetLineWidth =
(PFN_vkCmdSetLineWidth)gpa(dev, "vkCmdSetLineWidth");
table->CmdSetDepthBias =
(PFN_vkCmdSetDepthBias)gpa(dev, "vkCmdSetDepthBias");
table->CmdSetBlendConstants =
(PFN_vkCmdSetBlendConstants)gpa(dev, "vkCmdSetBlendConstants");
table->CmdSetDepthBounds =
(PFN_vkCmdSetDepthBounds)gpa(dev, "vkCmdSetDepthBounds");
table->CmdSetStencilCompareMask =
(PFN_vkCmdSetStencilCompareMask)gpa(dev, "vkCmdSetStencilCompareMask");
table->CmdSetStencilWriteMask =
(PFN_vkCmdSetStencilWriteMask)gpa(dev, "vkCmdSetStencilWriteMask");
table->CmdSetStencilReference =
(PFN_vkCmdSetStencilReference)gpa(dev, "vkCmdSetStencilReference");
table->CmdBindDescriptorSets =
(PFN_vkCmdBindDescriptorSets)gpa(dev, "vkCmdBindDescriptorSets");
table->CmdBindVertexBuffers =
(PFN_vkCmdBindVertexBuffers)gpa(dev, "vkCmdBindVertexBuffers");
table->CmdBindIndexBuffer =
(PFN_vkCmdBindIndexBuffer)gpa(dev, "vkCmdBindIndexBuffer");
table->CmdDraw = (PFN_vkCmdDraw)gpa(dev, "vkCmdDraw");
table->CmdDrawIndexed = (PFN_vkCmdDrawIndexed)gpa(dev, "vkCmdDrawIndexed");
table->CmdDrawIndirect =
(PFN_vkCmdDrawIndirect)gpa(dev, "vkCmdDrawIndirect");
table->CmdDrawIndexedIndirect =
(PFN_vkCmdDrawIndexedIndirect)gpa(dev, "vkCmdDrawIndexedIndirect");
table->CmdDispatch = (PFN_vkCmdDispatch)gpa(dev, "vkCmdDispatch");
table->CmdDispatchIndirect =
(PFN_vkCmdDispatchIndirect)gpa(dev, "vkCmdDispatchIndirect");
table->CmdCopyBuffer = (PFN_vkCmdCopyBuffer)gpa(dev, "vkCmdCopyBuffer");
table->CmdCopyImage = (PFN_vkCmdCopyImage)gpa(dev, "vkCmdCopyImage");
table->CmdBlitImage = (PFN_vkCmdBlitImage)gpa(dev, "vkCmdBlitImage");
table->CmdCopyBufferToImage =
(PFN_vkCmdCopyBufferToImage)gpa(dev, "vkCmdCopyBufferToImage");
table->CmdCopyImageToBuffer =
(PFN_vkCmdCopyImageToBuffer)gpa(dev, "vkCmdCopyImageToBuffer");
table->CmdUpdateBuffer =
(PFN_vkCmdUpdateBuffer)gpa(dev, "vkCmdUpdateBuffer");
table->CmdFillBuffer = (PFN_vkCmdFillBuffer)gpa(dev, "vkCmdFillBuffer");
table->CmdClearColorImage =
(PFN_vkCmdClearColorImage)gpa(dev, "vkCmdClearColorImage");
table->CmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage)gpa(
dev, "vkCmdClearDepthStencilImage");
table->CmdClearAttachments =
(PFN_vkCmdClearAttachments)gpa(dev, "vkCmdClearAttachments");
table->CmdResolveImage =
(PFN_vkCmdResolveImage)gpa(dev, "vkCmdResolveImage");
table->CmdSetEvent = (PFN_vkCmdSetEvent)gpa(dev, "vkCmdSetEvent");
table->CmdResetEvent = (PFN_vkCmdResetEvent)gpa(dev, "vkCmdResetEvent");
table->CmdWaitEvents = (PFN_vkCmdWaitEvents)gpa(dev, "vkCmdWaitEvents");
table->CmdPipelineBarrier =
(PFN_vkCmdPipelineBarrier)gpa(dev, "vkCmdPipelineBarrier");
table->CmdBeginQuery = (PFN_vkCmdBeginQuery)gpa(dev, "vkCmdBeginQuery");
table->CmdEndQuery = (PFN_vkCmdEndQuery)gpa(dev, "vkCmdEndQuery");
table->CmdResetQueryPool =
(PFN_vkCmdResetQueryPool)gpa(dev, "vkCmdResetQueryPool");
table->CmdWriteTimestamp =
(PFN_vkCmdWriteTimestamp)gpa(dev, "vkCmdWriteTimestamp");
table->CmdCopyQueryPoolResults =
(PFN_vkCmdCopyQueryPoolResults)gpa(dev, "vkCmdCopyQueryPoolResults");
table->CmdPushConstants =
(PFN_vkCmdPushConstants)gpa(dev, "vkCmdPushConstants");
table->CmdBeginRenderPass =
(PFN_vkCmdBeginRenderPass)gpa(dev, "vkCmdBeginRenderPass");
table->CmdNextSubpass = (PFN_vkCmdNextSubpass)gpa(dev, "vkCmdNextSubpass");
table->CmdEndRenderPass =
(PFN_vkCmdEndRenderPass)gpa(dev, "vkCmdEndRenderPass");
table->CmdExecuteCommands =
(PFN_vkCmdExecuteCommands)gpa(dev, "vkCmdExecuteCommands");
}
static inline void loader_init_device_extension_dispatch_table(
struct loader_dev_dispatch_table *dev_table, PFN_vkGetDeviceProcAddr gpa,
VkDevice dev) {
VkLayerDispatchTable *table = &dev_table->core_dispatch;
table->AcquireNextImageKHR =
(PFN_vkAcquireNextImageKHR)gpa(dev, "vkAcquireNextImageKHR");
table->CreateSwapchainKHR =
(PFN_vkCreateSwapchainKHR)gpa(dev, "vkCreateSwapchainKHR");
table->DestroySwapchainKHR =
(PFN_vkDestroySwapchainKHR)gpa(dev, "vkDestroySwapchainKHR");
table->GetSwapchainImagesKHR =
(PFN_vkGetSwapchainImagesKHR)gpa(dev, "vkGetSwapchainImagesKHR");
table->QueuePresentKHR =
(PFN_vkQueuePresentKHR)gpa(dev, "vkQueuePresentKHR");
}
static inline void *
loader_lookup_device_dispatch_table(const VkLayerDispatchTable *table,
const char *name) {
if (!name || name[0] != 'v' || name[1] != 'k')
return NULL;
name += 2;
if (!strcmp(name, "GetDeviceProcAddr"))
return (void *)table->GetDeviceProcAddr;
if (!strcmp(name, "DestroyDevice"))
return (void *)table->DestroyDevice;
if (!strcmp(name, "GetDeviceQueue"))
return (void *)table->GetDeviceQueue;
if (!strcmp(name, "QueueSubmit"))
return (void *)table->QueueSubmit;
if (!strcmp(name, "QueueWaitIdle"))
return (void *)table->QueueWaitIdle;
if (!strcmp(name, "DeviceWaitIdle"))
return (void *)table->DeviceWaitIdle;
if (!strcmp(name, "AllocateMemory"))
return (void *)table->AllocateMemory;
if (!strcmp(name, "FreeMemory"))
return (void *)table->FreeMemory;
if (!strcmp(name, "MapMemory"))
return (void *)table->MapMemory;
if (!strcmp(name, "UnmapMemory"))
return (void *)table->UnmapMemory;
if (!strcmp(name, "FlushMappedMemoryRanges"))
return (void *)table->FlushMappedMemoryRanges;
if (!strcmp(name, "InvalidateMappedMemoryRanges"))
return (void *)table->InvalidateMappedMemoryRanges;
if (!strcmp(name, "GetDeviceMemoryCommitment"))
return (void *)table->GetDeviceMemoryCommitment;
if (!strcmp(name, "GetImageSparseMemoryRequirements"))
return (void *)table->GetImageSparseMemoryRequirements;
if (!strcmp(name, "GetBufferMemoryRequirements"))
return (void *)table->GetBufferMemoryRequirements;
if (!strcmp(name, "GetImageMemoryRequirements"))
return (void *)table->GetImageMemoryRequirements;
if (!strcmp(name, "BindBufferMemory"))
return (void *)table->BindBufferMemory;
if (!strcmp(name, "BindImageMemory"))
return (void *)table->BindImageMemory;
if (!strcmp(name, "QueueBindSparse"))
return (void *)table->QueueBindSparse;
if (!strcmp(name, "CreateFence"))
return (void *)table->CreateFence;
if (!strcmp(name, "DestroyFence"))
return (void *)table->DestroyFence;
if (!strcmp(name, "ResetFences"))
return (void *)table->ResetFences;
if (!strcmp(name, "GetFenceStatus"))
return (void *)table->GetFenceStatus;
if (!strcmp(name, "WaitForFences"))
return (void *)table->WaitForFences;
if (!strcmp(name, "CreateSemaphore"))
return (void *)table->CreateSemaphore;
if (!strcmp(name, "DestroySemaphore"))
return (void *)table->DestroySemaphore;
if (!strcmp(name, "CreateEvent"))
return (void *)table->CreateEvent;
if (!strcmp(name, "DestroyEvent"))
return (void *)table->DestroyEvent;
if (!strcmp(name, "GetEventStatus"))
return (void *)table->GetEventStatus;
if (!strcmp(name, "SetEvent"))
return (void *)table->SetEvent;
if (!strcmp(name, "ResetEvent"))
return (void *)table->ResetEvent;
if (!strcmp(name, "CreateQueryPool"))
return (void *)table->CreateQueryPool;
if (!strcmp(name, "DestroyQueryPool"))
return (void *)table->DestroyQueryPool;
if (!strcmp(name, "GetQueryPoolResults"))
return (void *)table->GetQueryPoolResults;
if (!strcmp(name, "CreateBuffer"))
return (void *)table->CreateBuffer;
if (!strcmp(name, "DestroyBuffer"))
return (void *)table->DestroyBuffer;
if (!strcmp(name, "CreateBufferView"))
return (void *)table->CreateBufferView;
if (!strcmp(name, "DestroyBufferView"))
return (void *)table->DestroyBufferView;
if (!strcmp(name, "CreateImage"))
return (void *)table->CreateImage;
if (!strcmp(name, "DestroyImage"))
return (void *)table->DestroyImage;
if (!strcmp(name, "GetImageSubresourceLayout"))
return (void *)table->GetImageSubresourceLayout;
if (!strcmp(name, "CreateImageView"))
return (void *)table->CreateImageView;
if (!strcmp(name, "DestroyImageView"))
return (void *)table->DestroyImageView;
if (!strcmp(name, "CreateShaderModule"))
return (void *)table->CreateShaderModule;
if (!strcmp(name, "DestroyShaderModule"))
return (void *)table->DestroyShaderModule;
if (!strcmp(name, "CreatePipelineCache"))
return (void *)vkCreatePipelineCache;
if (!strcmp(name, "DestroyPipelineCache"))
return (void *)vkDestroyPipelineCache;
if (!strcmp(name, "GetPipelineCacheData"))
return (void *)vkGetPipelineCacheData;
if (!strcmp(name, "MergePipelineCaches"))
return (void *)vkMergePipelineCaches;
if (!strcmp(name, "CreateGraphicsPipelines"))
return (void *)vkCreateGraphicsPipelines;
if (!strcmp(name, "CreateComputePipelines"))
return (void *)vkCreateComputePipelines;
if (!strcmp(name, "DestroyPipeline"))
return (void *)table->DestroyPipeline;
if (!strcmp(name, "CreatePipelineLayout"))
return (void *)table->CreatePipelineLayout;
if (!strcmp(name, "DestroyPipelineLayout"))
return (void *)table->DestroyPipelineLayout;
if (!strcmp(name, "CreateSampler"))
return (void *)table->CreateSampler;
if (!strcmp(name, "DestroySampler"))
return (void *)table->DestroySampler;
if (!strcmp(name, "CreateDescriptorSetLayout"))
return (void *)table->CreateDescriptorSetLayout;
if (!strcmp(name, "DestroyDescriptorSetLayout"))
return (void *)table->DestroyDescriptorSetLayout;
if (!strcmp(name, "CreateDescriptorPool"))
return (void *)table->CreateDescriptorPool;
if (!strcmp(name, "DestroyDescriptorPool"))
return (void *)table->DestroyDescriptorPool;
if (!strcmp(name, "ResetDescriptorPool"))
return (void *)table->ResetDescriptorPool;
if (!strcmp(name, "AllocateDescriptorSets"))
return (void *)table->AllocateDescriptorSets;
if (!strcmp(name, "FreeDescriptorSets"))
return (void *)table->FreeDescriptorSets;
if (!strcmp(name, "UpdateDescriptorSets"))
return (void *)table->UpdateDescriptorSets;
if (!strcmp(name, "CreateFramebuffer"))
return (void *)table->CreateFramebuffer;
if (!strcmp(name, "DestroyFramebuffer"))
return (void *)table->DestroyFramebuffer;
if (!strcmp(name, "CreateRenderPass"))
return (void *)table->CreateRenderPass;
if (!strcmp(name, "DestroyRenderPass"))
return (void *)table->DestroyRenderPass;
if (!strcmp(name, "GetRenderAreaGranularity"))
return (void *)table->GetRenderAreaGranularity;
if (!strcmp(name, "CreateCommandPool"))
return (void *)table->CreateCommandPool;
if (!strcmp(name, "DestroyCommandPool"))
return (void *)table->DestroyCommandPool;
if (!strcmp(name, "ResetCommandPool"))
return (void *)table->ResetCommandPool;
if (!strcmp(name, "AllocateCommandBuffers"))
return (void *)table->AllocateCommandBuffers;
if (!strcmp(name, "FreeCommandBuffers"))
return (void *)table->FreeCommandBuffers;
if (!strcmp(name, "BeginCommandBuffer"))
return (void *)table->BeginCommandBuffer;
if (!strcmp(name, "EndCommandBuffer"))
return (void *)table->EndCommandBuffer;
if (!strcmp(name, "ResetCommandBuffer"))
return (void *)table->ResetCommandBuffer;
if (!strcmp(name, "CmdBindPipeline"))
return (void *)table->CmdBindPipeline;
if (!strcmp(name, "CmdSetViewport"))
return (void *)table->CmdSetViewport;
if (!strcmp(name, "CmdSetScissor"))
return (void *)table->CmdSetScissor;
if (!strcmp(name, "CmdSetLineWidth"))
return (void *)table->CmdSetLineWidth;
if (!strcmp(name, "CmdSetDepthBias"))
return (void *)table->CmdSetDepthBias;
if (!strcmp(name, "CmdSetBlendConstants"))
return (void *)table->CmdSetBlendConstants;
if (!strcmp(name, "CmdSetDepthBounds"))
return (void *)table->CmdSetDepthBounds;
if (!strcmp(name, "CmdSetStencilCompareMask"))
return (void *)table->CmdSetStencilCompareMask;
if (!strcmp(name, "CmdSetStencilwriteMask"))
return (void *)table->CmdSetStencilWriteMask;
if (!strcmp(name, "CmdSetStencilReference"))
return (void *)table->CmdSetStencilReference;
if (!strcmp(name, "CmdBindDescriptorSets"))
return (void *)table->CmdBindDescriptorSets;
if (!strcmp(name, "CmdBindVertexBuffers"))
return (void *)table->CmdBindVertexBuffers;
if (!strcmp(name, "CmdBindIndexBuffer"))
return (void *)table->CmdBindIndexBuffer;
if (!strcmp(name, "CmdDraw"))
return (void *)table->CmdDraw;
if (!strcmp(name, "CmdDrawIndexed"))
return (void *)table->CmdDrawIndexed;
if (!strcmp(name, "CmdDrawIndirect"))
return (void *)table->CmdDrawIndirect;
if (!strcmp(name, "CmdDrawIndexedIndirect"))
return (void *)table->CmdDrawIndexedIndirect;
if (!strcmp(name, "CmdDispatch"))
return (void *)table->CmdDispatch;
if (!strcmp(name, "CmdDispatchIndirect"))
return (void *)table->CmdDispatchIndirect;
if (!strcmp(name, "CmdCopyBuffer"))
return (void *)table->CmdCopyBuffer;
if (!strcmp(name, "CmdCopyImage"))
return (void *)table->CmdCopyImage;
if (!strcmp(name, "CmdBlitImage"))
return (void *)table->CmdBlitImage;
if (!strcmp(name, "CmdCopyBufferToImage"))
return (void *)table->CmdCopyBufferToImage;
if (!strcmp(name, "CmdCopyImageToBuffer"))
return (void *)table->CmdCopyImageToBuffer;
if (!strcmp(name, "CmdUpdateBuffer"))
return (void *)table->CmdUpdateBuffer;
if (!strcmp(name, "CmdFillBuffer"))
return (void *)table->CmdFillBuffer;
if (!strcmp(name, "CmdClearColorImage"))
return (void *)table->CmdClearColorImage;
if (!strcmp(name, "CmdClearDepthStencilImage"))
return (void *)table->CmdClearDepthStencilImage;
if (!strcmp(name, "CmdClearAttachments"))
return (void *)table->CmdClearAttachments;
if (!strcmp(name, "CmdResolveImage"))
return (void *)table->CmdResolveImage;
if (!strcmp(name, "CmdSetEvent"))
return (void *)table->CmdSetEvent;
if (!strcmp(name, "CmdResetEvent"))
return (void *)table->CmdResetEvent;
if (!strcmp(name, "CmdWaitEvents"))
return (void *)table->CmdWaitEvents;
if (!strcmp(name, "CmdPipelineBarrier"))
return (void *)table->CmdPipelineBarrier;
if (!strcmp(name, "CmdBeginQuery"))
return (void *)table->CmdBeginQuery;
if (!strcmp(name, "CmdEndQuery"))
return (void *)table->CmdEndQuery;
if (!strcmp(name, "CmdResetQueryPool"))
return (void *)table->CmdResetQueryPool;
if (!strcmp(name, "CmdWriteTimestamp"))
return (void *)table->CmdWriteTimestamp;
if (!strcmp(name, "CmdCopyQueryPoolResults"))
return (void *)table->CmdCopyQueryPoolResults;
if (!strcmp(name, "CmdPushConstants"))
return (void *)table->CmdPushConstants;
if (!strcmp(name, "CmdBeginRenderPass"))
return (void *)table->CmdBeginRenderPass;
if (!strcmp(name, "CmdNextSubpass"))
return (void *)table->CmdNextSubpass;
if (!strcmp(name, "CmdEndRenderPass"))
return (void *)table->CmdEndRenderPass;
if (!strcmp(name, "CmdExecuteCommands"))
return (void *)table->CmdExecuteCommands;
return NULL;
}
static inline void
loader_init_instance_core_dispatch_table(VkLayerInstanceDispatchTable *table,
PFN_vkGetInstanceProcAddr gpa,
VkInstance inst) {
table->GetInstanceProcAddr =
(PFN_vkGetInstanceProcAddr)gpa(inst, "vkGetInstanceProcAddr");
table->DestroyInstance =
(PFN_vkDestroyInstance)gpa(inst, "vkDestroyInstance");
table->EnumeratePhysicalDevices =
(PFN_vkEnumeratePhysicalDevices)gpa(inst, "vkEnumeratePhysicalDevices");
table->GetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures)gpa(
inst, "vkGetPhysicalDeviceFeatures");
table->GetPhysicalDeviceImageFormatProperties =
(PFN_vkGetPhysicalDeviceImageFormatProperties)gpa(
inst, "vkGetPhysicalDeviceImageFormatProperties");
table->GetPhysicalDeviceFormatProperties =
(PFN_vkGetPhysicalDeviceFormatProperties)gpa(
inst, "vkGetPhysicalDeviceFormatProperties");
table->GetPhysicalDeviceSparseImageFormatProperties =
(PFN_vkGetPhysicalDeviceSparseImageFormatProperties)gpa(
inst, "vkGetPhysicalDeviceSparseImageFormatProperties");
table->GetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties)gpa(
inst, "vkGetPhysicalDeviceProperties");
table->GetPhysicalDeviceQueueFamilyProperties =
(PFN_vkGetPhysicalDeviceQueueFamilyProperties)gpa(
inst, "vkGetPhysicalDeviceQueueFamilyProperties");
table->GetPhysicalDeviceMemoryProperties =
(PFN_vkGetPhysicalDeviceMemoryProperties)gpa(
inst, "vkGetPhysicalDeviceMemoryProperties");
table->EnumerateDeviceExtensionProperties =
(PFN_vkEnumerateDeviceExtensionProperties)gpa(
inst, "vkEnumerateDeviceExtensionProperties");
table->EnumerateDeviceLayerProperties =
(PFN_vkEnumerateDeviceLayerProperties)gpa(
inst, "vkEnumerateDeviceLayerProperties");
}
static inline void loader_init_instance_extension_dispatch_table(
VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa,
VkInstance inst) {
table->DestroySurfaceKHR =
(PFN_vkDestroySurfaceKHR)gpa(inst, "vkDestroySurfaceKHR");
table->CreateDebugReportCallbackEXT =
(PFN_vkCreateDebugReportCallbackEXT)gpa(
inst, "vkCreateDebugReportCallbackEXT");
table->DestroyDebugReportCallbackEXT =
(PFN_vkDestroyDebugReportCallbackEXT)gpa(
inst, "vkDestroyDebugReportCallbackEXT");
table->DebugReportMessageEXT =
(PFN_vkDebugReportMessageEXT)gpa(inst, "vkDebugReportMessageEXT");
table->GetPhysicalDeviceSurfaceSupportKHR =
(PFN_vkGetPhysicalDeviceSurfaceSupportKHR)gpa(
inst, "vkGetPhysicalDeviceSurfaceSupportKHR");
table->GetPhysicalDeviceSurfaceCapabilitiesKHR =
(PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)gpa(
inst, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
table->GetPhysicalDeviceSurfaceFormatsKHR =
(PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)gpa(
inst, "vkGetPhysicalDeviceSurfaceFormatsKHR");
table->GetPhysicalDeviceSurfacePresentModesKHR =
(PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)gpa(
inst, "vkGetPhysicalDeviceSurfacePresentModesKHR");
#ifdef VK_USE_PLATFORM_MIR_KHR
table->CreateMirSurfaceKHR =
(PFN_vkCreateMirSurfaceKHR)gpa(inst, "vkCreateMirSurfaceKHR");
table->GetPhysicalDeviceMirPresentationSupportKHR =
(PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)gpa(
inst, "vkGetPhysicalDeviceMirPresentationSupportKHR");
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
table->CreateWaylandSurfaceKHR =
(PFN_vkCreateWaylandSurfaceKHR)gpa(inst, "vkCreateWaylandSurfaceKHR");
table->GetPhysicalDeviceWaylandPresentationSupportKHR =
(PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)gpa(
inst, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
#endif
#ifdef VK_USE_PLATFORM_WIN32_KHR
table->CreateWin32SurfaceKHR =
(PFN_vkCreateWin32SurfaceKHR)gpa(inst, "vkCreateWin32SurfaceKHR");
table->GetPhysicalDeviceWin32PresentationSupportKHR =
(PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)gpa(
inst, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
table->CreateXcbSurfaceKHR =
(PFN_vkCreateXcbSurfaceKHR)gpa(inst, "vkCreateXcbSurfaceKHR");
table->GetPhysicalDeviceXcbPresentationSupportKHR =
(PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)gpa(
inst, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR
table->CreateXlibSurfaceKHR =
(PFN_vkCreateXlibSurfaceKHR)gpa(inst, "vkCreateXlibSurfaceKHR");
table->GetPhysicalDeviceXlibPresentationSupportKHR =
(PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)gpa(
inst, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
#endif
}
static inline void *
loader_lookup_instance_dispatch_table(const VkLayerInstanceDispatchTable *table,
const char *name) {
if (!name || name[0] != 'v' || name[1] != 'k')
return NULL;
name += 2;
if (!strcmp(name, "DestroyInstance"))
return (void *)table->DestroyInstance;
if (!strcmp(name, "EnumeratePhysicalDevices"))
return (void *)table->EnumeratePhysicalDevices;
if (!strcmp(name, "GetPhysicalDeviceFeatures"))
return (void *)table->GetPhysicalDeviceFeatures;
if (!strcmp(name, "GetPhysicalDeviceImageFormatProperties"))
return (void *)table->GetPhysicalDeviceImageFormatProperties;
if (!strcmp(name, "GetPhysicalDeviceFormatProperties"))
return (void *)table->GetPhysicalDeviceFormatProperties;
if (!strcmp(name, "GetPhysicalDeviceSparseImageFormatProperties"))
return (void *)table->GetPhysicalDeviceSparseImageFormatProperties;
if (!strcmp(name, "GetPhysicalDeviceProperties"))
return (void *)table->GetPhysicalDeviceProperties;
if (!strcmp(name, "GetPhysicalDeviceQueueFamilyProperties"))
return (void *)table->GetPhysicalDeviceQueueFamilyProperties;
if (!strcmp(name, "GetPhysicalDeviceMemoryProperties"))
return (void *)table->GetPhysicalDeviceMemoryProperties;
if (!strcmp(name, "GetInstanceProcAddr"))
return (void *)table->GetInstanceProcAddr;
if (!strcmp(name, "EnumerateDeviceExtensionProperties"))
return (void *)table->EnumerateDeviceExtensionProperties;
if (!strcmp(name, "EnumerateDeviceLayerProperties"))
return (void *)table->EnumerateDeviceLayerProperties;
if (!strcmp(name, "DestroySurfaceKHR"))
return (void *)table->DestroySurfaceKHR;
if (!strcmp(name, "GetPhysicalDeviceSurfaceSupportKHR"))
return (void *)table->GetPhysicalDeviceSurfaceSupportKHR;
if (!strcmp(name, "GetPhysicalDeviceSurfaceCapabilitiesKHR"))
return (void *)table->GetPhysicalDeviceSurfaceCapabilitiesKHR;
if (!strcmp(name, "GetPhysicalDeviceSurfaceFormatsKHR"))
return (void *)table->GetPhysicalDeviceSurfaceFormatsKHR;
if (!strcmp(name, "GetPhysicalDeviceSurfacePresentModesKHR"))
return (void *)table->GetPhysicalDeviceSurfacePresentModesKHR;
#ifdef VK_USE_PLATFORM_MIR_KHR
if (!strcmp(name, "CreateMirSurfaceKHR"))
return (void *)table->CreateMirSurfaceKHR;
if (!strcmp(name, "GetPhysicalDeviceMirPresentationSupportKHR"))
return (void *)table->GetPhysicalDeviceMirPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
if (!strcmp(name, "CreateWaylandSurfaceKHR"))
return (void *)table->CreateWaylandSurfaceKHR;
if (!strcmp(name, "GetPhysicalDeviceWaylandPresentationSupportKHR"))
return (void *)table->GetPhysicalDeviceWaylandPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_WIN32_KHR
if (!strcmp(name, "CreateWin32SurfaceKHR"))
return (void *)table->CreateWin32SurfaceKHR;
if (!strcmp(name, "GetPhysicalDeviceWin32PresentationSupportKHR"))
return (void *)table->GetPhysicalDeviceWin32PresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
if (!strcmp(name, "CreateXcbSurfaceKHR"))
return (void *)table->CreateXcbSurfaceKHR;
if (!strcmp(name, "GetPhysicalDeviceXcbPresentationSupportKHR"))
return (void *)table->GetPhysicalDeviceXcbPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR
if (!strcmp(name, "CreateXlibSurfaceKHR"))
return (void *)table->CreateXlibSurfaceKHR;
if (!strcmp(name, "GetPhysicalDeviceXlibPresentationSupportKHR"))
return (void *)table->GetPhysicalDeviceXlibPresentationSupportKHR;
#endif
if (!strcmp(name, "CreateDebugReportCallbackEXT"))
return (void *)table->CreateDebugReportCallbackEXT;
if (!strcmp(name, "DestroyDebugReportCallbackEXT"))
return (void *)table->DestroyDebugReportCallbackEXT;
if (!strcmp(name, "DebugReportMessageEXT"))
return (void *)table->DebugReportMessageEXT;
return NULL;
}

1731
third_party/vulkan/loader/trampoline.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,449 @@
/*
*
* Copyright (c) 2015-2016 The Khronos Group Inc.
* Copyright (c) 2015-2016 Valve Corporation
* Copyright (c) 2015-2016 LunarG, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and/or associated documentation files (the "Materials"), to
* deal in the Materials without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Materials, and to permit persons to whom the Materials are
* furnished to do so, subject to the following conditions:
*
* The above copyright notice(s) and this permission notice shall be included in
* all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
* USE OR OTHER DEALINGS IN THE MATERIALS.
*
* Author: Ian Elliot <ian@lunarg.com>
* Author: Jon Ashburn <jon@lunarg.com>
*
*/
#pragma once
#if defined(_WIN32)
// WinSock2.h must be included *BEFORE* windows.h
#include <WinSock2.h>
#endif // _WIN32
#include "vulkan/vk_platform.h"
#include "vulkan/vk_sdk_platform.h"
#if defined(__linux__)
/* Linux-specific common code: */
// Headers:
//#define _GNU_SOURCE 1
// TBD: Are the contents of the following file used?
#include <unistd.h>
// Note: The following file is for dynamic loading:
#include <dlfcn.h>
#include <pthread.h>
#include <assert.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <libgen.h>
// VK Library Filenames, Paths, etc.:
#define PATH_SEPERATOR ':'
#define DIRECTORY_SYMBOL '/'
#define VULKAN_ICDCONF_DIR \
"/" \
"vulkan" \
"/" \
"icd.d"
#define VULKAN_ICD_DIR \
"/" \
"vulkan" \
"/" \
"icd"
#define VULKAN_ELAYERCONF_DIR \
"/" \
"vulkan" \
"/" \
"explicit_layer.d"
#define VULKAN_ILAYERCONF_DIR \
"/" \
"vulkan" \
"/" \
"implicit_layer.d"
#define VULKAN_LAYER_DIR \
"/" \
"vulkan" \
"/" \
"layer"
#if defined(LOCALPREFIX)
#define LOCAL_DRIVERS_INFO \
LOCALPREFIX "/" SYSCONFDIR VULKAN_ICDCONF_DIR ":" LOCALPREFIX \
"/" DATADIR VULKAN_ICDCONF_DIR ":"
#define LOCAL_ELAYERS_INFO \
LOCALPREFIX "/" SYSCONFDIR VULKAN_ELAYERCONF_DIR ":" LOCALPREFIX \
"/" DATADIR VULKAN_ELAYERCONF_DIR ":"
#define LOCAL_ILAYERS_INFO \
LOCALPREFIX "/" SYSCONFDIR VULKAN_ILAYERCONF_DIR ":" LOCALPREFIX \
"/" DATADIR VULKAN_ILAYERCONF_DIR ":"
#else
#define LOCAL_DRIVERS_INFO
#define LOCAL_ELAYERS_INFO
#define LOCAL_ILAYERS_INFO
#endif
#define DEFAULT_VK_DRIVERS_INFO \
LOCAL_DRIVERS_INFO \
"/" SYSCONFDIR VULKAN_ICDCONF_DIR ":" \
"/usr/" DATADIR VULKAN_ICDCONF_DIR
#define DEFAULT_VK_DRIVERS_PATH ""
#define DEFAULT_VK_ELAYERS_INFO \
LOCAL_ELAYERS_INFO \
"/" SYSCONFDIR VULKAN_ELAYERCONF_DIR ":" \
"/usr/" DATADIR VULKAN_ELAYERCONF_DIR ":"
#define DEFAULT_VK_ILAYERS_INFO \
LOCAL_ILAYERS_INFO \
"/" SYSCONFDIR VULKAN_ILAYERCONF_DIR ":" \
"/usr/" DATADIR VULKAN_ILAYERCONF_DIR
#define DEFAULT_VK_LAYERS_PATH ""
#define LAYERS_PATH_ENV "VK_LAYER_PATH"
// C99:
#define PRINTF_SIZE_T_SPECIFIER "%zu"
// File IO
static inline bool loader_platform_file_exists(const char *path) {
if (access(path, F_OK))
return false;
else
return true;
}
static inline bool loader_platform_is_path_absolute(const char *path) {
if (path[0] == '/')
return true;
else
return false;
}
static inline char *loader_platform_dirname(char *path) {
return dirname(path);
}
// Environment variables
static inline char *loader_getenv(const char *name) { return getenv(name); }
static inline void loader_free_getenv(const char *val) {}
// Dynamic Loading of libraries:
typedef void *loader_platform_dl_handle;
static inline loader_platform_dl_handle
loader_platform_open_library(const char *libPath) {
return dlopen(libPath, RTLD_LAZY | RTLD_LOCAL);
}
static inline const char *
loader_platform_open_library_error(const char *libPath) {
return dlerror();
}
static inline void
loader_platform_close_library(loader_platform_dl_handle library) {
dlclose(library);
}
static inline void *
loader_platform_get_proc_address(loader_platform_dl_handle library,
const char *name) {
assert(library);
assert(name);
return dlsym(library, name);
}
static inline const char *
loader_platform_get_proc_address_error(const char *name) {
return dlerror();
}
// Threads:
typedef pthread_t loader_platform_thread;
#define THREAD_LOCAL_DECL __thread
#define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var) \
pthread_once_t var = PTHREAD_ONCE_INIT;
#define LOADER_PLATFORM_THREAD_ONCE_DEFINITION(var) pthread_once_t var;
static inline void loader_platform_thread_once(pthread_once_t *ctl,
void (*func)(void)) {
assert(func != NULL);
assert(ctl != NULL);
pthread_once(ctl, func);
}
// Thread IDs:
typedef pthread_t loader_platform_thread_id;
static inline loader_platform_thread_id loader_platform_get_thread_id() {
return pthread_self();
}
// Thread mutex:
typedef pthread_mutex_t loader_platform_thread_mutex;
static inline void
loader_platform_thread_create_mutex(loader_platform_thread_mutex *pMutex) {
pthread_mutex_init(pMutex, NULL);
}
static inline void
loader_platform_thread_lock_mutex(loader_platform_thread_mutex *pMutex) {
pthread_mutex_lock(pMutex);
}
static inline void
loader_platform_thread_unlock_mutex(loader_platform_thread_mutex *pMutex) {
pthread_mutex_unlock(pMutex);
}
static inline void
loader_platform_thread_delete_mutex(loader_platform_thread_mutex *pMutex) {
pthread_mutex_destroy(pMutex);
}
typedef pthread_cond_t loader_platform_thread_cond;
static inline void
loader_platform_thread_init_cond(loader_platform_thread_cond *pCond) {
pthread_cond_init(pCond, NULL);
}
static inline void
loader_platform_thread_cond_wait(loader_platform_thread_cond *pCond,
loader_platform_thread_mutex *pMutex) {
pthread_cond_wait(pCond, pMutex);
}
static inline void
loader_platform_thread_cond_broadcast(loader_platform_thread_cond *pCond) {
pthread_cond_broadcast(pCond);
}
#define loader_stack_alloc(size) alloca(size)
#elif defined(_WIN32) // defined(__linux__)
/* Windows-specific common code: */
// WinBase.h defines CreateSemaphore and synchapi.h defines CreateEvent
// undefine them to avoid conflicts with VkLayerDispatchTable struct members.
#ifdef CreateSemaphore
#undef CreateSemaphore
#endif
#ifdef CreateEvent
#undef CreateEvent
#endif
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <io.h>
#include <stdbool.h>
#include <shlwapi.h>
#ifdef __cplusplus
#include <iostream>
#include <string>
using namespace std;
#endif // __cplusplus
// VK Library Filenames, Paths, etc.:
#define PATH_SEPERATOR ';'
#define DIRECTORY_SYMBOL '\\'
#define DEFAULT_VK_REGISTRY_HIVE HKEY_LOCAL_MACHINE
#define DEFAULT_VK_DRIVERS_INFO "SOFTWARE\\Khronos\\Vulkan\\Drivers"
// TODO: Are these the correct paths
#define DEFAULT_VK_DRIVERS_PATH "C:\\Windows\\System32;C:\\Windows\\SysWow64"
#define DEFAULT_VK_ELAYERS_INFO "SOFTWARE\\Khronos\\Vulkan\\ExplicitLayers"
#define DEFAULT_VK_ILAYERS_INFO "SOFTWARE\\Khronos\\Vulkan\\ImplicitLayers"
#define DEFAULT_VK_LAYERS_PATH "C:\\Windows\\System32;C:\\Windows\\SysWow64"
#define LAYERS_PATH_ENV "VK_LAYER_PATH"
#define PRINTF_SIZE_T_SPECIFIER "%Iu"
// File IO
static bool loader_platform_file_exists(const char *path) {
if ((_access(path, 0)) == -1)
return false;
else
return true;
}
static bool loader_platform_is_path_absolute(const char *path) {
return !PathIsRelative(path);
}
// WIN32 runtime doesn't have dirname().
static inline char *loader_platform_dirname(char *path) {
char *current, *next;
// TODO/TBD: Do we need to deal with the Windows's ":" character?
for (current = path; *current != '\0'; current = next) {
next = strchr(current, DIRECTORY_SYMBOL);
if (next == NULL) {
if (current != path)
*(current - 1) = '\0';
return path;
} else {
// Point one character past the DIRECTORY_SYMBOL:
next++;
}
}
return path;
}
// WIN32 runtime doesn't have basename().
// Microsoft also doesn't have basename(). Paths are different on Windows, and
// so this is just a temporary solution in order to get us compiling, so that we
// can test some scenarios, and develop the correct solution for Windows.
// TODO: Develop a better, permanent solution for Windows, to replace this
// temporary code:
static char *loader_platform_basename(char *pathname) {
char *current, *next;
// TODO/TBD: Do we need to deal with the Windows's ":" character?
for (current = pathname; *current != '\0'; current = next) {
next = strchr(current, DIRECTORY_SYMBOL);
if (next == NULL) {
// No more DIRECTORY_SYMBOL's so return p:
return current;
} else {
// Point one character past the DIRECTORY_SYMBOL:
next++;
}
}
// We shouldn't get to here, but this makes the compiler happy:
return current;
}
// Environment variables
static inline char *loader_getenv(const char *name) {
char *retVal;
DWORD valSize;
valSize = GetEnvironmentVariableA(name, NULL, 0);
// valSize DOES include the null terminator, so for any set variable
// will always be at least 1. If it's 0, the variable wasn't set.
if (valSize == 0)
return NULL;
// TODO; FIXME This should be using any app defined memory allocation
retVal = (char *)malloc(valSize);
GetEnvironmentVariableA(name, retVal, valSize);
return retVal;
}
static inline void loader_free_getenv(const char *val) { free((void *)val); }
// Dynamic Loading:
typedef HMODULE loader_platform_dl_handle;
static loader_platform_dl_handle
loader_platform_open_library(const char *libPath) {
return LoadLibrary(libPath);
}
static char *loader_platform_open_library_error(const char *libPath) {
static char errorMsg[120];
snprintf(errorMsg, 119, "Failed to open dynamic library \"%s\"", libPath);
return errorMsg;
}
static void loader_platform_close_library(loader_platform_dl_handle library) {
FreeLibrary(library);
}
static void *loader_platform_get_proc_address(loader_platform_dl_handle library,
const char *name) {
assert(library);
assert(name);
return GetProcAddress(library, name);
}
static char *loader_platform_get_proc_address_error(const char *name) {
static char errorMsg[120];
snprintf(errorMsg, 119, "Failed to find function \"%s\" in dynamic library",
name);
return errorMsg;
}
// Threads:
typedef HANDLE loader_platform_thread;
#define THREAD_LOCAL_DECL __declspec(thread)
#define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var) \
INIT_ONCE var = INIT_ONCE_STATIC_INIT;
#define LOADER_PLATFORM_THREAD_ONCE_DEFINITION(var) INIT_ONCE var;
static BOOL CALLBACK
InitFuncWrapper(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) {
void (*func)(void) = (void (*)(void))Parameter;
func();
return TRUE;
}
static void loader_platform_thread_once(void *ctl, void (*func)(void)) {
assert(func != NULL);
assert(ctl != NULL);
InitOnceExecuteOnce((PINIT_ONCE)ctl, InitFuncWrapper, func, NULL);
}
// Thread IDs:
typedef DWORD loader_platform_thread_id;
static loader_platform_thread_id loader_platform_get_thread_id() {
return GetCurrentThreadId();
}
// Thread mutex:
typedef CRITICAL_SECTION loader_platform_thread_mutex;
static void
loader_platform_thread_create_mutex(loader_platform_thread_mutex *pMutex) {
InitializeCriticalSection(pMutex);
}
static void
loader_platform_thread_lock_mutex(loader_platform_thread_mutex *pMutex) {
EnterCriticalSection(pMutex);
}
static void
loader_platform_thread_unlock_mutex(loader_platform_thread_mutex *pMutex) {
LeaveCriticalSection(pMutex);
}
static void
loader_platform_thread_delete_mutex(loader_platform_thread_mutex *pMutex) {
DeleteCriticalSection(pMutex);
}
typedef CONDITION_VARIABLE loader_platform_thread_cond;
static void
loader_platform_thread_init_cond(loader_platform_thread_cond *pCond) {
InitializeConditionVariable(pCond);
}
static void
loader_platform_thread_cond_wait(loader_platform_thread_cond *pCond,
loader_platform_thread_mutex *pMutex) {
SleepConditionVariableCS(pCond, pMutex, INFINITE);
}
static void
loader_platform_thread_cond_broadcast(loader_platform_thread_cond *pCond) {
WakeAllConditionVariable(pCond);
}
// Windows Registry:
char *loader_get_registry_string(const HKEY hive, const LPCTSTR sub_key,
const char *value);
#define loader_stack_alloc(size) _alloca(size)
#else // defined(_WIN32)
#error The "loader_platform.h" file must be modified for this OS.
// NOTE: In order to support another OS, an #elif needs to be added (above the
// "#else // defined(_WIN32)") for that OS, and OS-specific versions of the
// contents of this file must be created.
// NOTE: Other OS-specific changes are also needed for this OS. Search for
// files with "WIN32" in it, as a quick way to find files that must be changed.
#endif // defined(_WIN32)
// returns true if the given string appears to be a relative or absolute
// path, as opposed to a bare filename.
static inline bool loader_platform_is_path(const char *path) {
return strchr(path, DIRECTORY_SYMBOL) != NULL;
}

1092
third_party/vulkan/loader/wsi.c vendored Normal file

File diff suppressed because it is too large Load Diff

120
third_party/vulkan/loader/wsi.h vendored Normal file
View File

@ -0,0 +1,120 @@
/*
* Copyright (c) 2015-2016 The Khronos Group Inc.
* Copyright (c) 2015-2016 Valve Corporation
* Copyright (c) 2015-2016 LunarG, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and/or associated documentation files (the "Materials"), to
* deal in the Materials without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Materials, and to permit persons to whom the Materials are
* furnished to do so, subject to the following conditions:
*
* The above copyright notice(s) and this permission notice shall be included in
* all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
* USE OR OTHER DEALINGS IN THE MATERIALS.
*
* Author: Ian Elliott <ian@lunarg.com>
*
*/
#include "vk_loader_platform.h"
#include "loader.h"
bool wsi_swapchain_instance_gpa(struct loader_instance *ptr_instance,
const char *name, void **addr);
void wsi_add_instance_extensions(const struct loader_instance *inst,
struct loader_extension_list *ext_list);
void wsi_create_instance(struct loader_instance *ptr_instance,
const VkInstanceCreateInfo *pCreateInfo);
VKAPI_ATTR void VKAPI_CALL
loader_DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
const VkAllocationCallbacks *pAllocator);
VKAPI_ATTR VkResult VKAPI_CALL
loader_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
VkSurfaceKHR surface,
VkBool32 *pSupported);
VKAPI_ATTR VkResult VKAPI_CALL loader_GetPhysicalDeviceSurfaceCapabilitiesKHR(
VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
VkSurfaceCapabilitiesKHR *pSurfaceCapabilities);
VKAPI_ATTR VkResult VKAPI_CALL
loader_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice,
VkSurfaceKHR surface,
uint32_t *pSurfaceFormatCount,
VkSurfaceFormatKHR *pSurfaceFormats);
VKAPI_ATTR VkResult VKAPI_CALL
loader_GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,
VkSurfaceKHR surface,
uint32_t *pPresentModeCount,
VkPresentModeKHR *pPresentModes);
#ifdef VK_USE_PLATFORM_WIN32_KHR
VKAPI_ATTR VkResult VKAPI_CALL
loader_CreateWin32SurfaceKHR(VkInstance instance,
const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkSurfaceKHR *pSurface);
VKAPI_ATTR VkBool32 VKAPI_CALL
loader_GetPhysicalDeviceWin32PresentationSupportKHR(
VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex);
#endif
#ifdef VK_USE_PLATFORM_MIR_KHR
VKAPI_ATTR VkResult VKAPI_CALL
loader_CreateMirSurfaceKHR(VkInstance instance,
const VkMirSurfaceCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkSurfaceKHR *pSurface);
VKAPI_ATTR VkBool32 VKAPI_CALL
loader_GetPhysicalDeviceMirPresentationSupportKHR(
VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex,
MirConnection *connection);
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
VKAPI_ATTR VkResult VKAPI_CALL
loader_CreateWaylandSurfaceKHR(VkInstance instance,
const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkSurfaceKHR *pSurface);
VKAPI_ATTR VkBool32 VKAPI_CALL
loader_GetPhysicalDeviceWaylandPresentationSupportKHR(
VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex,
struct wl_display *display);
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
VKAPI_ATTR VkResult VKAPI_CALL
loader_CreateXcbSurfaceKHR(VkInstance instance,
const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkSurfaceKHR *pSurface);
VKAPI_ATTR VkBool32 VKAPI_CALL
loader_GetPhysicalDeviceXcbPresentationSupportKHR(
VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex,
xcb_connection_t *connection, xcb_visualid_t visual_id);
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR
VKAPI_ATTR VkResult VKAPI_CALL
loader_CreateXlibSurfaceKHR(VkInstance instance,
const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkSurfaceKHR *pSurface);
VKAPI_ATTR VkBool32 VKAPI_CALL
loader_GetPhysicalDeviceXlibPresentationSupportKHR(
VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display *dpy,
VisualID visualID);
#endif

View File

@ -0,0 +1,44 @@
//
// File: vk_debug_marker_layer.h
//
/*
* Copyright (c) 2015-2016 The Khronos Group Inc.
* Copyright (c) 2015-2016 Valve Corporation
* Copyright (c) 2015-2016 LunarG, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and/or associated documentation files (the "Materials"), to
* deal in the Materials without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Materials, and to permit persons to whom the Materials are
* furnished to do so, subject to the following conditions:
*
* The above copyright notice(s) and this permission notice shall be included in
* all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
* USE OR OTHER DEALINGS IN THE MATERIALS.
*
* Authors:
* Jon Ashburn <jon@lunarg.com>
* Courtney Goeltzenleuchter <courtney@lunarg.com>
*/
#pragma once
#include "vulkan.h"
#include "vk_lunarg_debug_marker.h"
#include "vk_layer.h"
typedef struct VkLayerDebugMarkerDispatchTable_ {
PFN_vkCmdDbgMarkerBegin CmdDbgMarkerBegin;
PFN_vkCmdDbgMarkerEnd CmdDbgMarkerEnd;
PFN_vkDbgSetObjectTag DbgSetObjectTag;
PFN_vkDbgSetObjectName DbgSetObjectName;
} VkLayerDebugMarkerDispatchTable;

114
third_party/vulkan/vk_icd.h vendored Normal file
View File

@ -0,0 +1,114 @@
//
// File: vk_icd.h
//
/*
* Copyright (c) 2015-2016 The Khronos Group Inc.
* Copyright (c) 2015-2016 Valve Corporation
* Copyright (c) 2015-2016 LunarG, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and/or associated documentation files (the "Materials"), to
* deal in the Materials without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Materials, and to permit persons to whom the Materials are
* furnished to do so, subject to the following conditions:
*
* The above copyright notice(s) and this permission notice shall be included in
* all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
* USE OR OTHER DEALINGS IN THE MATERIALS.
*
*/
#ifndef VKICD_H
#define VKICD_H
#include "vk_platform.h"
/*
* The ICD must reserve space for a pointer for the loader's dispatch
* table, at the start of <each object>.
* The ICD must initialize this variable using the SET_LOADER_MAGIC_VALUE macro.
*/
#define ICD_LOADER_MAGIC 0x01CDC0DE
typedef union _VK_LOADER_DATA {
uintptr_t loaderMagic;
void *loaderData;
} VK_LOADER_DATA;
static inline void set_loader_magic_value(void *pNewObject) {
VK_LOADER_DATA *loader_info = (VK_LOADER_DATA *)pNewObject;
loader_info->loaderMagic = ICD_LOADER_MAGIC;
}
static inline bool valid_loader_magic_value(void *pNewObject) {
const VK_LOADER_DATA *loader_info = (VK_LOADER_DATA *)pNewObject;
return (loader_info->loaderMagic & 0xffffffff) == ICD_LOADER_MAGIC;
}
/*
* Windows and Linux ICDs will treat VkSurfaceKHR as a pointer to a struct that
* contains the platform-specific connection and surface information.
*/
typedef enum _VkIcdWsiPlatform {
VK_ICD_WSI_PLATFORM_MIR,
VK_ICD_WSI_PLATFORM_WAYLAND,
VK_ICD_WSI_PLATFORM_WIN32,
VK_ICD_WSI_PLATFORM_XCB,
VK_ICD_WSI_PLATFORM_XLIB,
} VkIcdWsiPlatform;
typedef struct _VkIcdSurfaceBase {
VkIcdWsiPlatform platform;
} VkIcdSurfaceBase;
#ifdef VK_USE_PLATFORM_MIR_KHR
typedef struct _VkIcdSurfaceMir {
VkIcdSurfaceBase base;
MirConnection *connection;
MirSurface *mirSurface;
} VkIcdSurfaceMir;
#endif // VK_USE_PLATFORM_MIR_KHR
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
typedef struct _VkIcdSurfaceWayland {
VkIcdSurfaceBase base;
struct wl_display *display;
struct wl_surface *surface;
} VkIcdSurfaceWayland;
#endif // VK_USE_PLATFORM_WAYLAND_KHR
#ifdef VK_USE_PLATFORM_WIN32_KHR
typedef struct _VkIcdSurfaceWin32 {
VkIcdSurfaceBase base;
HINSTANCE hinstance;
HWND hwnd;
} VkIcdSurfaceWin32;
#endif // VK_USE_PLATFORM_WIN32_KHR
#ifdef VK_USE_PLATFORM_XCB_KHR
typedef struct _VkIcdSurfaceXcb {
VkIcdSurfaceBase base;
xcb_connection_t *connection;
xcb_window_t window;
} VkIcdSurfaceXcb;
#endif // VK_USE_PLATFORM_XCB_KHR
#ifdef VK_USE_PLATFORM_XLIB_KHR
typedef struct _VkIcdSurfaceXlib {
VkIcdSurfaceBase base;
Display *dpy;
Window window;
} VkIcdSurfaceXlib;
#endif // VK_USE_PLATFORM_XLIB_KHR
#endif // VKICD_H

313
third_party/vulkan/vk_layer.h vendored Normal file
View File

@ -0,0 +1,313 @@
//
// File: vk_layer.h
//
/*
* Copyright (c) 2015-2016 The Khronos Group Inc.
* Copyright (c) 2015-2016 Valve Corporation
* Copyright (c) 2015-2016 LunarG, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and/or associated documentation files (the "Materials"), to
* deal in the Materials without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Materials, and to permit persons to whom the Materials are
* furnished to do so, subject to the following conditions:
*
* The above copyright notice(s) and this permission notice shall be included in
* all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
* USE OR OTHER DEALINGS IN THE MATERIALS.
*
*/
/* Need to define dispatch table
* Core struct can then have ptr to dispatch table at the top
* Along with object ptrs for current and next OBJ
*/
#pragma once
#include "vulkan.h"
#include "vk_lunarg_debug_marker.h"
#if defined(__GNUC__) && __GNUC__ >= 4
#define VK_LAYER_EXPORT __attribute__((visibility("default")))
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)
#define VK_LAYER_EXPORT __attribute__((visibility("default")))
#else
#define VK_LAYER_EXPORT
#endif
typedef struct VkLayerDispatchTable_ {
PFN_vkGetDeviceProcAddr GetDeviceProcAddr;
PFN_vkDestroyDevice DestroyDevice;
PFN_vkGetDeviceQueue GetDeviceQueue;
PFN_vkQueueSubmit QueueSubmit;
PFN_vkQueueWaitIdle QueueWaitIdle;
PFN_vkDeviceWaitIdle DeviceWaitIdle;
PFN_vkAllocateMemory AllocateMemory;
PFN_vkFreeMemory FreeMemory;
PFN_vkMapMemory MapMemory;
PFN_vkUnmapMemory UnmapMemory;
PFN_vkFlushMappedMemoryRanges FlushMappedMemoryRanges;
PFN_vkInvalidateMappedMemoryRanges InvalidateMappedMemoryRanges;
PFN_vkGetDeviceMemoryCommitment GetDeviceMemoryCommitment;
PFN_vkGetImageSparseMemoryRequirements GetImageSparseMemoryRequirements;
PFN_vkGetImageMemoryRequirements GetImageMemoryRequirements;
PFN_vkGetBufferMemoryRequirements GetBufferMemoryRequirements;
PFN_vkBindImageMemory BindImageMemory;
PFN_vkBindBufferMemory BindBufferMemory;
PFN_vkQueueBindSparse QueueBindSparse;
PFN_vkCreateFence CreateFence;
PFN_vkDestroyFence DestroyFence;
PFN_vkGetFenceStatus GetFenceStatus;
PFN_vkResetFences ResetFences;
PFN_vkWaitForFences WaitForFences;
PFN_vkCreateSemaphore CreateSemaphore;
PFN_vkDestroySemaphore DestroySemaphore;
PFN_vkCreateEvent CreateEvent;
PFN_vkDestroyEvent DestroyEvent;
PFN_vkGetEventStatus GetEventStatus;
PFN_vkSetEvent SetEvent;
PFN_vkResetEvent ResetEvent;
PFN_vkCreateQueryPool CreateQueryPool;
PFN_vkDestroyQueryPool DestroyQueryPool;
PFN_vkGetQueryPoolResults GetQueryPoolResults;
PFN_vkCreateBuffer CreateBuffer;
PFN_vkDestroyBuffer DestroyBuffer;
PFN_vkCreateBufferView CreateBufferView;
PFN_vkDestroyBufferView DestroyBufferView;
PFN_vkCreateImage CreateImage;
PFN_vkDestroyImage DestroyImage;
PFN_vkGetImageSubresourceLayout GetImageSubresourceLayout;
PFN_vkCreateImageView CreateImageView;
PFN_vkDestroyImageView DestroyImageView;
PFN_vkCreateShaderModule CreateShaderModule;
PFN_vkDestroyShaderModule DestroyShaderModule;
PFN_vkCreatePipelineCache CreatePipelineCache;
PFN_vkDestroyPipelineCache DestroyPipelineCache;
PFN_vkGetPipelineCacheData GetPipelineCacheData;
PFN_vkMergePipelineCaches MergePipelineCaches;
PFN_vkCreateGraphicsPipelines CreateGraphicsPipelines;
PFN_vkCreateComputePipelines CreateComputePipelines;
PFN_vkDestroyPipeline DestroyPipeline;
PFN_vkCreatePipelineLayout CreatePipelineLayout;
PFN_vkDestroyPipelineLayout DestroyPipelineLayout;
PFN_vkCreateSampler CreateSampler;
PFN_vkDestroySampler DestroySampler;
PFN_vkCreateDescriptorSetLayout CreateDescriptorSetLayout;
PFN_vkDestroyDescriptorSetLayout DestroyDescriptorSetLayout;
PFN_vkCreateDescriptorPool CreateDescriptorPool;
PFN_vkDestroyDescriptorPool DestroyDescriptorPool;
PFN_vkResetDescriptorPool ResetDescriptorPool;
PFN_vkAllocateDescriptorSets AllocateDescriptorSets;
PFN_vkFreeDescriptorSets FreeDescriptorSets;
PFN_vkUpdateDescriptorSets UpdateDescriptorSets;
PFN_vkCreateFramebuffer CreateFramebuffer;
PFN_vkDestroyFramebuffer DestroyFramebuffer;
PFN_vkCreateRenderPass CreateRenderPass;
PFN_vkDestroyRenderPass DestroyRenderPass;
PFN_vkGetRenderAreaGranularity GetRenderAreaGranularity;
PFN_vkCreateCommandPool CreateCommandPool;
PFN_vkDestroyCommandPool DestroyCommandPool;
PFN_vkResetCommandPool ResetCommandPool;
PFN_vkAllocateCommandBuffers AllocateCommandBuffers;
PFN_vkFreeCommandBuffers FreeCommandBuffers;
PFN_vkBeginCommandBuffer BeginCommandBuffer;
PFN_vkEndCommandBuffer EndCommandBuffer;
PFN_vkResetCommandBuffer ResetCommandBuffer;
PFN_vkCmdBindPipeline CmdBindPipeline;
PFN_vkCmdBindDescriptorSets CmdBindDescriptorSets;
PFN_vkCmdBindVertexBuffers CmdBindVertexBuffers;
PFN_vkCmdBindIndexBuffer CmdBindIndexBuffer;
PFN_vkCmdSetViewport CmdSetViewport;
PFN_vkCmdSetScissor CmdSetScissor;
PFN_vkCmdSetLineWidth CmdSetLineWidth;
PFN_vkCmdSetDepthBias CmdSetDepthBias;
PFN_vkCmdSetBlendConstants CmdSetBlendConstants;
PFN_vkCmdSetDepthBounds CmdSetDepthBounds;
PFN_vkCmdSetStencilCompareMask CmdSetStencilCompareMask;
PFN_vkCmdSetStencilWriteMask CmdSetStencilWriteMask;
PFN_vkCmdSetStencilReference CmdSetStencilReference;
PFN_vkCmdDraw CmdDraw;
PFN_vkCmdDrawIndexed CmdDrawIndexed;
PFN_vkCmdDrawIndirect CmdDrawIndirect;
PFN_vkCmdDrawIndexedIndirect CmdDrawIndexedIndirect;
PFN_vkCmdDispatch CmdDispatch;
PFN_vkCmdDispatchIndirect CmdDispatchIndirect;
PFN_vkCmdCopyBuffer CmdCopyBuffer;
PFN_vkCmdCopyImage CmdCopyImage;
PFN_vkCmdBlitImage CmdBlitImage;
PFN_vkCmdCopyBufferToImage CmdCopyBufferToImage;
PFN_vkCmdCopyImageToBuffer CmdCopyImageToBuffer;
PFN_vkCmdUpdateBuffer CmdUpdateBuffer;
PFN_vkCmdFillBuffer CmdFillBuffer;
PFN_vkCmdClearColorImage CmdClearColorImage;
PFN_vkCmdClearDepthStencilImage CmdClearDepthStencilImage;
PFN_vkCmdClearAttachments CmdClearAttachments;
PFN_vkCmdResolveImage CmdResolveImage;
PFN_vkCmdSetEvent CmdSetEvent;
PFN_vkCmdResetEvent CmdResetEvent;
PFN_vkCmdWaitEvents CmdWaitEvents;
PFN_vkCmdPipelineBarrier CmdPipelineBarrier;
PFN_vkCmdBeginQuery CmdBeginQuery;
PFN_vkCmdEndQuery CmdEndQuery;
PFN_vkCmdResetQueryPool CmdResetQueryPool;
PFN_vkCmdWriteTimestamp CmdWriteTimestamp;
PFN_vkCmdCopyQueryPoolResults CmdCopyQueryPoolResults;
PFN_vkCmdPushConstants CmdPushConstants;
PFN_vkCmdBeginRenderPass CmdBeginRenderPass;
PFN_vkCmdNextSubpass CmdNextSubpass;
PFN_vkCmdEndRenderPass CmdEndRenderPass;
PFN_vkCmdExecuteCommands CmdExecuteCommands;
PFN_vkCreateSwapchainKHR CreateSwapchainKHR;
PFN_vkDestroySwapchainKHR DestroySwapchainKHR;
PFN_vkGetSwapchainImagesKHR GetSwapchainImagesKHR;
PFN_vkAcquireNextImageKHR AcquireNextImageKHR;
PFN_vkQueuePresentKHR QueuePresentKHR;
} VkLayerDispatchTable;
typedef struct VkLayerInstanceDispatchTable_ {
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
PFN_vkDestroyInstance DestroyInstance;
PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices;
PFN_vkGetPhysicalDeviceFeatures GetPhysicalDeviceFeatures;
PFN_vkGetPhysicalDeviceImageFormatProperties
GetPhysicalDeviceImageFormatProperties;
PFN_vkGetPhysicalDeviceFormatProperties GetPhysicalDeviceFormatProperties;
PFN_vkGetPhysicalDeviceSparseImageFormatProperties
GetPhysicalDeviceSparseImageFormatProperties;
PFN_vkGetPhysicalDeviceProperties GetPhysicalDeviceProperties;
PFN_vkGetPhysicalDeviceQueueFamilyProperties
GetPhysicalDeviceQueueFamilyProperties;
PFN_vkGetPhysicalDeviceMemoryProperties GetPhysicalDeviceMemoryProperties;
PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties;
PFN_vkEnumerateDeviceLayerProperties EnumerateDeviceLayerProperties;
PFN_vkDestroySurfaceKHR DestroySurfaceKHR;
PFN_vkGetPhysicalDeviceSurfaceSupportKHR GetPhysicalDeviceSurfaceSupportKHR;
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR
GetPhysicalDeviceSurfaceCapabilitiesKHR;
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR GetPhysicalDeviceSurfaceFormatsKHR;
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR
GetPhysicalDeviceSurfacePresentModesKHR;
PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT;
PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT;
PFN_vkDebugReportMessageEXT DebugReportMessageEXT;
#ifdef VK_USE_PLATFORM_MIR_KHR
PFN_vkCreateMirSurfaceKHR CreateMirSurfaceKHR;
PFN_vkGetPhysicalDeviceMirPresentationSupportKHR
GetPhysicalDeviceMirPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
PFN_vkCreateWaylandSurfaceKHR CreateWaylandSurfaceKHR;
PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
GetPhysicalDeviceWaylandPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_WIN32_KHR
PFN_vkCreateWin32SurfaceKHR CreateWin32SurfaceKHR;
PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR
GetPhysicalDeviceWin32PresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
PFN_vkCreateXcbSurfaceKHR CreateXcbSurfaceKHR;
PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR
GetPhysicalDeviceXcbPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR
PFN_vkCreateXlibSurfaceKHR CreateXlibSurfaceKHR;
PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR
GetPhysicalDeviceXlibPresentationSupportKHR;
#endif
#ifdef VK_USE_PLATFORM_ANDROID_KHR
PFN_vkCreateAndroidSurfaceKHR CreateAndroidSurfaceKHR;
#endif
} VkLayerInstanceDispatchTable;
// LL node for tree of dbg callback functions
typedef struct VkLayerDbgFunctionNode_ {
VkDebugReportCallbackEXT msgCallback;
PFN_vkDebugReportCallbackEXT pfnMsgCallback;
VkFlags msgFlags;
void *pUserData;
struct VkLayerDbgFunctionNode_ *pNext;
} VkLayerDbgFunctionNode;
typedef enum VkLayerDbgAction_ {
VK_DBG_LAYER_ACTION_IGNORE = 0x0,
VK_DBG_LAYER_ACTION_CALLBACK = 0x1,
VK_DBG_LAYER_ACTION_LOG_MSG = 0x2,
VK_DBG_LAYER_ACTION_BREAK = 0x4,
VK_DBG_LAYER_ACTION_DEBUG_OUTPUT = 0x8,
} VkLayerDbgAction;
// ------------------------------------------------------------------------------------------------
// CreateInstance and CreateDevice support structures
typedef enum VkLayerFunction_ {
VK_LAYER_LINK_INFO = 0,
VK_LAYER_DEVICE_INFO = 1,
VK_LAYER_INSTANCE_INFO = 2
} VkLayerFunction;
/*
* When creating the device chain the loader needs to pass
* down information about it's device structure needed at
* the end of the chain. Passing the data via the
* VkLayerInstanceInfo avoids issues with finding the
* exact instance being used.
*/
typedef struct VkLayerInstanceInfo_ {
void *instance_info;
PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
} VkLayerInstanceInfo;
typedef struct VkLayerInstanceLink_ {
struct VkLayerInstanceLink_ *pNext;
PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
} VkLayerInstanceLink;
/*
* When creating the device chain the loader needs to pass
* down information about it's device structure needed at
* the end of the chain. Passing the data via the
* VkLayerDeviceInfo avoids issues with finding the
* exact instance being used.
*/
typedef struct VkLayerDeviceInfo_ {
void *device_info;
PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
} VkLayerDeviceInfo;
typedef struct {
VkStructureType sType; // VK_STRUCTURE_TYPE_LAYER_INSTANCE_CREATE_INFO
const void *pNext;
VkLayerFunction function;
union {
VkLayerInstanceLink *pLayerInfo;
VkLayerInstanceInfo instanceInfo;
} u;
} VkLayerInstanceCreateInfo;
typedef struct VkLayerDeviceLink_ {
struct VkLayerDeviceLink_ *pNext;
PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
PFN_vkGetDeviceProcAddr pfnNextGetDeviceProcAddr;
} VkLayerDeviceLink;
typedef struct {
VkStructureType sType; // VK_STRUCTURE_TYPE_LAYER_DEVICE_CREATE_INFO
const void *pNext;
VkLayerFunction function;
union {
VkLayerDeviceLink *pLayerInfo;
VkLayerDeviceInfo deviceInfo;
} u;
} VkLayerDeviceCreateInfo;
// ------------------------------------------------------------------------------------------------
// API functions

View File

@ -0,0 +1,98 @@
//
// File: vk_lunarg_debug_marker.h
//
/*
* Copyright (c) 2015-2016 The Khronos Group Inc.
* Copyright (c) 2015-2016 Valve Corporation
* Copyright (c) 2015-2016 LunarG, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and/or associated documentation files (the "Materials"), to
* deal in the Materials without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Materials, and to permit persons to whom the Materials are
* furnished to do so, subject to the following conditions:
*
* The above copyright notice(s) and this permission notice shall be included in
* all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
* USE OR OTHER DEALINGS IN THE MATERIALS.
*
* Authors:
* Jon Ashburn <jon@lunarg.com>
* Courtney Goeltzenleuchter <courtney@lunarg.com>
*/
#ifndef __VK_DEBUG_MARKER_H__
#define __VK_DEBUG_MARKER_H__
#include "vulkan.h"
#define VK_DEBUG_MARKER_EXTENSION_NUMBER 6
#define VK_DEBUG_MARKER_EXTENSION_REVISION 1
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
/*
***************************************************************************************************
* DebugMarker Vulkan Extension API
***************************************************************************************************
*/
#define DEBUG_MARKER_EXTENSION_NAME "VK_LUNARG_DEBUG_MARKER"
// ------------------------------------------------------------------------------------------------
// Enumerations
#define VK_DEBUG_MARKER_ENUM_EXTEND(type, id) \
((type)(VK_DEBUG_MARKER_EXTENSION_NUMBER * -1000 + (id)))
#define VK_OBJECT_INFO_TYPE_DBG_OBJECT_TAG \
VK_DEBUG_MARKER_ENUM_EXTEND(VkDbgObjectInfoType, 0)
#define VK_OBJECT_INFO_TYPE_DBG_OBJECT_NAME \
VK_DEBUG_MARKER_ENUM_EXTEND(VkDbgObjectInfoType, 1)
// ------------------------------------------------------------------------------------------------
// API functions
typedef void(VKAPI_PTR *PFN_vkCmdDbgMarkerBegin)(VkCommandBuffer commandBuffer,
const char *pMarker);
typedef void(VKAPI_PTR *PFN_vkCmdDbgMarkerEnd)(VkCommandBuffer commandBuffer);
typedef VkResult(VKAPI_PTR *PFN_vkDbgSetObjectTag)(
VkDevice device, VkDebugReportObjectTypeEXT objType, uint64_t object,
size_t tagSize, const void *pTag);
typedef VkResult(VKAPI_PTR *PFN_vkDbgSetObjectName)(
VkDevice device, VkDebugReportObjectTypeEXT objType, uint64_t object,
size_t nameSize, const char *pName);
#ifndef VK_NO_PROTOTYPES
// DebugMarker extension entrypoints
VKAPI_ATTR void VKAPI_CALL
vkCmdDbgMarkerBegin(VkCommandBuffer commandBuffer, const char *pMarker);
VKAPI_ATTR void VKAPI_CALL vkCmdDbgMarkerEnd(VkCommandBuffer commandBuffer);
VKAPI_ATTR VkResult VKAPI_CALL
vkDbgSetObjectTag(VkDevice device, VkDebugReportObjectTypeEXT objType,
uint64_t object, size_t tagSize, const void *pTag);
VKAPI_ATTR VkResult VKAPI_CALL
vkDbgSetObjectName(VkDevice device, VkDebugReportObjectTypeEXT objType,
uint64_t object, size_t nameSize, const char *pName);
#endif // VK_NO_PROTOTYPES
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif // __VK_DEBUG_MARKER_H__

127
third_party/vulkan/vk_platform.h vendored Normal file
View File

@ -0,0 +1,127 @@
//
// File: vk_platform.h
//
/*
** Copyright (c) 2014-2015 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
#ifndef __VK_PLATFORM_H__
#define __VK_PLATFORM_H__
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
/*
***************************************************************************************************
* Platform-specific directives and type declarations
***************************************************************************************************
*/
/* Platform-specific calling convention macros.
*
* Platforms should define these so that Vulkan clients call Vulkan commands
* with the same calling conventions that the Vulkan implementation expects.
*
* VKAPI_ATTR - Placed before the return type in function declarations.
* Useful for C++11 and GCC/Clang-style function attribute syntax.
* VKAPI_CALL - Placed after the return type in function declarations.
* Useful for MSVC-style calling convention syntax.
* VKAPI_PTR - Placed between the '(' and '*' in function pointer types.
*
* Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void);
* Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void);
*/
#if defined(_WIN32)
// On Windows, Vulkan commands use the stdcall convention
#define VKAPI_ATTR
#define VKAPI_CALL __stdcall
#define VKAPI_PTR VKAPI_CALL
#elif defined(__ANDROID__) && defined(__ARM_EABI__) && !defined(__ARM_ARCH_7A__)
// Android does not support Vulkan in native code using the "armeabi" ABI.
#error "Vulkan requires the 'armeabi-v7a' or 'armeabi-v7a-hard' ABI on 32-bit ARM CPUs"
#elif defined(__ANDROID__) && defined(__ARM_ARCH_7A__)
// On Android/ARMv7a, Vulkan functions use the armeabi-v7a-hard calling
// convention, even if the application's native code is compiled with the
// armeabi-v7a calling convention.
#define VKAPI_ATTR __attribute__((pcs("aapcs-vfp")))
#define VKAPI_CALL
#define VKAPI_PTR VKAPI_ATTR
#else
// On other platforms, use the default calling convention
#define VKAPI_ATTR
#define VKAPI_CALL
#define VKAPI_PTR
#endif
#include <stddef.h>
#if !defined(VK_NO_STDINT_H)
#if defined(_MSC_VER) && (_MSC_VER < 1600)
typedef signed __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef signed __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
#endif // !defined(VK_NO_STDINT_H)
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
// Platform-specific headers required by platform window system extensions.
// These are enabled prior to #including "vulkan.h". The same enable then
// controls inclusion of the extension interfaces in vulkan.h.
#ifdef VK_USE_PLATFORM_ANDROID_KHR
#include <android/native_window.h>
#endif
#ifdef VK_USE_PLATFORM_MIR_KHR
#include <mir_toolkit/client_types.h>
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
#include <wayland-client.h>
#endif
#ifdef VK_USE_PLATFORM_WIN32_KHR
#include <windows.h>
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR
#include <X11/Xlib.h>
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
#include <xcb/xcb.h>
#endif
#endif // __VK_PLATFORM_H__

53
third_party/vulkan/vk_sdk_platform.h vendored Normal file
View File

@ -0,0 +1,53 @@
//
// File: vk_sdk_platform.h
//
/*
* Copyright (c) 2015-2016 The Khronos Group Inc.
* Copyright (c) 2015-2016 Valve Corporation
* Copyright (c) 2015-2016 LunarG, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and/or associated documentation files (the "Materials"), to
* deal in the Materials without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Materials, and to permit persons to whom the Materials are
* furnished to do so, subject to the following conditions:
*
* The above copyright notice(s) and this permission notice shall be included in
* all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
* USE OR OTHER DEALINGS IN THE MATERIALS.
*/
#ifndef VK_SDK_PLATFORM_H
#define VK_SDK_PLATFORM_H
#if defined(_WIN32)
#define NOMINMAX
#ifndef __cplusplus
#undef inline
#define inline __inline
#endif // __cplusplus
#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/)
// C99:
// Microsoft didn't implement C99 in Visual Studio; but started adding it with
// VS2013. However, VS2013 still didn't have snprintf(). The following is a
// work-around (Note: The _CRT_SECURE_NO_WARNINGS macro must be set in the
// "CMakeLists.txt" file).
// NOTE: This is fixed in Visual Studio 2015.
#define snprintf _snprintf
#endif
#define strdup _strdup
#endif // _WIN32
#endif // VK_SDK_PLATFORM_H

3775
third_party/vulkan/vulkan.h vendored Normal file

File diff suppressed because it is too large Load Diff