mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-01 03:57:17 +01:00
Support depth clamping in OpenGL where available.
Should make support for depth texturing quite easy. Unfortunately, this extension does not exist on OpenGL ES. There we'll have to use ugly tricks with gl_FragDepth if we want this.
This commit is contained in:
1 parent
5bd9e93196
commit
df6abe83a3
9 files changed
+44
-6
No files matched your search
@@ -793,6 +793,7 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last
|
||||
bool blendEnabled = false;
|
||||
bool cullEnabled = false;
|
||||
bool ditherEnabled = false;
|
||||
bool depthClampEnabled = false;
|
||||
#ifndef USING_GLES2
|
||||
int logicOp = -1;
|
||||
bool logicEnabled = false;
|
||||
@@ -1283,6 +1284,15 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last
|
||||
glDisable(GL_DITHER);
|
||||
ditherEnabled = false;
|
||||
}
|
||||
if (c.raster.depthClampEnable) {
|
||||
if (!depthClampEnabled) {
|
||||
glEnable(GL_DEPTH_CLAMP);
|
||||
depthClampEnabled = true;
|
||||
}
|
||||
} else if (!c.raster.depthClampEnable && depthClampEnabled) {
|
||||
glDisable(GL_DEPTH_CLAMP);
|
||||
depthClampEnabled = false;
|
||||
}
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
break;
|
||||
default:
|
||||
@@ -1321,6 +1331,8 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last
|
||||
glDisable(GL_BLEND);
|
||||
if (cullEnabled)
|
||||
glDisable(GL_CULL_FACE);
|
||||
if (depthClampEnabled)
|
||||
glDisable(GL_DEPTH_CLAMP);
|
||||
#ifndef USING_GLES2
|
||||
if (!gl_extensions.IsGLES && logicEnabled) {
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
|
||||
@@ -196,6 +196,7 @@ struct GLRRenderData {
|
||||
GLenum frontFace;
|
||||
GLenum cullFace;
|
||||
GLboolean ditherEnable;
|
||||
GLboolean depthClampEnable;
|
||||
} raster;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -813,13 +813,14 @@ public:
|
||||
curRenderStep_->commands.push_back(data);
|
||||
}
|
||||
|
||||
void SetRaster(GLboolean cullEnable, GLenum frontFace, GLenum cullFace, GLboolean ditherEnable) {
|
||||
void SetRaster(GLboolean cullEnable, GLenum frontFace, GLenum cullFace, GLboolean ditherEnable, GLboolean depthClamp) {
|
||||
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER);
|
||||
GLRRenderData data{ GLRRenderCommand::RASTER };
|
||||
data.raster.cullEnable = cullEnable;
|
||||
data.raster.frontFace = frontFace;
|
||||
data.raster.cullFace = cullFace;
|
||||
data.raster.ditherEnable = ditherEnable;
|
||||
data.raster.depthClampEnable = depthClamp;
|
||||
curRenderStep_->commands.push_back(data);
|
||||
}
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ public:
|
||||
class OpenGLRasterState : public RasterState {
|
||||
public:
|
||||
void Apply(GLRenderManager *render) {
|
||||
render->SetRaster(cullEnable, frontFace, cullMode, false);
|
||||
render->SetRaster(cullEnable, frontFace, cullMode, GL_FALSE, GL_FALSE);
|
||||
}
|
||||
|
||||
GLboolean cullEnable;
|
||||
@@ -533,6 +533,10 @@ OpenGLContext::OpenGLContext() {
|
||||
}
|
||||
caps_.framebufferBlitSupported = gl_extensions.NV_framebuffer_blit || gl_extensions.ARB_framebuffer_object;
|
||||
caps_.framebufferDepthBlitSupported = caps_.framebufferBlitSupported;
|
||||
caps_.depthClampSupported = gl_extensions.ARB_depth_clamp;
|
||||
|
||||
// Interesting potential hack for emulating GL_DEPTH_CLAMP (use a separate varying, force depth in fragment shader):
|
||||
// https://stackoverflow.com/questions/5960757/how-to-emulate-gl-depth-clamp-nv
|
||||
|
||||
switch (gl_extensions.gpuVendor) {
|
||||
case GPU_VENDOR_AMD: caps_.vendor = GPUVendor::VENDOR_AMD; break;
|
||||
|
||||
@@ -133,7 +133,7 @@ void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int
|
||||
// We must bind the program after starting the render pass, and set the color mask after clearing.
|
||||
render_->SetScissor({ 0, 0, vfb->renderWidth, vfb->renderHeight });
|
||||
render_->SetDepth(false, false, GL_ALWAYS);
|
||||
render_->SetRaster(false, GL_CCW, GL_FRONT, GL_FALSE);
|
||||
render_->SetRaster(false, GL_CCW, GL_FRONT, GL_FALSE, GL_FALSE);
|
||||
render_->BindProgram(depthDownloadProgram_);
|
||||
|
||||
if (!gstate_c.Supports(GPU_SUPPORTS_ACCURATE_DEPTH)) {
|
||||
|
||||
@@ -203,7 +203,7 @@ void FramebufferManagerGLES::DrawActiveTexture(float x, float y, float w, float
|
||||
|
||||
// We always want a plain state here, well, except for when it's used by the stencil stuff...
|
||||
render_->SetDepth(false, false, GL_ALWAYS);
|
||||
render_->SetRaster(false, GL_CCW, GL_FRONT, GL_FALSE);
|
||||
render_->SetRaster(false, GL_CCW, GL_FRONT, GL_FALSE, GL_FALSE);
|
||||
if (!(flags & DRAWTEX_KEEP_STENCIL_ALPHA)) {
|
||||
render_->SetNoBlendAndMask(0xF);
|
||||
render_->SetStencilDisabled();
|
||||
|
||||
@@ -221,6 +221,9 @@ void GPU_GLES::CheckGPUFeatures() {
|
||||
if (gl_extensions.ARB_texture_float || gl_extensions.OES_texture_float)
|
||||
features |= GPU_SUPPORTS_TEXTURE_FLOAT;
|
||||
|
||||
if (draw_->GetDeviceCaps().depthClampSupported)
|
||||
features |= GPU_SUPPORTS_DEPTH_CLAMP;
|
||||
|
||||
// If we already have a 16-bit depth buffer, we don't need to round.
|
||||
bool prefer24 = draw_->GetDeviceCaps().preferredDepthBufferFormat == Draw::DataFormat::D24_S8;
|
||||
if (prefer24) {
|
||||
|
||||
@@ -230,7 +230,24 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
|
||||
GLenum cullMode = cullingMode[gstate.getCullMode() ^ !useBufferedRendering];
|
||||
|
||||
cullEnable = !gstate.isModeClear() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled();
|
||||
renderManager->SetRaster(cullEnable, GL_CCW, cullMode, dither);
|
||||
|
||||
bool depthClampEnable = false;
|
||||
if (gstate.isModeClear() || gstate.isModeThrough()) {
|
||||
// TODO: Might happen in clear mode if not through...
|
||||
depthClampEnable = false;
|
||||
} else {
|
||||
// Set cull
|
||||
if (gstate.getDepthRangeMin() == 0 || gstate.getDepthRangeMax() == 65535) {
|
||||
// TODO: Still has a bug where we clamp to depth range if one is not the full range.
|
||||
// But the alternate is not clamping in either direction...
|
||||
depthClampEnable = gstate.isDepthClampEnabled() && gstate_c.Supports(GPU_SUPPORTS_DEPTH_CLAMP);
|
||||
} else {
|
||||
// We just want to clip in this case, the clamp would be clipped anyway.
|
||||
depthClampEnable = false;
|
||||
}
|
||||
}
|
||||
|
||||
renderManager->SetRaster(cullEnable, GL_CCW, cullMode, dither, depthClampEnable);
|
||||
}
|
||||
|
||||
if (gstate_c.IsDirty(DIRTY_DEPTHSTENCIL_STATE)) {
|
||||
|
||||
@@ -191,7 +191,7 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, StencilUplo
|
||||
render_->SetDepth(false, false, GL_ALWAYS);
|
||||
render_->Clear(0, 0, 0, GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, 0x8, 0, 0, 0, 0);
|
||||
render_->SetStencilFunc(GL_TRUE, GL_ALWAYS, 0xFF, 0xFF);
|
||||
render_->SetRaster(false, GL_CCW, GL_FRONT, GL_FALSE);
|
||||
render_->SetRaster(false, GL_CCW, GL_FRONT, GL_FALSE, GL_FALSE);
|
||||
render_->BindProgram(stencilUploadProgram_);
|
||||
render_->SetNoBlendAndMask(0x8);
|
||||
|
||||
|
||||
Reference in new issue
Block a user