Fix OpenGL shader temp file collisions
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#include "XCEngine/RHI/RHIShader.h"
|
||||
#include "XCEngine/RHI/RHISampler.h"
|
||||
#include "XCEngine/RHI/RHISwapChain.h"
|
||||
#include "XCEngine/RHI/ShaderCompiler/SpirvShaderCompiler.h"
|
||||
#include "XCEngine/RHI/RHITexture.h"
|
||||
|
||||
#include <cstdint>
|
||||
@@ -23,6 +24,9 @@
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
using namespace XCEngine::RHI;
|
||||
@@ -118,6 +122,87 @@ VSOutput MainVS(VSInput input) {
|
||||
delete shader;
|
||||
}
|
||||
|
||||
TEST(OpenGLShaderCompiler_Test, ParallelSpirvToolInvocationsDoNotCollideOnTemporaryFiles) {
|
||||
if (!SupportsOpenGLHlslToolchainForTests()) {
|
||||
GTEST_SKIP() << "glslangValidator.exe or spirv-cross.exe was not found.";
|
||||
}
|
||||
|
||||
static const char* vertexSource = R"(
|
||||
struct VSInput {
|
||||
float4 position : POSITION;
|
||||
};
|
||||
|
||||
struct VSOutput {
|
||||
float4 position : SV_POSITION;
|
||||
};
|
||||
|
||||
VSOutput MainVS(VSInput input) {
|
||||
VSOutput output;
|
||||
output.position = input.position;
|
||||
return output;
|
||||
}
|
||||
)";
|
||||
|
||||
ShaderCompileDesc shaderDesc = {};
|
||||
shaderDesc.source.assign(vertexSource, vertexSource + std::strlen(vertexSource));
|
||||
shaderDesc.sourceLanguage = ShaderLanguage::HLSL;
|
||||
shaderDesc.entryPoint = L"MainVS";
|
||||
shaderDesc.profile = L"vs_5_0";
|
||||
|
||||
constexpr int kWorkerCount = 4;
|
||||
constexpr int kIterationsPerWorker = 4;
|
||||
|
||||
std::mutex failureMutex;
|
||||
std::vector<std::string> failures;
|
||||
std::vector<std::thread> workers;
|
||||
workers.reserve(kWorkerCount);
|
||||
|
||||
for (int workerIndex = 0; workerIndex < kWorkerCount; ++workerIndex) {
|
||||
workers.emplace_back([&, workerIndex]() {
|
||||
for (int iteration = 0; iteration < kIterationsPerWorker; ++iteration) {
|
||||
CompiledSpirvShader compiledShader = {};
|
||||
std::string errorMessage;
|
||||
if (!CompileSpirvShader(
|
||||
shaderDesc,
|
||||
SpirvTargetEnvironment::Vulkan,
|
||||
compiledShader,
|
||||
&errorMessage)) {
|
||||
std::lock_guard<std::mutex> lock(failureMutex);
|
||||
failures.push_back(
|
||||
"CompileSpirvShader failed for worker " +
|
||||
std::to_string(workerIndex) +
|
||||
", iteration " +
|
||||
std::to_string(iteration) +
|
||||
": " +
|
||||
errorMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string glslSource;
|
||||
errorMessage.clear();
|
||||
if (!TranspileSpirvToOpenGLGLSL(compiledShader, glslSource, &errorMessage) ||
|
||||
glslSource.empty()) {
|
||||
std::lock_guard<std::mutex> lock(failureMutex);
|
||||
failures.push_back(
|
||||
"TranspileSpirvToOpenGLGLSL failed for worker " +
|
||||
std::to_string(workerIndex) +
|
||||
", iteration " +
|
||||
std::to_string(iteration) +
|
||||
": " +
|
||||
errorMessage);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (std::thread& worker : workers) {
|
||||
worker.join();
|
||||
}
|
||||
|
||||
ASSERT_TRUE(failures.empty()) << failures.front();
|
||||
}
|
||||
|
||||
TEST_F(OpenGLTestFixture, Device_CreatePipelineState_HlslGraphicsShaders_UsesTranspiledHlslPath) {
|
||||
ASSERT_TRUE(GetDevice()->MakeContextCurrent());
|
||||
if (!SupportsOpenGLHlslToolchainForTests()) {
|
||||
|
||||
Reference in New Issue
Block a user