More work. Things are starting to work now.

This commit is contained in:
Henrik Rydgård 2022-10-22 17:34:23 +02:00
parent c668736924
commit 2e87f0bc0b
9 changed files with 63 additions and 16 deletions

View File

@ -270,6 +270,7 @@ public:
}
void SetDynamicUniformData(const void *data, size_t size) {
_dbg_assert_(size <= uboSize_);
memcpy(ubo_, data, size);
}

View File

@ -207,7 +207,7 @@ void PresentationCommon::CalculatePostShaderUniforms(int bufferWidth, int buffer
uniforms->gl_HalfPixel[0] = u_pixel_delta * 0.5f;
uniforms->gl_HalfPixel[1] = v_pixel_delta * 0.5f;
uniforms->setting[0] = g_Config.mPostShaderSetting[shaderInfo->section + "SettingValue1"];;
uniforms->setting[0] = g_Config.mPostShaderSetting[shaderInfo->section + "SettingValue1"];
uniforms->setting[1] = g_Config.mPostShaderSetting[shaderInfo->section + "SettingValue2"];
uniforms->setting[2] = g_Config.mPostShaderSetting[shaderInfo->section + "SettingValue3"];
uniforms->setting[3] = g_Config.mPostShaderSetting[shaderInfo->section + "SettingValue4"];
@ -235,7 +235,11 @@ bool PresentationCommon::UpdatePostShader() {
bool result = CompilePostShader(stereoShaderInfo, &stereoPipeline_);
if (!result) {
// We won't have a stereo shader. We have to check for this later.
delete stereoShaderInfo_;
stereoShaderInfo_ = nullptr;
stereoPipeline_ = nullptr;
} else {
stereoShaderInfo_ = new ShaderInfo(*stereoShaderInfo);
}
}
@ -544,6 +548,8 @@ void PresentationCommon::DestroyPostShader() {
void PresentationCommon::DestroyStereoShader() {
DoRelease(stereoPipeline_);
delete stereoShaderInfo_;
stereoShaderInfo_ = nullptr;
}
Draw::ShaderModule *PresentationCommon::CompileShaderModule(ShaderStage stage, ShaderLanguage lang, const std::string &src, std::string *errorString) const {
@ -812,6 +818,7 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u
if (!BindSource(0, true)) {
// Fall back
draw_->BindPipeline(texColor_);
useStereo = false; // Otherwise we end up uploading the wrong uniforms
}
} else {
if (isFinalAtOutputResolution && previousFramebuffers_.empty()) {
@ -830,6 +837,9 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u
if (isFinalAtOutputResolution && previousFramebuffers_.empty()) {
CalculatePostShaderUniforms(lastWidth, lastHeight, (int)rc.w, (int)rc.h, &postShaderInfo_.back(), &uniforms);
draw_->UpdateDynamicUniformBuffer(&uniforms, sizeof(uniforms));
} else if (useStereo) {
CalculatePostShaderUniforms(lastWidth, lastHeight, (int)rc.w, (int)rc.h, stereoShaderInfo_, &uniforms);
draw_->UpdateDynamicUniformBuffer(&uniforms, sizeof(uniforms));
} else {
Draw::VsTexColUB ub{};
memcpy(ub.WorldViewProj, g_display_rot_matrix.m, sizeof(float) * 16);

View File

@ -133,10 +133,13 @@ protected:
Draw::Buffer *idata_ = nullptr;
std::vector<Draw::Pipeline *> postShaderPipelines_;
Draw::Pipeline *stereoPipeline_ = nullptr;
std::vector<Draw::Framebuffer *> postShaderFramebuffers_;
std::vector<ShaderInfo> postShaderInfo_;
std::vector<Draw::Framebuffer *> previousFramebuffers_;
Draw::Pipeline *stereoPipeline_ = nullptr;
ShaderInfo *stereoShaderInfo_ = nullptr;
int previousIndex_ = 0;
PostShaderUniforms previousUniforms_{};

View File

@ -92,6 +92,10 @@ void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform,
id.SetBit(VS_BIT_HAS_COLOR, hasColor);
id.SetBit(VS_BIT_VERTEX_RANGE_CULLING, vertexRangeCulling);
if (!isModeThrough && VS_BIT_SIMPLE_STEREO) {
id.SetBit(VS_BIT_SIMPLE_STEREO);
}
if (doTexture) {
id.SetBit(VS_BIT_DO_TEXTURE);

View File

@ -15,7 +15,7 @@ enum VShaderBit : uint8_t {
VS_BIT_HAS_COLOR = 3,
VS_BIT_DO_TEXTURE = 4,
VS_BIT_VERTEX_RANGE_CULLING = 5,
// 6 is free,
VS_BIT_SIMPLE_STEREO = 6,
// 7 is free.
VS_BIT_USE_HW_TRANSFORM = 8,
VS_BIT_HAS_NORMAL = 9, // conditioned on hw transform

View File

@ -136,27 +136,33 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
bool highpFog = false;
bool highpTexcoord = false;
std::vector<const char*> gl_exts;
std::vector<const char*> extensions;
if (ShaderLanguageIsOpenGL(compat.shaderLanguage)) {
if (gl_extensions.EXT_gpu_shader4) {
gl_exts.push_back("#extension GL_EXT_gpu_shader4 : enable");
extensions.push_back("#extension GL_EXT_gpu_shader4 : enable");
}
bool useClamp = gstate_c.Use(GPU_USE_DEPTH_CLAMP) && !id.Bit(VS_BIT_IS_THROUGH);
if (gl_extensions.EXT_clip_cull_distance && (id.Bit(VS_BIT_VERTEX_RANGE_CULLING) || useClamp)) {
gl_exts.push_back("#extension GL_EXT_clip_cull_distance : enable");
extensions.push_back("#extension GL_EXT_clip_cull_distance : enable");
}
if (gl_extensions.APPLE_clip_distance && (id.Bit(VS_BIT_VERTEX_RANGE_CULLING) || useClamp)) {
gl_exts.push_back("#extension GL_APPLE_clip_distance : enable");
extensions.push_back("#extension GL_APPLE_clip_distance : enable");
}
if (gl_extensions.ARB_cull_distance && id.Bit(VS_BIT_VERTEX_RANGE_CULLING)) {
gl_exts.push_back("#extension GL_ARB_cull_distance : enable");
extensions.push_back("#extension GL_ARB_cull_distance : enable");
}
if (gstate_c.Use(GPU_USE_VIRTUAL_REALITY) && gstate_c.Use(GPU_USE_SINGLE_PASS_STEREO)) {
gl_exts.push_back("#extension GL_OVR_multiview2 : enable\nlayout(num_views=2) in;");
extensions.push_back("#extension GL_OVR_multiview2 : enable\nlayout(num_views=2) in;");
}
}
ShaderWriter p(buffer, compat, ShaderStage::Vertex, gl_exts);
bool useSimpleStereo = id.Bit(VS_BIT_SIMPLE_STEREO);
if (compat.shaderLanguage == ShaderLanguage::GLSL_VULKAN && useSimpleStereo) {
extensions.push_back("#extension GL_EXT_multiview : enable");
}
ShaderWriter p(buffer, compat, ShaderStage::Vertex, extensions);
bool isModeThrough = id.Bit(VS_BIT_IS_THROUGH);
bool lmode = id.Bit(VS_BIT_LMODE);
@ -1341,6 +1347,12 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
WRITE(p, " }\n");
}
if (useSimpleStereo) {
p.C(" float zFactor = 0.2 * float(gl_ViewIndex * 2 - 1);\n");
p.C(" float zFocus = 0.0;\n");
p.C(" gl_Position.x += (-gl_Position.z - zFocus) * zFactor;\n");
}
if (needsZWHack) {
// See comment in thin3d_vulkan.cpp.
WRITE(p, " if (%sgl_Position.z == %sgl_Position.w) %sgl_Position.z *= 0.999999;\n",

View File

@ -364,6 +364,19 @@ void GameSettingsScreen::CreateViews() {
screenManager()->push(procScreen);
return UI::EVENT_DONE;
});
const ShaderInfo *shaderInfo = GetPostShaderInfo(g_Config.sStereoToMonoShader);
if (shaderInfo) {
for (size_t i = 0; i < ARRAY_SIZE(shaderInfo->settings); ++i) {
auto &setting = shaderInfo->settings[i];
if (!setting.name.empty()) {
auto &value = g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", shaderInfo->section.c_str(), i + 1)];
PopupSliderChoiceFloat *settingValue = graphicsSettings->Add(new PopupSliderChoiceFloat(&value, setting.minValue, setting.maxValue, ps->T(setting.name), setting.step, screenManager()));
settingValue->SetEnabledFunc([] {
return g_Config.iRenderingMode != FB_NON_BUFFERED_MODE && g_Config.bStereoRendering;
});
}
}
}
}
std::set<std::string> alreadyAddedShader;

View File

@ -193,8 +193,13 @@ Author=Henrik Rydgård
SettingName1=ColorPreservation
SettingDefaultValue1=0.5
SettingMaxValue1=1.0
SettingMinValue1=1.0
SettingMinValue1=0.0
SettingStep1=0.05
SettingName2=GreenLevel
SettingDefaultValue2=0.5
SettingMaxValue2=1.0
SettingMinValue2=0.0
SettingStep2=0.05
Fragment=stereo_red_blue.fsh
Vertex=fxaa.vsh
[SideBySize]

View File

@ -8,13 +8,14 @@ varying vec2 v_texcoord0;
uniform vec4 u_setting;
void main() {
float saturation = u_setting.x;
float greenMix = u_setting.y;
// To be adjusted. Used to desaturate colors.
vec3 grayDot = vec3(0.35, 0.5, 0.15);
// And these are the output color channels.
vec3 red = vec3(1.0, 0.0, 0.0);
vec3 blue = vec3(0.0, 0.0, 1.0);
// We should probably add the ability to tint the blue one between blue and green
// to match whatever glasses the user has. Not sure if there's any win to adjusting red.
vec3 blue = vec3(0.0, greenMix, 1.0);
vec3 left = texture(sampler0, vec3(v_texcoord0, 0.0)).xyz;
vec3 right = texture(sampler0, vec3(v_texcoord0, 1.0)).xyz;
@ -22,8 +23,6 @@ void main() {
float leftGray = dot(left, grayDot);
float rightGray = dot(right, grayDot);
float saturation = u_setting.x;
vec3 leftColor = mix(vec3(leftGray), left, saturation) * red;
vec3 rightColor = mix(vec3(rightGray), right, saturation) * blue;