mirror of
https://github.com/RPCS3/glslang.git
synced 2025-02-26 05:47:29 +00:00
Merge branch 'jantlo-cpp11-feat'
This commit is contained in:
commit
6f1e595dbc
@ -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)
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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()
|
||||
{
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user