mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-03-09 01:13:33 +00:00
More work on detangling the concepts and making things make more sense.
This commit is contained in:
parent
3d289594f9
commit
391b8155c5
@ -480,8 +480,9 @@ u32 DrawEngineCommon::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr,
|
||||
return GE_VTYPE_TC_FLOAT | GE_VTYPE_COL_8888 | GE_VTYPE_NRM_FLOAT | GE_VTYPE_POS_FLOAT | (vertType & (GE_VTYPE_IDX_MASK | GE_VTYPE_THROUGH));
|
||||
}
|
||||
|
||||
bool DrawEngineCommon::ApplyShaderBlending() {
|
||||
bool DrawEngineCommon::ApplyFramebufferRead(bool *fboTexNeedsBind) {
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH)) {
|
||||
*fboTexNeedsBind = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -502,7 +503,7 @@ bool DrawEngineCommon::ApplyShaderBlending() {
|
||||
return false;
|
||||
}
|
||||
|
||||
fboTexNeedBind_ = true;
|
||||
*fboTexNeedsBind = true;
|
||||
|
||||
gstate_c.Dirty(DIRTY_SHADERBLEND);
|
||||
return true;
|
||||
|
@ -112,7 +112,7 @@ protected:
|
||||
// Vertex decoding
|
||||
void DecodeVertsStep(u8 *dest, int &i, int &decodedVerts);
|
||||
|
||||
bool ApplyShaderBlending();
|
||||
bool ApplyFramebufferRead(bool *fboTexNeedsBind);
|
||||
|
||||
inline int IndexSize(u32 vtype) const {
|
||||
const u32 indexType = (vtype & GE_VTYPE_IDX_MASK);
|
||||
@ -169,7 +169,7 @@ protected:
|
||||
GEPrimitiveType prevPrim_ = GE_PRIM_INVALID;
|
||||
|
||||
// Shader blending state
|
||||
bool fboTexNeedBind_ = false;
|
||||
bool fboTexNeedsBind_ = false;
|
||||
bool fboTexBound_ = false;
|
||||
|
||||
// Hardware tessellation
|
||||
|
@ -159,13 +159,14 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
|
||||
GenericBlendState blendState;
|
||||
ConvertBlendState(blendState, gstate_c.allowFramebufferRead);
|
||||
if (blendState.applyFramebufferRead) {
|
||||
if (ApplyShaderBlending()) {
|
||||
if (ApplyFramebufferRead(&fboTexNeedsBind_)) {
|
||||
// We may still want to do something about stencil -> alpha.
|
||||
ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState);
|
||||
} else {
|
||||
// Until next time, force it off.
|
||||
ResetFramebufferRead();
|
||||
gstate_c.SetAllowFramebufferRead(false);
|
||||
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
|
||||
}
|
||||
} else if (blendState.resetFramebufferRead) {
|
||||
ResetFramebufferRead();
|
||||
@ -446,11 +447,11 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
|
||||
|
||||
void DrawEngineD3D11::ApplyDrawStateLate(bool applyStencilRef, uint8_t stencilRef) {
|
||||
if (!gstate.isModeClear()) {
|
||||
if (fboTexNeedBind_) {
|
||||
if (fboTexNeedsBind_) {
|
||||
framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY);
|
||||
// No sampler required, we do a plain Load in the pixel shader.
|
||||
fboTexBound_ = true;
|
||||
fboTexNeedBind_ = false;
|
||||
fboTexNeedsBind_ = false;
|
||||
}
|
||||
textureCache_->ApplyTexture();
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ private:
|
||||
|
||||
void ApplyDrawState(int prim);
|
||||
void ApplyDrawStateLate();
|
||||
void ResetShaderBlending();
|
||||
void ResetFramebufferRead();
|
||||
|
||||
IDirect3DVertexDeclaration9 *SetupDecFmtForDraw(VSShader *vshader, const DecVtxFormat &decFmt, u32 pspFmt);
|
||||
|
||||
|
@ -90,7 +90,7 @@ static const D3DSTENCILOP stencilOps[] = {
|
||||
D3DSTENCILOP_KEEP, // reserved
|
||||
};
|
||||
|
||||
inline void DrawEngineDX9::ResetShaderBlending() {
|
||||
inline void DrawEngineDX9::ResetFramebufferRead() {
|
||||
if (fboTexBound_) {
|
||||
device_->SetTexture(1, nullptr);
|
||||
fboTexBound_ = false;
|
||||
@ -130,16 +130,17 @@ void DrawEngineDX9::ApplyDrawState(int prim) {
|
||||
ConvertBlendState(blendState, gstate_c.allowFramebufferRead);
|
||||
|
||||
if (blendState.applyFramebufferRead) {
|
||||
if (ApplyShaderBlending()) {
|
||||
if (ApplyFramebufferRead(&fboTexNeedsBind_)) {
|
||||
// We may still want to do something about stencil -> alpha.
|
||||
ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState);
|
||||
} else {
|
||||
// Until next time, force it off.
|
||||
ResetShaderBlending();
|
||||
ResetFramebufferRead();
|
||||
gstate_c.SetAllowFramebufferRead(false);
|
||||
}
|
||||
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
|
||||
} else if (blendState.resetFramebufferRead) {
|
||||
ResetShaderBlending();
|
||||
ResetFramebufferRead();
|
||||
}
|
||||
|
||||
if (blendState.enabled) {
|
||||
@ -166,20 +167,6 @@ void DrawEngineDX9::ApplyDrawState(int prim) {
|
||||
bool bmask = ((gstate.pmskc >> 16) & 0xFF) < 128;
|
||||
bool amask = (gstate.pmska & 0xFF) < 128;
|
||||
|
||||
#ifndef MOBILE_DEVICE
|
||||
u8 abits = (gstate.pmska >> 0) & 0xFF;
|
||||
u8 rbits = (gstate.pmskc >> 0) & 0xFF;
|
||||
u8 gbits = (gstate.pmskc >> 8) & 0xFF;
|
||||
u8 bbits = (gstate.pmskc >> 16) & 0xFF;
|
||||
if ((rbits != 0 && rbits != 0xFF) || (gbits != 0 && gbits != 0xFF) || (bbits != 0 && bbits != 0xFF)) {
|
||||
WARN_LOG_REPORT_ONCE(rgbmask, G3D, "Unsupported RGB mask: r=%02x g=%02x b=%02x", rbits, gbits, bbits);
|
||||
}
|
||||
if (abits != 0 && abits != 0xFF) {
|
||||
// The stencil part of the mask is supported.
|
||||
WARN_LOG_REPORT_ONCE(amask, G3D, "Unsupported alpha/stencil mask: %02x", abits);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Let's not write to alpha if stencil isn't enabled.
|
||||
if (IsStencilTestOutputDisabled()) {
|
||||
amask = false;
|
||||
@ -297,14 +284,14 @@ void DrawEngineDX9::ApplyDrawStateLate() {
|
||||
if (!gstate.isModeClear()) {
|
||||
textureCache_->ApplyTexture();
|
||||
|
||||
if (fboTexNeedBind_) {
|
||||
if (fboTexNeedsBind_) {
|
||||
// Note that this is positions, not UVs, that we need the copy from.
|
||||
framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY);
|
||||
// If we are rendering at a higher resolution, linear is probably best for the dest color.
|
||||
device_->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
device_->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
fboTexBound_ = true;
|
||||
fboTexNeedBind_ = false;
|
||||
fboTexNeedsBind_ = false;
|
||||
}
|
||||
|
||||
// TODO: Test texture?
|
||||
|
@ -193,7 +193,7 @@ private:
|
||||
void DoFlush();
|
||||
void ApplyDrawState(int prim);
|
||||
void ApplyDrawStateLate(bool setStencil, int stencilValue);
|
||||
void ResetShaderBlending();
|
||||
void ResetFramebufferRead();
|
||||
|
||||
GLRInputLayout *SetupDecFmtForDraw(LinkedShader *program, const DecVtxFormat &decFmt);
|
||||
|
||||
|
@ -121,7 +121,7 @@ static const GLushort logicOps[] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
inline void DrawEngineGLES::ResetShaderBlending() {
|
||||
inline void DrawEngineGLES::ResetFramebufferRead() {
|
||||
if (fboTexBound_) {
|
||||
GLRenderManager *renderManager = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||
renderManager->BindTexture(TEX_SLOT_SHADERBLEND_SRC, nullptr);
|
||||
@ -170,19 +170,19 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
|
||||
ConvertBlendState(blendState, gstate_c.allowFramebufferRead);
|
||||
|
||||
if (blendState.applyFramebufferRead) {
|
||||
if (ApplyShaderBlending()) {
|
||||
if (ApplyFramebufferRead(&fboTexNeedsBind_)) {
|
||||
// We may still want to do something about stencil -> alpha.
|
||||
ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState);
|
||||
|
||||
// We copy the framebuffer here, as doing so will wipe any blend state if we do it later.
|
||||
if (fboTexNeedBind_) {
|
||||
if (fboTexNeedsBind_) {
|
||||
// Note that this is positions, not UVs, that we need the copy from.
|
||||
// TODO: If the device doesn't support blit, this will corrupt the currently applied texture.
|
||||
framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY);
|
||||
// If we are rendering at a higher resolution, linear is probably best for the dest color.
|
||||
renderManager->SetTextureSampler(1, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_LINEAR, GL_LINEAR, 0.0f);
|
||||
fboTexBound_ = true;
|
||||
fboTexNeedBind_ = false;
|
||||
fboTexNeedsBind_ = false;
|
||||
|
||||
framebufferManager_->RebindFramebuffer("RebindFramebuffer - ApplyDrawState");
|
||||
// Must dirty blend state here so we re-copy next time. Example: Lunar's spell effects.
|
||||
@ -190,11 +190,12 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
|
||||
}
|
||||
} else {
|
||||
// Until next time, force it off.
|
||||
ResetShaderBlending();
|
||||
ResetFramebufferRead();
|
||||
gstate_c.SetAllowFramebufferRead(false);
|
||||
}
|
||||
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
|
||||
} else if (blendState.resetFramebufferRead) {
|
||||
ResetShaderBlending();
|
||||
ResetFramebufferRead();
|
||||
}
|
||||
|
||||
if (blendState.enabled) {
|
||||
@ -220,19 +221,6 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
|
||||
bool gmask = ((gstate.pmskc >> 8) & 0xFF) < 128;
|
||||
bool bmask = ((gstate.pmskc >> 16) & 0xFF) < 128;
|
||||
|
||||
#ifndef MOBILE_DEVICE
|
||||
u8 abits = (gstate.pmska >> 0) & 0xFF;
|
||||
u8 rbits = (gstate.pmskc >> 0) & 0xFF;
|
||||
u8 gbits = (gstate.pmskc >> 8) & 0xFF;
|
||||
u8 bbits = (gstate.pmskc >> 16) & 0xFF;
|
||||
if ((rbits != 0 && rbits != 0xFF) || (gbits != 0 && gbits != 0xFF) || (bbits != 0 && bbits != 0xFF)) {
|
||||
WARN_LOG_REPORT_ONCE(rgbmask, G3D, "Unsupported RGB mask: r=%02x g=%02x b=%02x", rbits, gbits, bbits);
|
||||
}
|
||||
if (abits != 0 && abits != 0xFF) {
|
||||
// The stencil part of the mask is supported.
|
||||
WARN_LOG_REPORT_ONCE(amask, G3D, "Unsupported alpha/stencil mask: %02x", abits);
|
||||
}
|
||||
#endif
|
||||
int mask = (int)rmask | ((int)gmask << 1) | ((int)bmask << 2) | ((int)amask << 3);
|
||||
if (blendState.enabled) {
|
||||
renderManager->SetBlendAndMask(mask, blendState.enabled,
|
||||
|
@ -199,7 +199,7 @@ private:
|
||||
void ApplyDrawStateLate(VulkanRenderManager *renderManager, bool applyStencilRef, uint8_t stencilRef, bool useBlendConstant);
|
||||
void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, ShaderManagerVulkan *shaderManager, int prim, VulkanPipelineRasterStateKey &key, VulkanDynamicState &dynState);
|
||||
void BindShaderBlendTex();
|
||||
void ResetShaderBlending();
|
||||
void ResetFramebufferRead();
|
||||
|
||||
void InitDeviceObjects();
|
||||
void DestroyDeviceObjects();
|
||||
|
@ -122,7 +122,7 @@ static const VkLogicOp logicOps[] = {
|
||||
VK_LOGIC_OP_SET,
|
||||
};
|
||||
|
||||
void DrawEngineVulkan::ResetShaderBlending() {
|
||||
void DrawEngineVulkan::ResetFramebufferRead() {
|
||||
boundSecondary_ = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
@ -166,18 +166,18 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
|
||||
ConvertBlendState(blendState, gstate_c.allowFramebufferRead);
|
||||
|
||||
if (blendState.applyFramebufferRead) {
|
||||
if (ApplyShaderBlending()) {
|
||||
if (ApplyFramebufferRead(&fboTexNeedsBind_)) {
|
||||
// We may still want to do something about stencil -> alpha.
|
||||
ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState);
|
||||
} else {
|
||||
// Until next time, force it off.
|
||||
ResetShaderBlending();
|
||||
ResetFramebufferRead();
|
||||
gstate_c.SetAllowFramebufferRead(false);
|
||||
// Make sure we recompute the fragment shader ID to one that doesn't try to use shader blending.
|
||||
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
|
||||
}
|
||||
} else if (blendState.resetFramebufferRead) {
|
||||
ResetShaderBlending();
|
||||
ResetFramebufferRead();
|
||||
}
|
||||
|
||||
if (blendState.enabled) {
|
||||
@ -213,20 +213,6 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
|
||||
bool bmask = ((gstate.pmskc >> 16) & 0xFF) < 128;
|
||||
bool amask = (gstate.pmska & 0xFF) < 128;
|
||||
|
||||
#ifndef MOBILE_DEVICE
|
||||
u8 abits = (gstate.pmska >> 0) & 0xFF;
|
||||
u8 rbits = (gstate.pmskc >> 0) & 0xFF;
|
||||
u8 gbits = (gstate.pmskc >> 8) & 0xFF;
|
||||
u8 bbits = (gstate.pmskc >> 16) & 0xFF;
|
||||
if ((rbits != 0 && rbits != 0xFF) || (gbits != 0 && gbits != 0xFF) || (bbits != 0 && bbits != 0xFF)) {
|
||||
WARN_LOG_REPORT_ONCE(rgbmask, G3D, "Unsupported RGB mask: r=%02x g=%02x b=%02x", rbits, gbits, bbits);
|
||||
}
|
||||
if (abits != 0 && abits != 0xFF) {
|
||||
// The stencil part of the mask is supported.
|
||||
WARN_LOG_REPORT_ONCE(amask, G3D, "Unsupported alpha/stencil mask: %02x", abits);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Let's not write to alpha if stencil isn't enabled.
|
||||
if (IsStencilTestOutputDisabled()) {
|
||||
amask = false;
|
||||
@ -395,13 +381,13 @@ void DrawEngineVulkan::BindShaderBlendTex() {
|
||||
// TODO: Set the nearest/linear here (since we correctly know if alpha/color tests are needed)?
|
||||
if (!gstate.isModeClear()) {
|
||||
// TODO: Test texture?
|
||||
if (fboTexNeedBind_) {
|
||||
if (fboTexNeedsBind_) {
|
||||
// Note that this is positions, not UVs, that we need the copy from.
|
||||
framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY);
|
||||
// If we are rendering at a higher resolution, linear is probably best for the dest color.
|
||||
boundSecondary_ = (VkImageView)draw_->GetNativeObject(Draw::NativeObject::BOUND_TEXTURE1_IMAGEVIEW);
|
||||
fboTexBound_ = true;
|
||||
fboTexNeedBind_ = false;
|
||||
fboTexNeedsBind_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user