D3D11: Remove support for BGRA textures and preferred framebuffer formats

This commit is contained in:
Henrik Rydgård
2026-07-03 16:15:43 +02:00
parent 171db92e7f
commit 90c48671d7
14 changed files with 21 additions and 62 deletions
+1 -1
View File
@@ -1820,7 +1820,7 @@ bool D3D11DrawContext::CopyFramebufferToMemory(Framebuffer *src, Aspect channelB
const uint8_t *srcWithOffset = (const uint8_t *)map.pData + srcByteOffset;
switch ((Aspect)channelBits) {
case Aspect::COLOR_BIT:
// Pixel size always 4 here because we always request BGRA8888.
// Pixel size always 4 here because we always request RGBA8888.
ConvertFromRGBA8888((uint8_t *)pixels, srcWithOffset, pixelStride, map.RowPitch / sizeof(uint32_t), bw, bh, destFormat);
break;
case Aspect::DEPTH_BIT:
+4 -5
View File
@@ -143,7 +143,6 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
*errorString = "depal requires bitwise ops";
return false;
}
bool bgraTexture = id.Bit(FS_BIT_BGRA_TEXTURE);
bool colorWriteMask = id.Bit(FS_BIT_COLOR_WRITEMASK) && compat.bitwiseOps;
GEComparison alphaTestFunc = (GEComparison)id.Bits(FS_BIT_ALPHA_TEST_FUNC, 3);
@@ -601,15 +600,15 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
if (compat.shaderLanguage == HLSL_D3D11) {
if (texture3D) {
if (doTextureProjection) {
WRITE(p, " vec4 t = tex.Sample(texSamp, vec3(v_texcoord.xy / v_texcoord.z, u_mipBias))%s;\n", bgraTexture ? ".bgra" : "");
WRITE(p, " vec4 t = tex.Sample(texSamp, vec3(v_texcoord.xy / v_texcoord.z, u_mipBias));\n");
} else {
WRITE(p, " vec4 t = tex.Sample(texSamp, vec3(%s.xy, u_mipBias))%s;\n", texcoord, bgraTexture ? ".bgra" : "");
WRITE(p, " vec4 t = tex.Sample(texSamp, vec3(%s.xy, u_mipBias));\n", texcoord);
}
} else {
if (doTextureProjection) {
WRITE(p, " vec4 t = tex.Sample(texSamp, v_texcoord.xy / v_texcoord.z)%s;\n", bgraTexture ? ".bgra" : "");
WRITE(p, " vec4 t = tex.Sample(texSamp, v_texcoord.xy / v_texcoord.z);\n");
} else {
WRITE(p, " vec4 t = tex.Sample(texSamp, %s.xy)%s;\n", texcoord, bgraTexture ? ".bgra" : "");
WRITE(p, " vec4 t = tex.Sample(texSamp, %s.xy);\n", texcoord);
}
}
} else {
+1 -1
View File
@@ -1384,7 +1384,7 @@ Draw::Texture *FramebufferManagerCommon::MakePixelTexture(const u8 *srcPixels, G
XXH3_freeState(hashState);
}
Draw::DataFormat texFormat = preferredPixelsFormat_;
Draw::DataFormat texFormat = Draw::DataFormat::R8G8B8A8_UNORM;
if (srcPixelFormat == GE_FORMAT_DEPTH16) {
if ((draw_->GetDataFormatSupport(Draw::DataFormat::R16_UNORM) & Draw::FMT_TEXTURE) != 0) {
-2
View File
@@ -625,8 +625,6 @@ protected:
int bloomHack_ = 0;
bool updatePostShaders_ = false;
Draw::DataFormat preferredPixelsFormat_ = Draw::DataFormat::R8G8B8A8_UNORM;
struct TempFBOInfo {
Draw::Framebuffer *fbo;
int last_frame_used;
+1
View File
@@ -42,6 +42,7 @@ bool IsStencilTestOutputDisabled() {
return true;
}
// This is used to figure out when we can replace discard with alpha blending.
bool NeedsTestDiscard() {
// We assume this is called only when enabled and not trivially true (may also be for color testing.)
if (gstate.isStencilTestEnabled() && (gstate.pmska & 0xFF) != 0xFF)
+1 -3
View File
@@ -175,7 +175,6 @@ std::string FragmentShaderDesc(const FShaderID &id) {
if (id.Bit(FS_BIT_DO_TEXTURE_PROJ)) desc << "TexProj ";
if (id.Bit(FS_BIT_LMODE)) desc << "LM ";
if (id.Bit(FS_BIT_FLATSHADE)) desc << "Flat ";
if (id.Bit(FS_BIT_BGRA_TEXTURE)) desc << "BGRA ";
if (id.Bit(FS_BIT_DEPTH_TEST_NEVER)) desc << "DepthNever ";
if (id.Bit(FS_BIT_COLOR_WRITEMASK)) desc << "WriteMask ";
if (id.Bit(FS_BIT_SHADER_TEX_CLAMP)) {
@@ -328,7 +327,6 @@ void ComputeFragmentShaderID(FShaderID *id_out, const ComputedPipelineState &pip
id.SetBit(FS_BIT_CLAMP_S, gstate.isTexCoordClampedS());
id.SetBit(FS_BIT_CLAMP_T, gstate.isTexCoordClampedT());
}
id.SetBit(FS_BIT_BGRA_TEXTURE, gstate_c.bgraTexture);
id.SetBits(FS_BIT_SHADER_DEPAL_MODE, 2, (int)shaderDepalMode);
id.SetBits(FS_BIT_SHADER_DEPAL_FORMAT, 3, (int)shaderDepalFormat);
id.SetBit(FS_BIT_3D_TEXTURE, gstate_c.curTextureIs3D);
@@ -348,7 +346,7 @@ void ComputeFragmentShaderID(FShaderID *id_out, const ComputedPipelineState &pip
id.SetBit(FS_BIT_COLOR_TEST);
id.SetBits(FS_BIT_COLOR_TEST_FUNC, 2, gstate.getColorTestFunction());
id.SetBit(FS_BIT_COLOR_AGAINST_ZERO, IsColorTestAgainstZero());
// This is alos set in enableAlphaTest - color test is uncommon, but we can skip discard the same way.
// This is also set in enableAlphaTest - color test is uncommon, but we can skip discard the same way.
id.SetBit(FS_BIT_TEST_DISCARD_TO_ZERO, !NeedsTestDiscard());
}
+2 -2
View File
@@ -76,7 +76,7 @@ static inline VShaderBit operator +(VShaderBit bit, int i) {
return VShaderBit((int)bit + i);
}
// Local
// TODO: See what we can free up. We're out of bits!
enum FShaderBit : uint8_t {
FS_BIT_CLEARMODE = 0,
FS_BIT_DO_TEXTURE = 1,
@@ -102,7 +102,7 @@ enum FShaderBit : uint8_t {
FS_BIT_BLENDFUNC_A = 38, // 4 bits
FS_BIT_BLENDFUNC_B = 42, // 4 bits
FS_BIT_FLATSHADE = 46,
FS_BIT_BGRA_TEXTURE = 47,
// Free bit 47
FS_BIT_TEST_DISCARD_TO_ZERO = 48,
FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL = 49,
FS_BIT_COLOR_WRITEMASK = 50,
-8
View File
@@ -611,7 +611,6 @@ TexCacheEntry *TextureCacheCommon::SetTexture() {
gstate_c.SetTextureIsVideo(false);
gstate_c.SetTextureIs3D(entry->status & TexStatus::IS_3D);
gstate_c.SetTextureIsArray(false);
gstate_c.SetTextureIsBGRA(entry->status & TexStatus::BGRA);
gstate_c.SetTextureIsFramebuffer(false);
if (entry->status & TexStatus::CLUT8_INDEXED) {
gstate_c.SetShaderDepal(ShaderDepalMode::NORMAL, GE_FORMAT_CLUT8);
@@ -709,7 +708,6 @@ TexCacheEntry *TextureCacheCommon::SetTexture() {
entry->dim = dim;
entry->format = texFormat;
entry->maxLevel = maxLevel;
entry->status &= ~TexStatus::BGRA;
entry->bufw = bufw;
@@ -1218,7 +1216,6 @@ void TextureCacheCommon::SetTextureFramebuffer(const AttachCandidate &candidate)
gstate_c.curTextureWidth = texWidth;
gstate_c.curTextureHeight = texHeight;
gstate_c.SetTextureIsFramebuffer(true);
gstate_c.SetTextureIsBGRA(false);
if ((gstate_c.curTextureXOffset == 0) != (fbInfo.xOffset == 0) || (gstate_c.curTextureYOffset == 0) != (fbInfo.yOffset == 0)) {
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
@@ -2240,7 +2237,6 @@ void TextureCacheCommon::ApplyTexture(bool doBind, bool flatZ) {
gstate_c.SetTextureSolidAlpha(false);
gstate_c.SetTextureIs3D(false);
gstate_c.SetTextureIsArray(false);
gstate_c.SetTextureIsBGRA(false);
} else {
if (doBind) {
BindTexture(entry, flatZ);
@@ -2248,7 +2244,6 @@ void TextureCacheCommon::ApplyTexture(bool doBind, bool flatZ) {
gstate_c.SetTextureSolidAlpha((entry->status & TexStatus::ALPHA_SOLID) != 0);
gstate_c.SetTextureIs3D((entry->status & TexStatus::IS_3D) != 0);
gstate_c.SetTextureIsArray(false);
gstate_c.SetTextureIsBGRA((entry->status & TexStatus::BGRA) != 0);
if (entry->status & TexStatus::CLUT8_INDEXED) {
bool smoothedDepal = false;
u32 depthUpperBits = 0;
@@ -3125,8 +3120,5 @@ std::string TexStatusToString(TexStatus status) {
if (status & TexStatus::VIDEO) {
result += "VIDEO ";
}
if (status & TexStatus::BGRA) {
result += "BGRA ";
}
return result.empty() ? "None" : result;
}
+1 -1
View File
@@ -137,7 +137,7 @@ struct TextureDefinition {
enum class TexStatus : u16 {
VIDEO = (1 << 0),
BGRA = (1 << 1),
// Free bit 1
ALPHA_SOLID = (1 << 2), // Has no alpha channel, or always solid (==1.0) alpha.
MANY_CLUT_VARIANTS = (1 << 3), // Has multiple CLUT variants.
-1
View File
@@ -25,5 +25,4 @@
FramebufferManagerD3D11::FramebufferManagerD3D11(Draw::DrawContext *draw)
: FramebufferManagerCommon(draw) {
presentation_->SetLanguage(HLSL_D3D11);
preferredPixelsFormat_ = Draw::DataFormat::B8G8R8A8_UNORM;
}
-13
View File
@@ -78,19 +78,6 @@ GPU_D3D11::GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
GPU_D3D11::~GPU_D3D11() {}
u32 GPU_D3D11::CheckGPUFeatures() const {
u32 features = GPUCommonHW::CheckGPUFeatures();
uint32_t fmt4444 = draw_->GetDataFormatSupport(Draw::DataFormat::A4R4G4B4_UNORM_PACK16);
uint32_t fmt1555 = draw_->GetDataFormatSupport(Draw::DataFormat::A1R5G5B5_UNORM_PACK16);
uint32_t fmt565 = draw_->GetDataFormatSupport(Draw::DataFormat::R5G6B5_UNORM_PACK16);
if ((fmt4444 & Draw::FMT_TEXTURE) && (fmt565 & Draw::FMT_TEXTURE) && (fmt1555 & Draw::FMT_TEXTURE)) {
features |= GPU_USE_16BIT_FORMATS;
}
return CheckGPUFeaturesLate(features);
}
void GPU_D3D11::DeviceLost() {
draw_->Invalidate(InvalidationFlags::CACHED_RENDER_STATE);
// Simply drop all caches and textures.
-2
View File
@@ -37,8 +37,6 @@ public:
GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw);
~GPU_D3D11();
u32 CheckGPUFeatures() const override;
void GetStats(StringWriter &w) override;
void DeviceLost() override; // Destroy all device objects.
void DeviceRestore(Draw::DrawContext *draw) override;
+9 -15
View File
@@ -57,7 +57,7 @@ static Draw::DataFormat FromD3D11Format(u32 fmt) {
case DXGI_FORMAT_B5G5R5A1_UNORM: return Draw::DataFormat::A1R5G5B5_UNORM_PACK16;
case DXGI_FORMAT_B5G6R5_UNORM: return Draw::DataFormat::R5G6B5_UNORM_PACK16;
case DXGI_FORMAT_R8_UNORM: return Draw::DataFormat::R8_UNORM;
case DXGI_FORMAT_B8G8R8A8_UNORM: default: return Draw::DataFormat::R8G8B8A8_UNORM;
case DXGI_FORMAT_R8G8B8A8_UNORM: default: return Draw::DataFormat::R8G8B8A8_UNORM;
}
}
@@ -69,7 +69,7 @@ static DXGI_FORMAT ToDXGIFormat(Draw::DataFormat fmt) {
case Draw::DataFormat::BC4_UNORM_BLOCK: return DXGI_FORMAT_BC4_UNORM;
case Draw::DataFormat::BC5_UNORM_BLOCK: return DXGI_FORMAT_BC5_UNORM;
case Draw::DataFormat::BC7_UNORM_BLOCK: return DXGI_FORMAT_BC7_UNORM;
case Draw::DataFormat::R8G8B8A8_UNORM: return DXGI_FORMAT_B8G8R8A8_UNORM;
case Draw::DataFormat::R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM;
default: _dbg_assert_(false); return DXGI_FORMAT_UNKNOWN;
}
}
@@ -254,7 +254,7 @@ void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry) {
if (plan.doReplace) {
dstFmt = ToDXGIFormat(plan.replaced->Format());
} else if (plan.scaleFactor > 1 || plan.saveTexture) {
dstFmt = DXGI_FORMAT_B8G8R8A8_UNORM;
dstFmt = DXGI_FORMAT_R8G8B8A8_UNORM;
} else if (plan.decodeToClut8) {
dstFmt = DXGI_FORMAT_R8_UNORM;
}
@@ -303,7 +303,7 @@ void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry) {
if (plan.scaleFactor > 1) {
bpp = 4;
} else {
bpp = dstFmt == DXGI_FORMAT_B8G8R8A8_UNORM ? 4 : 2;
bpp = dstFmt == DXGI_FORMAT_R8G8B8A8_UNORM ? 4 : 2;
}
stride = std::max(mipWidth * bpp, 16);
dataSize = stride * mipHeight;
@@ -404,12 +404,6 @@ void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry) {
if (plan.doReplace) {
entry->SetAlphaStatus(plan.replaced->AlphaStatus());
if (!Draw::DataFormatIsBlockCompressed(plan.replaced->Format(), nullptr)) {
entry->status |= TexStatus::BGRA;
}
} else {
entry->status |= TexStatus::BGRA;
}
}
@@ -422,15 +416,15 @@ DXGI_FORMAT GetClutDestFormatD3D11(GEPaletteFormat format) {
case GE_CMODE_16BIT_BGR5650:
return DXGI_FORMAT_B5G6R5_UNORM;
case GE_CMODE_32BIT_ABGR8888:
return DXGI_FORMAT_B8G8R8A8_UNORM;
return DXGI_FORMAT_R8G8B8A8_UNORM;
}
// Should never be here !
return DXGI_FORMAT_B8G8R8A8_UNORM;
return DXGI_FORMAT_R8G8B8A8_UNORM;
}
DXGI_FORMAT TextureCacheD3D11::GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const {
if (!gstate_c.Use(GPU_USE_16BIT_FORMATS)) {
return DXGI_FORMAT_B8G8R8A8_UNORM;
return DXGI_FORMAT_R8G8B8A8_UNORM;
}
switch (format) {
@@ -450,7 +444,7 @@ DXGI_FORMAT TextureCacheD3D11::GetDestFormat(GETextureFormat format, GEPaletteFo
case GE_TFMT_DXT3:
case GE_TFMT_DXT5:
default:
return DXGI_FORMAT_B8G8R8A8_UNORM;
return DXGI_FORMAT_R8G8B8A8_UNORM;
}
}
@@ -475,7 +469,7 @@ bool TextureCacheD3D11::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level
int height = desc.Height >> level;
switch (desc.Format) {
case DXGI_FORMAT_B8G8R8A8_UNORM:
case DXGI_FORMAT_R8G8B8A8_UNORM:
buffer.Allocate(width, height, GPU_DBG_FORMAT_8888);
break;
+1 -8
View File
@@ -483,7 +483,7 @@ enum : u32 {
// Free bit: 18
GPU_USE_FRAMEBUFFER_ARRAYS = FLAG_BIT(19),
GPU_USE_FRAMEBUFFER_FETCH = FLAG_BIT(20),
// Free bit: 21,
// Free bit: 21
GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT = FLAG_BIT(22),
GPU_ROUND_DEPTH_TO_16BIT = FLAG_BIT(23), // Can be disabled either per game or if we use a real 16-bit depth buffer
GPU_USE_CLIP_DISTANCE = FLAG_BIT(24),
@@ -563,12 +563,6 @@ struct GPUStateCache {
void SetTextureIsVideo(bool isVideo) {
textureIsVideo = isVideo;
}
void SetTextureIsBGRA(bool isBGRA) {
if (bgraTexture != isBGRA) {
bgraTexture = isBGRA;
Dirty(DIRTY_FRAGMENTSHADER_STATE);
}
}
void SetTextureIsFramebuffer(bool isFramebuffer) {
if (textureIsFramebuffer != isFramebuffer) {
textureIsFramebuffer = isFramebuffer;
@@ -609,7 +603,6 @@ public:
int skipDrawReason;
bool bgraTexture;
bool needShaderTexClamp;
bool textureIsArray;
bool textureIsFramebuffer;