mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
Simulate depth clamping.
We'll allow extra space in both directions. It's not exactly right, but it's a fast approximation.
This commit is contained in:
parent
0920f6c6eb
commit
b80c02c272
@ -498,6 +498,15 @@ LogicOpReplaceType ReplaceLogicOpType() {
|
||||
return LOGICOPTYPE_NORMAL;
|
||||
}
|
||||
|
||||
static const float depthSliceFactor = 4.0f;
|
||||
|
||||
float ToScaledDepth(u16 z) {
|
||||
return z * (1.0f / depthSliceFactor) * (1.0f / 65535.0f) + (0.5f / depthSliceFactor);
|
||||
}
|
||||
|
||||
float ToScaledDepthFromInteger(float z) {
|
||||
return z * (1.0f / depthSliceFactor) * (1.0f / 65535.0f) + (0.5f / depthSliceFactor);
|
||||
}
|
||||
|
||||
void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, float renderHeight, int bufferWidth, int bufferHeight, ViewportAndScissor &out) {
|
||||
bool throughmode = gstate.isModeThrough();
|
||||
@ -638,14 +647,27 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo
|
||||
float minz = gstate.getDepthRangeMin();
|
||||
float maxz = gstate.getDepthRangeMax();
|
||||
|
||||
if (gstate.isClippingEnabled() && (minz == 0 || maxz == 65535)) {
|
||||
// Here, we should "clamp." But clamping per fragment would be slow.
|
||||
// So, instead, we just increase the available range and hope.
|
||||
// If depthSliceFactor is 4, it means (75% / 2) of the depth lies in each direction.
|
||||
float fullDepthRange = 65535.0f * (depthSliceFactor - 1.0f) * (1.0f / 2.0f);
|
||||
if (minz == 0) {
|
||||
minz -= fullDepthRange;
|
||||
}
|
||||
if (maxz == 65535) {
|
||||
maxz += fullDepthRange;
|
||||
}
|
||||
}
|
||||
|
||||
// Okay. So, in our shader, -1 will map to minz, and +1 will map to maxz.
|
||||
float halfActualZRange = (maxz - minz) * (1.0f / 2.0f);
|
||||
float zScale = vpZScale / halfActualZRange;
|
||||
// This adjusts the center from halfActualZRange to vpZCenter.
|
||||
float zOffset = (vpZCenter - (minz + halfActualZRange)) / halfActualZRange;
|
||||
|
||||
out.depthRangeMin = ToScaledDepth(minz);
|
||||
out.depthRangeMax = ToScaledDepth(maxz);
|
||||
out.depthRangeMin = ToScaledDepthFromInteger(minz);
|
||||
out.depthRangeMax = ToScaledDepthFromInteger(maxz);
|
||||
|
||||
bool scaleChanged = gstate_c.vpWidthScale != wScale || gstate_c.vpHeightScale != hScale;
|
||||
bool offsetChanged = gstate_c.vpXOffset != xOffset || gstate_c.vpYOffset != yOffset;
|
||||
@ -663,10 +685,6 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo
|
||||
}
|
||||
}
|
||||
|
||||
float ToScaledDepth(u16 z) {
|
||||
return z * (1.0f / 65535.0f);
|
||||
}
|
||||
|
||||
static const BlendFactor genericALookup[11] = {
|
||||
BlendFactor::DST_COLOR,
|
||||
BlendFactor::ONE_MINUS_DST_COLOR,
|
||||
|
@ -205,6 +205,7 @@ static const CommandTableEntry commandTable[] = {
|
||||
{GE_CMD_VIEWPORTXCENTER, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, &DIRECTX9_GPU::Execute_ViewportType},
|
||||
{GE_CMD_VIEWPORTYCENTER, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, &DIRECTX9_GPU::Execute_ViewportType},
|
||||
{GE_CMD_VIEWPORTZCENTER, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, &DIRECTX9_GPU::Execute_ViewportType},
|
||||
{GE_CMD_CLIPENABLE, FLAG_FLUSHBEFOREONCHANGE},
|
||||
|
||||
// Region
|
||||
{GE_CMD_REGION1, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, &DIRECTX9_GPU::Execute_Region},
|
||||
@ -288,7 +289,6 @@ static const CommandTableEntry commandTable[] = {
|
||||
{GE_CMD_LSC3, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, &DIRECTX9_GPU::Execute_Light3Param},
|
||||
|
||||
// Ignored commands
|
||||
{GE_CMD_CLIPENABLE, 0},
|
||||
{GE_CMD_TEXFLUSH, 0},
|
||||
{GE_CMD_TEXLODSLOPE, 0},
|
||||
{GE_CMD_TEXSYNC, 0},
|
||||
|
@ -481,11 +481,13 @@ void ShaderManagerDX9::VSUpdateUniforms(int dirtyUniforms) {
|
||||
|
||||
if (dirtyUniforms & DIRTY_DEPTHRANGE) {
|
||||
// Depth is [0, 1] mapping to [minz, maxz], not too hard.
|
||||
float minz = gstate.getDepthRangeMin();
|
||||
float maxz = gstate.getDepthRangeMax();
|
||||
float vpZScale = gstate.getViewportZScale();
|
||||
float vpZCenter = gstate.getViewportZCenter();
|
||||
|
||||
float actualZRange = maxz - minz;
|
||||
float viewZScale = actualZRange;
|
||||
// These are just the reverse of the formulas in GPUStateUtils.
|
||||
float halfActualZRange = vpZScale / gstate_c.vpDepthScale;
|
||||
float minz = -((gstate_c.vpZOffset * halfActualZRange) - vpZCenter) - halfActualZRange;
|
||||
float viewZScale = halfActualZRange * 2.0f;
|
||||
float viewZCenter = minz;
|
||||
float viewZInvScale;
|
||||
|
||||
|
@ -211,6 +211,7 @@ static const CommandTableEntry commandTable[] = {
|
||||
{GE_CMD_VIEWPORTYCENTER, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GLES_GPU::Execute_ViewportType},
|
||||
{GE_CMD_VIEWPORTZSCALE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, DIRTY_DEPTHRANGE, &GLES_GPU::Execute_ViewportZType},
|
||||
{GE_CMD_VIEWPORTZCENTER, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, DIRTY_DEPTHRANGE, &GLES_GPU::Execute_ViewportZType},
|
||||
{GE_CMD_CLIPENABLE, FLAG_FLUSHBEFOREONCHANGE},
|
||||
|
||||
// Region
|
||||
{GE_CMD_REGION1, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GLES_GPU::Execute_Region},
|
||||
@ -294,7 +295,6 @@ static const CommandTableEntry commandTable[] = {
|
||||
{GE_CMD_LSC3, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, DIRTY_LIGHT3, &GLES_GPU::Execute_Light3Param},
|
||||
|
||||
// Ignored commands
|
||||
{GE_CMD_CLIPENABLE, 0},
|
||||
{GE_CMD_TEXFLUSH, 0},
|
||||
{GE_CMD_TEXLODSLOPE, 0},
|
||||
{GE_CMD_TEXSYNC, 0},
|
||||
|
@ -589,11 +589,13 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid) {
|
||||
SetMatrix4x3(u_texmtx, gstate.tgenMatrix);
|
||||
}
|
||||
if ((dirty & DIRTY_DEPTHRANGE) && u_depthRange != -1) {
|
||||
// Since depth is [-1, 1] mapping to [minz, maxz], this is easy.
|
||||
float minz = gstate.getDepthRangeMin();
|
||||
float maxz = gstate.getDepthRangeMax();
|
||||
// Since depth is [-1, 1] mapping to [minz, maxz], this is easyish.
|
||||
float vpZScale = gstate.getViewportZScale();
|
||||
float vpZCenter = gstate.getViewportZCenter();
|
||||
|
||||
float halfActualZRange = (maxz - minz) * (1.0f / 2.0f);
|
||||
// These are just the reverse of the formulas in GPUStateUtils.
|
||||
float halfActualZRange = vpZScale / gstate_c.vpDepthScale;
|
||||
float minz = -((gstate_c.vpZOffset * halfActualZRange) - vpZCenter) - halfActualZRange;
|
||||
float viewZScale = halfActualZRange;
|
||||
float viewZCenter = minz + halfActualZRange;
|
||||
float viewZInvScale;
|
||||
|
@ -375,6 +375,7 @@ struct GPUgstate {
|
||||
int getRegionY2() const { return (region2 >> 10) & 0x3FF; }
|
||||
|
||||
// Note that the X1/Y1/Z1 here does not mean the upper-left corner, but half the dimensions. X2/Y2/Z2 are the center.
|
||||
bool isClippingEnabled() const { return clipEnable & 1; }
|
||||
float getViewportXScale() const { return getFloat24(viewportxscale); }
|
||||
float getViewportYScale() const { return getFloat24(viewportyscale); }
|
||||
float getViewportZScale() const { return getFloat24(viewportzscale); }
|
||||
|
Loading…
Reference in New Issue
Block a user