mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #15870 from unknownbrackets/gpu-viewport-state
GPU: Dirty params when converting viewport state for sw transform
This commit is contained in:
commit
669ce4b99d
10 changed files with 50 additions and 57 deletions
|
@ -557,9 +557,7 @@ DepthScaleFactors GetDepthScaleFactors() {
|
|||
}
|
||||
|
||||
void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, float renderHeight, int bufferWidth, int bufferHeight, ViewportAndScissor &out) {
|
||||
bool throughmode = gstate.isModeThrough();
|
||||
out.dirtyProj = false;
|
||||
out.dirtyDepth = false;
|
||||
out.throughMode = gstate.isModeThrough();
|
||||
|
||||
float renderWidthFactor, renderHeightFactor;
|
||||
float renderX = 0.0f, renderY = 0.0f;
|
||||
|
@ -610,7 +608,7 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo
|
|||
float offsetX = gstate.getOffsetX();
|
||||
float offsetY = gstate.getOffsetY();
|
||||
|
||||
if (throughmode) {
|
||||
if (out.throughMode) {
|
||||
out.viewportX = renderX * renderWidthFactor + displayOffsetX;
|
||||
out.viewportY = renderY * renderHeightFactor + displayOffsetY;
|
||||
out.viewportW = curRTWidth * renderWidthFactor;
|
||||
|
@ -647,10 +645,10 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo
|
|||
float right = left + vpWidth;
|
||||
float bottom = top + vpHeight;
|
||||
|
||||
float wScale = 1.0f;
|
||||
float xOffset = 0.0f;
|
||||
float hScale = 1.0f;
|
||||
float yOffset = 0.0f;
|
||||
out.widthScale = 1.0f;
|
||||
out.xOffset = 0.0f;
|
||||
out.heightScale = 1.0f;
|
||||
out.yOffset = 0.0f;
|
||||
|
||||
// If we're within the bounds, we want clipping the viewport way. So leave it be.
|
||||
{
|
||||
|
@ -678,8 +676,8 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo
|
|||
right = left + 1.0f;
|
||||
}
|
||||
|
||||
wScale = vpWidth / (right - left);
|
||||
xOffset = drift / (right - left);
|
||||
out.widthScale = vpWidth / (right - left);
|
||||
out.xOffset = drift / (right - left);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -707,8 +705,8 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo
|
|||
bottom = top + 1.0f;
|
||||
}
|
||||
|
||||
hScale = vpHeight / (bottom - top);
|
||||
yOffset = drift / (bottom - top);
|
||||
out.heightScale = vpHeight / (bottom - top);
|
||||
out.yOffset = drift / (bottom - top);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -740,13 +738,13 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo
|
|||
}
|
||||
// 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 = halfActualZRange < std::numeric_limits<float>::epsilon() ? 1.0f : vpZScale / halfActualZRange;
|
||||
out.depthScale = halfActualZRange < std::numeric_limits<float>::epsilon() ? 1.0f : vpZScale / halfActualZRange;
|
||||
// This adjusts the center from halfActualZRange to vpZCenter.
|
||||
float zOffset = halfActualZRange < std::numeric_limits<float>::epsilon() ? 0.0f : (vpZCenter - (minz + halfActualZRange)) / halfActualZRange;
|
||||
out.zOffset = halfActualZRange < std::numeric_limits<float>::epsilon() ? 0.0f : (vpZCenter - (minz + halfActualZRange)) / halfActualZRange;
|
||||
|
||||
if (!gstate_c.Supports(GPU_SUPPORTS_ACCURATE_DEPTH)) {
|
||||
zScale = 1.0f;
|
||||
zOffset = 0.0f;
|
||||
out.depthScale = 1.0f;
|
||||
out.zOffset = 0.0f;
|
||||
out.depthRangeMin = ToScaledDepthFromIntegerScale(vpZCenter - vpZScale);
|
||||
out.depthRangeMax = ToScaledDepthFromIntegerScale(vpZCenter + vpZScale);
|
||||
} else {
|
||||
|
@ -757,19 +755,27 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo
|
|||
// OpenGL will clamp these for us anyway, and Direct3D will error if not clamped.
|
||||
out.depthRangeMin = std::max(out.depthRangeMin, 0.0f);
|
||||
out.depthRangeMax = std::min(out.depthRangeMax, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
bool scaleChanged = gstate_c.vpWidthScale != wScale || gstate_c.vpHeightScale != hScale;
|
||||
bool offsetChanged = gstate_c.vpXOffset != xOffset || gstate_c.vpYOffset != yOffset;
|
||||
bool depthChanged = gstate_c.vpDepthScale != zScale || gstate_c.vpZOffset != zOffset;
|
||||
if (scaleChanged || offsetChanged || depthChanged) {
|
||||
gstate_c.vpWidthScale = wScale;
|
||||
gstate_c.vpHeightScale = hScale;
|
||||
gstate_c.vpDepthScale = zScale;
|
||||
gstate_c.vpXOffset = xOffset;
|
||||
gstate_c.vpYOffset = yOffset;
|
||||
gstate_c.vpZOffset = zOffset;
|
||||
out.dirtyProj = true;
|
||||
out.dirtyDepth = depthChanged;
|
||||
void UpdateCachedViewportState(const ViewportAndScissor &vpAndScissor) {
|
||||
if (vpAndScissor.throughMode)
|
||||
return;
|
||||
|
||||
bool scaleChanged = gstate_c.vpWidthScale != vpAndScissor.widthScale || gstate_c.vpHeightScale != vpAndScissor.heightScale;
|
||||
bool offsetChanged = gstate_c.vpXOffset != vpAndScissor.xOffset || gstate_c.vpYOffset != vpAndScissor.yOffset;
|
||||
bool depthChanged = gstate_c.vpDepthScale != vpAndScissor.depthScale || gstate_c.vpZOffset != vpAndScissor.zOffset;
|
||||
if (scaleChanged || offsetChanged || depthChanged) {
|
||||
gstate_c.vpWidthScale = vpAndScissor.widthScale;
|
||||
gstate_c.vpHeightScale = vpAndScissor.heightScale;
|
||||
gstate_c.vpDepthScale = vpAndScissor.depthScale;
|
||||
gstate_c.vpXOffset = vpAndScissor.xOffset;
|
||||
gstate_c.vpYOffset = vpAndScissor.yOffset;
|
||||
gstate_c.vpZOffset = vpAndScissor.zOffset;
|
||||
|
||||
gstate_c.Dirty(DIRTY_PROJMATRIX);
|
||||
if (depthChanged) {
|
||||
gstate_c.Dirty(DIRTY_DEPTHRANGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,10 +75,16 @@ struct ViewportAndScissor {
|
|||
float viewportH;
|
||||
float depthRangeMin;
|
||||
float depthRangeMax;
|
||||
bool dirtyProj;
|
||||
bool dirtyDepth;
|
||||
float widthScale;
|
||||
float heightScale;
|
||||
float depthScale;
|
||||
float xOffset;
|
||||
float yOffset;
|
||||
float zOffset;
|
||||
bool throughMode;
|
||||
};
|
||||
void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, float renderHeight, int bufferWidth, int bufferHeight, ViewportAndScissor &out);
|
||||
void UpdateCachedViewportState(const ViewportAndScissor &vpAndScissor);
|
||||
float ToScaledDepthFromIntegerScale(float z);
|
||||
|
||||
struct DepthScaleFactors {
|
||||
|
|
|
@ -617,6 +617,7 @@ rotateVBO:
|
|||
framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),
|
||||
framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),
|
||||
vpAndScissor);
|
||||
UpdateCachedViewportState(vpAndScissor);
|
||||
}
|
||||
|
||||
int maxIndex = indexGen.MaxIndex();
|
||||
|
|
|
@ -374,15 +374,13 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
|
|||
framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),
|
||||
framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),
|
||||
vpAndScissor);
|
||||
UpdateCachedViewportState(vpAndScissor);
|
||||
|
||||
float depthMin = vpAndScissor.depthRangeMin;
|
||||
float depthMax = vpAndScissor.depthRangeMax;
|
||||
|
||||
if (depthMin < 0.0f) depthMin = 0.0f;
|
||||
if (depthMax > 1.0f) depthMax = 1.0f;
|
||||
if (vpAndScissor.dirtyDepth) {
|
||||
gstate_c.Dirty(DIRTY_DEPTHRANGE);
|
||||
}
|
||||
|
||||
Draw::Viewport &vp = dynState_.viewport;
|
||||
vp.TopLeftX = vpAndScissor.viewportX;
|
||||
|
@ -392,10 +390,6 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
|
|||
vp.MinDepth = depthMin;
|
||||
vp.MaxDepth = depthMax;
|
||||
|
||||
if (vpAndScissor.dirtyProj) {
|
||||
gstate_c.Dirty(DIRTY_PROJMATRIX);
|
||||
}
|
||||
|
||||
D3D11_RECT &scissor = dynState_.scissor;
|
||||
scissor.left = vpAndScissor.scissorX;
|
||||
scissor.top = vpAndScissor.scissorY;
|
||||
|
|
|
@ -582,6 +582,7 @@ rotateVBO:
|
|||
framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),
|
||||
framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),
|
||||
vpAndScissor);
|
||||
UpdateCachedViewportState(vpAndScissor);
|
||||
}
|
||||
|
||||
int maxIndex = indexGen.MaxIndex();
|
||||
|
|
|
@ -260,6 +260,7 @@ void DrawEngineDX9::ApplyDrawState(int prim) {
|
|||
framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),
|
||||
framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),
|
||||
vpAndScissor);
|
||||
UpdateCachedViewportState(vpAndScissor);
|
||||
|
||||
dxstate.scissorTest.enable();
|
||||
dxstate.scissorRect.set(vpAndScissor.scissorX, vpAndScissor.scissorY, vpAndScissor.scissorX + vpAndScissor.scissorW, vpAndScissor.scissorY + vpAndScissor.scissorH);
|
||||
|
@ -268,12 +269,6 @@ void DrawEngineDX9::ApplyDrawState(int prim) {
|
|||
float depthMax = vpAndScissor.depthRangeMax;
|
||||
|
||||
dxstate.viewport.set(vpAndScissor.viewportX, vpAndScissor.viewportY, vpAndScissor.viewportW, vpAndScissor.viewportH, depthMin, depthMax);
|
||||
if (vpAndScissor.dirtyProj) {
|
||||
gstate_c.Dirty(DIRTY_PROJMATRIX);
|
||||
}
|
||||
if (vpAndScissor.dirtyDepth) {
|
||||
gstate_c.Dirty(DIRTY_DEPTHRANGE);
|
||||
}
|
||||
}
|
||||
|
||||
gstate_c.Clean(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_BLEND_STATE);
|
||||
|
|
|
@ -364,6 +364,7 @@ void DrawEngineGLES::DoFlush() {
|
|||
framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),
|
||||
framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),
|
||||
vpAndScissor);
|
||||
UpdateCachedViewportState(vpAndScissor);
|
||||
}
|
||||
|
||||
int maxIndex = indexGen.MaxIndex();
|
||||
|
|
|
@ -276,19 +276,13 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
|
|||
framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),
|
||||
framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),
|
||||
vpAndScissor);
|
||||
UpdateCachedViewportState(vpAndScissor);
|
||||
|
||||
renderManager->SetScissor(GLRect2D{ vpAndScissor.scissorX, vpAndScissor.scissorY, vpAndScissor.scissorW, vpAndScissor.scissorH });
|
||||
renderManager->SetViewport({
|
||||
vpAndScissor.viewportX, vpAndScissor.viewportY,
|
||||
vpAndScissor.viewportW, vpAndScissor.viewportH,
|
||||
vpAndScissor.depthRangeMin, vpAndScissor.depthRangeMax });
|
||||
|
||||
if (vpAndScissor.dirtyProj) {
|
||||
gstate_c.Dirty(DIRTY_PROJMATRIX);
|
||||
}
|
||||
if (vpAndScissor.dirtyDepth) {
|
||||
gstate_c.Dirty(DIRTY_DEPTHRANGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -856,6 +856,7 @@ void DrawEngineVulkan::DoFlush() {
|
|||
framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),
|
||||
framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),
|
||||
vpAndScissor);
|
||||
UpdateCachedViewportState(vpAndScissor);
|
||||
}
|
||||
|
||||
int maxIndex = indexGen.MaxIndex();
|
||||
|
|
|
@ -318,15 +318,13 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
|
|||
fbManager.GetRenderWidth(), fbManager.GetRenderHeight(),
|
||||
fbManager.GetTargetBufferWidth(), fbManager.GetTargetBufferHeight(),
|
||||
vpAndScissor);
|
||||
UpdateCachedViewportState(vpAndScissor);
|
||||
|
||||
float depthMin = vpAndScissor.depthRangeMin;
|
||||
float depthMax = vpAndScissor.depthRangeMax;
|
||||
|
||||
if (depthMin < 0.0f) depthMin = 0.0f;
|
||||
if (depthMax > 1.0f) depthMax = 1.0f;
|
||||
if (vpAndScissor.dirtyDepth) {
|
||||
gstate_c.Dirty(DIRTY_DEPTHRANGE);
|
||||
}
|
||||
|
||||
VkViewport &vp = dynState.viewport;
|
||||
vp.x = vpAndScissor.viewportX;
|
||||
|
@ -336,10 +334,6 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
|
|||
vp.minDepth = vpAndScissor.depthRangeMin;
|
||||
vp.maxDepth = vpAndScissor.depthRangeMax;
|
||||
|
||||
if (vpAndScissor.dirtyProj) {
|
||||
gstate_c.Dirty(DIRTY_PROJMATRIX);
|
||||
}
|
||||
|
||||
ScissorRect &scissor = dynState.scissor;
|
||||
scissor.x = vpAndScissor.scissorX;
|
||||
scissor.y = vpAndScissor.scissorY;
|
||||
|
|
Loading…
Add table
Reference in a new issue