engine: sync editor rendering and ui changes
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include "fixtures/OpenGLTestFixture.h"
|
||||
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLDescriptorSet.h"
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLPipelineState.h"
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLPipelineLayout.h"
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLResourceView.h"
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLSampler.h"
|
||||
@@ -21,6 +22,7 @@
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace XCEngine::RHI;
|
||||
@@ -173,6 +175,128 @@ float4 MainPS(PSInput input) : SV_TARGET {
|
||||
delete pipelineState;
|
||||
}
|
||||
|
||||
TEST_F(OpenGLTestFixture, Device_CreatePipelineState_HlslGraphicsShaders_AssignsCombinedSamplerUniformUnits) {
|
||||
ASSERT_TRUE(GetDevice()->MakeContextCurrent());
|
||||
if (!SupportsOpenGLHlslToolchainForTests()) {
|
||||
GTEST_SKIP() << "glslangValidator.exe or spirv-cross.exe was not found.";
|
||||
}
|
||||
|
||||
static const char* hlslSource = R"(
|
||||
Texture2D BaseColorTexture : register(t0);
|
||||
SamplerState LinearClampSampler : register(s0);
|
||||
Texture2D ShadowMapTexture : register(t1);
|
||||
SamplerState ShadowMapSampler : register(s1);
|
||||
|
||||
struct VSInput {
|
||||
float4 position : POSITION;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct PSInput {
|
||||
float4 position : SV_POSITION;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
PSInput MainVS(VSInput input) {
|
||||
PSInput output;
|
||||
output.position = input.position;
|
||||
output.texcoord = input.texcoord;
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 MainPS(PSInput input) : SV_TARGET {
|
||||
float4 baseColor = BaseColorTexture.Sample(LinearClampSampler, input.texcoord);
|
||||
float shadow = ShadowMapTexture.Sample(ShadowMapSampler, input.texcoord).r;
|
||||
return float4(baseColor.rgb * shadow, baseColor.a);
|
||||
}
|
||||
)";
|
||||
|
||||
GraphicsPipelineDesc pipelineDesc = {};
|
||||
pipelineDesc.topologyType = static_cast<uint32_t>(PrimitiveTopologyType::Triangle);
|
||||
pipelineDesc.renderTargetFormats[0] = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
|
||||
|
||||
InputElementDesc position = {};
|
||||
position.semanticName = "POSITION";
|
||||
position.semanticIndex = 0;
|
||||
position.format = static_cast<uint32_t>(Format::R32G32B32A32_Float);
|
||||
position.inputSlot = 0;
|
||||
position.alignedByteOffset = 0;
|
||||
pipelineDesc.inputLayout.elements.push_back(position);
|
||||
|
||||
InputElementDesc texcoord = {};
|
||||
texcoord.semanticName = "TEXCOORD";
|
||||
texcoord.semanticIndex = 0;
|
||||
texcoord.format = static_cast<uint32_t>(Format::R32G32_Float);
|
||||
texcoord.inputSlot = 0;
|
||||
texcoord.alignedByteOffset = sizeof(float) * 4;
|
||||
pipelineDesc.inputLayout.elements.push_back(texcoord);
|
||||
|
||||
pipelineDesc.vertexShader.source.assign(hlslSource, hlslSource + std::strlen(hlslSource));
|
||||
pipelineDesc.vertexShader.sourceLanguage = ShaderLanguage::HLSL;
|
||||
pipelineDesc.vertexShader.entryPoint = L"MainVS";
|
||||
pipelineDesc.vertexShader.profile = L"vs_5_0";
|
||||
|
||||
pipelineDesc.fragmentShader.source.assign(hlslSource, hlslSource + std::strlen(hlslSource));
|
||||
pipelineDesc.fragmentShader.sourceLanguage = ShaderLanguage::HLSL;
|
||||
pipelineDesc.fragmentShader.entryPoint = L"MainPS";
|
||||
pipelineDesc.fragmentShader.profile = L"ps_5_0";
|
||||
|
||||
RHIPipelineState* pipelineState = GetDevice()->CreatePipelineState(pipelineDesc);
|
||||
ASSERT_NE(pipelineState, nullptr);
|
||||
|
||||
const GLuint program = static_cast<OpenGLPipelineState*>(pipelineState)->GetProgram();
|
||||
ASSERT_NE(program, 0u);
|
||||
|
||||
const GLint baseColorLocation =
|
||||
glGetUniformLocation(program, "SPIRV_Cross_CombinedBaseColorTextureLinearClampSampler");
|
||||
const GLint shadowLocation =
|
||||
glGetUniformLocation(program, "SPIRV_Cross_CombinedShadowMapTextureShadowMapSampler");
|
||||
ASSERT_GE(baseColorLocation, 0);
|
||||
ASSERT_GE(shadowLocation, 0);
|
||||
|
||||
GLint baseColorUnit = -1;
|
||||
GLint shadowUnit = -1;
|
||||
glGetUniformiv(program, baseColorLocation, &baseColorUnit);
|
||||
glGetUniformiv(program, shadowLocation, &shadowUnit);
|
||||
GLint activeUniformCount = 0;
|
||||
glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &activeUniformCount);
|
||||
for (GLint uniformIndex = 0; uniformIndex < activeUniformCount; ++uniformIndex) {
|
||||
GLsizei nameLength = 0;
|
||||
GLint arraySize = 0;
|
||||
GLenum type = 0;
|
||||
char nameBuffer[256] = {};
|
||||
glGetActiveUniform(
|
||||
program,
|
||||
static_cast<GLuint>(uniformIndex),
|
||||
static_cast<GLsizei>(sizeof(nameBuffer)),
|
||||
&nameLength,
|
||||
&arraySize,
|
||||
&type,
|
||||
nameBuffer);
|
||||
if (nameLength <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GLint location = glGetUniformLocation(program, nameBuffer);
|
||||
GLint value = -1;
|
||||
if (location >= 0) {
|
||||
glGetUniformiv(program, location, &value);
|
||||
}
|
||||
|
||||
std::cout << "uniform[" << uniformIndex << "] name=" << nameBuffer
|
||||
<< " location=" << location
|
||||
<< " value=" << value
|
||||
<< " type=" << type
|
||||
<< " arraySize=" << arraySize
|
||||
<< std::endl;
|
||||
}
|
||||
EXPECT_EQ(baseColorUnit, 0);
|
||||
EXPECT_EQ(shadowUnit, 1);
|
||||
|
||||
pipelineState->Shutdown();
|
||||
delete pipelineState;
|
||||
}
|
||||
|
||||
TEST_F(OpenGLTestFixture, CommandList_SetRenderTargets_BindsColorAndDepthAttachments) {
|
||||
TextureDesc colorDesc = {};
|
||||
colorDesc.width = 128;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "fixtures/OpenGLTestFixture.h"
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLCommandList.h"
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLBuffer.h"
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLPipelineState.h"
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLVertexArray.h"
|
||||
|
||||
using namespace XCEngine::RHI;
|
||||
@@ -160,3 +161,30 @@ TEST_F(OpenGLTestFixture, CommandList_SetBlendFactor) {
|
||||
EXPECT_FLOAT_EQ(color[2], 0.5f);
|
||||
EXPECT_FLOAT_EQ(color[3], 1.0f);
|
||||
}
|
||||
|
||||
TEST_F(OpenGLTestFixture, CommandList_SetStencilRef_UpdatesActivePipelineStencilReference) {
|
||||
OpenGLCommandList cmdList;
|
||||
OpenGLPipelineState pipeline;
|
||||
|
||||
DepthStencilStateDesc state = {};
|
||||
state.stencilEnable = true;
|
||||
state.front.func = static_cast<uint32_t>(ComparisonFunc::Equal);
|
||||
state.back.func = static_cast<uint32_t>(ComparisonFunc::NotEqual);
|
||||
pipeline.SetDepthStencilState(state);
|
||||
|
||||
cmdList.SetPipelineState(&pipeline);
|
||||
cmdList.SetStencilRef(5);
|
||||
|
||||
GLint frontRef = 0;
|
||||
GLint backRef = 0;
|
||||
GLint frontFunc = 0;
|
||||
GLint backFunc = 0;
|
||||
glGetIntegerv(GL_STENCIL_REF, &frontRef);
|
||||
glGetIntegerv(GL_STENCIL_BACK_REF, &backRef);
|
||||
glGetIntegerv(GL_STENCIL_FUNC, &frontFunc);
|
||||
glGetIntegerv(GL_STENCIL_BACK_FUNC, &backFunc);
|
||||
EXPECT_EQ(frontRef, 5);
|
||||
EXPECT_EQ(backRef, 5);
|
||||
EXPECT_EQ(frontFunc, GL_EQUAL);
|
||||
EXPECT_EQ(backFunc, GL_NOTEQUAL);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,92 @@ TEST_F(OpenGLTestFixture, PipelineState_SetBlendState) {
|
||||
EXPECT_EQ(blend, 1);
|
||||
}
|
||||
|
||||
TEST_F(OpenGLTestFixture, PipelineState_ApplyDepthStencil_UsesSeparateStencilFaces) {
|
||||
OpenGLPipelineState pipeline;
|
||||
|
||||
DepthStencilStateDesc state = {};
|
||||
state.depthTestEnable = true;
|
||||
state.depthWriteEnable = true;
|
||||
state.depthFunc = static_cast<uint32_t>(ComparisonFunc::LessEqual);
|
||||
state.stencilEnable = true;
|
||||
state.stencilReadMask = 0x3F;
|
||||
state.stencilWriteMask = 0x1F;
|
||||
state.front.func = static_cast<uint32_t>(ComparisonFunc::Equal);
|
||||
state.front.failOp = static_cast<uint32_t>(StencilOp::Replace);
|
||||
state.front.passOp = static_cast<uint32_t>(StencilOp::Incr);
|
||||
state.front.depthFailOp = static_cast<uint32_t>(StencilOp::DecrSat);
|
||||
state.back.func = static_cast<uint32_t>(ComparisonFunc::NotEqual);
|
||||
state.back.failOp = static_cast<uint32_t>(StencilOp::Invert);
|
||||
state.back.passOp = static_cast<uint32_t>(StencilOp::Decr);
|
||||
state.back.depthFailOp = static_cast<uint32_t>(StencilOp::Zero);
|
||||
|
||||
pipeline.SetDepthStencilState(state);
|
||||
pipeline.ApplyDepthStencil();
|
||||
|
||||
EXPECT_TRUE(glIsEnabled(GL_STENCIL_TEST));
|
||||
|
||||
GLint frontFunc = 0;
|
||||
GLint backFunc = 0;
|
||||
GLint frontRef = 0;
|
||||
GLint backRef = 0;
|
||||
GLint frontValueMask = 0;
|
||||
GLint backValueMask = 0;
|
||||
GLint frontWriteMask = 0;
|
||||
GLint backWriteMask = 0;
|
||||
GLint frontFail = 0;
|
||||
GLint backFail = 0;
|
||||
GLint frontPassDepthPass = 0;
|
||||
GLint backPassDepthPass = 0;
|
||||
glGetIntegerv(GL_STENCIL_FUNC, &frontFunc);
|
||||
glGetIntegerv(GL_STENCIL_BACK_FUNC, &backFunc);
|
||||
glGetIntegerv(GL_STENCIL_REF, &frontRef);
|
||||
glGetIntegerv(GL_STENCIL_BACK_REF, &backRef);
|
||||
glGetIntegerv(GL_STENCIL_VALUE_MASK, &frontValueMask);
|
||||
glGetIntegerv(GL_STENCIL_BACK_VALUE_MASK, &backValueMask);
|
||||
glGetIntegerv(GL_STENCIL_WRITEMASK, &frontWriteMask);
|
||||
glGetIntegerv(GL_STENCIL_BACK_WRITEMASK, &backWriteMask);
|
||||
glGetIntegerv(GL_STENCIL_FAIL, &frontFail);
|
||||
glGetIntegerv(GL_STENCIL_BACK_FAIL, &backFail);
|
||||
glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &frontPassDepthPass);
|
||||
glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS, &backPassDepthPass);
|
||||
|
||||
EXPECT_EQ(frontFunc, GL_EQUAL);
|
||||
EXPECT_EQ(backFunc, GL_NOTEQUAL);
|
||||
EXPECT_EQ(frontRef, 0);
|
||||
EXPECT_EQ(backRef, 0);
|
||||
EXPECT_EQ(frontValueMask, 0x3F);
|
||||
EXPECT_EQ(backValueMask, 0x3F);
|
||||
EXPECT_EQ(frontWriteMask, 0x1F);
|
||||
EXPECT_EQ(backWriteMask, 0x1F);
|
||||
EXPECT_EQ(frontFail, GL_REPLACE);
|
||||
EXPECT_EQ(backFail, GL_INVERT);
|
||||
EXPECT_EQ(frontPassDepthPass, GL_INCR_WRAP);
|
||||
EXPECT_EQ(backPassDepthPass, GL_DECR_WRAP);
|
||||
}
|
||||
|
||||
TEST_F(OpenGLTestFixture, PipelineState_ApplyRasterizer_EnablesPolygonOffset) {
|
||||
OpenGLPipelineState pipeline;
|
||||
|
||||
RasterizerDesc state = {};
|
||||
state.fillMode = static_cast<uint32_t>(FillMode::Solid);
|
||||
state.cullMode = static_cast<uint32_t>(CullMode::Back);
|
||||
state.frontFace = static_cast<uint32_t>(FrontFace::CounterClockwise);
|
||||
state.slopeScaledDepthBias = 1.5f;
|
||||
state.depthBias = 3;
|
||||
|
||||
pipeline.SetRasterizerState(state);
|
||||
pipeline.ApplyRasterizer();
|
||||
|
||||
EXPECT_TRUE(glIsEnabled(GL_POLYGON_OFFSET_FILL));
|
||||
|
||||
GLfloat factor = 0.0f;
|
||||
GLfloat units = 0.0f;
|
||||
glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &factor);
|
||||
glGetFloatv(GL_POLYGON_OFFSET_UNITS, &units);
|
||||
EXPECT_FLOAT_EQ(factor, 1.5f);
|
||||
EXPECT_FLOAT_EQ(units, 3.0f);
|
||||
}
|
||||
|
||||
TEST_F(OpenGLTestFixture, PipelineState_SetViewport_SetScissor) {
|
||||
OpenGLPipelineState pipeline;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user