Merge pull request #9231 from hrydgard/extended-dirty-flag

Set dirty-flags without callbacks
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2017-01-24 20:21:40 +01:00
commit 75cbf4065b
35 files changed
+905 -2829

No files matched your search

+1
View File
@@ -98,6 +98,7 @@ protected:
int prevSizeTex;
int prevSizeCol;
public:
virtual ~TessellationDataTransfer() {}
// Send spline/bezier's control points to vertex shader through floating point texture.
virtual void SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) = 0;
};
+1 -1
View File
@@ -287,7 +287,7 @@ void GetFramebufferHeuristicInputs(FramebufferHeuristicParams *params, const GPU
}
VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const FramebufferHeuristicParams &params, u32 skipDrawReason) {
gstate_c.framebufChanged = false;
gstate_c.Clean(DIRTY_FRAMEBUF);
// Collect all parameters. This whole function has really become a cesspool of heuristics...
// but it appears that's what it takes, unless we emulate VRAM layout more accurately somehow.
+6 -6
View File
@@ -87,6 +87,11 @@ enum : uint64_t {
DIRTY_ALL_UNIFORMS = 0x1FFFFFFFFFULL,
// Other dirty elements that aren't uniforms!
DIRTY_FRAMEBUF = 1ULL << 40,
DIRTY_TEXTURE_IMAGE = 1ULL << 41,
DIRTY_TEXTURE_PARAMS = 1ULL << 42,
// Now we can add further dirty flags that are not uniforms.
DIRTY_ALL = 0xFFFFFFFFFFFFFFFF
@@ -94,11 +99,6 @@ enum : uint64_t {
class ShaderManagerCommon {
public:
ShaderManagerCommon() : globalDirty_(DIRTY_ALL) {}
ShaderManagerCommon() {}
virtual ~ShaderManagerCommon() {}
void DirtyUniform(u64 what) {
globalDirty_ |= what;
}
protected:
uint64_t globalDirty_;
};
+1 -1
View File
@@ -313,7 +313,7 @@ void DrawEngineDX9::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, in
if (prim == GE_PRIM_RECTANGLES && (gstate.getTextureAddress(0) & 0x3FFFFFFF) == (gstate.getFrameBufAddress() & 0x3FFFFFFF)) {
// Rendertarget == texture?
if (!g_Config.bDisableSlowFramebufEffects) {
gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY;
gstate_c.Dirty(DIRTY_TEXTURE_PARAMS);
Flush();
}
}
+10 -10
View File
@@ -390,11 +390,11 @@ namespace DX9 {
// ugly...
if (gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) {
shaderManager_->DirtyUniform(DIRTY_PROJTHROUGHMATRIX);
gstate_c.Dirty(DIRTY_PROJTHROUGHMATRIX);
}
if (gstate_c.curRTRenderWidth != vfb->renderWidth || gstate_c.curRTRenderHeight != vfb->renderHeight) {
shaderManager_->DirtyUniform(DIRTY_PROJMATRIX);
shaderManager_->DirtyUniform(DIRTY_PROJTHROUGHMATRIX);
gstate_c.Dirty(DIRTY_PROJMATRIX);
gstate_c.Dirty(DIRTY_PROJTHROUGHMATRIX);
}
}
@@ -447,11 +447,11 @@ namespace DX9 {
// ugly...
if (gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) {
shaderManager_->DirtyUniform(DIRTY_PROJTHROUGHMATRIX);
gstate_c.Dirty(DIRTY_PROJTHROUGHMATRIX);
}
if (gstate_c.curRTRenderWidth != vfb->renderWidth || gstate_c.curRTRenderHeight != vfb->renderHeight) {
shaderManager_->DirtyUniform(DIRTY_PROJMATRIX);
shaderManager_->DirtyUniform(DIRTY_PROJTHROUGHMATRIX);
gstate_c.Dirty(DIRTY_PROJMATRIX);
gstate_c.Dirty(DIRTY_PROJTHROUGHMATRIX);
}
}
@@ -465,11 +465,11 @@ namespace DX9 {
// ugly...
if (gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) {
shaderManager_->DirtyUniform(DIRTY_PROJTHROUGHMATRIX);
gstate_c.Dirty(DIRTY_PROJTHROUGHMATRIX);
}
if (gstate_c.curRTRenderWidth != vfb->renderWidth || gstate_c.curRTRenderHeight != vfb->renderHeight) {
shaderManager_->DirtyUniform(DIRTY_PROJMATRIX);
shaderManager_->DirtyUniform(DIRTY_PROJTHROUGHMATRIX);
gstate_c.Dirty(DIRTY_PROJMATRIX);
gstate_c.Dirty(DIRTY_PROJTHROUGHMATRIX);
}
}
@@ -1303,7 +1303,7 @@ namespace DX9 {
// TODO: It's really bad that we are calling SetRenderFramebuffer here with
// all the irrelevant state checking it'll use to decide what to do. Should
// do something more focused here.
SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason);
SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason);
transformDraw_->Flush();
}
+234 -845
View File
File diff suppressed because it is too large. Load diff
+1 -32
View File
@@ -76,11 +76,10 @@ public:
typedef void (GPU_DX9::*CmdFunc)(u32 op, u32 diff);
struct CommandInfo {
u8 flags;
uint64_t flags;
GPU_DX9::CmdFunc func;
};
void Execute_Generic(u32 op, u32 diff);
void Execute_Vaddr(u32 op, u32 diff);
void Execute_Iaddr(u32 op, u32 diff);
void Execute_Prim(u32 op, u32 diff);
@@ -88,42 +87,12 @@ public:
void Execute_Spline(u32 op, u32 diff);
void Execute_VertexType(u32 op, u32 diff);
void Execute_VertexTypeSkinning(u32 op, u32 diff);
void Execute_Region(u32 op, u32 diff);
void Execute_Scissor(u32 op, u32 diff);
void Execute_FramebufType(u32 op, u32 diff);
void Execute_ViewportType(u32 op, u32 diff);
void Execute_TexScaleU(u32 op, u32 diff);
void Execute_TexScaleV(u32 op, u32 diff);
void Execute_TexOffsetU(u32 op, u32 diff);
void Execute_TexOffsetV(u32 op, u32 diff);
void Execute_TexAddr0(u32 op, u32 diff);
void Execute_TexAddrN(u32 op, u32 diff);
void Execute_TexBufw0(u32 op, u32 diff);
void Execute_TexBufwN(u32 op, u32 diff);
void Execute_TexSize0(u32 op, u32 diff);
void Execute_TexSizeN(u32 op, u32 diff);
void Execute_TexFormat(u32 op, u32 diff);
void Execute_TexMapMode(u32 op, u32 diff);
void Execute_TexParamType(u32 op, u32 diff);
void Execute_TexEnvColor(u32 op, u32 diff);
void Execute_TexLevel(u32 op, u32 diff);
void Execute_LoadClut(u32 op, u32 diff);
void Execute_ClutFormat(u32 op, u32 diff);
void Execute_Ambient(u32 op, u32 diff);
void Execute_MaterialDiffuse(u32 op, u32 diff);
void Execute_MaterialEmissive(u32 op, u32 diff);
void Execute_MaterialAmbient(u32 op, u32 diff);
void Execute_MaterialSpecular(u32 op, u32 diff);
void Execute_Light0Param(u32 op, u32 diff);
void Execute_Light1Param(u32 op, u32 diff);
void Execute_Light2Param(u32 op, u32 diff);
void Execute_Light3Param(u32 op, u32 diff);
void Execute_FogColor(u32 op, u32 diff);
void Execute_FogCoef(u32 op, u32 diff);
void Execute_ColorTestMask(u32 op, u32 diff);
void Execute_AlphaTest(u32 op, u32 diff);
void Execute_StencilTest(u32 op, u32 diff);
void Execute_ColorRef(u32 op, u32 diff);
// Using string because it's generic - makes no assumptions on the size of the shader IDs of this backend.
std::vector<std::string> DebugGetShaderIDs(DebugShaderType shader) override;
+22 -10
View File
@@ -272,6 +272,8 @@ static void ConvertProjMatrixToD3DThrough(Matrix4x4 &in) {
in.translateAndScale(Vec3(xoff, yoff, 0.5f), Vec3(1.0f, 1.0f, 0.5f));
}
const uint64_t psUniforms = DIRTY_TEXENV | DIRTY_ALPHACOLORREF | DIRTY_ALPHACOLORMASK | DIRTY_FOGCOLOR | DIRTY_STENCILREPLACEVALUE | DIRTY_SHADERBLEND | DIRTY_TEXCLAMP;
void ShaderManagerDX9::PSUpdateUniforms(u64 dirtyUniforms) {
if (dirtyUniforms & DIRTY_TEXENV) {
PSSetColorUniform3(CONST_PS_TEXENV, gstate.texenvcolor);
@@ -324,6 +326,10 @@ void ShaderManagerDX9::PSUpdateUniforms(u64 dirtyUniforms) {
}
}
const uint64_t vsUniforms = DIRTY_PROJMATRIX | DIRTY_PROJTHROUGHMATRIX | DIRTY_WORLDMATRIX | DIRTY_VIEWMATRIX | DIRTY_TEXMATRIX |
DIRTY_FOGCOEF | DIRTY_BONE_UNIFORMS | DIRTY_UVSCALEOFFSET | DIRTY_DEPTHRANGE |
DIRTY_AMBIENT | DIRTY_MATAMBIENTALPHA | DIRTY_MATSPECULAR | DIRTY_MATDIFFUSE | DIRTY_MATEMISSIVE | DIRTY_LIGHT0 | DIRTY_LIGHT1 | DIRTY_LIGHT2 | DIRTY_LIGHT3;
void ShaderManagerDX9::VSUpdateUniforms(u64 dirtyUniforms) {
// Update any dirty uniforms before we draw
if (dirtyUniforms & DIRTY_PROJMATRIX) {
@@ -522,7 +528,7 @@ void ShaderManagerDX9::Clear() {
}
fsCache_.clear();
vsCache_.clear();
globalDirty_ = 0xFFFFFFFF;
gstate_c.Dirty(DIRTY_ALL_UNIFORMS);
lastFSID_.clear();
lastVSID_.clear();
DirtyShader();
@@ -539,7 +545,7 @@ void ShaderManagerDX9::DirtyShader() {
lastVSID_.clear();
lastVShader_ = nullptr;
lastPShader_ = nullptr;
globalDirty_ = 0xFFFFFFFF;
gstate_c.Dirty(DIRTY_ALL_UNIFORMS);
}
void ShaderManagerDX9::DirtyLastShader() { // disables vertex arrays
@@ -557,10 +563,13 @@ VSShader *ShaderManagerDX9::ApplyShader(int prim, u32 vertType) {
// Just update uniforms if this is the same shader as last time.
if (lastVShader_ != nullptr && lastPShader_ != nullptr && VSID == lastVSID_ && FSID == lastFSID_) {
if (globalDirty_) {
PSUpdateUniforms(globalDirty_);
VSUpdateUniforms(globalDirty_);
globalDirty_ = 0;
uint64_t dirtyUniforms = gstate_c.GetDirtyUniforms();
if (dirtyUniforms) {
if (dirtyUniforms & psUniforms)
PSUpdateUniforms(dirtyUniforms);
if (dirtyUniforms & vsUniforms)
VSUpdateUniforms(dirtyUniforms);
gstate_c.CleanUniforms();
}
return lastVShader_; // Already all set.
}
@@ -608,10 +617,13 @@ VSShader *ShaderManagerDX9::ApplyShader(int prim, u32 vertType) {
lastFSID_ = FSID;
if (globalDirty_) {
PSUpdateUniforms(globalDirty_);
VSUpdateUniforms(globalDirty_);
globalDirty_ = 0;
uint64_t dirtyUniforms = gstate_c.GetDirtyUniforms();
if (dirtyUniforms) {
if (dirtyUniforms & psUniforms)
PSUpdateUniforms(dirtyUniforms);
if (dirtyUniforms & vsUniforms)
VSUpdateUniforms(dirtyUniforms);
gstate_c.CleanUniforms();
}
pD3Ddevice->SetPixelShader(fs->shader);
+7 -7
View File
@@ -111,7 +111,7 @@ bool DrawEngineDX9::ApplyShaderBlending() {
fboTexNeedBind_ = true;
shaderManager_->DirtyUniform(DIRTY_SHADERBLEND);
gstate_c.Dirty(DIRTY_SHADERBLEND);
return true;
}
@@ -125,13 +125,13 @@ inline void DrawEngineDX9::ResetShaderBlending() {
void DrawEngineDX9::ApplyDrawState(int prim) {
// TODO: All this setup is soon so expensive that we'll need dirty flags, or simply do it in the command writes where we detect dirty by xoring. Silly to do all this work on every drawcall.
if (gstate_c.textureChanged != TEXCHANGE_UNCHANGED && !gstate.isModeClear() && gstate.isTextureMapEnabled()) {
if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) {
textureCache_->SetTexture();
gstate_c.textureChanged = TEXCHANGE_UNCHANGED;
gstate_c.Clean(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS);
if (gstate_c.needShaderTexClamp) {
// We will rarely need to set this, so let's do it every time on use rather than in runloop.
// Most of the time non-framebuffer textures will be used which can be clamped themselves.
shaderManager_->DirtyUniform(DIRTY_TEXCLAMP);
gstate_c.Dirty(DIRTY_TEXCLAMP);
}
}
@@ -174,7 +174,7 @@ void DrawEngineDX9::ApplyDrawState(int prim) {
dxBlendFactorLookup[(size_t)blendState.srcColor], dxBlendFactorLookup[(size_t)blendState.dstColor],
dxBlendFactorLookup[(size_t)blendState.srcAlpha], dxBlendFactorLookup[(size_t)blendState.dstAlpha]);
if (blendState.dirtyShaderBlend) {
shaderManager_->DirtyUniform(DIRTY_SHADERBLEND);
gstate_c.Dirty(DIRTY_SHADERBLEND);
}
if (blendState.useBlendColor) {
dxstate.blendColor.setDWORD(blendState.blendColor);
@@ -297,10 +297,10 @@ void DrawEngineDX9::ApplyDrawState(int prim) {
dxstate.viewport.set(vpAndScissor.viewportX, vpAndScissor.viewportY, vpAndScissor.viewportW, vpAndScissor.viewportH, depthMin, depthMax);
if (vpAndScissor.dirtyProj) {
shaderManager_->DirtyUniform(DIRTY_PROJMATRIX);
gstate_c.Dirty(DIRTY_PROJMATRIX);
}
if (vpAndScissor.dirtyDepth) {
shaderManager_->DirtyUniform(DIRTY_DEPTHRANGE);
gstate_c.Dirty(DIRTY_DEPTHRANGE);
}
}
+2 -2
View File
@@ -127,7 +127,7 @@ void TextureCacheDX9::DeleteTexture(TexCache::iterator it) {
void TextureCacheDX9::ForgetLastTexture() {
lastBoundTexture = INVALID_TEX;
gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY;
gstate_c.Dirty(DIRTY_TEXTURE_PARAMS);
}
// Removes old textures.
@@ -931,7 +931,7 @@ void TextureCacheDX9::SetTexture(bool force) {
// Always rehash in this case, if one changed the rest all probably did.
rehash = true;
entry->status &= ~TexCacheEntry::STATUS_CLUT_RECHECK;
} else if ((gstate_c.textureChanged & TEXCHANGE_UPDATED) == 0) {
} else if (!gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE)) {
// Okay, just some parameter change - the data didn't change, no need to rehash.
rehash = false;
}
+1 -1
View File
@@ -337,7 +337,7 @@ void DrawEngineGLES::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, i
if (prim == GE_PRIM_RECTANGLES && (gstate.getTextureAddress(0) & 0x3FFFFFFF) == (gstate.getFrameBufAddress() & 0x3FFFFFFF)) {
// Rendertarget == texture?
if (!g_Config.bDisableSlowFramebufEffects) {
gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY;
gstate_c.Dirty(DIRTY_TEXTURE_PARAMS);
Flush();
}
}
+4 -4
View File
@@ -647,7 +647,7 @@ void FramebufferManagerGLES::NotifyRenderFramebufferCreated(VirtualFramebuffer *
// ugly...
if ((gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) && shaderManager_) {
shaderManager_->DirtyUniform(DIRTY_PROJTHROUGHMATRIX);
gstate_c.Dirty(DIRTY_PROJTHROUGHMATRIX);
}
}
@@ -710,7 +710,7 @@ void FramebufferManagerGLES::NotifyRenderFramebufferSwitched(VirtualFramebuffer
// ugly...
if ((gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) && shaderManager_) {
shaderManager_->DirtyUniform(DIRTY_PROJTHROUGHMATRIX);
gstate_c.Dirty(DIRTY_PROJTHROUGHMATRIX);
}
}
@@ -724,7 +724,7 @@ void FramebufferManagerGLES::NotifyRenderFramebufferUpdated(VirtualFramebuffer *
// ugly...
if ((gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) && shaderManager_) {
shaderManager_->DirtyUniform(DIRTY_PROJTHROUGHMATRIX);
gstate_c.Dirty(DIRTY_PROJTHROUGHMATRIX);
}
}
@@ -1962,7 +1962,7 @@ void FramebufferManagerGLES::FlushBeforeCopy() {
// TODO: It's really bad that we are calling SetRenderFramebuffer here with
// all the irrelevant state checking it'll use to decide what to do. Should
// do something more focused here.
SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason);
SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason);
transformDraw_->Flush();
}
+199 -866
View File
File diff suppressed because it is too large. Load diff
+3 -34
View File
@@ -41,7 +41,6 @@ public:
void CheckGPUFeatures();
void PreExecuteOp(u32 op, u32 diff) override;
void Execute_Generic(u32 op, u32 diff);
void ExecuteOp(u32 op, u32 diff) override;
void ReapplyGfxStateInternal() override;
@@ -82,7 +81,7 @@ public:
typedef void (GPU_GLES::*CmdFunc)(u32 op, u32 diff);
struct CommandInfo {
u8 flags;
uint64_t flags;
GPU_GLES::CmdFunc func;
};
@@ -91,45 +90,15 @@ public:
void Execute_Prim(u32 op, u32 diff);
void Execute_Bezier(u32 op, u32 diff);
void Execute_Spline(u32 op, u32 diff);
void Execute_LoadClut(u32 op, u32 diff);
void Execute_VertexType(u32 op, u32 diff);
void Execute_VertexTypeSkinning(u32 op, u32 diff);
void Execute_Region(u32 op, u32 diff);
void Execute_Scissor(u32 op, u32 diff);
void Execute_FramebufType(u32 op, u32 diff);
void Execute_ViewportType(u32 op, u32 diff);
void Execute_ViewportZType(u32 op, u32 diff);
void Execute_TexScaleU(u32 op, u32 diff);
void Execute_TexScaleV(u32 op, u32 diff);
void Execute_TexOffsetU(u32 op, u32 diff);
void Execute_TexOffsetV(u32 op, u32 diff);
void Execute_TexAddr0(u32 op, u32 diff);
void Execute_TexAddrN(u32 op, u32 diff);
void Execute_TexBufw0(u32 op, u32 diff);
void Execute_TexBufwN(u32 op, u32 diff);
void Execute_TexSize0(u32 op, u32 diff);
void Execute_TexSizeN(u32 op, u32 diff);
void Execute_TexFormat(u32 op, u32 diff);
void Execute_TexMapMode(u32 op, u32 diff);
void Execute_TexParamType(u32 op, u32 diff);
void Execute_TexEnvColor(u32 op, u32 diff);
void Execute_TexLevel(u32 op, u32 diff);
void Execute_LoadClut(u32 op, u32 diff);
void Execute_ClutFormat(u32 op, u32 diff);
void Execute_Ambient(u32 op, u32 diff);
void Execute_MaterialDiffuse(u32 op, u32 diff);
void Execute_MaterialEmissive(u32 op, u32 diff);
void Execute_MaterialAmbient(u32 op, u32 diff);
void Execute_MaterialSpecular(u32 op, u32 diff);
void Execute_Light0Param(u32 op, u32 diff);
void Execute_Light1Param(u32 op, u32 diff);
void Execute_Light2Param(u32 op, u32 diff);
void Execute_Light3Param(u32 op, u32 diff);
void Execute_FogColor(u32 op, u32 diff);
void Execute_FogCoef(u32 op, u32 diff);
void Execute_ColorTestMask(u32 op, u32 diff);
void Execute_AlphaTest(u32 op, u32 diff);
void Execute_StencilTest(u32 op, u32 diff);
void Execute_ColorRef(u32 op, u32 diff);
// Using string because it's generic - makes no assumptions on the size of the shader IDs of this backend.
std::vector<std::string> DebugGetShaderIDs(DebugShaderType shader) override;
+8 -7
View File
@@ -314,7 +314,7 @@ LinkedShader::LinkedShader(ShaderID VSID, Shader *vs, ShaderID FSID, Shader *fs,
glUniform1i(u_tess_col_tex, 5); // Texture unit 5
}
// The rest, use the "dirty" mechanism.
dirtyUniforms = DIRTY_ALL;
dirtyUniforms = DIRTY_ALL_UNIFORMS;
}
LinkedShader::~LinkedShader() {
@@ -772,7 +772,7 @@ void ShaderManagerGLES::Clear() {
linkedShaderCache_.clear();
fsCache_.clear();
vsCache_.clear();
globalDirty_ = DIRTY_ALL;
gstate_c.Dirty(DIRTY_ALL_UNIFORMS);
lastFSID_.set_invalid();
lastVSID_.set_invalid();
DirtyShader();
@@ -788,7 +788,7 @@ void ShaderManagerGLES::DirtyShader() {
lastFSID_.set_invalid();
lastVSID_.set_invalid();
DirtyLastShader();
globalDirty_ = DIRTY_ALL;
gstate_c.Dirty(DIRTY_ALL_UNIFORMS);
shaderSwitchDirty_ = 0;
}
@@ -813,11 +813,12 @@ Shader *ShaderManagerGLES::CompileVertexShader(ShaderID VSID) {
}
Shader *ShaderManagerGLES::ApplyVertexShader(int prim, u32 vertType, ShaderID *VSID) {
if (globalDirty_) {
uint64_t dirty = gstate_c.GetDirtyUniforms();
if (dirty) {
if (lastShader_)
lastShader_->dirtyUniforms |= globalDirty_;
shaderSwitchDirty_ |= globalDirty_;
globalDirty_ = 0;
lastShader_->dirtyUniforms |= dirty;
shaderSwitchDirty_ |= dirty;
gstate_c.CleanUniforms();
}
bool useHWTransform = CanUseHardwareTransform(prim);
+2 -2
View File
@@ -55,8 +55,8 @@ public:
bool useHWTransform_;
uint32_t program;
u64 availableUniforms;
u64 dirtyUniforms;
uint64_t availableUniforms;
uint64_t dirtyUniforms;
// Present attributes in the shader.
int attrMask; // 1 << ATTR_ ... or-ed together.
+14 -15
View File
@@ -144,7 +144,7 @@ bool DrawEngineGLES::ApplyShaderBlending() {
fboTexNeedBind_ = true;
shaderManager_->DirtyUniform(DIRTY_SHADERBLEND);
gstate_c.Dirty(DIRTY_SHADERBLEND);
return true;
}
@@ -157,16 +157,15 @@ inline void DrawEngineGLES::ResetShaderBlending() {
}
}
// TODO: All this setup is so expensive that we'll need dirty flags, or simply do it in the command writes where we detect dirty by xoring. Silly to do all this work on every drawcall.
void DrawEngineGLES::ApplyDrawState(int prim) {
// TODO: All this setup is so expensive that we'll need dirty flags, or simply do it in the command writes where we detect dirty by xoring. Silly to do all this work on every drawcall.
if (gstate_c.textureChanged != TEXCHANGE_UNCHANGED && !gstate.isModeClear() && gstate.isTextureMapEnabled()) {
if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) {
textureCache_->SetTexture();
gstate_c.textureChanged = TEXCHANGE_UNCHANGED;
gstate_c.Clean(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS);
if (gstate_c.needShaderTexClamp) {
// We will rarely need to set this, so let's do it every time on use rather than in runloop.
// Most of the time non-framebuffer textures will be used which can be clamped themselves.
shaderManager_->DirtyUniform(DIRTY_TEXCLAMP);
gstate_c.Dirty(DIRTY_TEXCLAMP);
}
}
@@ -174,18 +173,12 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
PROFILE_THIS_SCOPE("applydrawstate");
bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
gstate_c.allowShaderBlend = !g_Config.bDisableSlowFramebufEffects;
// Do the large chunks of state conversion. We might be able to hide these two behind a dirty-flag each,
// to avoid recomputing heavy stuff unnecessarily every draw call.
GenericBlendState blendState;
ConvertBlendState(blendState, gstate_c.allowShaderBlend);
ViewportAndScissor vpAndScissor;
ConvertViewportAndScissor(useBufferedRendering,
framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),
framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),
vpAndScissor);
if (blendState.applyShaderBlending) {
if (ApplyShaderBlending()) {
@@ -207,7 +200,7 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
glBlendFactorLookup[(size_t)blendState.srcColor], glBlendFactorLookup[(size_t)blendState.dstColor],
glBlendFactorLookup[(size_t)blendState.srcAlpha], glBlendFactorLookup[(size_t)blendState.dstAlpha]);
if (blendState.dirtyShaderBlend) {
shaderManager_->DirtyUniform(DIRTY_SHADERBLEND);
gstate_c.Dirty(DIRTY_SHADERBLEND);
}
if (blendState.useBlendColor) {
uint32_t color = blendState.blendColor;
@@ -351,6 +344,12 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
}
}
ViewportAndScissor vpAndScissor;
ConvertViewportAndScissor(useBufferedRendering,
framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),
framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),
vpAndScissor);
if (vpAndScissor.scissorEnable) {
glstate.scissorTest.enable();
if (!useBufferedRendering) {
@@ -368,10 +367,10 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
glstate.depthRange.set(vpAndScissor.depthRangeMin, vpAndScissor.depthRangeMax);
if (vpAndScissor.dirtyProj) {
shaderManager_->DirtyUniform(DIRTY_PROJMATRIX);
gstate_c.Dirty(DIRTY_PROJMATRIX);
}
if (vpAndScissor.dirtyDepth) {
shaderManager_->DirtyUniform(DIRTY_DEPTHRANGE);
gstate_c.Dirty(DIRTY_DEPTHRANGE);
}
}
+1 -1
View File
@@ -1034,7 +1034,7 @@ void TextureCacheGLES::SetTexture(bool force) {
// Always rehash in this case, if one changed the rest all probably did.
rehash = true;
entry->status &= ~TexCacheEntry::STATUS_CLUT_RECHECK;
} else if ((gstate_c.textureChanged & TEXCHANGE_UPDATED) == 0) {
} else if (!gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE)) {
// Okay, just some parameter change - the data didn't change, no need to rehash.
rehash = false;
}
+1 -1
View File
@@ -75,7 +75,7 @@ public:
void ForgetLastTexture() {
lastBoundTexture = -1;
gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY;
gstate_c.Dirty(DIRTY_TEXTURE_PARAMS);
}
u32 AllocTextureName();
+104 -16
View File
@@ -4,6 +4,7 @@
#include "base/mutex.h"
#include "base/timeutil.h"
#include "Common/ColorConv.h"
#include "Core/Reporting.h"
#include "GPU/GeDisasm.h"
#include "GPU/GPU.h"
#include "GPU/GPUCommon.h"
@@ -787,7 +788,8 @@ void GPUCommon::ProcessDLQueueInternal() {
UpdateTickEstimate(std::max(busyTicks, startingTicks + cyclesExecuted));
// Game might've written new texture data.
gstate_c.textureChanged = TEXCHANGE_UPDATED;
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
gstate_c.Dirty(DIRTY_TEXTURE_PARAMS);
// Seems to be correct behaviour to process the list anyway?
if (startingTicks < busyTicks) {
@@ -1071,7 +1073,7 @@ void GPUCommon::Execute_End(u32 op, u32 diff) {
void GPUCommon::Execute_Bezier(u32 op, u32 diff) {
// This also make skipping drawing very effective.
framebufferManager_->SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason);
framebufferManager_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason);
if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) {
// TODO: Should this eat some cycles? Probably yes. Not sure if important.
return;
@@ -1114,7 +1116,7 @@ void GPUCommon::Execute_Bezier(u32 op, u32 diff) {
void GPUCommon::Execute_Spline(u32 op, u32 diff) {
// This also make skipping drawing very effective.
framebufferManager_->SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason);
framebufferManager_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason);
if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) {
// TODO: Should this eat some cycles? Probably yes. Not sure if important.
return;
@@ -1193,7 +1195,7 @@ void GPUCommon::Execute_BlockTransferStart(u32 op, u32 diff) {
DoBlockTransfer(gstate_c.skipDrawReason);
// Fixes Gran Turismo's funky text issue, since it overwrites the current texture.
gstate_c.textureChanged = TEXCHANGE_UPDATED;
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
}
void GPUCommon::Execute_WorldMtxNum(u32 op, u32 diff) {
@@ -1208,7 +1210,7 @@ void GPUCommon::Execute_WorldMtxNum(u32 op, u32 diff) {
if (dst[i] != newVal) {
Flush();
dst[i] = newVal;
shaderManager_->DirtyUniform(DIRTY_WORLDMATRIX);
gstate_c.Dirty(DIRTY_WORLDMATRIX);
}
if (++i >= end) {
break;
@@ -1230,7 +1232,7 @@ void GPUCommon::Execute_WorldMtxData(u32 op, u32 diff) {
if (num < 12 && newVal != ((const u32 *)gstate.worldMatrix)[num]) {
Flush();
((u32 *)gstate.worldMatrix)[num] = newVal;
shaderManager_->DirtyUniform(DIRTY_WORLDMATRIX);
gstate_c.Dirty(DIRTY_WORLDMATRIX);
}
num++;
gstate.worldmtxnum = (GE_CMD_WORLDMATRIXNUMBER << 24) | (num & 0xF);
@@ -1248,7 +1250,7 @@ void GPUCommon::Execute_ViewMtxNum(u32 op, u32 diff) {
if (dst[i] != newVal) {
Flush();
dst[i] = newVal;
shaderManager_->DirtyUniform(DIRTY_VIEWMATRIX);
gstate_c.Dirty(DIRTY_VIEWMATRIX);
}
if (++i >= end) {
break;
@@ -1270,7 +1272,7 @@ void GPUCommon::Execute_ViewMtxData(u32 op, u32 diff) {
if (num < 12 && newVal != ((const u32 *)gstate.viewMatrix)[num]) {
Flush();
((u32 *)gstate.viewMatrix)[num] = newVal;
shaderManager_->DirtyUniform(DIRTY_VIEWMATRIX);
gstate_c.Dirty(DIRTY_VIEWMATRIX);
}
num++;
gstate.viewmtxnum = (GE_CMD_VIEWMATRIXNUMBER << 24) | (num & 0xF);
@@ -1288,7 +1290,7 @@ void GPUCommon::Execute_ProjMtxNum(u32 op, u32 diff) {
if (dst[i] != newVal) {
Flush();
dst[i] = newVal;
shaderManager_->DirtyUniform(DIRTY_PROJMATRIX);
gstate_c.Dirty(DIRTY_PROJMATRIX);
}
if (++i >= end) {
break;
@@ -1310,7 +1312,7 @@ void GPUCommon::Execute_ProjMtxData(u32 op, u32 diff) {
if (newVal != ((const u32 *)gstate.projMatrix)[num]) {
Flush();
((u32 *)gstate.projMatrix)[num] = newVal;
shaderManager_->DirtyUniform(DIRTY_PROJMATRIX);
gstate_c.Dirty(DIRTY_PROJMATRIX);
}
num++;
gstate.projmtxnum = (GE_CMD_PROJMATRIXNUMBER << 24) | (num & 0xF);
@@ -1328,7 +1330,7 @@ void GPUCommon::Execute_TgenMtxNum(u32 op, u32 diff) {
if (dst[i] != newVal) {
Flush();
dst[i] = newVal;
shaderManager_->DirtyUniform(DIRTY_TEXMATRIX);
gstate_c.Dirty(DIRTY_TEXMATRIX);
}
if (++i >= end) {
break;
@@ -1350,7 +1352,7 @@ void GPUCommon::Execute_TgenMtxData(u32 op, u32 diff) {
if (num < 12 && newVal != ((const u32 *)gstate.tgenMatrix)[num]) {
Flush();
((u32 *)gstate.tgenMatrix)[num] = newVal;
shaderManager_->DirtyUniform(DIRTY_TEXMATRIX);
gstate_c.Dirty(DIRTY_TEXMATRIX);
}
num++;
gstate.texmtxnum = (GE_CMD_TGENMATRIXNUMBER << 24) | (num & 0xF);
@@ -1378,7 +1380,7 @@ void GPUCommon::Execute_BoneMtxNum(u32 op, u32 diff) {
const int numPlusCount = (op & 0x7F) + i;
for (int num = op & 0x7F; num < numPlusCount; num += 12) {
shaderManager_->DirtyUniform(DIRTY_BONEMATRIX0 << (num / 12));
gstate_c.Dirty(DIRTY_BONEMATRIX0 << (num / 12));
}
} else {
while ((src[i] >> 24) == GE_CMD_BONEMATRIXDATA) {
@@ -1410,7 +1412,7 @@ void GPUCommon::Execute_BoneMtxData(u32 op, u32 diff) {
// Bone matrices should NOT flush when software skinning is enabled!
if (!g_Config.bSoftwareSkinning || (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) != 0) {
Flush();
shaderManager_->DirtyUniform(DIRTY_BONEMATRIX0 << (num / 12));
gstate_c.Dirty(DIRTY_BONEMATRIX0 << (num / 12));
} else {
gstate_c.deferredVertTypeDirty |= DIRTY_BONEMATRIX0 << (num / 12);
}
@@ -1420,6 +1422,10 @@ void GPUCommon::Execute_BoneMtxData(u32 op, u32 diff) {
gstate.boneMatrixNumber = (GE_CMD_BONEMATRIXNUMBER << 24) | (num & 0x7F);
}
void GPUCommon::Execute_MorphWeight(u32 op, u32 diff) {
gstate_c.morphWeights[(op >> 24) - GE_CMD_MORPHWEIGHT0] = getFloat24(op);
}
void GPUCommon::ExecuteOp(u32 op, u32 diff) {
const u32 cmd = op >> 24;
@@ -1462,7 +1468,89 @@ void GPUCommon::ExecuteOp(u32 op, u32 diff) {
break;
default:
DEBUG_LOG(G3D,"DL Unknown: %08x @ %08x", op, currentList == NULL ? 0 : currentList->pc);
DEBUG_LOG(G3D, "DL Unknown: %08x @ %08x", op, currentList == NULL ? 0 : currentList->pc);
break;
}
}
void GPUCommon::Execute_Unknown(u32 op, u32 diff) {
switch (op >> 24) {
case GE_CMD_VSCX:
if ((op & 0xFFFFFF) != 0)
WARN_LOG_REPORT_ONCE(vscx, G3D, "Unsupported Vertex Screen Coordinate X : %06x", op);
break;
case GE_CMD_VSCY:
if ((op & 0xFFFFFF) != 0)
WARN_LOG_REPORT_ONCE(vscy, G3D, "Unsupported Vertex Screen Coordinate Y : %06x", op);
break;
case GE_CMD_VSCZ:
if ((op & 0xFFFFFF) != 0)
WARN_LOG_REPORT_ONCE(vscz, G3D, "Unsupported Vertex Screen Coordinate Z : %06x", op);
break;
case GE_CMD_VTCS:
if ((op & 0xFFFFFF) != 0)
WARN_LOG_REPORT_ONCE(vtcs, G3D, "Unsupported Vertex Texture Coordinate S : %06x", op);
break;
case GE_CMD_VTCT:
if ((op & 0xFFFFFF) != 0)
WARN_LOG_REPORT_ONCE(vtct, G3D, "Unsupported Vertex Texture Coordinate T : %06x", op);
break;
case GE_CMD_VTCQ:
if ((op & 0xFFFFFF) != 0)
WARN_LOG_REPORT_ONCE(vtcq, G3D, "Unsupported Vertex Texture Coordinate Q : %06x", op);
break;
case GE_CMD_VCV:
if ((op & 0xFFFFFF) != 0)
WARN_LOG_REPORT_ONCE(vcv, G3D, "Unsupported Vertex Color Value : %06x", op);
break;
case GE_CMD_VAP:
if ((op & 0xFFFFFF) != 0)
WARN_LOG_REPORT_ONCE(vap, G3D, "Unsupported Vertex Alpha and Primitive : %06x", op);
break;
case GE_CMD_VFC:
if ((op & 0xFFFFFF) != 0)
WARN_LOG_REPORT_ONCE(vfc, G3D, "Unsupported Vertex Fog Coefficient : %06x", op);
break;
case GE_CMD_VSCV:
if ((op & 0xFFFFFF) != 0)
WARN_LOG_REPORT_ONCE(vscv, G3D, "Unsupported Vertex Secondary Color Value : %06x", op);
break;
case GE_CMD_UNKNOWN_03:
case GE_CMD_UNKNOWN_0D:
case GE_CMD_UNKNOWN_11:
case GE_CMD_UNKNOWN_29:
case GE_CMD_UNKNOWN_34:
case GE_CMD_UNKNOWN_35:
case GE_CMD_UNKNOWN_39:
case GE_CMD_UNKNOWN_4E:
case GE_CMD_UNKNOWN_4F:
case GE_CMD_UNKNOWN_52:
case GE_CMD_UNKNOWN_59:
case GE_CMD_UNKNOWN_5A:
case GE_CMD_UNKNOWN_B6:
case GE_CMD_UNKNOWN_B7:
case GE_CMD_UNKNOWN_D1:
case GE_CMD_UNKNOWN_ED:
case GE_CMD_UNKNOWN_EF:
case GE_CMD_UNKNOWN_FA:
case GE_CMD_UNKNOWN_FB:
case GE_CMD_UNKNOWN_FC:
case GE_CMD_UNKNOWN_FD:
case GE_CMD_UNKNOWN_FE:
if ((op & 0xFFFFFF) != 0)
WARN_LOG_REPORT_ONCE(unknowncmd, G3D, "Unknown GE command : %08x ", op);
break;
default:
break;
}
}
@@ -1477,7 +1565,7 @@ void GPUCommon::FastLoadBoneMatrix(u32 target) {
if (!g_Config.bSoftwareSkinning || (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) != 0) {
Flush();
shaderManager_->DirtyUniform(uniformsToDirty);
gstate_c.Dirty(uniformsToDirty);
} else {
gstate_c.deferredVertTypeDirty |= uniformsToDirty;
}
+5
View File
@@ -39,6 +39,7 @@ public:
void ExecuteOp(u32 op, u32 diff) override;
void PreExecuteOp(u32 op, u32 diff) override;
bool InterpretList(DisplayList &list) override;
virtual bool ProcessDLQueue();
u32 UpdateStall(int listid, u32 newstall) override;
@@ -96,6 +97,10 @@ public:
void Execute_BoneMtxNum(u32 op, u32 diff);
void Execute_BoneMtxData(u32 op, u32 diff);
void Execute_MorphWeight(u32 op, u32 diff);
void Execute_Unknown(u32 op, u32 diff);
int EstimatePerVertexCost();
// Note: Not virtual!
+7 -6
View File
@@ -216,10 +216,9 @@ void GPUStateCache::DoState(PointerWrap &p) {
vertexAddr = old.vertexAddr;
indexAddr = old.indexAddr;
offsetAddr = old.offsetAddr;
textureChanged = TEXCHANGE_UPDATED;
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS);
textureFullAlpha = old.textureFullAlpha;
vertexFullAlpha = old.vertexFullAlpha;
framebufChanged = old.framebufChanged;
skipDrawReason = old.skipDrawReason;
uv = old.uv;
} else {
@@ -227,18 +226,20 @@ void GPUStateCache::DoState(PointerWrap &p) {
p.Do(indexAddr);
p.Do(offsetAddr);
p.Do(textureChanged);
uint8_t textureChanged = 0;
p.Do(textureChanged); // legacy
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS);
p.Do(textureFullAlpha);
p.Do(vertexFullAlpha);
bool framebufChanged = false; // legacy
p.Do(framebufChanged);
p.Do(skipDrawReason);
p.Do(uv);
// No longer relevant. Remove when creating the next version.
bool oldFlipTexture;
p.Do(oldFlipTexture);
bool oldFlipTexture = false;
p.Do(oldFlipTexture); // legacy
}
// needShaderTexClamp and bgraTexture don't need to be saved.
+24 -16
View File
@@ -23,6 +23,7 @@
#include "GPU/GPU.h"
#include "GPU/ge_constants.h"
#include "Common/Common.h"
#include "GPU/Common/ShaderCommon.h"
class PointerWrap;
@@ -440,12 +441,6 @@ struct UVScale {
float uOff, vOff;
};
enum TextureChangeReason {
TEXCHANGE_UNCHANGED = 0x00,
TEXCHANGE_UPDATED = 0x01,
TEXCHANGE_PARAMSONLY = 0x02,
};
#define FLAG_BIT(x) (1 << x)
// Some of these are OpenGL-specific even though this file is neutral, unfortunately.
@@ -487,6 +482,19 @@ struct KnownVertexBounds {
struct GPUStateCache {
bool Supports(int flag) { return (featureFlags & flag) != 0; }
uint64_t GetDirtyUniforms() { return dirty & DIRTY_ALL_UNIFORMS; }
void Dirty(u64 what) {
dirty |= what;
}
void CleanUniforms() {
dirty &= ~DIRTY_ALL_UNIFORMS;
}
void Clean(u64 what) {
dirty &= ~what;
}
bool IsDirty(u64 what) const {
return (dirty & what) != 0ULL;
}
u32 featureFlags;
@@ -494,24 +502,16 @@ struct GPUStateCache {
u32 indexAddr;
u32 offsetAddr;
u8 textureChanged;
uint64_t dirty;
bool textureFullAlpha;
bool textureSimpleAlpha;
bool vertexFullAlpha;
bool framebufChanged;
int skipDrawReason;
UVScale uv;
bool bezier;
bool spline;
int bezier_count_u;
int spline_count_u;
int spline_count_v;
int spline_type_u;
int spline_type_v;
bool bgraTexture;
bool needShaderTexClamp;
bool allowShaderBlend;
@@ -545,6 +545,14 @@ struct GPUStateCache {
u32 curRTRenderHeight;
u32 curRTOffsetX;
bool bezier;
bool spline;
int bezier_count_u;
int spline_count_u;
int spline_count_v;
int spline_type_u;
int spline_type_v;
u32 getRelativeAddress(u32 data) const;
void Reset();
void DoState(PointerWrap &p);
+3 -3
View File
@@ -214,7 +214,7 @@ void NullGPU::ExecuteOp(u32 op, u32 diff) {
break;
case GE_CMD_TEXADDR0:
gstate_c.textureChanged = TEXCHANGE_UPDATED;
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
case GE_CMD_TEXADDR1:
case GE_CMD_TEXADDR2:
case GE_CMD_TEXADDR3:
@@ -226,7 +226,7 @@ void NullGPU::ExecuteOp(u32 op, u32 diff) {
break;
case GE_CMD_TEXBUFWIDTH0:
gstate_c.textureChanged = TEXCHANGE_UPDATED;
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
case GE_CMD_TEXBUFWIDTH1:
case GE_CMD_TEXBUFWIDTH2:
case GE_CMD_TEXBUFWIDTH3:
@@ -342,7 +342,7 @@ void NullGPU::ExecuteOp(u32 op, u32 diff) {
}
case GE_CMD_TEXSIZE0:
gstate_c.textureChanged = TEXCHANGE_UPDATED;
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
gstate_c.curTextureWidth = 1 << (gstate.texsize[0] & 0xf);
gstate_c.curTextureHeight = 1 << ((gstate.texsize[0]>>8) & 0xf);
//fall thru - ignoring the mipmap sizes for now
+5 -5
View File
@@ -361,7 +361,7 @@ void DrawEngineVulkan::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim,
if (prim == GE_PRIM_RECTANGLES && (gstate.getTextureAddress(0) & 0x3FFFFFFF) == (gstate.getFrameBufAddress() & 0x3FFFFFFF)) {
// Rendertarget == texture?
if (!g_Config.bDisableSlowFramebufEffects) {
gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY;
gstate_c.Dirty(DIRTY_TEXTURE_PARAMS);
Flush(cmd_);
}
}
@@ -600,7 +600,7 @@ void DrawEngineVulkan::DirtyAllUBOs() {
dirtyUniforms_ = DIRTY_BASE_UNIFORMS | DIRTY_LIGHT_UNIFORMS | DIRTY_BONE_UNIFORMS;
imageView = VK_NULL_HANDLE;
sampler = VK_NULL_HANDLE;
gstate_c.textureChanged = TEXCHANGE_UPDATED;
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
}
//void DrawEngineVulkan::ApplyDrawStateLate() {
@@ -630,14 +630,14 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) {
FrameData *frame = &frame_[curFrame_ & 1];
bool textureNeedsApply = false;
if (gstate_c.textureChanged != TEXCHANGE_UNCHANGED && !gstate.isModeClear() && gstate.isTextureMapEnabled()) {
if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) {
textureCache_->SetTexture();
gstate_c.Clean(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS);
textureNeedsApply = true;
gstate_c.textureChanged = TEXCHANGE_UNCHANGED;
if (gstate_c.needShaderTexClamp) {
// We will rarely need to set this, so let's do it every time on use rather than in runloop.
// Most of the time non-framebuffer textures will be used which can be clamped themselves.
shaderManager_->DirtyUniform(DIRTY_TEXCLAMP);
gstate_c.Dirty(DIRTY_TEXCLAMP);
}
}
+1 -1
View File
@@ -220,7 +220,7 @@ private:
enum { MAX_DEFERRED_DRAW_CALLS = 128 };
// State cache
uint32_t dirtyUniforms_;
uint64_t dirtyUniforms_;
uint32_t baseUBOOffset;
uint32_t lightUBOOffset;
uint32_t boneUBOOffset;
+4 -4
View File
@@ -646,7 +646,7 @@ void FramebufferManagerVulkan::NotifyRenderFramebufferCreated(VirtualFramebuffer
textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_CREATED);
// ugly...
if ((gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) && shaderManager_) {
shaderManager_->DirtyUniform(DIRTY_PROJMATRIX);
gstate_c.Dirty(DIRTY_PROJMATRIX);
}
}
@@ -695,7 +695,7 @@ void FramebufferManagerVulkan::NotifyRenderFramebufferSwitched(VirtualFramebuffe
// ugly...
if ((gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) && shaderManager_) {
shaderManager_->DirtyUniform(DIRTY_PROJMATRIX);
gstate_c.Dirty(DIRTY_PROJMATRIX);
}
}
@@ -709,7 +709,7 @@ void FramebufferManagerVulkan::NotifyRenderFramebufferUpdated(VirtualFramebuffer
// ugly...
if ((gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) && shaderManager_) {
shaderManager_->DirtyUniform(DIRTY_PROJMATRIX);
gstate_c.Dirty(DIRTY_PROJMATRIX);
}
}
@@ -1628,7 +1628,7 @@ void FramebufferManagerVulkan::FlushBeforeCopy() {
// TODO: It's really bad that we are calling SetRenderFramebuffer here with
// all the irrelevant state checking it'll use to decide what to do. Should
// do something more focused here.
SetRenderFrameBuffer(gstate_c.framebufChanged, gstate_c.skipDrawReason);
SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason);
drawEngine_->Flush(curCmd_);
}
+192 -861
View File
File diff suppressed because it is too large. Load diff
+1 -33
View File
@@ -43,7 +43,6 @@ public:
void EndHostFrame() override;
void PreExecuteOp(u32 op, u32 diff) override;
void Execute_Generic(u32 op, u32 diff);
void ExecuteOp(u32 op, u32 diff) override;
void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) override;
@@ -70,7 +69,7 @@ public:
typedef void (GPU_Vulkan::*CmdFunc)(u32 op, u32 diff);
struct CommandInfo {
u8 flags;
uint64_t flags;
GPU_Vulkan::CmdFunc func;
};
@@ -80,43 +79,12 @@ public:
void Execute_Bezier(u32 op, u32 diff);
void Execute_Spline(u32 op, u32 diff);
void Execute_VertexType(u32 op, u32 diff);
void Execute_Region(u32 op, u32 diff);
void Execute_Scissor(u32 op, u32 diff);
void Execute_FramebufType(u32 op, u32 diff);
void Execute_ViewportType(u32 op, u32 diff);
void Execute_ViewportZType(u32 op, u32 diff);
void Execute_TexScaleU(u32 op, u32 diff);
void Execute_TexScaleV(u32 op, u32 diff);
void Execute_TexOffsetU(u32 op, u32 diff);
void Execute_TexOffsetV(u32 op, u32 diff);
void Execute_TexAddr0(u32 op, u32 diff);
void Execute_TexAddrN(u32 op, u32 diff);
void Execute_TexBufw0(u32 op, u32 diff);
void Execute_TexBufwN(u32 op, u32 diff);
void Execute_TexSize0(u32 op, u32 diff);
void Execute_TexSizeN(u32 op, u32 diff);
void Execute_TexFormat(u32 op, u32 diff);
void Execute_TexMapMode(u32 op, u32 diff);
void Execute_TexParamType(u32 op, u32 diff);
void Execute_TexEnvColor(u32 op, u32 diff);
void Execute_TexLevel(u32 op, u32 diff);
void Execute_LoadClut(u32 op, u32 diff);
void Execute_ClutFormat(u32 op, u32 diff);
void Execute_Ambient(u32 op, u32 diff);
void Execute_MaterialDiffuse(u32 op, u32 diff);
void Execute_MaterialEmissive(u32 op, u32 diff);
void Execute_MaterialAmbient(u32 op, u32 diff);
void Execute_MaterialSpecular(u32 op, u32 diff);
void Execute_Light0Param(u32 op, u32 diff);
void Execute_Light1Param(u32 op, u32 diff);
void Execute_Light2Param(u32 op, u32 diff);
void Execute_Light3Param(u32 op, u32 diff);
void Execute_FogColor(u32 op, u32 diff);
void Execute_FogCoef(u32 op, u32 diff);
void Execute_ColorTestMask(u32 op, u32 diff);
void Execute_AlphaTest(u32 op, u32 diff);
void Execute_StencilTest(u32 op, u32 diff);
void Execute_ColorRef(u32 op, u32 diff);
void Execute_BoneMtxNum(u32 op, u32 diff);
void Execute_BoneMtxData(u32 op, u32 diff);
+14 -11
View File
@@ -187,7 +187,7 @@ uint32_t ShaderManagerVulkan::PushBoneBuffer(VulkanPushBuffer *dest, VkBuffer *b
return dest->PushAligned(&ub_bones, sizeof(ub_bones), uboAlignment_, buf);
}
void ShaderManagerVulkan::BaseUpdateUniforms(int dirtyUniforms) {
void ShaderManagerVulkan::BaseUpdateUniforms(uint64_t dirtyUniforms) {
if (dirtyUniforms & DIRTY_TEXENV) {
Uint8x3ToFloat4(ub_base.texEnvColor, gstate.texenvcolor);
}
@@ -337,7 +337,7 @@ void ShaderManagerVulkan::BaseUpdateUniforms(int dirtyUniforms) {
}
}
void ShaderManagerVulkan::LightUpdateUniforms(int dirtyUniforms) {
void ShaderManagerVulkan::LightUpdateUniforms(uint64_t dirtyUniforms) {
// Lighting
if (dirtyUniforms & DIRTY_AMBIENT) {
Uint8x3ToFloat4_AlphaUint8(ub_lights.ambientColor, gstate.ambientcolor, gstate.getAmbientA());
@@ -380,7 +380,7 @@ void ShaderManagerVulkan::LightUpdateUniforms(int dirtyUniforms) {
}
}
void ShaderManagerVulkan::BoneUpdateUniforms(int dirtyUniforms) {
void ShaderManagerVulkan::BoneUpdateUniforms(uint64_t dirtyUniforms) {
for (int i = 0; i < 8; i++) {
if (dirtyUniforms & (DIRTY_BONEMATRIX0 << i)) {
ConvertMatrix4x3To4x4(ub_bones.bones[i], gstate.boneMatrix + 12 * i);
@@ -409,7 +409,7 @@ void ShaderManagerVulkan::Clear() {
void ShaderManagerVulkan::ClearShaders() {
Clear();
DirtyShader();
DirtyUniform(0xFFFFFFFF);
gstate_c.Dirty(DIRTY_ALL_UNIFORMS);
}
void ShaderManagerVulkan::DirtyShader() {
@@ -425,14 +425,17 @@ void ShaderManagerVulkan::DirtyLastShader() { // disables vertex arrays
lastFShader_ = nullptr;
}
uint32_t ShaderManagerVulkan::UpdateUniforms() {
uint32_t dirty = globalDirty_;
if (globalDirty_) {
BaseUpdateUniforms(dirty);
LightUpdateUniforms(dirty);
BoneUpdateUniforms(dirty);
uint64_t ShaderManagerVulkan::UpdateUniforms() {
uint64_t dirty = gstate_c.GetDirtyUniforms();
if (dirty != 0) {
if (dirty & DIRTY_BASE_UNIFORMS)
BaseUpdateUniforms(dirty);
if (dirty & DIRTY_LIGHT_UNIFORMS)
LightUpdateUniforms(dirty);
if (dirty & DIRTY_BONE_UNIFORMS)
BoneUpdateUniforms(dirty);
}
globalDirty_ = 0;
gstate_c.CleanUniforms();
return dirty;
}
+4 -4
View File
@@ -202,7 +202,7 @@ public:
std::vector<std::string> DebugGetShaderIDs(DebugShaderType type);
std::string DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType);
uint32_t UpdateUniforms();
uint64_t UpdateUniforms();
// TODO: Avoid copying these buffers if same as last draw, can still point to it assuming we're still in the same pushbuffer.
// Applies dirty changes and copies the buffer.
@@ -215,9 +215,9 @@ public:
uint32_t PushBoneBuffer(VulkanPushBuffer *dest, VkBuffer *buf);
private:
void BaseUpdateUniforms(int dirtyUniforms);
void LightUpdateUniforms(int dirtyUniforms);
void BoneUpdateUniforms(int dirtyUniforms);
void BaseUpdateUniforms(uint64_t dirtyUniforms);
void LightUpdateUniforms(uint64_t dirtyUniforms);
void BoneUpdateUniforms(uint64_t dirtyUniforms);
void Clear();
+3 -3
View File
@@ -171,7 +171,7 @@ void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, ShaderManagerV
key.destColor = vkBlendFactorLookup[(size_t)blendState.dstColor];
key.destAlpha = vkBlendFactorLookup[(size_t)blendState.dstAlpha];
if (blendState.dirtyShaderBlend) {
shaderManager->DirtyUniform(DIRTY_SHADERBLEND);
gstate_c.Dirty(DIRTY_SHADERBLEND);
}
dynState.useBlendColor = blendState.useBlendColor;
if (blendState.useBlendColor) {
@@ -310,7 +310,7 @@ void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, ShaderManagerV
vp.minDepth = vpAndScissor.depthRangeMin;
vp.maxDepth = vpAndScissor.depthRangeMax;
if (vpAndScissor.dirtyProj) {
shaderManager->DirtyUniform(DIRTY_PROJMATRIX);
gstate_c.Dirty(DIRTY_PROJMATRIX);
}
VkRect2D &scissor = dynState.scissor;
@@ -325,6 +325,6 @@ void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, ShaderManagerV
if (depthMin < 0.0f) depthMin = 0.0f;
if (depthMax > 1.0f) depthMax = 1.0f;
if (vpAndScissor.dirtyDepth) {
shaderManager->DirtyUniform(DIRTY_DEPTHRANGE);
gstate_c.Dirty(DIRTY_DEPTHRANGE);
}
}
+1 -1
View File
@@ -968,7 +968,7 @@ void TextureCacheVulkan::SetTexture() {
// Always rehash in this case, if one changed the rest all probably did.
rehash = true;
entry->status &= ~TexCacheEntry::STATUS_CLUT_RECHECK;
} else if ((gstate_c.textureChanged & TEXCHANGE_UPDATED) == 0) {
} else if (!gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE)) {
// Okay, just some parameter change - the data didn't change, no need to rehash.
rehash = false;
}
+1 -1
View File
@@ -121,7 +121,7 @@ public:
void ForgetLastTexture() {
lastBoundTexture = nullptr;
gstate_c.textureChanged |= TEXCHANGE_PARAMSONLY;
gstate_c.Dirty(DIRTY_TEXTURE_PARAMS);
}
void ApplyTexture(VulkanPushBuffer *uploadBuffer, VkImageView &imageView, VkSampler &sampler);
+18 -19
View File
@@ -17,8 +17,7 @@
#pragma once
enum GECommand
{
enum GECommand {
GE_CMD_NOP = 0,
GE_CMD_VADDR = 0x1,
GE_CMD_IADDR = 0x2,
@@ -42,13 +41,13 @@ enum GECommand
GE_CMD_LIGHTINGENABLE = 0x17,
GE_CMD_LIGHTENABLE0 = 0x18,
GE_CMD_LIGHTENABLE1 = 0x19,
GE_CMD_LIGHTENABLE2 = 0x1a,
GE_CMD_LIGHTENABLE3 = 0x1b,
GE_CMD_CLIPENABLE = 0x1c,
GE_CMD_CULLFACEENABLE,
GE_CMD_TEXTUREMAPENABLE,
GE_CMD_FOGENABLE,
GE_CMD_DITHERENABLE,
GE_CMD_LIGHTENABLE2 = 0x1A,
GE_CMD_LIGHTENABLE3 = 0x1B,
GE_CMD_CLIPENABLE = 0x1C,
GE_CMD_CULLFACEENABLE = 0x1D,
GE_CMD_TEXTUREMAPENABLE = 0x1E,
GE_CMD_FOGENABLE = 0x1F,
GE_CMD_DITHERENABLE = 0x20,
GE_CMD_ALPHABLENDENABLE = 0x21,
GE_CMD_ALPHATESTENABLE = 0x22,
GE_CMD_ZTESTENABLE = 0x23,
@@ -71,14 +70,14 @@ enum GECommand
GE_CMD_PATCHPRIMITIVE = 0x37,
GE_CMD_PATCHFACING = 0x38,
GE_CMD_WORLDMATRIXNUMBER = 0x3A,
GE_CMD_WORLDMATRIXDATA,
GE_CMD_VIEWMATRIXNUMBER,
GE_CMD_VIEWMATRIXDATA,
GE_CMD_PROJMATRIXNUMBER,
GE_CMD_PROJMATRIXDATA,
GE_CMD_WORLDMATRIXDATA = 0x3B,
GE_CMD_VIEWMATRIXNUMBER = 0x3C,
GE_CMD_VIEWMATRIXDATA = 0x3D,
GE_CMD_PROJMATRIXNUMBER = 0x3E,
GE_CMD_PROJMATRIXDATA = 0x3F,
GE_CMD_TGENMATRIXNUMBER = 0x40,
GE_CMD_TGENMATRIXDATA = 0x41,
GE_CMD_VIEWPORTXSCALE,
GE_CMD_VIEWPORTXSCALE = 0x42,
GE_CMD_VIEWPORTYSCALE,
GE_CMD_VIEWPORTZSCALE,
GE_CMD_VIEWPORTXCENTER,
@@ -93,14 +92,14 @@ enum GECommand
GE_CMD_SHADEMODE = 0x50, // flat or gouraud
GE_CMD_REVERSENORMAL = 0x51,
GE_CMD_MATERIALUPDATE = 0x53,
GE_CMD_MATERIALEMISSIVE, //not sure about these but this makes sense
GE_CMD_MATERIALAMBIENT, //gotta try enabling lighting and check :)
GE_CMD_MATERIALEMISSIVE = 0x54, //not sure about these but this makes sense
GE_CMD_MATERIALAMBIENT = 0x55, //gotta try enabling lighting and check :)
GE_CMD_MATERIALDIFFUSE = 0x56,
GE_CMD_MATERIALSPECULAR = 0x57,
GE_CMD_MATERIALALPHA = 0x58,
GE_CMD_MATERIALSPECULARCOEF = 0x5B,
GE_CMD_AMBIENTCOLOR,
GE_CMD_AMBIENTALPHA,
GE_CMD_AMBIENTCOLOR = 0x5C,
GE_CMD_AMBIENTALPHA = 0x5D,
GE_CMD_LIGHTMODE = 0x5E,
GE_CMD_LIGHTTYPE0 = 0x5F,
GE_CMD_LIGHTTYPE1 = 0x60,