mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-07 19:58:32 +09:00
@@ -0,0 +1,82 @@
|
||||
cmake_minimum_required(VERSION 3.22.1)
|
||||
|
||||
project("mobilegluvk")
|
||||
|
||||
enable_language(CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w -fvisibility=hidden -funwind-tables -g -D_THREAD_SAFE -fPIC -stdlib=libc++")
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w -g -std=gnu99 -funwind-tables -O3 -fvisibility=hidden")
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++")
|
||||
|
||||
set(CMAKE_ANDROID_STL_TYPE c++_static)
|
||||
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
|
||||
set(PROFILING OFF)
|
||||
|
||||
find_library(GLSLANG_LIB glslang PATHS ${CMAKE_SOURCE_DIR}/libraries/arm64-v8a/)
|
||||
|
||||
add_library(${CMAKE_PROJECT_NAME} SHARED
|
||||
MG/Init.cpp
|
||||
|
||||
# MG_GL/GL
|
||||
MG/MG_GL/GL/Getter/GL_Getter.cpp
|
||||
MG/MG_GL/GL/Getter/BackendInfo.cpp
|
||||
|
||||
MG/MG_GL/GL/Framebuffer/GL_Framebuffer.cpp
|
||||
|
||||
# MG_GL/GLX
|
||||
MG/MG_GL/GLX/LookUp/LookUp.cpp
|
||||
|
||||
# MG_GL/GL_Def
|
||||
MG/MG_GL/GL_Def/GL_Def.cpp
|
||||
|
||||
# MG_UTIL/Debug
|
||||
MG/MG_UTIL/Debug/Debug.cpp
|
||||
|
||||
# MG_GL/TEMP_MESA
|
||||
MG/MG_GL/TEMP_MESA/MesaEmu.cpp
|
||||
)
|
||||
|
||||
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ./includes)
|
||||
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME}
|
||||
${CMAKE_SOURCE_DIR}/library/arm64-v8a/libglslang.a
|
||||
#${CMAKE_SOURCE_DIR}/library/arm64-v8a/libspirv-cross-c-shared.so
|
||||
#${CMAKE_SOURCE_DIR}/library/arm64-v8a/libshaderconv.so
|
||||
${CMAKE_SOURCE_DIR}/library/arm64-v8a/libGenericCodeGen.a
|
||||
${CMAKE_SOURCE_DIR}/library/arm64-v8a/libglslang-default-resource-limits.a
|
||||
${CMAKE_SOURCE_DIR}/library/arm64-v8a/libMachineIndependent.a
|
||||
${CMAKE_SOURCE_DIR}/library/arm64-v8a/libOSDependent.a
|
||||
${CMAKE_SOURCE_DIR}/library/arm64-v8a/libSPIRV-Tools-diff.a
|
||||
${CMAKE_SOURCE_DIR}/library/arm64-v8a/libSPIRV-Tools-link.a
|
||||
${CMAKE_SOURCE_DIR}/library/arm64-v8a/libSPIRV-Tools-lint.a
|
||||
${CMAKE_SOURCE_DIR}/library/arm64-v8a/libSPIRV-Tools-opt.a
|
||||
${CMAKE_SOURCE_DIR}/library/arm64-v8a/libSPIRV-Tools-reduce.a
|
||||
${CMAKE_SOURCE_DIR}/library/arm64-v8a/libSPIRV-Tools.a
|
||||
${CMAKE_SOURCE_DIR}/library/arm64-v8a/libSPIRV.a
|
||||
${CMAKE_SOURCE_DIR}/library/arm64-v8a/libSPVRemapper.a
|
||||
android
|
||||
log
|
||||
EGL
|
||||
vulkan
|
||||
)
|
||||
|
||||
target_include_directories(mobilegluvk PUBLIC
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
)
|
||||
|
||||
|
||||
if (PROFILING)
|
||||
find_package(Threads)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/3rdparty/perfetto/sdk)
|
||||
add_library(perfetto STATIC ${CMAKE_SOURCE_DIR}/3rdparty/perfetto/sdk/perfetto.cc)
|
||||
target_link_libraries(mobilegluvk perfetto ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_compile_definitions(mobilegluvk PUBLIC PROFILING=1)
|
||||
endif()
|
||||
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// Created by BZLZHH on 2025/3/15.
|
||||
//
|
||||
|
||||
#ifndef MOBILEGL_CONSTANTS_H
|
||||
#define MOBILEGL_CONSTANTS_H
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#define __ANDROID_API__ 26
|
||||
#endif
|
||||
#define MG_EXPORT __attribute__((visibility("default")))
|
||||
|
||||
namespace MG_Constants {
|
||||
namespace Common {
|
||||
inline const int LOG_LEVEL_DEBUG = 0x0010;
|
||||
inline const int LOG_LEVEL_WARN = 0x0011;
|
||||
inline const int LOG_LEVEL_ERROR = 0x0012;
|
||||
inline const int LOG_LEVEL_INFO = 0x0013;
|
||||
inline const int LOG_LEVEL_FATAL = 0x0014;
|
||||
}
|
||||
|
||||
namespace Backend {
|
||||
#define BACKEND_VULKAN 0x0015
|
||||
#define BACKEND_METAL 0x0016
|
||||
#define BACKEND_GLES 0x0017
|
||||
}
|
||||
|
||||
inline const char* RenderName = "MobileGL";
|
||||
}
|
||||
|
||||
#endif //MOBILEGL_CONSTANTS_H
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// Created by BZLZHH on 2025/3/15.
|
||||
//
|
||||
|
||||
#ifndef MOBILEGL_GLOBAL_H
|
||||
#define MOBILEGL_GLOBAL_H
|
||||
|
||||
#include "Includes.h"
|
||||
|
||||
namespace MG_Global {
|
||||
namespace MG {
|
||||
inline const int VersionMajor = 0;
|
||||
inline const int VersionMinor = 0;
|
||||
inline const int VersionRevision = 1;
|
||||
inline const int VersionPatch = 0;
|
||||
inline const std::string VersionSuffix = "";
|
||||
}
|
||||
|
||||
namespace Backend {
|
||||
#define BACKEND_TYPE BACKEND_VULKAN
|
||||
}
|
||||
|
||||
namespace GL {
|
||||
inline const int GLVersionMajor = 3;
|
||||
inline const int GLVersionMinor = 0;
|
||||
inline const int GLVersionRevision = 0;
|
||||
}
|
||||
|
||||
namespace Common {
|
||||
inline const int LogLevel = MG_Constants::Common::LOG_LEVEL_DEBUG;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
inline const char* LOG_FILE_PATH = "/sdcard/MG/latest.log";
|
||||
#else
|
||||
inline const char* LOG_FILE_PATH = nullptr;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif //MOBILEGL_GLOBAL_H
|
||||
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// Created by BZLZHH on 2025/3/15.
|
||||
//
|
||||
|
||||
#include "Constants.h"
|
||||
#ifndef MOBILEGL_GLOBAL_H
|
||||
#include "Global.h"
|
||||
#endif
|
||||
#ifndef MOBILEGL_GL_FRAMEBUFFER_H
|
||||
#include "MG_GL/GL/Framebuffer/GL_Framebuffer.h"
|
||||
#endif
|
||||
#ifndef MOBILEGL_GL_GETTER_H
|
||||
#include "MG_GL/GL/Getter/GL_Getter.h"
|
||||
#endif
|
||||
#ifndef MOBILEGL_BACKENDINFO_H
|
||||
#include "MG_GL/GL/Getter/BackendInfo.h"
|
||||
#endif
|
||||
#ifndef MOBILEGL_LOOKUP_H
|
||||
#include "MG_GL/GLX/LookUp/LookUp.h"
|
||||
#endif
|
||||
#ifndef MOBILEGL_DEBUG_H
|
||||
#include "MG_UTIL/Debug/Debug.h"
|
||||
#endif
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <dlfcn.h>
|
||||
#include <unistd.h>
|
||||
#include <ctime>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <string>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
#include <pthread.h>
|
||||
#elif _WIN32
|
||||
#include <windows.h>
|
||||
#include <processthreadsapi.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
//
|
||||
// Created by BZLZHH on 2025/3/15.
|
||||
//
|
||||
|
||||
#include "Includes.h"
|
||||
|
||||
__attribute__((constructor)) void MG_Initialize() {
|
||||
MG_Util::Debug::LogI("MobileGL Initializing...");
|
||||
MG_Util::Debug::LogInit();
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
//
|
||||
// Created by BZLZHH on 2025/3/15.
|
||||
//
|
||||
|
||||
#include "GL_Framebuffer.h"
|
||||
|
||||
namespace MG_GL::GL {
|
||||
GLenum CheckFramebufferStatus(GLenum target) {
|
||||
return GL_FRAMEBUFFER_COMPLETE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// Created by BZLZHH on 2025/3/15.
|
||||
//
|
||||
|
||||
#ifndef MOBILEGL_GL_FRAMEBUFFER_H
|
||||
#define MOBILEGL_GL_FRAMEBUFFER_H
|
||||
|
||||
#include "../../../Includes.h"
|
||||
|
||||
namespace MG_GL::GL {
|
||||
GLenum CheckFramebufferStatus(GLenum target);
|
||||
}
|
||||
|
||||
#endif //MOBILEGL_GL_FRAMEBUFFER_H
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Created by BZLZHH on 2025/3/15.
|
||||
//
|
||||
|
||||
#include "BackendInfo.h"
|
||||
|
||||
namespace MG_GL::Getter {
|
||||
const std::string GetBackendName() {
|
||||
#if BACKEND_TYPE == BACKEND_VULKAN
|
||||
return "Vulkan";
|
||||
#elif BACKEND_TYPE == BACKEND_VULKAN
|
||||
return "Metal";
|
||||
#elif BACKEND_TYPE == BACKEND_VULKAN
|
||||
return "OpenGL ES";
|
||||
#else
|
||||
return "<Unknown Backend>";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// Created by BZLZHH on 2025/3/15.
|
||||
//
|
||||
|
||||
#ifndef MOBILEGL_BACKENDINFO_H
|
||||
#define MOBILEGL_BACKENDINFO_H
|
||||
|
||||
#include "../../../Includes.h"
|
||||
|
||||
namespace MG_GL::Getter {
|
||||
const std::string GetBackendName();
|
||||
}
|
||||
|
||||
#endif //MOBILEGL_BACKENDINFO_H
|
||||
@@ -0,0 +1,165 @@
|
||||
//
|
||||
// Created by BZLZHH on 2025/3/15.
|
||||
//
|
||||
|
||||
#include "GL_Getter.h"
|
||||
|
||||
namespace MG_GL::GL {
|
||||
static std::string rendererString;
|
||||
const GLubyte* GetString(GLenum name) {
|
||||
MG_Util::Debug::LogD("glGetString, name: %s", MG_Util::Debug::GLEnumToString(name));
|
||||
switch (name) {
|
||||
case GL_VENDOR:
|
||||
return (const GLubyte *)"MobileGL-Dev";
|
||||
case GL_VERSION: {
|
||||
static std::string versionStr;
|
||||
if (versionStr.empty()) {
|
||||
versionStr == std::to_string(MG_Global::GL::GLVersionMajor) + "."
|
||||
+ std::to_string(MG_Global::GL::GLVersionMinor) + "."
|
||||
+ std::to_string(MG_Global::GL::GLVersionRevision)
|
||||
+ " MobileGL (" + MG_GL::Getter::GetBackendName() + ") ";
|
||||
|
||||
versionStr += std::to_string(MG_Global::MG::VersionMajor) + "."
|
||||
+ std::to_string(MG_Global::MG::VersionMinor) + "."
|
||||
+ std::to_string(MG_Global::MG::VersionRevision);
|
||||
if (MG_Global::MG::VersionPatch != 0)
|
||||
versionStr += "." + std::to_string(MG_Global::MG::VersionPatch);
|
||||
versionStr += MG_Global::MG::VersionSuffix;
|
||||
}
|
||||
return (const GLubyte *)versionStr.c_str();
|
||||
}
|
||||
|
||||
case GL_RENDERER:
|
||||
{
|
||||
/*
|
||||
if (rendererString == std::string("")) {
|
||||
const char* gpuName = getGpuName();
|
||||
const char* glesName = getGLESName();
|
||||
rendererString = std::string(gpuName) + " | " + std::string(glesName);
|
||||
}
|
||||
return (const GLubyte *)rendererString.c_str();
|
||||
*/
|
||||
return (const GLubyte *) "MobileGL";
|
||||
}
|
||||
case GL_SHADING_LANGUAGE_VERSION:
|
||||
return (const GLubyte *) "4.50 MobileGL with glslang";
|
||||
case GL_EXTENSIONS:
|
||||
return (const GLubyte *) "OpenGL11 "
|
||||
"OpenGL12 "
|
||||
"OpenGL13 "
|
||||
"OpenGL14 "
|
||||
"OpenGL15 "
|
||||
"OpenGL20 "
|
||||
"OpenGL21 "
|
||||
"OpenGL30 ";
|
||||
default:
|
||||
return (const GLubyte *) "Unknown enum";
|
||||
}
|
||||
}
|
||||
|
||||
const GLubyte* GetStringi(GLenum name, GLuint index) {
|
||||
MG_Util::Debug::LogD("glGetStringi, name: %s, index: %d", MG_Util::Debug::GLEnumToString(name), index);
|
||||
typedef struct {
|
||||
GLenum name;
|
||||
const char** parts;
|
||||
GLuint count;
|
||||
} StringCache;
|
||||
static StringCache caches[] = {
|
||||
{GL_EXTENSIONS, nullptr, 0},
|
||||
{GL_VENDOR, nullptr, 0},
|
||||
{GL_VERSION, nullptr, 0},
|
||||
{GL_SHADING_LANGUAGE_VERSION, nullptr, 0}
|
||||
};
|
||||
static int initialized = 0;
|
||||
if (!initialized) {
|
||||
for (auto & cache : caches) {
|
||||
GLenum target = cache.name;
|
||||
const GLubyte* str = nullptr;
|
||||
const char* delimiter = " ";
|
||||
|
||||
switch (target) {
|
||||
case GL_VENDOR:
|
||||
str = (const GLubyte*)"MobileGL-Dev";
|
||||
delimiter = ", ";
|
||||
break;
|
||||
case GL_VERSION:
|
||||
str = (const GLubyte*)"3.0.0 MobileGL";
|
||||
delimiter = " .";
|
||||
break;
|
||||
case GL_SHADING_LANGUAGE_VERSION:
|
||||
str = (const GLubyte*)"4.50 MobileGL glslang";
|
||||
break;
|
||||
case GL_EXTENSIONS:
|
||||
str = GetString(GL_EXTENSIONS);
|
||||
break;
|
||||
default:
|
||||
return (const GLubyte *) "Unknown enum";
|
||||
}
|
||||
|
||||
if (!str) continue;
|
||||
|
||||
char* copy = strdup((const char*)str);
|
||||
char* token = strtok(copy, delimiter);
|
||||
while (token) {
|
||||
cache.parts = (const char**)realloc(cache.parts, (cache.count + 1) * sizeof(char*));
|
||||
cache.parts[cache.count++] = strdup(token);
|
||||
token = strtok(nullptr, delimiter);
|
||||
}
|
||||
free(copy);
|
||||
}
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
for (auto & cache : caches) {
|
||||
if (cache.name == name) {
|
||||
if (index >= cache.count) {
|
||||
return nullptr;
|
||||
}
|
||||
return (const GLubyte*)cache.parts[index];
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GLenum GetError() {
|
||||
MG_Util::Debug::LogD("glGetError");
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
void GetIntegerv(GLenum pname, GLint *params) {
|
||||
MG_Util::Debug::LogD("glGetIntegerv, pname: %s", MG_Util::Debug::GLEnumToString(pname));
|
||||
switch (pname) {
|
||||
case GL_CONTEXT_PROFILE_MASK:
|
||||
(*params) = GL_CONTEXT_CORE_PROFILE_BIT;
|
||||
break;
|
||||
case GL_NUM_EXTENSIONS:
|
||||
static GLint num_extensions = -1;
|
||||
if (num_extensions == -1) {
|
||||
const GLubyte* ext_str = glGetString(GL_EXTENSIONS);
|
||||
if (ext_str) {
|
||||
char* copy = strdup((const char*)ext_str);
|
||||
char* token = strtok(copy, " ");
|
||||
num_extensions = 0;
|
||||
while (token) {
|
||||
num_extensions++;
|
||||
token = strtok(nullptr, " ");
|
||||
}
|
||||
free(copy);
|
||||
} else {
|
||||
num_extensions = 0;
|
||||
}
|
||||
}
|
||||
(*params) = num_extensions;
|
||||
break;
|
||||
case GL_MAJOR_VERSION:
|
||||
(*params) = MG_Global::GL::GLVersionMajor;
|
||||
break;
|
||||
case GL_MINOR_VERSION:
|
||||
(*params) = MG_Global::GL::GLVersionMinor;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// Created by BZLZHH on 2025/3/15.
|
||||
//
|
||||
|
||||
#ifndef MOBILEGL_GL_GETTER_H
|
||||
#define MOBILEGL_GL_GETTER_H
|
||||
|
||||
#include "../../../Includes.h"
|
||||
|
||||
namespace MG_GL::GL {
|
||||
const ::GLubyte* GetString(GLenum name);
|
||||
const ::GLubyte* GetStringi(GLenum name, GLuint index);
|
||||
::GLenum GetError();
|
||||
void GetIntegerv(GLenum pname, GLint *params);
|
||||
}
|
||||
|
||||
#endif //MOBILEGL_GL_GETTER_H
|
||||
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// Created by BZLZHH on 2025/3/15.
|
||||
//
|
||||
|
||||
#include "LookUp.h"
|
||||
|
||||
#include "../../../Includes.h"
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
namespace MG_GL::GLX {
|
||||
void* GetProcAddress(const char *name) {
|
||||
void* proc = dlsym(RTLD_DEFAULT, (const char*)name);
|
||||
|
||||
if (!proc) {
|
||||
MG_Util::Debug::LogW("Failed to get function: %s", (const char*)name);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return proc;
|
||||
}
|
||||
|
||||
void* GetProcAddressARB(const char *name) {
|
||||
return GetProcAddress(name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
//
|
||||
// Created by BZLZHH on 2025/3/15.
|
||||
//
|
||||
|
||||
#ifndef MOBILEGL_LOOKUP_H
|
||||
#define MOBILEGL_LOOKUP_H
|
||||
|
||||
namespace MG_GL::GLX {
|
||||
void* GetProcAddress(const char *name);
|
||||
void* GetProcAddressARB(const char *name);
|
||||
}
|
||||
#endif //MOBILEGL_LOOKUP_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
//
|
||||
// Created by BZLZHH on 2025/3/15.
|
||||
//
|
||||
|
||||
#ifndef MOBILEGL_GL_DEF_H
|
||||
#define MOBILEGL_GL_DEF_H
|
||||
|
||||
#include "../../Includes.h"
|
||||
|
||||
#endif //MOBILEGL_GL_DEF_H
|
||||
@@ -0,0 +1,160 @@
|
||||
//
|
||||
// Created by BZLZHH on 2025/3/15.
|
||||
//
|
||||
|
||||
#include "MesaEmu.h"
|
||||
|
||||
// Code From DeepSeek
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
struct OSMesaContextData {
|
||||
VkInstance instance = VK_NULL_HANDLE;
|
||||
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
||||
VkDevice device = VK_NULL_HANDLE;
|
||||
VkQueue graphicsQueue = VK_NULL_HANDLE;
|
||||
VkImage targetImage = VK_NULL_HANDLE;
|
||||
VkImageView imageView = VK_NULL_HANDLE;
|
||||
VkCommandPool commandPool = VK_NULL_HANDLE;
|
||||
GLsizei currentWidth = 0;
|
||||
GLsizei currentHeight = 0;
|
||||
GLint packAlignment = 4;
|
||||
GLubyte* frontBuffer = nullptr;
|
||||
uint32_t queueFamilyIndex = 0;
|
||||
};
|
||||
static std::map<OSMesaContext, OSMesaContextData> ctxMap;
|
||||
static thread_local OSMesaContext currentContext = nullptr;
|
||||
static uint32_t findGraphicsQueueFamily(VkPhysicalDevice physicalDevice) {
|
||||
uint32_t queueFamilyCount = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, nullptr);
|
||||
std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, queueFamilies.data());
|
||||
for (uint32_t i = 0; i < queueFamilyCount; ++i) {
|
||||
if (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw std::runtime_error("No graphics queue family found");
|
||||
}
|
||||
extern "C" MG_EXPORT OSMesaContext OSMesaCreateContext(GLenum format, OSMesaContext sharelist) {
|
||||
OSMesaContextData newCtx;
|
||||
try {
|
||||
VkInstanceCreateInfo instanceInfo{};
|
||||
instanceInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
if (vkCreateInstance(&instanceInfo, nullptr, &newCtx.instance) != VK_SUCCESS) {
|
||||
throw std::runtime_error("Failed to create Vulkan instance");
|
||||
}
|
||||
uint32_t deviceCount = 0;
|
||||
vkEnumeratePhysicalDevices(newCtx.instance, &deviceCount, nullptr);
|
||||
if (deviceCount == 0) {
|
||||
throw std::runtime_error("No Vulkan devices found");
|
||||
}
|
||||
|
||||
std::vector<VkPhysicalDevice> devices(deviceCount);
|
||||
vkEnumeratePhysicalDevices(newCtx.instance, &deviceCount, devices.data());
|
||||
newCtx.physicalDevice = devices[0];
|
||||
newCtx.queueFamilyIndex = findGraphicsQueueFamily(newCtx.physicalDevice);
|
||||
float queuePriority = 1.0f;
|
||||
VkDeviceQueueCreateInfo queueCreateInfo{};
|
||||
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||
queueCreateInfo.queueFamilyIndex = newCtx.queueFamilyIndex;
|
||||
queueCreateInfo.queueCount = 1;
|
||||
queueCreateInfo.pQueuePriorities = &queuePriority;
|
||||
VkDeviceCreateInfo deviceInfo{};
|
||||
deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||
deviceInfo.queueCreateInfoCount = 1;
|
||||
deviceInfo.pQueueCreateInfos = &queueCreateInfo;
|
||||
if (vkCreateDevice(newCtx.physicalDevice, &deviceInfo, nullptr, &newCtx.device) != VK_SUCCESS) {
|
||||
throw std::runtime_error("Failed to create logical device");
|
||||
}
|
||||
vkGetDeviceQueue(newCtx.device, newCtx.queueFamilyIndex, 0, &newCtx.graphicsQueue);
|
||||
VkCommandPoolCreateInfo poolInfo{};
|
||||
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
poolInfo.queueFamilyIndex = newCtx.queueFamilyIndex;
|
||||
poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||
if (vkCreateCommandPool(newCtx.device, &poolInfo, nullptr, &newCtx.commandPool) != VK_SUCCESS) {
|
||||
throw std::runtime_error("Failed to create command pool");
|
||||
}
|
||||
OSMesaContext ctx = reinterpret_cast<OSMesaContext>(new int(0));
|
||||
ctxMap[ctx] = newCtx;
|
||||
return ctx;
|
||||
} catch (const std::exception& e) {
|
||||
if (newCtx.device) vkDestroyDevice(newCtx.device, nullptr);
|
||||
if (newCtx.instance) vkDestroyInstance(newCtx.instance, nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
extern "C" MG_EXPORT void OSMesaDestroyContext(OSMesaContext ctx) {
|
||||
if (ctxMap.find(ctx) != ctxMap.end()) {
|
||||
auto& data = ctxMap[ctx];
|
||||
|
||||
if (data.commandPool) {
|
||||
vkDestroyCommandPool(data.device, data.commandPool, nullptr);
|
||||
}
|
||||
if (data.imageView) {
|
||||
vkDestroyImageView(data.device, data.imageView, nullptr);
|
||||
}
|
||||
if (data.targetImage) {
|
||||
vkDestroyImage(data.device, data.targetImage, nullptr);
|
||||
}
|
||||
if (data.device) {
|
||||
vkDestroyDevice(data.device, nullptr);
|
||||
}
|
||||
if (data.instance) {
|
||||
vkDestroyInstance(data.instance, nullptr);
|
||||
}
|
||||
|
||||
ctxMap.erase(ctx);
|
||||
delete reinterpret_cast<int*>(ctx);
|
||||
}
|
||||
}
|
||||
extern "C" MG_EXPORT GLboolean OSMesaMakeCurrent(OSMesaContext ctx, void *buffer, GLenum type,
|
||||
GLsizei width, GLsizei height) {
|
||||
if (!ctx || !buffer || width <= 0 || height <= 0) return GL_FALSE;
|
||||
auto& data = ctxMap[ctx];
|
||||
data.currentWidth = width;
|
||||
data.currentHeight = height;
|
||||
data.frontBuffer = static_cast<GLubyte*>(buffer);
|
||||
VkImageCreateInfo imageInfo{};
|
||||
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
imageInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||
imageInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
imageInfo.extent = {static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1};
|
||||
imageInfo.mipLevels = 1;
|
||||
imageInfo.arrayLayers = 1;
|
||||
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
imageInfo.tiling = VK_IMAGE_TILING_LINEAR;
|
||||
imageInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
if (vkCreateImage(data.device, &imageInfo, nullptr, &data.targetImage) != VK_SUCCESS) {
|
||||
return GL_FALSE;
|
||||
}
|
||||
VkImageViewCreateInfo viewInfo{};
|
||||
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
viewInfo.image = data.targetImage;
|
||||
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
viewInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
viewInfo.subresourceRange.levelCount = 1;
|
||||
viewInfo.subresourceRange.layerCount = 1;
|
||||
if (vkCreateImageView(data.device, &viewInfo, nullptr, &data.imageView) != VK_SUCCESS) {
|
||||
vkDestroyImage(data.device, data.targetImage, nullptr);
|
||||
return GL_FALSE;
|
||||
}
|
||||
currentContext = ctx;
|
||||
return GL_TRUE;
|
||||
}
|
||||
extern "C" MG_EXPORT OSMesaContext OSMesaGetCurrentContext() {
|
||||
return currentContext;
|
||||
}
|
||||
extern "C" MG_EXPORT void OSMesaPixelStore(GLint pname, GLint value) {
|
||||
if (pname == GL_PACK_ALIGNMENT && currentContext) {
|
||||
ctxMap[currentContext].packAlignment = value;
|
||||
}
|
||||
}
|
||||
extern "C" MG_EXPORT OSMESAproc OSMesaGetProcAddress( const char *funcName ) {
|
||||
return (OSMESAproc)MG_GL::GLX::GetProcAddress(funcName);
|
||||
}
|
||||
@@ -0,0 +1,343 @@
|
||||
//
|
||||
// Created by BZLZHH on 2025/3/15.
|
||||
//
|
||||
|
||||
#ifndef MOBILEGL_MESAEMU_H
|
||||
#define MOBILEGL_MESAEMU_H
|
||||
|
||||
#include "../../Includes.h"
|
||||
|
||||
#endif //MOBILEGL_MESAEMU_H
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
*
|
||||
* Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Mesa Off-Screen rendering interface.
|
||||
*
|
||||
* This is an operating system and window system independent interface to
|
||||
* Mesa which allows one to render images into a client-supplied buffer in
|
||||
* main memory. Such images may manipulated or saved in whatever way the
|
||||
* client wants.
|
||||
*
|
||||
* These are the API functions:
|
||||
* OSMesaCreateContext - create a new Off-Screen Mesa rendering context
|
||||
* OSMesaMakeCurrent - bind an OSMesaContext to a client's image buffer
|
||||
* and make the specified context the current one.
|
||||
* OSMesaDestroyContext - destroy an OSMesaContext
|
||||
* OSMesaGetCurrentContext - return thread's current context ID
|
||||
* OSMesaPixelStore - controls how pixels are stored in image buffer
|
||||
* OSMesaGetIntegerv - return OSMesa state parameters
|
||||
*
|
||||
*
|
||||
* The limits on the width and height of an image buffer can be retrieved
|
||||
* via OSMesaGetIntegerv(OSMESA_MAX_WIDTH/OSMESA_MAX_HEIGHT).
|
||||
*/
|
||||
|
||||
|
||||
#ifndef OSMESA_H
|
||||
#define OSMESA_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#include <GL/gl.h>
|
||||
|
||||
|
||||
#define OSMESA_MAJOR_VERSION 11
|
||||
#define OSMESA_MINOR_VERSION 2
|
||||
#define OSMESA_PATCH_VERSION 0
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Values for the format parameter of OSMesaCreateContext()
|
||||
* New in version 2.0.
|
||||
*/
|
||||
#define OSMESA_COLOR_INDEX GL_COLOR_INDEX
|
||||
#define OSMESA_RGBA GL_RGBA
|
||||
#define OSMESA_BGRA 0x1
|
||||
#define OSMESA_ARGB 0x2
|
||||
#define OSMESA_RGB GL_RGB
|
||||
#define OSMESA_BGR 0x4
|
||||
#define OSMESA_RGB_565 0x5
|
||||
|
||||
|
||||
/*
|
||||
* OSMesaPixelStore() parameters:
|
||||
* New in version 2.0.
|
||||
*/
|
||||
#define OSMESA_ROW_LENGTH 0x10
|
||||
#define OSMESA_Y_UP 0x11
|
||||
|
||||
|
||||
/*
|
||||
* Accepted by OSMesaGetIntegerv:
|
||||
*/
|
||||
#define OSMESA_WIDTH 0x20
|
||||
#define OSMESA_HEIGHT 0x21
|
||||
#define OSMESA_FORMAT 0x22
|
||||
#define OSMESA_TYPE 0x23
|
||||
#define OSMESA_MAX_WIDTH 0x24 /* new in 4.0 */
|
||||
#define OSMESA_MAX_HEIGHT 0x25 /* new in 4.0 */
|
||||
|
||||
/*
|
||||
* Accepted in OSMesaCreateContextAttrib's attribute list.
|
||||
*/
|
||||
#define OSMESA_DEPTH_BITS 0x30
|
||||
#define OSMESA_STENCIL_BITS 0x31
|
||||
#define OSMESA_ACCUM_BITS 0x32
|
||||
#define OSMESA_PROFILE 0x33
|
||||
#define OSMESA_CORE_PROFILE 0x34
|
||||
#define OSMESA_COMPAT_PROFILE 0x35
|
||||
#define OSMESA_CONTEXT_MAJOR_VERSION 0x36
|
||||
#define OSMESA_CONTEXT_MINOR_VERSION 0x37
|
||||
|
||||
|
||||
typedef struct osmesa_context *OSMesaContext;
|
||||
|
||||
|
||||
/*
|
||||
* Create an Off-Screen Mesa rendering context. The only attribute needed is
|
||||
* an RGBA vs Color-Index mode flag.
|
||||
*
|
||||
* Input: format - one of OSMESA_COLOR_INDEX, OSMESA_RGBA, OSMESA_BGRA,
|
||||
* OSMESA_ARGB, OSMESA_RGB, or OSMESA_BGR.
|
||||
* sharelist - specifies another OSMesaContext with which to share
|
||||
* display lists. NULL indicates no sharing.
|
||||
* Return: an OSMesaContext or 0 if error
|
||||
*/
|
||||
GLAPI OSMesaContext GLAPIENTRY
|
||||
OSMesaCreateContext( GLenum format, OSMesaContext sharelist );
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Create an Off-Screen Mesa rendering context and specify desired
|
||||
* size of depth buffer, stencil buffer and accumulation buffer.
|
||||
* If you specify zero for depthBits, stencilBits, accumBits you
|
||||
* can save some memory.
|
||||
*
|
||||
* New in Mesa 3.5
|
||||
*/
|
||||
GLAPI OSMesaContext GLAPIENTRY
|
||||
OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
|
||||
GLint accumBits, OSMesaContext sharelist);
|
||||
|
||||
|
||||
/*
|
||||
* Create an Off-Screen Mesa rendering context with attribute list.
|
||||
* The list is composed of (attribute, value) pairs and terminated with
|
||||
* attribute==0. Supported Attributes:
|
||||
*
|
||||
* Attributes Values
|
||||
* --------------------------------------------------------------------------
|
||||
* OSMESA_FORMAT OSMESA_RGBA*, OSMESA_BGRA, OSMESA_ARGB, etc.
|
||||
* OSMESA_DEPTH_BITS 0*, 16, 24, 32
|
||||
* OSMESA_STENCIL_BITS 0*, 8
|
||||
* OSMESA_ACCUM_BITS 0*, 16
|
||||
* OSMESA_PROFILE OSMESA_COMPAT_PROFILE*, OSMESA_CORE_PROFILE
|
||||
* OSMESA_CONTEXT_MAJOR_VERSION 1*, 2, 3
|
||||
* OSMESA_CONTEXT_MINOR_VERSION 0+
|
||||
*
|
||||
* Note: * = default value
|
||||
*
|
||||
* We return a context version >= what's specified by OSMESA_CONTEXT_MAJOR/
|
||||
* MINOR_VERSION for the given profile. For example, if you request a GL 1.4
|
||||
* compat profile, you might get a GL 3.0 compat profile.
|
||||
* Otherwise, null is returned if the version/profile is not supported.
|
||||
*
|
||||
* New in Mesa 11.2
|
||||
*/
|
||||
GLAPI OSMesaContext GLAPIENTRY
|
||||
OSMesaCreateContextAttribs( const int *attribList, OSMesaContext sharelist );
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Destroy an Off-Screen Mesa rendering context.
|
||||
*
|
||||
* Input: ctx - the context to destroy
|
||||
*/
|
||||
GLAPI void GLAPIENTRY
|
||||
OSMesaDestroyContext( OSMesaContext ctx );
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Bind an OSMesaContext to an image buffer. The image buffer is just a
|
||||
* block of memory which the client provides. Its size must be at least
|
||||
* as large as width*height*sizeof(type). Its address should be a multiple
|
||||
* of 4 if using RGBA mode.
|
||||
*
|
||||
* Image data is stored in the order of glDrawPixels: row-major order
|
||||
* with the lower-left image pixel stored in the first array position
|
||||
* (ie. bottom-to-top).
|
||||
*
|
||||
* Since the only type initially supported is GL_UNSIGNED_BYTE, if the
|
||||
* context is in RGBA mode, each pixel will be stored as a 4-byte RGBA
|
||||
* value. If the context is in color indexed mode, each pixel will be
|
||||
* stored as a 1-byte value.
|
||||
*
|
||||
* If the context's viewport hasn't been initialized yet, it will now be
|
||||
* initialized to (0,0,width,height).
|
||||
*
|
||||
* Input: ctx - the rendering context
|
||||
* buffer - the image buffer memory
|
||||
* type - data type for pixel components, only GL_UNSIGNED_BYTE
|
||||
* supported now
|
||||
* width, height - size of image buffer in pixels, at least 1
|
||||
* Return: GL_TRUE if success, GL_FALSE if error because of invalid ctx,
|
||||
* invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1,
|
||||
* width>internal limit or height>internal limit.
|
||||
*/
|
||||
GLAPI GLboolean GLAPIENTRY
|
||||
OSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type,
|
||||
GLsizei width, GLsizei height );
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Return the current Off-Screen Mesa rendering context handle.
|
||||
*/
|
||||
GLAPI OSMesaContext GLAPIENTRY
|
||||
OSMesaGetCurrentContext( void );
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Set pixel store/packing parameters for the current context.
|
||||
* This is similar to glPixelStore.
|
||||
* Input: pname - OSMESA_ROW_LENGTH
|
||||
* specify actual pixels per row in image buffer
|
||||
* 0 = same as image width (default)
|
||||
* OSMESA_Y_UP
|
||||
* zero = Y coordinates increase downward
|
||||
* non-zero = Y coordinates increase upward (default)
|
||||
* value - the value for the parameter pname
|
||||
*
|
||||
* New in version 2.0.
|
||||
*/
|
||||
GLAPI void GLAPIENTRY
|
||||
OSMesaPixelStore( GLint pname, GLint value );
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Return an integer value like glGetIntegerv.
|
||||
* Input: pname -
|
||||
* OSMESA_WIDTH return current image width
|
||||
* OSMESA_HEIGHT return current image height
|
||||
* OSMESA_FORMAT return image format
|
||||
* OSMESA_TYPE return color component data type
|
||||
* OSMESA_ROW_LENGTH return row length in pixels
|
||||
* OSMESA_Y_UP returns 1 or 0 to indicate Y axis direction
|
||||
* value - pointer to integer in which to return result.
|
||||
*/
|
||||
GLAPI void GLAPIENTRY
|
||||
OSMesaGetIntegerv( GLint pname, GLint *value );
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Return the depth buffer associated with an OSMesa context.
|
||||
* Input: c - the OSMesa context
|
||||
* Output: width, height - size of buffer in pixels
|
||||
* bytesPerValue - bytes per depth value (2 or 4)
|
||||
* buffer - pointer to depth buffer values
|
||||
* Return: GL_TRUE or GL_FALSE to indicate success or failure.
|
||||
*
|
||||
* New in Mesa 2.4.
|
||||
*/
|
||||
GLAPI GLboolean GLAPIENTRY
|
||||
OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height,
|
||||
GLint *bytesPerValue, void **buffer );
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Return the color buffer associated with an OSMesa context.
|
||||
* Input: c - the OSMesa context
|
||||
* Output: width, height - size of buffer in pixels
|
||||
* format - buffer format (OSMESA_FORMAT)
|
||||
* buffer - pointer to depth buffer values
|
||||
* Return: GL_TRUE or GL_FALSE to indicate success or failure.
|
||||
*
|
||||
* New in Mesa 3.3.
|
||||
*/
|
||||
GLAPI GLboolean GLAPIENTRY
|
||||
OSMesaGetColorBuffer( OSMesaContext c, GLint *width, GLint *height,
|
||||
GLint *format, void **buffer );
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This typedef is new in Mesa 6.3.
|
||||
*/
|
||||
typedef void (*OSMESAproc)();
|
||||
|
||||
|
||||
/*
|
||||
* Return pointer to the named function.
|
||||
* New in Mesa 4.1
|
||||
* Return OSMESAproc in 6.3.
|
||||
*/
|
||||
GLAPI OSMESAproc GLAPIENTRY
|
||||
OSMesaGetProcAddress( const char *funcName );
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Enable/disable color clamping, off by default.
|
||||
* New in Mesa 6.4.2
|
||||
*/
|
||||
GLAPI void GLAPIENTRY
|
||||
OSMesaColorClamp(GLboolean enable);
|
||||
|
||||
|
||||
/**
|
||||
* Enable/disable Gallium post-process filters.
|
||||
* This should be called after a context is created, but before it is
|
||||
* made current for the first time. After a context has been made
|
||||
* current, this function has no effect.
|
||||
* If the enable_value param is zero, the filter is disabled. Otherwise
|
||||
* the filter is enabled, and the value may control the filter's quality.
|
||||
* New in Mesa 10.0
|
||||
*/
|
||||
GLAPI void GLAPIENTRY
|
||||
OSMesaPostprocess(OSMesaContext osmesa, const char *filter,
|
||||
unsigned enable_value);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// Created by BZLZHH on 2025/1/26.
|
||||
//
|
||||
|
||||
#ifndef MOBILEGL_DEBUG_H
|
||||
#define MOBILEGL_DEBUG_H
|
||||
|
||||
#include "../../Includes.h"
|
||||
|
||||
#define FORCE_SYNC_WITH_LOG_FILE 0
|
||||
|
||||
namespace MG_Util {
|
||||
namespace Debug {
|
||||
const char* GetOSName();
|
||||
|
||||
void LogD (const char* format, ...);
|
||||
void LogW (const char* format, ...);
|
||||
void LogE (const char* format, ...);
|
||||
void LogI (const char* format, ...);
|
||||
void LogF (const char* format, ...);
|
||||
void LogClear();
|
||||
void LogInit();
|
||||
void LogWrite(const char* format, ...);
|
||||
|
||||
const char* GLEnumToString(::GLenum value);
|
||||
}
|
||||
}
|
||||
|
||||
#define MOBILEGL_DEBUG_H
|
||||
|
||||
#endif //MOBILEGL_DEBUG_H
|
||||
@@ -0,0 +1,329 @@
|
||||
/* -*- mode: c; tab-width: 8; -*- */
|
||||
/* vi: set sw=4 ts=8: */
|
||||
/* Reference version of egl.h for EGL 1.4.
|
||||
* $Revision: 9356 $ on $Date: 2009-10-21 02:52:25 -0700 (Wed, 21 Oct 2009) $
|
||||
*/
|
||||
|
||||
/*
|
||||
** Copyright (c) 2007-2009 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 __egl_h_
|
||||
#define __egl_h_
|
||||
|
||||
/* All platform-dependent types and macro boilerplate (such as EGLAPI
|
||||
* and EGLAPIENTRY) should go in eglplatform.h.
|
||||
*/
|
||||
#include <EGL/eglplatform.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* EGL Types */
|
||||
/* EGLint is defined in eglplatform.h */
|
||||
typedef unsigned int EGLBoolean;
|
||||
typedef unsigned int EGLenum;
|
||||
typedef void *EGLConfig;
|
||||
typedef void *EGLContext;
|
||||
typedef void *EGLDisplay;
|
||||
typedef void *EGLSurface;
|
||||
typedef void *EGLClientBuffer;
|
||||
|
||||
/* EGL Versioning */
|
||||
#define EGL_VERSION_1_0 1
|
||||
#define EGL_VERSION_1_1 1
|
||||
#define EGL_VERSION_1_2 1
|
||||
#define EGL_VERSION_1_3 1
|
||||
#define EGL_VERSION_1_4 1
|
||||
|
||||
/* EGL Enumerants. Bitmasks and other exceptional cases aside, most
|
||||
* enums are assigned unique values starting at 0x3000.
|
||||
*/
|
||||
|
||||
/* EGL aliases */
|
||||
#define EGL_FALSE 0
|
||||
#define EGL_TRUE 1
|
||||
|
||||
/* Out-of-band handle values */
|
||||
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0)
|
||||
#define EGL_NO_CONTEXT ((EGLContext)0)
|
||||
#define EGL_NO_DISPLAY ((EGLDisplay)0)
|
||||
#define EGL_NO_SURFACE ((EGLSurface)0)
|
||||
|
||||
/* Out-of-band attribute value */
|
||||
#define EGL_DONT_CARE ((EGLint)-1)
|
||||
|
||||
/* Errors / GetError return values */
|
||||
#define EGL_SUCCESS 0x3000
|
||||
#define EGL_NOT_INITIALIZED 0x3001
|
||||
#define EGL_BAD_ACCESS 0x3002
|
||||
#define EGL_BAD_ALLOC 0x3003
|
||||
#define EGL_BAD_ATTRIBUTE 0x3004
|
||||
#define EGL_BAD_CONFIG 0x3005
|
||||
#define EGL_BAD_CONTEXT 0x3006
|
||||
#define EGL_BAD_CURRENT_SURFACE 0x3007
|
||||
#define EGL_BAD_DISPLAY 0x3008
|
||||
#define EGL_BAD_MATCH 0x3009
|
||||
#define EGL_BAD_NATIVE_PIXMAP 0x300A
|
||||
#define EGL_BAD_NATIVE_WINDOW 0x300B
|
||||
#define EGL_BAD_PARAMETER 0x300C
|
||||
#define EGL_BAD_SURFACE 0x300D
|
||||
#define EGL_CONTEXT_LOST 0x300E /* EGL 1.1 - IMG_power_management */
|
||||
|
||||
/* Reserved 0x300F-0x301F for additional errors */
|
||||
|
||||
/* Config attributes */
|
||||
#define EGL_BUFFER_SIZE 0x3020
|
||||
#define EGL_ALPHA_SIZE 0x3021
|
||||
#define EGL_BLUE_SIZE 0x3022
|
||||
#define EGL_GREEN_SIZE 0x3023
|
||||
#define EGL_RED_SIZE 0x3024
|
||||
#define EGL_DEPTH_SIZE 0x3025
|
||||
#define EGL_STENCIL_SIZE 0x3026
|
||||
#define EGL_CONFIG_CAVEAT 0x3027
|
||||
#define EGL_CONFIG_ID 0x3028
|
||||
#define EGL_LEVEL 0x3029
|
||||
#define EGL_MAX_PBUFFER_HEIGHT 0x302A
|
||||
#define EGL_MAX_PBUFFER_PIXELS 0x302B
|
||||
#define EGL_MAX_PBUFFER_WIDTH 0x302C
|
||||
#define EGL_NATIVE_RENDERABLE 0x302D
|
||||
#define EGL_NATIVE_VISUAL_ID 0x302E
|
||||
#define EGL_NATIVE_VISUAL_TYPE 0x302F
|
||||
#define EGL_SAMPLES 0x3031
|
||||
#define EGL_SAMPLE_BUFFERS 0x3032
|
||||
#define EGL_SURFACE_TYPE 0x3033
|
||||
#define EGL_TRANSPARENT_TYPE 0x3034
|
||||
#define EGL_TRANSPARENT_BLUE_VALUE 0x3035
|
||||
#define EGL_TRANSPARENT_GREEN_VALUE 0x3036
|
||||
#define EGL_TRANSPARENT_RED_VALUE 0x3037
|
||||
#define EGL_NONE 0x3038 /* Attrib list terminator */
|
||||
#define EGL_BIND_TO_TEXTURE_RGB 0x3039
|
||||
#define EGL_BIND_TO_TEXTURE_RGBA 0x303A
|
||||
#define EGL_MIN_SWAP_INTERVAL 0x303B
|
||||
#define EGL_MAX_SWAP_INTERVAL 0x303C
|
||||
#define EGL_LUMINANCE_SIZE 0x303D
|
||||
#define EGL_ALPHA_MASK_SIZE 0x303E
|
||||
#define EGL_COLOR_BUFFER_TYPE 0x303F
|
||||
#define EGL_RENDERABLE_TYPE 0x3040
|
||||
#define EGL_MATCH_NATIVE_PIXMAP 0x3041 /* Pseudo-attribute (not queryable) */
|
||||
#define EGL_CONFORMANT 0x3042
|
||||
|
||||
/* Reserved 0x3041-0x304F for additional config attributes */
|
||||
|
||||
/* Config attribute values */
|
||||
#define EGL_SLOW_CONFIG 0x3050 /* EGL_CONFIG_CAVEAT value */
|
||||
#define EGL_NON_CONFORMANT_CONFIG 0x3051 /* EGL_CONFIG_CAVEAT value */
|
||||
#define EGL_TRANSPARENT_RGB 0x3052 /* EGL_TRANSPARENT_TYPE value */
|
||||
#define EGL_RGB_BUFFER 0x308E /* EGL_COLOR_BUFFER_TYPE value */
|
||||
#define EGL_LUMINANCE_BUFFER 0x308F /* EGL_COLOR_BUFFER_TYPE value */
|
||||
|
||||
/* More config attribute values, for EGL_TEXTURE_FORMAT */
|
||||
#define EGL_NO_TEXTURE 0x305C
|
||||
#define EGL_TEXTURE_RGB 0x305D
|
||||
#define EGL_TEXTURE_RGBA 0x305E
|
||||
#define EGL_TEXTURE_2D 0x305F
|
||||
|
||||
/* Config attribute mask bits */
|
||||
#define EGL_PBUFFER_BIT 0x0001 /* EGL_SURFACE_TYPE mask bits */
|
||||
#define EGL_PIXMAP_BIT 0x0002 /* EGL_SURFACE_TYPE mask bits */
|
||||
#define EGL_WINDOW_BIT 0x0004 /* EGL_SURFACE_TYPE mask bits */
|
||||
#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020 /* EGL_SURFACE_TYPE mask bits */
|
||||
#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040 /* EGL_SURFACE_TYPE mask bits */
|
||||
#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200 /* EGL_SURFACE_TYPE mask bits */
|
||||
#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 /* EGL_SURFACE_TYPE mask bits */
|
||||
|
||||
#define EGL_OPENGL_ES_BIT 0x0001 /* EGL_RENDERABLE_TYPE mask bits */
|
||||
#define EGL_OPENVG_BIT 0x0002 /* EGL_RENDERABLE_TYPE mask bits */
|
||||
#define EGL_OPENGL_ES2_BIT 0x0004 /* EGL_RENDERABLE_TYPE mask bits */
|
||||
#define EGL_OPENGL_BIT 0x0008 /* EGL_RENDERABLE_TYPE mask bits */
|
||||
|
||||
/* QueryString targets */
|
||||
#define EGL_VENDOR 0x3053
|
||||
#define EGL_VERSION 0x3054
|
||||
#define EGL_EXTENSIONS 0x3055
|
||||
#define EGL_CLIENT_APIS 0x308D
|
||||
|
||||
/* QuerySurface / SurfaceAttrib / CreatePbufferSurface targets */
|
||||
#define EGL_HEIGHT 0x3056
|
||||
#define EGL_WIDTH 0x3057
|
||||
#define EGL_LARGEST_PBUFFER 0x3058
|
||||
#define EGL_TEXTURE_FORMAT 0x3080
|
||||
#define EGL_TEXTURE_TARGET 0x3081
|
||||
#define EGL_MIPMAP_TEXTURE 0x3082
|
||||
#define EGL_MIPMAP_LEVEL 0x3083
|
||||
#define EGL_RENDER_BUFFER 0x3086
|
||||
#define EGL_VG_COLORSPACE 0x3087
|
||||
#define EGL_VG_ALPHA_FORMAT 0x3088
|
||||
#define EGL_HORIZONTAL_RESOLUTION 0x3090
|
||||
#define EGL_VERTICAL_RESOLUTION 0x3091
|
||||
#define EGL_PIXEL_ASPECT_RATIO 0x3092
|
||||
#define EGL_SWAP_BEHAVIOR 0x3093
|
||||
#define EGL_MULTISAMPLE_RESOLVE 0x3099
|
||||
|
||||
/* EGL_RENDER_BUFFER values / BindTexImage / ReleaseTexImage buffer targets */
|
||||
#define EGL_BACK_BUFFER 0x3084
|
||||
#define EGL_SINGLE_BUFFER 0x3085
|
||||
|
||||
/* OpenVG color spaces */
|
||||
#define EGL_VG_COLORSPACE_sRGB 0x3089 /* EGL_VG_COLORSPACE value */
|
||||
#define EGL_VG_COLORSPACE_LINEAR 0x308A /* EGL_VG_COLORSPACE value */
|
||||
|
||||
/* OpenVG alpha formats */
|
||||
#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B /* EGL_ALPHA_FORMAT value */
|
||||
#define EGL_VG_ALPHA_FORMAT_PRE 0x308C /* EGL_ALPHA_FORMAT value */
|
||||
|
||||
/* Constant scale factor by which fractional display resolutions &
|
||||
* aspect ratio are scaled when queried as integer values.
|
||||
*/
|
||||
#define EGL_DISPLAY_SCALING 10000
|
||||
|
||||
/* Unknown display resolution/aspect ratio */
|
||||
#define EGL_UNKNOWN ((EGLint)-1)
|
||||
|
||||
/* Back buffer swap behaviors */
|
||||
#define EGL_BUFFER_PRESERVED 0x3094 /* EGL_SWAP_BEHAVIOR value */
|
||||
#define EGL_BUFFER_DESTROYED 0x3095 /* EGL_SWAP_BEHAVIOR value */
|
||||
|
||||
/* CreatePbufferFromClientBuffer buffer types */
|
||||
#define EGL_OPENVG_IMAGE 0x3096
|
||||
|
||||
/* QueryContext targets */
|
||||
#define EGL_CONTEXT_CLIENT_TYPE 0x3097
|
||||
|
||||
/* CreateContext attributes */
|
||||
#define EGL_CONTEXT_CLIENT_VERSION 0x3098
|
||||
|
||||
/* Multisample resolution behaviors */
|
||||
#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A /* EGL_MULTISAMPLE_RESOLVE value */
|
||||
#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B /* EGL_MULTISAMPLE_RESOLVE value */
|
||||
|
||||
/* BindAPI/QueryAPI targets */
|
||||
#define EGL_OPENGL_ES_API 0x30A0
|
||||
#define EGL_OPENVG_API 0x30A1
|
||||
#define EGL_OPENGL_API 0x30A2
|
||||
|
||||
/* GetCurrentSurface targets */
|
||||
#define EGL_DRAW 0x3059
|
||||
#define EGL_READ 0x305A
|
||||
|
||||
/* WaitNative engines */
|
||||
#define EGL_CORE_NATIVE_ENGINE 0x305B
|
||||
|
||||
/* EGL 1.2 tokens renamed for consistency in EGL 1.3 */
|
||||
#define EGL_COLORSPACE EGL_VG_COLORSPACE
|
||||
#define EGL_ALPHA_FORMAT EGL_VG_ALPHA_FORMAT
|
||||
#define EGL_COLORSPACE_sRGB EGL_VG_COLORSPACE_sRGB
|
||||
#define EGL_COLORSPACE_LINEAR EGL_VG_COLORSPACE_LINEAR
|
||||
#define EGL_ALPHA_FORMAT_NONPRE EGL_VG_ALPHA_FORMAT_NONPRE
|
||||
#define EGL_ALPHA_FORMAT_PRE EGL_VG_ALPHA_FORMAT_PRE
|
||||
|
||||
/* EGL extensions must request enum blocks from the Khronos
|
||||
* API Registrar, who maintains the enumerant registry. Submit
|
||||
* a bug in Khronos Bugzilla against task "Registry".
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* EGL Functions */
|
||||
|
||||
EGLAPI EGLint EGLAPIENTRY eglGetError(void);
|
||||
|
||||
EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy);
|
||||
|
||||
EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name);
|
||||
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
|
||||
EGLint config_size, EGLint *num_config);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
|
||||
EGLConfig *configs, EGLint config_size,
|
||||
EGLint *num_config);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
|
||||
EGLint attribute, EGLint *value);
|
||||
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
|
||||
EGLNativeWindowType win,
|
||||
const EGLint *attrib_list);
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
|
||||
const EGLint *attrib_list);
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
|
||||
EGLNativePixmapType pixmap,
|
||||
const EGLint *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
|
||||
EGLint attribute, EGLint *value);
|
||||
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api);
|
||||
EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void);
|
||||
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void);
|
||||
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void);
|
||||
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(
|
||||
EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
|
||||
EGLConfig config, const EGLint *attrib_list);
|
||||
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
|
||||
EGLint attribute, EGLint value);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
|
||||
|
||||
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval);
|
||||
|
||||
|
||||
EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config,
|
||||
EGLContext share_context,
|
||||
const EGLint *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw,
|
||||
EGLSurface read, EGLContext ctx);
|
||||
|
||||
EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void);
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw);
|
||||
EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx,
|
||||
EGLint attribute, EGLint *value);
|
||||
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface,
|
||||
EGLNativePixmapType target);
|
||||
|
||||
/* This is a generic function pointer type, whose name indicates it must
|
||||
* be cast to the proper type *and calling convention* before use.
|
||||
*/
|
||||
typedef void (*__eglMustCastToProperFunctionPointerType)(void);
|
||||
|
||||
/* Now, define eglGetProcAddress using the generic function ptr. type */
|
||||
EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY
|
||||
eglGetProcAddress(const char *procname);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __egl_h_ */
|
||||
@@ -0,0 +1,477 @@
|
||||
#ifndef __eglext_h_
|
||||
#define __eglext_h_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Copyright (c) 2007-2012 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.
|
||||
*/
|
||||
|
||||
#include <EGL/eglplatform.h>
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
/* Header file version number */
|
||||
/* Current version at http://www.khronos.org/registry/egl/ */
|
||||
/* $Revision: 19571 $ on $Date: 2012-10-31 10:10:33 -0700 (Wed, 31 Oct 2012) $ */
|
||||
#define EGL_EGLEXT_VERSION 14
|
||||
|
||||
#ifndef EGL_KHR_config_attribs
|
||||
#define EGL_KHR_config_attribs 1
|
||||
#define EGL_CONFORMANT_KHR 0x3042 /* EGLConfig attribute */
|
||||
#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020 /* EGL_SURFACE_TYPE bitfield */
|
||||
#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040 /* EGL_SURFACE_TYPE bitfield */
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_lock_surface
|
||||
#define EGL_KHR_lock_surface 1
|
||||
#define EGL_READ_SURFACE_BIT_KHR 0x0001 /* EGL_LOCK_USAGE_HINT_KHR bitfield */
|
||||
#define EGL_WRITE_SURFACE_BIT_KHR 0x0002 /* EGL_LOCK_USAGE_HINT_KHR bitfield */
|
||||
#define EGL_LOCK_SURFACE_BIT_KHR 0x0080 /* EGL_SURFACE_TYPE bitfield */
|
||||
#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100 /* EGL_SURFACE_TYPE bitfield */
|
||||
#define EGL_MATCH_FORMAT_KHR 0x3043 /* EGLConfig attribute */
|
||||
#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0 /* EGL_MATCH_FORMAT_KHR value */
|
||||
#define EGL_FORMAT_RGB_565_KHR 0x30C1 /* EGL_MATCH_FORMAT_KHR value */
|
||||
#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2 /* EGL_MATCH_FORMAT_KHR value */
|
||||
#define EGL_FORMAT_RGBA_8888_KHR 0x30C3 /* EGL_MATCH_FORMAT_KHR value */
|
||||
#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4 /* eglLockSurfaceKHR attribute */
|
||||
#define EGL_LOCK_USAGE_HINT_KHR 0x30C5 /* eglLockSurfaceKHR attribute */
|
||||
#define EGL_BITMAP_POINTER_KHR 0x30C6 /* eglQuerySurface attribute */
|
||||
#define EGL_BITMAP_PITCH_KHR 0x30C7 /* eglQuerySurface attribute */
|
||||
#define EGL_BITMAP_ORIGIN_KHR 0x30C8 /* eglQuerySurface attribute */
|
||||
#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9 /* eglQuerySurface attribute */
|
||||
#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA /* eglQuerySurface attribute */
|
||||
#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB /* eglQuerySurface attribute */
|
||||
#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC /* eglQuerySurface attribute */
|
||||
#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD /* eglQuerySurface attribute */
|
||||
#define EGL_LOWER_LEFT_KHR 0x30CE /* EGL_BITMAP_ORIGIN_KHR value */
|
||||
#define EGL_UPPER_LEFT_KHR 0x30CF /* EGL_BITMAP_ORIGIN_KHR value */
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay display, EGLSurface surface);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface);
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_image
|
||||
#define EGL_KHR_image 1
|
||||
#define EGL_NATIVE_PIXMAP_KHR 0x30B0 /* eglCreateImageKHR target */
|
||||
typedef void *EGLImageKHR;
|
||||
#define EGL_NO_IMAGE_KHR ((EGLImageKHR)0)
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_vg_parent_image
|
||||
#define EGL_KHR_vg_parent_image 1
|
||||
#define EGL_VG_PARENT_IMAGE_KHR 0x30BA /* eglCreateImageKHR target */
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_gl_texture_2D_image
|
||||
#define EGL_KHR_gl_texture_2D_image 1
|
||||
#define EGL_GL_TEXTURE_2D_KHR 0x30B1 /* eglCreateImageKHR target */
|
||||
#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC /* eglCreateImageKHR attribute */
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_gl_texture_cubemap_image
|
||||
#define EGL_KHR_gl_texture_cubemap_image 1
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3 /* eglCreateImageKHR target */
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4 /* eglCreateImageKHR target */
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5 /* eglCreateImageKHR target */
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6 /* eglCreateImageKHR target */
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7 /* eglCreateImageKHR target */
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8 /* eglCreateImageKHR target */
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_gl_texture_3D_image
|
||||
#define EGL_KHR_gl_texture_3D_image 1
|
||||
#define EGL_GL_TEXTURE_3D_KHR 0x30B2 /* eglCreateImageKHR target */
|
||||
#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD /* eglCreateImageKHR attribute */
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_gl_renderbuffer_image
|
||||
#define EGL_KHR_gl_renderbuffer_image 1
|
||||
#define EGL_GL_RENDERBUFFER_KHR 0x30B9 /* eglCreateImageKHR target */
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64 /* EGLTimeKHR requires 64-bit uint support */
|
||||
#ifndef EGL_KHR_reusable_sync
|
||||
#define EGL_KHR_reusable_sync 1
|
||||
|
||||
typedef void* EGLSyncKHR;
|
||||
typedef khronos_utime_nanoseconds_t EGLTimeKHR;
|
||||
|
||||
#define EGL_SYNC_STATUS_KHR 0x30F1
|
||||
#define EGL_SIGNALED_KHR 0x30F2
|
||||
#define EGL_UNSIGNALED_KHR 0x30F3
|
||||
#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5
|
||||
#define EGL_CONDITION_SATISFIED_KHR 0x30F6
|
||||
#define EGL_SYNC_TYPE_KHR 0x30F7
|
||||
#define EGL_SYNC_REUSABLE_KHR 0x30FA
|
||||
#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001 /* eglClientWaitSyncKHR <flags> bitfield */
|
||||
#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull
|
||||
#define EGL_NO_SYNC_KHR ((EGLSyncKHR)0)
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync);
|
||||
EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync);
|
||||
typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_image_base
|
||||
#define EGL_KHR_image_base 1
|
||||
/* Most interfaces defined by EGL_KHR_image_pixmap above */
|
||||
#define EGL_IMAGE_PRESERVED_KHR 0x30D2 /* eglCreateImageKHR attribute */
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_image_pixmap
|
||||
#define EGL_KHR_image_pixmap 1
|
||||
/* Interfaces defined by EGL_KHR_image above */
|
||||
#endif
|
||||
|
||||
#ifndef EGL_IMG_context_priority
|
||||
#define EGL_IMG_context_priority 1
|
||||
#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100
|
||||
#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101
|
||||
#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102
|
||||
#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_lock_surface2
|
||||
#define EGL_KHR_lock_surface2 1
|
||||
#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110
|
||||
#endif
|
||||
|
||||
#ifndef EGL_NV_coverage_sample
|
||||
#define EGL_NV_coverage_sample 1
|
||||
#define EGL_COVERAGE_BUFFERS_NV 0x30E0
|
||||
#define EGL_COVERAGE_SAMPLES_NV 0x30E1
|
||||
#endif
|
||||
|
||||
#ifndef EGL_NV_depth_nonlinear
|
||||
#define EGL_NV_depth_nonlinear 1
|
||||
#define EGL_DEPTH_ENCODING_NV 0x30E2
|
||||
#define EGL_DEPTH_ENCODING_NONE_NV 0
|
||||
#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64 /* EGLTimeNV requires 64-bit uint support */
|
||||
#ifndef EGL_NV_sync
|
||||
#define EGL_NV_sync 1
|
||||
#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6
|
||||
#define EGL_SYNC_STATUS_NV 0x30E7
|
||||
#define EGL_SIGNALED_NV 0x30E8
|
||||
#define EGL_UNSIGNALED_NV 0x30E9
|
||||
#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001
|
||||
#define EGL_FOREVER_NV 0xFFFFFFFFFFFFFFFFull
|
||||
#define EGL_ALREADY_SIGNALED_NV 0x30EA
|
||||
#define EGL_TIMEOUT_EXPIRED_NV 0x30EB
|
||||
#define EGL_CONDITION_SATISFIED_NV 0x30EC
|
||||
#define EGL_SYNC_TYPE_NV 0x30ED
|
||||
#define EGL_SYNC_CONDITION_NV 0x30EE
|
||||
#define EGL_SYNC_FENCE_NV 0x30EF
|
||||
#define EGL_NO_SYNC_NV ((EGLSyncNV)0)
|
||||
typedef void* EGLSyncNV;
|
||||
typedef khronos_utime_nanoseconds_t EGLTimeNV;
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLSyncNV EGLAPIENTRY eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncNV (EGLSyncNV sync);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglFenceNV (EGLSyncNV sync);
|
||||
EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncNV (EGLSyncNV sync, EGLenum mode);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync);
|
||||
typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64 /* Dependent on EGL_KHR_reusable_sync which requires 64-bit uint support */
|
||||
#ifndef EGL_KHR_fence_sync
|
||||
#define EGL_KHR_fence_sync 1
|
||||
/* Reuses most tokens and entry points from EGL_KHR_reusable_sync */
|
||||
#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0
|
||||
#define EGL_SYNC_CONDITION_KHR 0x30F8
|
||||
#define EGL_SYNC_FENCE_KHR 0x30F9
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef EGL_HI_clientpixmap
|
||||
#define EGL_HI_clientpixmap 1
|
||||
|
||||
/* Surface Attribute */
|
||||
#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74
|
||||
/*
|
||||
* Structure representing a client pixmap
|
||||
* (pixmap's data is in client-space memory).
|
||||
*/
|
||||
struct EGLClientPixmapHI
|
||||
{
|
||||
void* pData;
|
||||
EGLint iWidth;
|
||||
EGLint iHeight;
|
||||
EGLint iStride;
|
||||
};
|
||||
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI(EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap);
|
||||
#endif /* EGL_HI_clientpixmap */
|
||||
|
||||
#ifndef EGL_HI_colorformats
|
||||
#define EGL_HI_colorformats 1
|
||||
/* Config Attribute */
|
||||
#define EGL_COLOR_FORMAT_HI 0x8F70
|
||||
/* Color Formats */
|
||||
#define EGL_COLOR_RGB_HI 0x8F71
|
||||
#define EGL_COLOR_RGBA_HI 0x8F72
|
||||
#define EGL_COLOR_ARGB_HI 0x8F73
|
||||
#endif /* EGL_HI_colorformats */
|
||||
|
||||
#ifndef EGL_MESA_drm_image
|
||||
#define EGL_MESA_drm_image 1
|
||||
#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 /* CreateDRMImageMESA attribute */
|
||||
#define EGL_DRM_BUFFER_USE_MESA 0x31D1 /* CreateDRMImageMESA attribute */
|
||||
#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2 /* EGL_IMAGE_FORMAT_MESA attribute value */
|
||||
#define EGL_DRM_BUFFER_MESA 0x31D3 /* eglCreateImageKHR target */
|
||||
#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4
|
||||
#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001 /* EGL_DRM_BUFFER_USE_MESA bits */
|
||||
#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002 /* EGL_DRM_BUFFER_USE_MESA bits */
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA (EGLDisplay dpy, const EGLint *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
|
||||
#endif
|
||||
|
||||
#ifndef EGL_NV_post_sub_buffer
|
||||
#define EGL_NV_post_sub_buffer 1
|
||||
#define EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
|
||||
#endif
|
||||
|
||||
#ifndef EGL_ANGLE_query_surface_pointer
|
||||
#define EGL_ANGLE_query_surface_pointer 1
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLBoolean eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
|
||||
#endif
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
|
||||
#endif
|
||||
|
||||
#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle
|
||||
#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
|
||||
#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
|
||||
#endif
|
||||
|
||||
#ifndef EGL_NV_coverage_sample_resolve
|
||||
#define EGL_NV_coverage_sample_resolve 1
|
||||
#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131
|
||||
#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV 0x3132
|
||||
#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64 /* EGLuint64NV requires 64-bit uint support */
|
||||
#ifndef EGL_NV_system_time
|
||||
#define EGL_NV_system_time 1
|
||||
|
||||
typedef khronos_utime_nanoseconds_t EGLuint64NV;
|
||||
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV(void);
|
||||
EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV(void);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void);
|
||||
typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64 /* EGLuint64KHR requires 64-bit uint support */
|
||||
#ifndef EGL_KHR_stream
|
||||
#define EGL_KHR_stream 1
|
||||
typedef void* EGLStreamKHR;
|
||||
typedef khronos_uint64_t EGLuint64KHR;
|
||||
#define EGL_NO_STREAM_KHR ((EGLStreamKHR)0)
|
||||
#define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210
|
||||
#define EGL_PRODUCER_FRAME_KHR 0x3212
|
||||
#define EGL_CONSUMER_FRAME_KHR 0x3213
|
||||
#define EGL_STREAM_STATE_KHR 0x3214
|
||||
#define EGL_STREAM_STATE_CREATED_KHR 0x3215
|
||||
#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216
|
||||
#define EGL_STREAM_STATE_EMPTY_KHR 0x3217
|
||||
#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218
|
||||
#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219
|
||||
#define EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A
|
||||
#define EGL_BAD_STREAM_KHR 0x321B
|
||||
#define EGL_BAD_STATE_KHR 0x321C
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglStreamAttribKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMKHRPROC)(EGLDisplay dpy, const EGLint *attrib_list);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSTREAMKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMATTRIBKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMU64KHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef EGL_KHR_stream /* Requires KHR_stream extension */
|
||||
#ifndef EGL_KHR_stream_consumer_gltexture
|
||||
#define EGL_KHR_stream_consumer_gltexture 1
|
||||
#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStreamKHR stream);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream);
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef EGL_KHR_stream /* Requires KHR_stream extension */
|
||||
#ifndef EGL_KHR_stream_producer_eglsurface
|
||||
#define EGL_KHR_stream_producer_eglsurface 1
|
||||
#define EGL_STREAM_BIT_KHR 0x0800
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC)(EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef EGL_KHR_stream /* Requires KHR_stream extension */
|
||||
#ifndef EGL_KHR_stream_producer_aldatalocator
|
||||
#define EGL_KHR_stream_producer_aldatalocator 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef EGL_KHR_stream /* Requires KHR_stream extension */
|
||||
#ifndef EGL_KHR_stream_fifo
|
||||
#define EGL_KHR_stream_fifo 1
|
||||
/* reuse EGLTimeKHR */
|
||||
#define EGL_STREAM_FIFO_LENGTH_KHR 0x31FC
|
||||
#define EGL_STREAM_TIME_NOW_KHR 0x31FD
|
||||
#define EGL_STREAM_TIME_CONSUMER_KHR 0x31FE
|
||||
#define EGL_STREAM_TIME_PRODUCER_KHR 0x31FF
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamTimeKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef EGL_EXT_create_context_robustness
|
||||
#define EGL_EXT_create_context_robustness 1
|
||||
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF
|
||||
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
|
||||
#define EGL_NO_RESET_NOTIFICATION_EXT 0x31BE
|
||||
#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF
|
||||
#endif
|
||||
|
||||
#ifndef EGL_ANGLE_d3d_share_handle_client_buffer
|
||||
#define EGL_ANGLE_d3d_share_handle_client_buffer 1
|
||||
/* reuse EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE */
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_create_context
|
||||
#define EGL_KHR_create_context 1
|
||||
#define EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION
|
||||
#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB
|
||||
#define EGL_CONTEXT_FLAGS_KHR 0x30FC
|
||||
#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD
|
||||
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD
|
||||
#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE
|
||||
#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF
|
||||
#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
|
||||
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
|
||||
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
|
||||
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
|
||||
#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
|
||||
#define EGL_OPENGL_ES3_BIT_KHR 0x00000040
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_surfaceless_context
|
||||
#define EGL_KHR_surfaceless_context 1
|
||||
/* No tokens/entry points, just relaxes an error condition */
|
||||
#endif
|
||||
|
||||
#ifdef EGL_KHR_stream /* Requires KHR_stream extension */
|
||||
#ifndef EGL_KHR_stream_cross_process_fd
|
||||
#define EGL_KHR_stream_cross_process_fd 1
|
||||
typedef int EGLNativeFileDescriptorKHR;
|
||||
#define EGL_NO_FILE_DESCRIPTOR_KHR ((EGLNativeFileDescriptorKHR)(-1))
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLNativeFileDescriptorKHR EGLAPIENTRY eglGetStreamFileDescriptorKHR(EGLDisplay dpy, EGLStreamKHR stream);
|
||||
EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamFromFileDescriptorKHR(EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream);
|
||||
typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC)(EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef EGL_EXT_multiview_window
|
||||
#define EGL_EXT_multiview_window 1
|
||||
#define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_wait_sync
|
||||
#define EGL_KHR_wait_sync 1
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
|
||||
#endif /* EGL_EGLEXT_PROTOTYPES */
|
||||
typedef EGLint (EGLAPIENTRYP PFNEGLWAITSYNCKHRPROC)(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,127 @@
|
||||
#ifndef __eglplatform_h_
|
||||
#define __eglplatform_h_
|
||||
|
||||
/*
|
||||
** Copyright (c) 2007-2009 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.
|
||||
*/
|
||||
|
||||
/* Platform-specific types and definitions for egl.h
|
||||
* $Revision: 12306 $ on $Date: 2010-08-25 09:51:28 -0700 (Wed, 25 Aug 2010) $
|
||||
*
|
||||
* Adopters may modify khrplatform.h and this file to suit their platform.
|
||||
* You are encouraged to submit all modifications to the Khronos group so that
|
||||
* they can be included in future versions of this file. Please submit changes
|
||||
* by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla)
|
||||
* by filing a bug against product "EGL" component "Registry".
|
||||
*/
|
||||
|
||||
#include <KHR/khrplatform.h>
|
||||
|
||||
/* Macros used in EGL function prototype declarations.
|
||||
*
|
||||
* EGL functions should be prototyped as:
|
||||
*
|
||||
* EGLAPI return-type EGLAPIENTRY eglFunction(arguments);
|
||||
* typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments);
|
||||
*
|
||||
* KHRONOS_APICALL and KHRONOS_APIENTRY are defined in KHR/khrplatform.h
|
||||
*/
|
||||
|
||||
#ifndef EGLAPI
|
||||
#define EGLAPI KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
#ifndef EGLAPIENTRY
|
||||
#define EGLAPIENTRY KHRONOS_APIENTRY
|
||||
#endif
|
||||
#define EGLAPIENTRYP EGLAPIENTRY*
|
||||
|
||||
/* The types NativeDisplayType, NativeWindowType, and NativePixmapType
|
||||
* are aliases of window-system-dependent types, such as X Display * or
|
||||
* Windows Device Context. They must be defined in platform-specific
|
||||
* code below. The EGL-prefixed versions of Native*Type are the same
|
||||
* types, renamed in EGL 1.3 so all types in the API start with "EGL".
|
||||
*
|
||||
* Khronos STRONGLY RECOMMENDS that you use the default definitions
|
||||
* provided below, since these changes affect both binary and source
|
||||
* portability of applications using EGL running on different EGL
|
||||
* implementations.
|
||||
*/
|
||||
|
||||
#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
typedef HDC EGLNativeDisplayType;
|
||||
typedef HBITMAP EGLNativePixmapType;
|
||||
typedef HWND EGLNativeWindowType;
|
||||
|
||||
#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
|
||||
|
||||
typedef int EGLNativeDisplayType;
|
||||
typedef void *EGLNativeWindowType;
|
||||
typedef void *EGLNativePixmapType;
|
||||
|
||||
#elif defined(__unix__) && !defined(ANDROID)
|
||||
|
||||
/* X11 (tentative) */
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
typedef Display *EGLNativeDisplayType;
|
||||
typedef Pixmap EGLNativePixmapType;
|
||||
typedef Window EGLNativeWindowType;
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
typedef int EGLNativeDisplayType;
|
||||
typedef void *EGLNativePixmapType;
|
||||
typedef void *EGLNativeWindowType;
|
||||
|
||||
#elif defined(ANDROID)
|
||||
|
||||
typedef int EGLNativeDisplayType;
|
||||
typedef void *EGLNativeWindowType;
|
||||
typedef void *EGLNativePixmapType;
|
||||
|
||||
#else
|
||||
#error "Platform not recognized"
|
||||
#endif
|
||||
|
||||
/* EGL 1.2 types, renamed for consistency in EGL 1.3 */
|
||||
typedef EGLNativeDisplayType NativeDisplayType;
|
||||
typedef EGLNativePixmapType NativePixmapType;
|
||||
typedef EGLNativeWindowType NativeWindowType;
|
||||
|
||||
|
||||
/* Define EGLint. This must be a signed integral type large enough to contain
|
||||
* all legal attribute names and values passed into and out of EGL, whether
|
||||
* their type is boolean, bitmask, enumerant (symbolic constant), integer,
|
||||
* handle, or other. While in general a 32-bit integer will suffice, if
|
||||
* handles are 64 bit types, then EGLint should be defined as a signed 64-bit
|
||||
* integer type.
|
||||
*/
|
||||
typedef khronos_int32_t EGLint;
|
||||
|
||||
#endif /* __eglplatform_h */
|
||||
+2103
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+12899
File diff suppressed because it is too large
Load Diff
+1808
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,27 @@
|
||||
#ifndef __gl3platform_h_
|
||||
#define __gl3platform_h_
|
||||
|
||||
/*
|
||||
** Copyright 2017-2020 The Khronos Group Inc.
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/* Platform-specific types and definitions for OpenGL ES 3.X gl3.h
|
||||
*
|
||||
* Adopters may modify khrplatform.h and this file to suit their platform.
|
||||
* Please contribute modifications back to Khronos as pull requests on the
|
||||
* public github repository:
|
||||
* https://github.com/KhronosGroup/OpenGL-Registry
|
||||
*/
|
||||
|
||||
#include <KHR/khrplatform.h>
|
||||
|
||||
#ifndef GL_APICALL
|
||||
#define GL_APICALL KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
#ifndef GL_APIENTRY
|
||||
#define GL_APIENTRY KHRONOS_APIENTRY
|
||||
#endif
|
||||
|
||||
#endif /* __gl3platform_h_ */
|
||||
@@ -0,0 +1,269 @@
|
||||
#ifndef __khrplatform_h_
|
||||
#define __khrplatform_h_
|
||||
|
||||
/*
|
||||
** Copyright (c) 2008-2009 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.
|
||||
*/
|
||||
|
||||
/* Khronos platform-specific types and definitions.
|
||||
*
|
||||
* $Revision: 9356 $ on $Date: 2009-10-21 02:52:25 -0700 (Wed, 21 Oct 2009) $
|
||||
*
|
||||
* Adopters may modify this file to suit their platform. Adopters are
|
||||
* encouraged to submit platform specific modifications to the Khronos
|
||||
* group so that they can be included in future versions of this file.
|
||||
* Please submit changes by sending them to the public Khronos Bugzilla
|
||||
* (http://khronos.org/bugzilla) by filing a bug against product
|
||||
* "Khronos (general)" component "Registry".
|
||||
*
|
||||
* A predefined template which fills in some of the bug fields can be
|
||||
* reached using http://tinyurl.com/khrplatform-h-bugreport, but you
|
||||
* must create a Bugzilla login first.
|
||||
*
|
||||
*
|
||||
* See the Implementer's Guidelines for information about where this file
|
||||
* should be located on your system and for more details of its use:
|
||||
* http://www.khronos.org/registry/implementers_guide.pdf
|
||||
*
|
||||
* This file should be included as
|
||||
* #include <KHR/khrplatform.h>
|
||||
* by Khronos client API header files that use its types and defines.
|
||||
*
|
||||
* The types in khrplatform.h should only be used to define API-specific types.
|
||||
*
|
||||
* Types defined in khrplatform.h:
|
||||
* khronos_int8_t signed 8 bit
|
||||
* khronos_uint8_t unsigned 8 bit
|
||||
* khronos_int16_t signed 16 bit
|
||||
* khronos_uint16_t unsigned 16 bit
|
||||
* khronos_int32_t signed 32 bit
|
||||
* khronos_uint32_t unsigned 32 bit
|
||||
* khronos_int64_t signed 64 bit
|
||||
* khronos_uint64_t unsigned 64 bit
|
||||
* khronos_intptr_t signed same number of bits as a pointer
|
||||
* khronos_uintptr_t unsigned same number of bits as a pointer
|
||||
* khronos_ssize_t signed size
|
||||
* khronos_usize_t unsigned size
|
||||
* khronos_float_t signed 32 bit floating point
|
||||
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
||||
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
||||
* nanoseconds
|
||||
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
||||
* khronos_boolean_enum_t enumerated boolean type. This should
|
||||
* only be used as a base type when a client API's boolean type is
|
||||
* an enum. Client APIs which use an integer or other type for
|
||||
* booleans cannot use this as the base type for their boolean.
|
||||
*
|
||||
* Tokens defined in khrplatform.h:
|
||||
*
|
||||
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
||||
*
|
||||
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
||||
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
||||
*
|
||||
* Calling convention macros defined in this file:
|
||||
* KHRONOS_APICALL
|
||||
* KHRONOS_APIENTRY
|
||||
* KHRONOS_APIATTRIBUTES
|
||||
*
|
||||
* These may be used in function prototypes as:
|
||||
*
|
||||
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
||||
* int arg1,
|
||||
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APICALL
|
||||
*-------------------------------------------------------------------------
|
||||
* This precedes the return type of the function in the function prototype.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||
# define KHRONOS_APICALL __declspec(dllimport)
|
||||
#elif defined (__SYMBIAN32__)
|
||||
# define KHRONOS_APICALL IMPORT_C
|
||||
#else
|
||||
# define KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIENTRY
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the return type of the function and precedes the function
|
||||
* name in the function prototype.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
||||
/* Win32 but not WinCE */
|
||||
# define KHRONOS_APIENTRY __stdcall
|
||||
#else
|
||||
# define KHRONOS_APIENTRY
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIATTRIBUTES
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the closing parenthesis of the function prototype arguments.
|
||||
*/
|
||||
#if defined (__ARMCC_2__)
|
||||
#define KHRONOS_APIATTRIBUTES __softfp
|
||||
#else
|
||||
#define KHRONOS_APIATTRIBUTES
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* basic type definitions
|
||||
*-----------------------------------------------------------------------*/
|
||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
||||
|
||||
|
||||
/*
|
||||
* Using <stdint.h>
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__VMS ) || defined(__sgi)
|
||||
|
||||
/*
|
||||
* Using <inttypes.h>
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||
|
||||
/*
|
||||
* Win32
|
||||
*/
|
||||
typedef __int32 khronos_int32_t;
|
||||
typedef unsigned __int32 khronos_uint32_t;
|
||||
typedef __int64 khronos_int64_t;
|
||||
typedef unsigned __int64 khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__sun__) || defined(__digital__)
|
||||
|
||||
/*
|
||||
* Sun or Digital
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#if defined(__arch64__) || defined(_LP64)
|
||||
typedef long int khronos_int64_t;
|
||||
typedef unsigned long int khronos_uint64_t;
|
||||
#else
|
||||
typedef long long int khronos_int64_t;
|
||||
typedef unsigned long long int khronos_uint64_t;
|
||||
#endif /* __arch64__ */
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif 0
|
||||
|
||||
/*
|
||||
* Hypothetical platform with no float or int64 support
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#define KHRONOS_SUPPORT_INT64 0
|
||||
#define KHRONOS_SUPPORT_FLOAT 0
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Generic fallback
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Types that are (so far) the same on all platforms
|
||||
*/
|
||||
typedef signed char khronos_int8_t;
|
||||
typedef unsigned char khronos_uint8_t;
|
||||
typedef signed short int khronos_int16_t;
|
||||
typedef unsigned short int khronos_uint16_t;
|
||||
typedef signed long int khronos_intptr_t;
|
||||
typedef unsigned long int khronos_uintptr_t;
|
||||
typedef signed long int khronos_ssize_t;
|
||||
typedef unsigned long int khronos_usize_t;
|
||||
|
||||
#if KHRONOS_SUPPORT_FLOAT
|
||||
/*
|
||||
* Float type
|
||||
*/
|
||||
typedef float khronos_float_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64
|
||||
/* Time types
|
||||
*
|
||||
* These types can be used to represent a time interval in nanoseconds or
|
||||
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
||||
* of nanoseconds since some arbitrary system event (e.g. since the last
|
||||
* time the system booted). The Unadjusted System Time is an unsigned
|
||||
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
||||
* may be either signed or unsigned.
|
||||
*/
|
||||
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
||||
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dummy value used to pad enum types to 32 bits.
|
||||
*/
|
||||
#ifndef KHRONOS_MAX_ENUM
|
||||
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enumerated boolean type
|
||||
*
|
||||
* Values other than zero should be considered to be true. Therefore
|
||||
* comparisons should not be made against KHRONOS_TRUE.
|
||||
*/
|
||||
typedef enum {
|
||||
KHRONOS_FALSE = 0,
|
||||
KHRONOS_TRUE = 1,
|
||||
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
||||
} khronos_boolean_enum_t;
|
||||
|
||||
#endif /* __khrplatform_h_ */
|
||||
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
This code is based on the glslang_c_interface implementation by Viktor Latypov
|
||||
**/
|
||||
|
||||
/**
|
||||
BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2019, Viktor Latypov
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**/
|
||||
|
||||
#include "glslang/Include/glslang_c_interface.h"
|
||||
|
||||
#include <cstring>
|
||||
#include "glslang/Public/ShaderLang.h"
|
||||
#include "SPIRV/GlslangToSpv.h"
|
||||
#include "SPIRV/Logger.h"
|
||||
#include "SPIRV/SpvTools.h"
|
||||
|
||||
static_assert(sizeof(glslang_spv_options_t) == sizeof(glslang::SpvOptions), "");
|
||||
|
||||
typedef struct glslang_program_s {
|
||||
glslang::TProgram* program;
|
||||
std::vector<unsigned int> spirv;
|
||||
std::string loggerMessages;
|
||||
} glslang_program_t;
|
||||
|
||||
static EShLanguage c_shader_stage(glslang_stage_t stage)
|
||||
{
|
||||
switch (stage) {
|
||||
case GLSLANG_STAGE_VERTEX:
|
||||
return EShLangVertex;
|
||||
case GLSLANG_STAGE_TESSCONTROL:
|
||||
return EShLangTessControl;
|
||||
case GLSLANG_STAGE_TESSEVALUATION:
|
||||
return EShLangTessEvaluation;
|
||||
case GLSLANG_STAGE_GEOMETRY:
|
||||
return EShLangGeometry;
|
||||
case GLSLANG_STAGE_FRAGMENT:
|
||||
return EShLangFragment;
|
||||
case GLSLANG_STAGE_COMPUTE:
|
||||
return EShLangCompute;
|
||||
case GLSLANG_STAGE_RAYGEN:
|
||||
return EShLangRayGen;
|
||||
case GLSLANG_STAGE_INTERSECT:
|
||||
return EShLangIntersect;
|
||||
case GLSLANG_STAGE_ANYHIT:
|
||||
return EShLangAnyHit;
|
||||
case GLSLANG_STAGE_CLOSESTHIT:
|
||||
return EShLangClosestHit;
|
||||
case GLSLANG_STAGE_MISS:
|
||||
return EShLangMiss;
|
||||
case GLSLANG_STAGE_CALLABLE:
|
||||
return EShLangCallable;
|
||||
case GLSLANG_STAGE_TASK:
|
||||
return EShLangTask;
|
||||
case GLSLANG_STAGE_MESH:
|
||||
return EShLangMesh;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return EShLangCount;
|
||||
}
|
||||
|
||||
GLSLANG_EXPORT void glslang_program_SPIRV_generate(glslang_program_t* program, glslang_stage_t stage)
|
||||
{
|
||||
glslang_spv_options_t spv_options {};
|
||||
spv_options.disable_optimizer = true;
|
||||
spv_options.validate = true;
|
||||
|
||||
glslang_program_SPIRV_generate_with_options(program, stage, &spv_options);
|
||||
}
|
||||
|
||||
GLSLANG_EXPORT void glslang_program_SPIRV_generate_with_options(glslang_program_t* program, glslang_stage_t stage, glslang_spv_options_t* spv_options) {
|
||||
spv::SpvBuildLogger logger;
|
||||
|
||||
const glslang::TIntermediate* intermediate = program->program->getIntermediate(c_shader_stage(stage));
|
||||
|
||||
program->spirv.clear();
|
||||
|
||||
glslang::GlslangToSpv(*intermediate, program->spirv, &logger, reinterpret_cast<glslang::SpvOptions*>(spv_options));
|
||||
|
||||
program->loggerMessages = logger.getAllMessages();
|
||||
}
|
||||
|
||||
GLSLANG_EXPORT size_t glslang_program_SPIRV_get_size(glslang_program_t* program) { return program->spirv.size(); }
|
||||
|
||||
GLSLANG_EXPORT void glslang_program_SPIRV_get(glslang_program_t* program, unsigned int* out)
|
||||
{
|
||||
memcpy(out, program->spirv.data(), program->spirv.size() * sizeof(unsigned int));
|
||||
}
|
||||
|
||||
GLSLANG_EXPORT unsigned int* glslang_program_SPIRV_get_ptr(glslang_program_t* program)
|
||||
{
|
||||
return program->spirv.data();
|
||||
}
|
||||
|
||||
GLSLANG_EXPORT const char* glslang_program_SPIRV_get_messages(glslang_program_t* program)
|
||||
{
|
||||
return program->loggerMessages.empty() ? nullptr : program->loggerMessages.c_str();
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
# Copyright (C) 2020 The Khronos Group Inc.
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
#
|
||||
# Neither the name of The Khronos Group Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
set(SPIRV_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GlslangToSpv.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/InReadableOrder.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Logger.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/SpvBuilder.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/SpvPostProcess.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/doc.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/SpvTools.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/disassemble.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CInterface/spirv_c_interface.cpp
|
||||
PARENT_SCOPE)
|
||||
|
||||
set(SPVREMAP_SOURCES
|
||||
SPVRemapper.cpp
|
||||
doc.cpp)
|
||||
|
||||
set(SPIRV_HEADERS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/bitutils.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GLSL.std.450.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GLSL.ext.EXT.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GLSL.ext.KHR.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GlslangToSpv.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hex_float.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Logger.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/SpvBuilder.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spvIR.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/doc.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/SpvTools.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/disassemble.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GLSL.ext.AMD.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GLSL.ext.NV.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GLSL.ext.ARM.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GLSL.ext.QCOM.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/NonSemanticDebugPrintf.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/NonSemanticShaderDebugInfo100.h
|
||||
PARENT_SCOPE)
|
||||
|
||||
set(SPVREMAP_HEADERS
|
||||
SPVRemapper.h
|
||||
doc.h)
|
||||
|
||||
set(PUBLIC_HEADERS
|
||||
GlslangToSpv.h
|
||||
disassemble.h
|
||||
Logger.h
|
||||
spirv.hpp
|
||||
SPVRemapper.h
|
||||
SpvTools.h)
|
||||
|
||||
add_library(SPIRV ${LIB_TYPE} ${CMAKE_CURRENT_SOURCE_DIR}/../glslang/stub.cpp)
|
||||
add_library(glslang::SPIRV ALIAS SPIRV)
|
||||
set_target_properties(SPIRV PROPERTIES
|
||||
FOLDER glslang
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
VERSION "${GLSLANG_VERSION}"
|
||||
SOVERSION "${GLSLANG_VERSION_MAJOR}")
|
||||
target_include_directories(SPIRV PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
||||
|
||||
if (ENABLE_SPVREMAPPER)
|
||||
add_library(SPVRemapper ${LIB_TYPE} ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS})
|
||||
add_library(glslang::SPVRemapper ALIAS SPVRemapper)
|
||||
set_target_properties(SPVRemapper PROPERTIES
|
||||
FOLDER glslang
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
VERSION "${GLSLANG_VERSION}"
|
||||
SOVERSION "${GLSLANG_VERSION_MAJOR}")
|
||||
glslang_only_export_explicit_symbols(SPVRemapper)
|
||||
endif()
|
||||
|
||||
if(WIN32 AND BUILD_SHARED_LIBS)
|
||||
set_target_properties(SPIRV PROPERTIES PREFIX "")
|
||||
if (ENABLE_SPVREMAPPER)
|
||||
set_target_properties(SPVRemapper PROPERTIES PREFIX "")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_OPT)
|
||||
target_link_libraries(SPIRV PRIVATE glslang PUBLIC SPIRV-Tools-opt)
|
||||
target_include_directories(SPIRV PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../External>)
|
||||
else()
|
||||
target_link_libraries(SPIRV PRIVATE glslang)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
source_group("Source" FILES ${SOURCES} ${HEADERS})
|
||||
source_group("Source" FILES ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS})
|
||||
endif()
|
||||
|
||||
if(GLSLANG_ENABLE_INSTALL)
|
||||
if (ENABLE_SPVREMAPPER)
|
||||
install(TARGETS SPVRemapper EXPORT glslang-targets)
|
||||
endif()
|
||||
|
||||
install(TARGETS SPIRV EXPORT glslang-targets)
|
||||
|
||||
install(FILES ${PUBLIC_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/glslang/SPIRV/)
|
||||
endif()
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
** 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 GLSLextAMD_H
|
||||
#define GLSLextAMD_H
|
||||
|
||||
static const int GLSLextAMDVersion = 100;
|
||||
static const int GLSLextAMDRevision = 7;
|
||||
|
||||
// SPV_AMD_shader_ballot
|
||||
static const char* const E_SPV_AMD_shader_ballot = "SPV_AMD_shader_ballot";
|
||||
|
||||
enum ShaderBallotAMD {
|
||||
ShaderBallotBadAMD = 0, // Don't use
|
||||
|
||||
SwizzleInvocationsAMD = 1,
|
||||
SwizzleInvocationsMaskedAMD = 2,
|
||||
WriteInvocationAMD = 3,
|
||||
MbcntAMD = 4,
|
||||
|
||||
ShaderBallotCountAMD
|
||||
};
|
||||
|
||||
// SPV_AMD_shader_trinary_minmax
|
||||
static const char* const E_SPV_AMD_shader_trinary_minmax = "SPV_AMD_shader_trinary_minmax";
|
||||
|
||||
enum ShaderTrinaryMinMaxAMD {
|
||||
ShaderTrinaryMinMaxBadAMD = 0, // Don't use
|
||||
|
||||
FMin3AMD = 1,
|
||||
UMin3AMD = 2,
|
||||
SMin3AMD = 3,
|
||||
FMax3AMD = 4,
|
||||
UMax3AMD = 5,
|
||||
SMax3AMD = 6,
|
||||
FMid3AMD = 7,
|
||||
UMid3AMD = 8,
|
||||
SMid3AMD = 9,
|
||||
|
||||
ShaderTrinaryMinMaxCountAMD
|
||||
};
|
||||
|
||||
// SPV_AMD_shader_explicit_vertex_parameter
|
||||
static const char* const E_SPV_AMD_shader_explicit_vertex_parameter = "SPV_AMD_shader_explicit_vertex_parameter";
|
||||
|
||||
enum ShaderExplicitVertexParameterAMD {
|
||||
ShaderExplicitVertexParameterBadAMD = 0, // Don't use
|
||||
|
||||
InterpolateAtVertexAMD = 1,
|
||||
|
||||
ShaderExplicitVertexParameterCountAMD
|
||||
};
|
||||
|
||||
// SPV_AMD_gcn_shader
|
||||
static const char* const E_SPV_AMD_gcn_shader = "SPV_AMD_gcn_shader";
|
||||
|
||||
enum GcnShaderAMD {
|
||||
GcnShaderBadAMD = 0, // Don't use
|
||||
|
||||
CubeFaceIndexAMD = 1,
|
||||
CubeFaceCoordAMD = 2,
|
||||
TimeAMD = 3,
|
||||
|
||||
GcnShaderCountAMD
|
||||
};
|
||||
|
||||
// SPV_AMD_gpu_shader_half_float
|
||||
static const char* const E_SPV_AMD_gpu_shader_half_float = "SPV_AMD_gpu_shader_half_float";
|
||||
|
||||
// SPV_AMD_texture_gather_bias_lod
|
||||
static const char* const E_SPV_AMD_texture_gather_bias_lod = "SPV_AMD_texture_gather_bias_lod";
|
||||
|
||||
// SPV_AMD_gpu_shader_int16
|
||||
static const char* const E_SPV_AMD_gpu_shader_int16 = "SPV_AMD_gpu_shader_int16";
|
||||
|
||||
// SPV_AMD_shader_image_load_store_lod
|
||||
static const char* const E_SPV_AMD_shader_image_load_store_lod = "SPV_AMD_shader_image_load_store_lod";
|
||||
|
||||
// SPV_AMD_shader_fragment_mask
|
||||
static const char* const E_SPV_AMD_shader_fragment_mask = "SPV_AMD_shader_fragment_mask";
|
||||
|
||||
// SPV_AMD_gpu_shader_half_float_fetch
|
||||
static const char* const E_SPV_AMD_gpu_shader_half_float_fetch = "SPV_AMD_gpu_shader_half_float_fetch";
|
||||
|
||||
#endif // #ifndef GLSLextAMD_H
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
** Copyright (c) 2022 ARM Limited
|
||||
**
|
||||
** 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 GLSLextARM_H
|
||||
#define GLSLextARM_H
|
||||
|
||||
static const int GLSLextARMVersion = 100;
|
||||
static const int GLSLextARMRevision = 1;
|
||||
|
||||
static const char * const E_SPV_ARM_core_builtins = "SPV_ARM_core_builtins";
|
||||
|
||||
#endif // #ifndef GLSLextARM_H
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
** 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 GLSLextEXT_H
|
||||
#define GLSLextEXT_H
|
||||
|
||||
static const int GLSLextEXTVersion = 100;
|
||||
static const int GLSLextEXTRevision = 2;
|
||||
|
||||
static const char* const E_SPV_EXT_shader_stencil_export = "SPV_EXT_shader_stencil_export";
|
||||
static const char* const E_SPV_EXT_shader_viewport_index_layer = "SPV_EXT_shader_viewport_index_layer";
|
||||
static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fully_covered";
|
||||
static const char* const E_SPV_EXT_fragment_invocation_density = "SPV_EXT_fragment_invocation_density";
|
||||
static const char* const E_SPV_EXT_demote_to_helper_invocation = "SPV_EXT_demote_to_helper_invocation";
|
||||
static const char* const E_SPV_EXT_shader_atomic_float_add = "SPV_EXT_shader_atomic_float_add";
|
||||
static const char* const E_SPV_EXT_shader_atomic_float16_add = "SPV_EXT_shader_atomic_float16_add";
|
||||
static const char* const E_SPV_EXT_shader_atomic_float_min_max = "SPV_EXT_shader_atomic_float_min_max";
|
||||
static const char* const E_SPV_EXT_shader_image_int64 = "SPV_EXT_shader_image_int64";
|
||||
static const char* const E_SPV_EXT_shader_tile_image = "SPV_EXT_shader_tile_image";
|
||||
static const char* const E_SPV_EXT_mesh_shader = "SPV_EXT_mesh_shader";
|
||||
static const char* const E_SPV_ARM_cooperative_matrix_layouts = "SPV_ARM_cooperative_matrix_layouts";
|
||||
|
||||
#endif // #ifndef GLSLextEXT_H
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
** Copyright (c) 2014-2020 The Khronos Group Inc.
|
||||
** Copyright (C) 2022-2024 Arm Limited.
|
||||
** Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||
**
|
||||
** 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 GLSLextKHR_H
|
||||
#define GLSLextKHR_H
|
||||
|
||||
static const int GLSLextKHRVersion = 100;
|
||||
static const int GLSLextKHRRevision = 3;
|
||||
|
||||
static const char* const E_SPV_KHR_shader_ballot = "SPV_KHR_shader_ballot";
|
||||
static const char* const E_SPV_KHR_subgroup_vote = "SPV_KHR_subgroup_vote";
|
||||
static const char* const E_SPV_KHR_device_group = "SPV_KHR_device_group";
|
||||
static const char* const E_SPV_KHR_multiview = "SPV_KHR_multiview";
|
||||
static const char* const E_SPV_KHR_shader_draw_parameters = "SPV_KHR_shader_draw_parameters";
|
||||
static const char* const E_SPV_KHR_16bit_storage = "SPV_KHR_16bit_storage";
|
||||
static const char* const E_SPV_KHR_8bit_storage = "SPV_KHR_8bit_storage";
|
||||
static const char* const E_SPV_KHR_storage_buffer_storage_class = "SPV_KHR_storage_buffer_storage_class";
|
||||
static const char* const E_SPV_KHR_post_depth_coverage = "SPV_KHR_post_depth_coverage";
|
||||
static const char* const E_SPV_KHR_vulkan_memory_model = "SPV_KHR_vulkan_memory_model";
|
||||
static const char* const E_SPV_EXT_physical_storage_buffer = "SPV_EXT_physical_storage_buffer";
|
||||
static const char* const E_SPV_KHR_physical_storage_buffer = "SPV_KHR_physical_storage_buffer";
|
||||
static const char* const E_SPV_EXT_fragment_shader_interlock = "SPV_EXT_fragment_shader_interlock";
|
||||
static const char* const E_SPV_KHR_shader_clock = "SPV_KHR_shader_clock";
|
||||
static const char* const E_SPV_KHR_non_semantic_info = "SPV_KHR_non_semantic_info";
|
||||
static const char* const E_SPV_KHR_ray_tracing = "SPV_KHR_ray_tracing";
|
||||
static const char* const E_SPV_KHR_ray_query = "SPV_KHR_ray_query";
|
||||
static const char* const E_SPV_KHR_fragment_shading_rate = "SPV_KHR_fragment_shading_rate";
|
||||
static const char* const E_SPV_KHR_terminate_invocation = "SPV_KHR_terminate_invocation";
|
||||
static const char* const E_SPV_KHR_workgroup_memory_explicit_layout = "SPV_KHR_workgroup_memory_explicit_layout";
|
||||
static const char* const E_SPV_KHR_subgroup_uniform_control_flow = "SPV_KHR_subgroup_uniform_control_flow";
|
||||
static const char* const E_SPV_KHR_fragment_shader_barycentric = "SPV_KHR_fragment_shader_barycentric";
|
||||
static const char* const E_SPV_KHR_quad_control = "SPV_KHR_quad_control";
|
||||
static const char* const E_SPV_AMD_shader_early_and_late_fragment_tests = "SPV_AMD_shader_early_and_late_fragment_tests";
|
||||
static const char* const E_SPV_KHR_ray_tracing_position_fetch = "SPV_KHR_ray_tracing_position_fetch";
|
||||
static const char* const E_SPV_KHR_cooperative_matrix = "SPV_KHR_cooperative_matrix";
|
||||
static const char* const E_SPV_KHR_maximal_reconvergence = "SPV_KHR_maximal_reconvergence";
|
||||
static const char* const E_SPV_KHR_subgroup_rotate = "SPV_KHR_subgroup_rotate";
|
||||
static const char* const E_SPV_KHR_expect_assume = "SPV_KHR_expect_assume";
|
||||
static const char* const E_SPV_EXT_replicated_composites = "SPV_EXT_replicated_composites";
|
||||
static const char* const E_SPV_KHR_relaxed_extended_instruction = "SPV_KHR_relaxed_extended_instruction";
|
||||
|
||||
#endif // #ifndef GLSLextKHR_H
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
** Copyright (c) 2014-2017 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 GLSLextNV_H
|
||||
#define GLSLextNV_H
|
||||
|
||||
enum BuiltIn;
|
||||
enum Decoration;
|
||||
enum Op;
|
||||
enum Capability;
|
||||
|
||||
static const int GLSLextNVVersion = 100;
|
||||
static const int GLSLextNVRevision = 11;
|
||||
|
||||
//SPV_NV_sample_mask_override_coverage
|
||||
const char* const E_SPV_NV_sample_mask_override_coverage = "SPV_NV_sample_mask_override_coverage";
|
||||
|
||||
//SPV_NV_geometry_shader_passthrough
|
||||
const char* const E_SPV_NV_geometry_shader_passthrough = "SPV_NV_geometry_shader_passthrough";
|
||||
|
||||
//SPV_NV_viewport_array2
|
||||
const char* const E_SPV_NV_viewport_array2 = "SPV_NV_viewport_array2";
|
||||
const char* const E_ARB_shader_viewport_layer_array = "SPV_ARB_shader_viewport_layer_array";
|
||||
|
||||
//SPV_NV_stereo_view_rendering
|
||||
const char* const E_SPV_NV_stereo_view_rendering = "SPV_NV_stereo_view_rendering";
|
||||
|
||||
//SPV_NVX_multiview_per_view_attributes
|
||||
const char* const E_SPV_NVX_multiview_per_view_attributes = "SPV_NVX_multiview_per_view_attributes";
|
||||
|
||||
//SPV_NV_shader_subgroup_partitioned
|
||||
const char* const E_SPV_NV_shader_subgroup_partitioned = "SPV_NV_shader_subgroup_partitioned";
|
||||
|
||||
//SPV_NV_fragment_shader_barycentric
|
||||
const char* const E_SPV_NV_fragment_shader_barycentric = "SPV_NV_fragment_shader_barycentric";
|
||||
|
||||
//SPV_NV_compute_shader_derivatives
|
||||
const char* const E_SPV_NV_compute_shader_derivatives = "SPV_NV_compute_shader_derivatives";
|
||||
|
||||
//SPV_NV_shader_image_footprint
|
||||
const char* const E_SPV_NV_shader_image_footprint = "SPV_NV_shader_image_footprint";
|
||||
|
||||
//SPV_NV_mesh_shader
|
||||
const char* const E_SPV_NV_mesh_shader = "SPV_NV_mesh_shader";
|
||||
|
||||
//SPV_NV_raytracing
|
||||
const char* const E_SPV_NV_ray_tracing = "SPV_NV_ray_tracing";
|
||||
|
||||
//SPV_NV_ray_tracing_motion_blur
|
||||
const char* const E_SPV_NV_ray_tracing_motion_blur = "SPV_NV_ray_tracing_motion_blur";
|
||||
|
||||
//SPV_NV_shading_rate
|
||||
const char* const E_SPV_NV_shading_rate = "SPV_NV_shading_rate";
|
||||
|
||||
//SPV_NV_cooperative_matrix
|
||||
const char* const E_SPV_NV_cooperative_matrix = "SPV_NV_cooperative_matrix";
|
||||
|
||||
//SPV_NV_shader_sm_builtins
|
||||
const char* const E_SPV_NV_shader_sm_builtins = "SPV_NV_shader_sm_builtins";
|
||||
|
||||
//SPV_NV_shader_execution_reorder
|
||||
const char* const E_SPV_NV_shader_invocation_reorder = "SPV_NV_shader_invocation_reorder";
|
||||
|
||||
//SPV_NV_displacement_micromap
|
||||
const char* const E_SPV_NV_displacement_micromap = "SPV_NV_displacement_micromap";
|
||||
|
||||
//SPV_NV_shader_atomic_fp16_vector
|
||||
const char* const E_SPV_NV_shader_atomic_fp16_vector = "SPV_NV_shader_atomic_fp16_vector";
|
||||
|
||||
//SPV_NV_tensor_addressing
|
||||
const char* const E_SPV_NV_tensor_addressing = "SPV_NV_tensor_addressing";
|
||||
|
||||
//SPV_NV_cooperative_matrix2
|
||||
const char* const E_SPV_NV_cooperative_matrix2 = "SPV_NV_cooperative_matrix2";
|
||||
|
||||
#endif // #ifndef GLSLextNV_H
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
** Copyright (c) 2021 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 GLSLextQCOM_H
|
||||
#define GLSLextQCOM_H
|
||||
|
||||
enum BuiltIn;
|
||||
enum Decoration;
|
||||
enum Op;
|
||||
enum Capability;
|
||||
|
||||
static const int GLSLextQCOMVersion = 100;
|
||||
static const int GLSLextQCOMRevision = 1;
|
||||
|
||||
//SPV_QCOM_image_processing
|
||||
const char* const E_SPV_QCOM_image_processing = "SPV_QCOM_image_processing";
|
||||
//SPV_QCOM_image_processing2
|
||||
const char* const E_SPV_QCOM_image_processing2 = "SPV_QCOM_image_processing2";
|
||||
|
||||
#endif // #ifndef GLSLextQCOM_H
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
** 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_H
|
||||
#define GLSLstd450_H
|
||||
|
||||
static const int GLSLstd450Version = 100;
|
||||
static const int GLSLstd450Revision = 1;
|
||||
|
||||
enum GLSLstd450 {
|
||||
GLSLstd450Bad = 0, // Don't use
|
||||
|
||||
GLSLstd450Round = 1,
|
||||
GLSLstd450RoundEven = 2,
|
||||
GLSLstd450Trunc = 3,
|
||||
GLSLstd450FAbs = 4,
|
||||
GLSLstd450SAbs = 5,
|
||||
GLSLstd450FSign = 6,
|
||||
GLSLstd450SSign = 7,
|
||||
GLSLstd450Floor = 8,
|
||||
GLSLstd450Ceil = 9,
|
||||
GLSLstd450Fract = 10,
|
||||
|
||||
GLSLstd450Radians = 11,
|
||||
GLSLstd450Degrees = 12,
|
||||
GLSLstd450Sin = 13,
|
||||
GLSLstd450Cos = 14,
|
||||
GLSLstd450Tan = 15,
|
||||
GLSLstd450Asin = 16,
|
||||
GLSLstd450Acos = 17,
|
||||
GLSLstd450Atan = 18,
|
||||
GLSLstd450Sinh = 19,
|
||||
GLSLstd450Cosh = 20,
|
||||
GLSLstd450Tanh = 21,
|
||||
GLSLstd450Asinh = 22,
|
||||
GLSLstd450Acosh = 23,
|
||||
GLSLstd450Atanh = 24,
|
||||
GLSLstd450Atan2 = 25,
|
||||
|
||||
GLSLstd450Pow = 26,
|
||||
GLSLstd450Exp = 27,
|
||||
GLSLstd450Log = 28,
|
||||
GLSLstd450Exp2 = 29,
|
||||
GLSLstd450Log2 = 30,
|
||||
GLSLstd450Sqrt = 31,
|
||||
GLSLstd450InverseSqrt = 32,
|
||||
|
||||
GLSLstd450Determinant = 33,
|
||||
GLSLstd450MatrixInverse = 34,
|
||||
|
||||
GLSLstd450Modf = 35, // second operand needs an OpVariable to write to
|
||||
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,
|
||||
|
||||
GLSLstd450Fma = 50,
|
||||
GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to
|
||||
GLSLstd450FrexpStruct = 52, // no OpVariable operand
|
||||
GLSLstd450Ldexp = 53,
|
||||
|
||||
GLSLstd450PackSnorm4x8 = 54,
|
||||
GLSLstd450PackUnorm4x8 = 55,
|
||||
GLSLstd450PackSnorm2x16 = 56,
|
||||
GLSLstd450PackUnorm2x16 = 57,
|
||||
GLSLstd450PackHalf2x16 = 58,
|
||||
GLSLstd450PackDouble2x32 = 59,
|
||||
GLSLstd450UnpackSnorm2x16 = 60,
|
||||
GLSLstd450UnpackUnorm2x16 = 61,
|
||||
GLSLstd450UnpackHalf2x16 = 62,
|
||||
GLSLstd450UnpackSnorm4x8 = 63,
|
||||
GLSLstd450UnpackUnorm4x8 = 64,
|
||||
GLSLstd450UnpackDouble2x32 = 65,
|
||||
|
||||
GLSLstd450Length = 66,
|
||||
GLSLstd450Distance = 67,
|
||||
GLSLstd450Cross = 68,
|
||||
GLSLstd450Normalize = 69,
|
||||
GLSLstd450FaceForward = 70,
|
||||
GLSLstd450Reflect = 71,
|
||||
GLSLstd450Refract = 72,
|
||||
|
||||
GLSLstd450FindILsb = 73,
|
||||
GLSLstd450FindSMsb = 74,
|
||||
GLSLstd450FindUMsb = 75,
|
||||
|
||||
GLSLstd450InterpolateAtCentroid = 76,
|
||||
GLSLstd450InterpolateAtSample = 77,
|
||||
GLSLstd450InterpolateAtOffset = 78,
|
||||
|
||||
GLSLstd450NMin = 79,
|
||||
GLSLstd450NMax = 80,
|
||||
GLSLstd450NClamp = 81,
|
||||
|
||||
GLSLstd450Count
|
||||
};
|
||||
|
||||
#endif // #ifndef GLSLstd450_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// Copyright (C) 2014 LunarG, Inc.
|
||||
// Copyright (C) 2015-2018 Google, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Logger.h"
|
||||
#include "/Include/visibility.h"
|
||||
|
||||
namespace glslang {
|
||||
class TIntermediate;
|
||||
|
||||
struct SpvOptions {
|
||||
bool generateDebugInfo {false};
|
||||
bool stripDebugInfo {false};
|
||||
bool disableOptimizer {true};
|
||||
bool optimizeSize {false};
|
||||
bool disassemble {false};
|
||||
bool validate {false};
|
||||
bool emitNonSemanticShaderDebugInfo {false};
|
||||
bool emitNonSemanticShaderDebugSource{ false };
|
||||
bool compileOnly{false};
|
||||
bool optimizerAllowExpandedIDBound{false};
|
||||
};
|
||||
|
||||
GLSLANG_EXPORT void GetSpirvVersion(std::string&);
|
||||
GLSLANG_EXPORT int GetSpirvGeneratorVersion();
|
||||
GLSLANG_EXPORT void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||
SpvOptions* options = nullptr);
|
||||
GLSLANG_EXPORT void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||
spv::SpvBuildLogger* logger, SpvOptions* options = nullptr);
|
||||
GLSLANG_EXPORT bool OutputSpvBin(const std::vector<unsigned int>& spirv, const char* baseName);
|
||||
GLSLANG_EXPORT bool OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName, const char* varName);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
//
|
||||
// Copyright (C) 2016 Google, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// The SPIR-V spec requires code blocks to appear in an order satisfying the
|
||||
// dominator-tree direction (ie, dominator before the dominated). This is,
|
||||
// actually, easy to achieve: any pre-order CFG traversal algorithm will do it.
|
||||
// Because such algorithms visit a block only after traversing some path to it
|
||||
// from the root, they necessarily visit the block's idom first.
|
||||
//
|
||||
// But not every graph-traversal algorithm outputs blocks in an order that
|
||||
// appears logical to human readers. The problem is that unrelated branches may
|
||||
// be interspersed with each other, and merge blocks may come before some of the
|
||||
// branches being merged.
|
||||
//
|
||||
// A good, human-readable order of blocks may be achieved by performing
|
||||
// depth-first search but delaying merge nodes until after all their branches
|
||||
// have been visited. This is implemented below by the inReadableOrder()
|
||||
// function.
|
||||
|
||||
#include "spvIR.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <unordered_set>
|
||||
|
||||
using spv::Block;
|
||||
using spv::Id;
|
||||
|
||||
namespace {
|
||||
// Traverses CFG in a readable order, invoking a pre-set callback on each block.
|
||||
// Use by calling visit() on the root block.
|
||||
class ReadableOrderTraverser {
|
||||
public:
|
||||
ReadableOrderTraverser(std::function<void(Block*, spv::ReachReason, Block*)> callback)
|
||||
: callback_(callback) {}
|
||||
// Visits the block if it hasn't been visited already and isn't currently
|
||||
// being delayed. Invokes callback(block, why, header), then descends into its
|
||||
// successors. Delays merge-block and continue-block processing until all
|
||||
// the branches have been completed. If |block| is an unreachable merge block or
|
||||
// an unreachable continue target, then |header| is the corresponding header block.
|
||||
void visit(Block* block, spv::ReachReason why, Block* header)
|
||||
{
|
||||
assert(block);
|
||||
if (why == spv::ReachViaControlFlow) {
|
||||
reachableViaControlFlow_.insert(block);
|
||||
}
|
||||
if (visited_.count(block) || delayed_.count(block))
|
||||
return;
|
||||
callback_(block, why, header);
|
||||
visited_.insert(block);
|
||||
Block* mergeBlock = nullptr;
|
||||
Block* continueBlock = nullptr;
|
||||
auto mergeInst = block->getMergeInstruction();
|
||||
if (mergeInst) {
|
||||
Id mergeId = mergeInst->getIdOperand(0);
|
||||
mergeBlock = block->getParent().getParent().getInstruction(mergeId)->getBlock();
|
||||
delayed_.insert(mergeBlock);
|
||||
if (mergeInst->getOpCode() == spv::OpLoopMerge) {
|
||||
Id continueId = mergeInst->getIdOperand(1);
|
||||
continueBlock =
|
||||
block->getParent().getParent().getInstruction(continueId)->getBlock();
|
||||
delayed_.insert(continueBlock);
|
||||
}
|
||||
}
|
||||
if (why == spv::ReachViaControlFlow) {
|
||||
const auto& successors = block->getSuccessors();
|
||||
for (auto it = successors.cbegin(); it != successors.cend(); ++it)
|
||||
visit(*it, why, nullptr);
|
||||
}
|
||||
if (continueBlock) {
|
||||
const spv::ReachReason continueWhy =
|
||||
(reachableViaControlFlow_.count(continueBlock) > 0)
|
||||
? spv::ReachViaControlFlow
|
||||
: spv::ReachDeadContinue;
|
||||
delayed_.erase(continueBlock);
|
||||
visit(continueBlock, continueWhy, block);
|
||||
}
|
||||
if (mergeBlock) {
|
||||
const spv::ReachReason mergeWhy =
|
||||
(reachableViaControlFlow_.count(mergeBlock) > 0)
|
||||
? spv::ReachViaControlFlow
|
||||
: spv::ReachDeadMerge;
|
||||
delayed_.erase(mergeBlock);
|
||||
visit(mergeBlock, mergeWhy, block);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<void(Block*, spv::ReachReason, Block*)> callback_;
|
||||
// Whether a block has already been visited or is being delayed.
|
||||
std::unordered_set<Block *> visited_, delayed_;
|
||||
|
||||
// The set of blocks that actually are reached via control flow.
|
||||
std::unordered_set<Block *> reachableViaControlFlow_;
|
||||
};
|
||||
}
|
||||
|
||||
void spv::inReadableOrder(Block* root, std::function<void(Block*, spv::ReachReason, Block*)> callback)
|
||||
{
|
||||
ReadableOrderTraverser(callback).visit(root, spv::ReachViaControlFlow, nullptr);
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// Copyright (C) 2016 Google, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "Logger.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
|
||||
namespace spv {
|
||||
|
||||
void SpvBuildLogger::tbdFunctionality(const std::string& f)
|
||||
{
|
||||
if (std::find(std::begin(tbdFeatures), std::end(tbdFeatures), f) == std::end(tbdFeatures))
|
||||
tbdFeatures.push_back(f);
|
||||
}
|
||||
|
||||
void SpvBuildLogger::missingFunctionality(const std::string& f)
|
||||
{
|
||||
if (std::find(std::begin(missingFeatures), std::end(missingFeatures), f) == std::end(missingFeatures))
|
||||
missingFeatures.push_back(f);
|
||||
}
|
||||
|
||||
std::string SpvBuildLogger::getAllMessages() const {
|
||||
std::ostringstream messages;
|
||||
for (auto it = tbdFeatures.cbegin(); it != tbdFeatures.cend(); ++it)
|
||||
messages << "TBD functionality: " << *it << "\n";
|
||||
for (auto it = missingFeatures.cbegin(); it != missingFeatures.cend(); ++it)
|
||||
messages << "Missing functionality: " << *it << "\n";
|
||||
for (auto it = warnings.cbegin(); it != warnings.cend(); ++it)
|
||||
messages << "warning: " << *it << "\n";
|
||||
for (auto it = errors.cbegin(); it != errors.cend(); ++it)
|
||||
messages << "error: " << *it << "\n";
|
||||
return messages.str();
|
||||
}
|
||||
|
||||
} // end spv namespace
|
||||
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// Copyright (C) 2016 Google, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef GLSLANG_SPIRV_LOGGER_H
|
||||
#define GLSLANG_SPIRV_LOGGER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "/Include/visibility.h"
|
||||
|
||||
namespace spv {
|
||||
|
||||
// A class for holding all SPIR-V build status messages, including
|
||||
// missing/TBD functionalities, warnings, and errors.
|
||||
class GLSLANG_EXPORT SpvBuildLogger {
|
||||
public:
|
||||
SpvBuildLogger() {}
|
||||
|
||||
// Registers a TBD functionality.
|
||||
void tbdFunctionality(const std::string& f);
|
||||
// Registers a missing functionality.
|
||||
void missingFunctionality(const std::string& f);
|
||||
|
||||
// Logs a warning.
|
||||
void warning(const std::string& w) { warnings.push_back(w); }
|
||||
// Logs an error.
|
||||
void error(const std::string& e) { errors.push_back(e); }
|
||||
|
||||
// Returns all messages accumulated in the order of:
|
||||
// TBD functionalities, missing functionalities, warnings, errors.
|
||||
std::string getAllMessages() const;
|
||||
|
||||
private:
|
||||
SpvBuildLogger(const SpvBuildLogger&);
|
||||
|
||||
std::vector<std::string> tbdFeatures;
|
||||
std::vector<std::string> missingFeatures;
|
||||
std::vector<std::string> warnings;
|
||||
std::vector<std::string> errors;
|
||||
};
|
||||
|
||||
} // end spv namespace
|
||||
|
||||
#endif // GLSLANG_SPIRV_LOGGER_H
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright (c) 2020 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 SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_
|
||||
#define SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
NonSemanticDebugPrintfRevision = 1,
|
||||
NonSemanticDebugPrintfRevision_BitWidthPadding = 0x7fffffff
|
||||
};
|
||||
|
||||
enum NonSemanticDebugPrintfInstructions {
|
||||
NonSemanticDebugPrintfDebugPrintf = 1,
|
||||
NonSemanticDebugPrintfInstructionsMax = 0x7fffffff
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_
|
||||
@@ -0,0 +1,171 @@
|
||||
// Copyright (c) 2018 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 SPIRV_UNIFIED1_NonSemanticShaderDebugInfo100_H_
|
||||
#define SPIRV_UNIFIED1_NonSemanticShaderDebugInfo100_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
NonSemanticShaderDebugInfo100Version = 100,
|
||||
NonSemanticShaderDebugInfo100Version_BitWidthPadding = 0x7fffffff
|
||||
};
|
||||
enum {
|
||||
NonSemanticShaderDebugInfo100Revision = 6,
|
||||
NonSemanticShaderDebugInfo100Revision_BitWidthPadding = 0x7fffffff
|
||||
};
|
||||
|
||||
enum NonSemanticShaderDebugInfo100Instructions {
|
||||
NonSemanticShaderDebugInfo100DebugInfoNone = 0,
|
||||
NonSemanticShaderDebugInfo100DebugCompilationUnit = 1,
|
||||
NonSemanticShaderDebugInfo100DebugTypeBasic = 2,
|
||||
NonSemanticShaderDebugInfo100DebugTypePointer = 3,
|
||||
NonSemanticShaderDebugInfo100DebugTypeQualifier = 4,
|
||||
NonSemanticShaderDebugInfo100DebugTypeArray = 5,
|
||||
NonSemanticShaderDebugInfo100DebugTypeVector = 6,
|
||||
NonSemanticShaderDebugInfo100DebugTypedef = 7,
|
||||
NonSemanticShaderDebugInfo100DebugTypeFunction = 8,
|
||||
NonSemanticShaderDebugInfo100DebugTypeEnum = 9,
|
||||
NonSemanticShaderDebugInfo100DebugTypeComposite = 10,
|
||||
NonSemanticShaderDebugInfo100DebugTypeMember = 11,
|
||||
NonSemanticShaderDebugInfo100DebugTypeInheritance = 12,
|
||||
NonSemanticShaderDebugInfo100DebugTypePtrToMember = 13,
|
||||
NonSemanticShaderDebugInfo100DebugTypeTemplate = 14,
|
||||
NonSemanticShaderDebugInfo100DebugTypeTemplateParameter = 15,
|
||||
NonSemanticShaderDebugInfo100DebugTypeTemplateTemplateParameter = 16,
|
||||
NonSemanticShaderDebugInfo100DebugTypeTemplateParameterPack = 17,
|
||||
NonSemanticShaderDebugInfo100DebugGlobalVariable = 18,
|
||||
NonSemanticShaderDebugInfo100DebugFunctionDeclaration = 19,
|
||||
NonSemanticShaderDebugInfo100DebugFunction = 20,
|
||||
NonSemanticShaderDebugInfo100DebugLexicalBlock = 21,
|
||||
NonSemanticShaderDebugInfo100DebugLexicalBlockDiscriminator = 22,
|
||||
NonSemanticShaderDebugInfo100DebugScope = 23,
|
||||
NonSemanticShaderDebugInfo100DebugNoScope = 24,
|
||||
NonSemanticShaderDebugInfo100DebugInlinedAt = 25,
|
||||
NonSemanticShaderDebugInfo100DebugLocalVariable = 26,
|
||||
NonSemanticShaderDebugInfo100DebugInlinedVariable = 27,
|
||||
NonSemanticShaderDebugInfo100DebugDeclare = 28,
|
||||
NonSemanticShaderDebugInfo100DebugValue = 29,
|
||||
NonSemanticShaderDebugInfo100DebugOperation = 30,
|
||||
NonSemanticShaderDebugInfo100DebugExpression = 31,
|
||||
NonSemanticShaderDebugInfo100DebugMacroDef = 32,
|
||||
NonSemanticShaderDebugInfo100DebugMacroUndef = 33,
|
||||
NonSemanticShaderDebugInfo100DebugImportedEntity = 34,
|
||||
NonSemanticShaderDebugInfo100DebugSource = 35,
|
||||
NonSemanticShaderDebugInfo100DebugFunctionDefinition = 101,
|
||||
NonSemanticShaderDebugInfo100DebugSourceContinued = 102,
|
||||
NonSemanticShaderDebugInfo100DebugLine = 103,
|
||||
NonSemanticShaderDebugInfo100DebugNoLine = 104,
|
||||
NonSemanticShaderDebugInfo100DebugBuildIdentifier = 105,
|
||||
NonSemanticShaderDebugInfo100DebugStoragePath = 106,
|
||||
NonSemanticShaderDebugInfo100DebugEntryPoint = 107,
|
||||
NonSemanticShaderDebugInfo100DebugTypeMatrix = 108,
|
||||
NonSemanticShaderDebugInfo100InstructionsMax = 0x7fffffff
|
||||
};
|
||||
|
||||
|
||||
enum NonSemanticShaderDebugInfo100DebugInfoFlags {
|
||||
NonSemanticShaderDebugInfo100None = 0x0000,
|
||||
NonSemanticShaderDebugInfo100FlagIsProtected = 0x01,
|
||||
NonSemanticShaderDebugInfo100FlagIsPrivate = 0x02,
|
||||
NonSemanticShaderDebugInfo100FlagIsPublic = 0x03,
|
||||
NonSemanticShaderDebugInfo100FlagIsLocal = 0x04,
|
||||
NonSemanticShaderDebugInfo100FlagIsDefinition = 0x08,
|
||||
NonSemanticShaderDebugInfo100FlagFwdDecl = 0x10,
|
||||
NonSemanticShaderDebugInfo100FlagArtificial = 0x20,
|
||||
NonSemanticShaderDebugInfo100FlagExplicit = 0x40,
|
||||
NonSemanticShaderDebugInfo100FlagPrototyped = 0x80,
|
||||
NonSemanticShaderDebugInfo100FlagObjectPointer = 0x100,
|
||||
NonSemanticShaderDebugInfo100FlagStaticMember = 0x200,
|
||||
NonSemanticShaderDebugInfo100FlagIndirectVariable = 0x400,
|
||||
NonSemanticShaderDebugInfo100FlagLValueReference = 0x800,
|
||||
NonSemanticShaderDebugInfo100FlagRValueReference = 0x1000,
|
||||
NonSemanticShaderDebugInfo100FlagIsOptimized = 0x2000,
|
||||
NonSemanticShaderDebugInfo100FlagIsEnumClass = 0x4000,
|
||||
NonSemanticShaderDebugInfo100FlagTypePassByValue = 0x8000,
|
||||
NonSemanticShaderDebugInfo100FlagTypePassByReference = 0x10000,
|
||||
NonSemanticShaderDebugInfo100FlagUnknownPhysicalLayout = 0x20000,
|
||||
NonSemanticShaderDebugInfo100DebugInfoFlagsMax = 0x7fffffff
|
||||
};
|
||||
|
||||
enum NonSemanticShaderDebugInfo100BuildIdentifierFlags {
|
||||
NonSemanticShaderDebugInfo100IdentifierPossibleDuplicates = 0x01,
|
||||
NonSemanticShaderDebugInfo100BuildIdentifierFlagsMax = 0x7fffffff
|
||||
};
|
||||
|
||||
enum NonSemanticShaderDebugInfo100DebugBaseTypeAttributeEncoding {
|
||||
NonSemanticShaderDebugInfo100Unspecified = 0,
|
||||
NonSemanticShaderDebugInfo100Address = 1,
|
||||
NonSemanticShaderDebugInfo100Boolean = 2,
|
||||
NonSemanticShaderDebugInfo100Float = 3,
|
||||
NonSemanticShaderDebugInfo100Signed = 4,
|
||||
NonSemanticShaderDebugInfo100SignedChar = 5,
|
||||
NonSemanticShaderDebugInfo100Unsigned = 6,
|
||||
NonSemanticShaderDebugInfo100UnsignedChar = 7,
|
||||
NonSemanticShaderDebugInfo100DebugBaseTypeAttributeEncodingMax = 0x7fffffff
|
||||
};
|
||||
|
||||
enum NonSemanticShaderDebugInfo100DebugCompositeType {
|
||||
NonSemanticShaderDebugInfo100Class = 0,
|
||||
NonSemanticShaderDebugInfo100Structure = 1,
|
||||
NonSemanticShaderDebugInfo100Union = 2,
|
||||
NonSemanticShaderDebugInfo100DebugCompositeTypeMax = 0x7fffffff
|
||||
};
|
||||
|
||||
enum NonSemanticShaderDebugInfo100DebugTypeQualifier {
|
||||
NonSemanticShaderDebugInfo100ConstType = 0,
|
||||
NonSemanticShaderDebugInfo100VolatileType = 1,
|
||||
NonSemanticShaderDebugInfo100RestrictType = 2,
|
||||
NonSemanticShaderDebugInfo100AtomicType = 3,
|
||||
NonSemanticShaderDebugInfo100DebugTypeQualifierMax = 0x7fffffff
|
||||
};
|
||||
|
||||
enum NonSemanticShaderDebugInfo100DebugOperation {
|
||||
NonSemanticShaderDebugInfo100Deref = 0,
|
||||
NonSemanticShaderDebugInfo100Plus = 1,
|
||||
NonSemanticShaderDebugInfo100Minus = 2,
|
||||
NonSemanticShaderDebugInfo100PlusUconst = 3,
|
||||
NonSemanticShaderDebugInfo100BitPiece = 4,
|
||||
NonSemanticShaderDebugInfo100Swap = 5,
|
||||
NonSemanticShaderDebugInfo100Xderef = 6,
|
||||
NonSemanticShaderDebugInfo100StackValue = 7,
|
||||
NonSemanticShaderDebugInfo100Constu = 8,
|
||||
NonSemanticShaderDebugInfo100Fragment = 9,
|
||||
NonSemanticShaderDebugInfo100DebugOperationMax = 0x7fffffff
|
||||
};
|
||||
|
||||
enum NonSemanticShaderDebugInfo100DebugImportedEntity {
|
||||
NonSemanticShaderDebugInfo100ImportedModule = 0,
|
||||
NonSemanticShaderDebugInfo100ImportedDeclaration = 1,
|
||||
NonSemanticShaderDebugInfo100DebugImportedEntityMax = 0x7fffffff
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SPIRV_UNIFIED1_NonSemanticShaderDebugInfo100_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,300 @@
|
||||
//
|
||||
// Copyright (C) 2015 LunarG, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#ifndef SPIRVREMAPPER_H
|
||||
#define SPIRVREMAPPER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <exception>
|
||||
|
||||
#ifdef GLSLANG_IS_SHARED_LIBRARY
|
||||
#ifdef _WIN32
|
||||
#ifdef GLSLANG_EXPORTING
|
||||
#define GLSLANG_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define GLSLANG_EXPORT __declspec(dllimport)
|
||||
#endif
|
||||
#elif __GNUC__ >= 4
|
||||
#define GLSLANG_EXPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
#endif // GLSLANG_IS_SHARED_LIBRARY
|
||||
#ifndef GLSLANG_EXPORT
|
||||
#define GLSLANG_EXPORT
|
||||
#endif
|
||||
|
||||
namespace spv {
|
||||
|
||||
class spirvbin_base_t
|
||||
{
|
||||
public:
|
||||
enum Options {
|
||||
NONE = 0,
|
||||
STRIP = (1<<0),
|
||||
MAP_TYPES = (1<<1),
|
||||
MAP_NAMES = (1<<2),
|
||||
MAP_FUNCS = (1<<3),
|
||||
DCE_FUNCS = (1<<4),
|
||||
DCE_VARS = (1<<5),
|
||||
DCE_TYPES = (1<<6),
|
||||
OPT_LOADSTORE = (1<<7),
|
||||
OPT_FWD_LS = (1<<8), // EXPERIMENTAL: PRODUCES INVALID SCHEMA-0 SPIRV
|
||||
MAP_ALL = (MAP_TYPES | MAP_NAMES | MAP_FUNCS),
|
||||
DCE_ALL = (DCE_FUNCS | DCE_VARS | DCE_TYPES),
|
||||
OPT_ALL = (OPT_LOADSTORE),
|
||||
|
||||
ALL_BUT_STRIP = (MAP_ALL | DCE_ALL | OPT_ALL),
|
||||
DO_EVERYTHING = (STRIP | ALL_BUT_STRIP)
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace SPV
|
||||
|
||||
#include <functional>
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <cassert>
|
||||
|
||||
#include "spirv.hpp"
|
||||
|
||||
namespace spv {
|
||||
|
||||
static inline constexpr Id NoResult = 0;
|
||||
|
||||
// class to hold SPIR-V binary data for remapping, DCE, and debug stripping
|
||||
class GLSLANG_EXPORT spirvbin_t : public spirvbin_base_t
|
||||
{
|
||||
public:
|
||||
spirvbin_t(int verbose = 0) : entryPoint(spv::NoResult), largestNewId(0), verbose(verbose), errorLatch(false)
|
||||
{ }
|
||||
|
||||
virtual ~spirvbin_t() { }
|
||||
|
||||
// remap on an existing binary in memory
|
||||
void remap(std::vector<std::uint32_t>& spv, const std::vector<std::string>& whiteListStrings,
|
||||
std::uint32_t opts = DO_EVERYTHING);
|
||||
|
||||
// remap on an existing binary in memory - legacy interface without white list
|
||||
void remap(std::vector<std::uint32_t>& spv, std::uint32_t opts = DO_EVERYTHING);
|
||||
|
||||
// Type for error/log handler functions
|
||||
typedef std::function<void(const std::string&)> errorfn_t;
|
||||
typedef std::function<void(const std::string&)> logfn_t;
|
||||
|
||||
// Register error/log handling functions (can be lambda fn / functor / etc)
|
||||
static void registerErrorHandler(errorfn_t handler) { errorHandler = handler; }
|
||||
static void registerLogHandler(logfn_t handler) { logHandler = handler; }
|
||||
|
||||
protected:
|
||||
// This can be overridden to provide other message behavior if needed
|
||||
virtual void msg(int minVerbosity, int indent, const std::string& txt) const;
|
||||
|
||||
private:
|
||||
// Local to global, or global to local ID map
|
||||
typedef std::unordered_map<spv::Id, spv::Id> idmap_t;
|
||||
typedef std::unordered_set<spv::Id> idset_t;
|
||||
typedef std::unordered_map<spv::Id, int> blockmap_t;
|
||||
|
||||
void remap(std::uint32_t opts = DO_EVERYTHING);
|
||||
|
||||
// Map of names to IDs
|
||||
typedef std::unordered_map<std::string, spv::Id> namemap_t;
|
||||
|
||||
typedef std::uint32_t spirword_t;
|
||||
|
||||
typedef std::pair<unsigned, unsigned> range_t;
|
||||
typedef std::function<void(spv::Id&)> idfn_t;
|
||||
typedef std::function<bool(spv::Op, unsigned start)> instfn_t;
|
||||
|
||||
// Special Values for ID map:
|
||||
static const spv::Id unmapped; // unchanged from default value
|
||||
static const spv::Id unused; // unused ID
|
||||
static const int header_size; // SPIR header = 5 words
|
||||
|
||||
class id_iterator_t;
|
||||
|
||||
// For mapping type entries between different shaders
|
||||
typedef std::vector<spirword_t> typeentry_t;
|
||||
typedef std::map<spv::Id, typeentry_t> globaltypes_t;
|
||||
|
||||
// A set that preserves position order, and a reverse map
|
||||
typedef std::set<int> posmap_t;
|
||||
typedef std::unordered_map<spv::Id, int> posmap_rev_t;
|
||||
|
||||
// Maps and ID to the size of its base type, if known.
|
||||
typedef std::unordered_map<spv::Id, unsigned> typesize_map_t;
|
||||
|
||||
// handle error
|
||||
void error(const std::string& txt) const { errorLatch = true; errorHandler(txt); }
|
||||
|
||||
bool isConstOp(spv::Op opCode) const;
|
||||
bool isTypeOp(spv::Op opCode) const;
|
||||
bool isStripOp(spv::Op opCode) const;
|
||||
bool isFlowCtrl(spv::Op opCode) const;
|
||||
range_t literalRange(spv::Op opCode) const;
|
||||
range_t typeRange(spv::Op opCode) const;
|
||||
range_t constRange(spv::Op opCode) const;
|
||||
unsigned typeSizeInWords(spv::Id id) const;
|
||||
unsigned idTypeSizeInWords(spv::Id id) const;
|
||||
|
||||
bool isStripOp(spv::Op opCode, unsigned start) const;
|
||||
|
||||
spv::Id& asId(unsigned word) { return spv[word]; }
|
||||
const spv::Id& asId(unsigned word) const { return spv[word]; }
|
||||
spv::Op asOpCode(unsigned word) const { return opOpCode(spv[word]); }
|
||||
std::uint32_t asOpCodeHash(unsigned word);
|
||||
spv::Decoration asDecoration(unsigned word) const { return spv::Decoration(spv[word]); }
|
||||
unsigned asWordCount(unsigned word) const { return opWordCount(spv[word]); }
|
||||
spv::Id asTypeConstId(unsigned word) const { return asId(word + (isTypeOp(asOpCode(word)) ? 1 : 2)); }
|
||||
unsigned idPos(spv::Id id) const;
|
||||
|
||||
static unsigned opWordCount(spirword_t data) { return data >> spv::WordCountShift; }
|
||||
static spv::Op opOpCode(spirword_t data) { return spv::Op(data & spv::OpCodeMask); }
|
||||
|
||||
// Header access & set methods
|
||||
spirword_t magic() const { return spv[0]; } // return magic number
|
||||
spirword_t bound() const { return spv[3]; } // return Id bound from header
|
||||
spirword_t bound(spirword_t b) { return spv[3] = b; }
|
||||
spirword_t genmagic() const { return spv[2]; } // generator magic
|
||||
spirword_t genmagic(spirword_t m) { return spv[2] = m; }
|
||||
spirword_t schemaNum() const { return spv[4]; } // schema number from header
|
||||
|
||||
// Mapping fns: get
|
||||
spv::Id localId(spv::Id id) const { return idMapL[id]; }
|
||||
|
||||
// Mapping fns: set
|
||||
inline spv::Id localId(spv::Id id, spv::Id newId);
|
||||
void countIds(spv::Id id);
|
||||
|
||||
// Return next unused new local ID.
|
||||
// NOTE: boost::dynamic_bitset would be more efficient due to find_next(),
|
||||
// which std::vector<bool> doens't have.
|
||||
inline spv::Id nextUnusedId(spv::Id id);
|
||||
|
||||
void buildLocalMaps();
|
||||
std::string literalString(unsigned word) const; // Return literal as a std::string
|
||||
int literalStringWords(const std::string& str) const { return (int(str.size())+4)/4; }
|
||||
|
||||
bool isNewIdMapped(spv::Id newId) const { return isMapped(newId); }
|
||||
bool isOldIdUnmapped(spv::Id oldId) const { return localId(oldId) == unmapped; }
|
||||
bool isOldIdUnused(spv::Id oldId) const { return localId(oldId) == unused; }
|
||||
bool isOldIdMapped(spv::Id oldId) const { return !isOldIdUnused(oldId) && !isOldIdUnmapped(oldId); }
|
||||
bool isFunction(spv::Id oldId) const { return fnPos.find(oldId) != fnPos.end(); }
|
||||
|
||||
// bool matchType(const globaltypes_t& globalTypes, spv::Id lt, spv::Id gt) const;
|
||||
// spv::Id findType(const globaltypes_t& globalTypes, spv::Id lt) const;
|
||||
std::uint32_t hashType(unsigned typeStart) const;
|
||||
|
||||
spirvbin_t& process(instfn_t, idfn_t, unsigned begin = 0, unsigned end = 0);
|
||||
int processInstruction(unsigned word, instfn_t, idfn_t);
|
||||
|
||||
void validate() const;
|
||||
void mapTypeConst();
|
||||
void mapFnBodies();
|
||||
void optLoadStore();
|
||||
void dceFuncs();
|
||||
void dceVars();
|
||||
void dceTypes();
|
||||
void mapNames();
|
||||
void foldIds(); // fold IDs to smallest space
|
||||
void forwardLoadStores(); // load store forwarding (EXPERIMENTAL)
|
||||
void offsetIds(); // create relative offset IDs
|
||||
|
||||
void applyMap(); // remap per local name map
|
||||
void mapRemainder(); // map any IDs we haven't touched yet
|
||||
void stripDebug(); // strip all debug info
|
||||
void stripDeadRefs(); // strips debug info for now-dead references after DCE
|
||||
void strip(); // remove debug symbols
|
||||
|
||||
std::vector<spirword_t> spv; // SPIR words
|
||||
|
||||
std::vector<std::string> stripWhiteList;
|
||||
|
||||
namemap_t nameMap; // ID names from OpName
|
||||
|
||||
// Since we want to also do binary ops, we can't use std::vector<bool>. we could use
|
||||
// boost::dynamic_bitset, but we're trying to avoid a boost dependency.
|
||||
typedef std::uint64_t bits_t;
|
||||
std::vector<bits_t> mapped; // which new IDs have been mapped
|
||||
static const int mBits = sizeof(bits_t) * 4;
|
||||
|
||||
bool isMapped(spv::Id id) const { return id < maxMappedId() && ((mapped[id/mBits] & (1LL<<(id%mBits))) != 0); }
|
||||
void setMapped(spv::Id id) { resizeMapped(id); mapped[id/mBits] |= (1LL<<(id%mBits)); }
|
||||
void resizeMapped(spv::Id id) { if (id >= maxMappedId()) mapped.resize(id/mBits+1, 0); }
|
||||
size_t maxMappedId() const { return mapped.size() * mBits; }
|
||||
|
||||
// Add a strip range for a given instruction starting at 'start'
|
||||
// Note: avoiding brace initializers to please older versions os MSVC.
|
||||
void stripInst(unsigned start) { stripRange.push_back(range_t(start, start + asWordCount(start))); }
|
||||
|
||||
// Function start and end. use unordered_map because we'll have
|
||||
// many fewer functions than IDs.
|
||||
std::unordered_map<spv::Id, range_t> fnPos;
|
||||
|
||||
// Which functions are called, anywhere in the module, with a call count
|
||||
std::unordered_map<spv::Id, int> fnCalls;
|
||||
|
||||
posmap_t typeConstPos; // word positions that define types & consts (ordered)
|
||||
posmap_rev_t idPosR; // reverse map from IDs to positions
|
||||
typesize_map_t idTypeSizeMap; // maps each ID to its type size, if known.
|
||||
|
||||
std::vector<spv::Id> idMapL; // ID {M}ap from {L}ocal to {G}lobal IDs
|
||||
|
||||
spv::Id entryPoint; // module entry point
|
||||
spv::Id largestNewId; // biggest new ID we have mapped anything to
|
||||
|
||||
// Sections of the binary to strip, given as [begin,end)
|
||||
std::vector<range_t> stripRange;
|
||||
|
||||
// processing options:
|
||||
std::uint32_t options;
|
||||
int verbose; // verbosity level
|
||||
|
||||
// Error latch: this is set if the error handler is ever executed. It would be better to
|
||||
// use a try/catch block and throw, but that's not desired for certain environments, so
|
||||
// this is the alternative.
|
||||
mutable bool errorLatch;
|
||||
|
||||
static errorfn_t errorHandler;
|
||||
static logfn_t logHandler;
|
||||
};
|
||||
|
||||
} // namespace SPV
|
||||
|
||||
#endif // SPIRVREMAPPER_H
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,551 @@
|
||||
//
|
||||
// Copyright (C) 2018 Google, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
//
|
||||
// Post-processing for SPIR-V IR, in internal form, not standard binary form.
|
||||
//
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <algorithm>
|
||||
|
||||
#include "SpvBuilder.h"
|
||||
#include "spirv.hpp"
|
||||
|
||||
namespace spv {
|
||||
#include "GLSL.std.450.h"
|
||||
#include "GLSL.ext.KHR.h"
|
||||
#include "GLSL.ext.EXT.h"
|
||||
#include "GLSL.ext.AMD.h"
|
||||
#include "GLSL.ext.NV.h"
|
||||
#include "GLSL.ext.ARM.h"
|
||||
#include "GLSL.ext.QCOM.h"
|
||||
}
|
||||
|
||||
namespace spv {
|
||||
|
||||
// Hook to visit each operand type and result type of an instruction.
|
||||
// Will be called multiple times for one instruction, once for each typed
|
||||
// operand and the result.
|
||||
void Builder::postProcessType(const Instruction& inst, Id typeId)
|
||||
{
|
||||
// Characterize the type being questioned
|
||||
Id basicTypeOp = getMostBasicTypeClass(typeId);
|
||||
int width = 0;
|
||||
if (basicTypeOp == OpTypeFloat || basicTypeOp == OpTypeInt)
|
||||
width = getScalarTypeWidth(typeId);
|
||||
|
||||
// Do opcode-specific checks
|
||||
switch (inst.getOpCode()) {
|
||||
case OpLoad:
|
||||
case OpStore:
|
||||
if (basicTypeOp == OpTypeStruct) {
|
||||
if (containsType(typeId, OpTypeInt, 8))
|
||||
addCapability(CapabilityInt8);
|
||||
if (containsType(typeId, OpTypeInt, 16))
|
||||
addCapability(CapabilityInt16);
|
||||
if (containsType(typeId, OpTypeFloat, 16))
|
||||
addCapability(CapabilityFloat16);
|
||||
} else {
|
||||
StorageClass storageClass = getStorageClass(inst.getIdOperand(0));
|
||||
if (width == 8) {
|
||||
switch (storageClass) {
|
||||
case StorageClassPhysicalStorageBufferEXT:
|
||||
case StorageClassUniform:
|
||||
case StorageClassStorageBuffer:
|
||||
case StorageClassPushConstant:
|
||||
break;
|
||||
default:
|
||||
addCapability(CapabilityInt8);
|
||||
break;
|
||||
}
|
||||
} else if (width == 16) {
|
||||
switch (storageClass) {
|
||||
case StorageClassPhysicalStorageBufferEXT:
|
||||
case StorageClassUniform:
|
||||
case StorageClassStorageBuffer:
|
||||
case StorageClassPushConstant:
|
||||
case StorageClassInput:
|
||||
case StorageClassOutput:
|
||||
break;
|
||||
default:
|
||||
if (basicTypeOp == OpTypeInt)
|
||||
addCapability(CapabilityInt16);
|
||||
if (basicTypeOp == OpTypeFloat)
|
||||
addCapability(CapabilityFloat16);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OpCopyObject:
|
||||
break;
|
||||
case OpFConvert:
|
||||
case OpSConvert:
|
||||
case OpUConvert:
|
||||
// Look for any 8/16-bit storage capabilities. If there are none, assume that
|
||||
// the convert instruction requires the Float16/Int8/16 capability.
|
||||
if (containsType(typeId, OpTypeFloat, 16) || containsType(typeId, OpTypeInt, 16)) {
|
||||
bool foundStorage = false;
|
||||
for (auto it = capabilities.begin(); it != capabilities.end(); ++it) {
|
||||
spv::Capability cap = *it;
|
||||
if (cap == spv::CapabilityStorageInputOutput16 ||
|
||||
cap == spv::CapabilityStoragePushConstant16 ||
|
||||
cap == spv::CapabilityStorageUniformBufferBlock16 ||
|
||||
cap == spv::CapabilityStorageUniform16) {
|
||||
foundStorage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundStorage) {
|
||||
if (containsType(typeId, OpTypeFloat, 16))
|
||||
addCapability(CapabilityFloat16);
|
||||
if (containsType(typeId, OpTypeInt, 16))
|
||||
addCapability(CapabilityInt16);
|
||||
}
|
||||
}
|
||||
if (containsType(typeId, OpTypeInt, 8)) {
|
||||
bool foundStorage = false;
|
||||
for (auto it = capabilities.begin(); it != capabilities.end(); ++it) {
|
||||
spv::Capability cap = *it;
|
||||
if (cap == spv::CapabilityStoragePushConstant8 ||
|
||||
cap == spv::CapabilityUniformAndStorageBuffer8BitAccess ||
|
||||
cap == spv::CapabilityStorageBuffer8BitAccess) {
|
||||
foundStorage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundStorage) {
|
||||
addCapability(CapabilityInt8);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OpExtInst:
|
||||
switch (inst.getImmediateOperand(1)) {
|
||||
case GLSLstd450Frexp:
|
||||
case GLSLstd450FrexpStruct:
|
||||
if (getSpvVersion() < spv::Spv_1_3 && containsType(typeId, OpTypeInt, 16))
|
||||
addExtension(spv::E_SPV_AMD_gpu_shader_int16);
|
||||
break;
|
||||
case GLSLstd450InterpolateAtCentroid:
|
||||
case GLSLstd450InterpolateAtSample:
|
||||
case GLSLstd450InterpolateAtOffset:
|
||||
if (getSpvVersion() < spv::Spv_1_3 && containsType(typeId, OpTypeFloat, 16))
|
||||
addExtension(spv::E_SPV_AMD_gpu_shader_half_float);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OpAccessChain:
|
||||
case OpPtrAccessChain:
|
||||
if (isPointerType(typeId))
|
||||
break;
|
||||
if (basicTypeOp == OpTypeInt) {
|
||||
if (width == 16)
|
||||
addCapability(CapabilityInt16);
|
||||
else if (width == 8)
|
||||
addCapability(CapabilityInt8);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (basicTypeOp == OpTypeInt) {
|
||||
if (width == 16)
|
||||
addCapability(CapabilityInt16);
|
||||
else if (width == 8)
|
||||
addCapability(CapabilityInt8);
|
||||
else if (width == 64)
|
||||
addCapability(CapabilityInt64);
|
||||
} else if (basicTypeOp == OpTypeFloat) {
|
||||
if (width == 16)
|
||||
addCapability(CapabilityFloat16);
|
||||
else if (width == 64)
|
||||
addCapability(CapabilityFloat64);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Called for each instruction that resides in a block.
|
||||
void Builder::postProcess(Instruction& inst)
|
||||
{
|
||||
// Add capabilities based simply on the opcode.
|
||||
switch (inst.getOpCode()) {
|
||||
case OpExtInst:
|
||||
switch (inst.getImmediateOperand(1)) {
|
||||
case GLSLstd450InterpolateAtCentroid:
|
||||
case GLSLstd450InterpolateAtSample:
|
||||
case GLSLstd450InterpolateAtOffset:
|
||||
addCapability(CapabilityInterpolationFunction);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OpDPdxFine:
|
||||
case OpDPdyFine:
|
||||
case OpFwidthFine:
|
||||
case OpDPdxCoarse:
|
||||
case OpDPdyCoarse:
|
||||
case OpFwidthCoarse:
|
||||
addCapability(CapabilityDerivativeControl);
|
||||
break;
|
||||
|
||||
case OpImageQueryLod:
|
||||
case OpImageQuerySize:
|
||||
case OpImageQuerySizeLod:
|
||||
case OpImageQuerySamples:
|
||||
case OpImageQueryLevels:
|
||||
addCapability(CapabilityImageQuery);
|
||||
break;
|
||||
|
||||
case OpGroupNonUniformPartitionNV:
|
||||
addExtension(E_SPV_NV_shader_subgroup_partitioned);
|
||||
addCapability(CapabilityGroupNonUniformPartitionedNV);
|
||||
break;
|
||||
|
||||
case OpLoad:
|
||||
case OpStore:
|
||||
{
|
||||
// For any load/store to a PhysicalStorageBufferEXT, walk the accesschain
|
||||
// index list to compute the misalignment. The pre-existing alignment value
|
||||
// (set via Builder::AccessChain::alignment) only accounts for the base of
|
||||
// the reference type and any scalar component selection in the accesschain,
|
||||
// and this function computes the rest from the SPIR-V Offset decorations.
|
||||
Instruction *accessChain = module.getInstruction(inst.getIdOperand(0));
|
||||
if (accessChain->getOpCode() == OpAccessChain) {
|
||||
Instruction *base = module.getInstruction(accessChain->getIdOperand(0));
|
||||
// Get the type of the base of the access chain. It must be a pointer type.
|
||||
Id typeId = base->getTypeId();
|
||||
Instruction *type = module.getInstruction(typeId);
|
||||
assert(type->getOpCode() == OpTypePointer);
|
||||
if (type->getImmediateOperand(0) != StorageClassPhysicalStorageBufferEXT) {
|
||||
break;
|
||||
}
|
||||
// Get the pointee type.
|
||||
typeId = type->getIdOperand(1);
|
||||
type = module.getInstruction(typeId);
|
||||
// Walk the index list for the access chain. For each index, find any
|
||||
// misalignment that can apply when accessing the member/element via
|
||||
// Offset/ArrayStride/MatrixStride decorations, and bitwise OR them all
|
||||
// together.
|
||||
int alignment = 0;
|
||||
for (int i = 1; i < accessChain->getNumOperands(); ++i) {
|
||||
Instruction *idx = module.getInstruction(accessChain->getIdOperand(i));
|
||||
if (type->getOpCode() == OpTypeStruct) {
|
||||
assert(idx->getOpCode() == OpConstant);
|
||||
unsigned int c = idx->getImmediateOperand(0);
|
||||
|
||||
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
|
||||
if (decoration.get()->getOpCode() == OpMemberDecorate &&
|
||||
decoration.get()->getIdOperand(0) == typeId &&
|
||||
decoration.get()->getImmediateOperand(1) == c &&
|
||||
(decoration.get()->getImmediateOperand(2) == DecorationOffset ||
|
||||
decoration.get()->getImmediateOperand(2) == DecorationMatrixStride)) {
|
||||
alignment |= decoration.get()->getImmediateOperand(3);
|
||||
}
|
||||
};
|
||||
std::for_each(decorations.begin(), decorations.end(), function);
|
||||
// get the next member type
|
||||
typeId = type->getIdOperand(c);
|
||||
type = module.getInstruction(typeId);
|
||||
} else if (type->getOpCode() == OpTypeArray ||
|
||||
type->getOpCode() == OpTypeRuntimeArray) {
|
||||
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
|
||||
if (decoration.get()->getOpCode() == OpDecorate &&
|
||||
decoration.get()->getIdOperand(0) == typeId &&
|
||||
decoration.get()->getImmediateOperand(1) == DecorationArrayStride) {
|
||||
alignment |= decoration.get()->getImmediateOperand(2);
|
||||
}
|
||||
};
|
||||
std::for_each(decorations.begin(), decorations.end(), function);
|
||||
// Get the element type
|
||||
typeId = type->getIdOperand(0);
|
||||
type = module.getInstruction(typeId);
|
||||
} else {
|
||||
// Once we get to any non-aggregate type, we're done.
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(inst.getNumOperands() >= 3);
|
||||
unsigned int memoryAccess = inst.getImmediateOperand((inst.getOpCode() == OpStore) ? 2 : 1);
|
||||
assert(memoryAccess & MemoryAccessAlignedMask);
|
||||
static_cast<void>(memoryAccess);
|
||||
// Compute the index of the alignment operand.
|
||||
int alignmentIdx = 2;
|
||||
if (inst.getOpCode() == OpStore)
|
||||
alignmentIdx++;
|
||||
// Merge new and old (mis)alignment
|
||||
alignment |= inst.getImmediateOperand(alignmentIdx);
|
||||
// Pick the LSB
|
||||
alignment = alignment & ~(alignment & (alignment-1));
|
||||
// update the Aligned operand
|
||||
inst.setImmediateOperand(alignmentIdx, alignment);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Checks based on type
|
||||
if (inst.getTypeId() != NoType)
|
||||
postProcessType(inst, inst.getTypeId());
|
||||
for (int op = 0; op < inst.getNumOperands(); ++op) {
|
||||
if (inst.isIdOperand(op)) {
|
||||
// In blocks, these are always result ids, but we are relying on
|
||||
// getTypeId() to return NoType for things like OpLabel.
|
||||
if (getTypeId(inst.getIdOperand(op)) != NoType)
|
||||
postProcessType(inst, getTypeId(inst.getIdOperand(op)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// comment in header
|
||||
void Builder::postProcessCFG()
|
||||
{
|
||||
// reachableBlocks is the set of blockss reached via control flow, or which are
|
||||
// unreachable continue targert or unreachable merge.
|
||||
std::unordered_set<const Block*> reachableBlocks;
|
||||
std::unordered_map<Block*, Block*> headerForUnreachableContinue;
|
||||
std::unordered_set<Block*> unreachableMerges;
|
||||
std::unordered_set<Id> unreachableDefinitions;
|
||||
// Collect IDs defined in unreachable blocks. For each function, label the
|
||||
// reachable blocks first. Then for each unreachable block, collect the
|
||||
// result IDs of the instructions in it.
|
||||
for (auto fi = module.getFunctions().cbegin(); fi != module.getFunctions().cend(); fi++) {
|
||||
Function* f = *fi;
|
||||
Block* entry = f->getEntryBlock();
|
||||
inReadableOrder(entry,
|
||||
[&reachableBlocks, &unreachableMerges, &headerForUnreachableContinue]
|
||||
(Block* b, ReachReason why, Block* header) {
|
||||
reachableBlocks.insert(b);
|
||||
if (why == ReachDeadContinue) headerForUnreachableContinue[b] = header;
|
||||
if (why == ReachDeadMerge) unreachableMerges.insert(b);
|
||||
});
|
||||
for (auto bi = f->getBlocks().cbegin(); bi != f->getBlocks().cend(); bi++) {
|
||||
Block* b = *bi;
|
||||
if (unreachableMerges.count(b) != 0 || headerForUnreachableContinue.count(b) != 0) {
|
||||
auto ii = b->getInstructions().cbegin();
|
||||
++ii; // Keep potential decorations on the label.
|
||||
for (; ii != b->getInstructions().cend(); ++ii)
|
||||
unreachableDefinitions.insert(ii->get()->getResultId());
|
||||
} else if (reachableBlocks.count(b) == 0) {
|
||||
// The normal case for unreachable code. All definitions are considered dead.
|
||||
for (auto ii = b->getInstructions().cbegin(); ii != b->getInstructions().cend(); ++ii)
|
||||
unreachableDefinitions.insert(ii->get()->getResultId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Modify unreachable merge blocks and unreachable continue targets.
|
||||
// Delete their contents.
|
||||
for (auto mergeIter = unreachableMerges.begin(); mergeIter != unreachableMerges.end(); ++mergeIter) {
|
||||
(*mergeIter)->rewriteAsCanonicalUnreachableMerge();
|
||||
}
|
||||
for (auto continueIter = headerForUnreachableContinue.begin();
|
||||
continueIter != headerForUnreachableContinue.end();
|
||||
++continueIter) {
|
||||
Block* continue_target = continueIter->first;
|
||||
Block* header = continueIter->second;
|
||||
continue_target->rewriteAsCanonicalUnreachableContinue(header);
|
||||
}
|
||||
|
||||
// Remove unneeded decorations, for unreachable instructions
|
||||
for (auto decorationIter = decorations.begin(); decorationIter != decorations.end();) {
|
||||
Id decorationId = (*decorationIter)->getIdOperand(0);
|
||||
if (unreachableDefinitions.count(decorationId) != 0) {
|
||||
decorationIter = decorations.erase(decorationIter);
|
||||
} else {
|
||||
++decorationIter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// comment in header
|
||||
void Builder::postProcessFeatures() {
|
||||
// Add per-instruction capabilities, extensions, etc.,
|
||||
|
||||
// Look for any 8/16 bit type in physical storage buffer class, and set the
|
||||
// appropriate capability. This happens in createSpvVariable for other storage
|
||||
// classes, but there isn't always a variable for physical storage buffer.
|
||||
for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) {
|
||||
Instruction* type = groupedTypes[OpTypePointer][t];
|
||||
if (type->getImmediateOperand(0) == (unsigned)StorageClassPhysicalStorageBufferEXT) {
|
||||
if (containsType(type->getIdOperand(1), OpTypeInt, 8)) {
|
||||
addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5);
|
||||
addCapability(spv::CapabilityStorageBuffer8BitAccess);
|
||||
}
|
||||
if (containsType(type->getIdOperand(1), OpTypeInt, 16) ||
|
||||
containsType(type->getIdOperand(1), OpTypeFloat, 16)) {
|
||||
addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3);
|
||||
addCapability(spv::CapabilityStorageBuffer16BitAccess);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// process all block-contained instructions
|
||||
for (auto fi = module.getFunctions().cbegin(); fi != module.getFunctions().cend(); fi++) {
|
||||
Function* f = *fi;
|
||||
for (auto bi = f->getBlocks().cbegin(); bi != f->getBlocks().cend(); bi++) {
|
||||
Block* b = *bi;
|
||||
for (auto ii = b->getInstructions().cbegin(); ii != b->getInstructions().cend(); ii++)
|
||||
postProcess(*ii->get());
|
||||
|
||||
// For all local variables that contain pointers to PhysicalStorageBufferEXT, check whether
|
||||
// there is an existing restrict/aliased decoration. If we don't find one, add Aliased as the
|
||||
// default.
|
||||
for (auto vi = b->getLocalVariables().cbegin(); vi != b->getLocalVariables().cend(); vi++) {
|
||||
const Instruction& inst = *vi->get();
|
||||
Id resultId = inst.getResultId();
|
||||
if (containsPhysicalStorageBufferOrArray(getDerefTypeId(resultId))) {
|
||||
bool foundDecoration = false;
|
||||
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
|
||||
if (decoration.get()->getIdOperand(0) == resultId &&
|
||||
decoration.get()->getOpCode() == OpDecorate &&
|
||||
(decoration.get()->getImmediateOperand(1) == spv::DecorationAliasedPointerEXT ||
|
||||
decoration.get()->getImmediateOperand(1) == spv::DecorationRestrictPointerEXT)) {
|
||||
foundDecoration = true;
|
||||
}
|
||||
};
|
||||
std::for_each(decorations.begin(), decorations.end(), function);
|
||||
if (!foundDecoration) {
|
||||
addDecoration(resultId, spv::DecorationAliasedPointerEXT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If any Vulkan memory model-specific functionality is used, update the
|
||||
// OpMemoryModel to match.
|
||||
if (capabilities.find(spv::CapabilityVulkanMemoryModelKHR) != capabilities.end()) {
|
||||
memoryModel = spv::MemoryModelVulkanKHR;
|
||||
addIncorporatedExtension(spv::E_SPV_KHR_vulkan_memory_model, spv::Spv_1_5);
|
||||
}
|
||||
|
||||
// Add Aliased decoration if there's more than one Workgroup Block variable.
|
||||
if (capabilities.find(spv::CapabilityWorkgroupMemoryExplicitLayoutKHR) != capabilities.end()) {
|
||||
assert(entryPoints.size() == 1);
|
||||
auto &ep = entryPoints[0];
|
||||
|
||||
std::vector<Id> workgroup_variables;
|
||||
for (int i = 0; i < (int)ep->getNumOperands(); i++) {
|
||||
if (!ep->isIdOperand(i))
|
||||
continue;
|
||||
|
||||
const Id id = ep->getIdOperand(i);
|
||||
const Instruction *instr = module.getInstruction(id);
|
||||
if (instr->getOpCode() != spv::OpVariable)
|
||||
continue;
|
||||
|
||||
if (instr->getImmediateOperand(0) == spv::StorageClassWorkgroup)
|
||||
workgroup_variables.push_back(id);
|
||||
}
|
||||
|
||||
if (workgroup_variables.size() > 1) {
|
||||
for (size_t i = 0; i < workgroup_variables.size(); i++)
|
||||
addDecoration(workgroup_variables[i], spv::DecorationAliased);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SPIR-V requires that any instruction consuming the result of an OpSampledImage
|
||||
// be in the same block as the OpSampledImage instruction. This pass goes finds
|
||||
// uses of OpSampledImage where that is not the case and duplicates the
|
||||
// OpSampledImage to be immediately before the instruction that consumes it.
|
||||
// The old OpSampledImage is left in place, potentially with no users.
|
||||
void Builder::postProcessSamplers()
|
||||
{
|
||||
// first, find all OpSampledImage instructions and store them in a map.
|
||||
std::map<Id, Instruction*> sampledImageInstrs;
|
||||
for (auto f: module.getFunctions()) {
|
||||
for (auto b: f->getBlocks()) {
|
||||
for (auto &i: b->getInstructions()) {
|
||||
if (i->getOpCode() == spv::OpSampledImage) {
|
||||
sampledImageInstrs[i->getResultId()] = i.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// next find all uses of the given ids and rewrite them if needed.
|
||||
for (auto f: module.getFunctions()) {
|
||||
for (auto b: f->getBlocks()) {
|
||||
auto &instrs = b->getInstructions();
|
||||
for (size_t idx = 0; idx < instrs.size(); idx++) {
|
||||
Instruction *i = instrs[idx].get();
|
||||
for (int opnum = 0; opnum < i->getNumOperands(); opnum++) {
|
||||
// Is this operand of the current instruction the result of an OpSampledImage?
|
||||
if (i->isIdOperand(opnum) &&
|
||||
sampledImageInstrs.count(i->getIdOperand(opnum)))
|
||||
{
|
||||
Instruction *opSampImg = sampledImageInstrs[i->getIdOperand(opnum)];
|
||||
if (i->getBlock() != opSampImg->getBlock()) {
|
||||
Instruction *newInstr = new Instruction(getUniqueId(),
|
||||
opSampImg->getTypeId(),
|
||||
spv::OpSampledImage);
|
||||
newInstr->addIdOperand(opSampImg->getIdOperand(0));
|
||||
newInstr->addIdOperand(opSampImg->getIdOperand(1));
|
||||
newInstr->setBlock(b);
|
||||
|
||||
// rewrite the user of the OpSampledImage to use the new instruction.
|
||||
i->setIdOperand(opnum, newInstr->getResultId());
|
||||
// insert the new OpSampledImage right before the current instruction.
|
||||
instrs.insert(instrs.begin() + idx,
|
||||
std::unique_ptr<Instruction>(newInstr));
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// comment in header
|
||||
void Builder::postProcess(bool compileOnly)
|
||||
{
|
||||
// postProcessCFG needs an entrypoint to determine what is reachable, but if we are not creating an "executable" shader, we don't have an entrypoint
|
||||
if (!compileOnly)
|
||||
postProcessCFG();
|
||||
|
||||
postProcessFeatures();
|
||||
postProcessSamplers();
|
||||
}
|
||||
|
||||
} // end spv namespace
|
||||
@@ -0,0 +1,314 @@
|
||||
//
|
||||
// Copyright (C) 2014-2016 LunarG, Inc.
|
||||
// Copyright (C) 2018-2020 Google, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
//
|
||||
// Call into SPIRV-Tools to disassemble, validate, and optimize.
|
||||
//
|
||||
|
||||
#if ENABLE_OPT
|
||||
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
|
||||
#include "SpvTools.h"
|
||||
#include "spirv-tools/optimizer.hpp"
|
||||
#include "glslang/MachineIndependent/localintermediate.h"
|
||||
|
||||
namespace glslang {
|
||||
|
||||
// Translate glslang's view of target versioning to what SPIRV-Tools uses.
|
||||
spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLogger* logger)
|
||||
{
|
||||
switch (spvVersion.vulkan) {
|
||||
case glslang::EShTargetVulkan_1_0:
|
||||
return spv_target_env::SPV_ENV_VULKAN_1_0;
|
||||
case glslang::EShTargetVulkan_1_1:
|
||||
switch (spvVersion.spv) {
|
||||
case EShTargetSpv_1_0:
|
||||
case EShTargetSpv_1_1:
|
||||
case EShTargetSpv_1_2:
|
||||
case EShTargetSpv_1_3:
|
||||
return spv_target_env::SPV_ENV_VULKAN_1_1;
|
||||
case EShTargetSpv_1_4:
|
||||
return spv_target_env::SPV_ENV_VULKAN_1_1_SPIRV_1_4;
|
||||
default:
|
||||
logger->missingFunctionality("Target version for SPIRV-Tools validator");
|
||||
return spv_target_env::SPV_ENV_VULKAN_1_1;
|
||||
}
|
||||
case glslang::EShTargetVulkan_1_2:
|
||||
return spv_target_env::SPV_ENV_VULKAN_1_2;
|
||||
case glslang::EShTargetVulkan_1_3:
|
||||
return spv_target_env::SPV_ENV_VULKAN_1_3;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (spvVersion.openGl > 0)
|
||||
return spv_target_env::SPV_ENV_OPENGL_4_5;
|
||||
|
||||
logger->missingFunctionality("Target version for SPIRV-Tools validator");
|
||||
return spv_target_env::SPV_ENV_UNIVERSAL_1_0;
|
||||
}
|
||||
|
||||
spv_target_env MapToSpirvToolsEnv(const glslang::TIntermediate& intermediate, spv::SpvBuildLogger* logger)
|
||||
{
|
||||
return MapToSpirvToolsEnv(intermediate.getSpv(), logger);
|
||||
}
|
||||
|
||||
// Callback passed to spvtools::Optimizer::SetMessageConsumer
|
||||
void OptimizerMesssageConsumer(spv_message_level_t level, const char *source,
|
||||
const spv_position_t &position, const char *message)
|
||||
{
|
||||
auto &out = std::cerr;
|
||||
switch (level)
|
||||
{
|
||||
case SPV_MSG_FATAL:
|
||||
case SPV_MSG_INTERNAL_ERROR:
|
||||
case SPV_MSG_ERROR:
|
||||
out << "error: ";
|
||||
break;
|
||||
case SPV_MSG_WARNING:
|
||||
out << "warning: ";
|
||||
break;
|
||||
case SPV_MSG_INFO:
|
||||
case SPV_MSG_DEBUG:
|
||||
out << "info: ";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (source)
|
||||
{
|
||||
out << source << ":";
|
||||
}
|
||||
out << position.line << ":" << position.column << ":" << position.index << ":";
|
||||
if (message)
|
||||
{
|
||||
out << " " << message;
|
||||
}
|
||||
out << std::endl;
|
||||
}
|
||||
|
||||
// Use the SPIRV-Tools disassembler to print SPIR-V using a SPV_ENV_UNIVERSAL_1_3 environment.
|
||||
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv)
|
||||
{
|
||||
SpirvToolsDisassemble(out, spirv, spv_target_env::SPV_ENV_UNIVERSAL_1_3);
|
||||
}
|
||||
|
||||
// Use the SPIRV-Tools disassembler to print SPIR-V with a provided SPIR-V environment.
|
||||
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv,
|
||||
spv_target_env requested_context)
|
||||
{
|
||||
// disassemble
|
||||
spv_context context = spvContextCreate(requested_context);
|
||||
spv_text text;
|
||||
spv_diagnostic diagnostic = nullptr;
|
||||
spvBinaryToText(context, spirv.data(), spirv.size(),
|
||||
SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES | SPV_BINARY_TO_TEXT_OPTION_INDENT,
|
||||
&text, &diagnostic);
|
||||
|
||||
// dump
|
||||
if (diagnostic == nullptr)
|
||||
out << text->str;
|
||||
else
|
||||
spvDiagnosticPrint(diagnostic);
|
||||
|
||||
// teardown
|
||||
spvDiagnosticDestroy(diagnostic);
|
||||
spvContextDestroy(context);
|
||||
}
|
||||
|
||||
// Apply the SPIRV-Tools validator to generated SPIR-V.
|
||||
void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||
spv::SpvBuildLogger* logger, bool prelegalization)
|
||||
{
|
||||
// validate
|
||||
spv_context context = spvContextCreate(MapToSpirvToolsEnv(intermediate.getSpv(), logger));
|
||||
spv_const_binary_t binary = { spirv.data(), spirv.size() };
|
||||
spv_diagnostic diagnostic = nullptr;
|
||||
spv_validator_options options = spvValidatorOptionsCreate();
|
||||
spvValidatorOptionsSetRelaxBlockLayout(options, intermediate.usingHlslOffsets());
|
||||
spvValidatorOptionsSetBeforeHlslLegalization(options, prelegalization);
|
||||
spvValidatorOptionsSetScalarBlockLayout(options, intermediate.usingScalarBlockLayout());
|
||||
spvValidatorOptionsSetWorkgroupScalarBlockLayout(options, intermediate.usingScalarBlockLayout());
|
||||
spvValidateWithOptions(context, options, &binary, &diagnostic);
|
||||
|
||||
// report
|
||||
if (diagnostic != nullptr) {
|
||||
logger->error("SPIRV-Tools Validation Errors");
|
||||
logger->error(diagnostic->error);
|
||||
}
|
||||
|
||||
// tear down
|
||||
spvValidatorOptionsDestroy(options);
|
||||
spvDiagnosticDestroy(diagnostic);
|
||||
spvContextDestroy(context);
|
||||
}
|
||||
|
||||
// Apply the SPIRV-Tools optimizer to generated SPIR-V. HLSL SPIR-V is legalized in the process.
|
||||
void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||
spv::SpvBuildLogger* logger, const SpvOptions* options)
|
||||
{
|
||||
spv_target_env target_env = MapToSpirvToolsEnv(intermediate.getSpv(), logger);
|
||||
|
||||
spvtools::Optimizer optimizer(target_env);
|
||||
optimizer.SetMessageConsumer(OptimizerMesssageConsumer);
|
||||
|
||||
// If debug (specifically source line info) is being generated, propagate
|
||||
// line information into all SPIR-V instructions. This avoids loss of
|
||||
// information when instructions are deleted or moved. Later, remove
|
||||
// redundant information to minimize final SPRIR-V size.
|
||||
if (options->stripDebugInfo) {
|
||||
optimizer.RegisterPass(spvtools::CreateStripDebugInfoPass());
|
||||
}
|
||||
optimizer.RegisterPass(spvtools::CreateWrapOpKillPass());
|
||||
optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass());
|
||||
optimizer.RegisterPass(spvtools::CreateMergeReturnPass());
|
||||
optimizer.RegisterPass(spvtools::CreateInlineExhaustivePass());
|
||||
optimizer.RegisterPass(spvtools::CreateEliminateDeadFunctionsPass());
|
||||
optimizer.RegisterPass(spvtools::CreateScalarReplacementPass());
|
||||
optimizer.RegisterPass(spvtools::CreateLocalAccessChainConvertPass());
|
||||
optimizer.RegisterPass(spvtools::CreateLocalSingleBlockLoadStoreElimPass());
|
||||
optimizer.RegisterPass(spvtools::CreateLocalSingleStoreElimPass());
|
||||
optimizer.RegisterPass(spvtools::CreateSimplificationPass());
|
||||
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
||||
optimizer.RegisterPass(spvtools::CreateVectorDCEPass());
|
||||
optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass());
|
||||
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
||||
optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass());
|
||||
optimizer.RegisterPass(spvtools::CreateBlockMergePass());
|
||||
optimizer.RegisterPass(spvtools::CreateLocalMultiStoreElimPass());
|
||||
optimizer.RegisterPass(spvtools::CreateIfConversionPass());
|
||||
optimizer.RegisterPass(spvtools::CreateSimplificationPass());
|
||||
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
||||
optimizer.RegisterPass(spvtools::CreateVectorDCEPass());
|
||||
optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass());
|
||||
optimizer.RegisterPass(spvtools::CreateInterpolateFixupPass());
|
||||
if (options->optimizeSize) {
|
||||
optimizer.RegisterPass(spvtools::CreateRedundancyEliminationPass());
|
||||
optimizer.RegisterPass(spvtools::CreateEliminateDeadInputComponentsSafePass());
|
||||
}
|
||||
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
||||
optimizer.RegisterPass(spvtools::CreateCFGCleanupPass());
|
||||
|
||||
spvtools::OptimizerOptions spvOptOptions;
|
||||
if (options->optimizerAllowExpandedIDBound)
|
||||
spvOptOptions.set_max_id_bound(0x3FFFFFFF);
|
||||
optimizer.SetTargetEnv(MapToSpirvToolsEnv(intermediate.getSpv(), logger));
|
||||
spvOptOptions.set_run_validator(false); // The validator may run as a separate step later on
|
||||
optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions);
|
||||
|
||||
if (options->optimizerAllowExpandedIDBound) {
|
||||
if (spirv.size() > 3 && spirv[3] > kDefaultMaxIdBound) {
|
||||
spvtools::Optimizer optimizer2(target_env);
|
||||
optimizer2.SetMessageConsumer(OptimizerMesssageConsumer);
|
||||
optimizer2.RegisterPass(spvtools::CreateCompactIdsPass());
|
||||
optimizer2.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SpirvToolsAnalyzeDeadOutputStores(spv_target_env target_env, std::vector<unsigned int>& spirv,
|
||||
std::unordered_set<uint32_t>* live_locs,
|
||||
std::unordered_set<uint32_t>* live_builtins,
|
||||
spv::SpvBuildLogger*)
|
||||
{
|
||||
spvtools::Optimizer optimizer(target_env);
|
||||
optimizer.SetMessageConsumer(OptimizerMesssageConsumer);
|
||||
|
||||
optimizer.RegisterPass(spvtools::CreateAnalyzeLiveInputPass(live_locs, live_builtins));
|
||||
|
||||
spvtools::OptimizerOptions spvOptOptions;
|
||||
optimizer.SetTargetEnv(target_env);
|
||||
spvOptOptions.set_run_validator(false);
|
||||
return optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions);
|
||||
}
|
||||
|
||||
void SpirvToolsEliminateDeadOutputStores(spv_target_env target_env, std::vector<unsigned int>& spirv,
|
||||
std::unordered_set<uint32_t>* live_locs,
|
||||
std::unordered_set<uint32_t>* live_builtins,
|
||||
spv::SpvBuildLogger*)
|
||||
{
|
||||
spvtools::Optimizer optimizer(target_env);
|
||||
optimizer.SetMessageConsumer(OptimizerMesssageConsumer);
|
||||
|
||||
optimizer.RegisterPass(spvtools::CreateEliminateDeadOutputStoresPass(live_locs, live_builtins));
|
||||
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass(false, true));
|
||||
optimizer.RegisterPass(spvtools::CreateEliminateDeadOutputComponentsPass());
|
||||
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass(false, true));
|
||||
|
||||
spvtools::OptimizerOptions spvOptOptions;
|
||||
optimizer.SetTargetEnv(target_env);
|
||||
spvOptOptions.set_run_validator(false);
|
||||
optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions);
|
||||
}
|
||||
|
||||
void SpirvToolsEliminateDeadInputComponents(spv_target_env target_env, std::vector<unsigned int>& spirv,
|
||||
spv::SpvBuildLogger*)
|
||||
{
|
||||
spvtools::Optimizer optimizer(target_env);
|
||||
optimizer.SetMessageConsumer(OptimizerMesssageConsumer);
|
||||
|
||||
optimizer.RegisterPass(spvtools::CreateEliminateDeadInputComponentsPass());
|
||||
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
||||
|
||||
spvtools::OptimizerOptions spvOptOptions;
|
||||
optimizer.SetTargetEnv(target_env);
|
||||
spvOptOptions.set_run_validator(false);
|
||||
optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions);
|
||||
}
|
||||
|
||||
// Apply the SPIRV-Tools optimizer to strip debug info from SPIR-V. This is implicitly done by
|
||||
// SpirvToolsTransform if spvOptions->stripDebugInfo is set, but can be called separately if
|
||||
// optimization is disabled.
|
||||
void SpirvToolsStripDebugInfo(const glslang::TIntermediate& intermediate,
|
||||
std::vector<unsigned int>& spirv, spv::SpvBuildLogger* logger)
|
||||
{
|
||||
spv_target_env target_env = MapToSpirvToolsEnv(intermediate.getSpv(), logger);
|
||||
|
||||
spvtools::Optimizer optimizer(target_env);
|
||||
optimizer.SetMessageConsumer(OptimizerMesssageConsumer);
|
||||
|
||||
optimizer.RegisterPass(spvtools::CreateStripDebugInfoPass());
|
||||
|
||||
spvtools::OptimizerOptions spvOptOptions;
|
||||
optimizer.SetTargetEnv(MapToSpirvToolsEnv(intermediate.getSpv(), logger));
|
||||
spvOptOptions.set_run_validator(false); // The validator may run as a separate step later on
|
||||
optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions);
|
||||
}
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,109 @@
|
||||
//
|
||||
// Copyright (C) 2014-2016 LunarG, Inc.
|
||||
// Copyright (C) 2018 Google, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
//
|
||||
// Call into SPIRV-Tools to disassemble, validate, and optimize.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef GLSLANG_SPV_TOOLS_H
|
||||
#define GLSLANG_SPV_TOOLS_H
|
||||
|
||||
#if ENABLE_OPT
|
||||
#include <vector>
|
||||
#include <ostream>
|
||||
#include <unordered_set>
|
||||
#include "spirv-tools/libspirv.h"
|
||||
#endif
|
||||
|
||||
#include "glslang/MachineIndependent/Versions.h"
|
||||
#include "glslang/Include/visibility.h"
|
||||
#include "GlslangToSpv.h"
|
||||
#include "Logger.h"
|
||||
|
||||
namespace glslang {
|
||||
|
||||
#if ENABLE_OPT
|
||||
|
||||
class TIntermediate;
|
||||
|
||||
// Translate glslang's view of target versioning to what SPIRV-Tools uses.
|
||||
GLSLANG_EXPORT spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLogger* logger);
|
||||
GLSLANG_EXPORT spv_target_env MapToSpirvToolsEnv(const glslang::TIntermediate& intermediate, spv::SpvBuildLogger* logger);
|
||||
|
||||
// Use the SPIRV-Tools disassembler to print SPIR-V using a SPV_ENV_UNIVERSAL_1_3 environment.
|
||||
GLSLANG_EXPORT void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv);
|
||||
|
||||
// Use the SPIRV-Tools disassembler to print SPIR-V with a provided SPIR-V environment.
|
||||
GLSLANG_EXPORT void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv,
|
||||
spv_target_env requested_context);
|
||||
|
||||
// Apply the SPIRV-Tools validator to generated SPIR-V.
|
||||
GLSLANG_EXPORT void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||
spv::SpvBuildLogger*, bool prelegalization);
|
||||
|
||||
// Apply the SPIRV-Tools optimizer to generated SPIR-V. HLSL SPIR-V is legalized in the process.
|
||||
GLSLANG_EXPORT void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||
spv::SpvBuildLogger*, const SpvOptions*);
|
||||
|
||||
// Apply the SPIRV-Tools EliminateDeadInputComponents pass to generated SPIR-V. Put result in |spirv|.
|
||||
GLSLANG_EXPORT void SpirvToolsEliminateDeadInputComponents(spv_target_env target_env, std::vector<unsigned int>& spirv,
|
||||
spv::SpvBuildLogger*);
|
||||
|
||||
// Apply the SPIRV-Tools AnalyzeDeadOutputStores pass to generated SPIR-V. Put result in |live_locs|.
|
||||
// Return true if the result is valid.
|
||||
GLSLANG_EXPORT bool SpirvToolsAnalyzeDeadOutputStores(spv_target_env target_env, std::vector<unsigned int>& spirv,
|
||||
std::unordered_set<uint32_t>* live_locs,
|
||||
std::unordered_set<uint32_t>* live_builtins,
|
||||
spv::SpvBuildLogger*);
|
||||
|
||||
// Apply the SPIRV-Tools EliminateDeadOutputStores and AggressiveDeadCodeElimination passes to generated SPIR-V using
|
||||
// |live_locs|. Put result in |spirv|.
|
||||
GLSLANG_EXPORT void SpirvToolsEliminateDeadOutputStores(spv_target_env target_env, std::vector<unsigned int>& spirv,
|
||||
std::unordered_set<uint32_t>* live_locs,
|
||||
std::unordered_set<uint32_t>* live_builtins,
|
||||
spv::SpvBuildLogger*);
|
||||
|
||||
// Apply the SPIRV-Tools optimizer to strip debug info from SPIR-V. This is implicitly done by
|
||||
// SpirvToolsTransform if spvOptions->stripDebugInfo is set, but can be called separately if
|
||||
// optimization is disabled.
|
||||
GLSLANG_EXPORT void SpirvToolsStripDebugInfo(const glslang::TIntermediate& intermediate,
|
||||
std::vector<unsigned int>& spirv, spv::SpvBuildLogger*);
|
||||
|
||||
#endif
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
#endif // GLSLANG_SPV_TOOLS_H
|
||||
@@ -0,0 +1,81 @@
|
||||
// Copyright (c) 2015-2016 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef LIBSPIRV_UTIL_BITUTILS_H_
|
||||
#define LIBSPIRV_UTIL_BITUTILS_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
namespace spvutils {
|
||||
|
||||
// Performs a bitwise copy of source to the destination type Dest.
|
||||
template <typename Dest, typename Src>
|
||||
Dest BitwiseCast(Src source) {
|
||||
Dest dest;
|
||||
static_assert(sizeof(source) == sizeof(dest),
|
||||
"BitwiseCast: Source and destination must have the same size");
|
||||
std::memcpy(static_cast<void*>(&dest), &source, sizeof(dest));
|
||||
return dest;
|
||||
}
|
||||
|
||||
// SetBits<T, First, Num> returns an integer of type <T> with bits set
|
||||
// for position <First> through <First + Num - 1>, counting from the least
|
||||
// significant bit. In particular when Num == 0, no positions are set to 1.
|
||||
// A static assert will be triggered if First + Num > sizeof(T) * 8, that is,
|
||||
// a bit that will not fit in the underlying type is set.
|
||||
template <typename T, size_t First = 0, size_t Num = 0>
|
||||
struct SetBits {
|
||||
static_assert(First < sizeof(T) * 8,
|
||||
"Tried to set a bit that is shifted too far.");
|
||||
const static T get = (T(1) << First) | SetBits<T, First + 1, Num - 1>::get;
|
||||
};
|
||||
|
||||
template <typename T, size_t Last>
|
||||
struct SetBits<T, Last, 0> {
|
||||
const static T get = T(0);
|
||||
};
|
||||
|
||||
// This is all compile-time so we can put our tests right here.
|
||||
static_assert(SetBits<uint32_t, 0, 0>::get == uint32_t(0x00000000),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint32_t, 0, 1>::get == uint32_t(0x00000001),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint32_t, 31, 1>::get == uint32_t(0x80000000),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint32_t, 1, 2>::get == uint32_t(0x00000006),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint32_t, 30, 2>::get == uint32_t(0xc0000000),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint32_t, 0, 31>::get == uint32_t(0x7FFFFFFF),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint32_t, 0, 32>::get == uint32_t(0xFFFFFFFF),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint32_t, 16, 16>::get == uint32_t(0xFFFF0000),
|
||||
"SetBits failed");
|
||||
|
||||
static_assert(SetBits<uint64_t, 0, 1>::get == uint64_t(0x0000000000000001LL),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint64_t, 63, 1>::get == uint64_t(0x8000000000000000LL),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint64_t, 62, 2>::get == uint64_t(0xc000000000000000LL),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint64_t, 31, 1>::get == uint64_t(0x0000000080000000LL),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint64_t, 16, 16>::get == uint64_t(0x00000000FFFF0000LL),
|
||||
"SetBits failed");
|
||||
|
||||
} // namespace spvutils
|
||||
|
||||
#endif // LIBSPIRV_UTIL_BITUTILS_H_
|
||||
@@ -0,0 +1,864 @@
|
||||
//
|
||||
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
//
|
||||
// Disassembler for SPIR-V.
|
||||
//
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <iomanip>
|
||||
#include <stack>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
|
||||
#include "disassemble.h"
|
||||
#include "doc.h"
|
||||
|
||||
namespace spv {
|
||||
extern "C" {
|
||||
// Include C-based headers that don't have a namespace
|
||||
#include "GLSL.std.450.h"
|
||||
#include "GLSL.ext.AMD.h"
|
||||
#include "GLSL.ext.NV.h"
|
||||
#include "GLSL.ext.ARM.h"
|
||||
#include "NonSemanticShaderDebugInfo100.h"
|
||||
#include "GLSL.ext.QCOM.h"
|
||||
}
|
||||
}
|
||||
const char* GlslStd450DebugNames[spv::GLSLstd450Count];
|
||||
|
||||
namespace spv {
|
||||
|
||||
static const char* GLSLextAMDGetDebugNames(const char*, unsigned);
|
||||
static const char* GLSLextNVGetDebugNames(const char*, unsigned);
|
||||
static const char* NonSemanticShaderDebugInfo100GetDebugNames(unsigned);
|
||||
|
||||
static void Kill(std::ostream& out, const char* message)
|
||||
{
|
||||
out << std::endl << "Disassembly failed: " << message << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// used to identify the extended instruction library imported when printing
|
||||
enum ExtInstSet {
|
||||
GLSL450Inst,
|
||||
GLSLextAMDInst,
|
||||
GLSLextNVInst,
|
||||
OpenCLExtInst,
|
||||
NonSemanticDebugPrintfExtInst,
|
||||
NonSemanticDebugBreakExtInst,
|
||||
NonSemanticShaderDebugInfo100
|
||||
};
|
||||
|
||||
// Container class for a single instance of a SPIR-V stream, with methods for disassembly.
|
||||
class SpirvStream {
|
||||
public:
|
||||
SpirvStream(std::ostream& out, const std::vector<unsigned int>& stream) : out(out), stream(stream), word(0), nextNestedControl(0) { }
|
||||
virtual ~SpirvStream() { }
|
||||
|
||||
void validate();
|
||||
void processInstructions();
|
||||
|
||||
protected:
|
||||
SpirvStream(const SpirvStream&);
|
||||
SpirvStream& operator=(const SpirvStream&);
|
||||
Op getOpCode(int id) const { return idInstruction[id] ? (Op)(stream[idInstruction[id]] & OpCodeMask) : OpNop; }
|
||||
|
||||
// Output methods
|
||||
void outputIndent();
|
||||
void formatId(Id id, std::stringstream&);
|
||||
void outputResultId(Id id);
|
||||
void outputTypeId(Id id);
|
||||
void outputId(Id id);
|
||||
void outputMask(OperandClass operandClass, unsigned mask);
|
||||
void disassembleImmediates(int numOperands);
|
||||
void disassembleIds(int numOperands);
|
||||
std::pair<int, std::string> decodeString();
|
||||
int disassembleString();
|
||||
void disassembleInstruction(Id resultId, Id typeId, Op opCode, int numOperands);
|
||||
|
||||
// Data
|
||||
std::ostream& out; // where to write the disassembly
|
||||
const std::vector<unsigned int>& stream; // the actual word stream
|
||||
int size; // the size of the word stream
|
||||
int word; // the next word of the stream to read
|
||||
|
||||
// map each <id> to the instruction that created it
|
||||
Id bound;
|
||||
std::vector<unsigned int> idInstruction; // the word offset into the stream where the instruction for result [id] starts; 0 if not yet seen (forward reference or function parameter)
|
||||
|
||||
std::vector<std::string> idDescriptor; // the best text string known for explaining the <id>
|
||||
|
||||
// schema
|
||||
unsigned int schema;
|
||||
|
||||
// stack of structured-merge points
|
||||
std::stack<Id> nestedControl;
|
||||
Id nextNestedControl; // need a slight delay for when we are nested
|
||||
};
|
||||
|
||||
void SpirvStream::validate()
|
||||
{
|
||||
size = (int)stream.size();
|
||||
if (size < 4)
|
||||
Kill(out, "stream is too short");
|
||||
|
||||
// Magic number
|
||||
if (stream[word++] != MagicNumber) {
|
||||
out << "Bad magic number";
|
||||
return;
|
||||
}
|
||||
|
||||
// Version
|
||||
out << "// Module Version " << std::hex << stream[word++] << std::endl;
|
||||
|
||||
// Generator's magic number
|
||||
out << "// Generated by (magic number): " << std::hex << stream[word++] << std::dec << std::endl;
|
||||
|
||||
// Result <id> bound
|
||||
bound = stream[word++];
|
||||
idInstruction.resize(bound);
|
||||
idDescriptor.resize(bound);
|
||||
out << "// Id's are bound by " << bound << std::endl;
|
||||
out << std::endl;
|
||||
|
||||
// Reserved schema, must be 0 for now
|
||||
schema = stream[word++];
|
||||
if (schema != 0)
|
||||
Kill(out, "bad schema, must be 0");
|
||||
}
|
||||
|
||||
// Loop over all the instructions, in order, processing each.
|
||||
// Boiler plate for each is handled here directly, the rest is dispatched.
|
||||
void SpirvStream::processInstructions()
|
||||
{
|
||||
// Instructions
|
||||
while (word < size) {
|
||||
int instructionStart = word;
|
||||
|
||||
// Instruction wordCount and opcode
|
||||
unsigned int firstWord = stream[word];
|
||||
unsigned wordCount = firstWord >> WordCountShift;
|
||||
Op opCode = (Op)(firstWord & OpCodeMask);
|
||||
int nextInst = word + wordCount;
|
||||
++word;
|
||||
|
||||
// Presence of full instruction
|
||||
if (nextInst > size)
|
||||
Kill(out, "stream instruction terminated too early");
|
||||
|
||||
// Base for computing number of operands; will be updated as more is learned
|
||||
unsigned numOperands = wordCount - 1;
|
||||
|
||||
// Type <id>
|
||||
Id typeId = 0;
|
||||
if (InstructionDesc[opCode].hasType()) {
|
||||
typeId = stream[word++];
|
||||
--numOperands;
|
||||
}
|
||||
|
||||
// Result <id>
|
||||
Id resultId = 0;
|
||||
if (InstructionDesc[opCode].hasResult()) {
|
||||
resultId = stream[word++];
|
||||
--numOperands;
|
||||
|
||||
// save instruction for future reference
|
||||
idInstruction[resultId] = instructionStart;
|
||||
}
|
||||
|
||||
outputResultId(resultId);
|
||||
outputTypeId(typeId);
|
||||
outputIndent();
|
||||
|
||||
// Hand off the Op and all its operands
|
||||
disassembleInstruction(resultId, typeId, opCode, numOperands);
|
||||
if (word != nextInst) {
|
||||
out << " ERROR, incorrect number of operands consumed. At " << word << " instead of " << nextInst << " instruction start was " << instructionStart;
|
||||
word = nextInst;
|
||||
}
|
||||
out << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void SpirvStream::outputIndent()
|
||||
{
|
||||
for (int i = 0; i < (int)nestedControl.size(); ++i)
|
||||
out << " ";
|
||||
}
|
||||
|
||||
void SpirvStream::formatId(Id id, std::stringstream& idStream)
|
||||
{
|
||||
if (id != 0) {
|
||||
// On instructions with no IDs, this is called with "0", which does not
|
||||
// have to be within ID bounds on null shaders.
|
||||
if (id >= bound)
|
||||
Kill(out, "Bad <id>");
|
||||
|
||||
idStream << id;
|
||||
if (idDescriptor[id].size() > 0)
|
||||
idStream << "(" << idDescriptor[id] << ")";
|
||||
}
|
||||
}
|
||||
|
||||
void SpirvStream::outputResultId(Id id)
|
||||
{
|
||||
const int width = 16;
|
||||
std::stringstream idStream;
|
||||
formatId(id, idStream);
|
||||
out << std::setw(width) << std::right << idStream.str();
|
||||
if (id != 0)
|
||||
out << ":";
|
||||
else
|
||||
out << " ";
|
||||
|
||||
if (nestedControl.size() && id == nestedControl.top())
|
||||
nestedControl.pop();
|
||||
}
|
||||
|
||||
void SpirvStream::outputTypeId(Id id)
|
||||
{
|
||||
const int width = 12;
|
||||
std::stringstream idStream;
|
||||
formatId(id, idStream);
|
||||
out << std::setw(width) << std::right << idStream.str() << " ";
|
||||
}
|
||||
|
||||
void SpirvStream::outputId(Id id)
|
||||
{
|
||||
if (id >= bound)
|
||||
Kill(out, "Bad <id>");
|
||||
|
||||
out << id;
|
||||
if (idDescriptor[id].size() > 0)
|
||||
out << "(" << idDescriptor[id] << ")";
|
||||
}
|
||||
|
||||
void SpirvStream::outputMask(OperandClass operandClass, unsigned mask)
|
||||
{
|
||||
if (mask == 0)
|
||||
out << "None";
|
||||
else {
|
||||
for (int m = 0; m < OperandClassParams[operandClass].ceiling; ++m) {
|
||||
if (mask & (1 << m))
|
||||
out << OperandClassParams[operandClass].getName(m) << " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpirvStream::disassembleImmediates(int numOperands)
|
||||
{
|
||||
for (int i = 0; i < numOperands; ++i) {
|
||||
out << stream[word++];
|
||||
if (i < numOperands - 1)
|
||||
out << " ";
|
||||
}
|
||||
}
|
||||
|
||||
void SpirvStream::disassembleIds(int numOperands)
|
||||
{
|
||||
for (int i = 0; i < numOperands; ++i) {
|
||||
outputId(stream[word++]);
|
||||
if (i < numOperands - 1)
|
||||
out << " ";
|
||||
}
|
||||
}
|
||||
|
||||
// decode string from words at current position (non-consuming)
|
||||
std::pair<int, std::string> SpirvStream::decodeString()
|
||||
{
|
||||
std::string res;
|
||||
int wordPos = word;
|
||||
char c;
|
||||
bool done = false;
|
||||
|
||||
do {
|
||||
unsigned int content = stream[wordPos];
|
||||
for (int charCount = 0; charCount < 4; ++charCount) {
|
||||
c = content & 0xff;
|
||||
content >>= 8;
|
||||
if (c == '\0') {
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
res += c;
|
||||
}
|
||||
++wordPos;
|
||||
} while(! done);
|
||||
|
||||
return std::make_pair(wordPos - word, res);
|
||||
}
|
||||
|
||||
// return the number of operands consumed by the string
|
||||
int SpirvStream::disassembleString()
|
||||
{
|
||||
out << " \"";
|
||||
|
||||
std::pair<int, std::string> decoderes = decodeString();
|
||||
|
||||
out << decoderes.second;
|
||||
out << "\"";
|
||||
|
||||
word += decoderes.first;
|
||||
|
||||
return decoderes.first;
|
||||
}
|
||||
|
||||
static uint32_t popcount(uint32_t mask)
|
||||
{
|
||||
uint32_t count = 0;
|
||||
while (mask) {
|
||||
if (mask & 1) {
|
||||
count++;
|
||||
}
|
||||
mask >>= 1;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, int numOperands)
|
||||
{
|
||||
// Process the opcode
|
||||
|
||||
out << (OpcodeString(opCode) + 2); // leave out the "Op"
|
||||
|
||||
if (opCode == OpLoopMerge || opCode == OpSelectionMerge)
|
||||
nextNestedControl = stream[word];
|
||||
else if (opCode == OpBranchConditional || opCode == OpSwitch) {
|
||||
if (nextNestedControl) {
|
||||
nestedControl.push(nextNestedControl);
|
||||
nextNestedControl = 0;
|
||||
}
|
||||
} else if (opCode == OpExtInstImport) {
|
||||
idDescriptor[resultId] = decodeString().second;
|
||||
}
|
||||
else {
|
||||
if (resultId != 0 && idDescriptor[resultId].size() == 0) {
|
||||
switch (opCode) {
|
||||
case OpTypeInt:
|
||||
switch (stream[word]) {
|
||||
case 8: idDescriptor[resultId] = "int8_t"; break;
|
||||
case 16: idDescriptor[resultId] = "int16_t"; break;
|
||||
default: assert(0); [[fallthrough]];
|
||||
case 32: idDescriptor[resultId] = "int"; break;
|
||||
case 64: idDescriptor[resultId] = "int64_t"; break;
|
||||
}
|
||||
break;
|
||||
case OpTypeFloat:
|
||||
switch (stream[word]) {
|
||||
case 16: idDescriptor[resultId] = "float16_t"; break;
|
||||
default: assert(0); [[fallthrough]];
|
||||
case 32: idDescriptor[resultId] = "float"; break;
|
||||
case 64: idDescriptor[resultId] = "float64_t"; break;
|
||||
}
|
||||
break;
|
||||
case OpTypeBool:
|
||||
idDescriptor[resultId] = "bool";
|
||||
break;
|
||||
case OpTypeStruct:
|
||||
idDescriptor[resultId] = "struct";
|
||||
break;
|
||||
case OpTypePointer:
|
||||
idDescriptor[resultId] = "ptr";
|
||||
break;
|
||||
case OpTypeVector:
|
||||
if (idDescriptor[stream[word]].size() > 0) {
|
||||
idDescriptor[resultId].append(idDescriptor[stream[word]].begin(), idDescriptor[stream[word]].begin() + 1);
|
||||
if (strstr(idDescriptor[stream[word]].c_str(), "8")) {
|
||||
idDescriptor[resultId].append("8");
|
||||
}
|
||||
if (strstr(idDescriptor[stream[word]].c_str(), "16")) {
|
||||
idDescriptor[resultId].append("16");
|
||||
}
|
||||
if (strstr(idDescriptor[stream[word]].c_str(), "64")) {
|
||||
idDescriptor[resultId].append("64");
|
||||
}
|
||||
}
|
||||
idDescriptor[resultId].append("vec");
|
||||
switch (stream[word + 1]) {
|
||||
case 2: idDescriptor[resultId].append("2"); break;
|
||||
case 3: idDescriptor[resultId].append("3"); break;
|
||||
case 4: idDescriptor[resultId].append("4"); break;
|
||||
case 8: idDescriptor[resultId].append("8"); break;
|
||||
case 16: idDescriptor[resultId].append("16"); break;
|
||||
case 32: idDescriptor[resultId].append("32"); break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process the operands. Note, a new context-dependent set could be
|
||||
// swapped in mid-traversal.
|
||||
|
||||
// Handle images specially, so can put out helpful strings.
|
||||
if (opCode == OpTypeImage) {
|
||||
out << " ";
|
||||
disassembleIds(1);
|
||||
out << " " << DimensionString((Dim)stream[word++]);
|
||||
out << (stream[word++] != 0 ? " depth" : "");
|
||||
out << (stream[word++] != 0 ? " array" : "");
|
||||
out << (stream[word++] != 0 ? " multi-sampled" : "");
|
||||
switch (stream[word++]) {
|
||||
case 0: out << " runtime"; break;
|
||||
case 1: out << " sampled"; break;
|
||||
case 2: out << " nonsampled"; break;
|
||||
}
|
||||
out << " format:" << ImageFormatString((ImageFormat)stream[word++]);
|
||||
|
||||
if (numOperands == 8) {
|
||||
out << " " << AccessQualifierString(stream[word++]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle all the parameterized operands
|
||||
for (int op = 0; op < InstructionDesc[opCode].operands.getNum() && numOperands > 0; ++op) {
|
||||
out << " ";
|
||||
OperandClass operandClass = InstructionDesc[opCode].operands.getClass(op);
|
||||
switch (operandClass) {
|
||||
case OperandId:
|
||||
case OperandScope:
|
||||
case OperandMemorySemantics:
|
||||
disassembleIds(1);
|
||||
--numOperands;
|
||||
// Get names for printing "(XXX)" for readability, *after* this id
|
||||
if (opCode == OpName)
|
||||
idDescriptor[stream[word - 1]] = decodeString().second;
|
||||
break;
|
||||
case OperandVariableIds:
|
||||
disassembleIds(numOperands);
|
||||
return;
|
||||
case OperandImageOperands:
|
||||
outputMask(OperandImageOperands, stream[word++]);
|
||||
--numOperands;
|
||||
disassembleIds(numOperands);
|
||||
return;
|
||||
case OperandOptionalLiteral:
|
||||
case OperandVariableLiterals:
|
||||
if ((opCode == OpDecorate && stream[word - 1] == DecorationBuiltIn) ||
|
||||
(opCode == OpMemberDecorate && stream[word - 1] == DecorationBuiltIn)) {
|
||||
out << BuiltInString(stream[word++]);
|
||||
--numOperands;
|
||||
++op;
|
||||
}
|
||||
disassembleImmediates(numOperands);
|
||||
return;
|
||||
case OperandVariableIdLiteral:
|
||||
while (numOperands > 0) {
|
||||
out << std::endl;
|
||||
outputResultId(0);
|
||||
outputTypeId(0);
|
||||
outputIndent();
|
||||
out << " Type ";
|
||||
disassembleIds(1);
|
||||
out << ", member ";
|
||||
disassembleImmediates(1);
|
||||
numOperands -= 2;
|
||||
}
|
||||
return;
|
||||
case OperandVariableLiteralId:
|
||||
while (numOperands > 0) {
|
||||
out << std::endl;
|
||||
outputResultId(0);
|
||||
outputTypeId(0);
|
||||
outputIndent();
|
||||
out << " case ";
|
||||
disassembleImmediates(1);
|
||||
out << ": ";
|
||||
disassembleIds(1);
|
||||
numOperands -= 2;
|
||||
}
|
||||
return;
|
||||
case OperandLiteralNumber:
|
||||
disassembleImmediates(1);
|
||||
--numOperands;
|
||||
if (opCode == OpExtInst) {
|
||||
ExtInstSet extInstSet = GLSL450Inst;
|
||||
const char* name = idDescriptor[stream[word - 2]].c_str();
|
||||
if (strcmp("OpenCL.std", name) == 0) {
|
||||
extInstSet = OpenCLExtInst;
|
||||
} else if (strcmp("OpenCL.DebugInfo.100", name) == 0) {
|
||||
extInstSet = OpenCLExtInst;
|
||||
} else if (strcmp("NonSemantic.DebugPrintf", name) == 0) {
|
||||
extInstSet = NonSemanticDebugPrintfExtInst;
|
||||
} else if (strcmp("NonSemantic.DebugBreak", name) == 0) {
|
||||
extInstSet = NonSemanticDebugBreakExtInst;
|
||||
} else if (strcmp("NonSemantic.Shader.DebugInfo.100", name) == 0) {
|
||||
extInstSet = NonSemanticShaderDebugInfo100;
|
||||
} else if (strcmp(spv::E_SPV_AMD_shader_ballot, name) == 0 ||
|
||||
strcmp(spv::E_SPV_AMD_shader_trinary_minmax, name) == 0 ||
|
||||
strcmp(spv::E_SPV_AMD_shader_explicit_vertex_parameter, name) == 0 ||
|
||||
strcmp(spv::E_SPV_AMD_gcn_shader, name) == 0) {
|
||||
extInstSet = GLSLextAMDInst;
|
||||
} else if (strcmp(spv::E_SPV_NV_sample_mask_override_coverage, name) == 0 ||
|
||||
strcmp(spv::E_SPV_NV_geometry_shader_passthrough, name) == 0 ||
|
||||
strcmp(spv::E_SPV_NV_viewport_array2, name) == 0 ||
|
||||
strcmp(spv::E_SPV_NVX_multiview_per_view_attributes, name) == 0 ||
|
||||
strcmp(spv::E_SPV_NV_fragment_shader_barycentric, name) == 0 ||
|
||||
strcmp(spv::E_SPV_NV_mesh_shader, name) == 0) {
|
||||
extInstSet = GLSLextNVInst;
|
||||
}
|
||||
unsigned entrypoint = stream[word - 1];
|
||||
if (extInstSet == GLSL450Inst) {
|
||||
if (entrypoint < GLSLstd450Count) {
|
||||
out << "(" << GlslStd450DebugNames[entrypoint] << ")";
|
||||
}
|
||||
} else if (extInstSet == GLSLextAMDInst) {
|
||||
out << "(" << GLSLextAMDGetDebugNames(name, entrypoint) << ")";
|
||||
}
|
||||
else if (extInstSet == GLSLextNVInst) {
|
||||
out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")";
|
||||
} else if (extInstSet == NonSemanticDebugPrintfExtInst) {
|
||||
out << "(DebugPrintf)";
|
||||
} else if (extInstSet == NonSemanticDebugBreakExtInst) {
|
||||
out << "(DebugBreak)";
|
||||
} else if (extInstSet == NonSemanticShaderDebugInfo100) {
|
||||
out << "(" << NonSemanticShaderDebugInfo100GetDebugNames(entrypoint) << ")";
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OperandOptionalLiteralString:
|
||||
case OperandLiteralString:
|
||||
numOperands -= disassembleString();
|
||||
break;
|
||||
case OperandVariableLiteralStrings:
|
||||
while (numOperands > 0)
|
||||
numOperands -= disassembleString();
|
||||
return;
|
||||
case OperandMemoryAccess:
|
||||
{
|
||||
outputMask(OperandMemoryAccess, stream[word++]);
|
||||
--numOperands;
|
||||
// Put a space after "None" if there are any remaining operands
|
||||
if (numOperands && stream[word-1] == 0) {
|
||||
out << " ";
|
||||
}
|
||||
uint32_t mask = stream[word-1];
|
||||
// Aligned is the only memory access operand that uses an immediate
|
||||
// value, and it is also the first operand that uses a value at all.
|
||||
if (mask & MemoryAccessAlignedMask) {
|
||||
disassembleImmediates(1);
|
||||
numOperands--;
|
||||
if (numOperands)
|
||||
out << " ";
|
||||
}
|
||||
|
||||
uint32_t bitCount = popcount(mask & (MemoryAccessMakePointerAvailableMask | MemoryAccessMakePointerVisibleMask));
|
||||
disassembleIds(bitCount);
|
||||
numOperands -= bitCount;
|
||||
}
|
||||
break;
|
||||
case OperandTensorAddressingOperands:
|
||||
{
|
||||
outputMask(OperandTensorAddressingOperands, stream[word++]);
|
||||
--numOperands;
|
||||
// Put a space after "None" if there are any remaining operands
|
||||
if (numOperands && stream[word-1] == 0) {
|
||||
out << " ";
|
||||
}
|
||||
uint32_t bitCount = popcount(stream[word-1]);
|
||||
disassembleIds(bitCount);
|
||||
numOperands -= bitCount;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(operandClass >= OperandSource && operandClass < OperandOpcode);
|
||||
|
||||
if (OperandClassParams[operandClass].bitmask)
|
||||
outputMask(operandClass, stream[word++]);
|
||||
else
|
||||
out << OperandClassParams[operandClass].getName(stream[word++]);
|
||||
--numOperands;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void GLSLstd450GetDebugNames(const char** names)
|
||||
{
|
||||
for (int i = 0; i < GLSLstd450Count; ++i)
|
||||
names[i] = "Unknown";
|
||||
|
||||
names[GLSLstd450Round] = "Round";
|
||||
names[GLSLstd450RoundEven] = "RoundEven";
|
||||
names[GLSLstd450Trunc] = "Trunc";
|
||||
names[GLSLstd450FAbs] = "FAbs";
|
||||
names[GLSLstd450SAbs] = "SAbs";
|
||||
names[GLSLstd450FSign] = "FSign";
|
||||
names[GLSLstd450SSign] = "SSign";
|
||||
names[GLSLstd450Floor] = "Floor";
|
||||
names[GLSLstd450Ceil] = "Ceil";
|
||||
names[GLSLstd450Fract] = "Fract";
|
||||
names[GLSLstd450Radians] = "Radians";
|
||||
names[GLSLstd450Degrees] = "Degrees";
|
||||
names[GLSLstd450Sin] = "Sin";
|
||||
names[GLSLstd450Cos] = "Cos";
|
||||
names[GLSLstd450Tan] = "Tan";
|
||||
names[GLSLstd450Asin] = "Asin";
|
||||
names[GLSLstd450Acos] = "Acos";
|
||||
names[GLSLstd450Atan] = "Atan";
|
||||
names[GLSLstd450Sinh] = "Sinh";
|
||||
names[GLSLstd450Cosh] = "Cosh";
|
||||
names[GLSLstd450Tanh] = "Tanh";
|
||||
names[GLSLstd450Asinh] = "Asinh";
|
||||
names[GLSLstd450Acosh] = "Acosh";
|
||||
names[GLSLstd450Atanh] = "Atanh";
|
||||
names[GLSLstd450Atan2] = "Atan2";
|
||||
names[GLSLstd450Pow] = "Pow";
|
||||
names[GLSLstd450Exp] = "Exp";
|
||||
names[GLSLstd450Log] = "Log";
|
||||
names[GLSLstd450Exp2] = "Exp2";
|
||||
names[GLSLstd450Log2] = "Log2";
|
||||
names[GLSLstd450Sqrt] = "Sqrt";
|
||||
names[GLSLstd450InverseSqrt] = "InverseSqrt";
|
||||
names[GLSLstd450Determinant] = "Determinant";
|
||||
names[GLSLstd450MatrixInverse] = "MatrixInverse";
|
||||
names[GLSLstd450Modf] = "Modf";
|
||||
names[GLSLstd450ModfStruct] = "ModfStruct";
|
||||
names[GLSLstd450FMin] = "FMin";
|
||||
names[GLSLstd450SMin] = "SMin";
|
||||
names[GLSLstd450UMin] = "UMin";
|
||||
names[GLSLstd450FMax] = "FMax";
|
||||
names[GLSLstd450SMax] = "SMax";
|
||||
names[GLSLstd450UMax] = "UMax";
|
||||
names[GLSLstd450FClamp] = "FClamp";
|
||||
names[GLSLstd450SClamp] = "SClamp";
|
||||
names[GLSLstd450UClamp] = "UClamp";
|
||||
names[GLSLstd450FMix] = "FMix";
|
||||
names[GLSLstd450Step] = "Step";
|
||||
names[GLSLstd450SmoothStep] = "SmoothStep";
|
||||
names[GLSLstd450Fma] = "Fma";
|
||||
names[GLSLstd450Frexp] = "Frexp";
|
||||
names[GLSLstd450FrexpStruct] = "FrexpStruct";
|
||||
names[GLSLstd450Ldexp] = "Ldexp";
|
||||
names[GLSLstd450PackSnorm4x8] = "PackSnorm4x8";
|
||||
names[GLSLstd450PackUnorm4x8] = "PackUnorm4x8";
|
||||
names[GLSLstd450PackSnorm2x16] = "PackSnorm2x16";
|
||||
names[GLSLstd450PackUnorm2x16] = "PackUnorm2x16";
|
||||
names[GLSLstd450PackHalf2x16] = "PackHalf2x16";
|
||||
names[GLSLstd450PackDouble2x32] = "PackDouble2x32";
|
||||
names[GLSLstd450UnpackSnorm2x16] = "UnpackSnorm2x16";
|
||||
names[GLSLstd450UnpackUnorm2x16] = "UnpackUnorm2x16";
|
||||
names[GLSLstd450UnpackHalf2x16] = "UnpackHalf2x16";
|
||||
names[GLSLstd450UnpackSnorm4x8] = "UnpackSnorm4x8";
|
||||
names[GLSLstd450UnpackUnorm4x8] = "UnpackUnorm4x8";
|
||||
names[GLSLstd450UnpackDouble2x32] = "UnpackDouble2x32";
|
||||
names[GLSLstd450Length] = "Length";
|
||||
names[GLSLstd450Distance] = "Distance";
|
||||
names[GLSLstd450Cross] = "Cross";
|
||||
names[GLSLstd450Normalize] = "Normalize";
|
||||
names[GLSLstd450FaceForward] = "FaceForward";
|
||||
names[GLSLstd450Reflect] = "Reflect";
|
||||
names[GLSLstd450Refract] = "Refract";
|
||||
names[GLSLstd450FindILsb] = "FindILsb";
|
||||
names[GLSLstd450FindSMsb] = "FindSMsb";
|
||||
names[GLSLstd450FindUMsb] = "FindUMsb";
|
||||
names[GLSLstd450InterpolateAtCentroid] = "InterpolateAtCentroid";
|
||||
names[GLSLstd450InterpolateAtSample] = "InterpolateAtSample";
|
||||
names[GLSLstd450InterpolateAtOffset] = "InterpolateAtOffset";
|
||||
names[GLSLstd450NMin] = "NMin";
|
||||
names[GLSLstd450NMax] = "NMax";
|
||||
names[GLSLstd450NClamp] = "NClamp";
|
||||
}
|
||||
|
||||
static const char* GLSLextAMDGetDebugNames(const char* name, unsigned entrypoint)
|
||||
{
|
||||
if (strcmp(name, spv::E_SPV_AMD_shader_ballot) == 0) {
|
||||
switch (entrypoint) {
|
||||
case SwizzleInvocationsAMD: return "SwizzleInvocationsAMD";
|
||||
case SwizzleInvocationsMaskedAMD: return "SwizzleInvocationsMaskedAMD";
|
||||
case WriteInvocationAMD: return "WriteInvocationAMD";
|
||||
case MbcntAMD: return "MbcntAMD";
|
||||
default: return "Bad";
|
||||
}
|
||||
} else if (strcmp(name, spv::E_SPV_AMD_shader_trinary_minmax) == 0) {
|
||||
switch (entrypoint) {
|
||||
case FMin3AMD: return "FMin3AMD";
|
||||
case UMin3AMD: return "UMin3AMD";
|
||||
case SMin3AMD: return "SMin3AMD";
|
||||
case FMax3AMD: return "FMax3AMD";
|
||||
case UMax3AMD: return "UMax3AMD";
|
||||
case SMax3AMD: return "SMax3AMD";
|
||||
case FMid3AMD: return "FMid3AMD";
|
||||
case UMid3AMD: return "UMid3AMD";
|
||||
case SMid3AMD: return "SMid3AMD";
|
||||
default: return "Bad";
|
||||
}
|
||||
} else if (strcmp(name, spv::E_SPV_AMD_shader_explicit_vertex_parameter) == 0) {
|
||||
switch (entrypoint) {
|
||||
case InterpolateAtVertexAMD: return "InterpolateAtVertexAMD";
|
||||
default: return "Bad";
|
||||
}
|
||||
}
|
||||
else if (strcmp(name, spv::E_SPV_AMD_gcn_shader) == 0) {
|
||||
switch (entrypoint) {
|
||||
case CubeFaceIndexAMD: return "CubeFaceIndexAMD";
|
||||
case CubeFaceCoordAMD: return "CubeFaceCoordAMD";
|
||||
case TimeAMD: return "TimeAMD";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return "Bad";
|
||||
}
|
||||
|
||||
static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint)
|
||||
{
|
||||
if (strcmp(name, spv::E_SPV_NV_sample_mask_override_coverage) == 0 ||
|
||||
strcmp(name, spv::E_SPV_NV_geometry_shader_passthrough) == 0 ||
|
||||
strcmp(name, spv::E_ARB_shader_viewport_layer_array) == 0 ||
|
||||
strcmp(name, spv::E_SPV_NV_viewport_array2) == 0 ||
|
||||
strcmp(name, spv::E_SPV_NVX_multiview_per_view_attributes) == 0 ||
|
||||
strcmp(name, spv::E_SPV_NV_fragment_shader_barycentric) == 0 ||
|
||||
strcmp(name, spv::E_SPV_NV_mesh_shader) == 0 ||
|
||||
strcmp(name, spv::E_SPV_NV_shader_image_footprint) == 0) {
|
||||
switch (entrypoint) {
|
||||
// NV builtins
|
||||
case BuiltInViewportMaskNV: return "ViewportMaskNV";
|
||||
case BuiltInSecondaryPositionNV: return "SecondaryPositionNV";
|
||||
case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
|
||||
case BuiltInPositionPerViewNV: return "PositionPerViewNV";
|
||||
case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
|
||||
case BuiltInBaryCoordNV: return "BaryCoordNV";
|
||||
case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
|
||||
case BuiltInTaskCountNV: return "TaskCountNV";
|
||||
case BuiltInPrimitiveCountNV: return "PrimitiveCountNV";
|
||||
case BuiltInPrimitiveIndicesNV: return "PrimitiveIndicesNV";
|
||||
case BuiltInClipDistancePerViewNV: return "ClipDistancePerViewNV";
|
||||
case BuiltInCullDistancePerViewNV: return "CullDistancePerViewNV";
|
||||
case BuiltInLayerPerViewNV: return "LayerPerViewNV";
|
||||
case BuiltInMeshViewCountNV: return "MeshViewCountNV";
|
||||
case BuiltInMeshViewIndicesNV: return "MeshViewIndicesNV";
|
||||
|
||||
// NV Capabilities
|
||||
case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
|
||||
case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV";
|
||||
case CapabilityShaderStereoViewNV: return "ShaderStereoViewNV";
|
||||
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
|
||||
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
|
||||
case CapabilityMeshShadingNV: return "MeshShadingNV";
|
||||
case CapabilityImageFootprintNV: return "ImageFootprintNV";
|
||||
case CapabilitySampleMaskOverrideCoverageNV:return "SampleMaskOverrideCoverageNV";
|
||||
|
||||
// NV Decorations
|
||||
case DecorationOverrideCoverageNV: return "OverrideCoverageNV";
|
||||
case DecorationPassthroughNV: return "PassthroughNV";
|
||||
case DecorationViewportRelativeNV: return "ViewportRelativeNV";
|
||||
case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV";
|
||||
case DecorationPerVertexNV: return "PerVertexNV";
|
||||
case DecorationPerPrimitiveNV: return "PerPrimitiveNV";
|
||||
case DecorationPerViewNV: return "PerViewNV";
|
||||
case DecorationPerTaskNV: return "PerTaskNV";
|
||||
|
||||
default: return "Bad";
|
||||
}
|
||||
}
|
||||
return "Bad";
|
||||
}
|
||||
|
||||
static const char* NonSemanticShaderDebugInfo100GetDebugNames(unsigned entrypoint)
|
||||
{
|
||||
switch (entrypoint) {
|
||||
case NonSemanticShaderDebugInfo100DebugInfoNone: return "DebugInfoNone";
|
||||
case NonSemanticShaderDebugInfo100DebugCompilationUnit: return "DebugCompilationUnit";
|
||||
case NonSemanticShaderDebugInfo100DebugTypeBasic: return "DebugTypeBasic";
|
||||
case NonSemanticShaderDebugInfo100DebugTypePointer: return "DebugTypePointer";
|
||||
case NonSemanticShaderDebugInfo100DebugTypeQualifier: return "DebugTypeQualifier";
|
||||
case NonSemanticShaderDebugInfo100DebugTypeArray: return "DebugTypeArray";
|
||||
case NonSemanticShaderDebugInfo100DebugTypeVector: return "DebugTypeVector";
|
||||
case NonSemanticShaderDebugInfo100DebugTypedef: return "DebugTypedef";
|
||||
case NonSemanticShaderDebugInfo100DebugTypeFunction: return "DebugTypeFunction";
|
||||
case NonSemanticShaderDebugInfo100DebugTypeEnum: return "DebugTypeEnum";
|
||||
case NonSemanticShaderDebugInfo100DebugTypeComposite: return "DebugTypeComposite";
|
||||
case NonSemanticShaderDebugInfo100DebugTypeMember: return "DebugTypeMember";
|
||||
case NonSemanticShaderDebugInfo100DebugTypeInheritance: return "DebugTypeInheritance";
|
||||
case NonSemanticShaderDebugInfo100DebugTypePtrToMember: return "DebugTypePtrToMember";
|
||||
case NonSemanticShaderDebugInfo100DebugTypeTemplate: return "DebugTypeTemplate";
|
||||
case NonSemanticShaderDebugInfo100DebugTypeTemplateParameter: return "DebugTypeTemplateParameter";
|
||||
case NonSemanticShaderDebugInfo100DebugTypeTemplateTemplateParameter: return "DebugTypeTemplateTemplateParameter";
|
||||
case NonSemanticShaderDebugInfo100DebugTypeTemplateParameterPack: return "DebugTypeTemplateParameterPack";
|
||||
case NonSemanticShaderDebugInfo100DebugGlobalVariable: return "DebugGlobalVariable";
|
||||
case NonSemanticShaderDebugInfo100DebugFunctionDeclaration: return "DebugFunctionDeclaration";
|
||||
case NonSemanticShaderDebugInfo100DebugFunction: return "DebugFunction";
|
||||
case NonSemanticShaderDebugInfo100DebugLexicalBlock: return "DebugLexicalBlock";
|
||||
case NonSemanticShaderDebugInfo100DebugLexicalBlockDiscriminator: return "DebugLexicalBlockDiscriminator";
|
||||
case NonSemanticShaderDebugInfo100DebugScope: return "DebugScope";
|
||||
case NonSemanticShaderDebugInfo100DebugNoScope: return "DebugNoScope";
|
||||
case NonSemanticShaderDebugInfo100DebugInlinedAt: return "DebugInlinedAt";
|
||||
case NonSemanticShaderDebugInfo100DebugLocalVariable: return "DebugLocalVariable";
|
||||
case NonSemanticShaderDebugInfo100DebugInlinedVariable: return "DebugInlinedVariable";
|
||||
case NonSemanticShaderDebugInfo100DebugDeclare: return "DebugDeclare";
|
||||
case NonSemanticShaderDebugInfo100DebugValue: return "DebugValue";
|
||||
case NonSemanticShaderDebugInfo100DebugOperation: return "DebugOperation";
|
||||
case NonSemanticShaderDebugInfo100DebugExpression: return "DebugExpression";
|
||||
case NonSemanticShaderDebugInfo100DebugMacroDef: return "DebugMacroDef";
|
||||
case NonSemanticShaderDebugInfo100DebugMacroUndef: return "DebugMacroUndef";
|
||||
case NonSemanticShaderDebugInfo100DebugImportedEntity: return "DebugImportedEntity";
|
||||
case NonSemanticShaderDebugInfo100DebugSource: return "DebugSource";
|
||||
case NonSemanticShaderDebugInfo100DebugFunctionDefinition: return "DebugFunctionDefinition";
|
||||
case NonSemanticShaderDebugInfo100DebugSourceContinued: return "DebugSourceContinued";
|
||||
case NonSemanticShaderDebugInfo100DebugLine: return "DebugLine";
|
||||
case NonSemanticShaderDebugInfo100DebugNoLine: return "DebugNoLine";
|
||||
case NonSemanticShaderDebugInfo100DebugBuildIdentifier: return "DebugBuildIdentifier";
|
||||
case NonSemanticShaderDebugInfo100DebugStoragePath: return "DebugStoragePath";
|
||||
case NonSemanticShaderDebugInfo100DebugEntryPoint: return "DebugEntryPoint";
|
||||
case NonSemanticShaderDebugInfo100DebugTypeMatrix: return "DebugTypeMatrix";
|
||||
default: return "Bad";
|
||||
}
|
||||
|
||||
return "Bad";
|
||||
}
|
||||
|
||||
void Disassemble(std::ostream& out, const std::vector<unsigned int>& stream)
|
||||
{
|
||||
SpirvStream SpirvStream(out, stream);
|
||||
spv::Parameterize();
|
||||
GLSLstd450GetDebugNames(GlslStd450DebugNames);
|
||||
SpirvStream.validate();
|
||||
SpirvStream.processInstructions();
|
||||
}
|
||||
|
||||
} // end namespace spv
|
||||
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
//
|
||||
// Disassembler for SPIR-V.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef disassembler_H
|
||||
#define disassembler_H
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "glslang/Include/visibility.h"
|
||||
|
||||
namespace spv {
|
||||
|
||||
// disassemble with glslang custom disassembler
|
||||
GLSLANG_EXPORT void Disassemble(std::ostream& out, const std::vector<unsigned int>&);
|
||||
|
||||
} // end namespace spv
|
||||
|
||||
#endif // disassembler_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,261 @@
|
||||
//
|
||||
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
//
|
||||
// Parameterize the SPIR-V enumerants.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "spirv.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace spv {
|
||||
|
||||
// Fill in all the parameters
|
||||
void Parameterize();
|
||||
|
||||
// Return the English names of all the enums.
|
||||
const char* SourceString(int);
|
||||
const char* AddressingString(int);
|
||||
const char* MemoryString(int);
|
||||
const char* ExecutionModelString(int);
|
||||
const char* ExecutionModeString(int);
|
||||
const char* StorageClassString(int);
|
||||
const char* DecorationString(int);
|
||||
const char* BuiltInString(int);
|
||||
const char* DimensionString(int);
|
||||
const char* SelectControlString(int);
|
||||
const char* LoopControlString(int);
|
||||
const char* FunctionControlString(int);
|
||||
const char* SamplerAddressingModeString(int);
|
||||
const char* SamplerFilterModeString(int);
|
||||
const char* ImageFormatString(int);
|
||||
const char* ImageChannelOrderString(int);
|
||||
const char* ImageChannelTypeString(int);
|
||||
const char* ImageChannelDataTypeString(int type);
|
||||
const char* ImageOperandsString(int format);
|
||||
const char* ImageOperands(int);
|
||||
const char* FPFastMathString(int);
|
||||
const char* FPRoundingModeString(int);
|
||||
const char* LinkageTypeString(int);
|
||||
const char* FuncParamAttrString(int);
|
||||
const char* AccessQualifierString(int);
|
||||
const char* MemorySemanticsString(int);
|
||||
const char* MemoryAccessString(int);
|
||||
const char* ExecutionScopeString(int);
|
||||
const char* GroupOperationString(int);
|
||||
const char* KernelEnqueueFlagsString(int);
|
||||
const char* KernelProfilingInfoString(int);
|
||||
const char* CapabilityString(int);
|
||||
const char* OpcodeString(int);
|
||||
const char* ScopeString(int mem);
|
||||
|
||||
// For grouping opcodes into subsections
|
||||
enum OpcodeClass {
|
||||
OpClassMisc,
|
||||
OpClassDebug,
|
||||
OpClassAnnotate,
|
||||
OpClassExtension,
|
||||
OpClassMode,
|
||||
OpClassType,
|
||||
OpClassConstant,
|
||||
OpClassMemory,
|
||||
OpClassFunction,
|
||||
OpClassImage,
|
||||
OpClassConvert,
|
||||
OpClassComposite,
|
||||
OpClassArithmetic,
|
||||
OpClassBit,
|
||||
OpClassRelationalLogical,
|
||||
OpClassDerivative,
|
||||
OpClassFlowControl,
|
||||
OpClassAtomic,
|
||||
OpClassPrimitive,
|
||||
OpClassBarrier,
|
||||
OpClassGroup,
|
||||
OpClassDeviceSideEnqueue,
|
||||
OpClassPipe,
|
||||
|
||||
OpClassCount,
|
||||
OpClassMissing // all instructions start out as missing
|
||||
};
|
||||
|
||||
// For parameterizing operands.
|
||||
enum OperandClass {
|
||||
OperandNone,
|
||||
OperandId,
|
||||
OperandVariableIds,
|
||||
OperandOptionalLiteral,
|
||||
OperandOptionalLiteralString,
|
||||
OperandVariableLiterals,
|
||||
OperandVariableIdLiteral,
|
||||
OperandVariableLiteralId,
|
||||
OperandLiteralNumber,
|
||||
OperandLiteralString,
|
||||
OperandVariableLiteralStrings,
|
||||
OperandSource,
|
||||
OperandExecutionModel,
|
||||
OperandAddressing,
|
||||
OperandMemory,
|
||||
OperandExecutionMode,
|
||||
OperandStorage,
|
||||
OperandDimensionality,
|
||||
OperandSamplerAddressingMode,
|
||||
OperandSamplerFilterMode,
|
||||
OperandSamplerImageFormat,
|
||||
OperandImageChannelOrder,
|
||||
OperandImageChannelDataType,
|
||||
OperandImageOperands,
|
||||
OperandFPFastMath,
|
||||
OperandFPRoundingMode,
|
||||
OperandLinkageType,
|
||||
OperandAccessQualifier,
|
||||
OperandFuncParamAttr,
|
||||
OperandDecoration,
|
||||
OperandBuiltIn,
|
||||
OperandSelect,
|
||||
OperandLoop,
|
||||
OperandFunction,
|
||||
OperandMemorySemantics,
|
||||
OperandMemoryAccess,
|
||||
OperandScope,
|
||||
OperandGroupOperation,
|
||||
OperandKernelEnqueueFlags,
|
||||
OperandKernelProfilingInfo,
|
||||
OperandCapability,
|
||||
OperandCooperativeMatrixOperands,
|
||||
OperandTensorAddressingOperands,
|
||||
|
||||
OperandOpcode,
|
||||
|
||||
OperandCount
|
||||
};
|
||||
|
||||
// Any specific enum can have a set of capabilities that allow it:
|
||||
typedef std::vector<Capability> EnumCaps;
|
||||
|
||||
// Parameterize a set of operands with their OperandClass(es) and descriptions.
|
||||
class OperandParameters {
|
||||
public:
|
||||
OperandParameters() { }
|
||||
void push(OperandClass oc, const char* d, bool opt = false)
|
||||
{
|
||||
opClass.push_back(oc);
|
||||
desc.push_back(d);
|
||||
optional.push_back(opt);
|
||||
}
|
||||
void setOptional();
|
||||
OperandClass getClass(int op) const { return opClass[op]; }
|
||||
const char* getDesc(int op) const { return desc[op]; }
|
||||
bool isOptional(int op) const { return optional[op]; }
|
||||
int getNum() const { return (int)opClass.size(); }
|
||||
|
||||
protected:
|
||||
std::vector<OperandClass> opClass;
|
||||
std::vector<const char*> desc;
|
||||
std::vector<bool> optional;
|
||||
};
|
||||
|
||||
// Parameterize an enumerant
|
||||
class EnumParameters {
|
||||
public:
|
||||
EnumParameters() : desc(nullptr) { }
|
||||
const char* desc;
|
||||
};
|
||||
|
||||
// Parameterize a set of enumerants that form an enum
|
||||
class EnumDefinition : public EnumParameters {
|
||||
public:
|
||||
EnumDefinition() :
|
||||
ceiling(0), bitmask(false), getName(nullptr), enumParams(nullptr), operandParams(nullptr) { }
|
||||
void set(int ceil, const char* (*name)(int), EnumParameters* ep, bool mask = false)
|
||||
{
|
||||
ceiling = ceil;
|
||||
getName = name;
|
||||
bitmask = mask;
|
||||
enumParams = ep;
|
||||
}
|
||||
void setOperands(OperandParameters* op) { operandParams = op; }
|
||||
int ceiling; // ceiling of enumerants
|
||||
bool bitmask; // true if these enumerants combine into a bitmask
|
||||
const char* (*getName)(int); // a function that returns the name for each enumerant value (or shift)
|
||||
EnumParameters* enumParams; // parameters for each individual enumerant
|
||||
OperandParameters* operandParams; // sets of operands
|
||||
};
|
||||
|
||||
// Parameterize an instruction's logical format, including its known set of operands,
|
||||
// per OperandParameters above.
|
||||
class InstructionParameters {
|
||||
public:
|
||||
InstructionParameters() :
|
||||
opDesc("TBD"),
|
||||
opClass(OpClassMissing),
|
||||
typePresent(true), // most normal, only exceptions have to be spelled out
|
||||
resultPresent(true) // most normal, only exceptions have to be spelled out
|
||||
{ }
|
||||
|
||||
void setResultAndType(bool r, bool t)
|
||||
{
|
||||
resultPresent = r;
|
||||
typePresent = t;
|
||||
}
|
||||
|
||||
bool hasResult() const { return resultPresent != 0; }
|
||||
bool hasType() const { return typePresent != 0; }
|
||||
|
||||
const char* opDesc;
|
||||
OpcodeClass opClass;
|
||||
OperandParameters operands;
|
||||
|
||||
protected:
|
||||
bool typePresent : 1;
|
||||
bool resultPresent : 1;
|
||||
};
|
||||
|
||||
// The set of objects that hold all the instruction/operand
|
||||
// parameterization information.
|
||||
extern InstructionParameters InstructionDesc[];
|
||||
|
||||
// These hold definitions of the enumerants used for operands
|
||||
extern EnumDefinition OperandClassParams[];
|
||||
|
||||
const char* GetOperandDesc(OperandClass operand);
|
||||
void PrintImmediateRow(int imm, const char* name, const EnumParameters* enumParams, bool caps, bool hex = false);
|
||||
const char* AccessQualifierString(int attr);
|
||||
|
||||
void PrintOperands(const OperandParameters& operands, int reservedOperands);
|
||||
|
||||
} // end namespace spv
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,592 @@
|
||||
//
|
||||
// Copyright (C) 2014 LunarG, Inc.
|
||||
// Copyright (C) 2015-2018 Google, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// SPIRV-IR
|
||||
//
|
||||
// Simple in-memory representation (IR) of SPIRV. Just for holding
|
||||
// Each function's CFG of blocks. Has this hierarchy:
|
||||
// - Module, which is a list of
|
||||
// - Function, which is a list of
|
||||
// - Block, which is a list of
|
||||
// - Instruction
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef spvIR_H
|
||||
#define spvIR_H
|
||||
|
||||
#include "spirv.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <optional>
|
||||
|
||||
namespace spv {
|
||||
|
||||
class Block;
|
||||
class Function;
|
||||
class Module;
|
||||
|
||||
const Id NoResult = 0;
|
||||
const Id NoType = 0;
|
||||
|
||||
const Decoration NoPrecision = DecorationMax;
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define POTENTIALLY_UNUSED __attribute__((unused))
|
||||
#else
|
||||
# define POTENTIALLY_UNUSED
|
||||
#endif
|
||||
|
||||
POTENTIALLY_UNUSED
|
||||
const MemorySemanticsMask MemorySemanticsAllMemory =
|
||||
(MemorySemanticsMask)(MemorySemanticsUniformMemoryMask |
|
||||
MemorySemanticsWorkgroupMemoryMask |
|
||||
MemorySemanticsAtomicCounterMemoryMask |
|
||||
MemorySemanticsImageMemoryMask);
|
||||
|
||||
struct IdImmediate {
|
||||
bool isId; // true if word is an Id, false if word is an immediate
|
||||
unsigned word;
|
||||
IdImmediate(bool i, unsigned w) : isId(i), word(w) {}
|
||||
};
|
||||
|
||||
//
|
||||
// SPIR-V IR instruction.
|
||||
//
|
||||
|
||||
class Instruction {
|
||||
public:
|
||||
Instruction(Id resultId, Id typeId, Op opCode) : resultId(resultId), typeId(typeId), opCode(opCode), block(nullptr) { }
|
||||
explicit Instruction(Op opCode) : resultId(NoResult), typeId(NoType), opCode(opCode), block(nullptr) { }
|
||||
virtual ~Instruction() {}
|
||||
void reserveOperands(size_t count) {
|
||||
operands.reserve(count);
|
||||
idOperand.reserve(count);
|
||||
}
|
||||
void addIdOperand(Id id) {
|
||||
// ids can't be 0
|
||||
assert(id);
|
||||
operands.push_back(id);
|
||||
idOperand.push_back(true);
|
||||
}
|
||||
// This method is potentially dangerous as it can break assumptions
|
||||
// about SSA and lack of forward references.
|
||||
void setIdOperand(unsigned idx, Id id) {
|
||||
assert(id);
|
||||
assert(idOperand[idx]);
|
||||
operands[idx] = id;
|
||||
}
|
||||
|
||||
void addImmediateOperand(unsigned int immediate) {
|
||||
operands.push_back(immediate);
|
||||
idOperand.push_back(false);
|
||||
}
|
||||
void setImmediateOperand(unsigned idx, unsigned int immediate) {
|
||||
assert(!idOperand[idx]);
|
||||
operands[idx] = immediate;
|
||||
}
|
||||
|
||||
void addStringOperand(const char* str)
|
||||
{
|
||||
unsigned int word = 0;
|
||||
unsigned int shiftAmount = 0;
|
||||
char c;
|
||||
|
||||
do {
|
||||
c = *(str++);
|
||||
word |= ((unsigned int)c) << shiftAmount;
|
||||
shiftAmount += 8;
|
||||
if (shiftAmount == 32) {
|
||||
addImmediateOperand(word);
|
||||
word = 0;
|
||||
shiftAmount = 0;
|
||||
}
|
||||
} while (c != 0);
|
||||
|
||||
// deal with partial last word
|
||||
if (shiftAmount > 0) {
|
||||
addImmediateOperand(word);
|
||||
}
|
||||
}
|
||||
bool isIdOperand(int op) const { return idOperand[op]; }
|
||||
void setBlock(Block* b) { block = b; }
|
||||
Block* getBlock() const { return block; }
|
||||
Op getOpCode() const { return opCode; }
|
||||
int getNumOperands() const
|
||||
{
|
||||
assert(operands.size() == idOperand.size());
|
||||
return (int)operands.size();
|
||||
}
|
||||
Id getResultId() const { return resultId; }
|
||||
Id getTypeId() const { return typeId; }
|
||||
Id getIdOperand(int op) const {
|
||||
assert(idOperand[op]);
|
||||
return operands[op];
|
||||
}
|
||||
unsigned int getImmediateOperand(int op) const {
|
||||
assert(!idOperand[op]);
|
||||
return operands[op];
|
||||
}
|
||||
|
||||
// Write out the binary form.
|
||||
void dump(std::vector<unsigned int>& out) const
|
||||
{
|
||||
// Compute the wordCount
|
||||
unsigned int wordCount = 1;
|
||||
if (typeId)
|
||||
++wordCount;
|
||||
if (resultId)
|
||||
++wordCount;
|
||||
wordCount += (unsigned int)operands.size();
|
||||
|
||||
// Write out the beginning of the instruction
|
||||
out.push_back(((wordCount) << WordCountShift) | opCode);
|
||||
if (typeId)
|
||||
out.push_back(typeId);
|
||||
if (resultId)
|
||||
out.push_back(resultId);
|
||||
|
||||
// Write out the operands
|
||||
for (int op = 0; op < (int)operands.size(); ++op)
|
||||
out.push_back(operands[op]);
|
||||
}
|
||||
|
||||
const char *getNameString() const {
|
||||
if (opCode == OpString) {
|
||||
return (const char *)&operands[0];
|
||||
} else {
|
||||
assert(opCode == OpName);
|
||||
return (const char *)&operands[1];
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
Instruction(const Instruction&);
|
||||
Id resultId;
|
||||
Id typeId;
|
||||
Op opCode;
|
||||
std::vector<Id> operands; // operands, both <id> and immediates (both are unsigned int)
|
||||
std::vector<bool> idOperand; // true for operands that are <id>, false for immediates
|
||||
Block* block;
|
||||
};
|
||||
|
||||
//
|
||||
// SPIR-V IR block.
|
||||
//
|
||||
|
||||
struct DebugSourceLocation {
|
||||
int line;
|
||||
int column;
|
||||
spv::Id fileId;
|
||||
};
|
||||
|
||||
class Block {
|
||||
public:
|
||||
Block(Id id, Function& parent);
|
||||
virtual ~Block()
|
||||
{
|
||||
}
|
||||
|
||||
Id getId() { return instructions.front()->getResultId(); }
|
||||
|
||||
Function& getParent() const { return parent; }
|
||||
// Returns true if the source location is actually updated.
|
||||
// Note we still need the builder to insert the line marker instruction. This is just a tracker.
|
||||
bool updateDebugSourceLocation(int line, int column, spv::Id fileId) {
|
||||
if (currentSourceLoc && currentSourceLoc->line == line && currentSourceLoc->column == column &&
|
||||
currentSourceLoc->fileId == fileId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
currentSourceLoc = DebugSourceLocation{line, column, fileId};
|
||||
return true;
|
||||
}
|
||||
// Returns true if the scope is actually updated.
|
||||
// Note we still need the builder to insert the debug scope instruction. This is just a tracker.
|
||||
bool updateDebugScope(spv::Id scopeId) {
|
||||
assert(scopeId);
|
||||
if (currentDebugScope && *currentDebugScope == scopeId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
currentDebugScope = scopeId;
|
||||
return true;
|
||||
}
|
||||
void addInstruction(std::unique_ptr<Instruction> inst);
|
||||
void addPredecessor(Block* pred) { predecessors.push_back(pred); pred->successors.push_back(this);}
|
||||
void addLocalVariable(std::unique_ptr<Instruction> inst) { localVariables.push_back(std::move(inst)); }
|
||||
const std::vector<Block*>& getPredecessors() const { return predecessors; }
|
||||
const std::vector<Block*>& getSuccessors() const { return successors; }
|
||||
std::vector<std::unique_ptr<Instruction> >& getInstructions() {
|
||||
return instructions;
|
||||
}
|
||||
const std::vector<std::unique_ptr<Instruction> >& getLocalVariables() const { return localVariables; }
|
||||
void setUnreachable() { unreachable = true; }
|
||||
bool isUnreachable() const { return unreachable; }
|
||||
// Returns the block's merge instruction, if one exists (otherwise null).
|
||||
const Instruction* getMergeInstruction() const {
|
||||
if (instructions.size() < 2) return nullptr;
|
||||
const Instruction* nextToLast = (instructions.cend() - 2)->get();
|
||||
switch (nextToLast->getOpCode()) {
|
||||
case OpSelectionMerge:
|
||||
case OpLoopMerge:
|
||||
return nextToLast;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Change this block into a canonical dead merge block. Delete instructions
|
||||
// as necessary. A canonical dead merge block has only an OpLabel and an
|
||||
// OpUnreachable.
|
||||
void rewriteAsCanonicalUnreachableMerge() {
|
||||
assert(localVariables.empty());
|
||||
// Delete all instructions except for the label.
|
||||
assert(instructions.size() > 0);
|
||||
instructions.resize(1);
|
||||
successors.clear();
|
||||
addInstruction(std::unique_ptr<Instruction>(new Instruction(OpUnreachable)));
|
||||
}
|
||||
// Change this block into a canonical dead continue target branching to the
|
||||
// given header ID. Delete instructions as necessary. A canonical dead continue
|
||||
// target has only an OpLabel and an unconditional branch back to the corresponding
|
||||
// header.
|
||||
void rewriteAsCanonicalUnreachableContinue(Block* header) {
|
||||
assert(localVariables.empty());
|
||||
// Delete all instructions except for the label.
|
||||
assert(instructions.size() > 0);
|
||||
instructions.resize(1);
|
||||
successors.clear();
|
||||
// Add OpBranch back to the header.
|
||||
assert(header != nullptr);
|
||||
Instruction* branch = new Instruction(OpBranch);
|
||||
branch->addIdOperand(header->getId());
|
||||
addInstruction(std::unique_ptr<Instruction>(branch));
|
||||
successors.push_back(header);
|
||||
}
|
||||
|
||||
bool isTerminated() const
|
||||
{
|
||||
switch (instructions.back()->getOpCode()) {
|
||||
case OpBranch:
|
||||
case OpBranchConditional:
|
||||
case OpSwitch:
|
||||
case OpKill:
|
||||
case OpTerminateInvocation:
|
||||
case OpReturn:
|
||||
case OpReturnValue:
|
||||
case OpUnreachable:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void dump(std::vector<unsigned int>& out) const
|
||||
{
|
||||
instructions[0]->dump(out);
|
||||
for (int i = 0; i < (int)localVariables.size(); ++i)
|
||||
localVariables[i]->dump(out);
|
||||
for (int i = 1; i < (int)instructions.size(); ++i)
|
||||
instructions[i]->dump(out);
|
||||
}
|
||||
|
||||
protected:
|
||||
Block(const Block&);
|
||||
Block& operator=(Block&);
|
||||
|
||||
// To enforce keeping parent and ownership in sync:
|
||||
friend Function;
|
||||
|
||||
std::vector<std::unique_ptr<Instruction> > instructions;
|
||||
std::vector<Block*> predecessors, successors;
|
||||
std::vector<std::unique_ptr<Instruction> > localVariables;
|
||||
Function& parent;
|
||||
|
||||
// Track source location of the last source location marker instruction.
|
||||
std::optional<DebugSourceLocation> currentSourceLoc;
|
||||
|
||||
// Track scope of the last debug scope instruction.
|
||||
std::optional<spv::Id> currentDebugScope;
|
||||
|
||||
// track whether this block is known to be uncreachable (not necessarily
|
||||
// true for all unreachable blocks, but should be set at least
|
||||
// for the extraneous ones introduced by the builder).
|
||||
bool unreachable;
|
||||
};
|
||||
|
||||
// The different reasons for reaching a block in the inReadableOrder traversal.
|
||||
enum ReachReason {
|
||||
// Reachable from the entry block via transfers of control, i.e. branches.
|
||||
ReachViaControlFlow = 0,
|
||||
// A continue target that is not reachable via control flow.
|
||||
ReachDeadContinue,
|
||||
// A merge block that is not reachable via control flow.
|
||||
ReachDeadMerge
|
||||
};
|
||||
|
||||
// Traverses the control-flow graph rooted at root in an order suited for
|
||||
// readable code generation. Invokes callback at every node in the traversal
|
||||
// order. The callback arguments are:
|
||||
// - the block,
|
||||
// - the reason we reached the block,
|
||||
// - if the reason was that block is an unreachable continue or unreachable merge block
|
||||
// then the last parameter is the corresponding header block.
|
||||
void inReadableOrder(Block* root, std::function<void(Block*, ReachReason, Block* header)> callback);
|
||||
|
||||
//
|
||||
// SPIR-V IR Function.
|
||||
//
|
||||
|
||||
class Function {
|
||||
public:
|
||||
Function(Id id, Id resultType, Id functionType, Id firstParam, LinkageType linkage, const std::string& name, Module& parent);
|
||||
virtual ~Function()
|
||||
{
|
||||
for (int i = 0; i < (int)parameterInstructions.size(); ++i)
|
||||
delete parameterInstructions[i];
|
||||
|
||||
for (int i = 0; i < (int)blocks.size(); ++i)
|
||||
delete blocks[i];
|
||||
}
|
||||
Id getId() const { return functionInstruction.getResultId(); }
|
||||
Id getParamId(int p) const { return parameterInstructions[p]->getResultId(); }
|
||||
Id getParamType(int p) const { return parameterInstructions[p]->getTypeId(); }
|
||||
|
||||
void addBlock(Block* block) { blocks.push_back(block); }
|
||||
void removeBlock(Block* block)
|
||||
{
|
||||
auto found = find(blocks.begin(), blocks.end(), block);
|
||||
assert(found != blocks.end());
|
||||
blocks.erase(found);
|
||||
delete block;
|
||||
}
|
||||
|
||||
Module& getParent() const { return parent; }
|
||||
Block* getEntryBlock() const { return blocks.front(); }
|
||||
Block* getLastBlock() const { return blocks.back(); }
|
||||
const std::vector<Block*>& getBlocks() const { return blocks; }
|
||||
void addLocalVariable(std::unique_ptr<Instruction> inst);
|
||||
Id getReturnType() const { return functionInstruction.getTypeId(); }
|
||||
Id getFuncId() const { return functionInstruction.getResultId(); }
|
||||
Id getFuncTypeId() const { return functionInstruction.getIdOperand(1); }
|
||||
void setReturnPrecision(Decoration precision)
|
||||
{
|
||||
if (precision == DecorationRelaxedPrecision)
|
||||
reducedPrecisionReturn = true;
|
||||
}
|
||||
Decoration getReturnPrecision() const
|
||||
{ return reducedPrecisionReturn ? DecorationRelaxedPrecision : NoPrecision; }
|
||||
|
||||
void setDebugLineInfo(Id fileName, int line, int column) {
|
||||
lineInstruction = std::unique_ptr<Instruction>{new Instruction(OpLine)};
|
||||
lineInstruction->reserveOperands(3);
|
||||
lineInstruction->addIdOperand(fileName);
|
||||
lineInstruction->addImmediateOperand(line);
|
||||
lineInstruction->addImmediateOperand(column);
|
||||
}
|
||||
bool hasDebugLineInfo() const { return lineInstruction != nullptr; }
|
||||
|
||||
void setImplicitThis() { implicitThis = true; }
|
||||
bool hasImplicitThis() const { return implicitThis; }
|
||||
|
||||
void addParamPrecision(unsigned param, Decoration precision)
|
||||
{
|
||||
if (precision == DecorationRelaxedPrecision)
|
||||
reducedPrecisionParams.insert(param);
|
||||
}
|
||||
Decoration getParamPrecision(unsigned param) const
|
||||
{
|
||||
return reducedPrecisionParams.find(param) != reducedPrecisionParams.end() ?
|
||||
DecorationRelaxedPrecision : NoPrecision;
|
||||
}
|
||||
|
||||
void dump(std::vector<unsigned int>& out) const
|
||||
{
|
||||
// OpLine
|
||||
if (lineInstruction != nullptr) {
|
||||
lineInstruction->dump(out);
|
||||
}
|
||||
|
||||
// OpFunction
|
||||
functionInstruction.dump(out);
|
||||
|
||||
// OpFunctionParameter
|
||||
for (int p = 0; p < (int)parameterInstructions.size(); ++p)
|
||||
parameterInstructions[p]->dump(out);
|
||||
|
||||
// Blocks
|
||||
inReadableOrder(blocks[0], [&out](const Block* b, ReachReason, Block*) { b->dump(out); });
|
||||
Instruction end(0, 0, OpFunctionEnd);
|
||||
end.dump(out);
|
||||
}
|
||||
|
||||
LinkageType getLinkType() const { return linkType; }
|
||||
const char* getExportName() const { return exportName.c_str(); }
|
||||
|
||||
protected:
|
||||
Function(const Function&);
|
||||
Function& operator=(Function&);
|
||||
|
||||
Module& parent;
|
||||
std::unique_ptr<Instruction> lineInstruction;
|
||||
Instruction functionInstruction;
|
||||
std::vector<Instruction*> parameterInstructions;
|
||||
std::vector<Block*> blocks;
|
||||
bool implicitThis; // true if this is a member function expecting to be passed a 'this' as the first argument
|
||||
bool reducedPrecisionReturn;
|
||||
std::set<int> reducedPrecisionParams; // list of parameter indexes that need a relaxed precision arg
|
||||
LinkageType linkType;
|
||||
std::string exportName;
|
||||
};
|
||||
|
||||
//
|
||||
// SPIR-V IR Module.
|
||||
//
|
||||
|
||||
class Module {
|
||||
public:
|
||||
Module() {}
|
||||
virtual ~Module()
|
||||
{
|
||||
// TODO delete things
|
||||
}
|
||||
|
||||
void addFunction(Function *fun) { functions.push_back(fun); }
|
||||
|
||||
void mapInstruction(Instruction *instruction)
|
||||
{
|
||||
spv::Id resultId = instruction->getResultId();
|
||||
// map the instruction's result id
|
||||
if (resultId >= idToInstruction.size())
|
||||
idToInstruction.resize(resultId + 16);
|
||||
idToInstruction[resultId] = instruction;
|
||||
}
|
||||
|
||||
Instruction* getInstruction(Id id) const { return idToInstruction[id]; }
|
||||
const std::vector<Function*>& getFunctions() const { return functions; }
|
||||
spv::Id getTypeId(Id resultId) const {
|
||||
return idToInstruction[resultId] == nullptr ? NoType : idToInstruction[resultId]->getTypeId();
|
||||
}
|
||||
StorageClass getStorageClass(Id typeId) const
|
||||
{
|
||||
assert(idToInstruction[typeId]->getOpCode() == spv::OpTypePointer);
|
||||
return (StorageClass)idToInstruction[typeId]->getImmediateOperand(0);
|
||||
}
|
||||
|
||||
void dump(std::vector<unsigned int>& out) const
|
||||
{
|
||||
for (int f = 0; f < (int)functions.size(); ++f)
|
||||
functions[f]->dump(out);
|
||||
}
|
||||
|
||||
protected:
|
||||
Module(const Module&);
|
||||
std::vector<Function*> functions;
|
||||
|
||||
// map from result id to instruction having that result id
|
||||
std::vector<Instruction*> idToInstruction;
|
||||
|
||||
// map from a result id to its type id
|
||||
};
|
||||
|
||||
//
|
||||
// Implementation (it's here due to circular type definitions).
|
||||
//
|
||||
|
||||
// Add both
|
||||
// - the OpFunction instruction
|
||||
// - all the OpFunctionParameter instructions
|
||||
__inline Function::Function(Id id, Id resultType, Id functionType, Id firstParamId, LinkageType linkage, const std::string& name, Module& parent)
|
||||
: parent(parent), lineInstruction(nullptr),
|
||||
functionInstruction(id, resultType, OpFunction), implicitThis(false),
|
||||
reducedPrecisionReturn(false),
|
||||
linkType(linkage)
|
||||
{
|
||||
// OpFunction
|
||||
functionInstruction.reserveOperands(2);
|
||||
functionInstruction.addImmediateOperand(FunctionControlMaskNone);
|
||||
functionInstruction.addIdOperand(functionType);
|
||||
parent.mapInstruction(&functionInstruction);
|
||||
parent.addFunction(this);
|
||||
|
||||
// OpFunctionParameter
|
||||
Instruction* typeInst = parent.getInstruction(functionType);
|
||||
int numParams = typeInst->getNumOperands() - 1;
|
||||
for (int p = 0; p < numParams; ++p) {
|
||||
Instruction* param = new Instruction(firstParamId + p, typeInst->getIdOperand(p + 1), OpFunctionParameter);
|
||||
parent.mapInstruction(param);
|
||||
parameterInstructions.push_back(param);
|
||||
}
|
||||
|
||||
// If importing/exporting, save the function name (without the mangled parameters) for the linkage decoration
|
||||
if (linkType != LinkageTypeMax) {
|
||||
exportName = name.substr(0, name.find_first_of('('));
|
||||
}
|
||||
}
|
||||
|
||||
__inline void Function::addLocalVariable(std::unique_ptr<Instruction> inst)
|
||||
{
|
||||
Instruction* raw_instruction = inst.get();
|
||||
blocks[0]->addLocalVariable(std::move(inst));
|
||||
parent.mapInstruction(raw_instruction);
|
||||
}
|
||||
|
||||
__inline Block::Block(Id id, Function& parent) : parent(parent), unreachable(false)
|
||||
{
|
||||
instructions.push_back(std::unique_ptr<Instruction>(new Instruction(id, NoType, OpLabel)));
|
||||
instructions.back()->setBlock(this);
|
||||
parent.getParent().mapInstruction(instructions.back().get());
|
||||
}
|
||||
|
||||
__inline void Block::addInstruction(std::unique_ptr<Instruction> inst)
|
||||
{
|
||||
Instruction* raw_instruction = inst.get();
|
||||
instructions.push_back(std::move(inst));
|
||||
raw_instruction->setBlock(this);
|
||||
if (raw_instruction->getResultId())
|
||||
parent.getParent().mapInstruction(raw_instruction);
|
||||
}
|
||||
|
||||
} // end spv namespace
|
||||
|
||||
#endif // spvIR_H
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef __ANDROID_DEBUG_H__
|
||||
#define __ANDROID_DEBUG_H__
|
||||
|
||||
// Redirect printf() to Android log
|
||||
// Put this file into CFLAGS: "-include ../android_debug.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <android/log.h>
|
||||
|
||||
//#define printf(...) __android_log_print(ANDROID_LOG_INFO, "LIBGL", __VA_ARGS__)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,647 @@
|
||||
//
|
||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||
// Copyright (C) 2017 ARM Limited.
|
||||
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#ifndef _BASICTYPES_INCLUDED_
|
||||
#define _BASICTYPES_INCLUDED_
|
||||
|
||||
namespace glslang {
|
||||
|
||||
//
|
||||
// Basic type. Arrays, vectors, sampler details, etc., are orthogonal to this.
|
||||
//
|
||||
enum TBasicType {
|
||||
EbtVoid,
|
||||
EbtFloat,
|
||||
EbtDouble,
|
||||
EbtFloat16,
|
||||
EbtInt8,
|
||||
EbtUint8,
|
||||
EbtInt16,
|
||||
EbtUint16,
|
||||
EbtInt,
|
||||
EbtUint,
|
||||
EbtInt64,
|
||||
EbtUint64,
|
||||
EbtBool,
|
||||
EbtAtomicUint,
|
||||
EbtSampler,
|
||||
EbtStruct,
|
||||
EbtBlock,
|
||||
EbtAccStruct,
|
||||
EbtReference,
|
||||
EbtRayQuery,
|
||||
EbtHitObjectNV,
|
||||
EbtCoopmat,
|
||||
EbtFunction,
|
||||
EbtTensorLayoutNV,
|
||||
EbtTensorViewNV,
|
||||
// SPIR-V type defined by spirv_type
|
||||
EbtSpirvType,
|
||||
|
||||
// HLSL types that live only temporarily.
|
||||
EbtString,
|
||||
|
||||
EbtNumTypes
|
||||
};
|
||||
|
||||
//
|
||||
// Storage qualifiers. Should align with different kinds of storage or
|
||||
// resource or GLSL storage qualifier. Expansion is deprecated.
|
||||
//
|
||||
// N.B.: You probably DON'T want to add anything here, but rather just add it
|
||||
// to the built-in variables. See the comment above TBuiltInVariable.
|
||||
//
|
||||
// A new built-in variable will normally be an existing qualifier, like 'in', 'out', etc.
|
||||
// DO NOT follow the design pattern of, say EvqInstanceId, etc.
|
||||
//
|
||||
enum TStorageQualifier {
|
||||
EvqTemporary, // For temporaries (within a function), read/write
|
||||
EvqGlobal, // For globals read/write
|
||||
EvqConst, // User-defined constant values, will be semantically constant and constant folded
|
||||
EvqVaryingIn, // pipeline input, read only, also supercategory for all built-ins not included in this enum (see TBuiltInVariable)
|
||||
EvqVaryingOut, // pipeline output, read/write, also supercategory for all built-ins not included in this enum (see TBuiltInVariable)
|
||||
EvqUniform, // read only, shared with app
|
||||
EvqBuffer, // read/write, shared with app
|
||||
EvqShared, // compute shader's read/write 'shared' qualifier
|
||||
EvqSpirvStorageClass, // spirv_storage_class
|
||||
|
||||
EvqPayload,
|
||||
EvqPayloadIn,
|
||||
EvqHitAttr,
|
||||
EvqCallableData,
|
||||
EvqCallableDataIn,
|
||||
EvqHitObjectAttrNV,
|
||||
|
||||
EvqtaskPayloadSharedEXT,
|
||||
|
||||
// parameters
|
||||
EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter
|
||||
EvqOut, // also, for 'out' in the grammar before we know if it's a pipeline output or an 'out' parameter
|
||||
EvqInOut,
|
||||
EvqConstReadOnly, // input; also other read-only types having neither a constant value nor constant-value semantics
|
||||
|
||||
// built-ins read by vertex shader
|
||||
EvqVertexId,
|
||||
EvqInstanceId,
|
||||
|
||||
// built-ins written by vertex shader
|
||||
EvqPosition,
|
||||
EvqPointSize,
|
||||
EvqClipVertex,
|
||||
|
||||
// built-ins read by fragment shader
|
||||
EvqFace,
|
||||
EvqFragCoord,
|
||||
EvqPointCoord,
|
||||
|
||||
// built-ins written by fragment shader
|
||||
EvqFragColor,
|
||||
EvqFragDepth,
|
||||
EvqFragStencil,
|
||||
|
||||
EvqTileImageEXT,
|
||||
|
||||
// end of list
|
||||
EvqLast
|
||||
};
|
||||
|
||||
//
|
||||
// Subcategories of the TStorageQualifier, simply to give a direct mapping
|
||||
// between built-in variable names and an numerical value (the enum).
|
||||
//
|
||||
// For backward compatibility, there is some redundancy between the
|
||||
// TStorageQualifier and these. Existing members should both be maintained accurately.
|
||||
// However, any new built-in variable (and any existing non-redundant one)
|
||||
// must follow the pattern that the specific built-in is here, and only its
|
||||
// general qualifier is in TStorageQualifier.
|
||||
//
|
||||
// Something like gl_Position, which is sometimes 'in' and sometimes 'out'
|
||||
// shows up as two different built-in variables in a single stage, but
|
||||
// only has a single enum in TBuiltInVariable, so both the
|
||||
// TStorageQualifier and the TBuitinVariable are needed to distinguish
|
||||
// between them.
|
||||
//
|
||||
enum TBuiltInVariable {
|
||||
EbvNone,
|
||||
EbvNumWorkGroups,
|
||||
EbvWorkGroupSize,
|
||||
EbvWorkGroupId,
|
||||
EbvLocalInvocationId,
|
||||
EbvGlobalInvocationId,
|
||||
EbvLocalInvocationIndex,
|
||||
EbvNumSubgroups,
|
||||
EbvSubgroupID,
|
||||
EbvSubGroupSize,
|
||||
EbvSubGroupInvocation,
|
||||
EbvSubGroupEqMask,
|
||||
EbvSubGroupGeMask,
|
||||
EbvSubGroupGtMask,
|
||||
EbvSubGroupLeMask,
|
||||
EbvSubGroupLtMask,
|
||||
EbvSubgroupSize2,
|
||||
EbvSubgroupInvocation2,
|
||||
EbvSubgroupEqMask2,
|
||||
EbvSubgroupGeMask2,
|
||||
EbvSubgroupGtMask2,
|
||||
EbvSubgroupLeMask2,
|
||||
EbvSubgroupLtMask2,
|
||||
EbvVertexId,
|
||||
EbvInstanceId,
|
||||
EbvVertexIndex,
|
||||
EbvInstanceIndex,
|
||||
EbvBaseVertex,
|
||||
EbvBaseInstance,
|
||||
EbvDrawId,
|
||||
EbvPosition,
|
||||
EbvPointSize,
|
||||
EbvClipVertex,
|
||||
EbvClipDistance,
|
||||
EbvCullDistance,
|
||||
EbvNormal,
|
||||
EbvVertex,
|
||||
EbvMultiTexCoord0,
|
||||
EbvMultiTexCoord1,
|
||||
EbvMultiTexCoord2,
|
||||
EbvMultiTexCoord3,
|
||||
EbvMultiTexCoord4,
|
||||
EbvMultiTexCoord5,
|
||||
EbvMultiTexCoord6,
|
||||
EbvMultiTexCoord7,
|
||||
EbvFrontColor,
|
||||
EbvBackColor,
|
||||
EbvFrontSecondaryColor,
|
||||
EbvBackSecondaryColor,
|
||||
EbvTexCoord,
|
||||
EbvFogFragCoord,
|
||||
EbvInvocationId,
|
||||
EbvPrimitiveId,
|
||||
EbvLayer,
|
||||
EbvViewportIndex,
|
||||
EbvPatchVertices,
|
||||
EbvTessLevelOuter,
|
||||
EbvTessLevelInner,
|
||||
EbvBoundingBox,
|
||||
EbvTessCoord,
|
||||
EbvColor,
|
||||
EbvSecondaryColor,
|
||||
EbvFace,
|
||||
EbvFragCoord,
|
||||
EbvPointCoord,
|
||||
EbvFragColor,
|
||||
EbvFragData,
|
||||
EbvFragDepth,
|
||||
EbvFragStencilRef,
|
||||
EbvSampleId,
|
||||
EbvSamplePosition,
|
||||
EbvSampleMask,
|
||||
EbvHelperInvocation,
|
||||
|
||||
EbvBaryCoordNoPersp,
|
||||
EbvBaryCoordNoPerspCentroid,
|
||||
EbvBaryCoordNoPerspSample,
|
||||
EbvBaryCoordSmooth,
|
||||
EbvBaryCoordSmoothCentroid,
|
||||
EbvBaryCoordSmoothSample,
|
||||
EbvBaryCoordPullModel,
|
||||
|
||||
EbvViewIndex,
|
||||
EbvDeviceIndex,
|
||||
|
||||
EbvShadingRateKHR,
|
||||
EbvPrimitiveShadingRateKHR,
|
||||
|
||||
EbvFragSizeEXT,
|
||||
EbvFragInvocationCountEXT,
|
||||
|
||||
EbvSecondaryFragDataEXT,
|
||||
EbvSecondaryFragColorEXT,
|
||||
|
||||
EbvViewportMaskNV,
|
||||
EbvSecondaryPositionNV,
|
||||
EbvSecondaryViewportMaskNV,
|
||||
EbvPositionPerViewNV,
|
||||
EbvViewportMaskPerViewNV,
|
||||
EbvFragFullyCoveredNV,
|
||||
EbvFragmentSizeNV,
|
||||
EbvInvocationsPerPixelNV,
|
||||
// ray tracing
|
||||
EbvLaunchId,
|
||||
EbvLaunchSize,
|
||||
EbvInstanceCustomIndex,
|
||||
EbvGeometryIndex,
|
||||
EbvWorldRayOrigin,
|
||||
EbvWorldRayDirection,
|
||||
EbvObjectRayOrigin,
|
||||
EbvObjectRayDirection,
|
||||
EbvRayTmin,
|
||||
EbvRayTmax,
|
||||
EbvCullMask,
|
||||
EbvHitKind,
|
||||
EbvObjectToWorld,
|
||||
EbvObjectToWorld3x4,
|
||||
EbvWorldToObject,
|
||||
EbvWorldToObject3x4,
|
||||
EbvIncomingRayFlags,
|
||||
EbvCurrentRayTimeNV,
|
||||
// barycentrics
|
||||
EbvBaryCoordNV,
|
||||
EbvBaryCoordNoPerspNV,
|
||||
EbvBaryCoordEXT,
|
||||
EbvBaryCoordNoPerspEXT,
|
||||
// mesh shaders
|
||||
EbvTaskCountNV,
|
||||
EbvPrimitiveCountNV,
|
||||
EbvPrimitiveIndicesNV,
|
||||
EbvClipDistancePerViewNV,
|
||||
EbvCullDistancePerViewNV,
|
||||
EbvLayerPerViewNV,
|
||||
EbvMeshViewCountNV,
|
||||
EbvMeshViewIndicesNV,
|
||||
|
||||
EbvMicroTrianglePositionNV,
|
||||
EbvMicroTriangleBaryNV,
|
||||
EbvHitKindFrontFacingMicroTriangleNV,
|
||||
EbvHitKindBackFacingMicroTriangleNV,
|
||||
|
||||
//GL_EXT_mesh_shader
|
||||
EbvPrimitivePointIndicesEXT,
|
||||
EbvPrimitiveLineIndicesEXT,
|
||||
EbvPrimitiveTriangleIndicesEXT,
|
||||
EbvCullPrimitiveEXT,
|
||||
|
||||
// sm builtins
|
||||
EbvWarpsPerSM,
|
||||
EbvSMCount,
|
||||
EbvWarpID,
|
||||
EbvSMID,
|
||||
|
||||
// HLSL built-ins that live only temporarily, until they get remapped
|
||||
// to one of the above.
|
||||
EbvFragDepthGreater,
|
||||
EbvFragDepthLesser,
|
||||
EbvGsOutputStream,
|
||||
EbvOutputPatch,
|
||||
EbvInputPatch,
|
||||
|
||||
// structbuffer types
|
||||
EbvAppendConsume, // no need to differentiate append and consume
|
||||
EbvRWStructuredBuffer,
|
||||
EbvStructuredBuffer,
|
||||
EbvByteAddressBuffer,
|
||||
EbvRWByteAddressBuffer,
|
||||
|
||||
// ARM specific core builtins
|
||||
EbvCoreCountARM,
|
||||
EbvCoreIDARM,
|
||||
EbvCoreMaxIDARM,
|
||||
EbvWarpIDARM,
|
||||
EbvWarpMaxIDARM,
|
||||
|
||||
EbvPositionFetch,
|
||||
|
||||
EbvLast
|
||||
};
|
||||
|
||||
// In this enum, order matters; users can assume higher precision is a bigger value
|
||||
// and EpqNone is 0.
|
||||
enum TPrecisionQualifier {
|
||||
EpqNone = 0,
|
||||
EpqLow,
|
||||
EpqMedium,
|
||||
EpqHigh
|
||||
};
|
||||
|
||||
// These will show up in error messages
|
||||
__inline const char* GetStorageQualifierString(TStorageQualifier q)
|
||||
{
|
||||
switch (q) {
|
||||
case EvqTemporary: return "temp"; break;
|
||||
case EvqGlobal: return "global"; break;
|
||||
case EvqConst: return "const"; break;
|
||||
case EvqConstReadOnly: return "const (read only)"; break;
|
||||
case EvqSpirvStorageClass: return "spirv_storage_class"; break;
|
||||
case EvqVaryingIn: return "in"; break;
|
||||
case EvqVaryingOut: return "out"; break;
|
||||
case EvqUniform: return "uniform"; break;
|
||||
case EvqBuffer: return "buffer"; break;
|
||||
case EvqShared: return "shared"; break;
|
||||
case EvqIn: return "in"; break;
|
||||
case EvqOut: return "out"; break;
|
||||
case EvqInOut: return "inout"; break;
|
||||
case EvqVertexId: return "gl_VertexId"; break;
|
||||
case EvqInstanceId: return "gl_InstanceId"; break;
|
||||
case EvqPosition: return "gl_Position"; break;
|
||||
case EvqPointSize: return "gl_PointSize"; break;
|
||||
case EvqClipVertex: return "gl_ClipVertex"; break;
|
||||
case EvqFace: return "gl_FrontFacing"; break;
|
||||
case EvqFragCoord: return "gl_FragCoord"; break;
|
||||
case EvqPointCoord: return "gl_PointCoord"; break;
|
||||
case EvqFragColor: return "fragColor"; break;
|
||||
case EvqFragDepth: return "gl_FragDepth"; break;
|
||||
case EvqFragStencil: return "gl_FragStencilRefARB"; break;
|
||||
case EvqPayload: return "rayPayloadNV"; break;
|
||||
case EvqPayloadIn: return "rayPayloadInNV"; break;
|
||||
case EvqHitAttr: return "hitAttributeNV"; break;
|
||||
case EvqCallableData: return "callableDataNV"; break;
|
||||
case EvqCallableDataIn: return "callableDataInNV"; break;
|
||||
case EvqtaskPayloadSharedEXT: return "taskPayloadSharedEXT"; break;
|
||||
case EvqHitObjectAttrNV:return "hitObjectAttributeNV"; break;
|
||||
default: return "unknown qualifier";
|
||||
}
|
||||
}
|
||||
|
||||
__inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
||||
{
|
||||
switch (v) {
|
||||
case EbvNone: return "";
|
||||
case EbvNumWorkGroups: return "NumWorkGroups";
|
||||
case EbvWorkGroupSize: return "WorkGroupSize";
|
||||
case EbvWorkGroupId: return "WorkGroupID";
|
||||
case EbvLocalInvocationId: return "LocalInvocationID";
|
||||
case EbvGlobalInvocationId: return "GlobalInvocationID";
|
||||
case EbvLocalInvocationIndex: return "LocalInvocationIndex";
|
||||
case EbvNumSubgroups: return "NumSubgroups";
|
||||
case EbvSubgroupID: return "SubgroupID";
|
||||
case EbvSubGroupSize: return "SubGroupSize";
|
||||
case EbvSubGroupInvocation: return "SubGroupInvocation";
|
||||
case EbvSubGroupEqMask: return "SubGroupEqMask";
|
||||
case EbvSubGroupGeMask: return "SubGroupGeMask";
|
||||
case EbvSubGroupGtMask: return "SubGroupGtMask";
|
||||
case EbvSubGroupLeMask: return "SubGroupLeMask";
|
||||
case EbvSubGroupLtMask: return "SubGroupLtMask";
|
||||
case EbvSubgroupSize2: return "SubgroupSize";
|
||||
case EbvSubgroupInvocation2: return "SubgroupInvocationID";
|
||||
case EbvSubgroupEqMask2: return "SubgroupEqMask";
|
||||
case EbvSubgroupGeMask2: return "SubgroupGeMask";
|
||||
case EbvSubgroupGtMask2: return "SubgroupGtMask";
|
||||
case EbvSubgroupLeMask2: return "SubgroupLeMask";
|
||||
case EbvSubgroupLtMask2: return "SubgroupLtMask";
|
||||
case EbvVertexId: return "VertexId";
|
||||
case EbvInstanceId: return "InstanceId";
|
||||
case EbvVertexIndex: return "VertexIndex";
|
||||
case EbvInstanceIndex: return "InstanceIndex";
|
||||
case EbvBaseVertex: return "BaseVertex";
|
||||
case EbvBaseInstance: return "BaseInstance";
|
||||
case EbvDrawId: return "DrawId";
|
||||
case EbvPosition: return "Position";
|
||||
case EbvPointSize: return "PointSize";
|
||||
case EbvClipVertex: return "ClipVertex";
|
||||
case EbvClipDistance: return "ClipDistance";
|
||||
case EbvCullDistance: return "CullDistance";
|
||||
case EbvNormal: return "Normal";
|
||||
case EbvVertex: return "Vertex";
|
||||
case EbvMultiTexCoord0: return "MultiTexCoord0";
|
||||
case EbvMultiTexCoord1: return "MultiTexCoord1";
|
||||
case EbvMultiTexCoord2: return "MultiTexCoord2";
|
||||
case EbvMultiTexCoord3: return "MultiTexCoord3";
|
||||
case EbvMultiTexCoord4: return "MultiTexCoord4";
|
||||
case EbvMultiTexCoord5: return "MultiTexCoord5";
|
||||
case EbvMultiTexCoord6: return "MultiTexCoord6";
|
||||
case EbvMultiTexCoord7: return "MultiTexCoord7";
|
||||
case EbvFrontColor: return "FrontColor";
|
||||
case EbvBackColor: return "BackColor";
|
||||
case EbvFrontSecondaryColor: return "FrontSecondaryColor";
|
||||
case EbvBackSecondaryColor: return "BackSecondaryColor";
|
||||
case EbvTexCoord: return "TexCoord";
|
||||
case EbvFogFragCoord: return "FogFragCoord";
|
||||
case EbvInvocationId: return "InvocationID";
|
||||
case EbvPrimitiveId: return "PrimitiveID";
|
||||
case EbvLayer: return "Layer";
|
||||
case EbvViewportIndex: return "ViewportIndex";
|
||||
case EbvPatchVertices: return "PatchVertices";
|
||||
case EbvTessLevelOuter: return "TessLevelOuter";
|
||||
case EbvTessLevelInner: return "TessLevelInner";
|
||||
case EbvBoundingBox: return "BoundingBox";
|
||||
case EbvTessCoord: return "TessCoord";
|
||||
case EbvColor: return "Color";
|
||||
case EbvSecondaryColor: return "SecondaryColor";
|
||||
case EbvFace: return "Face";
|
||||
case EbvFragCoord: return "FragCoord";
|
||||
case EbvPointCoord: return "PointCoord";
|
||||
case EbvFragColor: return "FragColor";
|
||||
case EbvFragData: return "FragData";
|
||||
case EbvFragDepth: return "FragDepth";
|
||||
case EbvFragStencilRef: return "FragStencilRef";
|
||||
case EbvSampleId: return "SampleId";
|
||||
case EbvSamplePosition: return "SamplePosition";
|
||||
case EbvSampleMask: return "SampleMaskIn";
|
||||
case EbvHelperInvocation: return "HelperInvocation";
|
||||
|
||||
case EbvBaryCoordNoPersp: return "BaryCoordNoPersp";
|
||||
case EbvBaryCoordNoPerspCentroid: return "BaryCoordNoPerspCentroid";
|
||||
case EbvBaryCoordNoPerspSample: return "BaryCoordNoPerspSample";
|
||||
case EbvBaryCoordSmooth: return "BaryCoordSmooth";
|
||||
case EbvBaryCoordSmoothCentroid: return "BaryCoordSmoothCentroid";
|
||||
case EbvBaryCoordSmoothSample: return "BaryCoordSmoothSample";
|
||||
case EbvBaryCoordPullModel: return "BaryCoordPullModel";
|
||||
|
||||
case EbvViewIndex: return "ViewIndex";
|
||||
case EbvDeviceIndex: return "DeviceIndex";
|
||||
|
||||
case EbvFragSizeEXT: return "FragSizeEXT";
|
||||
case EbvFragInvocationCountEXT: return "FragInvocationCountEXT";
|
||||
|
||||
case EbvSecondaryFragDataEXT: return "SecondaryFragDataEXT";
|
||||
case EbvSecondaryFragColorEXT: return "SecondaryFragColorEXT";
|
||||
|
||||
case EbvViewportMaskNV: return "ViewportMaskNV";
|
||||
case EbvSecondaryPositionNV: return "SecondaryPositionNV";
|
||||
case EbvSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
|
||||
case EbvPositionPerViewNV: return "PositionPerViewNV";
|
||||
case EbvViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
|
||||
case EbvFragFullyCoveredNV: return "FragFullyCoveredNV";
|
||||
case EbvFragmentSizeNV: return "FragmentSizeNV";
|
||||
case EbvInvocationsPerPixelNV: return "InvocationsPerPixelNV";
|
||||
case EbvLaunchId: return "LaunchIdNV";
|
||||
case EbvLaunchSize: return "LaunchSizeNV";
|
||||
case EbvInstanceCustomIndex: return "InstanceCustomIndexNV";
|
||||
case EbvGeometryIndex: return "GeometryIndexEXT";
|
||||
case EbvWorldRayOrigin: return "WorldRayOriginNV";
|
||||
case EbvWorldRayDirection: return "WorldRayDirectionNV";
|
||||
case EbvObjectRayOrigin: return "ObjectRayOriginNV";
|
||||
case EbvObjectRayDirection: return "ObjectRayDirectionNV";
|
||||
case EbvRayTmin: return "ObjectRayTminNV";
|
||||
case EbvRayTmax: return "ObjectRayTmaxNV";
|
||||
case EbvHitKind: return "HitKindNV";
|
||||
case EbvIncomingRayFlags: return "IncomingRayFlagsNV";
|
||||
case EbvObjectToWorld: return "ObjectToWorldNV";
|
||||
case EbvWorldToObject: return "WorldToObjectNV";
|
||||
case EbvCurrentRayTimeNV: return "CurrentRayTimeNV";
|
||||
|
||||
case EbvBaryCoordEXT:
|
||||
case EbvBaryCoordNV: return "BaryCoordKHR";
|
||||
case EbvBaryCoordNoPerspEXT:
|
||||
case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspKHR";
|
||||
|
||||
case EbvTaskCountNV: return "TaskCountNV";
|
||||
case EbvPrimitiveCountNV: return "PrimitiveCountNV";
|
||||
case EbvPrimitiveIndicesNV: return "PrimitiveIndicesNV";
|
||||
case EbvClipDistancePerViewNV: return "ClipDistancePerViewNV";
|
||||
case EbvCullDistancePerViewNV: return "CullDistancePerViewNV";
|
||||
case EbvLayerPerViewNV: return "LayerPerViewNV";
|
||||
case EbvMeshViewCountNV: return "MeshViewCountNV";
|
||||
case EbvMeshViewIndicesNV: return "MeshViewIndicesNV";
|
||||
// GL_EXT_mesh_shader
|
||||
case EbvPrimitivePointIndicesEXT: return "PrimitivePointIndicesEXT";
|
||||
case EbvPrimitiveLineIndicesEXT: return "PrimitiveLineIndicesEXT";
|
||||
case EbvPrimitiveTriangleIndicesEXT: return "PrimitiveTriangleIndicesEXT";
|
||||
case EbvCullPrimitiveEXT: return "CullPrimitiveEXT";
|
||||
|
||||
case EbvWarpsPerSM: return "WarpsPerSMNV";
|
||||
case EbvSMCount: return "SMCountNV";
|
||||
case EbvWarpID: return "WarpIDNV";
|
||||
case EbvSMID: return "SMIDNV";
|
||||
|
||||
case EbvShadingRateKHR: return "ShadingRateKHR";
|
||||
case EbvPrimitiveShadingRateKHR: return "PrimitiveShadingRateKHR";
|
||||
|
||||
case EbvHitKindFrontFacingMicroTriangleNV: return "HitKindFrontFacingMicroTriangleNV";
|
||||
case EbvHitKindBackFacingMicroTriangleNV: return "HitKindBackFacingMicroTriangleNV";
|
||||
|
||||
default: return "unknown built-in variable";
|
||||
}
|
||||
}
|
||||
|
||||
__inline const char* GetPrecisionQualifierString(TPrecisionQualifier p)
|
||||
{
|
||||
switch (p) {
|
||||
case EpqNone: return ""; break;
|
||||
case EpqLow: return "lowp"; break;
|
||||
case EpqMedium: return "mediump"; break;
|
||||
case EpqHigh: return "highp"; break;
|
||||
default: return "unknown precision qualifier";
|
||||
}
|
||||
}
|
||||
|
||||
__inline bool isTypeSignedInt(TBasicType type)
|
||||
{
|
||||
switch (type) {
|
||||
case EbtInt8:
|
||||
case EbtInt16:
|
||||
case EbtInt:
|
||||
case EbtInt64:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
__inline bool isTypeUnsignedInt(TBasicType type)
|
||||
{
|
||||
switch (type) {
|
||||
case EbtUint8:
|
||||
case EbtUint16:
|
||||
case EbtUint:
|
||||
case EbtUint64:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
__inline bool isTypeInt(TBasicType type)
|
||||
{
|
||||
return isTypeSignedInt(type) || isTypeUnsignedInt(type);
|
||||
}
|
||||
|
||||
__inline bool isTypeFloat(TBasicType type)
|
||||
{
|
||||
switch (type) {
|
||||
case EbtFloat:
|
||||
case EbtDouble:
|
||||
case EbtFloat16:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
__inline uint32_t GetNumBits(TBasicType type)
|
||||
{
|
||||
switch (type) {
|
||||
case EbtInt8:
|
||||
case EbtUint8:
|
||||
return 8;
|
||||
case EbtFloat16:
|
||||
case EbtInt16:
|
||||
case EbtUint16:
|
||||
return 16;
|
||||
case EbtInt:
|
||||
case EbtUint:
|
||||
case EbtFloat:
|
||||
return 32;
|
||||
case EbtDouble:
|
||||
case EbtInt64:
|
||||
case EbtUint64:
|
||||
return 64;
|
||||
default:
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
__inline int getTypeRank(TBasicType type)
|
||||
{
|
||||
int res = -1;
|
||||
switch(type) {
|
||||
case EbtInt8:
|
||||
case EbtUint8:
|
||||
res = 0;
|
||||
break;
|
||||
case EbtInt16:
|
||||
case EbtUint16:
|
||||
res = 1;
|
||||
break;
|
||||
case EbtInt:
|
||||
case EbtUint:
|
||||
res = 2;
|
||||
break;
|
||||
case EbtInt64:
|
||||
case EbtUint64:
|
||||
res = 3;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
#endif // _BASICTYPES_INCLUDED_
|
||||
@@ -0,0 +1,307 @@
|
||||
//
|
||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#ifndef _COMMON_INCLUDED_
|
||||
#define _COMMON_INCLUDED_
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#ifdef _MSC_VER
|
||||
#include <cfloat>
|
||||
#else
|
||||
#include <cmath>
|
||||
#endif
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#include <sstream>
|
||||
namespace std {
|
||||
template<typename T>
|
||||
std::string to_string(const T& val) {
|
||||
std::ostringstream os;
|
||||
os << val;
|
||||
return os.str();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MINGW_HAS_SECURE_API) && MINGW_HAS_SECURE_API
|
||||
#include <basetsd.h>
|
||||
#ifndef snprintf
|
||||
#define snprintf sprintf_s
|
||||
#endif
|
||||
#define safe_vsprintf(buf,max,format,args) vsnprintf_s((buf), (max), (max), (format), (args))
|
||||
#elif defined (solaris)
|
||||
#define safe_vsprintf(buf,max,format,args) vsnprintf((buf), (max), (format), (args))
|
||||
#include <sys/int_types.h>
|
||||
#define UINT_PTR uintptr_t
|
||||
#else
|
||||
#define safe_vsprintf(buf,max,format,args) vsnprintf((buf), (max), (format), (args))
|
||||
#include <stdint.h>
|
||||
#define UINT_PTR uintptr_t
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
|
||||
/* windows only pragma */
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4786) // Don't warn about too long identifiers
|
||||
#pragma warning(disable : 4514) // unused inline method
|
||||
#pragma warning(disable : 4201) // nameless union
|
||||
#endif
|
||||
|
||||
// Allow compilation to WASI which does not support threads yet.
|
||||
#ifdef __wasi__
|
||||
#define DISABLE_THREAD_SUPPORT
|
||||
#endif
|
||||
|
||||
#include "PoolAlloc.h"
|
||||
|
||||
//
|
||||
// Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
|
||||
//
|
||||
#define POOL_ALLOCATOR_NEW_DELETE(A) \
|
||||
void* operator new(size_t s) { return (A).allocate(s); } \
|
||||
void* operator new(size_t, void *_Where) { return (_Where); } \
|
||||
void operator delete(void*) { } \
|
||||
void operator delete(void *, void *) { } \
|
||||
void* operator new[](size_t s) { return (A).allocate(s); } \
|
||||
void* operator new[](size_t, void *_Where) { return (_Where); } \
|
||||
void operator delete[](void*) { } \
|
||||
void operator delete[](void *, void *) { }
|
||||
|
||||
namespace glslang {
|
||||
|
||||
//
|
||||
// Pool version of string.
|
||||
//
|
||||
typedef pool_allocator<char> TStringAllocator;
|
||||
typedef std::basic_string <char, std::char_traits<char>, TStringAllocator> TString;
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
// Repackage the std::hash for use by unordered map/set with a TString key.
|
||||
namespace std {
|
||||
|
||||
template<> struct hash<glslang::TString> {
|
||||
std::size_t operator()(const glslang::TString& s) const
|
||||
{
|
||||
const unsigned _FNV_offset_basis = 2166136261U;
|
||||
const unsigned _FNV_prime = 16777619U;
|
||||
unsigned _Val = _FNV_offset_basis;
|
||||
size_t _Count = s.size();
|
||||
const char* _First = s.c_str();
|
||||
for (size_t _Next = 0; _Next < _Count; ++_Next)
|
||||
{
|
||||
_Val ^= (unsigned)_First[_Next];
|
||||
_Val *= _FNV_prime;
|
||||
}
|
||||
|
||||
return _Val;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace glslang {
|
||||
|
||||
inline TString* NewPoolTString(const char* s)
|
||||
{
|
||||
void* memory = GetThreadPoolAllocator().allocate(sizeof(TString));
|
||||
return new(memory) TString(s);
|
||||
}
|
||||
|
||||
template<class T> inline T* NewPoolObject(T*)
|
||||
{
|
||||
return new(GetThreadPoolAllocator().allocate(sizeof(T))) T;
|
||||
}
|
||||
|
||||
template<class T> inline T* NewPoolObject(T, int instances)
|
||||
{
|
||||
return new(GetThreadPoolAllocator().allocate(instances * sizeof(T))) T[instances];
|
||||
}
|
||||
|
||||
inline bool StartsWith(TString const &str, const char *prefix)
|
||||
{
|
||||
return str.compare(0, strlen(prefix), prefix) == 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Pool allocator versions of vectors, lists, and maps
|
||||
//
|
||||
template <class T> class TVector : public std::vector<T, pool_allocator<T> > {
|
||||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
|
||||
typedef typename std::vector<T, pool_allocator<T> >::size_type size_type;
|
||||
TVector() : std::vector<T, pool_allocator<T> >() {}
|
||||
TVector(const pool_allocator<T>& a) : std::vector<T, pool_allocator<T> >(a) {}
|
||||
TVector(size_type i) : std::vector<T, pool_allocator<T> >(i) {}
|
||||
TVector(size_type i, const T& val) : std::vector<T, pool_allocator<T> >(i, val) {}
|
||||
};
|
||||
|
||||
template <class T> class TList : public std::list<T, pool_allocator<T> > {
|
||||
};
|
||||
|
||||
template <class K, class D, class CMP = std::less<K> >
|
||||
class TMap : public std::map<K, D, CMP, pool_allocator<std::pair<K const, D> > > {
|
||||
};
|
||||
|
||||
template <class K, class D, class HASH = std::hash<K>, class PRED = std::equal_to<K> >
|
||||
class TUnorderedMap : public std::unordered_map<K, D, HASH, PRED, pool_allocator<std::pair<K const, D> > > {
|
||||
};
|
||||
|
||||
template <class K, class CMP = std::less<K> >
|
||||
class TSet : public std::set<K, CMP, pool_allocator<K> > {
|
||||
};
|
||||
|
||||
//
|
||||
// Persistent string memory. Should only be used for strings that survive
|
||||
// across compiles/links.
|
||||
//
|
||||
typedef std::basic_string<char> TPersistString;
|
||||
|
||||
//
|
||||
// templatized min and max functions.
|
||||
//
|
||||
template <class T> T Min(const T a, const T b) { return a < b ? a : b; }
|
||||
template <class T> T Max(const T a, const T b) { return a > b ? a : b; }
|
||||
|
||||
//
|
||||
// Create a TString object from an integer.
|
||||
//
|
||||
#if defined(_MSC_VER) || (defined(MINGW_HAS_SECURE_API) && MINGW_HAS_SECURE_API)
|
||||
inline const TString String(const int i, const int base = 10)
|
||||
{
|
||||
char text[16]; // 32 bit ints are at most 10 digits in base 10
|
||||
_itoa_s(i, text, sizeof(text), base);
|
||||
return text;
|
||||
}
|
||||
#else
|
||||
inline const TString String(const int i, const int /*base*/ = 10)
|
||||
{
|
||||
char text[16]; // 32 bit ints are at most 10 digits in base 10
|
||||
|
||||
// we assume base 10 for all cases
|
||||
snprintf(text, sizeof(text), "%d", i);
|
||||
|
||||
return text;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct TSourceLoc {
|
||||
void init()
|
||||
{
|
||||
name = nullptr; string = 0; line = 0; column = 0;
|
||||
}
|
||||
void init(int stringNum) { init(); string = stringNum; }
|
||||
// Returns the name if it exists. Otherwise, returns the string number.
|
||||
std::string getStringNameOrNum(bool quoteStringName = true) const
|
||||
{
|
||||
if (name != nullptr) {
|
||||
TString qstr = quoteStringName ? ("\"" + *name + "\"") : *name;
|
||||
std::string ret_str(qstr.c_str());
|
||||
return ret_str;
|
||||
}
|
||||
return std::to_string((long long)string);
|
||||
}
|
||||
const char* getFilename() const
|
||||
{
|
||||
if (name == nullptr)
|
||||
return nullptr;
|
||||
return name->c_str();
|
||||
}
|
||||
const char* getFilenameStr() const { return name == nullptr ? "" : name->c_str(); }
|
||||
TString* name; // descriptive name for this string, when a textual name is available, otherwise nullptr
|
||||
int string;
|
||||
int line;
|
||||
int column;
|
||||
};
|
||||
|
||||
class TPragmaTable : public TMap<TString, TString> {
|
||||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
};
|
||||
|
||||
const int MaxTokenLength = 1024;
|
||||
|
||||
template <class T> bool IsPow2(T powerOf2)
|
||||
{
|
||||
if (powerOf2 <= 0)
|
||||
return false;
|
||||
|
||||
return (powerOf2 & (powerOf2 - 1)) == 0;
|
||||
}
|
||||
|
||||
// Round number up to a multiple of the given powerOf2, which is not
|
||||
// a power, just a number that must be a power of 2.
|
||||
template <class T> void RoundToPow2(T& number, int powerOf2)
|
||||
{
|
||||
assert(IsPow2(powerOf2));
|
||||
number = (number + powerOf2 - 1) & ~(powerOf2 - 1);
|
||||
}
|
||||
|
||||
template <class T> bool IsMultipleOfPow2(T number, int powerOf2)
|
||||
{
|
||||
assert(IsPow2(powerOf2));
|
||||
return ! (number & (powerOf2 - 1));
|
||||
}
|
||||
|
||||
// Returns log2 of an integer power of 2.
|
||||
// T should be integral.
|
||||
template <class T> int IntLog2(T n)
|
||||
{
|
||||
assert(IsPow2(n));
|
||||
int result = 0;
|
||||
while ((T(1) << result) != n) {
|
||||
result++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
#endif // _COMMON_INCLUDED_
|
||||
@@ -0,0 +1,938 @@
|
||||
//
|
||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||
// Copyright (C) 2013 LunarG, Inc.
|
||||
// Copyright (C) 2017 ARM Limited.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#ifndef _CONSTANT_UNION_INCLUDED_
|
||||
#define _CONSTANT_UNION_INCLUDED_
|
||||
|
||||
#include "../Include/Common.h"
|
||||
#include "../Include/BaseTypes.h"
|
||||
|
||||
namespace glslang {
|
||||
|
||||
class TConstUnion {
|
||||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
|
||||
TConstUnion() : iConst(0), type(EbtInt) { }
|
||||
|
||||
void setI8Const(signed char i)
|
||||
{
|
||||
i8Const = i;
|
||||
type = EbtInt8;
|
||||
}
|
||||
|
||||
void setU8Const(unsigned char u)
|
||||
{
|
||||
u8Const = u;
|
||||
type = EbtUint8;
|
||||
}
|
||||
|
||||
void setI16Const(signed short i)
|
||||
{
|
||||
i16Const = i;
|
||||
type = EbtInt16;
|
||||
}
|
||||
|
||||
void setU16Const(unsigned short u)
|
||||
{
|
||||
u16Const = u;
|
||||
type = EbtUint16;
|
||||
}
|
||||
|
||||
void setIConst(int i)
|
||||
{
|
||||
iConst = i;
|
||||
type = EbtInt;
|
||||
}
|
||||
|
||||
void setUConst(unsigned int u)
|
||||
{
|
||||
uConst = u;
|
||||
type = EbtUint;
|
||||
}
|
||||
|
||||
void setI64Const(long long i64)
|
||||
{
|
||||
i64Const = i64;
|
||||
type = EbtInt64;
|
||||
}
|
||||
|
||||
void setU64Const(unsigned long long u64)
|
||||
{
|
||||
u64Const = u64;
|
||||
type = EbtUint64;
|
||||
}
|
||||
|
||||
void setDConst(double d)
|
||||
{
|
||||
dConst = d;
|
||||
type = EbtDouble;
|
||||
}
|
||||
|
||||
void setBConst(bool b)
|
||||
{
|
||||
bConst = b;
|
||||
type = EbtBool;
|
||||
}
|
||||
|
||||
void setSConst(const TString* s)
|
||||
{
|
||||
sConst = s;
|
||||
type = EbtString;
|
||||
}
|
||||
|
||||
signed char getI8Const() const { return i8Const; }
|
||||
unsigned char getU8Const() const { return u8Const; }
|
||||
signed short getI16Const() const { return i16Const; }
|
||||
unsigned short getU16Const() const { return u16Const; }
|
||||
int getIConst() const { return iConst; }
|
||||
unsigned int getUConst() const { return uConst; }
|
||||
long long getI64Const() const { return i64Const; }
|
||||
unsigned long long getU64Const() const { return u64Const; }
|
||||
double getDConst() const { return dConst; }
|
||||
bool getBConst() const { return bConst; }
|
||||
const TString* getSConst() const { return sConst; }
|
||||
|
||||
bool operator==(const signed char i) const
|
||||
{
|
||||
if (i == i8Const)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const unsigned char u) const
|
||||
{
|
||||
if (u == u8Const)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const signed short i) const
|
||||
{
|
||||
if (i == i16Const)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const unsigned short u) const
|
||||
{
|
||||
if (u == u16Const)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const int i) const
|
||||
{
|
||||
if (i == iConst)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const unsigned int u) const
|
||||
{
|
||||
if (u == uConst)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const long long i64) const
|
||||
{
|
||||
if (i64 == i64Const)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const unsigned long long u64) const
|
||||
{
|
||||
if (u64 == u64Const)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const double d) const
|
||||
{
|
||||
if (d == dConst)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const bool b) const
|
||||
{
|
||||
if (b == bConst)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const TConstUnion& constant) const
|
||||
{
|
||||
if (constant.type != type)
|
||||
return false;
|
||||
|
||||
switch (type) {
|
||||
case EbtInt:
|
||||
if (constant.iConst == iConst)
|
||||
return true;
|
||||
|
||||
break;
|
||||
case EbtUint:
|
||||
if (constant.uConst == uConst)
|
||||
return true;
|
||||
|
||||
break;
|
||||
case EbtBool:
|
||||
if (constant.bConst == bConst)
|
||||
return true;
|
||||
|
||||
break;
|
||||
case EbtDouble:
|
||||
if (constant.dConst == dConst)
|
||||
return true;
|
||||
|
||||
break;
|
||||
|
||||
case EbtInt16:
|
||||
if (constant.i16Const == i16Const)
|
||||
return true;
|
||||
|
||||
break;
|
||||
case EbtUint16:
|
||||
if (constant.u16Const == u16Const)
|
||||
return true;
|
||||
|
||||
break;
|
||||
case EbtInt8:
|
||||
if (constant.i8Const == i8Const)
|
||||
return true;
|
||||
|
||||
break;
|
||||
case EbtUint8:
|
||||
if (constant.u8Const == u8Const)
|
||||
return true;
|
||||
|
||||
break;
|
||||
case EbtInt64:
|
||||
if (constant.i64Const == i64Const)
|
||||
return true;
|
||||
|
||||
break;
|
||||
case EbtUint64:
|
||||
if (constant.u64Const == u64Const)
|
||||
return true;
|
||||
|
||||
break;
|
||||
default:
|
||||
assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator!=(const signed char i) const
|
||||
{
|
||||
return !operator==(i);
|
||||
}
|
||||
|
||||
bool operator!=(const unsigned char u) const
|
||||
{
|
||||
return !operator==(u);
|
||||
}
|
||||
|
||||
bool operator!=(const signed short i) const
|
||||
{
|
||||
return !operator==(i);
|
||||
}
|
||||
|
||||
bool operator!=(const unsigned short u) const
|
||||
{
|
||||
return !operator==(u);
|
||||
}
|
||||
|
||||
bool operator!=(const int i) const
|
||||
{
|
||||
return !operator==(i);
|
||||
}
|
||||
|
||||
bool operator!=(const unsigned int u) const
|
||||
{
|
||||
return !operator==(u);
|
||||
}
|
||||
|
||||
bool operator!=(const long long i) const
|
||||
{
|
||||
return !operator==(i);
|
||||
}
|
||||
|
||||
bool operator!=(const unsigned long long u) const
|
||||
{
|
||||
return !operator==(u);
|
||||
}
|
||||
|
||||
bool operator!=(const float f) const
|
||||
{
|
||||
return !operator==(f);
|
||||
}
|
||||
|
||||
bool operator!=(const bool b) const
|
||||
{
|
||||
return !operator==(b);
|
||||
}
|
||||
|
||||
bool operator!=(const TConstUnion& constant) const
|
||||
{
|
||||
return !operator==(constant);
|
||||
}
|
||||
|
||||
bool operator>(const TConstUnion& constant) const
|
||||
{
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt:
|
||||
if (iConst > constant.iConst)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
case EbtUint:
|
||||
if (uConst > constant.uConst)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
case EbtDouble:
|
||||
if (dConst > constant.dConst)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
case EbtInt8:
|
||||
if (i8Const > constant.i8Const)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
case EbtUint8:
|
||||
if (u8Const > constant.u8Const)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
case EbtInt16:
|
||||
if (i16Const > constant.i16Const)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
case EbtUint16:
|
||||
if (u16Const > constant.u16Const)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
case EbtInt64:
|
||||
if (i64Const > constant.i64Const)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
case EbtUint64:
|
||||
if (u64Const > constant.u64Const)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
default:
|
||||
assert(false && "Default missing");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator<(const TConstUnion& constant) const
|
||||
{
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt8:
|
||||
if (i8Const < constant.i8Const)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
case EbtUint8:
|
||||
if (u8Const < constant.u8Const)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
case EbtInt16:
|
||||
if (i16Const < constant.i16Const)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
case EbtUint16:
|
||||
if (u16Const < constant.u16Const)
|
||||
return true;
|
||||
return false;
|
||||
case EbtInt64:
|
||||
if (i64Const < constant.i64Const)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
case EbtUint64:
|
||||
if (u64Const < constant.u64Const)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
case EbtDouble:
|
||||
if (dConst < constant.dConst)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
case EbtInt:
|
||||
if (iConst < constant.iConst)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
case EbtUint:
|
||||
if (uConst < constant.uConst)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
default:
|
||||
assert(false && "Default missing");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
TConstUnion operator+(const TConstUnion& constant) const
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(iConst + constant.iConst); break;
|
||||
case EbtUint: returnValue.setUConst(uConst + constant.uConst); break;
|
||||
case EbtDouble: returnValue.setDConst(dConst + constant.dConst); break;
|
||||
case EbtInt8: returnValue.setI8Const(i8Const + constant.i8Const); break;
|
||||
case EbtInt16: returnValue.setI16Const(i16Const + constant.i16Const); break;
|
||||
case EbtInt64: returnValue.setI64Const(i64Const + constant.i64Const); break;
|
||||
case EbtUint8: returnValue.setU8Const(u8Const + constant.u8Const); break;
|
||||
case EbtUint16: returnValue.setU16Const(u16Const + constant.u16Const); break;
|
||||
case EbtUint64: returnValue.setU64Const(u64Const + constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
TConstUnion operator-(const TConstUnion& constant) const
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(iConst - constant.iConst); break;
|
||||
case EbtUint: returnValue.setUConst(uConst - constant.uConst); break;
|
||||
case EbtDouble: returnValue.setDConst(dConst - constant.dConst); break;
|
||||
case EbtInt8: returnValue.setI8Const(i8Const - constant.i8Const); break;
|
||||
case EbtInt16: returnValue.setI16Const(i16Const - constant.i16Const); break;
|
||||
case EbtInt64: returnValue.setI64Const(i64Const - constant.i64Const); break;
|
||||
case EbtUint8: returnValue.setU8Const(u8Const - constant.u8Const); break;
|
||||
case EbtUint16: returnValue.setU16Const(u16Const - constant.u16Const); break;
|
||||
case EbtUint64: returnValue.setU64Const(u64Const - constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
TConstUnion operator*(const TConstUnion& constant) const
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(iConst * constant.iConst); break;
|
||||
case EbtUint: returnValue.setUConst(uConst * constant.uConst); break;
|
||||
case EbtDouble: returnValue.setDConst(dConst * constant.dConst); break;
|
||||
case EbtInt8: returnValue.setI8Const(i8Const * constant.i8Const); break;
|
||||
case EbtInt16: returnValue.setI16Const(i16Const * constant.i16Const); break;
|
||||
case EbtInt64: returnValue.setI64Const(i64Const * constant.i64Const); break;
|
||||
case EbtUint8: returnValue.setU8Const(u8Const * constant.u8Const); break;
|
||||
case EbtUint16: returnValue.setU16Const(u16Const * constant.u16Const); break;
|
||||
case EbtUint64: returnValue.setU64Const(u64Const * constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
TConstUnion operator%(const TConstUnion& constant) const
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(iConst % constant.iConst); break;
|
||||
case EbtUint: returnValue.setUConst(uConst % constant.uConst); break;
|
||||
case EbtInt8: returnValue.setI8Const(i8Const % constant.i8Const); break;
|
||||
case EbtInt16: returnValue.setI16Const(i16Const % constant.i16Const); break;
|
||||
case EbtInt64: returnValue.setI64Const(i64Const % constant.i64Const); break;
|
||||
case EbtUint8: returnValue.setU8Const(u8Const % constant.u8Const); break;
|
||||
case EbtUint16: returnValue.setU16Const(u16Const % constant.u16Const); break;
|
||||
case EbtUint64: returnValue.setU64Const(u64Const % constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
TConstUnion operator>>(const TConstUnion& constant) const
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
switch (type) {
|
||||
case EbtInt8:
|
||||
switch (constant.type) {
|
||||
case EbtInt8: returnValue.setI8Const(i8Const >> constant.i8Const); break;
|
||||
case EbtUint8: returnValue.setI8Const(i8Const >> constant.u8Const); break;
|
||||
case EbtInt16: returnValue.setI8Const(i8Const >> constant.i16Const); break;
|
||||
case EbtUint16: returnValue.setI8Const(i8Const >> constant.u16Const); break;
|
||||
case EbtInt: returnValue.setI8Const(i8Const >> constant.iConst); break;
|
||||
case EbtUint: returnValue.setI8Const(i8Const >> constant.uConst); break;
|
||||
case EbtInt64: returnValue.setI8Const(i8Const >> constant.i64Const); break;
|
||||
case EbtUint64: returnValue.setI8Const(i8Const >> constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
break;
|
||||
case EbtUint8:
|
||||
switch (constant.type) {
|
||||
case EbtInt8: returnValue.setU8Const(u8Const >> constant.i8Const); break;
|
||||
case EbtUint8: returnValue.setU8Const(u8Const >> constant.u8Const); break;
|
||||
case EbtInt16: returnValue.setU8Const(u8Const >> constant.i16Const); break;
|
||||
case EbtUint16: returnValue.setU8Const(u8Const >> constant.u16Const); break;
|
||||
case EbtInt: returnValue.setU8Const(u8Const >> constant.iConst); break;
|
||||
case EbtUint: returnValue.setU8Const(u8Const >> constant.uConst); break;
|
||||
case EbtInt64: returnValue.setU8Const(u8Const >> constant.i64Const); break;
|
||||
case EbtUint64: returnValue.setU8Const(u8Const >> constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
break;
|
||||
case EbtInt16:
|
||||
switch (constant.type) {
|
||||
case EbtInt8: returnValue.setI16Const(i16Const >> constant.i8Const); break;
|
||||
case EbtUint8: returnValue.setI16Const(i16Const >> constant.u8Const); break;
|
||||
case EbtInt16: returnValue.setI16Const(i16Const >> constant.i16Const); break;
|
||||
case EbtUint16: returnValue.setI16Const(i16Const >> constant.u16Const); break;
|
||||
case EbtInt: returnValue.setI16Const(i16Const >> constant.iConst); break;
|
||||
case EbtUint: returnValue.setI16Const(i16Const >> constant.uConst); break;
|
||||
case EbtInt64: returnValue.setI16Const(i16Const >> constant.i64Const); break;
|
||||
case EbtUint64: returnValue.setI16Const(i16Const >> constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
break;
|
||||
case EbtUint16:
|
||||
switch (constant.type) {
|
||||
case EbtInt8: returnValue.setU16Const(u16Const >> constant.i8Const); break;
|
||||
case EbtUint8: returnValue.setU16Const(u16Const >> constant.u8Const); break;
|
||||
case EbtInt16: returnValue.setU16Const(u16Const >> constant.i16Const); break;
|
||||
case EbtUint16: returnValue.setU16Const(u16Const >> constant.u16Const); break;
|
||||
case EbtInt: returnValue.setU16Const(u16Const >> constant.iConst); break;
|
||||
case EbtUint: returnValue.setU16Const(u16Const >> constant.uConst); break;
|
||||
case EbtInt64: returnValue.setU16Const(u16Const >> constant.i64Const); break;
|
||||
case EbtUint64: returnValue.setU16Const(u16Const >> constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
break;
|
||||
case EbtInt:
|
||||
switch (constant.type) {
|
||||
case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break;
|
||||
case EbtUint: returnValue.setIConst(iConst >> constant.uConst); break;
|
||||
case EbtInt8: returnValue.setIConst(iConst >> constant.i8Const); break;
|
||||
case EbtUint8: returnValue.setIConst(iConst >> constant.u8Const); break;
|
||||
case EbtInt16: returnValue.setIConst(iConst >> constant.i16Const); break;
|
||||
case EbtUint16: returnValue.setIConst(iConst >> constant.u16Const); break;
|
||||
case EbtInt64: returnValue.setIConst(iConst >> constant.i64Const); break;
|
||||
case EbtUint64: returnValue.setIConst(iConst >> constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
break;
|
||||
case EbtUint:
|
||||
switch (constant.type) {
|
||||
case EbtInt: returnValue.setUConst(uConst >> constant.iConst); break;
|
||||
case EbtUint: returnValue.setUConst(uConst >> constant.uConst); break;
|
||||
case EbtInt8: returnValue.setUConst(uConst >> constant.i8Const); break;
|
||||
case EbtUint8: returnValue.setUConst(uConst >> constant.u8Const); break;
|
||||
case EbtInt16: returnValue.setUConst(uConst >> constant.i16Const); break;
|
||||
case EbtUint16: returnValue.setUConst(uConst >> constant.u16Const); break;
|
||||
case EbtInt64: returnValue.setUConst(uConst >> constant.i64Const); break;
|
||||
case EbtUint64: returnValue.setUConst(uConst >> constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
break;
|
||||
case EbtInt64:
|
||||
switch (constant.type) {
|
||||
case EbtInt8: returnValue.setI64Const(i64Const >> constant.i8Const); break;
|
||||
case EbtUint8: returnValue.setI64Const(i64Const >> constant.u8Const); break;
|
||||
case EbtInt16: returnValue.setI64Const(i64Const >> constant.i16Const); break;
|
||||
case EbtUint16: returnValue.setI64Const(i64Const >> constant.u16Const); break;
|
||||
case EbtInt: returnValue.setI64Const(i64Const >> constant.iConst); break;
|
||||
case EbtUint: returnValue.setI64Const(i64Const >> constant.uConst); break;
|
||||
case EbtInt64: returnValue.setI64Const(i64Const >> constant.i64Const); break;
|
||||
case EbtUint64: returnValue.setI64Const(i64Const >> constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
break;
|
||||
case EbtUint64:
|
||||
switch (constant.type) {
|
||||
case EbtInt8: returnValue.setU64Const(u64Const >> constant.i8Const); break;
|
||||
case EbtUint8: returnValue.setU64Const(u64Const >> constant.u8Const); break;
|
||||
case EbtInt16: returnValue.setU64Const(u64Const >> constant.i16Const); break;
|
||||
case EbtUint16: returnValue.setU64Const(u64Const >> constant.u16Const); break;
|
||||
case EbtInt: returnValue.setU64Const(u64Const >> constant.iConst); break;
|
||||
case EbtUint: returnValue.setU64Const(u64Const >> constant.uConst); break;
|
||||
case EbtInt64: returnValue.setU64Const(u64Const >> constant.i64Const); break;
|
||||
case EbtUint64: returnValue.setU64Const(u64Const >> constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
TConstUnion operator<<(const TConstUnion& constant) const
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
switch (type) {
|
||||
case EbtInt8:
|
||||
switch (constant.type) {
|
||||
case EbtInt8: returnValue.setI8Const(i8Const << constant.i8Const); break;
|
||||
case EbtUint8: returnValue.setI8Const(i8Const << constant.u8Const); break;
|
||||
case EbtInt16: returnValue.setI8Const(i8Const << constant.i16Const); break;
|
||||
case EbtUint16: returnValue.setI8Const(i8Const << constant.u16Const); break;
|
||||
case EbtInt: returnValue.setI8Const(i8Const << constant.iConst); break;
|
||||
case EbtUint: returnValue.setI8Const(i8Const << constant.uConst); break;
|
||||
case EbtInt64: returnValue.setI8Const(i8Const << constant.i64Const); break;
|
||||
case EbtUint64: returnValue.setI8Const(i8Const << constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
break;
|
||||
case EbtUint8:
|
||||
switch (constant.type) {
|
||||
case EbtInt8: returnValue.setU8Const(u8Const << constant.i8Const); break;
|
||||
case EbtUint8: returnValue.setU8Const(u8Const << constant.u8Const); break;
|
||||
case EbtInt16: returnValue.setU8Const(u8Const << constant.i16Const); break;
|
||||
case EbtUint16: returnValue.setU8Const(u8Const << constant.u16Const); break;
|
||||
case EbtInt: returnValue.setU8Const(u8Const << constant.iConst); break;
|
||||
case EbtUint: returnValue.setU8Const(u8Const << constant.uConst); break;
|
||||
case EbtInt64: returnValue.setU8Const(u8Const << constant.i64Const); break;
|
||||
case EbtUint64: returnValue.setU8Const(u8Const << constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
break;
|
||||
case EbtInt16:
|
||||
switch (constant.type) {
|
||||
case EbtInt8: returnValue.setI16Const(i16Const << constant.i8Const); break;
|
||||
case EbtUint8: returnValue.setI16Const(i16Const << constant.u8Const); break;
|
||||
case EbtInt16: returnValue.setI16Const(i16Const << constant.i16Const); break;
|
||||
case EbtUint16: returnValue.setI16Const(i16Const << constant.u16Const); break;
|
||||
case EbtInt: returnValue.setI16Const(i16Const << constant.iConst); break;
|
||||
case EbtUint: returnValue.setI16Const(i16Const << constant.uConst); break;
|
||||
case EbtInt64: returnValue.setI16Const(i16Const << constant.i64Const); break;
|
||||
case EbtUint64: returnValue.setI16Const(i16Const << constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
break;
|
||||
case EbtUint16:
|
||||
switch (constant.type) {
|
||||
case EbtInt8: returnValue.setU16Const(u16Const << constant.i8Const); break;
|
||||
case EbtUint8: returnValue.setU16Const(u16Const << constant.u8Const); break;
|
||||
case EbtInt16: returnValue.setU16Const(u16Const << constant.i16Const); break;
|
||||
case EbtUint16: returnValue.setU16Const(u16Const << constant.u16Const); break;
|
||||
case EbtInt: returnValue.setU16Const(u16Const << constant.iConst); break;
|
||||
case EbtUint: returnValue.setU16Const(u16Const << constant.uConst); break;
|
||||
case EbtInt64: returnValue.setU16Const(u16Const << constant.i64Const); break;
|
||||
case EbtUint64: returnValue.setU16Const(u16Const << constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
break;
|
||||
case EbtInt64:
|
||||
switch (constant.type) {
|
||||
case EbtInt8: returnValue.setI64Const(i64Const << constant.i8Const); break;
|
||||
case EbtUint8: returnValue.setI64Const(i64Const << constant.u8Const); break;
|
||||
case EbtInt16: returnValue.setI64Const(i64Const << constant.i16Const); break;
|
||||
case EbtUint16: returnValue.setI64Const(i64Const << constant.u16Const); break;
|
||||
case EbtInt: returnValue.setI64Const(i64Const << constant.iConst); break;
|
||||
case EbtUint: returnValue.setI64Const(i64Const << constant.uConst); break;
|
||||
case EbtInt64: returnValue.setI64Const(i64Const << constant.i64Const); break;
|
||||
case EbtUint64: returnValue.setI64Const(i64Const << constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
break;
|
||||
case EbtUint64:
|
||||
switch (constant.type) {
|
||||
case EbtInt8: returnValue.setU64Const(u64Const << constant.i8Const); break;
|
||||
case EbtUint8: returnValue.setU64Const(u64Const << constant.u8Const); break;
|
||||
case EbtInt16: returnValue.setU64Const(u64Const << constant.i16Const); break;
|
||||
case EbtUint16: returnValue.setU64Const(u64Const << constant.u16Const); break;
|
||||
case EbtInt: returnValue.setU64Const(u64Const << constant.iConst); break;
|
||||
case EbtUint: returnValue.setU64Const(u64Const << constant.uConst); break;
|
||||
case EbtInt64: returnValue.setU64Const(u64Const << constant.i64Const); break;
|
||||
case EbtUint64: returnValue.setU64Const(u64Const << constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
break;
|
||||
case EbtInt:
|
||||
switch (constant.type) {
|
||||
case EbtInt: returnValue.setIConst(iConst << constant.iConst); break;
|
||||
case EbtUint: returnValue.setIConst(iConst << constant.uConst); break;
|
||||
case EbtInt8: returnValue.setIConst(iConst << constant.i8Const); break;
|
||||
case EbtUint8: returnValue.setIConst(iConst << constant.u8Const); break;
|
||||
case EbtInt16: returnValue.setIConst(iConst << constant.i16Const); break;
|
||||
case EbtUint16: returnValue.setIConst(iConst << constant.u16Const); break;
|
||||
case EbtInt64: returnValue.setIConst(iConst << constant.i64Const); break;
|
||||
case EbtUint64: returnValue.setIConst(iConst << constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
break;
|
||||
case EbtUint:
|
||||
switch (constant.type) {
|
||||
case EbtInt: returnValue.setUConst(uConst << constant.iConst); break;
|
||||
case EbtUint: returnValue.setUConst(uConst << constant.uConst); break;
|
||||
case EbtInt8: returnValue.setUConst(uConst << constant.i8Const); break;
|
||||
case EbtUint8: returnValue.setUConst(uConst << constant.u8Const); break;
|
||||
case EbtInt16: returnValue.setUConst(uConst << constant.i16Const); break;
|
||||
case EbtUint16: returnValue.setUConst(uConst << constant.u16Const); break;
|
||||
case EbtInt64: returnValue.setUConst(uConst << constant.i64Const); break;
|
||||
case EbtUint64: returnValue.setUConst(uConst << constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
TConstUnion operator&(const TConstUnion& constant) const
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(iConst & constant.iConst); break;
|
||||
case EbtUint: returnValue.setUConst(uConst & constant.uConst); break;
|
||||
case EbtInt8: returnValue.setI8Const(i8Const & constant.i8Const); break;
|
||||
case EbtUint8: returnValue.setU8Const(u8Const & constant.u8Const); break;
|
||||
case EbtInt16: returnValue.setI16Const(i16Const & constant.i16Const); break;
|
||||
case EbtUint16: returnValue.setU16Const(u16Const & constant.u16Const); break;
|
||||
case EbtInt64: returnValue.setI64Const(i64Const & constant.i64Const); break;
|
||||
case EbtUint64: returnValue.setU64Const(u64Const & constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
TConstUnion operator|(const TConstUnion& constant) const
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(iConst | constant.iConst); break;
|
||||
case EbtUint: returnValue.setUConst(uConst | constant.uConst); break;
|
||||
case EbtInt8: returnValue.setI8Const(i8Const | constant.i8Const); break;
|
||||
case EbtUint8: returnValue.setU8Const(u8Const | constant.u8Const); break;
|
||||
case EbtInt16: returnValue.setI16Const(i16Const | constant.i16Const); break;
|
||||
case EbtUint16: returnValue.setU16Const(u16Const | constant.u16Const); break;
|
||||
case EbtInt64: returnValue.setI64Const(i64Const | constant.i64Const); break;
|
||||
case EbtUint64: returnValue.setU64Const(u64Const | constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
TConstUnion operator^(const TConstUnion& constant) const
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break;
|
||||
case EbtUint: returnValue.setUConst(uConst ^ constant.uConst); break;
|
||||
case EbtInt8: returnValue.setI8Const(i8Const ^ constant.i8Const); break;
|
||||
case EbtUint8: returnValue.setU8Const(u8Const ^ constant.u8Const); break;
|
||||
case EbtInt16: returnValue.setI16Const(i16Const ^ constant.i16Const); break;
|
||||
case EbtUint16: returnValue.setU16Const(u16Const ^ constant.u16Const); break;
|
||||
case EbtInt64: returnValue.setI64Const(i64Const ^ constant.i64Const); break;
|
||||
case EbtUint64: returnValue.setU64Const(u64Const ^ constant.u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
TConstUnion operator~() const
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
switch (type) {
|
||||
case EbtInt: returnValue.setIConst(~iConst); break;
|
||||
case EbtUint: returnValue.setUConst(~uConst); break;
|
||||
case EbtInt8: returnValue.setI8Const(~i8Const); break;
|
||||
case EbtUint8: returnValue.setU8Const(~u8Const); break;
|
||||
case EbtInt16: returnValue.setI16Const(~i16Const); break;
|
||||
case EbtUint16: returnValue.setU16Const(~u16Const); break;
|
||||
case EbtInt64: returnValue.setI64Const(~i64Const); break;
|
||||
case EbtUint64: returnValue.setU64Const(~u64Const); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
TConstUnion operator&&(const TConstUnion& constant) const
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtBool: returnValue.setBConst(bConst && constant.bConst); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
TConstUnion operator||(const TConstUnion& constant) const
|
||||
{
|
||||
TConstUnion returnValue;
|
||||
assert(type == constant.type);
|
||||
switch (type) {
|
||||
case EbtBool: returnValue.setBConst(bConst || constant.bConst); break;
|
||||
default: assert(false && "Default missing");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
TBasicType getType() const { return type; }
|
||||
|
||||
private:
|
||||
union {
|
||||
signed char i8Const; // used for i8vec, scalar int8s
|
||||
unsigned char u8Const; // used for u8vec, scalar uint8s
|
||||
signed short i16Const; // used for i16vec, scalar int16s
|
||||
unsigned short u16Const; // used for u16vec, scalar uint16s
|
||||
int iConst; // used for ivec, scalar ints
|
||||
unsigned int uConst; // used for uvec, scalar uints
|
||||
long long i64Const; // used for i64vec, scalar int64s
|
||||
unsigned long long u64Const; // used for u64vec, scalar uint64s
|
||||
bool bConst; // used for bvec, scalar bools
|
||||
double dConst; // used for vec, dvec, mat, dmat, scalar floats and doubles
|
||||
const TString* sConst; // string constant
|
||||
};
|
||||
|
||||
TBasicType type;
|
||||
};
|
||||
|
||||
// Encapsulate having a pointer to an array of TConstUnion,
|
||||
// which only needs to be allocated if its size is going to be
|
||||
// bigger than 0.
|
||||
//
|
||||
// One convenience is being able to use [] to go inside the array, instead
|
||||
// of C++ assuming it as an array of pointers to vectors.
|
||||
//
|
||||
// General usage is that the size is known up front, and it is
|
||||
// created once with the proper size.
|
||||
//
|
||||
class TConstUnionArray {
|
||||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
|
||||
TConstUnionArray() : unionArray(nullptr) { }
|
||||
virtual ~TConstUnionArray() { }
|
||||
|
||||
explicit TConstUnionArray(int size)
|
||||
{
|
||||
if (size == 0)
|
||||
unionArray = nullptr;
|
||||
else
|
||||
unionArray = new TConstUnionVector(size);
|
||||
}
|
||||
TConstUnionArray(const TConstUnionArray& a) = default;
|
||||
TConstUnionArray(const TConstUnionArray& a, int start, int size)
|
||||
{
|
||||
unionArray = new TConstUnionVector(size);
|
||||
for (int i = 0; i < size; ++i)
|
||||
(*unionArray)[i] = a[start + i];
|
||||
}
|
||||
|
||||
// Use this constructor for a smear operation
|
||||
TConstUnionArray(int size, const TConstUnion& val)
|
||||
{
|
||||
unionArray = new TConstUnionVector(size, val);
|
||||
}
|
||||
|
||||
int size() const { return unionArray ? (int)unionArray->size() : 0; }
|
||||
TConstUnion& operator[](size_t index) { return (*unionArray)[index]; }
|
||||
const TConstUnion& operator[](size_t index) const { return (*unionArray)[index]; }
|
||||
bool operator==(const TConstUnionArray& rhs) const
|
||||
{
|
||||
// this includes the case that both are unallocated
|
||||
if (unionArray == rhs.unionArray)
|
||||
return true;
|
||||
|
||||
if (! unionArray || ! rhs.unionArray)
|
||||
return false;
|
||||
|
||||
return *unionArray == *rhs.unionArray;
|
||||
}
|
||||
bool operator!=(const TConstUnionArray& rhs) const { return ! operator==(rhs); }
|
||||
|
||||
double dot(const TConstUnionArray& rhs)
|
||||
{
|
||||
assert(rhs.unionArray->size() == unionArray->size());
|
||||
double sum = 0.0;
|
||||
|
||||
for (size_t comp = 0; comp < unionArray->size(); ++comp)
|
||||
sum += (*this)[comp].getDConst() * rhs[comp].getDConst();
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
bool empty() const { return unionArray == nullptr; }
|
||||
|
||||
protected:
|
||||
typedef TVector<TConstUnion> TConstUnionVector;
|
||||
TConstUnionVector* unionArray;
|
||||
};
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
#endif // _CONSTANT_UNION_INCLUDED_
|
||||
@@ -0,0 +1,168 @@
|
||||
//
|
||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#ifndef _INFOSINK_INCLUDED_
|
||||
#define _INFOSINK_INCLUDED_
|
||||
|
||||
#include "../Include/Common.h"
|
||||
#include <filesystem>
|
||||
#include <cmath>
|
||||
|
||||
namespace glslang {
|
||||
|
||||
//
|
||||
// TPrefixType is used to centralize how info log messages start.
|
||||
// See below.
|
||||
//
|
||||
enum TPrefixType {
|
||||
EPrefixNone,
|
||||
EPrefixWarning,
|
||||
EPrefixError,
|
||||
EPrefixInternalError,
|
||||
EPrefixUnimplemented,
|
||||
EPrefixNote
|
||||
};
|
||||
|
||||
enum TOutputStream {
|
||||
ENull = 0,
|
||||
EDebugger = 0x01,
|
||||
EStdOut = 0x02,
|
||||
EString = 0x04,
|
||||
};
|
||||
//
|
||||
// Encapsulate info logs for all objects that have them.
|
||||
//
|
||||
// The methods are a general set of tools for getting a variety of
|
||||
// messages and types inserted into the log.
|
||||
//
|
||||
class TInfoSinkBase {
|
||||
public:
|
||||
TInfoSinkBase() : outputStream(4), shaderFileName(nullptr) {}
|
||||
void erase() { sink.erase(); }
|
||||
TInfoSinkBase& operator<<(const TPersistString& t) { append(t); return *this; }
|
||||
TInfoSinkBase& operator<<(char c) { append(1, c); return *this; }
|
||||
TInfoSinkBase& operator<<(const char* s) { append(s); return *this; }
|
||||
TInfoSinkBase& operator<<(int n) { append(String(n)); return *this; }
|
||||
TInfoSinkBase& operator<<(unsigned int n) { append(String(n)); return *this; }
|
||||
TInfoSinkBase& operator<<(float n) { const int size = 40; char buf[size];
|
||||
snprintf(buf, size, (fabs(n) > 1e-8 && fabs(n) < 1e8) || n == 0.0f ? "%f" : "%g", n);
|
||||
append(buf);
|
||||
return *this; }
|
||||
TInfoSinkBase& operator+(const TPersistString& t) { append(t); return *this; }
|
||||
TInfoSinkBase& operator+(const TString& t) { append(t); return *this; }
|
||||
TInfoSinkBase& operator<<(const TString& t) { append(t); return *this; }
|
||||
TInfoSinkBase& operator+(const char* s) { append(s); return *this; }
|
||||
const char* c_str() const { return sink.c_str(); }
|
||||
void prefix(TPrefixType message) {
|
||||
switch(message) {
|
||||
case EPrefixNone: break;
|
||||
case EPrefixWarning: append("WARNING: "); break;
|
||||
case EPrefixError: append("ERROR: "); break;
|
||||
case EPrefixInternalError: append("INTERNAL ERROR: "); break;
|
||||
case EPrefixUnimplemented: append("UNIMPLEMENTED: "); break;
|
||||
case EPrefixNote: append("NOTE: "); break;
|
||||
default: append("UNKNOWN ERROR: "); break;
|
||||
}
|
||||
}
|
||||
void location(const TSourceLoc& loc, bool absolute = false, bool displayColumn = false) {
|
||||
const int maxSize = 24;
|
||||
char locText[maxSize];
|
||||
if (displayColumn) {
|
||||
snprintf(locText, maxSize, ":%d:%d", loc.line, loc.column);
|
||||
} else {
|
||||
snprintf(locText, maxSize, ":%d", loc.line);
|
||||
}
|
||||
|
||||
if(loc.getFilename() == nullptr && shaderFileName != nullptr && absolute) {
|
||||
append(std::filesystem::absolute(shaderFileName).string());
|
||||
} else {
|
||||
std::string location = loc.getStringNameOrNum(false);
|
||||
if (absolute) {
|
||||
append(std::filesystem::absolute(location).string());
|
||||
} else {
|
||||
append(location);
|
||||
}
|
||||
}
|
||||
|
||||
append(locText);
|
||||
append(": ");
|
||||
}
|
||||
void message(TPrefixType message, const char* s) {
|
||||
prefix(message);
|
||||
append(s);
|
||||
append("\n");
|
||||
}
|
||||
void message(TPrefixType message, const char* s, const TSourceLoc& loc, bool absolute = false,
|
||||
bool displayColumn = false)
|
||||
{
|
||||
prefix(message);
|
||||
location(loc, absolute, displayColumn);
|
||||
append(s);
|
||||
append("\n");
|
||||
}
|
||||
|
||||
void setOutputStream(int output = 4)
|
||||
{
|
||||
outputStream = output;
|
||||
}
|
||||
|
||||
void setShaderFileName(const char* file = nullptr)
|
||||
{
|
||||
shaderFileName = file;
|
||||
}
|
||||
|
||||
protected:
|
||||
void append(const char* s);
|
||||
|
||||
void append(int count, char c);
|
||||
void append(const TPersistString& t);
|
||||
void append(const TString& t);
|
||||
|
||||
void checkMem(size_t growth) { if (sink.capacity() < sink.size() + growth + 2)
|
||||
sink.reserve(sink.capacity() + sink.capacity() / 2); }
|
||||
void appendToStream(const char* s);
|
||||
TPersistString sink;
|
||||
int outputStream;
|
||||
const char* shaderFileName;
|
||||
};
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
class TInfoSink {
|
||||
public:
|
||||
glslang::TInfoSinkBase info;
|
||||
glslang::TInfoSinkBase debug;
|
||||
};
|
||||
|
||||
#endif // _INFOSINK_INCLUDED_
|
||||
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#ifndef __INITIALIZE_GLOBALS_INCLUDED_
|
||||
#define __INITIALIZE_GLOBALS_INCLUDED_
|
||||
|
||||
namespace glslang {
|
||||
|
||||
inline bool InitializePoolIndex() { return true; } // DEPRECATED: No need to call
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
#endif // __INITIALIZE_GLOBALS_INCLUDED_
|
||||
@@ -0,0 +1,323 @@
|
||||
//
|
||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#ifndef _POOLALLOC_INCLUDED_
|
||||
#define _POOLALLOC_INCLUDED_
|
||||
|
||||
#ifndef NDEBUG
|
||||
# define GUARD_BLOCKS // define to enable guard block sanity checking
|
||||
#endif
|
||||
|
||||
//
|
||||
// This header defines an allocator that can be used to efficiently
|
||||
// allocate a large number of small requests for heap memory, with the
|
||||
// intention that they are not individually deallocated, but rather
|
||||
// collectively deallocated at one time.
|
||||
//
|
||||
// This simultaneously
|
||||
//
|
||||
// * Makes each individual allocation much more efficient; the
|
||||
// typical allocation is trivial.
|
||||
// * Completely avoids the cost of doing individual deallocation.
|
||||
// * Saves the trouble of tracking down and plugging a large class of leaks.
|
||||
//
|
||||
// Individual classes can use this allocator by supplying their own
|
||||
// new and delete methods.
|
||||
//
|
||||
// STL containers can use this allocator by using the pool_allocator
|
||||
// class as the allocator (second) template argument.
|
||||
//
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
namespace glslang {
|
||||
|
||||
// If we are using guard blocks, we must track each individual
|
||||
// allocation. If we aren't using guard blocks, these
|
||||
// never get instantiated, so won't have any impact.
|
||||
//
|
||||
|
||||
class TAllocation {
|
||||
public:
|
||||
TAllocation(size_t size, unsigned char* mem, TAllocation* prev = nullptr) :
|
||||
size(size), mem(mem), prevAlloc(prev) {
|
||||
// Allocations are bracketed:
|
||||
// [allocationHeader][initialGuardBlock][userData][finalGuardBlock]
|
||||
// This would be cleaner with if (guardBlockSize)..., but that
|
||||
// makes the compiler print warnings about 0 length memsets,
|
||||
// even with the if() protecting them.
|
||||
# ifdef GUARD_BLOCKS
|
||||
memset(preGuard(), guardBlockBeginVal, guardBlockSize);
|
||||
memset(data(), userDataFill, size);
|
||||
memset(postGuard(), guardBlockEndVal, guardBlockSize);
|
||||
# endif
|
||||
}
|
||||
|
||||
void check() const {
|
||||
checkGuardBlock(preGuard(), guardBlockBeginVal, "before");
|
||||
checkGuardBlock(postGuard(), guardBlockEndVal, "after");
|
||||
}
|
||||
|
||||
void checkAllocList() const;
|
||||
|
||||
// Return total size needed to accommodate user buffer of 'size',
|
||||
// plus our tracking data.
|
||||
inline static size_t allocationSize(size_t size) {
|
||||
return size + 2 * guardBlockSize + headerSize();
|
||||
}
|
||||
|
||||
// Offset from surrounding buffer to get to user data buffer.
|
||||
inline static unsigned char* offsetAllocation(unsigned char* m) {
|
||||
return m + guardBlockSize + headerSize();
|
||||
}
|
||||
|
||||
private:
|
||||
void checkGuardBlock(unsigned char* blockMem, unsigned char val, const char* locText) const;
|
||||
|
||||
// Find offsets to pre and post guard blocks, and user data buffer
|
||||
unsigned char* preGuard() const { return mem + headerSize(); }
|
||||
unsigned char* data() const { return preGuard() + guardBlockSize; }
|
||||
unsigned char* postGuard() const { return data() + size; }
|
||||
|
||||
size_t size; // size of the user data area
|
||||
unsigned char* mem; // beginning of our allocation (pts to header)
|
||||
TAllocation* prevAlloc; // prior allocation in the chain
|
||||
|
||||
static inline constexpr unsigned char guardBlockBeginVal = 0xfb;
|
||||
static inline constexpr unsigned char guardBlockEndVal = 0xfe;
|
||||
static inline constexpr unsigned char userDataFill = 0xcd;
|
||||
|
||||
# ifdef GUARD_BLOCKS
|
||||
static inline constexpr size_t guardBlockSize = 16;
|
||||
# else
|
||||
static inline constexpr size_t guardBlockSize = 0;
|
||||
# endif
|
||||
|
||||
# ifdef GUARD_BLOCKS
|
||||
inline static size_t headerSize() { return sizeof(TAllocation); }
|
||||
# else
|
||||
inline static size_t headerSize() { return 0; }
|
||||
# endif
|
||||
};
|
||||
|
||||
//
|
||||
// There are several stacks. One is to track the pushing and popping
|
||||
// of the user, and not yet implemented. The others are simply a
|
||||
// repositories of free pages or used pages.
|
||||
//
|
||||
// Page stacks are linked together with a simple header at the beginning
|
||||
// of each allocation obtained from the underlying OS. Multi-page allocations
|
||||
// are returned to the OS. Individual page allocations are kept for future
|
||||
// re-use.
|
||||
//
|
||||
// The "page size" used is not, nor must it match, the underlying OS
|
||||
// page size. But, having it be about that size or equal to a set of
|
||||
// pages is likely most optimal.
|
||||
//
|
||||
class TPoolAllocator {
|
||||
public:
|
||||
TPoolAllocator(int growthIncrement = 8*1024, int allocationAlignment = 16);
|
||||
|
||||
//
|
||||
// Don't call the destructor just to free up the memory, call pop()
|
||||
//
|
||||
~TPoolAllocator();
|
||||
|
||||
//
|
||||
// Call push() to establish a new place to pop memory too. Does not
|
||||
// have to be called to get things started.
|
||||
//
|
||||
void push();
|
||||
|
||||
//
|
||||
// Call pop() to free all memory allocated since the last call to push(),
|
||||
// or if no last call to push, frees all memory since first allocation.
|
||||
//
|
||||
void pop();
|
||||
|
||||
//
|
||||
// Call popAll() to free all memory allocated.
|
||||
//
|
||||
void popAll();
|
||||
|
||||
//
|
||||
// Call allocate() to actually acquire memory. Returns nullptr if no memory
|
||||
// available, otherwise a properly aligned pointer to 'numBytes' of memory.
|
||||
//
|
||||
void* allocate(size_t numBytes);
|
||||
|
||||
//
|
||||
// There is no deallocate. The point of this class is that
|
||||
// deallocation can be skipped by the user of it, as the model
|
||||
// of use is to simultaneously deallocate everything at once
|
||||
// by calling pop(), and to not have to solve memory leak problems.
|
||||
//
|
||||
|
||||
protected:
|
||||
friend struct tHeader;
|
||||
|
||||
struct tHeader {
|
||||
tHeader(tHeader* nextPage, size_t pageCount) :
|
||||
#ifdef GUARD_BLOCKS
|
||||
lastAllocation(nullptr),
|
||||
#endif
|
||||
nextPage(nextPage), pageCount(pageCount) { }
|
||||
|
||||
~tHeader() {
|
||||
#ifdef GUARD_BLOCKS
|
||||
if (lastAllocation)
|
||||
lastAllocation->checkAllocList();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef GUARD_BLOCKS
|
||||
TAllocation* lastAllocation;
|
||||
#endif
|
||||
tHeader* nextPage;
|
||||
size_t pageCount;
|
||||
};
|
||||
|
||||
struct tAllocState {
|
||||
size_t offset;
|
||||
tHeader* page;
|
||||
};
|
||||
typedef std::vector<tAllocState> tAllocStack;
|
||||
|
||||
// Track allocations if and only if we're using guard blocks
|
||||
#ifndef GUARD_BLOCKS
|
||||
void* initializeAllocation(tHeader*, unsigned char* memory, size_t) {
|
||||
#else
|
||||
void* initializeAllocation(tHeader* block, unsigned char* memory, size_t numBytes) {
|
||||
new(memory) TAllocation(numBytes, memory, block->lastAllocation);
|
||||
block->lastAllocation = reinterpret_cast<TAllocation*>(memory);
|
||||
#endif
|
||||
|
||||
// This is optimized entirely away if GUARD_BLOCKS is not defined.
|
||||
return TAllocation::offsetAllocation(memory);
|
||||
}
|
||||
|
||||
size_t pageSize; // granularity of allocation from the OS
|
||||
size_t alignment; // all returned allocations will be aligned at
|
||||
// this granularity, which will be a power of 2
|
||||
size_t alignmentMask;
|
||||
size_t headerSkip; // amount of memory to skip to make room for the
|
||||
// header (basically, size of header, rounded
|
||||
// up to make it aligned
|
||||
size_t currentPageOffset; // next offset in top of inUseList to allocate from
|
||||
tHeader* freeList; // list of popped memory
|
||||
tHeader* inUseList; // list of all memory currently being used
|
||||
tAllocStack stack; // stack of where to allocate from, to partition pool
|
||||
|
||||
int numCalls; // just an interesting statistic
|
||||
size_t totalBytes; // just an interesting statistic
|
||||
private:
|
||||
TPoolAllocator& operator=(const TPoolAllocator&); // don't allow assignment operator
|
||||
TPoolAllocator(const TPoolAllocator&); // don't allow default copy constructor
|
||||
};
|
||||
|
||||
//
|
||||
// There could potentially be many pools with pops happening at
|
||||
// different times. But a simple use is to have a global pop
|
||||
// with everyone using the same global allocator.
|
||||
//
|
||||
extern TPoolAllocator& GetThreadPoolAllocator();
|
||||
void SetThreadPoolAllocator(TPoolAllocator* poolAllocator);
|
||||
|
||||
//
|
||||
// This STL compatible allocator is intended to be used as the allocator
|
||||
// parameter to templatized STL containers, like vector and map.
|
||||
//
|
||||
// It will use the pools for allocation, and not
|
||||
// do any deallocation, but will still do destruction.
|
||||
//
|
||||
template<class T>
|
||||
class pool_allocator {
|
||||
public:
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef T *pointer;
|
||||
typedef const T *const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T value_type;
|
||||
template<class Other>
|
||||
struct rebind {
|
||||
typedef pool_allocator<Other> other;
|
||||
};
|
||||
pointer address(reference x) const { return &x; }
|
||||
const_pointer address(const_reference x) const { return &x; }
|
||||
|
||||
pool_allocator() : allocator(GetThreadPoolAllocator()) { }
|
||||
pool_allocator(TPoolAllocator& a) : allocator(a) { }
|
||||
pool_allocator(const pool_allocator<T>& p) : allocator(p.allocator) { }
|
||||
|
||||
template<class Other>
|
||||
pool_allocator(const pool_allocator<Other>& p) : allocator(p.getAllocator()) { }
|
||||
|
||||
pointer allocate(size_type n) {
|
||||
return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T))); }
|
||||
pointer allocate(size_type n, const void*) {
|
||||
return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T))); }
|
||||
|
||||
void deallocate(void*, size_type) { }
|
||||
void deallocate(pointer, size_type) { }
|
||||
|
||||
pointer _Charalloc(size_t n) {
|
||||
return reinterpret_cast<pointer>(getAllocator().allocate(n)); }
|
||||
|
||||
void construct(pointer p, const T& val) { new ((void *)p) T(val); }
|
||||
void destroy(pointer p) { p->T::~T(); }
|
||||
|
||||
bool operator==(const pool_allocator& rhs) const { return &getAllocator() == &rhs.getAllocator(); }
|
||||
bool operator!=(const pool_allocator& rhs) const { return &getAllocator() != &rhs.getAllocator(); }
|
||||
|
||||
size_type max_size() const { return static_cast<size_type>(-1) / sizeof(T); }
|
||||
size_type max_size(int size) const { return static_cast<size_type>(-1) / size; }
|
||||
|
||||
TPoolAllocator& getAllocator() const { return allocator; }
|
||||
|
||||
pool_allocator select_on_container_copy_construction() const { return pool_allocator{}; }
|
||||
|
||||
protected:
|
||||
pool_allocator& operator=(const pool_allocator&) { return *this; }
|
||||
TPoolAllocator& allocator;
|
||||
};
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
#endif // _POOLALLOC_INCLUDED_
|
||||
@@ -0,0 +1,159 @@
|
||||
//
|
||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||
// Copyright (C) 2013 LunarG, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#ifndef _RESOURCE_LIMITS_INCLUDED_
|
||||
#define _RESOURCE_LIMITS_INCLUDED_
|
||||
|
||||
struct TLimits {
|
||||
bool nonInductiveForLoops;
|
||||
bool whileLoops;
|
||||
bool doWhileLoops;
|
||||
bool generalUniformIndexing;
|
||||
bool generalAttributeMatrixVectorIndexing;
|
||||
bool generalVaryingIndexing;
|
||||
bool generalSamplerIndexing;
|
||||
bool generalVariableIndexing;
|
||||
bool generalConstantMatrixVectorIndexing;
|
||||
};
|
||||
|
||||
struct TBuiltInResource {
|
||||
int maxLights;
|
||||
int maxClipPlanes;
|
||||
int maxTextureUnits;
|
||||
int maxTextureCoords;
|
||||
int maxVertexAttribs;
|
||||
int maxVertexUniformComponents;
|
||||
int maxVaryingFloats;
|
||||
int maxVertexTextureImageUnits;
|
||||
int maxCombinedTextureImageUnits;
|
||||
int maxTextureImageUnits;
|
||||
int maxFragmentUniformComponents;
|
||||
int maxDrawBuffers;
|
||||
int maxVertexUniformVectors;
|
||||
int maxVaryingVectors;
|
||||
int maxFragmentUniformVectors;
|
||||
int maxVertexOutputVectors;
|
||||
int maxFragmentInputVectors;
|
||||
int minProgramTexelOffset;
|
||||
int maxProgramTexelOffset;
|
||||
int maxClipDistances;
|
||||
int maxComputeWorkGroupCountX;
|
||||
int maxComputeWorkGroupCountY;
|
||||
int maxComputeWorkGroupCountZ;
|
||||
int maxComputeWorkGroupSizeX;
|
||||
int maxComputeWorkGroupSizeY;
|
||||
int maxComputeWorkGroupSizeZ;
|
||||
int maxComputeUniformComponents;
|
||||
int maxComputeTextureImageUnits;
|
||||
int maxComputeImageUniforms;
|
||||
int maxComputeAtomicCounters;
|
||||
int maxComputeAtomicCounterBuffers;
|
||||
int maxVaryingComponents;
|
||||
int maxVertexOutputComponents;
|
||||
int maxGeometryInputComponents;
|
||||
int maxGeometryOutputComponents;
|
||||
int maxFragmentInputComponents;
|
||||
int maxImageUnits;
|
||||
int maxCombinedImageUnitsAndFragmentOutputs;
|
||||
int maxCombinedShaderOutputResources;
|
||||
int maxImageSamples;
|
||||
int maxVertexImageUniforms;
|
||||
int maxTessControlImageUniforms;
|
||||
int maxTessEvaluationImageUniforms;
|
||||
int maxGeometryImageUniforms;
|
||||
int maxFragmentImageUniforms;
|
||||
int maxCombinedImageUniforms;
|
||||
int maxGeometryTextureImageUnits;
|
||||
int maxGeometryOutputVertices;
|
||||
int maxGeometryTotalOutputComponents;
|
||||
int maxGeometryUniformComponents;
|
||||
int maxGeometryVaryingComponents;
|
||||
int maxTessControlInputComponents;
|
||||
int maxTessControlOutputComponents;
|
||||
int maxTessControlTextureImageUnits;
|
||||
int maxTessControlUniformComponents;
|
||||
int maxTessControlTotalOutputComponents;
|
||||
int maxTessEvaluationInputComponents;
|
||||
int maxTessEvaluationOutputComponents;
|
||||
int maxTessEvaluationTextureImageUnits;
|
||||
int maxTessEvaluationUniformComponents;
|
||||
int maxTessPatchComponents;
|
||||
int maxPatchVertices;
|
||||
int maxTessGenLevel;
|
||||
int maxViewports;
|
||||
int maxVertexAtomicCounters;
|
||||
int maxTessControlAtomicCounters;
|
||||
int maxTessEvaluationAtomicCounters;
|
||||
int maxGeometryAtomicCounters;
|
||||
int maxFragmentAtomicCounters;
|
||||
int maxCombinedAtomicCounters;
|
||||
int maxAtomicCounterBindings;
|
||||
int maxVertexAtomicCounterBuffers;
|
||||
int maxTessControlAtomicCounterBuffers;
|
||||
int maxTessEvaluationAtomicCounterBuffers;
|
||||
int maxGeometryAtomicCounterBuffers;
|
||||
int maxFragmentAtomicCounterBuffers;
|
||||
int maxCombinedAtomicCounterBuffers;
|
||||
int maxAtomicCounterBufferSize;
|
||||
int maxTransformFeedbackBuffers;
|
||||
int maxTransformFeedbackInterleavedComponents;
|
||||
int maxCullDistances;
|
||||
int maxCombinedClipAndCullDistances;
|
||||
int maxSamples;
|
||||
int maxMeshOutputVerticesNV;
|
||||
int maxMeshOutputPrimitivesNV;
|
||||
int maxMeshWorkGroupSizeX_NV;
|
||||
int maxMeshWorkGroupSizeY_NV;
|
||||
int maxMeshWorkGroupSizeZ_NV;
|
||||
int maxTaskWorkGroupSizeX_NV;
|
||||
int maxTaskWorkGroupSizeY_NV;
|
||||
int maxTaskWorkGroupSizeZ_NV;
|
||||
int maxMeshViewCountNV;
|
||||
int maxMeshOutputVerticesEXT;
|
||||
int maxMeshOutputPrimitivesEXT;
|
||||
int maxMeshWorkGroupSizeX_EXT;
|
||||
int maxMeshWorkGroupSizeY_EXT;
|
||||
int maxMeshWorkGroupSizeZ_EXT;
|
||||
int maxTaskWorkGroupSizeX_EXT;
|
||||
int maxTaskWorkGroupSizeY_EXT;
|
||||
int maxTaskWorkGroupSizeZ_EXT;
|
||||
int maxMeshViewCountEXT;
|
||||
int maxDualSourceDrawBuffersEXT;
|
||||
|
||||
TLimits limits;
|
||||
};
|
||||
|
||||
#endif // _RESOURCE_LIMITS_INCLUDED_
|
||||
@@ -0,0 +1,176 @@
|
||||
//
|
||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#ifndef _SHHANDLE_INCLUDED_
|
||||
#define _SHHANDLE_INCLUDED_
|
||||
|
||||
//
|
||||
// Machine independent part of the compiler private objects
|
||||
// sent as ShHandle to the driver.
|
||||
//
|
||||
// This should not be included by driver code.
|
||||
//
|
||||
|
||||
#define SH_EXPORTING
|
||||
#include "../Public/ShaderLang.h"
|
||||
#include "../MachineIndependent/Versions.h"
|
||||
#include "InfoSink.h"
|
||||
|
||||
class TCompiler;
|
||||
class TLinker;
|
||||
class TUniformMap;
|
||||
|
||||
//
|
||||
// The base class used to back handles returned to the driver.
|
||||
//
|
||||
class TShHandleBase {
|
||||
public:
|
||||
TShHandleBase() { pool = new glslang::TPoolAllocator; }
|
||||
virtual ~TShHandleBase() { delete pool; }
|
||||
virtual TCompiler* getAsCompiler() { return nullptr; }
|
||||
virtual TLinker* getAsLinker() { return nullptr; }
|
||||
virtual TUniformMap* getAsUniformMap() { return nullptr; }
|
||||
virtual glslang::TPoolAllocator* getPool() const { return pool; }
|
||||
private:
|
||||
glslang::TPoolAllocator* pool;
|
||||
};
|
||||
|
||||
//
|
||||
// The base class for the machine dependent linker to derive from
|
||||
// for managing where uniforms live.
|
||||
//
|
||||
class TUniformMap : public TShHandleBase {
|
||||
public:
|
||||
TUniformMap() { }
|
||||
virtual ~TUniformMap() { }
|
||||
virtual TUniformMap* getAsUniformMap() { return this; }
|
||||
virtual int getLocation(const char* name) = 0;
|
||||
virtual TInfoSink& getInfoSink() { return infoSink; }
|
||||
TInfoSink infoSink;
|
||||
};
|
||||
|
||||
class TIntermNode;
|
||||
|
||||
//
|
||||
// The base class for the machine dependent compiler to derive from
|
||||
// for managing object code from the compile.
|
||||
//
|
||||
class TCompiler : public TShHandleBase {
|
||||
public:
|
||||
TCompiler(EShLanguage l, TInfoSink& sink) : infoSink(sink) , language(l), haveValidObjectCode(false) { }
|
||||
virtual ~TCompiler() { }
|
||||
EShLanguage getLanguage() { return language; }
|
||||
virtual TInfoSink& getInfoSink() { return infoSink; }
|
||||
|
||||
virtual bool compile(TIntermNode* root, int version = 0, EProfile profile = ENoProfile) = 0;
|
||||
|
||||
virtual TCompiler* getAsCompiler() { return this; }
|
||||
virtual bool linkable() { return haveValidObjectCode; }
|
||||
|
||||
TInfoSink& infoSink;
|
||||
protected:
|
||||
TCompiler& operator=(TCompiler&);
|
||||
|
||||
EShLanguage language;
|
||||
bool haveValidObjectCode;
|
||||
};
|
||||
|
||||
//
|
||||
// Link operations are based on a list of compile results...
|
||||
//
|
||||
typedef glslang::TVector<TCompiler*> TCompilerList;
|
||||
typedef glslang::TVector<TShHandleBase*> THandleList;
|
||||
|
||||
//
|
||||
// The base class for the machine dependent linker to derive from
|
||||
// to manage the resulting executable.
|
||||
//
|
||||
|
||||
class TLinker : public TShHandleBase {
|
||||
public:
|
||||
TLinker(EShExecutable e, TInfoSink& iSink) :
|
||||
infoSink(iSink),
|
||||
executable(e),
|
||||
haveReturnableObjectCode(false),
|
||||
appAttributeBindings(nullptr),
|
||||
fixedAttributeBindings(nullptr),
|
||||
excludedAttributes(nullptr),
|
||||
excludedCount(0),
|
||||
uniformBindings(nullptr) { }
|
||||
virtual TLinker* getAsLinker() { return this; }
|
||||
virtual ~TLinker() { }
|
||||
virtual bool link(TCompilerList&, TUniformMap*) = 0;
|
||||
virtual bool link(THandleList&) { return false; }
|
||||
virtual void setAppAttributeBindings(const ShBindingTable* t) { appAttributeBindings = t; }
|
||||
virtual void setFixedAttributeBindings(const ShBindingTable* t) { fixedAttributeBindings = t; }
|
||||
virtual void getAttributeBindings(ShBindingTable const **t) const = 0;
|
||||
virtual void setExcludedAttributes(const int* attributes, int count) { excludedAttributes = attributes; excludedCount = count; }
|
||||
virtual ShBindingTable* getUniformBindings() const { return uniformBindings; }
|
||||
virtual const void* getObjectCode() const { return nullptr; } // a real compiler would be returning object code here
|
||||
virtual TInfoSink& getInfoSink() { return infoSink; }
|
||||
TInfoSink& infoSink;
|
||||
protected:
|
||||
TLinker& operator=(TLinker&);
|
||||
EShExecutable executable;
|
||||
bool haveReturnableObjectCode; // true when objectCode is acceptable to send to driver
|
||||
|
||||
const ShBindingTable* appAttributeBindings;
|
||||
const ShBindingTable* fixedAttributeBindings;
|
||||
const int* excludedAttributes;
|
||||
int excludedCount;
|
||||
ShBindingTable* uniformBindings; // created by the linker
|
||||
};
|
||||
|
||||
//
|
||||
// This is the interface between the machine independent code
|
||||
// and the machine dependent code.
|
||||
//
|
||||
// The machine dependent code should derive from the classes
|
||||
// above. Then Construct*() and Delete*() will create and
|
||||
// destroy the machine dependent objects, which contain the
|
||||
// above machine independent information.
|
||||
//
|
||||
TCompiler* ConstructCompiler(EShLanguage, int);
|
||||
|
||||
TShHandleBase* ConstructLinker(EShExecutable, int);
|
||||
TShHandleBase* ConstructBindings();
|
||||
void DeleteLinker(TShHandleBase*);
|
||||
void DeleteBindingList(TShHandleBase* bindingList);
|
||||
|
||||
TUniformMap* ConstructUniformMap();
|
||||
void DeleteCompiler(TCompiler*);
|
||||
|
||||
void DeleteUniformMap(TUniformMap*);
|
||||
|
||||
#endif // _SHHANDLE_INCLUDED_
|
||||
@@ -0,0 +1,140 @@
|
||||
//
|
||||
// Copyright(C) 2021 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// GL_EXT_spirv_intrinsics
|
||||
//
|
||||
#include "Common.h"
|
||||
#include <variant>
|
||||
|
||||
namespace glslang {
|
||||
|
||||
class TIntermTyped;
|
||||
class TIntermConstantUnion;
|
||||
class TType;
|
||||
|
||||
// SPIR-V requirements
|
||||
struct TSpirvRequirement {
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
|
||||
// capability = [..]
|
||||
TSet<TString> extensions;
|
||||
// extension = [..]
|
||||
TSet<int> capabilities;
|
||||
};
|
||||
|
||||
// SPIR-V execution modes
|
||||
struct TSpirvExecutionMode {
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
|
||||
// spirv_execution_mode
|
||||
TMap<int, TVector<const TIntermConstantUnion*>> modes;
|
||||
// spirv_execution_mode_id
|
||||
TMap<int, TVector<const TIntermTyped*> > modeIds;
|
||||
};
|
||||
|
||||
// SPIR-V decorations
|
||||
struct TSpirvDecorate {
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
|
||||
// spirv_decorate
|
||||
TMap<int, TVector<const TIntermConstantUnion*> > decorates;
|
||||
// spirv_decorate_id
|
||||
TMap<int, TVector<const TIntermTyped*>> decorateIds;
|
||||
// spirv_decorate_string
|
||||
TMap<int, TVector<const TIntermConstantUnion*> > decorateStrings;
|
||||
};
|
||||
|
||||
// SPIR-V instruction
|
||||
struct TSpirvInstruction {
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
|
||||
TSpirvInstruction() { set = ""; id = -1; }
|
||||
|
||||
bool operator==(const TSpirvInstruction& rhs) const { return set == rhs.set && id == rhs.id; }
|
||||
bool operator!=(const TSpirvInstruction& rhs) const { return !operator==(rhs); }
|
||||
|
||||
// spirv_instruction
|
||||
TString set;
|
||||
int id;
|
||||
};
|
||||
|
||||
// SPIR-V type parameter
|
||||
struct TSpirvTypeParameter {
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
|
||||
TSpirvTypeParameter(const TIntermConstantUnion* arg) { value = arg; }
|
||||
TSpirvTypeParameter(const TType* arg) { value = arg; }
|
||||
|
||||
const TIntermConstantUnion* getAsConstant() const
|
||||
{
|
||||
if (value.index() == 0)
|
||||
return std::get<const TIntermConstantUnion*>(value);
|
||||
return nullptr;
|
||||
}
|
||||
const TType* getAsType() const
|
||||
{
|
||||
if (value.index() == 1)
|
||||
return std::get<const TType*>(value);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool operator==(const TSpirvTypeParameter& rhs) const;
|
||||
bool operator!=(const TSpirvTypeParameter& rhs) const { return !operator==(rhs); }
|
||||
|
||||
// Parameter value: constant expression or type specifier
|
||||
std::variant<const TIntermConstantUnion*, const TType*> value;
|
||||
};
|
||||
|
||||
typedef TVector<TSpirvTypeParameter> TSpirvTypeParameters;
|
||||
|
||||
// SPIR-V type
|
||||
struct TSpirvType {
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
|
||||
bool operator==(const TSpirvType& rhs) const
|
||||
{
|
||||
return spirvInst == rhs.spirvInst && typeParams == rhs.typeParams;
|
||||
}
|
||||
bool operator!=(const TSpirvType& rhs) const { return !operator==(rhs); }
|
||||
|
||||
// spirv_type
|
||||
TSpirvInstruction spirvInst;
|
||||
TSpirvTypeParameters typeParams;
|
||||
};
|
||||
|
||||
} // end namespace glslang
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,362 @@
|
||||
//
|
||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
//
|
||||
// Implement types for tracking GLSL arrays, arrays of arrays, etc.
|
||||
//
|
||||
|
||||
#ifndef _ARRAYS_INCLUDED
|
||||
#define _ARRAYS_INCLUDED
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace glslang {
|
||||
|
||||
// This is used to mean there is no size yet (unsized), it is waiting to get a size from somewhere else.
|
||||
const int UnsizedArraySize = 0;
|
||||
|
||||
class TIntermTyped;
|
||||
extern bool SameSpecializationConstants(TIntermTyped*, TIntermTyped*);
|
||||
|
||||
// Specialization constants need both a nominal size and a node that defines
|
||||
// the specialization constant being used. Array types are the same when their
|
||||
// size and specialization constant nodes are the same.
|
||||
struct TArraySize {
|
||||
unsigned int size;
|
||||
TIntermTyped* node; // nullptr means no specialization constant node
|
||||
bool operator==(const TArraySize& rhs) const
|
||||
{
|
||||
if (size != rhs.size)
|
||||
return false;
|
||||
if (node == nullptr || rhs.node == nullptr)
|
||||
return node == rhs.node;
|
||||
|
||||
return SameSpecializationConstants(node, rhs.node);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// TSmallArrayVector is used as the container for the set of sizes in TArraySizes.
|
||||
// It has generic-container semantics, while TArraySizes has array-of-array semantics.
|
||||
// That is, TSmallArrayVector should be more focused on mechanism and TArraySizes on policy.
|
||||
//
|
||||
struct TSmallArrayVector {
|
||||
//
|
||||
// TODO: memory: TSmallArrayVector is intended to be smaller.
|
||||
// Almost all arrays could be handled by two sizes each fitting
|
||||
// in 16 bits, needing a real vector only in the cases where there
|
||||
// are more than 3 sizes or a size needing more than 16 bits.
|
||||
//
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
|
||||
TSmallArrayVector() : sizes(nullptr) { }
|
||||
virtual ~TSmallArrayVector() { dealloc(); }
|
||||
|
||||
// For breaking into two non-shared copies, independently modifiable.
|
||||
TSmallArrayVector& operator=(const TSmallArrayVector& from)
|
||||
{
|
||||
if (from.sizes == nullptr)
|
||||
sizes = nullptr;
|
||||
else {
|
||||
alloc();
|
||||
*sizes = *from.sizes;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
int size() const
|
||||
{
|
||||
if (sizes == nullptr)
|
||||
return 0;
|
||||
return (int)sizes->size();
|
||||
}
|
||||
|
||||
unsigned int frontSize() const
|
||||
{
|
||||
assert(sizes != nullptr && sizes->size() > 0);
|
||||
return sizes->front().size;
|
||||
}
|
||||
|
||||
TIntermTyped* frontNode() const
|
||||
{
|
||||
assert(sizes != nullptr && sizes->size() > 0);
|
||||
return sizes->front().node;
|
||||
}
|
||||
|
||||
void changeFront(unsigned int s)
|
||||
{
|
||||
assert(sizes != nullptr);
|
||||
// this should only happen for implicitly sized arrays, not specialization constants
|
||||
assert(sizes->front().node == nullptr);
|
||||
sizes->front().size = s;
|
||||
}
|
||||
|
||||
void push_back(unsigned int e, TIntermTyped* n)
|
||||
{
|
||||
alloc();
|
||||
TArraySize pair = { e, n };
|
||||
sizes->push_back(pair);
|
||||
}
|
||||
|
||||
void push_back(const TSmallArrayVector& newDims)
|
||||
{
|
||||
alloc();
|
||||
sizes->insert(sizes->end(), newDims.sizes->begin(), newDims.sizes->end());
|
||||
}
|
||||
|
||||
void pop_front()
|
||||
{
|
||||
assert(sizes != nullptr && sizes->size() > 0);
|
||||
if (sizes->size() == 1)
|
||||
dealloc();
|
||||
else
|
||||
sizes->erase(sizes->begin());
|
||||
}
|
||||
|
||||
void pop_back()
|
||||
{
|
||||
assert(sizes != nullptr && sizes->size() > 0);
|
||||
if (sizes->size() == 1)
|
||||
dealloc();
|
||||
else
|
||||
sizes->resize(sizes->size() - 1);
|
||||
}
|
||||
|
||||
// 'this' should currently not be holding anything, and copyNonFront
|
||||
// will make it hold a copy of all but the first element of rhs.
|
||||
// (This would be useful for making a type that is dereferenced by
|
||||
// one dimension.)
|
||||
void copyNonFront(const TSmallArrayVector& rhs)
|
||||
{
|
||||
assert(sizes == nullptr);
|
||||
if (rhs.size() > 1) {
|
||||
alloc();
|
||||
sizes->insert(sizes->begin(), rhs.sizes->begin() + 1, rhs.sizes->end());
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int getDimSize(int i) const
|
||||
{
|
||||
assert(sizes != nullptr && (int)sizes->size() > i);
|
||||
return (*sizes)[i].size;
|
||||
}
|
||||
|
||||
void setDimSize(int i, unsigned int size) const
|
||||
{
|
||||
assert(sizes != nullptr && (int)sizes->size() > i);
|
||||
assert((*sizes)[i].node == nullptr);
|
||||
(*sizes)[i].size = size;
|
||||
}
|
||||
|
||||
TIntermTyped* getDimNode(int i) const
|
||||
{
|
||||
assert(sizes != nullptr && (int)sizes->size() > i);
|
||||
return (*sizes)[i].node;
|
||||
}
|
||||
|
||||
bool operator==(const TSmallArrayVector& rhs) const
|
||||
{
|
||||
if (sizes == nullptr && rhs.sizes == nullptr)
|
||||
return true;
|
||||
if (sizes == nullptr || rhs.sizes == nullptr)
|
||||
return false;
|
||||
return *sizes == *rhs.sizes;
|
||||
}
|
||||
bool operator!=(const TSmallArrayVector& rhs) const { return ! operator==(rhs); }
|
||||
|
||||
protected:
|
||||
TSmallArrayVector(const TSmallArrayVector&);
|
||||
|
||||
void alloc()
|
||||
{
|
||||
if (sizes == nullptr)
|
||||
sizes = new TVector<TArraySize>;
|
||||
}
|
||||
void dealloc()
|
||||
{
|
||||
delete sizes;
|
||||
sizes = nullptr;
|
||||
}
|
||||
|
||||
TVector<TArraySize>* sizes; // will either hold such a pointer, or in the future, hold the two array sizes
|
||||
};
|
||||
|
||||
//
|
||||
// Represent an array, or array of arrays, to arbitrary depth. This is not
|
||||
// done through a hierarchy of types in a type tree, rather all contiguous arrayness
|
||||
// in the type hierarchy is localized into this single cumulative object.
|
||||
//
|
||||
// The arrayness in TTtype is a pointer, so that it can be non-allocated and zero
|
||||
// for the vast majority of types that are non-array types.
|
||||
//
|
||||
// Order Policy: these are all identical:
|
||||
// - left to right order within a contiguous set of ...[..][..][..]... in the source language
|
||||
// - index order 0, 1, 2, ... within the 'sizes' member below
|
||||
// - outer-most to inner-most
|
||||
//
|
||||
struct TArraySizes {
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
|
||||
TArraySizes() : implicitArraySize(0), implicitlySized(true), variablyIndexed(false){ }
|
||||
|
||||
// For breaking into two non-shared copies, independently modifiable.
|
||||
TArraySizes& operator=(const TArraySizes& from)
|
||||
{
|
||||
implicitArraySize = from.implicitArraySize;
|
||||
variablyIndexed = from.variablyIndexed;
|
||||
sizes = from.sizes;
|
||||
implicitlySized = from.implicitlySized;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// translate from array-of-array semantics to container semantics
|
||||
int getNumDims() const { return sizes.size(); }
|
||||
int getDimSize(int dim) const { return sizes.getDimSize(dim); }
|
||||
TIntermTyped* getDimNode(int dim) const { return sizes.getDimNode(dim); }
|
||||
void setDimSize(int dim, int size) { sizes.setDimSize(dim, size); }
|
||||
int getOuterSize() const { return sizes.frontSize(); }
|
||||
TIntermTyped* getOuterNode() const { return sizes.frontNode(); }
|
||||
int getCumulativeSize() const
|
||||
{
|
||||
int size = 1;
|
||||
for (int d = 0; d < sizes.size(); ++d) {
|
||||
// this only makes sense in paths that have a known array size
|
||||
assert(sizes.getDimSize(d) != UnsizedArraySize);
|
||||
size *= sizes.getDimSize(d);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
void addInnerSize() { addInnerSize((unsigned)UnsizedArraySize); }
|
||||
void addInnerSize(int s) { addInnerSize((unsigned)s, nullptr); }
|
||||
void addInnerSize(int s, TIntermTyped* n) { sizes.push_back((unsigned)s, n); }
|
||||
void addInnerSize(TArraySize pair) {
|
||||
sizes.push_back(pair.size, pair.node);
|
||||
implicitlySized = false;
|
||||
}
|
||||
void addInnerSizes(const TArraySizes& s) { sizes.push_back(s.sizes); }
|
||||
void changeOuterSize(int s) {
|
||||
sizes.changeFront((unsigned)s);
|
||||
implicitlySized = false;
|
||||
}
|
||||
int getImplicitSize() const { return implicitArraySize > 0 ? implicitArraySize : 1; }
|
||||
void updateImplicitSize(int s) {
|
||||
implicitArraySize = (std::max)(implicitArraySize, s);
|
||||
}
|
||||
bool isInnerUnsized() const
|
||||
{
|
||||
for (int d = 1; d < sizes.size(); ++d) {
|
||||
if (sizes.getDimSize(d) == (unsigned)UnsizedArraySize)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
bool clearInnerUnsized()
|
||||
{
|
||||
for (int d = 1; d < sizes.size(); ++d) {
|
||||
if (sizes.getDimSize(d) == (unsigned)UnsizedArraySize)
|
||||
setDimSize(d, 1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
bool isInnerSpecialization() const
|
||||
{
|
||||
for (int d = 1; d < sizes.size(); ++d) {
|
||||
if (sizes.getDimNode(d) != nullptr)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
bool isOuterSpecialization()
|
||||
{
|
||||
return sizes.getDimNode(0) != nullptr;
|
||||
}
|
||||
|
||||
bool hasUnsized() const { return getOuterSize() == UnsizedArraySize || isInnerUnsized(); }
|
||||
bool isSized() const { return getOuterSize() != UnsizedArraySize; }
|
||||
bool isImplicitlySized() const { return implicitlySized; }
|
||||
bool isDefaultImplicitlySized() const { return implicitlySized && implicitArraySize == 0; }
|
||||
void setImplicitlySized(bool isImplicitSizing) { implicitlySized = isImplicitSizing; }
|
||||
void dereference() { sizes.pop_front(); }
|
||||
void removeLastSize() { sizes.pop_back(); }
|
||||
void copyDereferenced(const TArraySizes& rhs)
|
||||
{
|
||||
assert(sizes.size() == 0);
|
||||
if (rhs.sizes.size() > 1)
|
||||
sizes.copyNonFront(rhs.sizes);
|
||||
}
|
||||
|
||||
bool sameInnerArrayness(const TArraySizes& rhs) const
|
||||
{
|
||||
if (sizes.size() != rhs.sizes.size())
|
||||
return false;
|
||||
|
||||
for (int d = 1; d < sizes.size(); ++d) {
|
||||
if (sizes.getDimSize(d) != rhs.sizes.getDimSize(d) ||
|
||||
sizes.getDimNode(d) != rhs.sizes.getDimNode(d))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void setVariablyIndexed() { variablyIndexed = true; }
|
||||
bool isVariablyIndexed() const { return variablyIndexed; }
|
||||
|
||||
bool operator==(const TArraySizes& rhs) const { return sizes == rhs.sizes; }
|
||||
bool operator!=(const TArraySizes& rhs) const { return sizes != rhs.sizes; }
|
||||
|
||||
protected:
|
||||
TSmallArrayVector sizes;
|
||||
|
||||
TArraySizes(const TArraySizes&);
|
||||
|
||||
// For tracking maximum referenced compile-time constant index.
|
||||
// Applies only to the outer-most dimension. Potentially becomes
|
||||
// the implicit size of the array, if not variably indexed and
|
||||
// otherwise legal.
|
||||
int implicitArraySize;
|
||||
bool implicitlySized;
|
||||
bool variablyIndexed; // true if array is indexed with a non compile-time constant
|
||||
};
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
#endif // _ARRAYS_INCLUDED_
|
||||
@@ -0,0 +1,297 @@
|
||||
/**
|
||||
This code is based on the glslang_c_interface implementation by Viktor Latypov
|
||||
**/
|
||||
|
||||
/**
|
||||
BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2019, Viktor Latypov
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**/
|
||||
|
||||
#ifndef GLSLANG_C_IFACE_H_INCLUDED
|
||||
#define GLSLANG_C_IFACE_H_INCLUDED
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "glslang_c_shader_types.h"
|
||||
#include "visibility.h"
|
||||
|
||||
typedef struct glslang_shader_s glslang_shader_t;
|
||||
typedef struct glslang_program_s glslang_program_t;
|
||||
typedef struct glslang_mapper_s glslang_mapper_t;
|
||||
typedef struct glslang_resolver_s glslang_resolver_t;
|
||||
|
||||
/* Version counterpart */
|
||||
typedef struct glslang_version_s {
|
||||
int major;
|
||||
int minor;
|
||||
int patch;
|
||||
const char* flavor;
|
||||
} glslang_version_t;
|
||||
|
||||
/* TLimits counterpart */
|
||||
typedef struct glslang_limits_s {
|
||||
bool non_inductive_for_loops;
|
||||
bool while_loops;
|
||||
bool do_while_loops;
|
||||
bool general_uniform_indexing;
|
||||
bool general_attribute_matrix_vector_indexing;
|
||||
bool general_varying_indexing;
|
||||
bool general_sampler_indexing;
|
||||
bool general_variable_indexing;
|
||||
bool general_constant_matrix_vector_indexing;
|
||||
} glslang_limits_t;
|
||||
|
||||
/* TBuiltInResource counterpart */
|
||||
typedef struct glslang_resource_s {
|
||||
int max_lights;
|
||||
int max_clip_planes;
|
||||
int max_texture_units;
|
||||
int max_texture_coords;
|
||||
int max_vertex_attribs;
|
||||
int max_vertex_uniform_components;
|
||||
int max_varying_floats;
|
||||
int max_vertex_texture_image_units;
|
||||
int max_combined_texture_image_units;
|
||||
int max_texture_image_units;
|
||||
int max_fragment_uniform_components;
|
||||
int max_draw_buffers;
|
||||
int max_vertex_uniform_vectors;
|
||||
int max_varying_vectors;
|
||||
int max_fragment_uniform_vectors;
|
||||
int max_vertex_output_vectors;
|
||||
int max_fragment_input_vectors;
|
||||
int min_program_texel_offset;
|
||||
int max_program_texel_offset;
|
||||
int max_clip_distances;
|
||||
int max_compute_work_group_count_x;
|
||||
int max_compute_work_group_count_y;
|
||||
int max_compute_work_group_count_z;
|
||||
int max_compute_work_group_size_x;
|
||||
int max_compute_work_group_size_y;
|
||||
int max_compute_work_group_size_z;
|
||||
int max_compute_uniform_components;
|
||||
int max_compute_texture_image_units;
|
||||
int max_compute_image_uniforms;
|
||||
int max_compute_atomic_counters;
|
||||
int max_compute_atomic_counter_buffers;
|
||||
int max_varying_components;
|
||||
int max_vertex_output_components;
|
||||
int max_geometry_input_components;
|
||||
int max_geometry_output_components;
|
||||
int max_fragment_input_components;
|
||||
int max_image_units;
|
||||
int max_combined_image_units_and_fragment_outputs;
|
||||
int max_combined_shader_output_resources;
|
||||
int max_image_samples;
|
||||
int max_vertex_image_uniforms;
|
||||
int max_tess_control_image_uniforms;
|
||||
int max_tess_evaluation_image_uniforms;
|
||||
int max_geometry_image_uniforms;
|
||||
int max_fragment_image_uniforms;
|
||||
int max_combined_image_uniforms;
|
||||
int max_geometry_texture_image_units;
|
||||
int max_geometry_output_vertices;
|
||||
int max_geometry_total_output_components;
|
||||
int max_geometry_uniform_components;
|
||||
int max_geometry_varying_components;
|
||||
int max_tess_control_input_components;
|
||||
int max_tess_control_output_components;
|
||||
int max_tess_control_texture_image_units;
|
||||
int max_tess_control_uniform_components;
|
||||
int max_tess_control_total_output_components;
|
||||
int max_tess_evaluation_input_components;
|
||||
int max_tess_evaluation_output_components;
|
||||
int max_tess_evaluation_texture_image_units;
|
||||
int max_tess_evaluation_uniform_components;
|
||||
int max_tess_patch_components;
|
||||
int max_patch_vertices;
|
||||
int max_tess_gen_level;
|
||||
int max_viewports;
|
||||
int max_vertex_atomic_counters;
|
||||
int max_tess_control_atomic_counters;
|
||||
int max_tess_evaluation_atomic_counters;
|
||||
int max_geometry_atomic_counters;
|
||||
int max_fragment_atomic_counters;
|
||||
int max_combined_atomic_counters;
|
||||
int max_atomic_counter_bindings;
|
||||
int max_vertex_atomic_counter_buffers;
|
||||
int max_tess_control_atomic_counter_buffers;
|
||||
int max_tess_evaluation_atomic_counter_buffers;
|
||||
int max_geometry_atomic_counter_buffers;
|
||||
int max_fragment_atomic_counter_buffers;
|
||||
int max_combined_atomic_counter_buffers;
|
||||
int max_atomic_counter_buffer_size;
|
||||
int max_transform_feedback_buffers;
|
||||
int max_transform_feedback_interleaved_components;
|
||||
int max_cull_distances;
|
||||
int max_combined_clip_and_cull_distances;
|
||||
int max_samples;
|
||||
int max_mesh_output_vertices_nv;
|
||||
int max_mesh_output_primitives_nv;
|
||||
int max_mesh_work_group_size_x_nv;
|
||||
int max_mesh_work_group_size_y_nv;
|
||||
int max_mesh_work_group_size_z_nv;
|
||||
int max_task_work_group_size_x_nv;
|
||||
int max_task_work_group_size_y_nv;
|
||||
int max_task_work_group_size_z_nv;
|
||||
int max_mesh_view_count_nv;
|
||||
int max_mesh_output_vertices_ext;
|
||||
int max_mesh_output_primitives_ext;
|
||||
int max_mesh_work_group_size_x_ext;
|
||||
int max_mesh_work_group_size_y_ext;
|
||||
int max_mesh_work_group_size_z_ext;
|
||||
int max_task_work_group_size_x_ext;
|
||||
int max_task_work_group_size_y_ext;
|
||||
int max_task_work_group_size_z_ext;
|
||||
int max_mesh_view_count_ext;
|
||||
union
|
||||
{
|
||||
int max_dual_source_draw_buffers_ext;
|
||||
|
||||
/* Incorrectly capitalized name retained for backward compatibility */
|
||||
int maxDualSourceDrawBuffersEXT;
|
||||
};
|
||||
|
||||
glslang_limits_t limits;
|
||||
} glslang_resource_t;
|
||||
|
||||
/* Inclusion result structure allocated by C include_local/include_system callbacks */
|
||||
typedef struct glsl_include_result_s {
|
||||
/* Header file name or NULL if inclusion failed */
|
||||
const char* header_name;
|
||||
|
||||
/* Header contents or NULL */
|
||||
const char* header_data;
|
||||
size_t header_length;
|
||||
|
||||
} glsl_include_result_t;
|
||||
|
||||
/* Callback for local file inclusion */
|
||||
typedef glsl_include_result_t* (*glsl_include_local_func)(void* ctx, const char* header_name, const char* includer_name,
|
||||
size_t include_depth);
|
||||
|
||||
/* Callback for system file inclusion */
|
||||
typedef glsl_include_result_t* (*glsl_include_system_func)(void* ctx, const char* header_name,
|
||||
const char* includer_name, size_t include_depth);
|
||||
|
||||
/* Callback for include result destruction */
|
||||
typedef int (*glsl_free_include_result_func)(void* ctx, glsl_include_result_t* result);
|
||||
|
||||
/* Collection of callbacks for GLSL preprocessor */
|
||||
typedef struct glsl_include_callbacks_s {
|
||||
glsl_include_system_func include_system;
|
||||
glsl_include_local_func include_local;
|
||||
glsl_free_include_result_func free_include_result;
|
||||
} glsl_include_callbacks_t;
|
||||
|
||||
typedef struct glslang_input_s {
|
||||
glslang_source_t language;
|
||||
glslang_stage_t stage;
|
||||
glslang_client_t client;
|
||||
glslang_target_client_version_t client_version;
|
||||
glslang_target_language_t target_language;
|
||||
glslang_target_language_version_t target_language_version;
|
||||
/** Shader source code */
|
||||
const char* code;
|
||||
int default_version;
|
||||
glslang_profile_t default_profile;
|
||||
int force_default_version_and_profile;
|
||||
int forward_compatible;
|
||||
glslang_messages_t messages;
|
||||
const glslang_resource_t* resource;
|
||||
glsl_include_callbacks_t callbacks;
|
||||
void* callbacks_ctx;
|
||||
} glslang_input_t;
|
||||
|
||||
/* SpvOptions counterpart */
|
||||
typedef struct glslang_spv_options_s {
|
||||
bool generate_debug_info;
|
||||
bool strip_debug_info;
|
||||
bool disable_optimizer;
|
||||
bool optimize_size;
|
||||
bool disassemble;
|
||||
bool validate;
|
||||
bool emit_nonsemantic_shader_debug_info;
|
||||
bool emit_nonsemantic_shader_debug_source;
|
||||
bool compile_only;
|
||||
bool optimize_allow_expanded_id_bound;
|
||||
} glslang_spv_options_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
GLSLANG_EXPORT void glslang_get_version(glslang_version_t* version);
|
||||
|
||||
GLSLANG_EXPORT int glslang_initialize_process(void);
|
||||
GLSLANG_EXPORT void glslang_finalize_process(void);
|
||||
|
||||
GLSLANG_EXPORT glslang_shader_t* glslang_shader_create(const glslang_input_t* input);
|
||||
GLSLANG_EXPORT void glslang_shader_delete(glslang_shader_t* shader);
|
||||
GLSLANG_EXPORT void glslang_shader_set_preamble(glslang_shader_t* shader, const char* s);
|
||||
GLSLANG_EXPORT void glslang_shader_shift_binding(glslang_shader_t* shader, glslang_resource_type_t res, unsigned int base);
|
||||
GLSLANG_EXPORT void glslang_shader_shift_binding_for_set(glslang_shader_t* shader, glslang_resource_type_t res, unsigned int base, unsigned int set);
|
||||
GLSLANG_EXPORT void glslang_shader_set_options(glslang_shader_t* shader, int options); // glslang_shader_options_t
|
||||
GLSLANG_EXPORT void glslang_shader_set_glsl_version(glslang_shader_t* shader, int version);
|
||||
GLSLANG_EXPORT void glslang_shader_set_default_uniform_block_set_and_binding(glslang_shader_t* shader, unsigned int set, unsigned int binding);
|
||||
GLSLANG_EXPORT void glslang_shader_set_default_uniform_block_name(glslang_shader_t* shader, const char *name);
|
||||
GLSLANG_EXPORT void glslang_shader_set_resource_set_binding(glslang_shader_t* shader, const char *const *bindings, unsigned int num_bindings);
|
||||
GLSLANG_EXPORT int glslang_shader_preprocess(glslang_shader_t* shader, const glslang_input_t* input);
|
||||
GLSLANG_EXPORT int glslang_shader_parse(glslang_shader_t* shader, const glslang_input_t* input);
|
||||
GLSLANG_EXPORT const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader);
|
||||
GLSLANG_EXPORT void glslang_shader_set_preprocessed_code(glslang_shader_t* shader, const char* code);
|
||||
GLSLANG_EXPORT const char* glslang_shader_get_info_log(glslang_shader_t* shader);
|
||||
GLSLANG_EXPORT const char* glslang_shader_get_info_debug_log(glslang_shader_t* shader);
|
||||
|
||||
GLSLANG_EXPORT glslang_program_t* glslang_program_create(void);
|
||||
GLSLANG_EXPORT void glslang_program_delete(glslang_program_t* program);
|
||||
GLSLANG_EXPORT void glslang_program_add_shader(glslang_program_t* program, glslang_shader_t* shader);
|
||||
GLSLANG_EXPORT int glslang_program_link(glslang_program_t* program, int messages); // glslang_messages_t
|
||||
GLSLANG_EXPORT void glslang_program_add_source_text(glslang_program_t* program, glslang_stage_t stage, const char* text, size_t len);
|
||||
GLSLANG_EXPORT void glslang_program_set_source_file(glslang_program_t* program, glslang_stage_t stage, const char* file);
|
||||
GLSLANG_EXPORT int glslang_program_map_io(glslang_program_t* program);
|
||||
GLSLANG_EXPORT int glslang_program_map_io_with_resolver_and_mapper(glslang_program_t* program, glslang_resolver_t* resolver, glslang_mapper_t* mapper);
|
||||
GLSLANG_EXPORT void glslang_program_SPIRV_generate(glslang_program_t* program, glslang_stage_t stage);
|
||||
GLSLANG_EXPORT void glslang_program_SPIRV_generate_with_options(glslang_program_t* program, glslang_stage_t stage, glslang_spv_options_t* spv_options);
|
||||
GLSLANG_EXPORT size_t glslang_program_SPIRV_get_size(glslang_program_t* program);
|
||||
GLSLANG_EXPORT void glslang_program_SPIRV_get(glslang_program_t* program, unsigned int*);
|
||||
GLSLANG_EXPORT unsigned int* glslang_program_SPIRV_get_ptr(glslang_program_t* program);
|
||||
GLSLANG_EXPORT const char* glslang_program_SPIRV_get_messages(glslang_program_t* program);
|
||||
GLSLANG_EXPORT const char* glslang_program_get_info_log(glslang_program_t* program);
|
||||
GLSLANG_EXPORT const char* glslang_program_get_info_debug_log(glslang_program_t* program);
|
||||
|
||||
GLSLANG_EXPORT glslang_mapper_t* glslang_glsl_mapper_create();
|
||||
GLSLANG_EXPORT void glslang_glsl_mapper_delete(glslang_mapper_t* mapper);
|
||||
|
||||
GLSLANG_EXPORT glslang_resolver_t* glslang_glsl_resolver_create(glslang_program_t* program, glslang_stage_t stage);
|
||||
GLSLANG_EXPORT void glslang_glsl_resolver_delete(glslang_resolver_t* resolver);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* #ifdef GLSLANG_C_IFACE_INCLUDED */
|
||||
@@ -0,0 +1,230 @@
|
||||
/**
|
||||
This code is based on the glslang_c_interface implementation by Viktor Latypov
|
||||
**/
|
||||
|
||||
/**
|
||||
BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2019, Viktor Latypov
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**/
|
||||
|
||||
#ifndef C_SHADER_TYPES_H_INCLUDED
|
||||
#define C_SHADER_TYPES_H_INCLUDED
|
||||
|
||||
#define LAST_ELEMENT_MARKER(x) x
|
||||
|
||||
/* EShLanguage counterpart */
|
||||
typedef enum {
|
||||
GLSLANG_STAGE_VERTEX,
|
||||
GLSLANG_STAGE_TESSCONTROL,
|
||||
GLSLANG_STAGE_TESSEVALUATION,
|
||||
GLSLANG_STAGE_GEOMETRY,
|
||||
GLSLANG_STAGE_FRAGMENT,
|
||||
GLSLANG_STAGE_COMPUTE,
|
||||
GLSLANG_STAGE_RAYGEN,
|
||||
GLSLANG_STAGE_RAYGEN_NV = GLSLANG_STAGE_RAYGEN,
|
||||
GLSLANG_STAGE_INTERSECT,
|
||||
GLSLANG_STAGE_INTERSECT_NV = GLSLANG_STAGE_INTERSECT,
|
||||
GLSLANG_STAGE_ANYHIT,
|
||||
GLSLANG_STAGE_ANYHIT_NV = GLSLANG_STAGE_ANYHIT,
|
||||
GLSLANG_STAGE_CLOSESTHIT,
|
||||
GLSLANG_STAGE_CLOSESTHIT_NV = GLSLANG_STAGE_CLOSESTHIT,
|
||||
GLSLANG_STAGE_MISS,
|
||||
GLSLANG_STAGE_MISS_NV = GLSLANG_STAGE_MISS,
|
||||
GLSLANG_STAGE_CALLABLE,
|
||||
GLSLANG_STAGE_CALLABLE_NV = GLSLANG_STAGE_CALLABLE,
|
||||
GLSLANG_STAGE_TASK,
|
||||
GLSLANG_STAGE_TASK_NV = GLSLANG_STAGE_TASK,
|
||||
GLSLANG_STAGE_MESH,
|
||||
GLSLANG_STAGE_MESH_NV = GLSLANG_STAGE_MESH,
|
||||
LAST_ELEMENT_MARKER(GLSLANG_STAGE_COUNT),
|
||||
} glslang_stage_t; // would be better as stage, but this is ancient now
|
||||
|
||||
/* EShLanguageMask counterpart */
|
||||
typedef enum {
|
||||
GLSLANG_STAGE_VERTEX_MASK = (1 << GLSLANG_STAGE_VERTEX),
|
||||
GLSLANG_STAGE_TESSCONTROL_MASK = (1 << GLSLANG_STAGE_TESSCONTROL),
|
||||
GLSLANG_STAGE_TESSEVALUATION_MASK = (1 << GLSLANG_STAGE_TESSEVALUATION),
|
||||
GLSLANG_STAGE_GEOMETRY_MASK = (1 << GLSLANG_STAGE_GEOMETRY),
|
||||
GLSLANG_STAGE_FRAGMENT_MASK = (1 << GLSLANG_STAGE_FRAGMENT),
|
||||
GLSLANG_STAGE_COMPUTE_MASK = (1 << GLSLANG_STAGE_COMPUTE),
|
||||
GLSLANG_STAGE_RAYGEN_MASK = (1 << GLSLANG_STAGE_RAYGEN),
|
||||
GLSLANG_STAGE_RAYGEN_NV_MASK = GLSLANG_STAGE_RAYGEN_MASK,
|
||||
GLSLANG_STAGE_INTERSECT_MASK = (1 << GLSLANG_STAGE_INTERSECT),
|
||||
GLSLANG_STAGE_INTERSECT_NV_MASK = GLSLANG_STAGE_INTERSECT_MASK,
|
||||
GLSLANG_STAGE_ANYHIT_MASK = (1 << GLSLANG_STAGE_ANYHIT),
|
||||
GLSLANG_STAGE_ANYHIT_NV_MASK = GLSLANG_STAGE_ANYHIT_MASK,
|
||||
GLSLANG_STAGE_CLOSESTHIT_MASK = (1 << GLSLANG_STAGE_CLOSESTHIT),
|
||||
GLSLANG_STAGE_CLOSESTHIT_NV_MASK = GLSLANG_STAGE_CLOSESTHIT_MASK,
|
||||
GLSLANG_STAGE_MISS_MASK = (1 << GLSLANG_STAGE_MISS),
|
||||
GLSLANG_STAGE_MISS_NV_MASK = GLSLANG_STAGE_MISS_MASK,
|
||||
GLSLANG_STAGE_CALLABLE_MASK = (1 << GLSLANG_STAGE_CALLABLE),
|
||||
GLSLANG_STAGE_CALLABLE_NV_MASK = GLSLANG_STAGE_CALLABLE_MASK,
|
||||
GLSLANG_STAGE_TASK_MASK = (1 << GLSLANG_STAGE_TASK),
|
||||
GLSLANG_STAGE_TASK_NV_MASK = GLSLANG_STAGE_TASK_MASK,
|
||||
GLSLANG_STAGE_MESH_MASK = (1 << GLSLANG_STAGE_MESH),
|
||||
GLSLANG_STAGE_MESH_NV_MASK = GLSLANG_STAGE_MESH_MASK,
|
||||
LAST_ELEMENT_MARKER(GLSLANG_STAGE_MASK_COUNT),
|
||||
} glslang_stage_mask_t;
|
||||
|
||||
/* EShSource counterpart */
|
||||
typedef enum {
|
||||
GLSLANG_SOURCE_NONE,
|
||||
GLSLANG_SOURCE_GLSL,
|
||||
GLSLANG_SOURCE_HLSL,
|
||||
LAST_ELEMENT_MARKER(GLSLANG_SOURCE_COUNT),
|
||||
} glslang_source_t;
|
||||
|
||||
/* EShClient counterpart */
|
||||
typedef enum {
|
||||
GLSLANG_CLIENT_NONE,
|
||||
GLSLANG_CLIENT_VULKAN,
|
||||
GLSLANG_CLIENT_OPENGL,
|
||||
LAST_ELEMENT_MARKER(GLSLANG_CLIENT_COUNT),
|
||||
} glslang_client_t;
|
||||
|
||||
/* EShTargetLanguage counterpart */
|
||||
typedef enum {
|
||||
GLSLANG_TARGET_NONE,
|
||||
GLSLANG_TARGET_SPV,
|
||||
LAST_ELEMENT_MARKER(GLSLANG_TARGET_COUNT),
|
||||
} glslang_target_language_t;
|
||||
|
||||
/* SH_TARGET_ClientVersion counterpart */
|
||||
typedef enum {
|
||||
GLSLANG_TARGET_VULKAN_1_0 = (1 << 22),
|
||||
GLSLANG_TARGET_VULKAN_1_1 = (1 << 22) | (1 << 12),
|
||||
GLSLANG_TARGET_VULKAN_1_2 = (1 << 22) | (2 << 12),
|
||||
GLSLANG_TARGET_VULKAN_1_3 = (1 << 22) | (3 << 12),
|
||||
GLSLANG_TARGET_OPENGL_450 = 450,
|
||||
LAST_ELEMENT_MARKER(GLSLANG_TARGET_CLIENT_VERSION_COUNT = 5),
|
||||
} glslang_target_client_version_t;
|
||||
|
||||
/* SH_TARGET_LanguageVersion counterpart */
|
||||
typedef enum {
|
||||
GLSLANG_TARGET_SPV_1_0 = (1 << 16),
|
||||
GLSLANG_TARGET_SPV_1_1 = (1 << 16) | (1 << 8),
|
||||
GLSLANG_TARGET_SPV_1_2 = (1 << 16) | (2 << 8),
|
||||
GLSLANG_TARGET_SPV_1_3 = (1 << 16) | (3 << 8),
|
||||
GLSLANG_TARGET_SPV_1_4 = (1 << 16) | (4 << 8),
|
||||
GLSLANG_TARGET_SPV_1_5 = (1 << 16) | (5 << 8),
|
||||
GLSLANG_TARGET_SPV_1_6 = (1 << 16) | (6 << 8),
|
||||
LAST_ELEMENT_MARKER(GLSLANG_TARGET_LANGUAGE_VERSION_COUNT = 7),
|
||||
} glslang_target_language_version_t;
|
||||
|
||||
/* EShExecutable counterpart */
|
||||
typedef enum { GLSLANG_EX_VERTEX_FRAGMENT, GLSLANG_EX_FRAGMENT } glslang_executable_t;
|
||||
|
||||
// EShOptimizationLevel counterpart
|
||||
// This enum is not used in the current C interface, but could be added at a later date.
|
||||
// GLSLANG_OPT_NONE is the current default.
|
||||
typedef enum {
|
||||
GLSLANG_OPT_NO_GENERATION,
|
||||
GLSLANG_OPT_NONE,
|
||||
GLSLANG_OPT_SIMPLE,
|
||||
GLSLANG_OPT_FULL,
|
||||
LAST_ELEMENT_MARKER(GLSLANG_OPT_LEVEL_COUNT),
|
||||
} glslang_optimization_level_t;
|
||||
|
||||
/* EShTextureSamplerTransformMode counterpart */
|
||||
typedef enum {
|
||||
GLSLANG_TEX_SAMP_TRANS_KEEP,
|
||||
GLSLANG_TEX_SAMP_TRANS_UPGRADE_TEXTURE_REMOVE_SAMPLER,
|
||||
LAST_ELEMENT_MARKER(GLSLANG_TEX_SAMP_TRANS_COUNT),
|
||||
} glslang_texture_sampler_transform_mode_t;
|
||||
|
||||
/* EShMessages counterpart */
|
||||
typedef enum {
|
||||
GLSLANG_MSG_DEFAULT_BIT = 0,
|
||||
GLSLANG_MSG_RELAXED_ERRORS_BIT = (1 << 0),
|
||||
GLSLANG_MSG_SUPPRESS_WARNINGS_BIT = (1 << 1),
|
||||
GLSLANG_MSG_AST_BIT = (1 << 2),
|
||||
GLSLANG_MSG_SPV_RULES_BIT = (1 << 3),
|
||||
GLSLANG_MSG_VULKAN_RULES_BIT = (1 << 4),
|
||||
GLSLANG_MSG_ONLY_PREPROCESSOR_BIT = (1 << 5),
|
||||
GLSLANG_MSG_READ_HLSL_BIT = (1 << 6),
|
||||
GLSLANG_MSG_CASCADING_ERRORS_BIT = (1 << 7),
|
||||
GLSLANG_MSG_KEEP_UNCALLED_BIT = (1 << 8),
|
||||
GLSLANG_MSG_HLSL_OFFSETS_BIT = (1 << 9),
|
||||
GLSLANG_MSG_DEBUG_INFO_BIT = (1 << 10),
|
||||
GLSLANG_MSG_HLSL_ENABLE_16BIT_TYPES_BIT = (1 << 11),
|
||||
GLSLANG_MSG_HLSL_LEGALIZATION_BIT = (1 << 12),
|
||||
GLSLANG_MSG_HLSL_DX9_COMPATIBLE_BIT = (1 << 13),
|
||||
GLSLANG_MSG_BUILTIN_SYMBOL_TABLE_BIT = (1 << 14),
|
||||
GLSLANG_MSG_ENHANCED = (1 << 15),
|
||||
GLSLANG_MSG_ABSOLUTE_PATH = (1 << 16),
|
||||
GLSLANG_MSG_DISPLAY_ERROR_COLUMN = (1 << 17),
|
||||
GLSLANG_MSG_LINK_TIME_OPTIMIZATION_BIT = (1 << 18),
|
||||
LAST_ELEMENT_MARKER(GLSLANG_MSG_COUNT),
|
||||
} glslang_messages_t;
|
||||
|
||||
/* EShReflectionOptions counterpart */
|
||||
typedef enum {
|
||||
GLSLANG_REFLECTION_DEFAULT_BIT = 0,
|
||||
GLSLANG_REFLECTION_STRICT_ARRAY_SUFFIX_BIT = (1 << 0),
|
||||
GLSLANG_REFLECTION_BASIC_ARRAY_SUFFIX_BIT = (1 << 1),
|
||||
GLSLANG_REFLECTION_INTERMEDIATE_IOO_BIT = (1 << 2),
|
||||
GLSLANG_REFLECTION_SEPARATE_BUFFERS_BIT = (1 << 3),
|
||||
GLSLANG_REFLECTION_ALL_BLOCK_VARIABLES_BIT = (1 << 4),
|
||||
GLSLANG_REFLECTION_UNWRAP_IO_BLOCKS_BIT = (1 << 5),
|
||||
GLSLANG_REFLECTION_ALL_IO_VARIABLES_BIT = (1 << 6),
|
||||
GLSLANG_REFLECTION_SHARED_STD140_SSBO_BIT = (1 << 7),
|
||||
GLSLANG_REFLECTION_SHARED_STD140_UBO_BIT = (1 << 8),
|
||||
LAST_ELEMENT_MARKER(GLSLANG_REFLECTION_COUNT),
|
||||
} glslang_reflection_options_t;
|
||||
|
||||
/* EProfile counterpart (from Versions.h) */
|
||||
typedef enum {
|
||||
GLSLANG_BAD_PROFILE = 0,
|
||||
GLSLANG_NO_PROFILE = (1 << 0),
|
||||
GLSLANG_CORE_PROFILE = (1 << 1),
|
||||
GLSLANG_COMPATIBILITY_PROFILE = (1 << 2),
|
||||
GLSLANG_ES_PROFILE = (1 << 3),
|
||||
LAST_ELEMENT_MARKER(GLSLANG_PROFILE_COUNT),
|
||||
} glslang_profile_t;
|
||||
|
||||
/* Shader options */
|
||||
typedef enum {
|
||||
GLSLANG_SHADER_DEFAULT_BIT = 0,
|
||||
GLSLANG_SHADER_AUTO_MAP_BINDINGS = (1 << 0),
|
||||
GLSLANG_SHADER_AUTO_MAP_LOCATIONS = (1 << 1),
|
||||
GLSLANG_SHADER_VULKAN_RULES_RELAXED = (1 << 2),
|
||||
LAST_ELEMENT_MARKER(GLSLANG_SHADER_COUNT),
|
||||
} glslang_shader_options_t;
|
||||
|
||||
/* TResourceType counterpart */
|
||||
typedef enum {
|
||||
GLSLANG_RESOURCE_TYPE_SAMPLER,
|
||||
GLSLANG_RESOURCE_TYPE_TEXTURE,
|
||||
GLSLANG_RESOURCE_TYPE_IMAGE,
|
||||
GLSLANG_RESOURCE_TYPE_UBO,
|
||||
GLSLANG_RESOURCE_TYPE_SSBO,
|
||||
GLSLANG_RESOURCE_TYPE_UAV,
|
||||
LAST_ELEMENT_MARKER(GLSLANG_RESOURCE_TYPE_COUNT),
|
||||
} glslang_resource_type_t;
|
||||
|
||||
#undef LAST_ELEMENT_MARKER
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// Copyright (C) 2023 LunarG, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
#ifdef GLSLANG_IS_SHARED_LIBRARY
|
||||
#ifdef _WIN32
|
||||
#ifdef GLSLANG_EXPORTING
|
||||
#define GLSLANG_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define GLSLANG_EXPORT __declspec(dllimport)
|
||||
#endif
|
||||
#elif __GNUC__ >= 4
|
||||
#define GLSLANG_EXPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
#endif // GLSLANG_IS_SHARED_LIBRARY
|
||||
|
||||
#ifndef GLSLANG_EXPORT
|
||||
#define GLSLANG_EXPORT
|
||||
#endif
|
||||
|
||||
// Symbols marked with this macro are only meant for public use by the test suite
|
||||
// and do not appear in publicly installed headers. They are not considered to be
|
||||
// part of the glslang library ABI.
|
||||
#define GLSLANG_EXPORT_FOR_TESTS GLSLANG_EXPORT
|
||||
@@ -0,0 +1,385 @@
|
||||
//
|
||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||
// Copyright (C) 2017, 2022-2024 Arm Limited.
|
||||
// Copyright (C) 2015-2018 Google, Inc.
|
||||
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#ifndef _VERSIONS_INCLUDED_
|
||||
#define _VERSIONS_INCLUDED_
|
||||
|
||||
#define LAST_ELEMENT_MARKER(x) x
|
||||
|
||||
//
|
||||
// Help manage multiple profiles, versions, extensions etc.
|
||||
//
|
||||
|
||||
//
|
||||
// Profiles are set up for masking operations, so queries can be done on multiple
|
||||
// profiles at the same time.
|
||||
//
|
||||
// Don't maintain an ordinal set of enums (0,1,2,3...) to avoid all possible
|
||||
// defects from mixing the two different forms.
|
||||
//
|
||||
typedef enum : unsigned {
|
||||
EBadProfile = 0,
|
||||
ENoProfile = (1 << 0), // only for desktop, before profiles showed up
|
||||
ECoreProfile = (1 << 1),
|
||||
ECompatibilityProfile = (1 << 2),
|
||||
EEsProfile = (1 << 3),
|
||||
LAST_ELEMENT_MARKER(EProfileCount),
|
||||
} EProfile;
|
||||
|
||||
namespace glslang {
|
||||
|
||||
//
|
||||
// Map from profile enum to externally readable text name.
|
||||
//
|
||||
inline const char* ProfileName(EProfile profile)
|
||||
{
|
||||
switch (profile) {
|
||||
case ENoProfile: return "none";
|
||||
case ECoreProfile: return "core";
|
||||
case ECompatibilityProfile: return "compatibility";
|
||||
case EEsProfile: return "es";
|
||||
default: return "unknown profile";
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// What source rules, validation rules, target language, etc. are needed or
|
||||
// desired for SPIR-V?
|
||||
//
|
||||
// 0 means a target or rule set is not enabled (ignore rules from that entity).
|
||||
// Non-0 means to apply semantic rules arising from that version of its rule set.
|
||||
// The union of all requested rule sets will be applied.
|
||||
//
|
||||
struct SpvVersion {
|
||||
SpvVersion() : spv(0), vulkanGlsl(0), vulkan(0), openGl(0), vulkanRelaxed(false) {}
|
||||
unsigned int spv; // the version of SPIR-V to target, as defined by "word 1" of the SPIR-V binary header
|
||||
int vulkanGlsl; // the version of GLSL semantics for Vulkan, from GL_KHR_vulkan_glsl, for "#define VULKAN XXX"
|
||||
int vulkan; // the version of Vulkan, for which SPIR-V execution environment rules to use
|
||||
int openGl; // the version of GLSL semantics for OpenGL, from GL_ARB_gl_spirv, for "#define GL_SPIRV XXX"
|
||||
bool vulkanRelaxed; // relax changes to GLSL for Vulkan, allowing some GL-specific to be compiled to Vulkan SPIR-V target
|
||||
};
|
||||
|
||||
//
|
||||
// The behaviors from the GLSL "#extension extension_name : behavior"
|
||||
//
|
||||
typedef enum {
|
||||
EBhMissing = 0,
|
||||
EBhRequire,
|
||||
EBhEnable,
|
||||
EBhWarn,
|
||||
EBhDisable,
|
||||
EBhDisablePartial // use as initial state of an extension that is only partially implemented
|
||||
} TExtensionBehavior;
|
||||
|
||||
//
|
||||
// Symbolic names for extensions. Strings may be directly used when calling the
|
||||
// functions, but better to have the compiler do spelling checks.
|
||||
//
|
||||
const char* const E_GL_OES_texture_3D = "GL_OES_texture_3D";
|
||||
const char* const E_GL_OES_standard_derivatives = "GL_OES_standard_derivatives";
|
||||
const char* const E_GL_EXT_frag_depth = "GL_EXT_frag_depth";
|
||||
const char* const E_GL_OES_EGL_image_external = "GL_OES_EGL_image_external";
|
||||
const char* const E_GL_OES_EGL_image_external_essl3 = "GL_OES_EGL_image_external_essl3";
|
||||
const char* const E_GL_EXT_YUV_target = "GL_EXT_YUV_target";
|
||||
const char* const E_GL_EXT_shader_texture_lod = "GL_EXT_shader_texture_lod";
|
||||
const char* const E_GL_EXT_shadow_samplers = "GL_EXT_shadow_samplers";
|
||||
|
||||
const char* const E_GL_ARB_texture_rectangle = "GL_ARB_texture_rectangle";
|
||||
const char* const E_GL_3DL_array_objects = "GL_3DL_array_objects";
|
||||
const char* const E_GL_ARB_shading_language_420pack = "GL_ARB_shading_language_420pack";
|
||||
const char* const E_GL_ARB_texture_gather = "GL_ARB_texture_gather";
|
||||
const char* const E_GL_ARB_gpu_shader5 = "GL_ARB_gpu_shader5";
|
||||
const char* const E_GL_ARB_separate_shader_objects = "GL_ARB_separate_shader_objects";
|
||||
const char* const E_GL_ARB_compute_shader = "GL_ARB_compute_shader";
|
||||
const char* const E_GL_ARB_tessellation_shader = "GL_ARB_tessellation_shader";
|
||||
const char* const E_GL_ARB_enhanced_layouts = "GL_ARB_enhanced_layouts";
|
||||
const char* const E_GL_ARB_texture_cube_map_array = "GL_ARB_texture_cube_map_array";
|
||||
const char* const E_GL_ARB_texture_multisample = "GL_ARB_texture_multisample";
|
||||
const char* const E_GL_ARB_shader_texture_lod = "GL_ARB_shader_texture_lod";
|
||||
const char* const E_GL_ARB_explicit_attrib_location = "GL_ARB_explicit_attrib_location";
|
||||
const char* const E_GL_ARB_explicit_uniform_location = "GL_ARB_explicit_uniform_location";
|
||||
const char* const E_GL_ARB_shader_image_load_store = "GL_ARB_shader_image_load_store";
|
||||
const char* const E_GL_ARB_shader_atomic_counters = "GL_ARB_shader_atomic_counters";
|
||||
const char* const E_GL_ARB_shader_atomic_counter_ops = "GL_ARB_shader_atomic_counter_ops";
|
||||
const char* const E_GL_ARB_shader_draw_parameters = "GL_ARB_shader_draw_parameters";
|
||||
const char* const E_GL_ARB_shader_group_vote = "GL_ARB_shader_group_vote";
|
||||
const char* const E_GL_ARB_derivative_control = "GL_ARB_derivative_control";
|
||||
const char* const E_GL_ARB_shader_texture_image_samples = "GL_ARB_shader_texture_image_samples";
|
||||
const char* const E_GL_ARB_viewport_array = "GL_ARB_viewport_array";
|
||||
const char* const E_GL_ARB_gpu_shader_int64 = "GL_ARB_gpu_shader_int64";
|
||||
const char* const E_GL_ARB_gpu_shader_fp64 = "GL_ARB_gpu_shader_fp64";
|
||||
const char* const E_GL_ARB_shader_ballot = "GL_ARB_shader_ballot";
|
||||
const char* const E_GL_ARB_sparse_texture2 = "GL_ARB_sparse_texture2";
|
||||
const char* const E_GL_ARB_sparse_texture_clamp = "GL_ARB_sparse_texture_clamp";
|
||||
const char* const E_GL_ARB_shader_stencil_export = "GL_ARB_shader_stencil_export";
|
||||
// const char* const E_GL_ARB_cull_distance = "GL_ARB_cull_distance"; // present for 4.5, but need extension control over block members
|
||||
const char* const E_GL_ARB_post_depth_coverage = "GL_ARB_post_depth_coverage";
|
||||
const char* const E_GL_ARB_shader_viewport_layer_array = "GL_ARB_shader_viewport_layer_array";
|
||||
const char* const E_GL_ARB_fragment_shader_interlock = "GL_ARB_fragment_shader_interlock";
|
||||
const char* const E_GL_ARB_shader_clock = "GL_ARB_shader_clock";
|
||||
const char* const E_GL_ARB_uniform_buffer_object = "GL_ARB_uniform_buffer_object";
|
||||
const char* const E_GL_ARB_sample_shading = "GL_ARB_sample_shading";
|
||||
const char* const E_GL_ARB_shader_bit_encoding = "GL_ARB_shader_bit_encoding";
|
||||
const char* const E_GL_ARB_shader_image_size = "GL_ARB_shader_image_size";
|
||||
const char* const E_GL_ARB_shader_storage_buffer_object = "GL_ARB_shader_storage_buffer_object";
|
||||
const char* const E_GL_ARB_shading_language_packing = "GL_ARB_shading_language_packing";
|
||||
const char* const E_GL_ARB_texture_query_lod = "GL_ARB_texture_query_lod";
|
||||
const char* const E_GL_ARB_vertex_attrib_64bit = "GL_ARB_vertex_attrib_64bit";
|
||||
const char* const E_GL_ARB_draw_instanced = "GL_ARB_draw_instanced";
|
||||
const char* const E_GL_ARB_fragment_coord_conventions = "GL_ARB_fragment_coord_conventions";
|
||||
const char* const E_GL_ARB_bindless_texture = "GL_ARB_bindless_texture";
|
||||
|
||||
const char* const E_GL_KHR_shader_subgroup_basic = "GL_KHR_shader_subgroup_basic";
|
||||
const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote";
|
||||
const char* const E_GL_KHR_shader_subgroup_arithmetic = "GL_KHR_shader_subgroup_arithmetic";
|
||||
const char* const E_GL_KHR_shader_subgroup_ballot = "GL_KHR_shader_subgroup_ballot";
|
||||
const char* const E_GL_KHR_shader_subgroup_shuffle = "GL_KHR_shader_subgroup_shuffle";
|
||||
const char* const E_GL_KHR_shader_subgroup_shuffle_relative = "GL_KHR_shader_subgroup_shuffle_relative";
|
||||
const char* const E_GL_KHR_shader_subgroup_rotate = "GL_KHR_shader_subgroup_rotate";
|
||||
const char* const E_GL_KHR_shader_subgroup_clustered = "GL_KHR_shader_subgroup_clustered";
|
||||
const char* const E_GL_KHR_shader_subgroup_quad = "GL_KHR_shader_subgroup_quad";
|
||||
const char* const E_GL_KHR_memory_scope_semantics = "GL_KHR_memory_scope_semantics";
|
||||
const char* const E_GL_KHR_cooperative_matrix = "GL_KHR_cooperative_matrix";
|
||||
|
||||
const char* const E_GL_EXT_shader_atomic_int64 = "GL_EXT_shader_atomic_int64";
|
||||
|
||||
const char* const E_GL_EXT_shader_non_constant_global_initializers = "GL_EXT_shader_non_constant_global_initializers";
|
||||
const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted";
|
||||
|
||||
const char* const E_GL_EXT_shader_16bit_storage = "GL_EXT_shader_16bit_storage";
|
||||
const char* const E_GL_EXT_shader_8bit_storage = "GL_EXT_shader_8bit_storage";
|
||||
|
||||
|
||||
// EXT extensions
|
||||
const char* const E_GL_EXT_device_group = "GL_EXT_device_group";
|
||||
const char* const E_GL_EXT_multiview = "GL_EXT_multiview";
|
||||
const char* const E_GL_EXT_post_depth_coverage = "GL_EXT_post_depth_coverage";
|
||||
const char* const E_GL_EXT_control_flow_attributes = "GL_EXT_control_flow_attributes";
|
||||
const char* const E_GL_EXT_nonuniform_qualifier = "GL_EXT_nonuniform_qualifier";
|
||||
const char* const E_GL_EXT_samplerless_texture_functions = "GL_EXT_samplerless_texture_functions";
|
||||
const char* const E_GL_EXT_scalar_block_layout = "GL_EXT_scalar_block_layout";
|
||||
const char* const E_GL_EXT_fragment_invocation_density = "GL_EXT_fragment_invocation_density";
|
||||
const char* const E_GL_EXT_buffer_reference = "GL_EXT_buffer_reference";
|
||||
const char* const E_GL_EXT_buffer_reference2 = "GL_EXT_buffer_reference2";
|
||||
const char* const E_GL_EXT_buffer_reference_uvec2 = "GL_EXT_buffer_reference_uvec2";
|
||||
const char* const E_GL_EXT_demote_to_helper_invocation = "GL_EXT_demote_to_helper_invocation";
|
||||
const char* const E_GL_EXT_shader_realtime_clock = "GL_EXT_shader_realtime_clock";
|
||||
const char* const E_GL_EXT_debug_printf = "GL_EXT_debug_printf";
|
||||
const char* const E_GL_EXT_ray_tracing = "GL_EXT_ray_tracing";
|
||||
const char* const E_GL_EXT_ray_query = "GL_EXT_ray_query";
|
||||
const char* const E_GL_EXT_ray_flags_primitive_culling = "GL_EXT_ray_flags_primitive_culling";
|
||||
const char* const E_GL_EXT_ray_cull_mask = "GL_EXT_ray_cull_mask";
|
||||
const char* const E_GL_EXT_blend_func_extended = "GL_EXT_blend_func_extended";
|
||||
const char* const E_GL_EXT_shader_implicit_conversions = "GL_EXT_shader_implicit_conversions";
|
||||
const char* const E_GL_EXT_fragment_shading_rate = "GL_EXT_fragment_shading_rate";
|
||||
const char* const E_GL_EXT_shader_image_int64 = "GL_EXT_shader_image_int64";
|
||||
const char* const E_GL_EXT_null_initializer = "GL_EXT_null_initializer";
|
||||
const char* const E_GL_EXT_shared_memory_block = "GL_EXT_shared_memory_block";
|
||||
const char* const E_GL_EXT_subgroup_uniform_control_flow = "GL_EXT_subgroup_uniform_control_flow";
|
||||
const char* const E_GL_EXT_spirv_intrinsics = "GL_EXT_spirv_intrinsics";
|
||||
const char* const E_GL_EXT_fragment_shader_barycentric = "GL_EXT_fragment_shader_barycentric";
|
||||
const char* const E_GL_EXT_mesh_shader = "GL_EXT_mesh_shader";
|
||||
const char* const E_GL_EXT_opacity_micromap = "GL_EXT_opacity_micromap";
|
||||
const char* const E_GL_EXT_shader_quad_control = "GL_EXT_shader_quad_control";
|
||||
const char* const E_GL_EXT_draw_instanced = "GL_EXT_draw_instanced";
|
||||
const char* const E_GL_EXT_texture_array = "GL_EXT_texture_array";
|
||||
const char* const E_GL_EXT_maximal_reconvergence = "GL_EXT_maximal_reconvergence";
|
||||
const char* const E_GL_EXT_expect_assume = "GL_EXT_expect_assume";
|
||||
const char* const E_GL_EXT_control_flow_attributes2 = "GL_EXT_control_flow_attributes2";
|
||||
const char* const E_GL_EXT_spec_constant_composites = "GL_EXT_spec_constant_composites";
|
||||
|
||||
// Arrays of extensions for the above viewportEXTs duplications
|
||||
|
||||
const char* const post_depth_coverageEXTs[] = { E_GL_ARB_post_depth_coverage, E_GL_EXT_post_depth_coverage };
|
||||
const int Num_post_depth_coverageEXTs = sizeof(post_depth_coverageEXTs) / sizeof(post_depth_coverageEXTs[0]);
|
||||
|
||||
// Array of extensions to cover both extensions providing ray tracing capabilities.
|
||||
const char* const ray_tracing_EXTs[] = { E_GL_EXT_ray_query, E_GL_EXT_ray_tracing };
|
||||
const int Num_ray_tracing_EXTs = sizeof(ray_tracing_EXTs) / sizeof(ray_tracing_EXTs[0]);
|
||||
|
||||
// OVR extensions
|
||||
const char* const E_GL_OVR_multiview = "GL_OVR_multiview";
|
||||
const char* const E_GL_OVR_multiview2 = "GL_OVR_multiview2";
|
||||
|
||||
const char* const OVR_multiview_EXTs[] = { E_GL_OVR_multiview, E_GL_OVR_multiview2 };
|
||||
const int Num_OVR_multiview_EXTs = sizeof(OVR_multiview_EXTs) / sizeof(OVR_multiview_EXTs[0]);
|
||||
|
||||
// #line and #include
|
||||
const char* const E_GL_GOOGLE_cpp_style_line_directive = "GL_GOOGLE_cpp_style_line_directive";
|
||||
const char* const E_GL_GOOGLE_include_directive = "GL_GOOGLE_include_directive";
|
||||
const char* const E_GL_ARB_shading_language_include = "GL_ARB_shading_language_include";
|
||||
|
||||
const char* const E_GL_AMD_shader_ballot = "GL_AMD_shader_ballot";
|
||||
const char* const E_GL_AMD_shader_trinary_minmax = "GL_AMD_shader_trinary_minmax";
|
||||
const char* const E_GL_AMD_shader_explicit_vertex_parameter = "GL_AMD_shader_explicit_vertex_parameter";
|
||||
const char* const E_GL_AMD_gcn_shader = "GL_AMD_gcn_shader";
|
||||
const char* const E_GL_AMD_gpu_shader_half_float = "GL_AMD_gpu_shader_half_float";
|
||||
const char* const E_GL_AMD_texture_gather_bias_lod = "GL_AMD_texture_gather_bias_lod";
|
||||
const char* const E_GL_AMD_gpu_shader_int16 = "GL_AMD_gpu_shader_int16";
|
||||
const char* const E_GL_AMD_shader_image_load_store_lod = "GL_AMD_shader_image_load_store_lod";
|
||||
const char* const E_GL_AMD_shader_fragment_mask = "GL_AMD_shader_fragment_mask";
|
||||
const char* const E_GL_AMD_gpu_shader_half_float_fetch = "GL_AMD_gpu_shader_half_float_fetch";
|
||||
const char* const E_GL_AMD_shader_early_and_late_fragment_tests = "GL_AMD_shader_early_and_late_fragment_tests";
|
||||
|
||||
const char* const E_GL_INTEL_shader_integer_functions2 = "GL_INTEL_shader_integer_functions2";
|
||||
|
||||
const char* const E_GL_NV_sample_mask_override_coverage = "GL_NV_sample_mask_override_coverage";
|
||||
const char* const E_SPV_NV_geometry_shader_passthrough = "GL_NV_geometry_shader_passthrough";
|
||||
const char* const E_GL_NV_viewport_array2 = "GL_NV_viewport_array2";
|
||||
const char* const E_GL_NV_stereo_view_rendering = "GL_NV_stereo_view_rendering";
|
||||
const char* const E_GL_NVX_multiview_per_view_attributes = "GL_NVX_multiview_per_view_attributes";
|
||||
const char* const E_GL_NV_shader_atomic_int64 = "GL_NV_shader_atomic_int64";
|
||||
const char* const E_GL_NV_conservative_raster_underestimation = "GL_NV_conservative_raster_underestimation";
|
||||
const char* const E_GL_NV_shader_noperspective_interpolation = "GL_NV_shader_noperspective_interpolation";
|
||||
const char* const E_GL_NV_shader_subgroup_partitioned = "GL_NV_shader_subgroup_partitioned";
|
||||
const char* const E_GL_NV_shading_rate_image = "GL_NV_shading_rate_image";
|
||||
const char* const E_GL_NV_ray_tracing = "GL_NV_ray_tracing";
|
||||
const char* const E_GL_NV_ray_tracing_motion_blur = "GL_NV_ray_tracing_motion_blur";
|
||||
const char* const E_GL_NV_fragment_shader_barycentric = "GL_NV_fragment_shader_barycentric";
|
||||
const char* const E_GL_NV_compute_shader_derivatives = "GL_NV_compute_shader_derivatives";
|
||||
const char* const E_GL_NV_shader_texture_footprint = "GL_NV_shader_texture_footprint";
|
||||
const char* const E_GL_NV_mesh_shader = "GL_NV_mesh_shader";
|
||||
const char* const E_GL_NV_cooperative_matrix = "GL_NV_cooperative_matrix";
|
||||
const char* const E_GL_NV_shader_sm_builtins = "GL_NV_shader_sm_builtins";
|
||||
const char* const E_GL_NV_integer_cooperative_matrix = "GL_NV_integer_cooperative_matrix";
|
||||
const char* const E_GL_NV_shader_invocation_reorder = "GL_NV_shader_invocation_reorder";
|
||||
const char* const E_GL_EXT_ray_tracing_position_fetch = "GL_EXT_ray_tracing_position_fetch";
|
||||
const char* const E_GL_NV_displacement_micromap = "GL_NV_displacement_micromap";
|
||||
const char* const E_GL_NV_shader_atomic_fp16_vector = "GL_NV_shader_atomic_fp16_vector";
|
||||
const char* const E_GL_NV_cooperative_matrix2 = "GL_NV_cooperative_matrix2";
|
||||
|
||||
// ARM
|
||||
const char* const E_GL_ARM_shader_core_builtins = "GL_ARM_shader_core_builtins";
|
||||
|
||||
// Arrays of extensions for the above viewportEXTs duplications
|
||||
|
||||
const char* const viewportEXTs[] = { E_GL_ARB_shader_viewport_layer_array, E_GL_NV_viewport_array2 };
|
||||
const int Num_viewportEXTs = sizeof(viewportEXTs) / sizeof(viewportEXTs[0]);
|
||||
|
||||
|
||||
const char* const E_GL_QCOM_image_processing = "GL_QCOM_image_processing";
|
||||
const char* const E_GL_QCOM_image_processing2 = "GL_QCOM_image_processing2";
|
||||
|
||||
// AEP
|
||||
const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a";
|
||||
const char* const E_GL_KHR_blend_equation_advanced = "GL_KHR_blend_equation_advanced";
|
||||
const char* const E_GL_OES_sample_variables = "GL_OES_sample_variables";
|
||||
const char* const E_GL_OES_shader_image_atomic = "GL_OES_shader_image_atomic";
|
||||
const char* const E_GL_OES_shader_multisample_interpolation = "GL_OES_shader_multisample_interpolation";
|
||||
const char* const E_GL_OES_texture_storage_multisample_2d_array = "GL_OES_texture_storage_multisample_2d_array";
|
||||
const char* const E_GL_EXT_geometry_shader = "GL_EXT_geometry_shader";
|
||||
const char* const E_GL_EXT_geometry_point_size = "GL_EXT_geometry_point_size";
|
||||
const char* const E_GL_EXT_gpu_shader5 = "GL_EXT_gpu_shader5";
|
||||
const char* const E_GL_EXT_primitive_bounding_box = "GL_EXT_primitive_bounding_box";
|
||||
const char* const E_GL_EXT_shader_io_blocks = "GL_EXT_shader_io_blocks";
|
||||
const char* const E_GL_EXT_tessellation_shader = "GL_EXT_tessellation_shader";
|
||||
const char* const E_GL_EXT_tessellation_point_size = "GL_EXT_tessellation_point_size";
|
||||
const char* const E_GL_EXT_texture_buffer = "GL_EXT_texture_buffer";
|
||||
const char* const E_GL_EXT_texture_cube_map_array = "GL_EXT_texture_cube_map_array";
|
||||
const char* const E_GL_EXT_shader_integer_mix = "GL_EXT_shader_integer_mix";
|
||||
|
||||
// OES matching AEP
|
||||
const char* const E_GL_OES_geometry_shader = "GL_OES_geometry_shader";
|
||||
const char* const E_GL_OES_geometry_point_size = "GL_OES_geometry_point_size";
|
||||
const char* const E_GL_OES_gpu_shader5 = "GL_OES_gpu_shader5";
|
||||
const char* const E_GL_OES_primitive_bounding_box = "GL_OES_primitive_bounding_box";
|
||||
const char* const E_GL_OES_shader_io_blocks = "GL_OES_shader_io_blocks";
|
||||
const char* const E_GL_OES_tessellation_shader = "GL_OES_tessellation_shader";
|
||||
const char* const E_GL_OES_tessellation_point_size = "GL_OES_tessellation_point_size";
|
||||
const char* const E_GL_OES_texture_buffer = "GL_OES_texture_buffer";
|
||||
const char* const E_GL_OES_texture_cube_map_array = "GL_OES_texture_cube_map_array";
|
||||
|
||||
// EXT
|
||||
const char* const E_GL_EXT_shader_explicit_arithmetic_types = "GL_EXT_shader_explicit_arithmetic_types";
|
||||
const char* const E_GL_EXT_shader_explicit_arithmetic_types_int8 = "GL_EXT_shader_explicit_arithmetic_types_int8";
|
||||
const char* const E_GL_EXT_shader_explicit_arithmetic_types_int16 = "GL_EXT_shader_explicit_arithmetic_types_int16";
|
||||
const char* const E_GL_EXT_shader_explicit_arithmetic_types_int32 = "GL_EXT_shader_explicit_arithmetic_types_int32";
|
||||
const char* const E_GL_EXT_shader_explicit_arithmetic_types_int64 = "GL_EXT_shader_explicit_arithmetic_types_int64";
|
||||
const char* const E_GL_EXT_shader_explicit_arithmetic_types_float16 = "GL_EXT_shader_explicit_arithmetic_types_float16";
|
||||
const char* const E_GL_EXT_shader_explicit_arithmetic_types_float32 = "GL_EXT_shader_explicit_arithmetic_types_float32";
|
||||
const char* const E_GL_EXT_shader_explicit_arithmetic_types_float64 = "GL_EXT_shader_explicit_arithmetic_types_float64";
|
||||
|
||||
const char* const E_GL_EXT_shader_subgroup_extended_types_int8 = "GL_EXT_shader_subgroup_extended_types_int8";
|
||||
const char* const E_GL_EXT_shader_subgroup_extended_types_int16 = "GL_EXT_shader_subgroup_extended_types_int16";
|
||||
const char* const E_GL_EXT_shader_subgroup_extended_types_int64 = "GL_EXT_shader_subgroup_extended_types_int64";
|
||||
const char* const E_GL_EXT_shader_subgroup_extended_types_float16 = "GL_EXT_shader_subgroup_extended_types_float16";
|
||||
const char* const E_GL_EXT_terminate_invocation = "GL_EXT_terminate_invocation";
|
||||
|
||||
const char* const E_GL_EXT_shader_atomic_float = "GL_EXT_shader_atomic_float";
|
||||
const char* const E_GL_EXT_shader_atomic_float2 = "GL_EXT_shader_atomic_float2";
|
||||
|
||||
const char* const E_GL_EXT_shader_tile_image = "GL_EXT_shader_tile_image";
|
||||
|
||||
const char* const E_GL_EXT_texture_shadow_lod = "GL_EXT_texture_shadow_lod";
|
||||
|
||||
// Arrays of extensions for the above AEP duplications
|
||||
|
||||
const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader };
|
||||
const int Num_AEP_geometry_shader = sizeof(AEP_geometry_shader)/sizeof(AEP_geometry_shader[0]);
|
||||
|
||||
const char* const AEP_geometry_point_size[] = { E_GL_EXT_geometry_point_size, E_GL_OES_geometry_point_size };
|
||||
const int Num_AEP_geometry_point_size = sizeof(AEP_geometry_point_size)/sizeof(AEP_geometry_point_size[0]);
|
||||
|
||||
const char* const AEP_gpu_shader5[] = { E_GL_EXT_gpu_shader5, E_GL_OES_gpu_shader5 };
|
||||
const int Num_AEP_gpu_shader5 = sizeof(AEP_gpu_shader5)/sizeof(AEP_gpu_shader5[0]);
|
||||
|
||||
const char* const AEP_primitive_bounding_box[] = { E_GL_EXT_primitive_bounding_box, E_GL_OES_primitive_bounding_box };
|
||||
const int Num_AEP_primitive_bounding_box = sizeof(AEP_primitive_bounding_box)/sizeof(AEP_primitive_bounding_box[0]);
|
||||
|
||||
const char* const AEP_shader_io_blocks[] = { E_GL_EXT_shader_io_blocks, E_GL_OES_shader_io_blocks };
|
||||
const int Num_AEP_shader_io_blocks = sizeof(AEP_shader_io_blocks)/sizeof(AEP_shader_io_blocks[0]);
|
||||
|
||||
const char* const AEP_tessellation_shader[] = { E_GL_EXT_tessellation_shader, E_GL_OES_tessellation_shader };
|
||||
const int Num_AEP_tessellation_shader = sizeof(AEP_tessellation_shader)/sizeof(AEP_tessellation_shader[0]);
|
||||
|
||||
const char* const AEP_tessellation_point_size[] = { E_GL_EXT_tessellation_point_size, E_GL_OES_tessellation_point_size };
|
||||
const int Num_AEP_tessellation_point_size = sizeof(AEP_tessellation_point_size)/sizeof(AEP_tessellation_point_size[0]);
|
||||
|
||||
const char* const AEP_texture_buffer[] = { E_GL_EXT_texture_buffer, E_GL_OES_texture_buffer };
|
||||
const int Num_AEP_texture_buffer = sizeof(AEP_texture_buffer)/sizeof(AEP_texture_buffer[0]);
|
||||
|
||||
const char* const AEP_texture_cube_map_array[] = { E_GL_EXT_texture_cube_map_array, E_GL_OES_texture_cube_map_array };
|
||||
const int Num_AEP_texture_cube_map_array = sizeof(AEP_texture_cube_map_array)/sizeof(AEP_texture_cube_map_array[0]);
|
||||
|
||||
const char* const AEP_mesh_shader[] = { E_GL_NV_mesh_shader, E_GL_EXT_mesh_shader };
|
||||
const int Num_AEP_mesh_shader = sizeof(AEP_mesh_shader)/sizeof(AEP_mesh_shader[0]);
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
#endif // _VERSIONS_INCLUDED_
|
||||
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// Copyright (C) 2016 Google, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_
|
||||
#define _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "../Include/ResourceLimits.h"
|
||||
#include "../Include/visibility.h"
|
||||
|
||||
// Return pointer to user-writable Resource to pass through API in
|
||||
// future-proof way.
|
||||
GLSLANG_EXPORT extern TBuiltInResource* GetResources();
|
||||
|
||||
// These are the default resources for TBuiltInResources, used for both
|
||||
// - parsing this string for the case where the user didn't supply one,
|
||||
// - dumping out a template for user construction of a config file.
|
||||
GLSLANG_EXPORT extern const TBuiltInResource* GetDefaultResources();
|
||||
|
||||
// Returns the DefaultTBuiltInResource as a human-readable string.
|
||||
GLSLANG_EXPORT std::string GetDefaultTBuiltInResourceString();
|
||||
|
||||
// Decodes the resource limits from |config| to |resources|.
|
||||
GLSLANG_EXPORT void DecodeResourceLimits(TBuiltInResource* resources, char* config);
|
||||
|
||||
#endif // _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2020, Travis Fort
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**/
|
||||
|
||||
#ifndef _STAND_ALONE_RESOURCE_LIMITS_C_INCLUDED_
|
||||
#define _STAND_ALONE_RESOURCE_LIMITS_C_INCLUDED_
|
||||
|
||||
#include "../Include/glslang_c_interface.h"
|
||||
#include "../Include/visibility.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Returns a struct that can be use to create custom resource values.
|
||||
GLSLANG_EXPORT glslang_resource_t* glslang_resource(void);
|
||||
|
||||
// These are the default resources for TBuiltInResources, used for both
|
||||
// - parsing this string for the case where the user didn't supply one,
|
||||
// - dumping out a template for user construction of a config file.
|
||||
GLSLANG_EXPORT const glslang_resource_t* glslang_default_resource(void);
|
||||
|
||||
// Returns the DefaultTBuiltInResource as a human-readable string.
|
||||
// NOTE: User is responsible for freeing this string.
|
||||
GLSLANG_EXPORT const char* glslang_default_resource_string();
|
||||
|
||||
// Decodes the resource limits from |config| to |resources|.
|
||||
GLSLANG_EXPORT void glslang_decode_resource_limits(glslang_resource_t* resources, char* config);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _STAND_ALONE_RESOURCE_LIMITS_C_INCLUDED_
|
||||
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// Copyright (C) 2014 LunarG, Inc.
|
||||
// Copyright (C) 2015-2018 Google, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Logger.h"
|
||||
#include "glslang/Include/visibility.h"
|
||||
|
||||
namespace glslang {
|
||||
class TIntermediate;
|
||||
|
||||
struct SpvOptions {
|
||||
bool generateDebugInfo {false};
|
||||
bool stripDebugInfo {false};
|
||||
bool disableOptimizer {true};
|
||||
bool optimizeSize {false};
|
||||
bool disassemble {false};
|
||||
bool validate {false};
|
||||
bool emitNonSemanticShaderDebugInfo {false};
|
||||
bool emitNonSemanticShaderDebugSource{ false };
|
||||
bool compileOnly{false};
|
||||
bool optimizerAllowExpandedIDBound{false};
|
||||
};
|
||||
|
||||
GLSLANG_EXPORT void GetSpirvVersion(std::string&);
|
||||
GLSLANG_EXPORT int GetSpirvGeneratorVersion();
|
||||
GLSLANG_EXPORT void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||
SpvOptions* options = nullptr);
|
||||
GLSLANG_EXPORT void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||
spv::SpvBuildLogger* logger, SpvOptions* options = nullptr);
|
||||
GLSLANG_EXPORT bool OutputSpvBin(const std::vector<unsigned int>& spirv, const char* baseName);
|
||||
GLSLANG_EXPORT bool OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName, const char* varName);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// Copyright (C) 2016 Google, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef GLSLANG_SPIRV_LOGGER_H
|
||||
#define GLSLANG_SPIRV_LOGGER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "glslang/Include/visibility.h"
|
||||
|
||||
namespace spv {
|
||||
|
||||
// A class for holding all SPIR-V build status messages, including
|
||||
// missing/TBD functionalities, warnings, and errors.
|
||||
class GLSLANG_EXPORT SpvBuildLogger {
|
||||
public:
|
||||
SpvBuildLogger() {}
|
||||
|
||||
// Registers a TBD functionality.
|
||||
void tbdFunctionality(const std::string& f);
|
||||
// Registers a missing functionality.
|
||||
void missingFunctionality(const std::string& f);
|
||||
|
||||
// Logs a warning.
|
||||
void warning(const std::string& w) { warnings.push_back(w); }
|
||||
// Logs an error.
|
||||
void error(const std::string& e) { errors.push_back(e); }
|
||||
|
||||
// Returns all messages accumulated in the order of:
|
||||
// TBD functionalities, missing functionalities, warnings, errors.
|
||||
std::string getAllMessages() const;
|
||||
|
||||
private:
|
||||
SpvBuildLogger(const SpvBuildLogger&);
|
||||
|
||||
std::vector<std::string> tbdFeatures;
|
||||
std::vector<std::string> missingFeatures;
|
||||
std::vector<std::string> warnings;
|
||||
std::vector<std::string> errors;
|
||||
};
|
||||
|
||||
} // end spv namespace
|
||||
|
||||
#endif // GLSLANG_SPIRV_LOGGER_H
|
||||
@@ -0,0 +1,300 @@
|
||||
//
|
||||
// Copyright (C) 2015 LunarG, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#ifndef SPIRVREMAPPER_H
|
||||
#define SPIRVREMAPPER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <exception>
|
||||
|
||||
#ifdef GLSLANG_IS_SHARED_LIBRARY
|
||||
#ifdef _WIN32
|
||||
#ifdef GLSLANG_EXPORTING
|
||||
#define GLSLANG_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define GLSLANG_EXPORT __declspec(dllimport)
|
||||
#endif
|
||||
#elif __GNUC__ >= 4
|
||||
#define GLSLANG_EXPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
#endif // GLSLANG_IS_SHARED_LIBRARY
|
||||
#ifndef GLSLANG_EXPORT
|
||||
#define GLSLANG_EXPORT
|
||||
#endif
|
||||
|
||||
namespace spv {
|
||||
|
||||
class spirvbin_base_t
|
||||
{
|
||||
public:
|
||||
enum Options {
|
||||
NONE = 0,
|
||||
STRIP = (1<<0),
|
||||
MAP_TYPES = (1<<1),
|
||||
MAP_NAMES = (1<<2),
|
||||
MAP_FUNCS = (1<<3),
|
||||
DCE_FUNCS = (1<<4),
|
||||
DCE_VARS = (1<<5),
|
||||
DCE_TYPES = (1<<6),
|
||||
OPT_LOADSTORE = (1<<7),
|
||||
OPT_FWD_LS = (1<<8), // EXPERIMENTAL: PRODUCES INVALID SCHEMA-0 SPIRV
|
||||
MAP_ALL = (MAP_TYPES | MAP_NAMES | MAP_FUNCS),
|
||||
DCE_ALL = (DCE_FUNCS | DCE_VARS | DCE_TYPES),
|
||||
OPT_ALL = (OPT_LOADSTORE),
|
||||
|
||||
ALL_BUT_STRIP = (MAP_ALL | DCE_ALL | OPT_ALL),
|
||||
DO_EVERYTHING = (STRIP | ALL_BUT_STRIP)
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace SPV
|
||||
|
||||
#include <functional>
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <cassert>
|
||||
|
||||
#include "spirv.hpp"
|
||||
|
||||
namespace spv {
|
||||
|
||||
static inline constexpr Id NoResult = 0;
|
||||
|
||||
// class to hold SPIR-V binary data for remapping, DCE, and debug stripping
|
||||
class GLSLANG_EXPORT spirvbin_t : public spirvbin_base_t
|
||||
{
|
||||
public:
|
||||
spirvbin_t(int verbose = 0) : entryPoint(spv::NoResult), largestNewId(0), verbose(verbose), errorLatch(false)
|
||||
{ }
|
||||
|
||||
virtual ~spirvbin_t() { }
|
||||
|
||||
// remap on an existing binary in memory
|
||||
void remap(std::vector<std::uint32_t>& spv, const std::vector<std::string>& whiteListStrings,
|
||||
std::uint32_t opts = DO_EVERYTHING);
|
||||
|
||||
// remap on an existing binary in memory - legacy interface without white list
|
||||
void remap(std::vector<std::uint32_t>& spv, std::uint32_t opts = DO_EVERYTHING);
|
||||
|
||||
// Type for error/log handler functions
|
||||
typedef std::function<void(const std::string&)> errorfn_t;
|
||||
typedef std::function<void(const std::string&)> logfn_t;
|
||||
|
||||
// Register error/log handling functions (can be lambda fn / functor / etc)
|
||||
static void registerErrorHandler(errorfn_t handler) { errorHandler = handler; }
|
||||
static void registerLogHandler(logfn_t handler) { logHandler = handler; }
|
||||
|
||||
protected:
|
||||
// This can be overridden to provide other message behavior if needed
|
||||
virtual void msg(int minVerbosity, int indent, const std::string& txt) const;
|
||||
|
||||
private:
|
||||
// Local to global, or global to local ID map
|
||||
typedef std::unordered_map<spv::Id, spv::Id> idmap_t;
|
||||
typedef std::unordered_set<spv::Id> idset_t;
|
||||
typedef std::unordered_map<spv::Id, int> blockmap_t;
|
||||
|
||||
void remap(std::uint32_t opts = DO_EVERYTHING);
|
||||
|
||||
// Map of names to IDs
|
||||
typedef std::unordered_map<std::string, spv::Id> namemap_t;
|
||||
|
||||
typedef std::uint32_t spirword_t;
|
||||
|
||||
typedef std::pair<unsigned, unsigned> range_t;
|
||||
typedef std::function<void(spv::Id&)> idfn_t;
|
||||
typedef std::function<bool(spv::Op, unsigned start)> instfn_t;
|
||||
|
||||
// Special Values for ID map:
|
||||
static const spv::Id unmapped; // unchanged from default value
|
||||
static const spv::Id unused; // unused ID
|
||||
static const int header_size; // SPIR header = 5 words
|
||||
|
||||
class id_iterator_t;
|
||||
|
||||
// For mapping type entries between different shaders
|
||||
typedef std::vector<spirword_t> typeentry_t;
|
||||
typedef std::map<spv::Id, typeentry_t> globaltypes_t;
|
||||
|
||||
// A set that preserves position order, and a reverse map
|
||||
typedef std::set<int> posmap_t;
|
||||
typedef std::unordered_map<spv::Id, int> posmap_rev_t;
|
||||
|
||||
// Maps and ID to the size of its base type, if known.
|
||||
typedef std::unordered_map<spv::Id, unsigned> typesize_map_t;
|
||||
|
||||
// handle error
|
||||
void error(const std::string& txt) const { errorLatch = true; errorHandler(txt); }
|
||||
|
||||
bool isConstOp(spv::Op opCode) const;
|
||||
bool isTypeOp(spv::Op opCode) const;
|
||||
bool isStripOp(spv::Op opCode) const;
|
||||
bool isFlowCtrl(spv::Op opCode) const;
|
||||
range_t literalRange(spv::Op opCode) const;
|
||||
range_t typeRange(spv::Op opCode) const;
|
||||
range_t constRange(spv::Op opCode) const;
|
||||
unsigned typeSizeInWords(spv::Id id) const;
|
||||
unsigned idTypeSizeInWords(spv::Id id) const;
|
||||
|
||||
bool isStripOp(spv::Op opCode, unsigned start) const;
|
||||
|
||||
spv::Id& asId(unsigned word) { return spv[word]; }
|
||||
const spv::Id& asId(unsigned word) const { return spv[word]; }
|
||||
spv::Op asOpCode(unsigned word) const { return opOpCode(spv[word]); }
|
||||
std::uint32_t asOpCodeHash(unsigned word);
|
||||
spv::Decoration asDecoration(unsigned word) const { return spv::Decoration(spv[word]); }
|
||||
unsigned asWordCount(unsigned word) const { return opWordCount(spv[word]); }
|
||||
spv::Id asTypeConstId(unsigned word) const { return asId(word + (isTypeOp(asOpCode(word)) ? 1 : 2)); }
|
||||
unsigned idPos(spv::Id id) const;
|
||||
|
||||
static unsigned opWordCount(spirword_t data) { return data >> spv::WordCountShift; }
|
||||
static spv::Op opOpCode(spirword_t data) { return spv::Op(data & spv::OpCodeMask); }
|
||||
|
||||
// Header access & set methods
|
||||
spirword_t magic() const { return spv[0]; } // return magic number
|
||||
spirword_t bound() const { return spv[3]; } // return Id bound from header
|
||||
spirword_t bound(spirword_t b) { return spv[3] = b; }
|
||||
spirword_t genmagic() const { return spv[2]; } // generator magic
|
||||
spirword_t genmagic(spirword_t m) { return spv[2] = m; }
|
||||
spirword_t schemaNum() const { return spv[4]; } // schema number from header
|
||||
|
||||
// Mapping fns: get
|
||||
spv::Id localId(spv::Id id) const { return idMapL[id]; }
|
||||
|
||||
// Mapping fns: set
|
||||
inline spv::Id localId(spv::Id id, spv::Id newId);
|
||||
void countIds(spv::Id id);
|
||||
|
||||
// Return next unused new local ID.
|
||||
// NOTE: boost::dynamic_bitset would be more efficient due to find_next(),
|
||||
// which std::vector<bool> doens't have.
|
||||
inline spv::Id nextUnusedId(spv::Id id);
|
||||
|
||||
void buildLocalMaps();
|
||||
std::string literalString(unsigned word) const; // Return literal as a std::string
|
||||
int literalStringWords(const std::string& str) const { return (int(str.size())+4)/4; }
|
||||
|
||||
bool isNewIdMapped(spv::Id newId) const { return isMapped(newId); }
|
||||
bool isOldIdUnmapped(spv::Id oldId) const { return localId(oldId) == unmapped; }
|
||||
bool isOldIdUnused(spv::Id oldId) const { return localId(oldId) == unused; }
|
||||
bool isOldIdMapped(spv::Id oldId) const { return !isOldIdUnused(oldId) && !isOldIdUnmapped(oldId); }
|
||||
bool isFunction(spv::Id oldId) const { return fnPos.find(oldId) != fnPos.end(); }
|
||||
|
||||
// bool matchType(const globaltypes_t& globalTypes, spv::Id lt, spv::Id gt) const;
|
||||
// spv::Id findType(const globaltypes_t& globalTypes, spv::Id lt) const;
|
||||
std::uint32_t hashType(unsigned typeStart) const;
|
||||
|
||||
spirvbin_t& process(instfn_t, idfn_t, unsigned begin = 0, unsigned end = 0);
|
||||
int processInstruction(unsigned word, instfn_t, idfn_t);
|
||||
|
||||
void validate() const;
|
||||
void mapTypeConst();
|
||||
void mapFnBodies();
|
||||
void optLoadStore();
|
||||
void dceFuncs();
|
||||
void dceVars();
|
||||
void dceTypes();
|
||||
void mapNames();
|
||||
void foldIds(); // fold IDs to smallest space
|
||||
void forwardLoadStores(); // load store forwarding (EXPERIMENTAL)
|
||||
void offsetIds(); // create relative offset IDs
|
||||
|
||||
void applyMap(); // remap per local name map
|
||||
void mapRemainder(); // map any IDs we haven't touched yet
|
||||
void stripDebug(); // strip all debug info
|
||||
void stripDeadRefs(); // strips debug info for now-dead references after DCE
|
||||
void strip(); // remove debug symbols
|
||||
|
||||
std::vector<spirword_t> spv; // SPIR words
|
||||
|
||||
std::vector<std::string> stripWhiteList;
|
||||
|
||||
namemap_t nameMap; // ID names from OpName
|
||||
|
||||
// Since we want to also do binary ops, we can't use std::vector<bool>. we could use
|
||||
// boost::dynamic_bitset, but we're trying to avoid a boost dependency.
|
||||
typedef std::uint64_t bits_t;
|
||||
std::vector<bits_t> mapped; // which new IDs have been mapped
|
||||
static const int mBits = sizeof(bits_t) * 4;
|
||||
|
||||
bool isMapped(spv::Id id) const { return id < maxMappedId() && ((mapped[id/mBits] & (1LL<<(id%mBits))) != 0); }
|
||||
void setMapped(spv::Id id) { resizeMapped(id); mapped[id/mBits] |= (1LL<<(id%mBits)); }
|
||||
void resizeMapped(spv::Id id) { if (id >= maxMappedId()) mapped.resize(id/mBits+1, 0); }
|
||||
size_t maxMappedId() const { return mapped.size() * mBits; }
|
||||
|
||||
// Add a strip range for a given instruction starting at 'start'
|
||||
// Note: avoiding brace initializers to please older versions os MSVC.
|
||||
void stripInst(unsigned start) { stripRange.push_back(range_t(start, start + asWordCount(start))); }
|
||||
|
||||
// Function start and end. use unordered_map because we'll have
|
||||
// many fewer functions than IDs.
|
||||
std::unordered_map<spv::Id, range_t> fnPos;
|
||||
|
||||
// Which functions are called, anywhere in the module, with a call count
|
||||
std::unordered_map<spv::Id, int> fnCalls;
|
||||
|
||||
posmap_t typeConstPos; // word positions that define types & consts (ordered)
|
||||
posmap_rev_t idPosR; // reverse map from IDs to positions
|
||||
typesize_map_t idTypeSizeMap; // maps each ID to its type size, if known.
|
||||
|
||||
std::vector<spv::Id> idMapL; // ID {M}ap from {L}ocal to {G}lobal IDs
|
||||
|
||||
spv::Id entryPoint; // module entry point
|
||||
spv::Id largestNewId; // biggest new ID we have mapped anything to
|
||||
|
||||
// Sections of the binary to strip, given as [begin,end)
|
||||
std::vector<range_t> stripRange;
|
||||
|
||||
// processing options:
|
||||
std::uint32_t options;
|
||||
int verbose; // verbosity level
|
||||
|
||||
// Error latch: this is set if the error handler is ever executed. It would be better to
|
||||
// use a try/catch block and throw, but that's not desired for certain environments, so
|
||||
// this is the alternative.
|
||||
mutable bool errorLatch;
|
||||
|
||||
static errorfn_t errorHandler;
|
||||
static logfn_t logHandler;
|
||||
};
|
||||
|
||||
} // namespace SPV
|
||||
|
||||
#endif // SPIRVREMAPPER_H
|
||||
@@ -0,0 +1,109 @@
|
||||
//
|
||||
// Copyright (C) 2014-2016 LunarG, Inc.
|
||||
// Copyright (C) 2018 Google, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
//
|
||||
// Call into SPIRV-Tools to disassemble, validate, and optimize.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef GLSLANG_SPV_TOOLS_H
|
||||
#define GLSLANG_SPV_TOOLS_H
|
||||
|
||||
#if ENABLE_OPT
|
||||
#include <vector>
|
||||
#include <ostream>
|
||||
#include <unordered_set>
|
||||
#include "spirv-tools/libspirv.h"
|
||||
#endif
|
||||
|
||||
#include "glslang/MachineIndependent/Versions.h"
|
||||
#include "glslang/Include/visibility.h"
|
||||
#include "GlslangToSpv.h"
|
||||
#include "Logger.h"
|
||||
|
||||
namespace glslang {
|
||||
|
||||
#if ENABLE_OPT
|
||||
|
||||
class TIntermediate;
|
||||
|
||||
// Translate glslang's view of target versioning to what SPIRV-Tools uses.
|
||||
GLSLANG_EXPORT spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLogger* logger);
|
||||
GLSLANG_EXPORT spv_target_env MapToSpirvToolsEnv(const glslang::TIntermediate& intermediate, spv::SpvBuildLogger* logger);
|
||||
|
||||
// Use the SPIRV-Tools disassembler to print SPIR-V using a SPV_ENV_UNIVERSAL_1_3 environment.
|
||||
GLSLANG_EXPORT void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv);
|
||||
|
||||
// Use the SPIRV-Tools disassembler to print SPIR-V with a provided SPIR-V environment.
|
||||
GLSLANG_EXPORT void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv,
|
||||
spv_target_env requested_context);
|
||||
|
||||
// Apply the SPIRV-Tools validator to generated SPIR-V.
|
||||
GLSLANG_EXPORT void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||
spv::SpvBuildLogger*, bool prelegalization);
|
||||
|
||||
// Apply the SPIRV-Tools optimizer to generated SPIR-V. HLSL SPIR-V is legalized in the process.
|
||||
GLSLANG_EXPORT void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||
spv::SpvBuildLogger*, const SpvOptions*);
|
||||
|
||||
// Apply the SPIRV-Tools EliminateDeadInputComponents pass to generated SPIR-V. Put result in |spirv|.
|
||||
GLSLANG_EXPORT void SpirvToolsEliminateDeadInputComponents(spv_target_env target_env, std::vector<unsigned int>& spirv,
|
||||
spv::SpvBuildLogger*);
|
||||
|
||||
// Apply the SPIRV-Tools AnalyzeDeadOutputStores pass to generated SPIR-V. Put result in |live_locs|.
|
||||
// Return true if the result is valid.
|
||||
GLSLANG_EXPORT bool SpirvToolsAnalyzeDeadOutputStores(spv_target_env target_env, std::vector<unsigned int>& spirv,
|
||||
std::unordered_set<uint32_t>* live_locs,
|
||||
std::unordered_set<uint32_t>* live_builtins,
|
||||
spv::SpvBuildLogger*);
|
||||
|
||||
// Apply the SPIRV-Tools EliminateDeadOutputStores and AggressiveDeadCodeElimination passes to generated SPIR-V using
|
||||
// |live_locs|. Put result in |spirv|.
|
||||
GLSLANG_EXPORT void SpirvToolsEliminateDeadOutputStores(spv_target_env target_env, std::vector<unsigned int>& spirv,
|
||||
std::unordered_set<uint32_t>* live_locs,
|
||||
std::unordered_set<uint32_t>* live_builtins,
|
||||
spv::SpvBuildLogger*);
|
||||
|
||||
// Apply the SPIRV-Tools optimizer to strip debug info from SPIR-V. This is implicitly done by
|
||||
// SpirvToolsTransform if spvOptions->stripDebugInfo is set, but can be called separately if
|
||||
// optimization is disabled.
|
||||
GLSLANG_EXPORT void SpirvToolsStripDebugInfo(const glslang::TIntermediate& intermediate,
|
||||
std::vector<unsigned int>& spirv, spv::SpvBuildLogger*);
|
||||
|
||||
#endif
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
#endif // GLSLANG_SPV_TOOLS_H
|
||||
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
//
|
||||
// Disassembler for SPIR-V.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef disassembler_H
|
||||
#define disassembler_H
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "glslang/Include/visibility.h"
|
||||
|
||||
namespace spv {
|
||||
|
||||
// disassemble with glslang custom disassembler
|
||||
GLSLANG_EXPORT void Disassemble(std::ostream& out, const std::vector<unsigned int>&);
|
||||
|
||||
} // end namespace spv
|
||||
|
||||
#endif // disassembler_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,62 @@
|
||||
// Copyright (C) 2020 The Khronos Group Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of The Khronos Group Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef GLSLANG_BUILD_INFO
|
||||
#define GLSLANG_BUILD_INFO
|
||||
|
||||
#define GLSLANG_VERSION_MAJOR 15
|
||||
#define GLSLANG_VERSION_MINOR 0
|
||||
#define GLSLANG_VERSION_PATCH 0
|
||||
#define GLSLANG_VERSION_FLAVOR ""
|
||||
|
||||
#define GLSLANG_VERSION_GREATER_THAN(major, minor, patch) \
|
||||
((GLSLANG_VERSION_MAJOR) > (major) || ((major) == GLSLANG_VERSION_MAJOR && \
|
||||
((GLSLANG_VERSION_MINOR) > (minor) || ((minor) == GLSLANG_VERSION_MINOR && \
|
||||
(GLSLANG_VERSION_PATCH) > (patch)))))
|
||||
|
||||
#define GLSLANG_VERSION_GREATER_OR_EQUAL_TO(major, minor, patch) \
|
||||
((GLSLANG_VERSION_MAJOR) > (major) || ((major) == GLSLANG_VERSION_MAJOR && \
|
||||
((GLSLANG_VERSION_MINOR) > (minor) || ((minor) == GLSLANG_VERSION_MINOR && \
|
||||
(GLSLANG_VERSION_PATCH >= (patch))))))
|
||||
|
||||
#define GLSLANG_VERSION_LESS_THAN(major, minor, patch) \
|
||||
((GLSLANG_VERSION_MAJOR) < (major) || ((major) == GLSLANG_VERSION_MAJOR && \
|
||||
((GLSLANG_VERSION_MINOR) < (minor) || ((minor) == GLSLANG_VERSION_MINOR && \
|
||||
(GLSLANG_VERSION_PATCH) < (patch)))))
|
||||
|
||||
#define GLSLANG_VERSION_LESS_OR_EQUAL_TO(major, minor, patch) \
|
||||
((GLSLANG_VERSION_MAJOR) < (major) || ((major) == GLSLANG_VERSION_MAJOR && \
|
||||
((GLSLANG_VERSION_MINOR) < (minor) || ((minor) == GLSLANG_VERSION_MINOR && \
|
||||
(GLSLANG_VERSION_PATCH <= (patch))))))
|
||||
|
||||
#endif // GLSLANG_BUILD_INFO
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2014-2016,2021 The Khronos Group, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* 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/
|
||||
*/
|
||||
|
||||
#ifndef GLSLstd450_H
|
||||
#define GLSLstd450_H
|
||||
|
||||
static const int GLSLstd450Version = 100;
|
||||
static const int GLSLstd450Revision = 3;
|
||||
|
||||
enum GLSLstd450 {
|
||||
GLSLstd450Bad = 0, // Don't use
|
||||
|
||||
GLSLstd450Round = 1,
|
||||
GLSLstd450RoundEven = 2,
|
||||
GLSLstd450Trunc = 3,
|
||||
GLSLstd450FAbs = 4,
|
||||
GLSLstd450SAbs = 5,
|
||||
GLSLstd450FSign = 6,
|
||||
GLSLstd450SSign = 7,
|
||||
GLSLstd450Floor = 8,
|
||||
GLSLstd450Ceil = 9,
|
||||
GLSLstd450Fract = 10,
|
||||
|
||||
GLSLstd450Radians = 11,
|
||||
GLSLstd450Degrees = 12,
|
||||
GLSLstd450Sin = 13,
|
||||
GLSLstd450Cos = 14,
|
||||
GLSLstd450Tan = 15,
|
||||
GLSLstd450Asin = 16,
|
||||
GLSLstd450Acos = 17,
|
||||
GLSLstd450Atan = 18,
|
||||
GLSLstd450Sinh = 19,
|
||||
GLSLstd450Cosh = 20,
|
||||
GLSLstd450Tanh = 21,
|
||||
GLSLstd450Asinh = 22,
|
||||
GLSLstd450Acosh = 23,
|
||||
GLSLstd450Atanh = 24,
|
||||
GLSLstd450Atan2 = 25,
|
||||
|
||||
GLSLstd450Pow = 26,
|
||||
GLSLstd450Exp = 27,
|
||||
GLSLstd450Log = 28,
|
||||
GLSLstd450Exp2 = 29,
|
||||
GLSLstd450Log2 = 30,
|
||||
GLSLstd450Sqrt = 31,
|
||||
GLSLstd450InverseSqrt = 32,
|
||||
|
||||
GLSLstd450Determinant = 33,
|
||||
GLSLstd450MatrixInverse = 34,
|
||||
|
||||
GLSLstd450Modf = 35, // second operand needs an OpVariable to write to
|
||||
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,
|
||||
|
||||
GLSLstd450Fma = 50,
|
||||
GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to
|
||||
GLSLstd450FrexpStruct = 52, // no OpVariable operand
|
||||
GLSLstd450Ldexp = 53,
|
||||
|
||||
GLSLstd450PackSnorm4x8 = 54,
|
||||
GLSLstd450PackUnorm4x8 = 55,
|
||||
GLSLstd450PackSnorm2x16 = 56,
|
||||
GLSLstd450PackUnorm2x16 = 57,
|
||||
GLSLstd450PackHalf2x16 = 58,
|
||||
GLSLstd450PackDouble2x32 = 59,
|
||||
GLSLstd450UnpackSnorm2x16 = 60,
|
||||
GLSLstd450UnpackUnorm2x16 = 61,
|
||||
GLSLstd450UnpackHalf2x16 = 62,
|
||||
GLSLstd450UnpackSnorm4x8 = 63,
|
||||
GLSLstd450UnpackUnorm4x8 = 64,
|
||||
GLSLstd450UnpackDouble2x32 = 65,
|
||||
|
||||
GLSLstd450Length = 66,
|
||||
GLSLstd450Distance = 67,
|
||||
GLSLstd450Cross = 68,
|
||||
GLSLstd450Normalize = 69,
|
||||
GLSLstd450FaceForward = 70,
|
||||
GLSLstd450Reflect = 71,
|
||||
GLSLstd450Refract = 72,
|
||||
|
||||
GLSLstd450FindILsb = 73,
|
||||
GLSLstd450FindSMsb = 74,
|
||||
GLSLstd450FindUMsb = 75,
|
||||
|
||||
GLSLstd450InterpolateAtCentroid = 76,
|
||||
GLSLstd450InterpolateAtSample = 77,
|
||||
GLSLstd450InterpolateAtOffset = 78,
|
||||
|
||||
GLSLstd450NMin = 79,
|
||||
GLSLstd450NMax = 80,
|
||||
GLSLstd450NClamp = 81,
|
||||
|
||||
GLSLstd450Count
|
||||
};
|
||||
|
||||
#endif // #ifndef GLSLstd450_H
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright 2016-2021 Arm Limited
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_CFG_HPP
|
||||
#define SPIRV_CROSS_CFG_HPP
|
||||
|
||||
#include "spirv_common.hpp"
|
||||
#include <assert.h>
|
||||
|
||||
namespace SPIRV_CROSS_NAMESPACE
|
||||
{
|
||||
class Compiler;
|
||||
class CFG
|
||||
{
|
||||
public:
|
||||
CFG(Compiler &compiler, const SPIRFunction &function);
|
||||
|
||||
Compiler &get_compiler()
|
||||
{
|
||||
return compiler;
|
||||
}
|
||||
|
||||
const Compiler &get_compiler() const
|
||||
{
|
||||
return compiler;
|
||||
}
|
||||
|
||||
const SPIRFunction &get_function() const
|
||||
{
|
||||
return func;
|
||||
}
|
||||
|
||||
uint32_t get_immediate_dominator(uint32_t block) const
|
||||
{
|
||||
auto itr = immediate_dominators.find(block);
|
||||
if (itr != std::end(immediate_dominators))
|
||||
return itr->second;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool is_reachable(uint32_t block) const
|
||||
{
|
||||
return visit_order.count(block) != 0;
|
||||
}
|
||||
|
||||
uint32_t get_visit_order(uint32_t block) const
|
||||
{
|
||||
auto itr = visit_order.find(block);
|
||||
assert(itr != std::end(visit_order));
|
||||
int v = itr->second.get();
|
||||
assert(v > 0);
|
||||
return uint32_t(v);
|
||||
}
|
||||
|
||||
uint32_t find_common_dominator(uint32_t a, uint32_t b) const;
|
||||
|
||||
const SmallVector<uint32_t> &get_preceding_edges(uint32_t block) const
|
||||
{
|
||||
auto itr = preceding_edges.find(block);
|
||||
if (itr != std::end(preceding_edges))
|
||||
return itr->second;
|
||||
else
|
||||
return empty_vector;
|
||||
}
|
||||
|
||||
const SmallVector<uint32_t> &get_succeeding_edges(uint32_t block) const
|
||||
{
|
||||
auto itr = succeeding_edges.find(block);
|
||||
if (itr != std::end(succeeding_edges))
|
||||
return itr->second;
|
||||
else
|
||||
return empty_vector;
|
||||
}
|
||||
|
||||
template <typename Op>
|
||||
void walk_from(std::unordered_set<uint32_t> &seen_blocks, uint32_t block, const Op &op) const
|
||||
{
|
||||
if (seen_blocks.count(block))
|
||||
return;
|
||||
seen_blocks.insert(block);
|
||||
|
||||
if (op(block))
|
||||
{
|
||||
for (auto b : get_succeeding_edges(block))
|
||||
walk_from(seen_blocks, b, op);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t find_loop_dominator(uint32_t block) const;
|
||||
|
||||
bool node_terminates_control_flow_in_sub_graph(BlockID from, BlockID to) const;
|
||||
|
||||
private:
|
||||
struct VisitOrder
|
||||
{
|
||||
int &get()
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
const int &get() const
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
int v = -1;
|
||||
};
|
||||
|
||||
Compiler &compiler;
|
||||
const SPIRFunction &func;
|
||||
std::unordered_map<uint32_t, SmallVector<uint32_t>> preceding_edges;
|
||||
std::unordered_map<uint32_t, SmallVector<uint32_t>> succeeding_edges;
|
||||
std::unordered_map<uint32_t, uint32_t> immediate_dominators;
|
||||
std::unordered_map<uint32_t, VisitOrder> visit_order;
|
||||
SmallVector<uint32_t> post_order;
|
||||
SmallVector<uint32_t> empty_vector;
|
||||
|
||||
void add_branch(uint32_t from, uint32_t to);
|
||||
void build_post_order_visit_order();
|
||||
void build_immediate_dominators();
|
||||
bool post_order_visit(uint32_t block);
|
||||
uint32_t visit_count = 0;
|
||||
|
||||
bool is_back_edge(uint32_t to) const;
|
||||
bool has_visited_forward_edge(uint32_t to) const;
|
||||
};
|
||||
|
||||
class DominatorBuilder
|
||||
{
|
||||
public:
|
||||
DominatorBuilder(const CFG &cfg);
|
||||
|
||||
void add_block(uint32_t block);
|
||||
uint32_t get_dominator() const
|
||||
{
|
||||
return dominator;
|
||||
}
|
||||
|
||||
void lift_continue_block_dominator();
|
||||
|
||||
private:
|
||||
const CFG &cfg;
|
||||
uint32_t dominator = 0;
|
||||
};
|
||||
} // namespace SPIRV_CROSS_NAMESPACE
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2015-2021 Arm Limited
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_CPP_HPP
|
||||
#define SPIRV_CROSS_CPP_HPP
|
||||
|
||||
#include "spirv_glsl.hpp"
|
||||
#include <utility>
|
||||
|
||||
namespace SPIRV_CROSS_NAMESPACE
|
||||
{
|
||||
class CompilerCPP : public CompilerGLSL
|
||||
{
|
||||
public:
|
||||
explicit CompilerCPP(std::vector<uint32_t> spirv_)
|
||||
: CompilerGLSL(std::move(spirv_))
|
||||
{
|
||||
}
|
||||
|
||||
CompilerCPP(const uint32_t *ir_, size_t word_count)
|
||||
: CompilerGLSL(ir_, word_count)
|
||||
{
|
||||
}
|
||||
|
||||
explicit CompilerCPP(const ParsedIR &ir_)
|
||||
: CompilerGLSL(ir_)
|
||||
{
|
||||
}
|
||||
|
||||
explicit CompilerCPP(ParsedIR &&ir_)
|
||||
: CompilerGLSL(std::move(ir_))
|
||||
{
|
||||
}
|
||||
|
||||
std::string compile() override;
|
||||
|
||||
// Sets a custom symbol name that can override
|
||||
// spirv_cross_get_interface.
|
||||
//
|
||||
// Useful when several shader interfaces are linked
|
||||
// statically into the same binary.
|
||||
void set_interface_name(std::string name)
|
||||
{
|
||||
interface_name = std::move(name);
|
||||
}
|
||||
|
||||
private:
|
||||
void emit_header() override;
|
||||
void emit_c_linkage();
|
||||
void emit_function_prototype(SPIRFunction &func, const Bitset &return_flags) override;
|
||||
|
||||
void emit_resources();
|
||||
void emit_buffer_block(const SPIRVariable &type) override;
|
||||
void emit_push_constant_block(const SPIRVariable &var) override;
|
||||
void emit_interface_block(const SPIRVariable &type);
|
||||
void emit_block_chain(SPIRBlock &block);
|
||||
void emit_uniform(const SPIRVariable &var) override;
|
||||
void emit_shared(const SPIRVariable &var);
|
||||
void emit_block_struct(SPIRType &type);
|
||||
std::string variable_decl(const SPIRType &type, const std::string &name, uint32_t id) override;
|
||||
|
||||
std::string argument_decl(const SPIRFunction::Parameter &arg);
|
||||
|
||||
SmallVector<std::string> resource_registrations;
|
||||
std::string impl_type;
|
||||
std::string resource_type;
|
||||
uint32_t shared_counter = 0;
|
||||
|
||||
std::string interface_name;
|
||||
};
|
||||
} // namespace SPIRV_CROSS_NAMESPACE
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,756 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Hans-Kristian Arntzen
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_CONTAINERS_HPP
|
||||
#define SPIRV_CROSS_CONTAINERS_HPP
|
||||
|
||||
#include "spirv_cross_error_handling.hpp"
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#ifdef SPIRV_CROSS_NAMESPACE_OVERRIDE
|
||||
#define SPIRV_CROSS_NAMESPACE SPIRV_CROSS_NAMESPACE_OVERRIDE
|
||||
#else
|
||||
#define SPIRV_CROSS_NAMESPACE spirv_cross
|
||||
#endif
|
||||
|
||||
namespace SPIRV_CROSS_NAMESPACE
|
||||
{
|
||||
#ifndef SPIRV_CROSS_FORCE_STL_TYPES
|
||||
// std::aligned_storage does not support size == 0, so roll our own.
|
||||
template <typename T, size_t N>
|
||||
class AlignedBuffer
|
||||
{
|
||||
public:
|
||||
T *data()
|
||||
{
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
// MSVC 2013 workarounds, sigh ...
|
||||
// Only use this workaround on MSVC 2013 due to some confusion around default initialized unions.
|
||||
// Spec seems to suggest the memory will be zero-initialized, which is *not* what we want.
|
||||
return reinterpret_cast<T *>(u.aligned_char);
|
||||
#else
|
||||
return reinterpret_cast<T *>(aligned_char);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
// MSVC 2013 workarounds, sigh ...
|
||||
union
|
||||
{
|
||||
char aligned_char[sizeof(T) * N];
|
||||
double dummy_aligner;
|
||||
} u;
|
||||
#else
|
||||
alignas(T) char aligned_char[sizeof(T) * N];
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class AlignedBuffer<T, 0>
|
||||
{
|
||||
public:
|
||||
T *data()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
// An immutable version of SmallVector which erases type information about storage.
|
||||
template <typename T>
|
||||
class VectorView
|
||||
{
|
||||
public:
|
||||
T &operator[](size_t i) SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
return ptr[i];
|
||||
}
|
||||
|
||||
const T &operator[](size_t i) const SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
return ptr[i];
|
||||
}
|
||||
|
||||
bool empty() const SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
return buffer_size == 0;
|
||||
}
|
||||
|
||||
size_t size() const SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
return buffer_size;
|
||||
}
|
||||
|
||||
T *data() SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
const T *data() const SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
T *begin() SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
T *end() SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
return ptr + buffer_size;
|
||||
}
|
||||
|
||||
const T *begin() const SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
const T *end() const SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
return ptr + buffer_size;
|
||||
}
|
||||
|
||||
T &front() SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
return ptr[0];
|
||||
}
|
||||
|
||||
const T &front() const SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
return ptr[0];
|
||||
}
|
||||
|
||||
T &back() SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
return ptr[buffer_size - 1];
|
||||
}
|
||||
|
||||
const T &back() const SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
return ptr[buffer_size - 1];
|
||||
}
|
||||
|
||||
// Makes it easier to consume SmallVector.
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
explicit operator std::vector<T>() const
|
||||
{
|
||||
// Another MSVC 2013 workaround. It does not understand lvalue/rvalue qualified operations.
|
||||
return std::vector<T>(ptr, ptr + buffer_size);
|
||||
}
|
||||
#else
|
||||
// Makes it easier to consume SmallVector.
|
||||
explicit operator std::vector<T>() const &
|
||||
{
|
||||
return std::vector<T>(ptr, ptr + buffer_size);
|
||||
}
|
||||
|
||||
// If we are converting as an r-value, we can pilfer our elements.
|
||||
explicit operator std::vector<T>() &&
|
||||
{
|
||||
return std::vector<T>(std::make_move_iterator(ptr), std::make_move_iterator(ptr + buffer_size));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Avoid sliced copies. Base class should only be read as a reference.
|
||||
VectorView(const VectorView &) = delete;
|
||||
void operator=(const VectorView &) = delete;
|
||||
|
||||
protected:
|
||||
VectorView() = default;
|
||||
T *ptr = nullptr;
|
||||
size_t buffer_size = 0;
|
||||
};
|
||||
|
||||
// Simple vector which supports up to N elements inline, without malloc/free.
|
||||
// We use a lot of throwaway vectors all over the place which triggers allocations.
|
||||
// This class only implements the subset of std::vector we need in SPIRV-Cross.
|
||||
// It is *NOT* a drop-in replacement in general projects.
|
||||
template <typename T, size_t N = 8>
|
||||
class SmallVector : public VectorView<T>
|
||||
{
|
||||
public:
|
||||
SmallVector() SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
this->ptr = stack_storage.data();
|
||||
buffer_capacity = N;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
SmallVector(const U *arg_list_begin, const U *arg_list_end) SPIRV_CROSS_NOEXCEPT : SmallVector()
|
||||
{
|
||||
auto count = size_t(arg_list_end - arg_list_begin);
|
||||
reserve(count);
|
||||
for (size_t i = 0; i < count; i++, arg_list_begin++)
|
||||
new (&this->ptr[i]) T(*arg_list_begin);
|
||||
this->buffer_size = count;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
SmallVector(std::initializer_list<U> init) SPIRV_CROSS_NOEXCEPT : SmallVector(init.begin(), init.end())
|
||||
{
|
||||
}
|
||||
|
||||
template <typename U, size_t M>
|
||||
explicit SmallVector(const U (&init)[M]) SPIRV_CROSS_NOEXCEPT : SmallVector(init, init + M)
|
||||
{
|
||||
}
|
||||
|
||||
SmallVector(SmallVector &&other) SPIRV_CROSS_NOEXCEPT : SmallVector()
|
||||
{
|
||||
*this = std::move(other);
|
||||
}
|
||||
|
||||
SmallVector &operator=(SmallVector &&other) SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
clear();
|
||||
if (other.ptr != other.stack_storage.data())
|
||||
{
|
||||
// Pilfer allocated pointer.
|
||||
if (this->ptr != stack_storage.data())
|
||||
free(this->ptr);
|
||||
this->ptr = other.ptr;
|
||||
this->buffer_size = other.buffer_size;
|
||||
buffer_capacity = other.buffer_capacity;
|
||||
other.ptr = nullptr;
|
||||
other.buffer_size = 0;
|
||||
other.buffer_capacity = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Need to move the stack contents individually.
|
||||
reserve(other.buffer_size);
|
||||
for (size_t i = 0; i < other.buffer_size; i++)
|
||||
{
|
||||
new (&this->ptr[i]) T(std::move(other.ptr[i]));
|
||||
other.ptr[i].~T();
|
||||
}
|
||||
this->buffer_size = other.buffer_size;
|
||||
other.buffer_size = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
SmallVector(const SmallVector &other) SPIRV_CROSS_NOEXCEPT : SmallVector()
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
SmallVector &operator=(const SmallVector &other) SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
clear();
|
||||
reserve(other.buffer_size);
|
||||
for (size_t i = 0; i < other.buffer_size; i++)
|
||||
new (&this->ptr[i]) T(other.ptr[i]);
|
||||
this->buffer_size = other.buffer_size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
explicit SmallVector(size_t count) SPIRV_CROSS_NOEXCEPT : SmallVector()
|
||||
{
|
||||
resize(count);
|
||||
}
|
||||
|
||||
~SmallVector()
|
||||
{
|
||||
clear();
|
||||
if (this->ptr != stack_storage.data())
|
||||
free(this->ptr);
|
||||
}
|
||||
|
||||
void clear() SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
for (size_t i = 0; i < this->buffer_size; i++)
|
||||
this->ptr[i].~T();
|
||||
this->buffer_size = 0;
|
||||
}
|
||||
|
||||
void push_back(const T &t) SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
reserve(this->buffer_size + 1);
|
||||
new (&this->ptr[this->buffer_size]) T(t);
|
||||
this->buffer_size++;
|
||||
}
|
||||
|
||||
void push_back(T &&t) SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
reserve(this->buffer_size + 1);
|
||||
new (&this->ptr[this->buffer_size]) T(std::move(t));
|
||||
this->buffer_size++;
|
||||
}
|
||||
|
||||
void pop_back() SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
// Work around false positive warning on GCC 8.3.
|
||||
// Calling pop_back on empty vector is undefined.
|
||||
if (!this->empty())
|
||||
resize(this->buffer_size - 1);
|
||||
}
|
||||
|
||||
template <typename... Ts>
|
||||
void emplace_back(Ts &&... ts) SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
reserve(this->buffer_size + 1);
|
||||
new (&this->ptr[this->buffer_size]) T(std::forward<Ts>(ts)...);
|
||||
this->buffer_size++;
|
||||
}
|
||||
|
||||
void reserve(size_t count) SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
if ((count > (std::numeric_limits<size_t>::max)() / sizeof(T)) ||
|
||||
(count > (std::numeric_limits<size_t>::max)() / 2))
|
||||
{
|
||||
// Only way this should ever happen is with garbage input, terminate.
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
if (count > buffer_capacity)
|
||||
{
|
||||
size_t target_capacity = buffer_capacity;
|
||||
if (target_capacity == 0)
|
||||
target_capacity = 1;
|
||||
|
||||
// Weird parens works around macro issues on Windows if NOMINMAX is not used.
|
||||
target_capacity = (std::max)(target_capacity, N);
|
||||
|
||||
// Need to ensure there is a POT value of target capacity which is larger than count,
|
||||
// otherwise this will overflow.
|
||||
while (target_capacity < count)
|
||||
target_capacity <<= 1u;
|
||||
|
||||
T *new_buffer =
|
||||
target_capacity > N ? static_cast<T *>(malloc(target_capacity * sizeof(T))) : stack_storage.data();
|
||||
|
||||
// If we actually fail this malloc, we are hosed anyways, there is no reason to attempt recovery.
|
||||
if (!new_buffer)
|
||||
std::terminate();
|
||||
|
||||
// In case for some reason two allocations both come from same stack.
|
||||
if (new_buffer != this->ptr)
|
||||
{
|
||||
// We don't deal with types which can throw in move constructor.
|
||||
for (size_t i = 0; i < this->buffer_size; i++)
|
||||
{
|
||||
new (&new_buffer[i]) T(std::move(this->ptr[i]));
|
||||
this->ptr[i].~T();
|
||||
}
|
||||
}
|
||||
|
||||
if (this->ptr != stack_storage.data())
|
||||
free(this->ptr);
|
||||
this->ptr = new_buffer;
|
||||
buffer_capacity = target_capacity;
|
||||
}
|
||||
}
|
||||
|
||||
void insert(T *itr, const T *insert_begin, const T *insert_end) SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
auto count = size_t(insert_end - insert_begin);
|
||||
if (itr == this->end())
|
||||
{
|
||||
reserve(this->buffer_size + count);
|
||||
for (size_t i = 0; i < count; i++, insert_begin++)
|
||||
new (&this->ptr[this->buffer_size + i]) T(*insert_begin);
|
||||
this->buffer_size += count;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this->buffer_size + count > buffer_capacity)
|
||||
{
|
||||
auto target_capacity = this->buffer_size + count;
|
||||
if (target_capacity == 0)
|
||||
target_capacity = 1;
|
||||
if (target_capacity < N)
|
||||
target_capacity = N;
|
||||
|
||||
while (target_capacity < count)
|
||||
target_capacity <<= 1u;
|
||||
|
||||
// Need to allocate new buffer. Move everything to a new buffer.
|
||||
T *new_buffer =
|
||||
target_capacity > N ? static_cast<T *>(malloc(target_capacity * sizeof(T))) : stack_storage.data();
|
||||
|
||||
// If we actually fail this malloc, we are hosed anyways, there is no reason to attempt recovery.
|
||||
if (!new_buffer)
|
||||
std::terminate();
|
||||
|
||||
// First, move elements from source buffer to new buffer.
|
||||
// We don't deal with types which can throw in move constructor.
|
||||
auto *target_itr = new_buffer;
|
||||
auto *original_source_itr = this->begin();
|
||||
|
||||
if (new_buffer != this->ptr)
|
||||
{
|
||||
while (original_source_itr != itr)
|
||||
{
|
||||
new (target_itr) T(std::move(*original_source_itr));
|
||||
original_source_itr->~T();
|
||||
++original_source_itr;
|
||||
++target_itr;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy-construct new elements.
|
||||
for (auto *source_itr = insert_begin; source_itr != insert_end; ++source_itr, ++target_itr)
|
||||
new (target_itr) T(*source_itr);
|
||||
|
||||
// Move over the other half.
|
||||
if (new_buffer != this->ptr || insert_begin != insert_end)
|
||||
{
|
||||
while (original_source_itr != this->end())
|
||||
{
|
||||
new (target_itr) T(std::move(*original_source_itr));
|
||||
original_source_itr->~T();
|
||||
++original_source_itr;
|
||||
++target_itr;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->ptr != stack_storage.data())
|
||||
free(this->ptr);
|
||||
this->ptr = new_buffer;
|
||||
buffer_capacity = target_capacity;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Move in place, need to be a bit careful about which elements are constructed and which are not.
|
||||
// Move the end and construct the new elements.
|
||||
auto *target_itr = this->end() + count;
|
||||
auto *source_itr = this->end();
|
||||
while (target_itr != this->end() && source_itr != itr)
|
||||
{
|
||||
--target_itr;
|
||||
--source_itr;
|
||||
new (target_itr) T(std::move(*source_itr));
|
||||
}
|
||||
|
||||
// For already constructed elements we can move-assign.
|
||||
std::move_backward(itr, source_itr, target_itr);
|
||||
|
||||
// For the inserts which go to already constructed elements, we can do a plain copy.
|
||||
while (itr != this->end() && insert_begin != insert_end)
|
||||
*itr++ = *insert_begin++;
|
||||
|
||||
// For inserts into newly allocated memory, we must copy-construct instead.
|
||||
while (insert_begin != insert_end)
|
||||
{
|
||||
new (itr) T(*insert_begin);
|
||||
++itr;
|
||||
++insert_begin;
|
||||
}
|
||||
}
|
||||
|
||||
this->buffer_size += count;
|
||||
}
|
||||
}
|
||||
|
||||
void insert(T *itr, const T &value) SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
insert(itr, &value, &value + 1);
|
||||
}
|
||||
|
||||
T *erase(T *itr) SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
std::move(itr + 1, this->end(), itr);
|
||||
this->ptr[--this->buffer_size].~T();
|
||||
return itr;
|
||||
}
|
||||
|
||||
void erase(T *start_erase, T *end_erase) SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
if (end_erase == this->end())
|
||||
{
|
||||
resize(size_t(start_erase - this->begin()));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto new_size = this->buffer_size - (end_erase - start_erase);
|
||||
std::move(end_erase, this->end(), start_erase);
|
||||
resize(new_size);
|
||||
}
|
||||
}
|
||||
|
||||
void resize(size_t new_size) SPIRV_CROSS_NOEXCEPT
|
||||
{
|
||||
if (new_size < this->buffer_size)
|
||||
{
|
||||
for (size_t i = new_size; i < this->buffer_size; i++)
|
||||
this->ptr[i].~T();
|
||||
}
|
||||
else if (new_size > this->buffer_size)
|
||||
{
|
||||
reserve(new_size);
|
||||
for (size_t i = this->buffer_size; i < new_size; i++)
|
||||
new (&this->ptr[i]) T();
|
||||
}
|
||||
|
||||
this->buffer_size = new_size;
|
||||
}
|
||||
|
||||
private:
|
||||
size_t buffer_capacity = 0;
|
||||
AlignedBuffer<T, N> stack_storage;
|
||||
};
|
||||
|
||||
// A vector without stack storage.
|
||||
// Could also be a typedef-ed to std::vector,
|
||||
// but might as well use the one we have.
|
||||
template <typename T>
|
||||
using Vector = SmallVector<T, 0>;
|
||||
|
||||
#else // SPIRV_CROSS_FORCE_STL_TYPES
|
||||
|
||||
template <typename T, size_t N = 8>
|
||||
using SmallVector = std::vector<T>;
|
||||
template <typename T>
|
||||
using Vector = std::vector<T>;
|
||||
template <typename T>
|
||||
using VectorView = std::vector<T>;
|
||||
|
||||
#endif // SPIRV_CROSS_FORCE_STL_TYPES
|
||||
|
||||
// An object pool which we use for allocating IVariant-derived objects.
|
||||
// We know we are going to allocate a bunch of objects of each type,
|
||||
// so amortize the mallocs.
|
||||
class ObjectPoolBase
|
||||
{
|
||||
public:
|
||||
virtual ~ObjectPoolBase() = default;
|
||||
virtual void deallocate_opaque(void *ptr) = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class ObjectPool : public ObjectPoolBase
|
||||
{
|
||||
public:
|
||||
explicit ObjectPool(unsigned start_object_count_ = 16)
|
||||
: start_object_count(start_object_count_)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename... P>
|
||||
T *allocate(P &&... p)
|
||||
{
|
||||
if (vacants.empty())
|
||||
{
|
||||
unsigned num_objects = start_object_count << memory.size();
|
||||
T *ptr = static_cast<T *>(malloc(num_objects * sizeof(T)));
|
||||
if (!ptr)
|
||||
return nullptr;
|
||||
|
||||
vacants.reserve(num_objects);
|
||||
for (unsigned i = 0; i < num_objects; i++)
|
||||
vacants.push_back(&ptr[i]);
|
||||
|
||||
memory.emplace_back(ptr);
|
||||
}
|
||||
|
||||
T *ptr = vacants.back();
|
||||
vacants.pop_back();
|
||||
new (ptr) T(std::forward<P>(p)...);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void deallocate(T *ptr)
|
||||
{
|
||||
ptr->~T();
|
||||
vacants.push_back(ptr);
|
||||
}
|
||||
|
||||
void deallocate_opaque(void *ptr) override
|
||||
{
|
||||
deallocate(static_cast<T *>(ptr));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
vacants.clear();
|
||||
memory.clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
Vector<T *> vacants;
|
||||
|
||||
struct MallocDeleter
|
||||
{
|
||||
void operator()(T *ptr)
|
||||
{
|
||||
::free(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
SmallVector<std::unique_ptr<T, MallocDeleter>> memory;
|
||||
unsigned start_object_count;
|
||||
};
|
||||
|
||||
template <size_t StackSize = 4096, size_t BlockSize = 4096>
|
||||
class StringStream
|
||||
{
|
||||
public:
|
||||
StringStream()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
~StringStream()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
// Disable copies and moves. Makes it easier to implement, and we don't need it.
|
||||
StringStream(const StringStream &) = delete;
|
||||
void operator=(const StringStream &) = delete;
|
||||
|
||||
template <typename T, typename std::enable_if<!std::is_floating_point<T>::value, int>::type = 0>
|
||||
StringStream &operator<<(const T &t)
|
||||
{
|
||||
auto s = std::to_string(t);
|
||||
append(s.data(), s.size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Only overload this to make float/double conversions ambiguous.
|
||||
StringStream &operator<<(uint32_t v)
|
||||
{
|
||||
auto s = std::to_string(v);
|
||||
append(s.data(), s.size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
StringStream &operator<<(char c)
|
||||
{
|
||||
append(&c, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
StringStream &operator<<(const std::string &s)
|
||||
{
|
||||
append(s.data(), s.size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
StringStream &operator<<(const char *s)
|
||||
{
|
||||
append(s, strlen(s));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
StringStream &operator<<(const char (&s)[N])
|
||||
{
|
||||
append(s, strlen(s));
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string str() const
|
||||
{
|
||||
std::string ret;
|
||||
size_t target_size = 0;
|
||||
for (auto &saved : saved_buffers)
|
||||
target_size += saved.offset;
|
||||
target_size += current_buffer.offset;
|
||||
ret.reserve(target_size);
|
||||
|
||||
for (auto &saved : saved_buffers)
|
||||
ret.insert(ret.end(), saved.buffer, saved.buffer + saved.offset);
|
||||
ret.insert(ret.end(), current_buffer.buffer, current_buffer.buffer + current_buffer.offset);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
for (auto &saved : saved_buffers)
|
||||
if (saved.buffer != stack_buffer)
|
||||
free(saved.buffer);
|
||||
if (current_buffer.buffer != stack_buffer)
|
||||
free(current_buffer.buffer);
|
||||
|
||||
saved_buffers.clear();
|
||||
current_buffer.buffer = stack_buffer;
|
||||
current_buffer.offset = 0;
|
||||
current_buffer.size = sizeof(stack_buffer);
|
||||
}
|
||||
|
||||
private:
|
||||
struct Buffer
|
||||
{
|
||||
char *buffer = nullptr;
|
||||
size_t offset = 0;
|
||||
size_t size = 0;
|
||||
};
|
||||
Buffer current_buffer;
|
||||
char stack_buffer[StackSize];
|
||||
SmallVector<Buffer> saved_buffers;
|
||||
|
||||
void append(const char *s, size_t len)
|
||||
{
|
||||
size_t avail = current_buffer.size - current_buffer.offset;
|
||||
if (avail < len)
|
||||
{
|
||||
if (avail > 0)
|
||||
{
|
||||
memcpy(current_buffer.buffer + current_buffer.offset, s, avail);
|
||||
s += avail;
|
||||
len -= avail;
|
||||
current_buffer.offset += avail;
|
||||
}
|
||||
|
||||
saved_buffers.push_back(current_buffer);
|
||||
size_t target_size = len > BlockSize ? len : BlockSize;
|
||||
current_buffer.buffer = static_cast<char *>(malloc(target_size));
|
||||
if (!current_buffer.buffer)
|
||||
SPIRV_CROSS_THROW("Out of memory.");
|
||||
|
||||
memcpy(current_buffer.buffer, s, len);
|
||||
current_buffer.offset = len;
|
||||
current_buffer.size = target_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(current_buffer.buffer + current_buffer.offset, s, len);
|
||||
current_buffer.offset += len;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace SPIRV_CROSS_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2015-2021 Arm Limited
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_ERROR_HANDLING
|
||||
#define SPIRV_CROSS_ERROR_HANDLING
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#ifndef SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
|
||||
#include <stdexcept>
|
||||
#endif
|
||||
|
||||
#ifdef SPIRV_CROSS_NAMESPACE_OVERRIDE
|
||||
#define SPIRV_CROSS_NAMESPACE SPIRV_CROSS_NAMESPACE_OVERRIDE
|
||||
#else
|
||||
#define SPIRV_CROSS_NAMESPACE spirv_cross
|
||||
#endif
|
||||
|
||||
namespace SPIRV_CROSS_NAMESPACE
|
||||
{
|
||||
#ifdef SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
|
||||
#if !defined(_MSC_VER) || defined(__clang__)
|
||||
[[noreturn]]
|
||||
#elif defined(_MSC_VER)
|
||||
__declspec(noreturn)
|
||||
#endif
|
||||
inline void
|
||||
report_and_abort(const std::string &msg)
|
||||
{
|
||||
#ifdef NDEBUG
|
||||
(void)msg;
|
||||
#else
|
||||
fprintf(stderr, "There was a compiler error: %s\n", msg.c_str());
|
||||
#endif
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
|
||||
#define SPIRV_CROSS_THROW(x) report_and_abort(x)
|
||||
#else
|
||||
class CompilerError : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit CompilerError(const std::string &str)
|
||||
: std::runtime_error(str)
|
||||
{
|
||||
}
|
||||
|
||||
explicit CompilerError(const char *str)
|
||||
: std::runtime_error(str)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#define SPIRV_CROSS_THROW(x) throw CompilerError(x)
|
||||
#endif
|
||||
|
||||
// MSVC 2013 does not have noexcept. We need this for Variant to get move constructor to work correctly
|
||||
// instead of copy constructor.
|
||||
// MSVC 2013 ignores that move constructors cannot throw in std::vector, so just don't define it.
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define SPIRV_CROSS_NOEXCEPT
|
||||
#else
|
||||
#define SPIRV_CROSS_NOEXCEPT noexcept
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201402l
|
||||
#define SPIRV_CROSS_DEPRECATED(reason) [[deprecated(reason)]]
|
||||
#elif defined(__GNUC__)
|
||||
#define SPIRV_CROSS_DEPRECATED(reason) __attribute__((deprecated))
|
||||
#elif defined(_MSC_VER)
|
||||
#define SPIRV_CROSS_DEPRECATED(reason) __declspec(deprecated(reason))
|
||||
#else
|
||||
#define SPIRV_CROSS_DEPRECATED(reason)
|
||||
#endif
|
||||
} // namespace SPIRV_CROSS_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright 2018-2021 Arm Limited
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_PARSED_IR_HPP
|
||||
#define SPIRV_CROSS_PARSED_IR_HPP
|
||||
|
||||
#include "spirv_common.hpp"
|
||||
#include <stdint.h>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace SPIRV_CROSS_NAMESPACE
|
||||
{
|
||||
|
||||
// This data structure holds all information needed to perform cross-compilation and reflection.
|
||||
// It is the output of the Parser, but any implementation could create this structure.
|
||||
// It is intentionally very "open" and struct-like with some helper functions to deal with decorations.
|
||||
// Parser is the reference implementation of how this data structure should be filled in.
|
||||
|
||||
class ParsedIR
|
||||
{
|
||||
private:
|
||||
// This must be destroyed after the "ids" vector.
|
||||
std::unique_ptr<ObjectPoolGroup> pool_group;
|
||||
|
||||
public:
|
||||
ParsedIR();
|
||||
|
||||
// Due to custom allocations from object pools, we cannot use a default copy constructor.
|
||||
ParsedIR(const ParsedIR &other);
|
||||
ParsedIR &operator=(const ParsedIR &other);
|
||||
|
||||
// Moves are unproblematic, but we need to implement it anyways, since MSVC 2013 does not understand
|
||||
// how to default-implement these.
|
||||
ParsedIR(ParsedIR &&other) SPIRV_CROSS_NOEXCEPT;
|
||||
ParsedIR &operator=(ParsedIR &&other) SPIRV_CROSS_NOEXCEPT;
|
||||
|
||||
// Resizes ids, meta and block_meta.
|
||||
void set_id_bounds(uint32_t bounds);
|
||||
|
||||
// The raw SPIR-V, instructions and opcodes refer to this by offset + count.
|
||||
std::vector<uint32_t> spirv;
|
||||
|
||||
// Holds various data structures which inherit from IVariant.
|
||||
SmallVector<Variant> ids;
|
||||
|
||||
// Various meta data for IDs, decorations, names, etc.
|
||||
std::unordered_map<ID, Meta> meta;
|
||||
|
||||
// Holds all IDs which have a certain type.
|
||||
// This is needed so we can iterate through a specific kind of resource quickly,
|
||||
// and in-order of module declaration.
|
||||
SmallVector<ID> ids_for_type[TypeCount];
|
||||
|
||||
// Special purpose lists which contain a union of types.
|
||||
// This is needed so we can declare specialization constants and structs in an interleaved fashion,
|
||||
// among other things.
|
||||
// Constants can be undef or of struct type, and struct array sizes can use specialization constants.
|
||||
SmallVector<ID> ids_for_constant_undef_or_type;
|
||||
SmallVector<ID> ids_for_constant_or_variable;
|
||||
|
||||
// We need to keep track of the width the Ops that contains a type for the
|
||||
// OpSwitch instruction, since this one doesn't contains the type in the
|
||||
// instruction itself. And in some case we need to cast the condition to
|
||||
// wider types. We only need the width to do the branch fixup since the
|
||||
// type check itself can be done at runtime
|
||||
std::unordered_map<ID, uint32_t> load_type_width;
|
||||
|
||||
// Declared capabilities and extensions in the SPIR-V module.
|
||||
// Not really used except for reflection at the moment.
|
||||
SmallVector<spv::Capability> declared_capabilities;
|
||||
SmallVector<std::string> declared_extensions;
|
||||
|
||||
// Meta data about blocks. The cross-compiler needs to query if a block is either of these types.
|
||||
// It is a bitset as there can be more than one tag per block.
|
||||
enum BlockMetaFlagBits
|
||||
{
|
||||
BLOCK_META_LOOP_HEADER_BIT = 1 << 0,
|
||||
BLOCK_META_CONTINUE_BIT = 1 << 1,
|
||||
BLOCK_META_LOOP_MERGE_BIT = 1 << 2,
|
||||
BLOCK_META_SELECTION_MERGE_BIT = 1 << 3,
|
||||
BLOCK_META_MULTISELECT_MERGE_BIT = 1 << 4
|
||||
};
|
||||
using BlockMetaFlags = uint8_t;
|
||||
SmallVector<BlockMetaFlags> block_meta;
|
||||
std::unordered_map<BlockID, BlockID> continue_block_to_loop_header;
|
||||
|
||||
// Normally, we'd stick SPIREntryPoint in ids array, but it conflicts with SPIRFunction.
|
||||
// Entry points can therefore be seen as some sort of meta structure.
|
||||
std::unordered_map<FunctionID, SPIREntryPoint> entry_points;
|
||||
FunctionID default_entry_point = 0;
|
||||
|
||||
struct Source
|
||||
{
|
||||
uint32_t version = 0;
|
||||
bool es = false;
|
||||
bool known = false;
|
||||
bool hlsl = false;
|
||||
|
||||
Source() = default;
|
||||
};
|
||||
|
||||
Source source;
|
||||
|
||||
spv::AddressingModel addressing_model = spv::AddressingModelMax;
|
||||
spv::MemoryModel memory_model = spv::MemoryModelMax;
|
||||
|
||||
// Decoration handling methods.
|
||||
// Can be useful for simple "raw" reflection.
|
||||
// However, most members are here because the Parser needs most of these,
|
||||
// and might as well just have the whole suite of decoration/name handling in one place.
|
||||
void set_name(ID id, const std::string &name);
|
||||
const std::string &get_name(ID id) const;
|
||||
void set_decoration(ID id, spv::Decoration decoration, uint32_t argument = 0);
|
||||
void set_decoration_string(ID id, spv::Decoration decoration, const std::string &argument);
|
||||
bool has_decoration(ID id, spv::Decoration decoration) const;
|
||||
uint32_t get_decoration(ID id, spv::Decoration decoration) const;
|
||||
const std::string &get_decoration_string(ID id, spv::Decoration decoration) const;
|
||||
const Bitset &get_decoration_bitset(ID id) const;
|
||||
void unset_decoration(ID id, spv::Decoration decoration);
|
||||
|
||||
// Decoration handling methods (for members of a struct).
|
||||
void set_member_name(TypeID id, uint32_t index, const std::string &name);
|
||||
const std::string &get_member_name(TypeID id, uint32_t index) const;
|
||||
void set_member_decoration(TypeID id, uint32_t index, spv::Decoration decoration, uint32_t argument = 0);
|
||||
void set_member_decoration_string(TypeID id, uint32_t index, spv::Decoration decoration,
|
||||
const std::string &argument);
|
||||
uint32_t get_member_decoration(TypeID id, uint32_t index, spv::Decoration decoration) const;
|
||||
const std::string &get_member_decoration_string(TypeID id, uint32_t index, spv::Decoration decoration) const;
|
||||
bool has_member_decoration(TypeID id, uint32_t index, spv::Decoration decoration) const;
|
||||
const Bitset &get_member_decoration_bitset(TypeID id, uint32_t index) const;
|
||||
void unset_member_decoration(TypeID id, uint32_t index, spv::Decoration decoration);
|
||||
|
||||
void mark_used_as_array_length(ID id);
|
||||
uint32_t increase_bound_by(uint32_t count);
|
||||
Bitset get_buffer_block_flags(const SPIRVariable &var) const;
|
||||
Bitset get_buffer_block_type_flags(const SPIRType &type) const;
|
||||
|
||||
void add_typed_id(Types type, ID id);
|
||||
void remove_typed_id(Types type, ID id);
|
||||
|
||||
class LoopLock
|
||||
{
|
||||
public:
|
||||
explicit LoopLock(uint32_t *counter);
|
||||
LoopLock(const LoopLock &) = delete;
|
||||
void operator=(const LoopLock &) = delete;
|
||||
LoopLock(LoopLock &&other) SPIRV_CROSS_NOEXCEPT;
|
||||
LoopLock &operator=(LoopLock &&other) SPIRV_CROSS_NOEXCEPT;
|
||||
~LoopLock();
|
||||
|
||||
private:
|
||||
uint32_t *lock = nullptr;
|
||||
};
|
||||
|
||||
// This must be held while iterating over a type ID array.
|
||||
// It is undefined if someone calls set<>() while we're iterating over a data structure, so we must
|
||||
// make sure that this case is avoided.
|
||||
|
||||
// If we have a hard lock, it is an error to call set<>(), and an exception is thrown.
|
||||
// If we have a soft lock, we silently ignore any additions to the typed arrays.
|
||||
// This should only be used for physical ID remapping where we need to create an ID, but we will never
|
||||
// care about iterating over them.
|
||||
LoopLock create_loop_hard_lock() const;
|
||||
LoopLock create_loop_soft_lock() const;
|
||||
|
||||
template <typename T, typename Op>
|
||||
void for_each_typed_id(const Op &op)
|
||||
{
|
||||
auto loop_lock = create_loop_hard_lock();
|
||||
for (auto &id : ids_for_type[T::type])
|
||||
{
|
||||
if (ids[id].get_type() == static_cast<Types>(T::type))
|
||||
op(id, get<T>(id));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename Op>
|
||||
void for_each_typed_id(const Op &op) const
|
||||
{
|
||||
auto loop_lock = create_loop_hard_lock();
|
||||
for (auto &id : ids_for_type[T::type])
|
||||
{
|
||||
if (ids[id].get_type() == static_cast<Types>(T::type))
|
||||
op(id, get<T>(id));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void reset_all_of_type()
|
||||
{
|
||||
reset_all_of_type(static_cast<Types>(T::type));
|
||||
}
|
||||
|
||||
void reset_all_of_type(Types type);
|
||||
|
||||
Meta *find_meta(ID id);
|
||||
const Meta *find_meta(ID id) const;
|
||||
|
||||
const std::string &get_empty_string() const
|
||||
{
|
||||
return empty_string;
|
||||
}
|
||||
|
||||
void make_constant_null(uint32_t id, uint32_t type, bool add_to_typed_id_set);
|
||||
|
||||
void fixup_reserved_names();
|
||||
|
||||
static void sanitize_underscores(std::string &str);
|
||||
static void sanitize_identifier(std::string &str, bool member, bool allow_reserved_prefixes);
|
||||
static bool is_globally_reserved_identifier(std::string &str, bool allow_reserved_prefixes);
|
||||
|
||||
uint32_t get_spirv_version() const;
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
T &get(uint32_t id)
|
||||
{
|
||||
return variant_get<T>(ids[id]);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T &get(uint32_t id) const
|
||||
{
|
||||
return variant_get<T>(ids[id]);
|
||||
}
|
||||
|
||||
mutable uint32_t loop_iteration_depth_hard = 0;
|
||||
mutable uint32_t loop_iteration_depth_soft = 0;
|
||||
std::string empty_string;
|
||||
Bitset cleared_bitset;
|
||||
|
||||
std::unordered_set<uint32_t> meta_needing_name_fixup;
|
||||
};
|
||||
} // namespace SPIRV_CROSS_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2015-2021 Arm Limited
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_UTIL_HPP
|
||||
#define SPIRV_CROSS_UTIL_HPP
|
||||
|
||||
#include "spirv_cross.hpp"
|
||||
|
||||
namespace spirv_cross_util
|
||||
{
|
||||
void rename_interface_variable(SPIRV_CROSS_NAMESPACE::Compiler &compiler,
|
||||
const SPIRV_CROSS_NAMESPACE::SmallVector<SPIRV_CROSS_NAMESPACE::Resource> &resources,
|
||||
uint32_t location, const std::string &name);
|
||||
void inherit_combined_sampler_bindings(SPIRV_CROSS_NAMESPACE::Compiler &compiler);
|
||||
} // namespace spirv_cross_util
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,414 @@
|
||||
/*
|
||||
* Copyright 2016-2021 Robert Konrad
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* At your option, you may choose to accept this material under either:
|
||||
* 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
|
||||
* 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_HLSL_HPP
|
||||
#define SPIRV_HLSL_HPP
|
||||
|
||||
#include "spirv_glsl.hpp"
|
||||
#include <utility>
|
||||
|
||||
namespace SPIRV_CROSS_NAMESPACE
|
||||
{
|
||||
// Interface which remaps vertex inputs to a fixed semantic name to make linking easier.
|
||||
struct HLSLVertexAttributeRemap
|
||||
{
|
||||
uint32_t location;
|
||||
std::string semantic;
|
||||
};
|
||||
// Specifying a root constant (d3d12) or push constant range (vulkan).
|
||||
//
|
||||
// `start` and `end` denotes the range of the root constant in bytes.
|
||||
// Both values need to be multiple of 4.
|
||||
struct RootConstants
|
||||
{
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
|
||||
uint32_t binding;
|
||||
uint32_t space;
|
||||
};
|
||||
|
||||
// For finer control, decorations may be removed from specific resources instead with unset_decoration().
|
||||
enum HLSLBindingFlagBits
|
||||
{
|
||||
HLSL_BINDING_AUTO_NONE_BIT = 0,
|
||||
|
||||
// Push constant (root constant) resources will be declared as CBVs (b-space) without a register() declaration.
|
||||
// A register will be automatically assigned by the D3D compiler, but must therefore be reflected in D3D-land.
|
||||
// Push constants do not normally have a DecorationBinding set, but if they do, this can be used to ignore it.
|
||||
HLSL_BINDING_AUTO_PUSH_CONSTANT_BIT = 1 << 0,
|
||||
|
||||
// cbuffer resources will be declared as CBVs (b-space) without a register() declaration.
|
||||
// A register will be automatically assigned, but must be reflected in D3D-land.
|
||||
HLSL_BINDING_AUTO_CBV_BIT = 1 << 1,
|
||||
|
||||
// All SRVs (t-space) will be declared without a register() declaration.
|
||||
HLSL_BINDING_AUTO_SRV_BIT = 1 << 2,
|
||||
|
||||
// All UAVs (u-space) will be declared without a register() declaration.
|
||||
HLSL_BINDING_AUTO_UAV_BIT = 1 << 3,
|
||||
|
||||
// All samplers (s-space) will be declared without a register() declaration.
|
||||
HLSL_BINDING_AUTO_SAMPLER_BIT = 1 << 4,
|
||||
|
||||
// No resources will be declared with register().
|
||||
HLSL_BINDING_AUTO_ALL = 0x7fffffff
|
||||
};
|
||||
using HLSLBindingFlags = uint32_t;
|
||||
|
||||
// By matching stage, desc_set and binding for a SPIR-V resource,
|
||||
// register bindings are set based on whether the HLSL resource is a
|
||||
// CBV, UAV, SRV or Sampler. A single binding in SPIR-V might contain multiple
|
||||
// resource types, e.g. COMBINED_IMAGE_SAMPLER, and SRV/Sampler bindings will be used respectively.
|
||||
// On SM 5.0 and lower, register_space is ignored.
|
||||
//
|
||||
// To remap a push constant block which does not have any desc_set/binding associated with it,
|
||||
// use ResourceBindingPushConstant{DescriptorSet,Binding} as values for desc_set/binding.
|
||||
// For deeper control of push constants, set_root_constant_layouts() can be used instead.
|
||||
struct HLSLResourceBinding
|
||||
{
|
||||
spv::ExecutionModel stage = spv::ExecutionModelMax;
|
||||
uint32_t desc_set = 0;
|
||||
uint32_t binding = 0;
|
||||
|
||||
struct Binding
|
||||
{
|
||||
uint32_t register_space = 0;
|
||||
uint32_t register_binding = 0;
|
||||
} cbv, uav, srv, sampler;
|
||||
};
|
||||
|
||||
enum HLSLAuxBinding
|
||||
{
|
||||
HLSL_AUX_BINDING_BASE_VERTEX_INSTANCE = 0
|
||||
};
|
||||
|
||||
class CompilerHLSL : public CompilerGLSL
|
||||
{
|
||||
public:
|
||||
struct Options
|
||||
{
|
||||
uint32_t shader_model = 30; // TODO: map ps_4_0_level_9_0,... somehow
|
||||
|
||||
// Allows the PointSize builtin in SM 4.0+, and ignores it, as PointSize is not supported in SM 4+.
|
||||
bool point_size_compat = false;
|
||||
|
||||
// Allows the PointCoord builtin, returns float2(0.5, 0.5), as PointCoord is not supported in HLSL.
|
||||
bool point_coord_compat = false;
|
||||
|
||||
// If true, the backend will assume that VertexIndex and InstanceIndex will need to apply
|
||||
// a base offset, and you will need to fill in a cbuffer with offsets.
|
||||
// Set to false if you know you will never use base instance or base vertex
|
||||
// functionality as it might remove an internal cbuffer.
|
||||
bool support_nonzero_base_vertex_base_instance = false;
|
||||
|
||||
// Forces a storage buffer to always be declared as UAV, even if the readonly decoration is used.
|
||||
// By default, a readonly storage buffer will be declared as ByteAddressBuffer (SRV) instead.
|
||||
// Alternatively, use set_hlsl_force_storage_buffer_as_uav to specify individually.
|
||||
bool force_storage_buffer_as_uav = false;
|
||||
|
||||
// Forces any storage image type marked as NonWritable to be considered an SRV instead.
|
||||
// For this to work with function call parameters, NonWritable must be considered to be part of the type system
|
||||
// so that NonWritable image arguments are also translated to Texture rather than RWTexture.
|
||||
bool nonwritable_uav_texture_as_srv = false;
|
||||
|
||||
// Enables native 16-bit types. Needs SM 6.2.
|
||||
// Uses half/int16_t/uint16_t instead of min16* types.
|
||||
// Also adds support for 16-bit load-store from (RW)ByteAddressBuffer.
|
||||
bool enable_16bit_types = false;
|
||||
|
||||
// If matrices are used as IO variables, flatten the attribute declaration to use
|
||||
// TEXCOORD{N,N+1,N+2,...} rather than TEXCOORDN_{0,1,2,3}.
|
||||
// If add_vertex_attribute_remap is used and this feature is used,
|
||||
// the semantic name will be queried once per active location.
|
||||
bool flatten_matrix_vertex_input_semantics = false;
|
||||
|
||||
// Rather than emitting main() for the entry point, use the name in SPIR-V.
|
||||
bool use_entry_point_name = false;
|
||||
|
||||
// Preserve (RW)StructuredBuffer types if the input source was HLSL.
|
||||
// This relies on UserTypeGOOGLE to encode the buffer type either as "structuredbuffer" or "rwstructuredbuffer"
|
||||
// whereas the type can be extended with an optional subtype, e.g. "structuredbuffer:int".
|
||||
bool preserve_structured_buffers = false;
|
||||
};
|
||||
|
||||
explicit CompilerHLSL(std::vector<uint32_t> spirv_)
|
||||
: CompilerGLSL(std::move(spirv_))
|
||||
{
|
||||
}
|
||||
|
||||
CompilerHLSL(const uint32_t *ir_, size_t size)
|
||||
: CompilerGLSL(ir_, size)
|
||||
{
|
||||
}
|
||||
|
||||
explicit CompilerHLSL(const ParsedIR &ir_)
|
||||
: CompilerGLSL(ir_)
|
||||
{
|
||||
}
|
||||
|
||||
explicit CompilerHLSL(ParsedIR &&ir_)
|
||||
: CompilerGLSL(std::move(ir_))
|
||||
{
|
||||
}
|
||||
|
||||
const Options &get_hlsl_options() const
|
||||
{
|
||||
return hlsl_options;
|
||||
}
|
||||
|
||||
void set_hlsl_options(const Options &opts)
|
||||
{
|
||||
hlsl_options = opts;
|
||||
}
|
||||
|
||||
// Optionally specify a custom root constant layout.
|
||||
//
|
||||
// Push constants ranges will be split up according to the
|
||||
// layout specified.
|
||||
void set_root_constant_layouts(std::vector<RootConstants> layout);
|
||||
|
||||
// Compiles and remaps vertex attributes at specific locations to a fixed semantic.
|
||||
// The default is TEXCOORD# where # denotes location.
|
||||
// Matrices are unrolled to vectors with notation ${SEMANTIC}_#, where # denotes row.
|
||||
// $SEMANTIC is either TEXCOORD# or a semantic name specified here.
|
||||
void add_vertex_attribute_remap(const HLSLVertexAttributeRemap &vertex_attributes);
|
||||
std::string compile() override;
|
||||
|
||||
// This is a special HLSL workaround for the NumWorkGroups builtin.
|
||||
// This does not exist in HLSL, so the calling application must create a dummy cbuffer in
|
||||
// which the application will store this builtin.
|
||||
// The cbuffer layout will be:
|
||||
// cbuffer SPIRV_Cross_NumWorkgroups : register(b#, space#) { uint3 SPIRV_Cross_NumWorkgroups_count; };
|
||||
// This must be called before compile().
|
||||
// The function returns 0 if NumWorkGroups builtin is not statically used in the shader from the current entry point.
|
||||
// If non-zero, this returns the variable ID of a cbuffer which corresponds to
|
||||
// the cbuffer declared above. By default, no binding or descriptor set decoration is set,
|
||||
// so the calling application should declare explicit bindings on this ID before calling compile().
|
||||
VariableID remap_num_workgroups_builtin();
|
||||
|
||||
// Controls how resource bindings are declared in the output HLSL.
|
||||
void set_resource_binding_flags(HLSLBindingFlags flags);
|
||||
|
||||
// resource is a resource binding to indicate the HLSL CBV, SRV, UAV or sampler binding
|
||||
// to use for a particular SPIR-V description set
|
||||
// and binding. If resource bindings are provided,
|
||||
// is_hlsl_resource_binding_used() will return true after calling ::compile() if
|
||||
// the set/binding combination was used by the HLSL code.
|
||||
void add_hlsl_resource_binding(const HLSLResourceBinding &resource);
|
||||
bool is_hlsl_resource_binding_used(spv::ExecutionModel model, uint32_t set, uint32_t binding) const;
|
||||
|
||||
// Controls which storage buffer bindings will be forced to be declared as UAVs.
|
||||
void set_hlsl_force_storage_buffer_as_uav(uint32_t desc_set, uint32_t binding);
|
||||
|
||||
// By default, these magic buffers are not assigned a specific binding.
|
||||
void set_hlsl_aux_buffer_binding(HLSLAuxBinding binding, uint32_t register_index, uint32_t register_space);
|
||||
void unset_hlsl_aux_buffer_binding(HLSLAuxBinding binding);
|
||||
bool is_hlsl_aux_buffer_binding_used(HLSLAuxBinding binding) const;
|
||||
|
||||
private:
|
||||
std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override;
|
||||
std::string image_type_hlsl(const SPIRType &type, uint32_t id);
|
||||
std::string image_type_hlsl_modern(const SPIRType &type, uint32_t id);
|
||||
std::string image_type_hlsl_legacy(const SPIRType &type, uint32_t id);
|
||||
void emit_function_prototype(SPIRFunction &func, const Bitset &return_flags) override;
|
||||
void emit_hlsl_entry_point();
|
||||
void emit_header() override;
|
||||
void emit_resources();
|
||||
void emit_interface_block_globally(const SPIRVariable &type);
|
||||
void emit_interface_block_in_struct(const SPIRVariable &var, std::unordered_set<uint32_t> &active_locations);
|
||||
void emit_interface_block_member_in_struct(const SPIRVariable &var, uint32_t member_index, uint32_t location,
|
||||
std::unordered_set<uint32_t> &active_locations);
|
||||
void emit_builtin_inputs_in_struct();
|
||||
void emit_builtin_outputs_in_struct();
|
||||
void emit_builtin_primitive_outputs_in_struct();
|
||||
void emit_texture_op(const Instruction &i, bool sparse) override;
|
||||
void emit_instruction(const Instruction &instruction) override;
|
||||
void emit_glsl_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args,
|
||||
uint32_t count) override;
|
||||
void emit_buffer_block(const SPIRVariable &type) override;
|
||||
void emit_push_constant_block(const SPIRVariable &var) override;
|
||||
void emit_uniform(const SPIRVariable &var) override;
|
||||
void emit_modern_uniform(const SPIRVariable &var);
|
||||
void emit_legacy_uniform(const SPIRVariable &var);
|
||||
void emit_specialization_constants_and_structs();
|
||||
void emit_composite_constants();
|
||||
void emit_fixup() override;
|
||||
std::string builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClass storage) override;
|
||||
std::string layout_for_member(const SPIRType &type, uint32_t index) override;
|
||||
std::string to_interpolation_qualifiers(const Bitset &flags) override;
|
||||
std::string bitcast_glsl_op(const SPIRType &result_type, const SPIRType &argument_type) override;
|
||||
bool emit_complex_bitcast(uint32_t result_type, uint32_t id, uint32_t op0) override;
|
||||
std::string to_func_call_arg(const SPIRFunction::Parameter &arg, uint32_t id) override;
|
||||
std::string to_sampler_expression(uint32_t id);
|
||||
std::string to_resource_binding(const SPIRVariable &var);
|
||||
std::string to_resource_binding_sampler(const SPIRVariable &var);
|
||||
std::string to_resource_register(HLSLBindingFlagBits flag, char space, uint32_t binding, uint32_t set);
|
||||
std::string to_initializer_expression(const SPIRVariable &var) override;
|
||||
void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id) override;
|
||||
void emit_access_chain(const Instruction &instruction);
|
||||
void emit_load(const Instruction &instruction);
|
||||
void read_access_chain(std::string *expr, const std::string &lhs, const SPIRAccessChain &chain);
|
||||
void read_access_chain_struct(const std::string &lhs, const SPIRAccessChain &chain);
|
||||
void read_access_chain_array(const std::string &lhs, const SPIRAccessChain &chain);
|
||||
void write_access_chain(const SPIRAccessChain &chain, uint32_t value, const SmallVector<uint32_t> &composite_chain);
|
||||
void write_access_chain_struct(const SPIRAccessChain &chain, uint32_t value,
|
||||
const SmallVector<uint32_t> &composite_chain);
|
||||
void write_access_chain_array(const SPIRAccessChain &chain, uint32_t value,
|
||||
const SmallVector<uint32_t> &composite_chain);
|
||||
std::string write_access_chain_value(uint32_t value, const SmallVector<uint32_t> &composite_chain, bool enclose);
|
||||
void emit_store(const Instruction &instruction);
|
||||
void emit_atomic(const uint32_t *ops, uint32_t length, spv::Op op);
|
||||
void emit_subgroup_op(const Instruction &i) override;
|
||||
void emit_block_hints(const SPIRBlock &block) override;
|
||||
|
||||
void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index, const std::string &qualifier,
|
||||
uint32_t base_offset = 0) override;
|
||||
void emit_rayquery_function(const char *commited, const char *candidate, const uint32_t *ops);
|
||||
void emit_mesh_tasks(SPIRBlock &block) override;
|
||||
|
||||
const char *to_storage_qualifiers_glsl(const SPIRVariable &var) override;
|
||||
void replace_illegal_names() override;
|
||||
|
||||
SPIRType::BaseType get_builtin_basetype(spv::BuiltIn builtin, SPIRType::BaseType default_type) override;
|
||||
|
||||
bool is_hlsl_force_storage_buffer_as_uav(ID id) const;
|
||||
|
||||
Options hlsl_options;
|
||||
|
||||
// TODO: Refactor this to be more similar to MSL, maybe have some common system in place?
|
||||
bool requires_op_fmod = false;
|
||||
bool requires_fp16_packing = false;
|
||||
bool requires_uint2_packing = false;
|
||||
bool requires_explicit_fp16_packing = false;
|
||||
bool requires_unorm8_packing = false;
|
||||
bool requires_snorm8_packing = false;
|
||||
bool requires_unorm16_packing = false;
|
||||
bool requires_snorm16_packing = false;
|
||||
bool requires_bitfield_insert = false;
|
||||
bool requires_bitfield_extract = false;
|
||||
bool requires_inverse_2x2 = false;
|
||||
bool requires_inverse_3x3 = false;
|
||||
bool requires_inverse_4x4 = false;
|
||||
bool requires_scalar_reflect = false;
|
||||
bool requires_scalar_refract = false;
|
||||
bool requires_scalar_faceforward = false;
|
||||
|
||||
struct TextureSizeVariants
|
||||
{
|
||||
// MSVC 2013 workaround.
|
||||
TextureSizeVariants()
|
||||
{
|
||||
srv = 0;
|
||||
for (auto &unorm : uav)
|
||||
for (auto &u : unorm)
|
||||
u = 0;
|
||||
}
|
||||
uint64_t srv;
|
||||
uint64_t uav[3][4];
|
||||
} required_texture_size_variants;
|
||||
|
||||
void require_texture_query_variant(uint32_t var_id);
|
||||
void emit_texture_size_variants(uint64_t variant_mask, const char *vecsize_qualifier, bool uav,
|
||||
const char *type_qualifier);
|
||||
|
||||
enum TextureQueryVariantDim
|
||||
{
|
||||
Query1D = 0,
|
||||
Query1DArray,
|
||||
Query2D,
|
||||
Query2DArray,
|
||||
Query3D,
|
||||
QueryBuffer,
|
||||
QueryCube,
|
||||
QueryCubeArray,
|
||||
Query2DMS,
|
||||
Query2DMSArray,
|
||||
QueryDimCount
|
||||
};
|
||||
|
||||
enum TextureQueryVariantType
|
||||
{
|
||||
QueryTypeFloat = 0,
|
||||
QueryTypeInt = 16,
|
||||
QueryTypeUInt = 32,
|
||||
QueryTypeCount = 3
|
||||
};
|
||||
|
||||
enum BitcastType
|
||||
{
|
||||
TypeNormal,
|
||||
TypePackUint2x32,
|
||||
TypeUnpackUint64
|
||||
};
|
||||
|
||||
void analyze_meshlet_writes();
|
||||
void analyze_meshlet_writes(uint32_t func_id, uint32_t id_per_vertex, uint32_t id_per_primitive,
|
||||
std::unordered_set<uint32_t> &processed_func_ids);
|
||||
|
||||
BitcastType get_bitcast_type(uint32_t result_type, uint32_t op0);
|
||||
|
||||
void emit_builtin_variables();
|
||||
bool require_output = false;
|
||||
bool require_input = false;
|
||||
SmallVector<HLSLVertexAttributeRemap> remap_vertex_attributes;
|
||||
|
||||
uint32_t type_to_consumed_locations(const SPIRType &type) const;
|
||||
|
||||
std::string to_semantic(uint32_t location, spv::ExecutionModel em, spv::StorageClass sc);
|
||||
|
||||
uint32_t num_workgroups_builtin = 0;
|
||||
HLSLBindingFlags resource_binding_flags = 0;
|
||||
|
||||
// Custom root constant layout, which should be emitted
|
||||
// when translating push constant ranges.
|
||||
std::vector<RootConstants> root_constants_layout;
|
||||
|
||||
void validate_shader_model();
|
||||
|
||||
std::string get_unique_identifier();
|
||||
uint32_t unique_identifier_count = 0;
|
||||
|
||||
std::unordered_map<StageSetBinding, std::pair<HLSLResourceBinding, bool>, InternalHasher> resource_bindings;
|
||||
void remap_hlsl_resource_binding(HLSLBindingFlagBits type, uint32_t &desc_set, uint32_t &binding);
|
||||
|
||||
std::unordered_set<SetBindingPair, InternalHasher> force_uav_buffer_bindings;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32_t register_index = 0;
|
||||
uint32_t register_space = 0;
|
||||
bool explicit_binding = false;
|
||||
bool used = false;
|
||||
} base_vertex_info;
|
||||
|
||||
// Returns true if the specified ID has a UserTypeGOOGLE decoration for StructuredBuffer or RWStructuredBuffer resources.
|
||||
bool is_user_type_structured(uint32_t id) const override;
|
||||
|
||||
std::vector<TypeID> composite_selection_workaround_types;
|
||||
|
||||
std::string get_inner_entry_point_name() const;
|
||||
};
|
||||
} // namespace SPIRV_CROSS_NAMESPACE
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user