[SPIR-V] Main loop blocks, validation
This commit is contained in:
113
src/xenia/ui/vulkan/spirv_tools_context.cc
Normal file
113
src/xenia/ui/vulkan/spirv_tools_context.cc
Normal file
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2020 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "xenia/ui/vulkan/spirv_tools_context.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/base/platform.h"
|
||||
|
||||
#if XE_PLATFORM_LINUX
|
||||
#include <dlfcn.h>
|
||||
#elif XE_PLATFORM_WIN32
|
||||
#include "xenia/base/platform_win.h"
|
||||
#endif
|
||||
|
||||
namespace xe {
|
||||
namespace ui {
|
||||
namespace vulkan {
|
||||
|
||||
bool SpirvToolsContext::Initialize() {
|
||||
const char* vulkan_sdk_env = std::getenv("VULKAN_SDK");
|
||||
if (!vulkan_sdk_env) {
|
||||
XELOGE("SPIRV-Tools: Failed to get the VULKAN_SDK environment variable");
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
std::filesystem::path vulkan_sdk_path(vulkan_sdk_env);
|
||||
#if XE_PLATFORM_LINUX
|
||||
library_ = dlopen((vulkan_sdk_path / "bin/libSPIRV-Tools-shared.so").c_str(),
|
||||
RTLD_NOW | RTLD_LOCAL);
|
||||
if (!library_) {
|
||||
XELOGE(
|
||||
"SPIRV-Tools: Failed to load $VULKAN_SDK/bin/libSPIRV-Tools-shared.so");
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
#elif XE_PLATFORM_WIN32
|
||||
library_ = LoadLibraryW(
|
||||
(vulkan_sdk_path / "Bin/SPIRV-Tools-shared.dll").wstring().c_str());
|
||||
if (!library_) {
|
||||
XELOGE(
|
||||
"SPIRV-Tools: Failed to load %VULKAN_SDK%/Bin/SPIRV-Tools-shared.dll");
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
#error No SPIRV-Tools library loading provided for the target platform.
|
||||
#endif
|
||||
if (!LoadLibraryFunction(fn_spvContextCreate_, "spvContextCreate") ||
|
||||
!LoadLibraryFunction(fn_spvContextDestroy_, "spvContextDestroy") ||
|
||||
!LoadLibraryFunction(fn_spvValidateBinary_, "spvValidateBinary") ||
|
||||
!LoadLibraryFunction(fn_spvDiagnosticDestroy_, "spvDiagnosticDestroy")) {
|
||||
XELOGE("SPIRV-Tools: Failed to get library function pointers");
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
context_ = fn_spvContextCreate_(SPV_ENV_VULKAN_1_0);
|
||||
if (!context_) {
|
||||
XELOGE("SPIRV-Tools: Failed to create a Vulkan 1.0 context");
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SpirvToolsContext::Shutdown() {
|
||||
if (context_) {
|
||||
fn_spvContextDestroy_(context_);
|
||||
context_ = nullptr;
|
||||
}
|
||||
if (library_) {
|
||||
#if XE_PLATFORM_LINUX
|
||||
dlclose(library_);
|
||||
#elif XE_PLATFORM_WIN32
|
||||
FreeLibrary(library_);
|
||||
#endif
|
||||
library_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
spv_result_t SpirvToolsContext::Validate(const uint32_t* words,
|
||||
size_t num_words,
|
||||
std::string* error) const {
|
||||
if (error) {
|
||||
error->clear();
|
||||
}
|
||||
if (!context_) {
|
||||
return SPV_UNSUPPORTED;
|
||||
}
|
||||
spv_diagnostic diagnostic = nullptr;
|
||||
spv_result_t result =
|
||||
fn_spvValidateBinary_(context_, words, num_words, &diagnostic);
|
||||
if (diagnostic) {
|
||||
if (error && diagnostic && diagnostic->error) {
|
||||
*error = diagnostic->error;
|
||||
}
|
||||
fn_spvDiagnosticDestroy_(diagnostic);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace vulkan
|
||||
} // namespace ui
|
||||
} // namespace xe
|
||||
72
src/xenia/ui/vulkan/spirv_tools_context.h
Normal file
72
src/xenia/ui/vulkan/spirv_tools_context.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2020 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_UI_VULKAN_SPIRV_TOOLS_CONTEXT_H_
|
||||
#define XENIA_UI_VULKAN_SPIRV_TOOLS_CONTEXT_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "third_party/SPIRV-Tools/include/spirv-tools/libspirv.h"
|
||||
#include "xenia/base/platform.h"
|
||||
|
||||
#if XE_PLATFORM_LINUX
|
||||
#include <dlfcn.h>
|
||||
#elif XE_PLATFORM_WIN32
|
||||
#include "xenia/base/platform_win.h"
|
||||
#endif
|
||||
|
||||
namespace xe {
|
||||
namespace ui {
|
||||
namespace vulkan {
|
||||
|
||||
class SpirvToolsContext {
|
||||
public:
|
||||
SpirvToolsContext() {}
|
||||
SpirvToolsContext(const SpirvToolsContext& context) = delete;
|
||||
SpirvToolsContext& operator=(const SpirvToolsContext& context) = delete;
|
||||
~SpirvToolsContext() { Shutdown(); }
|
||||
bool Initialize();
|
||||
void Shutdown();
|
||||
|
||||
spv_result_t Validate(const uint32_t* words, size_t num_words,
|
||||
std::string* error) const;
|
||||
|
||||
private:
|
||||
#if XE_PLATFORM_LINUX
|
||||
void* library_ = nullptr;
|
||||
#elif XE_PLATFORM_WIN32
|
||||
HMODULE library_ = nullptr;
|
||||
#endif
|
||||
|
||||
template <typename FunctionPointer>
|
||||
bool LoadLibraryFunction(FunctionPointer& function, const char* name) {
|
||||
#if XE_PLATFORM_LINUX
|
||||
function = reinterpret_cast<FunctionPointer>(dlsym(library_, name));
|
||||
#elif XE_PLATFORM_WIN32
|
||||
function =
|
||||
reinterpret_cast<FunctionPointer>(GetProcAddress(library_, name));
|
||||
#else
|
||||
#error No SPIRV-Tools LoadLibraryFunction provided for the target platform.
|
||||
#endif
|
||||
return function != nullptr;
|
||||
}
|
||||
decltype(&spvContextCreate) fn_spvContextCreate_ = nullptr;
|
||||
decltype(&spvContextDestroy) fn_spvContextDestroy_ = nullptr;
|
||||
decltype(&spvValidateBinary) fn_spvValidateBinary_ = nullptr;
|
||||
decltype(&spvDiagnosticDestroy) fn_spvDiagnosticDestroy_ = nullptr;
|
||||
|
||||
spv_context context_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace vulkan
|
||||
} // namespace ui
|
||||
} // namespace xe
|
||||
|
||||
#endif // XENIA_UI_VULKAN_SPIRV_TOOLS_CONTEXT_H_
|
||||
Reference in New Issue
Block a user