Merge branch 'jantlo-cpp11-feat'

This commit is contained in:
John Kessenich 2017-04-04 15:37:45 -06:00
commit 6f1e595dbc
5 changed files with 45 additions and 92 deletions

View File

@ -51,6 +51,8 @@
#include <cctype>
#include <cmath>
#include <array>
#include <memory>
#include <thread>
#include "../glslang/OSDependent/osinclude.h"
@ -150,13 +152,6 @@ void ProcessConfigFile()
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;
const char* ExecutableName = 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.
//
void ProcessArguments(int argc, char* argv[])
void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItems, int argc, char* argv[])
{
baseSamplerBinding.fill(0);
baseTextureBinding.fill(0);
@ -262,10 +257,7 @@ void ProcessArguments(int argc, char* argv[])
baseSsboBinding.fill(0);
ExecutableName = argv[0];
NumWorkItems = argc; // will include some empties where the '-' options were, but it doesn't matter, they'll be 0
Work = new glslang::TWorkItem*[NumWorkItems];
for (int w = 0; w < NumWorkItems; ++w)
Work[w] = 0;
workItems.reserve(argc);
argc--;
argv++;
@ -420,9 +412,7 @@ void ProcessArguments(int argc, char* argv[])
Options |= EOptionSuppressInfolog;
break;
case 't':
#ifdef _WIN32
Options |= EOptionMultiThreaded;
#endif
Options |= EOptionMultiThreaded;
break;
case 'v':
Options |= EOptionDumpVersions;
@ -440,8 +430,7 @@ void ProcessArguments(int argc, char* argv[])
} else {
std::string name(argv[0]);
if (! SetConfigFile(name)) {
Work[argc] = new glslang::TWorkItem(name);
Worklist.add(Work[argc]);
workItems.push_back(std::unique_ptr<glslang::TWorkItem>(new glslang::TWorkItem(name)));
}
}
}
@ -487,15 +476,13 @@ void SetMessageOptions(EShMessages& messages)
//
// Thread entry point, for non-linking asynchronous mode.
//
// Return 0 for failure, 1 for success.
//
unsigned int CompileShaders(void*)
void CompileShaders(glslang::TWorklist& worklist)
{
glslang::TWorkItem* workItem;
while (Worklist.remove(workItem)) {
while (worklist.remove(workItem)) {
ShHandle compiler = ShConstructCompiler(FindLanguage(workItem->name), Options);
if (compiler == 0)
return 0;
return;
CompileFile(workItem->name.c_str(), compiler);
@ -504,8 +491,6 @@ unsigned int CompileShaders(void*)
ShDestruct(compiler);
}
return 0;
}
// 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
// a loop, independent of processing the work items and file IO.
//
void CompileAndLinkShaderFiles()
void CompileAndLinkShaderFiles(glslang::TWorklist& Worklist)
{
std::vector<ShaderCompUnit> compUnits;
@ -747,11 +732,19 @@ void CompileAndLinkShaderFiles()
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) {
printf("%s", glslang::GetDefaultTBuiltInResourceString().c_str());
if (Worklist.empty())
if (workList.empty())
return ESuccess;
}
@ -766,11 +759,11 @@ int C_DECL main(int argc, char* argv[])
printf("Khronos Tool ID %d\n", glslang::GetKhronosToolId());
printf("GL_KHR_vulkan_glsl version %d\n", 100);
printf("ARB_GL_gl_spirv version %d\n", 100);
if (Worklist.empty())
if (workList.empty())
return ESuccess;
}
if (Worklist.empty()) {
if (workList.empty()) {
usage();
}
@ -784,47 +777,42 @@ int C_DECL main(int argc, char* argv[])
if (Options & EOptionLinkProgram ||
Options & EOptionOutputPreprocessed) {
glslang::InitializeProcess();
CompileAndLinkShaderFiles();
CompileAndLinkShaderFiles(workList);
glslang::FinalizeProcess();
for (int w = 0; w < NumWorkItems; ++w) {
if (Work[w]) {
delete Work[w];
}
}
} else {
ShInitialize();
bool printShaderNames = Worklist.size() > 1;
bool printShaderNames = workList.size() > 1;
if (Options & EOptionMultiThreaded) {
const int NumThreads = 16;
void* threads[NumThreads];
for (int t = 0; t < NumThreads; ++t) {
threads[t] = glslang::OS_CreateThread(&CompileShaders);
if (! threads[t]) {
if (Options & EOptionMultiThreaded)
{
std::array<std::thread, 16> threads;
for (unsigned int t = 0; t < threads.size(); ++t)
{
threads[t] = std::thread(CompileShaders, std::ref(workList));
if (threads[t].get_id() == std::thread::id())
{
printf("Failed to create thread\n");
return EFailThreadCreate;
}
}
glslang::OS_WaitForAllThreads(threads, NumThreads);
std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); });
} else
CompileShaders(0);
CompileShaders(workList);
// Print out all the resulting infologs
for (int w = 0; w < NumWorkItems; ++w) {
if (Work[w]) {
if (printShaderNames || Work[w]->results.size() > 0)
PutsIfNonEmpty(Work[w]->name.c_str());
PutsIfNonEmpty(Work[w]->results.c_str());
delete Work[w];
for (size_t w = 0; w < workItems.size(); ++w) {
if (workItems[w]) {
if (printShaderNames || workItems[w]->results.size() > 0)
PutsIfNonEmpty(workItems[w]->name.c_str());
PutsIfNonEmpty(workItems[w]->results.c_str());
}
}
ShFinalize();
}
delete[] Work;
if (CompileFailed)
return EFailCompile;
if (LinkFailed)

View File

@ -36,8 +36,9 @@
#define WORKLIST_H_INCLUDED
#include "../glslang/OSDependent/osinclude.h"
#include <string>
#include <list>
#include <mutex>
#include <string>
namespace glslang {
@ -58,24 +59,19 @@ namespace glslang {
void add(TWorkItem* item)
{
GetGlobalLock();
std::lock_guard<std::mutex> guard(mutex);
worklist.push_back(item);
ReleaseGlobalLock();
}
bool remove(TWorkItem*& item)
{
GetGlobalLock();
std::lock_guard<std::mutex> guard(mutex);
if (worklist.empty())
return false;
item = worklist.front();
worklist.pop_front();
ReleaseGlobalLock();
return true;
}
@ -90,6 +86,7 @@ namespace glslang {
}
protected:
std::mutex mutex;
std::list<TWorkItem*> worklist;
};

View File

@ -184,20 +184,6 @@ void ReleaseGlobalLock()
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()
{
}

View File

@ -131,21 +131,6 @@ unsigned int __stdcall EnterGenericThread (void* entry)
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
void OS_DumpMemoryCounters()

View File

@ -53,11 +53,8 @@ void GetGlobalLock();
void ReleaseGlobalLock();
typedef unsigned int (*TThreadEntrypoint)(void*);
void* OS_CreateThread(TThreadEntrypoint);
void OS_WaitForAllThreads(void* threads, int numThreads);
void OS_CleanupThreadData(void);
void OS_Sleep(int milliseconds);
void OS_DumpMemoryCounters();