Reshuffle so that SetTexture and ApplyTexture are always called together (will merge them later)

This commit is contained in:
Henrik Rydgård committed 2026-07-16 18:23:58 +02:00
1 parent 7c73ed71bf
commit b4d1b3d469
4 files changed
+69 -51

No files matched your search

+20 -15
View File
@@ -269,15 +269,6 @@ void DrawEngineD3D11::Flush() {
if (!numDrawVerts_) {
return;
}
bool textureNeedsApply = false;
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;
} else if (gstate.getTextureAddress(0) == (gstate.getFrameBufRawAddress() | 0x04000000)) {
// This catches the case of clearing a texture. (#10957)
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
}
// This is not done on every drawcall, we collect vertex data
// until critical state changes. That's when we draw (flush).
@@ -325,13 +316,15 @@ void DrawEngineD3D11::Flush() {
gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && ((hasColor && (gstate.materialupdate & 1)) || gstate.getMaterialAmbientA() == 255) && (!gstate.isLightingEnabled() || gstate.getAmbientA() == 255);
}
if (textureNeedsApply) {
gstate_c.dstSquared = false;
bool textureNeedsApply = false;
if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) {
gstate_c.Clean(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS);
textureCache_->SetTexture();
TextureApplyResult textureResult = textureCache_->ApplyTexture(true);
textureCache_->ApplySampler(textureResult, clipInfoFlags_ & ClipInfoFlags::FlatZ, false);
if (gstate_c.dstSquared) {
gstate_c.Dirty(DIRTY_BLEND_STATE);
}
} else if (gstate.getTextureAddress(0) == (gstate.getFrameBufRawAddress() | 0x04000000)) {
// This catches the case of clearing a texture. (#10957)
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
}
// Need to ApplyDrawState after ApplyTexture because depal can launch a render pass and that wrecks the state.
@@ -415,6 +408,19 @@ void DrawEngineD3D11::Flush() {
DepthRasterPredecoded(prim, decoded_, numDecodedVerts_, dec_, vertexCount);
}
bool textureNeedsApply = false;
TextureApplyResult textureResult;
if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) {
gstate_c.Clean(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS);
gstate_c.dstSquared = false;
textureCache_->SetTexture();
textureResult = textureCache_->ApplyTexture(true);
textureNeedsApply = true;
} else if (gstate.getTextureAddress(0) == (gstate.getFrameBufRawAddress() | 0x04000000)) {
// This catches the case of clearing a texture. (#10957)
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
}
SoftwareTransformResult result{};
SoftwareTransformParams params{};
params.everUsedEqualDepth = everUsedEqualDepth_;
@@ -429,7 +435,6 @@ void DrawEngineD3D11::Flush() {
// TODO: This should be after BuildDrawingParams!
if (textureNeedsApply) {
TextureApplyResult textureResult = textureCache_->ApplyTexture(true);
textureCache_->ApplySampler(textureResult, clipInfoFlags_ & ClipInfoFlags::FlatZ, result.pixelMapped);
}
-8
View File
@@ -427,14 +427,6 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
}
depthStencilState_ = ds;
}
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);
} else if (gstate.getTextureAddress(0) == (gstate.getFrameBufRawAddress() | 0x04000000)) {
// This catches the case of clearing a texture.
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
}
}
void DrawEngineD3D11::ApplyDrawStateLate(bool applyStencilRef, uint8_t stencilRef) {
+24 -12
View File
@@ -234,16 +234,6 @@ void DrawEngineGLES::Flush() {
return;
}
bool textureNeedsApply = false;
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;
} else if (gstate.getTextureAddress(0) == (gstate.getFrameBufRawAddress() | 0x04000000)) {
// This catches the case of clearing a texture. (#10957)
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
}
GEPrimitiveType prim = prevPrim_;
bool useHWTransform = CanUseHardwareTransform(prim);
@@ -313,6 +303,17 @@ void DrawEngineGLES::Flush() {
gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && ((hasColor && (gstate.materialupdate & 1)) || gstate.getMaterialAmbientA() == 255) && (!gstate.isLightingEnabled() || gstate.getAmbientA() == 255);
}
bool textureNeedsApply = false;
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;
} else if (gstate.getTextureAddress(0) == (gstate.getFrameBufRawAddress() | 0x04000000)) {
// This catches the case of clearing a texture. (#10957)
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
}
if (textureNeedsApply) {
TextureApplyResult textureResult = textureCache_->ApplyTexture(true);
textureCache_->ApplySampler(textureResult, clipInfoFlags_ & ClipInfoFlags::FlatZ, false);
@@ -369,6 +370,19 @@ void DrawEngineGLES::Flush() {
DepthRasterPredecoded(prim, decoded_, numDecodedVerts_, dec_, vertexCount);
}
bool textureNeedsApply = false;
TextureApplyResult textureResult;
if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) {
gstate_c.Clean(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS);
gstate_c.dstSquared = false;
textureCache_->SetTexture();
textureResult = textureCache_->ApplyTexture(true);
textureNeedsApply = true;
} else if (gstate.getTextureAddress(0) == (gstate.getFrameBufRawAddress() | 0x04000000)) {
// This catches the case of clearing a texture. (#10957)
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
}
u16 *inds = decIndex_;
SoftwareTransformResult result{};
SoftwareTransformParams params{};
@@ -382,8 +396,6 @@ void DrawEngineGLES::Flush() {
const SoftwareTransformAction action = RunSoftwareTransform(params, prim, dec_->VertexType(), dec_->GetDecVtxFmt(), numDecodedVerts_, VERTEX_BUFFER_MAX, vertexCount, inds, RemainingIndices(inds), &result);
if (textureNeedsApply) {
gstate_c.dstSquared = false;
TextureApplyResult textureResult = textureCache_->ApplyTexture(true);
textureCache_->ApplySampler(textureResult, clipInfoFlags_ & ClipInfoFlags::FlatZ, result.pixelMapped);
if (gstate_c.dstSquared) {
gstate_c.Dirty(DIRTY_BLEND_STATE);
+25 -16
View File
@@ -204,18 +204,6 @@ void DrawEngineVulkan::Flush() {
renderManager->AssertInRenderPass();
PROFILE_THIS_SCOPE("Flush");
bool textureNeedsApply = false;
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);
// NOTE: After this is set, we MUST call ApplyTexture before returning.
textureNeedsApply = true;
} else if (gstate.getTextureAddress(0) == (gstate.getFrameBufRawAddress() | 0x04000000)) {
// This catches the case of clearing a texture.
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
}
GEPrimitiveType prim = prevPrim_;
// Always use software for flat shading to fix the provoking index
@@ -285,14 +273,20 @@ void DrawEngineVulkan::Flush() {
gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && ((hasColor && (gstate.materialupdate & 1)) || gstate.getMaterialAmbientA() == 255) && (!gstate.isLightingEnabled() || gstate.getAmbientA() == 255);
}
if (textureNeedsApply) {
TextureApplyResult textureResult = textureCache_->ApplyTexture(true);
bool textureNeedsApply = false;
if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) {
gstate_c.Clean(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS);
textureCache_->SetTexture();
const TextureApplyResult textureResult = textureCache_->ApplyTexture(true);
textureCache_->ApplySampler(textureResult, clipInfoFlags_ & ClipInfoFlags::FlatZ, false);
textureCache_->GetVulkanHandles(imageView, sampler);
if (imageView == VK_NULL_HANDLE)
imageView = (VkImageView)draw_->GetNativeObject(gstate_c.textureIsArray ? Draw::NativeObject::NULL_IMAGEVIEW_ARRAY : Draw::NativeObject::NULL_IMAGEVIEW);
if (sampler == VK_NULL_HANDLE)
sampler = nullSampler_;
} else if (gstate.getTextureAddress(0) == (gstate.getFrameBufRawAddress() | 0x04000000)) {
// This catches the case of clearing a texture.
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
}
if (!lastPipeline_ || gstate_c.IsDirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE) || prim != lastPrim_) {
@@ -408,6 +402,21 @@ void DrawEngineVulkan::Flush() {
}
}
bool textureNeedsApply = false;
TextureApplyResult textureResult;
if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) {
gstate_c.Clean(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS);
gstate_c.dstSquared = false;
textureCache_->SetTexture();
textureResult = textureCache_->ApplyTexture(true);
// NOTE: After this is set, we MUST call ApplyTexture before returning.
textureNeedsApply = true;
} else if (gstate.getTextureAddress(0) == (gstate.getFrameBufRawAddress() | 0x04000000)) {
// This catches the case of clearing a texture.
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
}
SoftwareTransformResult result{};
SoftwareTransformParams params{};
params.decoded = decoded_;
@@ -420,13 +429,13 @@ void DrawEngineVulkan::Flush() {
params.everUsedEqualDepth = everUsedEqualDepth_;
params.clipInfoFlags = clipInfoFlags_;
// The texture needs to have been applied when running RunSoftwareTransform, however we must not have applied the sampler yet since it takes
// result.pixelMapped as an input.
const SoftwareTransformAction action = RunSoftwareTransform(params, prim, dec_->VertexType(), dec_->GetDecVtxFmt(), numDecodedVerts_, VERTEX_BUFFER_MAX, vertexCount, inds, RemainingIndices(inds), &result);
// Only here, where we know whether to clear or to draw primitives, should we actually set the current framebuffer! Because that gives use the opportunity
// to use a "pre-clear" render pass, for high efficiency on tilers.
if (action == SW_DRAW_INDEXED) {
if (textureNeedsApply) {
gstate_c.dstSquared = false;
TextureApplyResult textureResult = textureCache_->ApplyTexture(true);
textureCache_->ApplySampler(textureResult, clipInfoFlags_ & ClipInfoFlags::FlatZ, result.pixelMapped);
textureCache_->GetVulkanHandles(imageView, sampler);
if (imageView == VK_NULL_HANDLE)