Merge branch 'jantlo-cpp11-feat'
This commit is contained in:
commit
6f1e595dbc
@ -51,6 +51,8 @@
|
|||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include "../glslang/OSDependent/osinclude.h"
|
#include "../glslang/OSDependent/osinclude.h"
|
||||||
|
|
||||||
@ -150,13 +152,6 @@ void ProcessConfigFile()
|
|||||||
delete[] config;
|
delete[] config;
|
||||||
}
|
}
|
||||||
|
|
||||||
// thread-safe list of shaders to asynchronously grab and compile
|
|
||||||
glslang::TWorklist Worklist;
|
|
||||||
|
|
||||||
// array of unique places to leave the shader names and infologs for the asynchronous compiles
|
|
||||||
glslang::TWorkItem** Work = 0;
|
|
||||||
int NumWorkItems = 0;
|
|
||||||
|
|
||||||
int Options = 0;
|
int Options = 0;
|
||||||
const char* ExecutableName = nullptr;
|
const char* ExecutableName = nullptr;
|
||||||
const char* binaryFileName = nullptr;
|
const char* binaryFileName = nullptr;
|
||||||
@ -253,7 +248,7 @@ void ProcessBindingBase(int& argc, char**& argv, std::array<unsigned int, EShLan
|
|||||||
//
|
//
|
||||||
// Does not return (it exits) if command-line is fatally flawed.
|
// Does not return (it exits) if command-line is fatally flawed.
|
||||||
//
|
//
|
||||||
void ProcessArguments(int argc, char* argv[])
|
void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItems, int argc, char* argv[])
|
||||||
{
|
{
|
||||||
baseSamplerBinding.fill(0);
|
baseSamplerBinding.fill(0);
|
||||||
baseTextureBinding.fill(0);
|
baseTextureBinding.fill(0);
|
||||||
@ -262,10 +257,7 @@ void ProcessArguments(int argc, char* argv[])
|
|||||||
baseSsboBinding.fill(0);
|
baseSsboBinding.fill(0);
|
||||||
|
|
||||||
ExecutableName = argv[0];
|
ExecutableName = argv[0];
|
||||||
NumWorkItems = argc; // will include some empties where the '-' options were, but it doesn't matter, they'll be 0
|
workItems.reserve(argc);
|
||||||
Work = new glslang::TWorkItem*[NumWorkItems];
|
|
||||||
for (int w = 0; w < NumWorkItems; ++w)
|
|
||||||
Work[w] = 0;
|
|
||||||
|
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
@ -420,9 +412,7 @@ void ProcessArguments(int argc, char* argv[])
|
|||||||
Options |= EOptionSuppressInfolog;
|
Options |= EOptionSuppressInfolog;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
#ifdef _WIN32
|
Options |= EOptionMultiThreaded;
|
||||||
Options |= EOptionMultiThreaded;
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
Options |= EOptionDumpVersions;
|
Options |= EOptionDumpVersions;
|
||||||
@ -440,8 +430,7 @@ void ProcessArguments(int argc, char* argv[])
|
|||||||
} else {
|
} else {
|
||||||
std::string name(argv[0]);
|
std::string name(argv[0]);
|
||||||
if (! SetConfigFile(name)) {
|
if (! SetConfigFile(name)) {
|
||||||
Work[argc] = new glslang::TWorkItem(name);
|
workItems.push_back(std::unique_ptr<glslang::TWorkItem>(new glslang::TWorkItem(name)));
|
||||||
Worklist.add(Work[argc]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -487,15 +476,13 @@ void SetMessageOptions(EShMessages& messages)
|
|||||||
//
|
//
|
||||||
// Thread entry point, for non-linking asynchronous mode.
|
// Thread entry point, for non-linking asynchronous mode.
|
||||||
//
|
//
|
||||||
// Return 0 for failure, 1 for success.
|
void CompileShaders(glslang::TWorklist& worklist)
|
||||||
//
|
|
||||||
unsigned int CompileShaders(void*)
|
|
||||||
{
|
{
|
||||||
glslang::TWorkItem* workItem;
|
glslang::TWorkItem* workItem;
|
||||||
while (Worklist.remove(workItem)) {
|
while (worklist.remove(workItem)) {
|
||||||
ShHandle compiler = ShConstructCompiler(FindLanguage(workItem->name), Options);
|
ShHandle compiler = ShConstructCompiler(FindLanguage(workItem->name), Options);
|
||||||
if (compiler == 0)
|
if (compiler == 0)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
CompileFile(workItem->name.c_str(), compiler);
|
CompileFile(workItem->name.c_str(), compiler);
|
||||||
|
|
||||||
@ -504,8 +491,6 @@ unsigned int CompileShaders(void*)
|
|||||||
|
|
||||||
ShDestruct(compiler);
|
ShDestruct(compiler);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Outputs the given string, but only if it is non-null and non-empty.
|
// Outputs the given string, but only if it is non-null and non-empty.
|
||||||
@ -705,7 +690,7 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
|||||||
// performance and memory testing, the actual compile/link can be put in
|
// performance and memory testing, the actual compile/link can be put in
|
||||||
// a loop, independent of processing the work items and file IO.
|
// a loop, independent of processing the work items and file IO.
|
||||||
//
|
//
|
||||||
void CompileAndLinkShaderFiles()
|
void CompileAndLinkShaderFiles(glslang::TWorklist& Worklist)
|
||||||
{
|
{
|
||||||
std::vector<ShaderCompUnit> compUnits;
|
std::vector<ShaderCompUnit> compUnits;
|
||||||
|
|
||||||
@ -747,11 +732,19 @@ void CompileAndLinkShaderFiles()
|
|||||||
|
|
||||||
int C_DECL main(int argc, char* argv[])
|
int C_DECL main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
ProcessArguments(argc, argv);
|
// array of unique places to leave the shader names and infologs for the asynchronous compiles
|
||||||
|
std::vector<std::unique_ptr<glslang::TWorkItem>> workItems;
|
||||||
|
ProcessArguments(workItems, argc, argv);
|
||||||
|
|
||||||
|
glslang::TWorklist workList;
|
||||||
|
std::for_each(workItems.begin(), workItems.end(), [&workList](std::unique_ptr<glslang::TWorkItem>& item) {
|
||||||
|
assert(item);
|
||||||
|
workList.add(item.get());
|
||||||
|
});
|
||||||
|
|
||||||
if (Options & EOptionDumpConfig) {
|
if (Options & EOptionDumpConfig) {
|
||||||
printf("%s", glslang::GetDefaultTBuiltInResourceString().c_str());
|
printf("%s", glslang::GetDefaultTBuiltInResourceString().c_str());
|
||||||
if (Worklist.empty())
|
if (workList.empty())
|
||||||
return ESuccess;
|
return ESuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -766,11 +759,11 @@ int C_DECL main(int argc, char* argv[])
|
|||||||
printf("Khronos Tool ID %d\n", glslang::GetKhronosToolId());
|
printf("Khronos Tool ID %d\n", glslang::GetKhronosToolId());
|
||||||
printf("GL_KHR_vulkan_glsl version %d\n", 100);
|
printf("GL_KHR_vulkan_glsl version %d\n", 100);
|
||||||
printf("ARB_GL_gl_spirv version %d\n", 100);
|
printf("ARB_GL_gl_spirv version %d\n", 100);
|
||||||
if (Worklist.empty())
|
if (workList.empty())
|
||||||
return ESuccess;
|
return ESuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Worklist.empty()) {
|
if (workList.empty()) {
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -784,47 +777,42 @@ int C_DECL main(int argc, char* argv[])
|
|||||||
if (Options & EOptionLinkProgram ||
|
if (Options & EOptionLinkProgram ||
|
||||||
Options & EOptionOutputPreprocessed) {
|
Options & EOptionOutputPreprocessed) {
|
||||||
glslang::InitializeProcess();
|
glslang::InitializeProcess();
|
||||||
CompileAndLinkShaderFiles();
|
CompileAndLinkShaderFiles(workList);
|
||||||
glslang::FinalizeProcess();
|
glslang::FinalizeProcess();
|
||||||
for (int w = 0; w < NumWorkItems; ++w) {
|
|
||||||
if (Work[w]) {
|
|
||||||
delete Work[w];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ShInitialize();
|
ShInitialize();
|
||||||
|
|
||||||
bool printShaderNames = Worklist.size() > 1;
|
bool printShaderNames = workList.size() > 1;
|
||||||
|
|
||||||
if (Options & EOptionMultiThreaded) {
|
if (Options & EOptionMultiThreaded)
|
||||||
const int NumThreads = 16;
|
{
|
||||||
void* threads[NumThreads];
|
std::array<std::thread, 16> threads;
|
||||||
for (int t = 0; t < NumThreads; ++t) {
|
for (unsigned int t = 0; t < threads.size(); ++t)
|
||||||
threads[t] = glslang::OS_CreateThread(&CompileShaders);
|
{
|
||||||
if (! threads[t]) {
|
threads[t] = std::thread(CompileShaders, std::ref(workList));
|
||||||
|
if (threads[t].get_id() == std::thread::id())
|
||||||
|
{
|
||||||
printf("Failed to create thread\n");
|
printf("Failed to create thread\n");
|
||||||
return EFailThreadCreate;
|
return EFailThreadCreate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glslang::OS_WaitForAllThreads(threads, NumThreads);
|
|
||||||
|
std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); });
|
||||||
} else
|
} else
|
||||||
CompileShaders(0);
|
CompileShaders(workList);
|
||||||
|
|
||||||
// Print out all the resulting infologs
|
// Print out all the resulting infologs
|
||||||
for (int w = 0; w < NumWorkItems; ++w) {
|
for (size_t w = 0; w < workItems.size(); ++w) {
|
||||||
if (Work[w]) {
|
if (workItems[w]) {
|
||||||
if (printShaderNames || Work[w]->results.size() > 0)
|
if (printShaderNames || workItems[w]->results.size() > 0)
|
||||||
PutsIfNonEmpty(Work[w]->name.c_str());
|
PutsIfNonEmpty(workItems[w]->name.c_str());
|
||||||
PutsIfNonEmpty(Work[w]->results.c_str());
|
PutsIfNonEmpty(workItems[w]->results.c_str());
|
||||||
delete Work[w];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ShFinalize();
|
ShFinalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] Work;
|
|
||||||
|
|
||||||
if (CompileFailed)
|
if (CompileFailed)
|
||||||
return EFailCompile;
|
return EFailCompile;
|
||||||
if (LinkFailed)
|
if (LinkFailed)
|
||||||
|
|||||||
@ -36,8 +36,9 @@
|
|||||||
#define WORKLIST_H_INCLUDED
|
#define WORKLIST_H_INCLUDED
|
||||||
|
|
||||||
#include "../glslang/OSDependent/osinclude.h"
|
#include "../glslang/OSDependent/osinclude.h"
|
||||||
#include <string>
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
@ -58,24 +59,19 @@ namespace glslang {
|
|||||||
|
|
||||||
void add(TWorkItem* item)
|
void add(TWorkItem* item)
|
||||||
{
|
{
|
||||||
GetGlobalLock();
|
std::lock_guard<std::mutex> guard(mutex);
|
||||||
|
|
||||||
worklist.push_back(item);
|
worklist.push_back(item);
|
||||||
|
|
||||||
ReleaseGlobalLock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool remove(TWorkItem*& item)
|
bool remove(TWorkItem*& item)
|
||||||
{
|
{
|
||||||
GetGlobalLock();
|
std::lock_guard<std::mutex> guard(mutex);
|
||||||
|
|
||||||
if (worklist.empty())
|
if (worklist.empty())
|
||||||
return false;
|
return false;
|
||||||
item = worklist.front();
|
item = worklist.front();
|
||||||
worklist.pop_front();
|
worklist.pop_front();
|
||||||
|
|
||||||
ReleaseGlobalLock();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,6 +86,7 @@ namespace glslang {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
std::mutex mutex;
|
||||||
std::list<TWorkItem*> worklist;
|
std::list<TWorkItem*> worklist;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -184,20 +184,6 @@ void ReleaseGlobalLock()
|
|||||||
pthread_mutex_unlock(&gMutex);
|
pthread_mutex_unlock(&gMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: non-windows: if we need these on linux, flesh them out
|
|
||||||
void* OS_CreateThread(TThreadEntrypoint /*entry*/)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_WaitForAllThreads(void* /*threads*/, int /*numThreads*/)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_Sleep(int /*milliseconds*/)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_DumpMemoryCounters()
|
void OS_DumpMemoryCounters()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@ -131,21 +131,6 @@ unsigned int __stdcall EnterGenericThread (void* entry)
|
|||||||
return ((TThreadEntrypoint)entry)(0);
|
return ((TThreadEntrypoint)entry)(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* OS_CreateThread(TThreadEntrypoint entry)
|
|
||||||
{
|
|
||||||
return (void*)_beginthreadex(0, 0, EnterGenericThread, (void*)entry, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_WaitForAllThreads(void* threads, int numThreads)
|
|
||||||
{
|
|
||||||
WaitForMultipleObjects(numThreads, (HANDLE*)threads, true, INFINITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_Sleep(int milliseconds)
|
|
||||||
{
|
|
||||||
Sleep(milliseconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
//#define DUMP_COUNTERS
|
//#define DUMP_COUNTERS
|
||||||
|
|
||||||
void OS_DumpMemoryCounters()
|
void OS_DumpMemoryCounters()
|
||||||
|
|||||||
@ -53,11 +53,8 @@ void GetGlobalLock();
|
|||||||
void ReleaseGlobalLock();
|
void ReleaseGlobalLock();
|
||||||
|
|
||||||
typedef unsigned int (*TThreadEntrypoint)(void*);
|
typedef unsigned int (*TThreadEntrypoint)(void*);
|
||||||
void* OS_CreateThread(TThreadEntrypoint);
|
|
||||||
void OS_WaitForAllThreads(void* threads, int numThreads);
|
|
||||||
|
|
||||||
void OS_CleanupThreadData(void);
|
void OS_CleanupThreadData(void);
|
||||||
void OS_Sleep(int milliseconds);
|
|
||||||
|
|
||||||
void OS_DumpMemoryCounters();
|
void OS_DumpMemoryCounters();
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user