Initial vulkan context and immediate drawer.
Extremely rough, just checking in so DrChat can snoop.
This commit is contained in:
parent
d52d2c4837
commit
9f52f2e819
|
@ -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
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
})
|
|
@ -0,0 +1,2 @@
|
||||||
|
glslangValidator -V immediate.vert -o immediate.vert.spv
|
||||||
|
glslangValidator -V immediate.frag -o immediate.frag.spv
|
|
@ -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.
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.
|
@ -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;
|
||||||
|
}
|
|
@ -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.
|
@ -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.");
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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, ¤t_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
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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);
|
|
@ -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
|
|
@ -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",
|
||||||
})
|
})
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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
|
@ -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
|
||||||
|
|
|
@ -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 */
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
@ -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.
|
||||||
|
|
||||||
|
*/
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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",
|
||||||
|
})
|
|
@ -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;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -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;
|
|
@ -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
|
|
@ -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
|
|
@ -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__
|
|
@ -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__
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue