1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-02 09:03:37 +00:00

Re-implement slower N64 depth compare synchronization method,

which requires only core OpenGL 4.2 without shader_interlock extensions.

Fixed N64 depth compare with older AMD GPU.
This commit is contained in:
Sergey Lipskiy 2020-02-09 13:02:55 +07:00
parent 3d93752b61
commit 0692abea4a
18 changed files with 165 additions and 112 deletions

View File

@ -63,7 +63,7 @@ void Config::resetToDefaults()
frameBufferEmulation.copyFromRDRAM = 0;
frameBufferEmulation.copyAuxToRDRAM = 0;
frameBufferEmulation.copyToRDRAM = ctDoubleBuffer;
frameBufferEmulation.N64DepthCompare = 0;
frameBufferEmulation.N64DepthCompare = dcDisable;
frameBufferEmulation.forceDepthBufferClear = 0;
frameBufferEmulation.aspect = a43;
frameBufferEmulation.bufferSwapMode = bsOnVerticalInterrupt;
@ -140,7 +140,7 @@ bool isHWLightingAllowed()
void Config::validate()
{
if (frameBufferEmulation.enable != 0 && frameBufferEmulation.N64DepthCompare != 0)
if (frameBufferEmulation.enable != 0 && frameBufferEmulation.N64DepthCompare != dcDisable)
video.multisampling = 0;
if (frameBufferEmulation.nativeResFactor == 1) {
graphics2D.enableNativeResTexrects = 0;

View File

@ -107,6 +107,12 @@ struct Config
cdSoftwareRender = 2
};
enum N64DepthCompareMode {
dcDisable = 0,
dcFast,
dcCompatible
};
struct {
u32 enable;
u32 aspect; // 0: stretch ; 1: 4/3 ; 2: 16/9; 3: adjust

View File

@ -98,7 +98,7 @@ void DepthBuffer::_initDepthImageTexture(FrameBuffer * _pBuffer, CachedTexture&
void DepthBuffer::initDepthImageTexture(FrameBuffer * _pBuffer)
{
if (config.frameBufferEmulation.N64DepthCompare == 0 || m_pDepthImageZTexture != nullptr)
if (config.frameBufferEmulation.N64DepthCompare == Config::dcDisable || m_pDepthImageZTexture != nullptr)
return;
m_pDepthImageZTexture = textureCache().addFrameBufferTexture(textureTarget::TEXTURE_2D);
@ -491,7 +491,7 @@ void DepthBufferList::clearBuffer()
if (m_pCurrent != nullptr)
m_pCurrent->m_cleared = true;
if (config.frameBufferEmulation.enable == 0 || config.frameBufferEmulation.N64DepthCompare == 0) {
if (config.frameBufferEmulation.enable == 0 || config.frameBufferEmulation.N64DepthCompare == Config::dcDisable) {
gfxContext.clearDepthBuffer();
return;
}

View File

@ -943,7 +943,7 @@ void FrameBufferList::attachDepthBuffer()
if (goodDepthBufferTexture) {
pCurrent->m_pDepthBuffer = pDepthBuffer;
pDepthBuffer->setDepthAttachment(pCurrent->m_FBO, bufferTarget::DRAW_FRAMEBUFFER);
if (config.frameBufferEmulation.N64DepthCompare != 0)
if (config.frameBufferEmulation.N64DepthCompare != Config::dcDisable)
pDepthBuffer->bindDepthImageTexture(pCurrent->m_FBO);
} else
pCurrent->m_pDepthBuffer = nullptr;

View File

@ -203,8 +203,7 @@ void ConfigDialog::_init(bool reInit, bool blockCustomSettings)
ui->copyDepthBufferComboBox->setCurrentIndex(config.frameBufferEmulation.copyDepthToRDRAM);
ui->RenderFBCheckBox->setChecked(config.frameBufferEmulation.copyFromRDRAM != 0);
ui->copyDepthToMainDepthBufferCheckBox->setChecked(config.frameBufferEmulation.copyDepthToMainDepthBuffer != 0);
ui->n64DepthCompareCheckBox->toggle();
ui->n64DepthCompareCheckBox->setChecked(config.frameBufferEmulation.N64DepthCompare != 0);
ui->n64DepthCompareComboBox->setCurrentIndex(config.frameBufferEmulation.N64DepthCompare);
ui->forceDepthBufferClearCheckBox->setChecked(config.frameBufferEmulation.forceDepthBufferClear != 0);
if (config.video.fxaa != 0)
@ -430,9 +429,9 @@ void ConfigDialog::accept(bool justSave) {
getFullscreenRefreshRate(ui->fullScreenRefreshRateComboBox->currentIndex(), config.video.fullscreenRefresh);
config.video.fxaa = ui->fxaaRadioButton->isChecked() ? 1 : 0;
config.video.multisampling =
config.video.multisampling =
(ui->fxaaRadioButton->isChecked()
|| ui->n64DepthCompareCheckBox->isChecked()
|| ui->n64DepthCompareComboBox->currentIndex() != 0
|| ui->noaaRadioButton->isChecked()
) ? 0
: pow2(ui->aliasingSlider->value());
@ -476,7 +475,7 @@ void ConfigDialog::accept(bool justSave) {
config.graphics2D.correctTexrectCoords = Config::tcSmart;
else if (ui->fixTexrectForceRadioButton->isChecked())
config.graphics2D.correctTexrectCoords = Config::tcForce;
if (ui->bgModeOnePieceRadioButton->isChecked())
config.graphics2D.bgMode = Config::BGMode::bgOnePiece;
else if (ui->bgModeStrippedRadioButton->isChecked())
@ -493,7 +492,7 @@ void ConfigDialog::accept(bool justSave) {
config.frameBufferEmulation.copyFromRDRAM = ui->RenderFBCheckBox->isChecked() ? 1 : 0;
config.frameBufferEmulation.copyDepthToMainDepthBuffer = ui->copyDepthToMainDepthBufferCheckBox->isChecked() ? 1 : 0;
config.frameBufferEmulation.N64DepthCompare = ui->n64DepthCompareCheckBox->isChecked() ? 1 : 0;
config.frameBufferEmulation.N64DepthCompare = ui->n64DepthCompareComboBox->currentIndex();
config.frameBufferEmulation.forceDepthBufferClear = ui->forceDepthBufferClearCheckBox->isChecked() ? 1 : 0;
if (ui->aspectComboBox->currentIndex() == 2)
@ -760,7 +759,7 @@ void ConfigDialog::on_aliasingWarningLabel_linkActivated(QString link)
{
if (link == "#n64DepthCompare") {
ui->tabWidget->setCurrentIndex(2);
ui->n64DepthCompareCheckBox->setStyleSheet("background:yellow");
ui->n64DepthCompareComboBox->setStyleSheet("background:yellow");
}
}
@ -810,7 +809,7 @@ void ConfigDialog::on_n64DepthCompareCheckBox_toggled(bool checked)
{
if (checked && ui->msaaRadioButton->isChecked())
ui->fxaaRadioButton->setChecked(true);
ui->n64DepthCompareCheckBox->setStyleSheet("");
ui->n64DepthCompareComboBox->setStyleSheet("");
}
void ConfigDialog::on_gammaLevelSpinBox_valueChanged(double /*value*/)
@ -887,7 +886,7 @@ void ConfigDialog::on_tabWidget_currentChanged(int tab)
m_fontsInited = true;
}
ui->n64DepthCompareCheckBox->setStyleSheet("");
ui->n64DepthCompareComboBox->setStyleSheet("");
ui->frameBufferCheckBox->setStyleSheet("");
}
@ -982,3 +981,10 @@ void ConfigDialog::on_nativeRes2DComboBox_currentIndexChanged(int index)
{
ui->fixTexrectFrame->setEnabled(index == 0);
}
void ConfigDialog::on_n64DepthCompareComboBox_currentIndexChanged(int index)
{
ui->aliasingWarningFrame->setVisible(index > 0);
ui->aliasingSliderFrame->setDisabled(index > 0);
ui->msaaRadioButton->setDisabled(index > 0);
}

View File

@ -76,7 +76,9 @@ private slots:
void on_removeProfilePushButton_clicked();
void on_nativeRes2DComboBox_currentIndexChanged(int index);
void on_nativeRes2DComboBox_currentIndexChanged(int index);
void on_n64DepthCompareComboBox_currentIndexChanged(int index);
private:
void _init(bool reInit = false, bool blockCustomSettings = false);

View File

@ -10,7 +10,7 @@
<x>0</x>
<y>0</y>
<width>559</width>
<height>685</height>
<height>595</height>
</rect>
</property>
<property name="windowTitle">
@ -2059,14 +2059,40 @@
<number>4</number>
</property>
<item>
<widget class="QCheckBox" name="n64DepthCompareCheckBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The N64 uses a unique method of calculating depth to the camera. When checked, GlideN64 uses shaders to try to emulate these calculations correctly. Not compatible with anti-aliasing. &lt;span style=&quot; font-weight:600;&quot;&gt;Experimental!&lt;/span&gt;&lt;/p&gt;&lt;p&gt;[Recommended: &lt;span style=&quot; font-style:italic;&quot;&gt;Sometimes checked, for a few games&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Enable N64-style depth compare (experimental, disables MSAA)</string>
</property>
</widget>
<layout class="QHBoxLayout" name="n64DepthCompareHorizontalLayout">
<item>
<widget class="QLabel" name="n64DepthCompareLabel">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The N64 uses a unique method of calculating depth to the camera. When enabled, GlideN64 uses shaders to try to emulate these calculations correctly. Not compatible with anti-aliasing. &lt;span style=&quot; font-weight:600;&quot;&gt;Experimental!&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Fast mode requires OpenGL 4.2 and &amp;quot;fragment shader interlock&amp;quot; extensions.&lt;/p&gt;&lt;p&gt;Compatible mode requires only core OpenGL 4.2 &lt;span style=&quot; font-weight:600;&quot;&gt;Can be slow!&lt;/span&gt;&lt;/p&gt;&lt;p&gt;[Recommended: &lt;span style=&quot; font-style:italic;&quot;&gt;Sometimes checked, for several games&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>N64-style depth compare (experimental, disables MSAA)</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="n64DepthCompareComboBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The N64 uses a unique method of calculating depth to the camera. When enabled, GlideN64 uses shaders to try to emulate these calculations correctly. Not compatible with anti-aliasing. &lt;span style=&quot; font-weight:600;&quot;&gt;Experimental!&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Fast mode requires OpenGL 4.2 and &amp;quot;fragment shader interlock&amp;quot; extensions.&lt;/p&gt;&lt;p&gt;Compatible mode requires only core OpenGL 4.2 &lt;span style=&quot; font-weight:600;&quot;&gt;Can be slow!&lt;/span&gt;&lt;/p&gt;&lt;p&gt;[Recommended: &lt;span style=&quot; font-style:italic;&quot;&gt;Sometimes checked, for several games&lt;/span&gt;]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<item>
<property name="text">
<string>Disable</string>
</property>
</item>
<item>
<property name="text">
<string>Fast</string>
</property>
</item>
<item>
<property name="text">
<string>Compatible</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="forceDepthBufferClearCheckBox">
@ -3792,22 +3818,6 @@
</hint>
</hints>
</connection>
<connection>
<sender>n64DepthCompareCheckBox</sender>
<signal>toggled(bool)</signal>
<receiver>aliasingWarningFrame</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>106</x>
<y>396</y>
</hint>
<hint type="destinationlabel">
<x>524</x>
<y>199</y>
</hint>
</hints>
</connection>
<connection>
<sender>fbInfoEnableCheckBox</sender>
<signal>toggled(bool)</signal>
@ -3856,38 +3866,6 @@
</hint>
</hints>
</connection>
<connection>
<sender>n64DepthCompareCheckBox</sender>
<signal>toggled(bool)</signal>
<receiver>aliasingSliderFrame</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>123</x>
<y>396</y>
</hint>
<hint type="destinationlabel">
<x>420</x>
<y>147</y>
</hint>
</hints>
</connection>
<connection>
<sender>n64DepthCompareCheckBox</sender>
<signal>toggled(bool)</signal>
<receiver>msaaRadioButton</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>123</x>
<y>396</y>
</hint>
<hint type="destinationlabel">
<x>420</x>
<y>113</y>
</hint>
</hints>
</connection>
<connection>
<sender>textureDumpCheckBox</sender>
<signal>toggled(bool)</signal>

View File

@ -14,7 +14,8 @@ namespace graphics {
vecOptions.push_back(config.generalEmulation.enableHWLighting);
vecOptions.push_back(config.generalEmulation.enableNoise);
vecOptions.push_back(config.generalEmulation.enableLOD);
vecOptions.push_back(config.frameBufferEmulation.N64DepthCompare);
vecOptions.push_back(config.frameBufferEmulation.N64DepthCompare == Config::dcFast ? 1 : 0);
vecOptions.push_back(config.frameBufferEmulation.N64DepthCompare == Config::dcCompatible ? 1 : 0);
vecOptions.push_back(config.generalEmulation.enableLegacyBlending);
vecOptions.push_back(config.generalEmulation.enableFragmentDepthWrite);
u32 optionsSet = 0;

View File

@ -463,7 +463,7 @@ public:
ss << "#version " << Utils::to_string(_glinfo.majorVersion) << Utils::to_string(_glinfo.minorVersion) << "0 es " << std::endl;
if (_glinfo.noPerspective)
ss << "#extension GL_NV_shader_noperspective_interpolation : enable" << std::endl;
if (config.frameBufferEmulation.N64DepthCompare != 0) {
if (config.frameBufferEmulation.N64DepthCompare == Config::dcFast) {
if (_glinfo.imageTextures && _glinfo.fragment_interlockNV) {
ss << "#extension GL_NV_fragment_shader_interlock : enable" << std::endl
<< "layout(pixel_interlock_ordered) in;" << std::endl;
@ -477,7 +477,7 @@ public:
} else {
std::stringstream ss;
ss << "#version " << Utils::to_string(_glinfo.majorVersion) << Utils::to_string(_glinfo.minorVersion) << "0 core " << std::endl;
if (config.frameBufferEmulation.N64DepthCompare != 0) {
if (config.frameBufferEmulation.N64DepthCompare != Config::dcDisable) {
if (_glinfo.imageTextures) {
if (_glinfo.majorVersion * 10 + _glinfo.minorVersion < 42) {
ss << "#extension GL_ARB_shader_image_load_store : enable" << std::endl
@ -760,7 +760,7 @@ public:
"uniform lowp int uRenderTarget; \n"
"uniform mediump vec2 uDepthScale; \n"
;
if (config.frameBufferEmulation.N64DepthCompare != 0) {
if (config.frameBufferEmulation.N64DepthCompare != Config::dcDisable) {
m_part +=
"uniform lowp int uEnableDepthCompare; \n"
;
@ -787,7 +787,7 @@ public:
"IN lowp float vNumLights; \n"
;
if (config.frameBufferEmulation.N64DepthCompare != 0 && _glinfo.ext_fetch) {
if (config.frameBufferEmulation.N64DepthCompare == Config::dcFast && _glinfo.ext_fetch) {
m_part +=
"layout(location = 0) OUT lowp vec4 fragColor; \n"
"layout(location = 1) inout highp vec4 depthZ; \n"
@ -847,7 +847,7 @@ public:
"uniform lowp int uRenderTarget; \n"
"uniform mediump vec2 uDepthScale; \n"
;
if (config.frameBufferEmulation.N64DepthCompare != 0) {
if (config.frameBufferEmulation.N64DepthCompare != Config::dcDisable) {
m_part +=
"uniform lowp int uEnableDepthCompare; \n"
;
@ -863,7 +863,7 @@ public:
"IN lowp float vNumLights; \n"
;
if (config.frameBufferEmulation.N64DepthCompare != 0 && _glinfo.ext_fetch) {
if (config.frameBufferEmulation.N64DepthCompare == Config::dcFast && _glinfo.ext_fetch) {
m_part +=
"layout(location = 0) OUT lowp vec4 fragColor; \n"
"layout(location = 1) inout highp vec4 depthZ; \n"
@ -985,7 +985,7 @@ class ShaderFragmentHeaderDepthCompare : public ShaderPart
public:
ShaderFragmentHeaderDepthCompare(const opengl::GLInfo & _glinfo)
{
if (config.frameBufferEmulation.N64DepthCompare != 0) {
if (config.frameBufferEmulation.N64DepthCompare != Config::dcDisable) {
m_part =
"bool depth_compare(highp float curZ); \n"
"bool depth_render(highp float Z, highp float curZ); \n"
@ -1474,7 +1474,7 @@ class ShaderFragmentCallN64Depth : public ShaderPart
public:
ShaderFragmentCallN64Depth(const opengl::GLInfo & _glinfo)
{
if (config.frameBufferEmulation.N64DepthCompare != 0) {
if (config.frameBufferEmulation.N64DepthCompare != Config::dcDisable) {
m_part = " bool should_discard = false; \n";
if (_glinfo.imageTextures) {
@ -1615,7 +1615,7 @@ public:
{
if (!_glinfo.isGLES2) {
if (config.generalEmulation.enableFragmentDepthWrite == 0 &&
config.frameBufferEmulation.N64DepthCompare == 0) {
config.frameBufferEmulation.N64DepthCompare == Config::dcDisable) {
// Dummy write depth
m_part =
"highp float writeDepth() \n"
@ -2098,7 +2098,7 @@ class ShaderN64DepthCompare : public ShaderPart
public:
ShaderN64DepthCompare(const opengl::GLInfo & _glinfo)
{
if (config.frameBufferEmulation.N64DepthCompare != 0) {
if (config.frameBufferEmulation.N64DepthCompare != Config::dcDisable) {
m_part =
"uniform lowp int uEnableDepth; \n"
"uniform lowp int uDepthMode; \n"
@ -2171,7 +2171,7 @@ class ShaderN64DepthRender : public ShaderPart
public:
ShaderN64DepthRender(const opengl::GLInfo & _glinfo)
{
if (config.frameBufferEmulation.N64DepthCompare != 0) {
if (config.frameBufferEmulation.N64DepthCompare != Config::dcDisable) {
m_part =
"bool depth_render(highp float Z, highp float curZ) \n"
"{ \n"
@ -2465,7 +2465,7 @@ graphics::CombinerProgram * CombinerProgramBuilder::buildCombinerProgram(Combine
ssShader << " vec_color = vec4(input_color, vShadeColor.a);" << std::endl;
ssShader << strCombiner << std::endl;
if (config.frameBufferEmulation.N64DepthCompare != 0)
if (config.frameBufferEmulation.N64DepthCompare != Config::dcDisable)
m_fragmentCallN64Depth->write(ssShader);
else
m_fragmentRenderTarget->write(ssShader);

View File

@ -1099,13 +1099,13 @@ void CombinerProgramUniformFactory::buildUniforms(GLuint _program,
if ((config.generalEmulation.hacks & hack_RE2) != 0 && config.generalEmulation.enableFragmentDepthWrite != 0)
_uniforms.emplace_back(new UZLutTexture(_program));
if (config.frameBufferEmulation.N64DepthCompare != 0)
if (config.frameBufferEmulation.N64DepthCompare != Config::dcDisable)
_uniforms.emplace_back(new UDepthInfo(_program));
else
_uniforms.emplace_back(new UDepthSource(_program));
if (config.generalEmulation.enableFragmentDepthWrite != 0 ||
config.frameBufferEmulation.N64DepthCompare != 0)
config.frameBufferEmulation.N64DepthCompare != Config::dcDisable)
_uniforms.emplace_back(new URenderTarget(_program));
if (m_glInfo.isGLESX && m_glInfo.noPerspective) {

View File

@ -20,7 +20,7 @@ namespace glsl {
bool _saveCombinerKeys(const graphics::Combiners & _combiners) const;
bool _loadFromCombinerKeys(graphics::Combiners & _combiners);
const u32 m_formatVersion = 0x29U;
const u32 m_formatVersion = 0x2AU;
const u32 m_keysFormatVersion = 0x04;
const opengl::GLInfo & m_glinfo;
opengl::CachedUseProgram * m_useProgram;

View File

@ -66,7 +66,7 @@ namespace glsl {
"uniform lowp vec4 uFogColor; \n"
;
if (config.frameBufferEmulation.N64DepthCompare != 0) {
if (config.frameBufferEmulation.N64DepthCompare != Config::dcDisable) {
if (_glinfo.imageTextures)
m_part += "layout(binding = 2, r32f) highp uniform restrict readonly image2D uDepthImageZ; \n";
@ -85,7 +85,7 @@ namespace glsl {
"{ \n"
;
if (config.frameBufferEmulation.N64DepthCompare == 0) {
if (config.frameBufferEmulation.N64DepthCompare == Config::dcDisable) {
if (_glinfo.fetch_depth) {
m_part +=
" highp float bufZ = gl_LastFragDepthARM; \n"
@ -127,7 +127,7 @@ namespace glsl {
"} \n"
;
if (config.frameBufferEmulation.N64DepthCompare == 0 && _glinfo.fetch_depth)
if (config.frameBufferEmulation.N64DepthCompare == Config::dcDisable && _glinfo.fetch_depth)
m_part = "#extension GL_ARM_shader_framebuffer_fetch_depth_stencil : enable \n" + m_part;
}
};
@ -314,7 +314,7 @@ namespace glsl {
;
if (!_glinfo.isGLES2 &&
config.generalEmulation.enableFragmentDepthWrite != 0 &&
config.frameBufferEmulation.N64DepthCompare == 0) {
config.frameBufferEmulation.N64DepthCompare == Config::dcDisable) {
m_part +=
" gl_FragDepth = uPrimDepth; \n"
;

View File

@ -121,7 +121,7 @@ void DisplayWindowMupen64plus::_swapBuffers()
// if emulator defined a render callback function, call it before buffer swap
if (renderCallback != nullptr) {
gfxContext.resetShaderProgram();
if (config.frameBufferEmulation.N64DepthCompare == 0) {
if (config.frameBufferEmulation.N64DepthCompare == Config::dcDisable) {
gfxContext.setViewport(0, getHeightOffset(), getScreenWidth(), getScreenHeight());
gSP.changed |= CHANGED_VIEWPORT;
}

View File

@ -194,13 +194,41 @@ void BufferedDrawer::drawTriangles(const graphics::Context::DrawTriangleParamete
if (isHWLightingAllowed())
glVertexAttrib1f(triangleAttrib::numlights, GLfloat(_params.vertices[0].HWLight));
if (_params.elements == nullptr) {
glDrawArrays(GLenum(_params.mode), m_trisBuffers.vbo.pos - _params.verticesCount, _params.verticesCount);
if (config.frameBufferEmulation.N64DepthCompare != Config::dcCompatible) {
if (_params.elements == nullptr) {
glDrawArrays(GLenum(_params.mode), m_trisBuffers.vbo.pos - _params.verticesCount, _params.verticesCount);
return;
}
glDrawRangeElementsBaseVertex(GLenum(_params.mode), 0, _params.verticesCount - 1, _params.elementsCount, GL_UNSIGNED_SHORT,
(u16*)nullptr + m_trisBuffers.ebo.pos - _params.elementsCount, m_trisBuffers.vbo.pos - _params.verticesCount);
return;
}
glDrawRangeElementsBaseVertex(GLenum(_params.mode), 0, _params.verticesCount - 1, _params.elementsCount, GL_UNSIGNED_SHORT,
(u16*)nullptr + m_trisBuffers.ebo.pos - _params.elementsCount, m_trisBuffers.vbo.pos - _params.verticesCount);
// Draw polygons one by one
if (_params.elements == nullptr) {
const GLint vboStartPos = m_trisBuffers.vbo.pos - _params.verticesCount;
if (_params.mode != graphics::drawmode::TRIANGLES) {
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
glDrawArrays(GLenum(_params.mode), m_trisBuffers.vbo.pos - _params.verticesCount, _params.verticesCount);
return;
}
for (GLint i = 0; i < GLint(_params.verticesCount); i += 3) {
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
glDrawArrays(GLenum(_params.mode), vboStartPos + i, 3);
}
return;
}
const GLint eboStartPos = m_trisBuffers.ebo.pos - _params.elementsCount;
const GLint vboStartPos = m_trisBuffers.vbo.pos - _params.verticesCount;
for (GLint i = 0; i < GLint(_params.elementsCount); i += 3) {
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
glDrawRangeElementsBaseVertex(GLenum(_params.mode), i, i + 2, 3, GL_UNSIGNED_SHORT,
(u16*)nullptr + eboStartPos + i, vboStartPos);
}
}
void BufferedDrawer::drawLine(f32 _width, SPVertex * _vertices)

View File

@ -92,8 +92,8 @@ void GLInfo::init() {
fragment_interlock = Utils::isExtensionSupported(*this, "GL_ARB_fragment_shader_interlock") && !hasBuggyFragmentShaderInterlock;
fragment_interlockNV = Utils::isExtensionSupported(*this, "GL_NV_fragment_shader_interlock") && !fragment_interlock && !hasBuggyFragmentShaderInterlock;
fragment_ordering = Utils::isExtensionSupported(*this, "GL_INTEL_fragment_shader_ordering") && !fragment_interlock && !fragment_interlockNV;
imageTextures = imageTextures && (fragment_interlock || fragment_interlockNV || fragment_ordering);
const bool imageTexturesInterlock = imageTextures && (fragment_interlock || fragment_interlockNV || fragment_ordering);
if (isGLES2)
config.generalEmulation.enableFragmentDepthWrite = 0;
@ -155,7 +155,7 @@ void GLInfo::init() {
texture_barrier = !isGLESX && (numericVersion >= 45 || Utils::isExtensionSupported(*this, "GL_ARB_texture_barrier"));
texture_barrierNV = Utils::isExtensionSupported(*this, "GL_NV_texture_barrier");
ext_fetch = Utils::isExtensionSupported(*this, "GL_EXT_shader_framebuffer_fetch") && !isGLES2 && (!isGLESX || ext_draw_buffers_indexed) && !imageTextures;
ext_fetch = Utils::isExtensionSupported(*this, "GL_EXT_shader_framebuffer_fetch") && !isGLES2 && (!isGLESX || ext_draw_buffers_indexed) && !imageTexturesInterlock;
eglImage = (Utils::isEGLExtensionSupported("EGL_KHR_image_base") || Utils::isEGLExtensionSupported("EGL_KHR_image"));
#ifdef OS_ANDROID
@ -166,10 +166,18 @@ void GLInfo::init() {
eglImageFramebuffer = eglImage && !isGLES2;
if (config.frameBufferEmulation.N64DepthCompare != 0) {
if (!imageTextures && !ext_fetch) {
config.frameBufferEmulation.N64DepthCompare = 0;
LOG(LOG_WARNING, "Your GPU does not support the extensions needed for N64 Depth Compare.");
if (config.frameBufferEmulation.N64DepthCompare != Config::dcDisable) {
if (config.frameBufferEmulation.N64DepthCompare == Config::dcFast) {
if (!imageTexturesInterlock && !ext_fetch) {
config.frameBufferEmulation.N64DepthCompare = Config::dcDisable;
LOG(LOG_WARNING, "Your GPU does not support the extensions needed for fast N64 Depth Compare.");
}
} else {
// Compatible
if (!imageTextures) {
config.frameBufferEmulation.N64DepthCompare = Config::dcDisable;
LOG(LOG_WARNING, "Your GPU does not support the extensions needed for N64 Depth Compare.");
}
}
}

View File

@ -76,12 +76,36 @@ void UnbufferedDrawer::drawTriangles(const graphics::Context::DrawTriangleParame
m_cachedAttribArray->enableVertexAttribArray(rectAttrib::texcoord0, false);
m_cachedAttribArray->enableVertexAttribArray(rectAttrib::texcoord1, false);
if (_params.elements == nullptr) {
glDrawArrays(GLenum(_params.mode), 0, _params.verticesCount);
if (config.frameBufferEmulation.N64DepthCompare != Config::dcCompatible) {
if (_params.elements == nullptr) {
glDrawArrays(GLenum(_params.mode), 0, _params.verticesCount);
return;
}
glDrawElements(GLenum(_params.mode), _params.elementsCount, GL_UNSIGNED_SHORT, _params.elements);
return;
}
glDrawElements(GLenum(_params.mode), _params.elementsCount, GL_UNSIGNED_SHORT, _params.elements);
// Draw polygons one by one
if (_params.elements == nullptr) {
if (_params.mode != graphics::drawmode::TRIANGLES) {
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
glDrawArrays(GLenum(_params.mode), 0, _params.verticesCount);
return;
}
for (GLint i = 0; i < GLint(_params.verticesCount); i += 3) {
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
glDrawArrays(GLenum(_params.mode), i, 3);
}
return;
}
for (GLint i = 0; i < GLint(_params.elementsCount); i += 3) {
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
glDrawElements(GLenum(_params.mode), 3, GL_UNSIGNED_BYTE, (u8*)_params.elements + i);
}
}
void UnbufferedDrawer::drawRects(const graphics::Context::DrawRectParameters & _params)

View File

@ -120,7 +120,7 @@ void GraphicsDrawer::_updateDepthUpdate() const
void GraphicsDrawer::_updateDepthCompare() const
{
if (config.frameBufferEmulation.N64DepthCompare != 0) {
if (config.frameBufferEmulation.N64DepthCompare != Config::dcDisable) {
gfxContext.enable(enable::DEPTH_TEST, false);
gfxContext.enableDepthWrite(false);
}
@ -676,7 +676,7 @@ void GraphicsDrawer::_updateStates(DrawingState _drawingState) const
if (isCurrentColorImageDepthImage() &&
config.generalEmulation.enableFragmentDepthWrite != 0 &&
config.frameBufferEmulation.N64DepthCompare == 0) {
config.frameBufferEmulation.N64DepthCompare == Config::dcDisable) {
// Current render target is depth buffer.
// Shader will set gl_FragDepth to shader color, see ShaderCombiner ctor
// Here we enable depth buffer write.
@ -1726,7 +1726,7 @@ void GraphicsDrawer::_initStates()
gfxContext.enableDepthWrite(false);
gfxContext.setDepthCompare(compare::ALWAYS);
if (config.frameBufferEmulation.N64DepthCompare != 0) {
if (config.frameBufferEmulation.N64DepthCompare != Config::dcDisable) {
gfxContext.enable(enable::DEPTH_TEST, false);
gfxContext.enable(enable::POLYGON_OFFSET_FILL, false);
}

View File

@ -104,7 +104,7 @@ bool Config_SetDefault()
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableCopyAuxiliaryToRDRAM", config.frameBufferEmulation.copyAuxToRDRAM, "Copy auxiliary buffers to RDRAM");
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableN64DepthCompare", config.frameBufferEmulation.N64DepthCompare, "Enable N64 depth compare instead of OpenGL standard one. Experimental.");
res = ConfigSetDefaultInt(g_configVideoGliden64, "EnableN64DepthCompare", config.frameBufferEmulation.N64DepthCompare, "Enable N64 depth compare instead of OpenGL standard one. Experimental. (0=Off, 1=Fast, 2=Compatible)");
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultBool(g_configVideoGliden64, "ForceDepthBufferClear", config.frameBufferEmulation.forceDepthBufferClear, "Force depth buffer clear. Hack. Needed for Eikou no Saint Andrews.");
assert(res == M64ERR_SUCCESS);
@ -415,7 +415,7 @@ void Config_LoadConfig()
config.frameBufferEmulation.copyToRDRAM = ConfigGetParamInt(g_configVideoGliden64, "EnableCopyColorToRDRAM");
config.frameBufferEmulation.copyDepthToRDRAM = ConfigGetParamInt(g_configVideoGliden64, "EnableCopyDepthToRDRAM");
config.frameBufferEmulation.copyFromRDRAM = ConfigGetParamBool(g_configVideoGliden64, "EnableCopyColorFromRDRAM");
config.frameBufferEmulation.N64DepthCompare = ConfigGetParamBool(g_configVideoGliden64, "EnableN64DepthCompare");
config.frameBufferEmulation.N64DepthCompare = ConfigGetParamInt(g_configVideoGliden64, "EnableN64DepthCompare");
config.frameBufferEmulation.forceDepthBufferClear = ConfigGetParamBool(g_configVideoGliden64, "ForceDepthBufferClear");
config.frameBufferEmulation.fbInfoDisabled = ConfigGetParamBool(g_configVideoGliden64, "DisableFBInfo");
config.frameBufferEmulation.fbInfoReadColorChunk = ConfigGetParamBool(g_configVideoGliden64, "FBInfoReadColorChunk");