Add config option working around buggy graphics drivers
"subImageFix=true" should fix missing text on radeonsi fglrx as well as most mobile drivers. Also fixes tileset atlas on mobile.
This commit is contained in:
parent
9122446b23
commit
b42725ea20
|
@ -94,6 +94,15 @@
|
||||||
# solidFonts=false
|
# solidFonts=false
|
||||||
|
|
||||||
|
|
||||||
|
# Work around buggy graphics drivers which don't
|
||||||
|
# properly synchronize texture access, most
|
||||||
|
# apparent when text doesn't show up or the map
|
||||||
|
# tileset doesn't render at all
|
||||||
|
# (default: disabled)
|
||||||
|
#
|
||||||
|
# subImageFix=false
|
||||||
|
|
||||||
|
|
||||||
# Set the base path of the game to '/path/to/game'
|
# Set the base path of the game to '/path/to/game'
|
||||||
# (default: executable directory)
|
# (default: executable directory)
|
||||||
#
|
#
|
||||||
|
|
|
@ -374,14 +374,46 @@ void Bitmap::stretchBlt(const IntRect &destRect,
|
||||||
if (opacity == 0)
|
if (opacity == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (source.megaSurface())
|
SDL_Surface *srcSurf = source.megaSurface();
|
||||||
|
|
||||||
|
if (srcSurf && shState->config().subImageFix)
|
||||||
{
|
{
|
||||||
|
/* Blit from software surface, for broken GL drivers */
|
||||||
|
Vec2i gpTexSize;
|
||||||
|
shState->ensureTexSize(sourceRect.w, sourceRect.h, gpTexSize);
|
||||||
|
shState->bindTex();
|
||||||
|
|
||||||
|
GLMeta::subRectImageUpload(srcSurf->w, sourceRect.x, sourceRect.y, 0, 0,
|
||||||
|
sourceRect.w, sourceRect.h, srcSurf, GL_RGBA);
|
||||||
|
GLMeta::subRectImageEnd();
|
||||||
|
|
||||||
|
SimpleShader &shader = shState->shaders().simple;
|
||||||
|
shader.bind();
|
||||||
|
shader.setTranslation(Vec2i());
|
||||||
|
shader.setTexSize(gpTexSize);
|
||||||
|
|
||||||
|
p->pushSetViewport(shader);
|
||||||
|
p->bindFBO();
|
||||||
|
|
||||||
|
Quad &quad = shState->gpQuad();
|
||||||
|
quad.setTexRect(FloatRect(0, 0, sourceRect.w, sourceRect.h));
|
||||||
|
quad.setPosRect(destRect);
|
||||||
|
|
||||||
|
p->blitQuad(quad);
|
||||||
|
p->popViewport();
|
||||||
|
|
||||||
|
p->addTaintedArea(destRect);
|
||||||
|
p->onModified();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (srcSurf)
|
||||||
|
{
|
||||||
|
/* Blit from software surface */
|
||||||
/* Don't do transparent blits for now */
|
/* Don't do transparent blits for now */
|
||||||
if (opacity < 255)
|
if (opacity < 255)
|
||||||
source.ensureNonMega();
|
source.ensureNonMega();
|
||||||
|
|
||||||
SDL_Surface *srcSurf = source.megaSurface();
|
|
||||||
|
|
||||||
SDL_Rect srcRect = sourceRect;
|
SDL_Rect srcRect = sourceRect;
|
||||||
SDL_Rect dstRect = destRect;
|
SDL_Rect dstRect = destRect;
|
||||||
SDL_Rect btmRect = { 0, 0, width(), height() };
|
SDL_Rect btmRect = { 0, 0, width(), height() };
|
||||||
|
@ -405,18 +437,19 @@ void Bitmap::stretchBlt(const IntRect &destRect,
|
||||||
|
|
||||||
if (bltRect.w == dstRect.w && bltRect.h == dstRect.h)
|
if (bltRect.w == dstRect.w && bltRect.h == dstRect.h)
|
||||||
{
|
{
|
||||||
|
/* Dest rectangle lies within bounding box */
|
||||||
TEX::uploadSubImage(destRect.x, destRect.y,
|
TEX::uploadSubImage(destRect.x, destRect.y,
|
||||||
destRect.w, destRect.h,
|
destRect.w, destRect.h,
|
||||||
blitTemp->pixels, GL_RGBA);
|
blitTemp->pixels, GL_RGBA);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Clipped blit */
|
||||||
GLMeta::subRectImageUpload(blitTemp->w, bltRect.x - dstRect.x, bltRect.y - dstRect.y,
|
GLMeta::subRectImageUpload(blitTemp->w, bltRect.x - dstRect.x, bltRect.y - dstRect.y,
|
||||||
bltRect.x, bltRect.y, bltRect.w, bltRect.h, blitTemp, GL_RGBA);
|
bltRect.x, bltRect.y, bltRect.w, bltRect.h, blitTemp, GL_RGBA);
|
||||||
GLMeta::subRectImageEnd();
|
GLMeta::subRectImageEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SDL_FreeSurface(blitTemp);
|
SDL_FreeSurface(blitTemp);
|
||||||
|
|
||||||
p->onModified();
|
p->onModified();
|
||||||
|
@ -468,7 +501,6 @@ void Bitmap::stretchBlt(const IntRect &destRect,
|
||||||
}
|
}
|
||||||
|
|
||||||
p->addTaintedArea(destRect);
|
p->addTaintedArea(destRect);
|
||||||
|
|
||||||
p->onModified();
|
p->onModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1023,7 +1055,7 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align)
|
||||||
|
|
||||||
if (fastBlit)
|
if (fastBlit)
|
||||||
{
|
{
|
||||||
if (squeeze == 1.0)
|
if (squeeze == 1.0 && !shState->config().subImageFix)
|
||||||
{
|
{
|
||||||
/* Even faster: upload directly to bitmap texture.
|
/* Even faster: upload directly to bitmap texture.
|
||||||
* We have to make sure the posRect lies within the texture
|
* We have to make sure the posRect lies within the texture
|
||||||
|
|
|
@ -153,6 +153,7 @@ Config::Config()
|
||||||
fixedFramerate(0),
|
fixedFramerate(0),
|
||||||
frameSkip(true),
|
frameSkip(true),
|
||||||
solidFonts(false),
|
solidFonts(false),
|
||||||
|
subImageFix(false),
|
||||||
gameFolder("."),
|
gameFolder("."),
|
||||||
anyAltToggleFS(false),
|
anyAltToggleFS(false),
|
||||||
enableReset(true),
|
enableReset(true),
|
||||||
|
@ -181,6 +182,7 @@ void Config::read(int argc, char *argv[])
|
||||||
PO_DESC(fixedFramerate, int) \
|
PO_DESC(fixedFramerate, int) \
|
||||||
PO_DESC(frameSkip, bool) \
|
PO_DESC(frameSkip, bool) \
|
||||||
PO_DESC(solidFonts, bool) \
|
PO_DESC(solidFonts, bool) \
|
||||||
|
PO_DESC(subImageFix, bool) \
|
||||||
PO_DESC(gameFolder, std::string) \
|
PO_DESC(gameFolder, std::string) \
|
||||||
PO_DESC(anyAltToggleFS, bool) \
|
PO_DESC(anyAltToggleFS, bool) \
|
||||||
PO_DESC(enableReset, bool) \
|
PO_DESC(enableReset, bool) \
|
||||||
|
|
|
@ -89,6 +89,8 @@ struct Config
|
||||||
|
|
||||||
bool solidFonts;
|
bool solidFonts;
|
||||||
|
|
||||||
|
bool subImageFix;
|
||||||
|
|
||||||
std::string gameFolder;
|
std::string gameFolder;
|
||||||
bool anyAltToggleFS;
|
bool anyAltToggleFS;
|
||||||
bool enableReset;
|
bool enableReset;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
|
|
||||||
#include "sharedstate.h"
|
#include "sharedstate.h"
|
||||||
|
#include "config.h"
|
||||||
#include "glstate.h"
|
#include "glstate.h"
|
||||||
#include "gl-util.h"
|
#include "gl-util.h"
|
||||||
#include "gl-meta.h"
|
#include "gl-meta.h"
|
||||||
|
@ -542,19 +543,59 @@ struct TilemapPrivate
|
||||||
if (tileset->megaSurface())
|
if (tileset->megaSurface())
|
||||||
{
|
{
|
||||||
/* Mega surface tileset */
|
/* Mega surface tileset */
|
||||||
TEX::bind(atlas.gl.tex);
|
|
||||||
|
|
||||||
SDL_Surface *tsSurf = tileset->megaSurface();
|
SDL_Surface *tsSurf = tileset->megaSurface();
|
||||||
|
|
||||||
for (size_t i = 0; i < blits.size(); ++i)
|
if (shState->config().subImageFix)
|
||||||
{
|
{
|
||||||
const TileAtlas::Blit &blitOp = blits[i];
|
/* Implementation for broken GL drivers */
|
||||||
|
FBO::bind(atlas.gl.fbo);
|
||||||
|
glState.blend.pushSet(false);
|
||||||
|
glState.viewport.pushSet(IntRect(0, 0, atlas.size.x, atlas.size.y));
|
||||||
|
|
||||||
GLMeta::subRectImageUpload(tsSurf->w, blitOp.src.x, blitOp.src.y,
|
SimpleShader &shader = shState->shaders().simple;
|
||||||
blitOp.dst.x, blitOp.dst.y, tsLaneW, blitOp.h, tsSurf, GL_RGBA);
|
shader.bind();
|
||||||
|
shader.applyViewportProj();
|
||||||
|
shader.setTranslation(Vec2i());
|
||||||
|
|
||||||
|
Quad &quad = shState->gpQuad();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < blits.size(); ++i)
|
||||||
|
{
|
||||||
|
const TileAtlas::Blit &blitOp = blits[i];
|
||||||
|
|
||||||
|
Vec2i texSize;
|
||||||
|
shState->ensureTexSize(tsLaneW, blitOp.h, texSize);
|
||||||
|
shState->bindTex();
|
||||||
|
GLMeta::subRectImageUpload(tsSurf->w, blitOp.src.x, blitOp.src.y,
|
||||||
|
0, 0, tsLaneW, blitOp.h, tsSurf, GL_RGBA);
|
||||||
|
|
||||||
|
shader.setTexSize(texSize);
|
||||||
|
quad.setTexRect(FloatRect(0, 0, tsLaneW, blitOp.h));
|
||||||
|
quad.setPosRect(FloatRect(blitOp.dst.x, blitOp.dst.y, tsLaneW, blitOp.h));
|
||||||
|
|
||||||
|
quad.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
GLMeta::subRectImageEnd();
|
||||||
|
glState.viewport.pop();
|
||||||
|
glState.blend.pop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Clean implementation */
|
||||||
|
TEX::bind(atlas.gl.tex);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < blits.size(); ++i)
|
||||||
|
{
|
||||||
|
const TileAtlas::Blit &blitOp = blits[i];
|
||||||
|
|
||||||
|
GLMeta::subRectImageUpload(tsSurf->w, blitOp.src.x, blitOp.src.y,
|
||||||
|
blitOp.dst.x, blitOp.dst.y, tsLaneW, blitOp.h, tsSurf, GL_RGBA);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLMeta::subRectImageEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLMeta::subRectImageEnd();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue