From 48a1790d812efe6abaf9c217962438f82b2525b7 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Mon, 10 Mar 2014 15:59:32 +0100 Subject: [PATCH 1/5] Common: Add a generic class for accessing bitfields in a fast and endianness-independent way. The underlying storage type of a bitfield can be any intrinsic integer type, but also any enumeration. Custom storage types are supported if the following things are defined on the storage type: - casting 0 to the storage type - bit shift operators (in both directions) - bitwise & operator - bitwise ~ operator - std::make_unsigned specialization --- Source/Core/Common/BitField.h | 160 ++++++++++++++++++++++ Source/Core/Common/Common.vcxproj | 3 +- Source/Core/Common/Common.vcxproj.filters | 3 +- 3 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 Source/Core/Common/BitField.h diff --git a/Source/Core/Common/BitField.h b/Source/Core/Common/BitField.h new file mode 100644 index 0000000000..40e748229e --- /dev/null +++ b/Source/Core/Common/BitField.h @@ -0,0 +1,160 @@ +// Copyright 2014 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + + +// Copyright 2014 Tony Wasserka +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the owner nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#pragma once + +#include +#include + +/* + * Abstract bitfield class + * + * Allows endianness-independent access to individual bitfields within some raw + * integer value. The assembly generated by this class is identical to the + * usage of raw bitfields, so it's a perfectly fine replacement. + * + * For BitField, X is the distance of the bitfield to the LSB of the + * raw value, Y is the length in bits of the bitfield. Z is an integer type + * which determines the sign of the bitfield. Z must have the same size as the + * raw integer. + * + * + * General usage: + * + * Create a new union with the raw integer value as a member. + * Then for each bitfield you want to expose, add a BitField member + * in the union. The template parameters are the bit offset and the number + * of desired bits. + * + * Changes in the bitfield members will then get reflected in the raw integer + * value and vice-versa. + * + * + * Sample usage: + * + * union SomeRegister + * { + * u32 hex; + * + * BitField<0,7,u32> first_seven_bits; // unsigned + * BitField<7,8,32> next_eight_bits; // unsigned + * BitField<3,15,s32> some_signed_fields; // signed + * }; + * + * This is equivalent to the little-endian specific code: + * + * union SomeRegister + * { + * u32 hex; + * + * struct + * { + * u32 first_seven_bits : 7; + * u32 next_eight_bits : 8; + * }; + * struct + * { + * u32 : 3; // padding + * s32 some_signed_fields : 15; + * }; + * }; + * + * + * Caveats: + * + * BitField provides automatic casting from and to the storage type where + * appropriate. However, when using non-typesafe functions like printf, an + * explicit cast must be performed on the BitField object to make sure it gets + * passed correctly, e.g.: + * printf("Value: %d", (s32)some_register.some_signed_fields); + * + */ +template +struct BitField +{ +private: + // This constructor might be considered ambiguous: + // Would it initialize the storage or just the bitfield? + // Hence, delete it. Use the assignment operator to set bitfield values! + BitField(T val) = delete; + +public: + // Force default constructor to be created + // so that we can use this within unions + BitField() = default; + + BitField& operator=(T val) + { + storage = (storage & ~GetMask()) | ((val << position) & GetMask()); + return *this; + } + + operator T() const + { + if (std::numeric_limits::is_signed) + { + std::size_t shift = 8 * sizeof(T) - bits; + return (T)(((storage & GetMask()) << (shift - position)) >> shift); + } + else + { + return (T)((storage & GetMask()) >> position); + } + } + +private: + // StorageType is T for non-enum types and the underlying type of T if + // T is an enumeration. Note that T is wrapped within an enable_if in the + // former case to workaround compile errors which arise when using + // std::underlying_type::type directly. + typedef typename std::conditional::value, + std::underlying_type, + std::enable_if>::type::type StorageType; + + // Unsigned version of StorageType + typedef typename std::make_unsigned::type StorageTypeU; + + StorageType GetMask() const + { + return ((~(StorageTypeU)0) >> (8*sizeof(T) - bits)) << position; + } + + StorageType storage; + + static_assert(bits + position <= 8 * sizeof(T), "Bitfield out of range"); + + // And, you know, just in case people specify something stupid like bits=position=0x80000000 + static_assert(position < 8 * sizeof(T), "Invalid position"); + static_assert(bits <= 8 * sizeof(T), "Invalid number of bits"); + static_assert(bits > 0, "Invalid number of bits"); +}; diff --git a/Source/Core/Common/Common.vcxproj b/Source/Core/Common/Common.vcxproj index 213e3c0765..f45ae50c12 100644 --- a/Source/Core/Common/Common.vcxproj +++ b/Source/Core/Common/Common.vcxproj @@ -46,6 +46,7 @@ + @@ -143,4 +144,4 @@ - \ No newline at end of file + diff --git a/Source/Core/Common/Common.vcxproj.filters b/Source/Core/Common/Common.vcxproj.filters index e50e5ebfb8..a663f170ab 100644 --- a/Source/Core/Common/Common.vcxproj.filters +++ b/Source/Core/Common/Common.vcxproj.filters @@ -12,6 +12,7 @@ + @@ -110,4 +111,4 @@ - \ No newline at end of file + From 948c0a54f14085b1edb76afe39ee985424ea4474 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Tue, 11 Mar 2014 00:43:29 +0100 Subject: [PATCH 2/5] UnitTests: Add tests for BitField. --- Source/UnitTests/Common/BitFieldTest.cpp | 127 +++++++++++++++++++++++ Source/UnitTests/Common/CMakeLists.txt | 1 + 2 files changed, 128 insertions(+) create mode 100644 Source/UnitTests/Common/BitFieldTest.cpp diff --git a/Source/UnitTests/Common/BitFieldTest.cpp b/Source/UnitTests/Common/BitFieldTest.cpp new file mode 100644 index 0000000000..16efd29d19 --- /dev/null +++ b/Source/UnitTests/Common/BitFieldTest.cpp @@ -0,0 +1,127 @@ +// Copyright 2014 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include + +#include "Common/BitField.h" +#include "Common/CommonTypes.h" + +union TestUnion +{ + u64 hex; + + BitField< 0,64,u64> full_u64; // spans whole storage + BitField< 0,64,s64> full_s64; // spans whole storage + + BitField< 9, 3,u64> regular_field_unsigned; // a plain bitfield + BitField< 9, 3,u64> regular_field_unsigned2; // Just the very same bitfield again + BitField< 9, 3,s64> regular_field_signed; // Same bitfield, but different sign + + BitField<30, 4,s64> at_dword_boundary; // goes over the boundary of two u32 values + + BitField<15, 1,s64> signed_1bit; // allowed values: -1 and 0 +}; + +// table of raw numbers to test with +u64 table[] = +{ + 0x0000000000000000ull, // all zero + 0xffffffffffffffffull, // all one + 0x7fffffffffffffffull, // all one apart from the sign bit + 0x8000000000000000ull, // all zero apart from the sign bit + 0x8000000000000048ull, // regular_field = 0b1001 + + // "random" numbers + 0x0F7B8B1ABD9B8D3Full, + 0xA8B86F73FDAADD2Dull, + 0x1B17A557BFEB351Dull, + 0xE3354268B0C2395Bull, +}; + +// Verify that bitfields in a union have the same underlying data +TEST(BitField, Storage) +{ + TestUnion object; + + EXPECT_EQ((void*)&object.hex, (void*)&object.regular_field_unsigned); + EXPECT_EQ(sizeof(TestUnion), sizeof(object.hex)); + EXPECT_EQ(sizeof(TestUnion), sizeof(object.full_u64)); + EXPECT_EQ(sizeof(TestUnion), sizeof(object.full_s64)); + EXPECT_EQ(sizeof(TestUnion), sizeof(object.regular_field_unsigned)); + EXPECT_EQ(sizeof(TestUnion), sizeof(object.regular_field_signed)); + EXPECT_EQ(sizeof(TestUnion), sizeof(object.at_dword_boundary)); + EXPECT_EQ(sizeof(TestUnion), sizeof(object.signed_1bit)); + + // Now write some values to one field and check if this reflects properly + // in the others. + for (u64 val : table) + { + object.hex = val; + EXPECT_EQ(object.hex, object.full_u64); + EXPECT_EQ(object.regular_field_unsigned, object.regular_field_unsigned2); + + object.regular_field_unsigned = val & 0x3; + EXPECT_EQ(object.hex, object.full_u64); + EXPECT_EQ(object.regular_field_unsigned, object.regular_field_unsigned2); + } +} + +TEST(BitField, Read) +{ + TestUnion object; + + for (u64 val : table) + { + object.hex = val; + + // Make sure reading/casting does not behave completely idiotic + EXPECT_EQ(object.full_u64, (u64)object.full_u64); + EXPECT_EQ(object.full_s64, (s64)object.full_s64); + EXPECT_EQ(object.regular_field_unsigned, (u64)object.regular_field_unsigned); + EXPECT_EQ(object.regular_field_unsigned2, (u64)object.regular_field_unsigned2); + EXPECT_EQ(object.regular_field_signed, (s64)object.regular_field_signed); + EXPECT_EQ(object.at_dword_boundary, (s64)object.at_dword_boundary); + EXPECT_EQ(object.signed_1bit, (s64)object.signed_1bit); + + // Now make sure the value is indeed correct + EXPECT_EQ(val, object.full_u64); + EXPECT_EQ(*(s64*)&val, object.full_s64); + EXPECT_EQ((val >> 9) & 0x7, object.regular_field_unsigned); + EXPECT_EQ((val >> 9) & 0x7, object.regular_field_unsigned2); + EXPECT_EQ(((s64)(object.hex << 52)) >> 61, object.regular_field_signed); + EXPECT_EQ(((s64)(object.hex << 30)) >> 60, object.at_dword_boundary); + EXPECT_EQ(((object.hex >> 15) & 1) ? -1 : 0, object.signed_1bit); + } +} + +TEST(BitField, Assignment) +{ + TestUnion object; + + for (u64 val : table) + { + // Assignments with fixed values + object.full_u64 = val; + EXPECT_EQ(val, object.full_u64); + + object.full_s64 = (s64)val; + EXPECT_EQ((s64)val, object.full_u64); + + object.regular_field_unsigned = val; + EXPECT_EQ(val & 0x7, object.regular_field_unsigned); + + object.at_dword_boundary = val; + EXPECT_EQ(((s64)(val << 60)) >> 60, object.at_dword_boundary); + + object.signed_1bit = val; + EXPECT_EQ((val & 1) ? -1 : 0, object.signed_1bit); + + object.regular_field_signed = val; + EXPECT_EQ(((s64)(object.hex << 61)) >> 61, object.regular_field_signed); + + // Assignment from other BitField + object.at_dword_boundary = object.regular_field_unsigned; + EXPECT_EQ(object.regular_field_unsigned, object.at_dword_boundary); + } +} diff --git a/Source/UnitTests/Common/CMakeLists.txt b/Source/UnitTests/Common/CMakeLists.txt index 80d4943c2e..78f9938e1c 100644 --- a/Source/UnitTests/Common/CMakeLists.txt +++ b/Source/UnitTests/Common/CMakeLists.txt @@ -1,3 +1,4 @@ +add_dolphin_test(BitFieldTest BitFieldTest.cpp common) add_dolphin_test(CommonFuncsTest CommonFuncsTest.cpp common) add_dolphin_test(FifoQueueTest FifoQueueTest.cpp common) add_dolphin_test(FixedSizeQueueTest FixedSizeQueueTest.cpp common) From 77a7bab5ae86871d756522affa3e4e899999da4c Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Mon, 10 Mar 2014 16:15:40 +0100 Subject: [PATCH 3/5] BPMemory: Use the new BitField class in two selected structures. --- .../VideoBackends/Software/BPMemLoader.cpp | 16 ++--- Source/Core/VideoCommon/BPMemory.cpp | 2 +- Source/Core/VideoCommon/BPMemory.h | 61 ++++++++++--------- Source/Core/VideoCommon/BPStructs.cpp | 4 +- .../Core/VideoCommon/PixelShaderManager.cpp | 12 ++-- 5 files changed, 47 insertions(+), 48 deletions(-) diff --git a/Source/Core/VideoBackends/Software/BPMemLoader.cpp b/Source/Core/VideoBackends/Software/BPMemLoader.cpp index 7672e233ac..b81f2b340e 100644 --- a/Source/Core/VideoBackends/Software/BPMemLoader.cpp +++ b/Source/Core/VideoBackends/Software/BPMemLoader.cpp @@ -160,11 +160,11 @@ void SWBPWritten(int address, int newvalue) case BPMEM_TEV_REGISTER_L+6: // Reg 4 { int regNum = (address >> 1 ) & 0x3; - ColReg& reg = bpmem.tevregs[regNum].low; - bool konst = reg.type; + TevReg& reg = bpmem.tevregs[regNum]; + bool konst = reg.type_ra; - Rasterizer::SetTevReg(regNum, Tev::ALP_C, konst, reg.b); // A - Rasterizer::SetTevReg(regNum, Tev::RED_C, konst, reg.a); // R + Rasterizer::SetTevReg(regNum, Tev::ALP_C, konst, reg.alpha); + Rasterizer::SetTevReg(regNum, Tev::RED_C, konst, reg.red); break; } @@ -175,11 +175,11 @@ void SWBPWritten(int address, int newvalue) case BPMEM_TEV_REGISTER_H+6: // Reg 4 { int regNum = (address >> 1 ) & 0x3; - ColReg& reg = bpmem.tevregs[regNum].high; - bool konst = reg.type; + TevReg& reg = bpmem.tevregs[regNum]; + bool konst = reg.type_bg; - Rasterizer::SetTevReg(regNum, Tev::GRN_C, konst, reg.b); // G - Rasterizer::SetTevReg(regNum, Tev::BLU_C, konst, reg.a); // B + Rasterizer::SetTevReg(regNum, Tev::GRN_C, konst, reg.green); + Rasterizer::SetTevReg(regNum, Tev::BLU_C, konst, reg.blue); break; } diff --git a/Source/Core/VideoCommon/BPMemory.cpp b/Source/Core/VideoCommon/BPMemory.cpp index 7902bf70a6..6f49e12c08 100644 --- a/Source/Core/VideoCommon/BPMemory.cpp +++ b/Source/Core/VideoCommon/BPMemory.cpp @@ -158,7 +158,7 @@ void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size no_yes[copy.half_scale], no_yes[copy.scale_invert], no_yes[copy.clear], - copy.frame_to_field, + (u32)copy.frame_to_field, no_yes[copy.copy_to_xfb], no_yes[copy.intensity_fmt], no_yes[copy.auto_conv]); diff --git a/Source/Core/VideoCommon/BPMemory.h b/Source/Core/VideoCommon/BPMemory.h index 2bb35d92c0..ca08d9b9a7 100644 --- a/Source/Core/VideoCommon/BPMemory.h +++ b/Source/Core/VideoCommon/BPMemory.h @@ -4,6 +4,7 @@ #pragma once +#include "Common/BitField.h" #include "Common/Common.h" #pragma pack(4) @@ -828,22 +829,25 @@ struct TCoordInfo }; -union ColReg +union TevReg { - u32 hex; - struct - { - s32 a : 11; - u32 : 1; - s32 b : 11; - u32 type : 1; - }; -}; + u64 hex; -struct TevReg -{ - ColReg low; - ColReg high; + // Access to individual registers + BitField< 0, 32,u64> low; + BitField<32, 32,u64> high; + + // Low register + BitField< 0,11,s64> red; + + BitField<12,11,s64> alpha; + BitField<23, 1,u64> type_ra; + + // High register + BitField<32,11,s64> blue; + + BitField<44,11,s64> green; + BitField<55, 1,u64> type_bg; }; union TevKSel @@ -920,21 +924,20 @@ union AlphaTest union UPE_Copy { u32 Hex; - struct - { - u32 clamp0 : 1; // if set clamp top - u32 clamp1 : 1; // if set clamp bottom - u32 yuv : 1; // if set, color conversion from RGB to YUV - u32 target_pixel_format : 4; // realformat is (fmt/2)+((fmt&1)*8).... for some reason the msb is the lsb (pattern: cycling right shift) - u32 gamma : 2; // gamma correction.. 0 = 1.0 ; 1 = 1.7 ; 2 = 2.2 ; 3 is reserved - u32 half_scale : 1; // "mipmap" filter... 0 = no filter (scale 1:1) ; 1 = box filter (scale 2:1) - u32 scale_invert : 1; // if set vertical scaling is on - u32 clear : 1; - u32 frame_to_field : 2; // 0 progressive ; 1 is reserved ; 2 = interlaced (even lines) ; 3 = interlaced 1 (odd lines) - u32 copy_to_xfb : 1; - u32 intensity_fmt : 1; // if set, is an intensity format (I4,I8,IA4,IA8) - u32 auto_conv : 1; // if 0 automatic color conversion by texture format and pixel type - }; + + BitField< 0,1,u32> clamp0; // if set clamp top + BitField< 1,1,u32> clamp1; // if set clamp bottom + BitField< 2,1,u32> yuv; // if set, color conversion from RGB to YUV + BitField< 3,4,u32> target_pixel_format; // realformat is (fmt/2)+((fmt&1)*8).... for some reason the msb is the lsb (pattern: cycling right shift) + BitField< 7,2,u32> gamma; // gamma correction.. 0 = 1.0 ; 1 = 1.7 ; 2 = 2.2 ; 3 is reserved + BitField< 9,1,u32> half_scale; // "mipmap" filter... 0 = no filter (scale 1:1) ; 1 = box filter (scale 2:1) + BitField<10,1,u32> scale_invert; // if set vertical scaling is on + BitField<11,1,u32> clear; + BitField<12,2,u32> frame_to_field; // 0 progressive ; 1 is reserved ; 2 = interlaced (even lines) ; 3 = interlaced 1 (odd lines) + BitField<14,1,u32> copy_to_xfb; + BitField<15,1,u32> intensity_fmt; // if set, is an intensity format (I4,I8,IA4,IA8) + BitField<16,1,u32> auto_conv; // if 0 automatic color conversion by texture format and pixel type + u32 tp_realFormat() { return target_pixel_format / 2 + (target_pixel_format & 1) * 8; } diff --git a/Source/Core/VideoCommon/BPStructs.cpp b/Source/Core/VideoCommon/BPStructs.cpp index ff60ff6392..e5301b555f 100644 --- a/Source/Core/VideoCommon/BPStructs.cpp +++ b/Source/Core/VideoCommon/BPStructs.cpp @@ -560,9 +560,9 @@ void BPWritten(const BPCmd& bp) // don't compare with changes! int num = (bp.address >> 1) & 0x3; if ((bp.address & 1) == 0) - PixelShaderManager::SetColorChanged(bpmem.tevregs[num].low.type, num); + PixelShaderManager::SetColorChanged(bpmem.tevregs[num].type_ra, num); else - PixelShaderManager::SetColorChanged(bpmem.tevregs[num].high.type, num); + PixelShaderManager::SetColorChanged(bpmem.tevregs[num].type_bg, num); } break; diff --git a/Source/Core/VideoCommon/PixelShaderManager.cpp b/Source/Core/VideoCommon/PixelShaderManager.cpp index 7cbb155be2..bd24ce269a 100644 --- a/Source/Core/VideoCommon/PixelShaderManager.cpp +++ b/Source/Core/VideoCommon/PixelShaderManager.cpp @@ -148,17 +148,13 @@ void PixelShaderManager::SetConstants() } } -// This one is high in profiles (0.5%). -// TODO: Move conversion out, only store the raw color value -// and update it when the shader constant is set, only. -// TODO: Conversion should be checked in the context of tev_fixes.. void PixelShaderManager::SetColorChanged(int type, int num) { int4* c = type ? constants.kcolors : constants.colors; - c[num][0] = bpmem.tevregs[num].low.a; - c[num][3] = bpmem.tevregs[num].low.b; - c[num][2] = bpmem.tevregs[num].high.a; - c[num][1] = bpmem.tevregs[num].high.b; + c[num][0] = bpmem.tevregs[num].red; + c[num][3] = bpmem.tevregs[num].alpha; + c[num][2] = bpmem.tevregs[num].blue; + c[num][1] = bpmem.tevregs[num].green; dirty = true; PRIM_LOG("pixel %scolor%d: %d %d %d %d\n", type?"k":"", num, c[num][0], c[num][1], c[num][2], c[num][3]); From 8941f19cdb01bbe8c40851240d02019ed6e13a32 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Sun, 23 Mar 2014 21:44:23 +0100 Subject: [PATCH 4/5] BPMemory: Expose the pixel_format and zformat fields in PE_CONTROL as enumerations. --- .../Core/FifoPlayer/FifoPlaybackAnalyzer.cpp | 2 +- .../VideoBackends/D3D/PSTextureEncoder.cpp | 18 ++--- .../Core/VideoBackends/D3D/PSTextureEncoder.h | 18 ++--- Source/Core/VideoBackends/D3D/Render.cpp | 12 +-- .../Core/VideoBackends/D3D/TextureCache.cpp | 6 +- Source/Core/VideoBackends/D3D/TextureCache.h | 2 +- .../Core/VideoBackends/D3D/TextureEncoder.h | 4 +- Source/Core/VideoBackends/OGL/Render.cpp | 12 +-- .../Core/VideoBackends/OGL/TextureCache.cpp | 10 +-- Source/Core/VideoBackends/OGL/TextureCache.h | 2 +- .../VideoBackends/Software/EfbInterface.cpp | 78 +++++++++---------- .../VideoBackends/Software/TextureEncoder.cpp | 20 ++--- Source/Core/VideoCommon/BPFunctions.cpp | 49 ++++++------ Source/Core/VideoCommon/BPFunctions.h | 2 +- Source/Core/VideoCommon/BPMemory.cpp | 2 +- Source/Core/VideoCommon/BPMemory.h | 56 ++++++------- Source/Core/VideoCommon/Debugger.cpp | 2 +- Source/Core/VideoCommon/RenderBase.cpp | 4 +- Source/Core/VideoCommon/RenderBase.h | 6 +- Source/Core/VideoCommon/TextureCacheBase.cpp | 6 +- Source/Core/VideoCommon/TextureCacheBase.h | 4 +- Source/Core/VideoCommon/VertexManagerBase.cpp | 2 +- 22 files changed, 160 insertions(+), 157 deletions(-) diff --git a/Source/Core/Core/FifoPlayer/FifoPlaybackAnalyzer.cpp b/Source/Core/Core/FifoPlayer/FifoPlaybackAnalyzer.cpp index 95175b6d94..3dbd84777b 100644 --- a/Source/Core/Core/FifoPlayer/FifoPlaybackAnalyzer.cpp +++ b/Source/Core/Core/FifoPlayer/FifoPlaybackAnalyzer.cpp @@ -246,7 +246,7 @@ void FifoPlaybackAnalyzer::StoreEfbCopyRegion() UPE_Copy peCopy = m_BpMem.triggerEFBCopy; u32 copyfmt = peCopy.tp_realFormat(); - bool bFromZBuffer = m_BpMem.zcontrol.pixel_format == PIXELFMT_Z24; + bool bFromZBuffer = m_BpMem.zcontrol.pixel_format == PEControl::Z24; u32 address = bpmem.copyTexDest << 5; u32 format = copyfmt; diff --git a/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp b/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp index db7eb9ee3e..aa35479767 100644 --- a/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp +++ b/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp @@ -1031,8 +1031,8 @@ void PSTextureEncoder::Shutdown() } size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat, - unsigned int srcFormat, const EFBRectangle& srcRect, bool isIntensity, - bool scaleByHalf) + PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, + bool isIntensity, bool scaleByHalf) { if (!m_ready) // Make sure we initialized OK return 0; @@ -1122,7 +1122,7 @@ size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat, D3D::context->OMSetRenderTargets(1, &m_outRTV, nullptr); - ID3D11ShaderResourceView* pEFB = (srcFormat == PIXELFMT_Z24) ? + ID3D11ShaderResourceView* pEFB = (srcFormat == PEControl::Z24) ? FramebufferManager::GetEFBDepthTexture()->GetSRV() : // FIXME: Instead of resolving EFB, it would be better to pick out a // single sample from each pixel. The game may break if it isn't @@ -1208,10 +1208,10 @@ static const char* INTENSITY_FUNC_NAMES[2] = { "Intensity_0", "Intensity_1" }; -bool PSTextureEncoder::SetStaticShader(unsigned int dstFormat, unsigned int srcFormat, +bool PSTextureEncoder::SetStaticShader(unsigned int dstFormat, PEControl::PixelFormat srcFormat, bool isIntensity, bool scaleByHalf) { - size_t fetchNum = srcFormat; + size_t fetchNum = static_cast(srcFormat); size_t scaledFetchNum = scaleByHalf ? 1 : 0; size_t intensityNum = isIntensity ? 1 : 0; size_t generatorNum = dstFormat; @@ -1244,7 +1244,7 @@ bool PSTextureEncoder::SetStaticShader(unsigned int dstFormat, unsigned int srcF } INFO_LOG(VIDEO, "Compiling efb encoding shader for dstFormat 0x%X, srcFormat %d, isIntensity %d, scaleByHalf %d", - dstFormat, srcFormat, isIntensity ? 1 : 0, scaleByHalf ? 1 : 0); + dstFormat, static_cast(srcFormat), isIntensity ? 1 : 0, scaleByHalf ? 1 : 0); // Shader permutation not found, so compile it D3DBlob* bytecode = nullptr; @@ -1258,7 +1258,7 @@ bool PSTextureEncoder::SetStaticShader(unsigned int dstFormat, unsigned int srcF if (!D3D::CompilePixelShader(EFB_ENCODE_PS, sizeof(EFB_ENCODE_PS), &bytecode, macros)) { WARN_LOG(VIDEO, "EFB encoder shader for dstFormat 0x%X, srcFormat %d, isIntensity %d, scaleByHalf %d failed to compile", - dstFormat, srcFormat, isIntensity ? 1 : 0, scaleByHalf ? 1 : 0); + dstFormat, static_cast(srcFormat), isIntensity ? 1 : 0, scaleByHalf ? 1 : 0); // Add dummy shader to map to prevent trying to compile over and // over again m_staticShaders[key] = nullptr; @@ -1369,9 +1369,9 @@ static const char* INTENSITY_CLASS_NAMES[2] = { }; bool PSTextureEncoder::SetDynamicShader(unsigned int dstFormat, - unsigned int srcFormat, bool isIntensity, bool scaleByHalf) + PEControl::PixelFormat srcFormat, bool isIntensity, bool scaleByHalf) { - size_t fetchNum = srcFormat; + size_t fetchNum = static_cast(srcFormat); size_t scaledFetchNum = scaleByHalf ? 1 : 0; size_t intensityNum = isIntensity ? 1 : 0; size_t generatorNum = dstFormat; diff --git a/Source/Core/VideoBackends/D3D/PSTextureEncoder.h b/Source/Core/VideoBackends/D3D/PSTextureEncoder.h index e581775b73..c14020acfe 100644 --- a/Source/Core/VideoBackends/D3D/PSTextureEncoder.h +++ b/Source/Core/VideoBackends/D3D/PSTextureEncoder.h @@ -32,8 +32,8 @@ public: void Init(); void Shutdown(); size_t Encode(u8* dst, unsigned int dstFormat, - unsigned int srcFormat, const EFBRectangle& srcRect, bool isIntensity, - bool scaleByHalf); + PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, + bool isIntensity, bool scaleByHalf); private: @@ -54,15 +54,15 @@ private: // Stuff only used in static-linking mode (SM4.0-compatible) bool InitStaticMode(); - bool SetStaticShader(unsigned int dstFormat, unsigned int srcFormat, - bool isIntensity, bool scaleByHalf); + bool SetStaticShader(unsigned int dstFormat, + PEControl::PixelFormat srcFormat, bool isIntensity, bool scaleByHalf); typedef unsigned int ComboKey; // Key for a shader combination - ComboKey MakeComboKey(unsigned int dstFormat, unsigned int srcFormat, - bool isIntensity, bool scaleByHalf) + ComboKey MakeComboKey(unsigned int dstFormat, + PEControl::PixelFormat srcFormat, bool isIntensity, bool scaleByHalf) { - return (dstFormat << 4) | (srcFormat << 2) | (isIntensity ? (1<<1) : 0) + return (dstFormat << 4) | (static_cast(srcFormat) << 2) | (isIntensity ? (1<<1) : 0) | (scaleByHalf ? (1<<0) : 0); } @@ -74,8 +74,8 @@ private: // Microsoft fixes their bloody HLSL compiler) bool InitDynamicMode(); - bool SetDynamicShader(unsigned int dstFormat, unsigned int srcFormat, - bool isIntensity, bool scaleByHalf); + bool SetDynamicShader(unsigned int dstFormat, + PEControl::PixelFormat srcFormat, bool isIntensity, bool scaleByHalf); ID3D11PixelShader* m_dynamicShader; ID3D11ClassLinkage* m_classLinkage; diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index 6ed8ae82bc..f890726e35 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -315,7 +315,7 @@ void Renderer::SetColorMask() UINT8 color_mask = 0; if (bpmem.alpha_test.TestResult() != AlphaTest::FAIL) { - if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)) + if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24)) color_mask = D3D11_COLOR_WRITE_ENABLE_ALPHA; if (bpmem.blendmode.colorupdate) color_mask |= D3D11_COLOR_WRITE_ENABLE_RED | D3D11_COLOR_WRITE_ENABLE_GREEN | D3D11_COLOR_WRITE_ENABLE_BLUE; @@ -409,7 +409,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) float val = *(float*)map.pData; u32 ret = 0; - if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16) + if (bpmem.zcontrol.pixel_format == PEControl::RGB565_Z16) { // if Z is in 16 bit format you must return a 16 bit integer ret = ((u32)(val * 0xffff)); @@ -440,15 +440,15 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) // check what to do with the alpha channel (GX_PokeAlphaRead) PixelEngine::UPEAlphaReadReg alpha_read_mode = PixelEngine::GetAlphaReadMode(); - if (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24) + if (bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24) { ret = RGBA8ToRGBA6ToRGBA8(ret); } - else if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16) + else if (bpmem.zcontrol.pixel_format == PEControl::RGB565_Z16) { ret = RGBA8ToRGB565ToRGBA8(ret); } - if (bpmem.zcontrol.pixel_format != PIXELFMT_RGBA6_Z24) + if (bpmem.zcontrol.pixel_format != PEControl::RGBA6_Z24) { ret |= 0xFF000000; } @@ -634,7 +634,7 @@ void Renderer::SetBlendMode(bool forceUpdate) { // Our render target always uses an alpha channel, so we need to override the blend functions to assume a destination alpha of 1 if the render target isn't supposed to have an alpha channel // Example: D3DBLEND_DESTALPHA needs to be D3DBLEND_ONE since the result without an alpha channel is assumed to always be 1. - bool target_has_alpha = bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; + bool target_has_alpha = bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24; const D3D11_BLEND d3dSrcFactors[8] = { D3D11_BLEND_ZERO, diff --git a/Source/Core/VideoBackends/D3D/TextureCache.cpp b/Source/Core/VideoBackends/D3D/TextureCache.cpp index 608cbd67cc..773833ee18 100644 --- a/Source/Core/VideoBackends/D3D/TextureCache.cpp +++ b/Source/Core/VideoBackends/D3D/TextureCache.cpp @@ -121,7 +121,7 @@ TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width, } void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFormat, - unsigned int srcFormat, const EFBRectangle& srcRect, + PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf, unsigned int cbufid, const float *colmat) { @@ -159,9 +159,9 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo // Create texture copy D3D::drawShadedTexQuad( - (srcFormat == PIXELFMT_Z24) ? FramebufferManager::GetEFBDepthTexture()->GetSRV() : FramebufferManager::GetEFBColorTexture()->GetSRV(), + (srcFormat == PEControl::Z24) ? FramebufferManager::GetEFBDepthTexture()->GetSRV() : FramebufferManager::GetEFBColorTexture()->GetSRV(), &sourcerect, Renderer::GetTargetWidth(), Renderer::GetTargetHeight(), - (srcFormat == PIXELFMT_Z24) ? PixelShaderCache::GetDepthMatrixProgram(true) : PixelShaderCache::GetColorMatrixProgram(true), + (srcFormat == PEControl::Z24) ? PixelShaderCache::GetDepthMatrixProgram(true) : PixelShaderCache::GetColorMatrixProgram(true), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); diff --git a/Source/Core/VideoBackends/D3D/TextureCache.h b/Source/Core/VideoBackends/D3D/TextureCache.h index 569f2d024f..6045d3f7db 100644 --- a/Source/Core/VideoBackends/D3D/TextureCache.h +++ b/Source/Core/VideoBackends/D3D/TextureCache.h @@ -30,7 +30,7 @@ private: unsigned int expanded_width, unsigned int levels) override; void FromRenderTarget(u32 dstAddr, unsigned int dstFormat, - unsigned int srcFormat, const EFBRectangle& srcRect, + PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf, unsigned int cbufid, const float *colmat) override; diff --git a/Source/Core/VideoBackends/D3D/TextureEncoder.h b/Source/Core/VideoBackends/D3D/TextureEncoder.h index 56f4092ea8..d5448088e1 100644 --- a/Source/Core/VideoBackends/D3D/TextureEncoder.h +++ b/Source/Core/VideoBackends/D3D/TextureEncoder.h @@ -111,8 +111,8 @@ public: virtual void Shutdown() = 0; // Returns size in bytes of encoded block of memory virtual size_t Encode(u8* dst, unsigned int dstFormat, - unsigned int srcFormat, const EFBRectangle& srcRect, bool isIntensity, - bool scaleByHalf) = 0; + PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, + bool isIntensity, bool scaleByHalf) = 0; }; diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index a9ea91f7bc..e493150de7 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -877,7 +877,7 @@ void Renderer::SetColorMask() { if (bpmem.blendmode.colorupdate) ColorMask = GL_TRUE; - if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)) + if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24)) AlphaMask = GL_TRUE; } glColorMask(ColorMask, ColorMask, ColorMask, AlphaMask); @@ -989,7 +989,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) // Scale the 32-bit value returned by glReadPixels to a 24-bit // value (GC uses a 24-bit Z-buffer). // TODO: in RE0 this value is often off by one, which causes lighting to disappear - if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16) + if (bpmem.zcontrol.pixel_format == PEControl::RGB565_Z16) { // if Z is in 16 bit format you must return a 16 bit integer z = z >> 16; @@ -1047,15 +1047,15 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) // check what to do with the alpha channel (GX_PokeAlphaRead) PixelEngine::UPEAlphaReadReg alpha_read_mode = PixelEngine::GetAlphaReadMode(); - if (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24) + if (bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24) { color = RGBA8ToRGBA6ToRGBA8(color); } - else if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16) + else if (bpmem.zcontrol.pixel_format == PEControl::RGB565_Z16) { color = RGBA8ToRGB565ToRGBA8(color); } - if (bpmem.zcontrol.pixel_format != PIXELFMT_RGBA6_Z24) + if (bpmem.zcontrol.pixel_format != PEControl::RGBA6_Z24) { color |= 0xFF000000; } @@ -1207,7 +1207,7 @@ void Renderer::SetBlendMode(bool forceUpdate) { // Our render target always uses an alpha channel, so we need to override the blend functions to assume a destination alpha of 1 if the render target isn't supposed to have an alpha channel // Example: D3DBLEND_DESTALPHA needs to be D3DBLEND_ONE since the result without an alpha channel is assumed to always be 1. - bool target_has_alpha = bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; + bool target_has_alpha = bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24; bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && target_has_alpha; bool useDualSource = useDstAlpha && g_ActiveConfig.backend_info.bSupportsDualSourceBlend; diff --git a/Source/Core/VideoBackends/OGL/TextureCache.cpp b/Source/Core/VideoBackends/OGL/TextureCache.cpp index 6a20813e80..3757bc45f9 100644 --- a/Source/Core/VideoBackends/OGL/TextureCache.cpp +++ b/Source/Core/VideoBackends/OGL/TextureCache.cpp @@ -258,14 +258,14 @@ TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture( } void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFormat, - unsigned int srcFormat, const EFBRectangle& srcRect, + PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf, unsigned int cbufid, const float *colmat) { g_renderer->ResetAPIState(); // reset any game specific settings // Make sure to resolve anything we need to read from. - const GLuint read_texture = (srcFormat == PIXELFMT_Z24) ? + const GLuint read_texture = (srcFormat == PEControl::Z24) ? FramebufferManager::ResolveAndGetDepthTarget(srcRect) : FramebufferManager::ResolveAndGetRenderTarget(srcRect); @@ -282,7 +282,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo glViewport(0, 0, virtual_width, virtual_height); - if (srcFormat == PIXELFMT_Z24) + if (srcFormat == PEControl::Z24) { s_DepthMatrixProgram.Bind(); if (s_DepthCbufid != cbufid) @@ -298,7 +298,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo } TargetRectangle R = g_renderer->ConvertEFBRectangle(srcRect); - glUniform4f(srcFormat == PIXELFMT_Z24 ? s_DepthCopyPositionUniform : s_ColorCopyPositionUniform, + glUniform4f(srcFormat == PEControl::Z24 ? s_DepthCopyPositionUniform : s_ColorCopyPositionUniform, R.left, R.top, R.right, R.bottom); GL_REPORT_ERRORD(); @@ -312,7 +312,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo int encoded_size = TextureConverter::EncodeToRamFromTexture( addr, read_texture, - srcFormat == PIXELFMT_Z24, + srcFormat == PEControl::Z24, isIntensity, dstFormat, scaleByHalf, diff --git a/Source/Core/VideoBackends/OGL/TextureCache.h b/Source/Core/VideoBackends/OGL/TextureCache.h index 19190efd0d..e1e2ec694c 100644 --- a/Source/Core/VideoBackends/OGL/TextureCache.h +++ b/Source/Core/VideoBackends/OGL/TextureCache.h @@ -43,7 +43,7 @@ private: unsigned int expanded_width, unsigned int level) override; void FromRenderTarget(u32 dstAddr, unsigned int dstFormat, - unsigned int srcFormat, const EFBRectangle& srcRect, + PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf, unsigned int cbufid, const float *colmat) override; diff --git a/Source/Core/VideoBackends/Software/EfbInterface.cpp b/Source/Core/VideoBackends/Software/EfbInterface.cpp index dffe392e6f..b994193b09 100644 --- a/Source/Core/VideoBackends/Software/EfbInterface.cpp +++ b/Source/Core/VideoBackends/Software/EfbInterface.cpp @@ -33,14 +33,14 @@ namespace EfbInterface void SetPixelAlphaOnly(u32 offset, u8 a) { - switch (bpmem.zcontrol.pixel_format) + switch (bpmem.zcontrol.pixel_format) { - case PIXELFMT_RGB8_Z24: - case PIXELFMT_Z24: - case PIXELFMT_RGB565_Z16: + case PEControl::RGB8_Z24: + case PEControl::Z24: + case PEControl::RGB565_Z16: // do nothing break; - case PIXELFMT_RGBA6_Z24: + case PEControl::RGBA6_Z24: { u32 a32 = a; u32 *dst = (u32*)&efb[offset]; @@ -50,7 +50,7 @@ namespace EfbInterface } break; default: - ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format); + ERROR_LOG(VIDEO, "Unsupported pixel format: %i", static_cast(bpmem.zcontrol.pixel_format)); } } @@ -58,8 +58,8 @@ namespace EfbInterface { switch (bpmem.zcontrol.pixel_format) { - case PIXELFMT_RGB8_Z24: - case PIXELFMT_Z24: + case PEControl::RGB8_Z24: + case PEControl::Z24: { u32 src = *(u32*)rgb; u32 *dst = (u32*)&efb[offset]; @@ -68,7 +68,7 @@ namespace EfbInterface *dst = val; } break; - case PIXELFMT_RGBA6_Z24: + case PEControl::RGBA6_Z24: { u32 src = *(u32*)rgb; u32 *dst = (u32*)&efb[offset]; @@ -79,9 +79,9 @@ namespace EfbInterface *dst = val; } break; - case PIXELFMT_RGB565_Z16: + case PEControl::RGB565_Z16: { - INFO_LOG(VIDEO, "PIXELFMT_RGB565_Z16 is not supported correctly yet"); + INFO_LOG(VIDEO, "RGB565_Z16 is not supported correctly yet"); u32 src = *(u32*)rgb; u32 *dst = (u32*)&efb[offset]; u32 val = *dst & 0xff000000; @@ -90,16 +90,16 @@ namespace EfbInterface } break; default: - ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format); + ERROR_LOG(VIDEO, "Unsupported pixel format: %i", static_cast(bpmem.zcontrol.pixel_format)); } } void SetPixelAlphaColor(u32 offset, u8 *color) { - switch (bpmem.zcontrol.pixel_format) + switch (bpmem.zcontrol.pixel_format) { - case PIXELFMT_RGB8_Z24: - case PIXELFMT_Z24: + case PEControl::RGB8_Z24: + case PEControl::Z24: { u32 src = *(u32*)color; u32 *dst = (u32*)&efb[offset]; @@ -108,7 +108,7 @@ namespace EfbInterface *dst = val; } break; - case PIXELFMT_RGBA6_Z24: + case PEControl::RGBA6_Z24: { u32 src = *(u32*)color; u32 *dst = (u32*)&efb[offset]; @@ -120,9 +120,9 @@ namespace EfbInterface *dst = val; } break; - case PIXELFMT_RGB565_Z16: + case PEControl::RGB565_Z16: { - INFO_LOG(VIDEO, "PIXELFMT_RGB565_Z16 is not supported correctly yet"); + INFO_LOG(VIDEO, "RGB565_Z16 is not supported correctly yet"); u32 src = *(u32*)color; u32 *dst = (u32*)&efb[offset]; u32 val = *dst & 0xff000000; @@ -131,16 +131,16 @@ namespace EfbInterface } break; default: - ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format); + ERROR_LOG(VIDEO, "Unsupported pixel format: %i", static_cast(bpmem.zcontrol.pixel_format)); } } - void GetPixelColor(u32 offset, u8 *color) + void GetPixelColor(u32 offset, u8 *color) { switch (bpmem.zcontrol.pixel_format) { - case PIXELFMT_RGB8_Z24: - case PIXELFMT_Z24: + case PEControl::RGB8_Z24: + case PEControl::Z24: { u32 src = *(u32*)&efb[offset]; u32 *dst = (u32*)color; @@ -148,7 +148,7 @@ namespace EfbInterface *dst = val; } break; - case PIXELFMT_RGBA6_Z24: + case PEControl::RGBA6_Z24: { u32 src = *(u32*)&efb[offset]; color[ALP_C] = Convert6To8(src & 0x3f); @@ -157,9 +157,9 @@ namespace EfbInterface color[RED_C] = Convert6To8((src >> 18) & 0x3f); } break; - case PIXELFMT_RGB565_Z16: + case PEControl::RGB565_Z16: { - INFO_LOG(VIDEO, "PIXELFMT_RGB565_Z16 is not supported correctly yet"); + INFO_LOG(VIDEO, "RGB565_Z16 is not supported correctly yet"); u32 src = *(u32*)&efb[offset]; u32 *dst = (u32*)color; u32 val = 0xff | ((src & 0x00ffffff) << 8); @@ -167,7 +167,7 @@ namespace EfbInterface } break; default: - ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format); + ERROR_LOG(VIDEO, "Unsupported pixel format: %i", static_cast(bpmem.zcontrol.pixel_format)); } } @@ -175,9 +175,9 @@ namespace EfbInterface { switch (bpmem.zcontrol.pixel_format) { - case PIXELFMT_RGB8_Z24: - case PIXELFMT_RGBA6_Z24: - case PIXELFMT_Z24: + case PEControl::RGB8_Z24: + case PEControl::RGBA6_Z24: + case PEControl::Z24: { u32 *dst = (u32*)&efb[offset]; u32 val = *dst & 0xff000000; @@ -185,9 +185,9 @@ namespace EfbInterface *dst = val; } break; - case PIXELFMT_RGB565_Z16: + case PEControl::RGB565_Z16: { - INFO_LOG(VIDEO, "PIXELFMT_RGB565_Z16 is not supported correctly yet"); + INFO_LOG(VIDEO, "RGB565_Z16 is not supported correctly yet"); u32 *dst = (u32*)&efb[offset]; u32 val = *dst & 0xff000000; val |= depth & 0x00ffffff; @@ -195,31 +195,31 @@ namespace EfbInterface } break; default: - ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format); + ERROR_LOG(VIDEO, "Unsupported pixel format: %i", static_cast(bpmem.zcontrol.pixel_format)); } } - u32 GetPixelDepth(u32 offset) + u32 GetPixelDepth(u32 offset) { u32 depth = 0; switch (bpmem.zcontrol.pixel_format) { - case PIXELFMT_RGB8_Z24: - case PIXELFMT_RGBA6_Z24: - case PIXELFMT_Z24: + case PEControl::RGB8_Z24: + case PEControl::RGBA6_Z24: + case PEControl::Z24: { depth = (*(u32*)&efb[offset]) & 0x00ffffff; } break; - case PIXELFMT_RGB565_Z16: + case PEControl::RGB565_Z16: { - INFO_LOG(VIDEO, "PIXELFMT_RGB565_Z16 is not supported correctly yet"); + INFO_LOG(VIDEO, "RGB565_Z16 is not supported correctly yet"); depth = (*(u32*)&efb[offset]) & 0x00ffffff; } break; default: - ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format); + ERROR_LOG(VIDEO, "Unsupported pixel format: %i", static_cast(bpmem.zcontrol.pixel_format)); } return depth; diff --git a/Source/Core/VideoBackends/Software/TextureEncoder.cpp b/Source/Core/VideoBackends/Software/TextureEncoder.cpp index cf99dbf911..5913125a08 100644 --- a/Source/Core/VideoBackends/Software/TextureEncoder.cpp +++ b/Source/Core/VideoBackends/Software/TextureEncoder.cpp @@ -1386,8 +1386,8 @@ void EncodeZ24halfscale(u8 *dst, u8 *src, u32 format) void Encode(u8 *dest_ptr) { - int pixelformat = bpmem.zcontrol.pixel_format; - bool bFromZBuffer = pixelformat == PIXELFMT_Z24; + auto pixelformat = bpmem.zcontrol.pixel_format; + bool bFromZBuffer = pixelformat == PEControl::Z24; bool bIsIntensityFmt = bpmem.triggerEFBCopy.intensity_fmt > 0; u32 copyfmt = ((bpmem.triggerEFBCopy.target_pixel_format / 2) + ((bpmem.triggerEFBCopy.target_pixel_format & 1) * 8)); @@ -1409,24 +1409,24 @@ void Encode(u8 *dest_ptr) if (bpmem.triggerEFBCopy.half_scale) { - if (pixelformat == PIXELFMT_RGBA6_Z24) + if (pixelformat == PEControl::RGBA6_Z24) EncodeRGBA6halfscale(dest_ptr, src, format); - else if (pixelformat == PIXELFMT_RGB8_Z24) + else if (pixelformat == PEControl::RGB8_Z24) EncodeRGB8halfscale(dest_ptr, src, format); - else if (pixelformat == PIXELFMT_RGB565_Z16) // not supported + else if (pixelformat == PEControl::RGB565_Z16) // not supported EncodeRGB8halfscale(dest_ptr, src, format); - else if (pixelformat == PIXELFMT_Z24) + else if (pixelformat == PEControl::Z24) EncodeZ24halfscale(dest_ptr, src, format); } else { - if (pixelformat == PIXELFMT_RGBA6_Z24) + if (pixelformat == PEControl::RGBA6_Z24) EncodeRGBA6(dest_ptr, src, format); - else if (pixelformat == PIXELFMT_RGB8_Z24) + else if (pixelformat == PEControl::RGB8_Z24) EncodeRGB8(dest_ptr, src, format); - else if (pixelformat == PIXELFMT_RGB565_Z16) // not supported + else if (pixelformat == PEControl::RGB565_Z16) // not supported EncodeRGB8(dest_ptr, src, format); - else if (pixelformat == PIXELFMT_Z24) + else if (pixelformat == PEControl::Z24) EncodeZ24(dest_ptr, src, format); } } diff --git a/Source/Core/VideoCommon/BPFunctions.cpp b/Source/Core/VideoCommon/BPFunctions.cpp index 1149392179..58362f1a57 100644 --- a/Source/Core/VideoCommon/BPFunctions.cpp +++ b/Source/Core/VideoCommon/BPFunctions.cpp @@ -79,10 +79,10 @@ void SetColorMask() g_renderer->SetColorMask(); } -void CopyEFB(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat, +void CopyEFB(u32 dstAddr, unsigned int dstFormat, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf) { - // bpmem.zcontrol.pixel_format to PIXELFMT_Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format) + // bpmem.zcontrol.pixel_format to PEControl::Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format) if (g_ActiveConfig.bEFBCopyEnable) { TextureCache::CopyRenderTargetToTexture(dstAddr, dstFormat, srcFormat, @@ -111,11 +111,12 @@ void ClearScreen(const EFBRectangle &rc) bool colorEnable = bpmem.blendmode.colorupdate; bool alphaEnable = bpmem.blendmode.alphaupdate; bool zEnable = bpmem.zmode.updateenable; + auto pixel_format = bpmem.zcontrol.pixel_format; // (1): Disable unused color channels - if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB8_Z24 || - bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16 || - bpmem.zcontrol.pixel_format == PIXELFMT_Z24) + if (pixel_format == PEControl::RGB8_Z24 || + pixel_format == PEControl::RGB565_Z16 || + pixel_format == PEControl::Z24) { alphaEnable = false; } @@ -126,11 +127,11 @@ void ClearScreen(const EFBRectangle &rc) u32 z = bpmem.clearZValue; // (2) drop additional accuracy - if (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24) + if (pixel_format == PEControl::RGBA6_Z24) { color = RGBA8ToRGBA6ToRGBA8(color); } - else if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16) + else if (pixel_format == PEControl::RGB565_Z16) { color = RGBA8ToRGB565ToRGBA8(color); z = Z24ToZ16ToZ24(z); @@ -156,8 +157,8 @@ void OnPixelFormatChange() !g_ActiveConfig.backend_info.bSupportsFormatReinterpretation) return; - u32 old_format = Renderer::GetPrevPixelFormat(); - u32 new_format = bpmem.zcontrol.pixel_format; + auto old_format = Renderer::GetPrevPixelFormat(); + auto new_format = bpmem.zcontrol.pixel_format; // no need to reinterpret pixel data in these cases if (new_format == old_format || old_format == (unsigned int)-1) @@ -166,31 +167,31 @@ void OnPixelFormatChange() // Check for pixel format changes switch (old_format) { - case PIXELFMT_RGB8_Z24: - case PIXELFMT_Z24: + case PEControl::RGB8_Z24: + case PEControl::Z24: // Z24 and RGB8_Z24 are treated equal, so just return in this case - if (new_format == PIXELFMT_RGB8_Z24 || new_format == PIXELFMT_Z24) + if (new_format == PEControl::RGB8_Z24 || new_format == PEControl::Z24) goto skip; - if (new_format == PIXELFMT_RGBA6_Z24) + if (new_format == PEControl::RGBA6_Z24) convtype = 0; - else if (new_format == PIXELFMT_RGB565_Z16) + else if (new_format == PEControl::RGB565_Z16) convtype = 1; break; - case PIXELFMT_RGBA6_Z24: - if (new_format == PIXELFMT_RGB8_Z24 || - new_format == PIXELFMT_Z24) + case PEControl::RGBA6_Z24: + if (new_format == PEControl::RGB8_Z24 || + new_format == PEControl::Z24) convtype = 2; - else if (new_format == PIXELFMT_RGB565_Z16) + else if (new_format == PEControl::RGB565_Z16) convtype = 3; break; - case PIXELFMT_RGB565_Z16: - if (new_format == PIXELFMT_RGB8_Z24 || - new_format == PIXELFMT_Z24) + case PEControl::RGB565_Z16: + if (new_format == PEControl::RGB8_Z24 || + new_format == PEControl::Z24) convtype = 4; - else if (new_format == PIXELFMT_RGBA6_Z24) + else if (new_format == PEControl::RGBA6_Z24) convtype = 5; break; @@ -200,14 +201,14 @@ void OnPixelFormatChange() if (convtype == -1) { - ERROR_LOG(VIDEO, "Unhandled EFB format change: %d to %d\n", old_format, new_format); + ERROR_LOG(VIDEO, "Unhandled EFB format change: %d to %d\n", static_cast(old_format), static_cast(new_format)); goto skip; } g_renderer->ReinterpretPixelData(convtype); skip: - DEBUG_LOG(VIDEO, "pixelfmt: pixel=%d, zc=%d", new_format, bpmem.zcontrol.zformat); + DEBUG_LOG(VIDEO, "pixelfmt: pixel=%d, zc=%d", static_cast(new_format), static_cast(bpmem.zcontrol.zformat)); Renderer::StorePixelFormat(new_format); } diff --git a/Source/Core/VideoCommon/BPFunctions.h b/Source/Core/VideoCommon/BPFunctions.h index dfaaa39600..77b7f86c91 100644 --- a/Source/Core/VideoCommon/BPFunctions.h +++ b/Source/Core/VideoCommon/BPFunctions.h @@ -31,7 +31,7 @@ void SetBlendMode(); void SetDitherMode(); void SetLogicOpMode(); void SetColorMask(); -void CopyEFB(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat, +void CopyEFB(u32 dstAddr, unsigned int dstFormat, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf); void ClearScreen(const EFBRectangle &rc); void OnPixelFormatChange(); diff --git a/Source/Core/VideoCommon/BPMemory.cpp b/Source/Core/VideoCommon/BPMemory.cpp index 6f49e12c08..356ee6c133 100644 --- a/Source/Core/VideoCommon/BPMemory.cpp +++ b/Source/Core/VideoCommon/BPMemory.cpp @@ -92,7 +92,7 @@ void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size case BPMEM_ZCOMPARE: { SetRegName(BPMEM_ZCOMPARE); - PE_CONTROL config; config.hex = cmddata; + PEControl config; config.hex = cmddata; const char* pixel_formats[] = { "RGB8_Z24", "RGBA6_Z24", "RGB565_Z16", "Z24", "Y8", "U8", "V8", "YUV420" }; const char* zformats[] = { "linear", "compressed (near)", "compressed (mid)", "compressed (far)", "inv linear", "compressed (inv near)", "compressed (inv mid)", "compressed (inv far)" }; snprintf(desc, desc_size, "EFB pixel format: %s\n" diff --git a/Source/Core/VideoCommon/BPMemory.h b/Source/Core/VideoCommon/BPMemory.h index ca08d9b9a7..ef7c41d88d 100644 --- a/Source/Core/VideoCommon/BPMemory.h +++ b/Source/Core/VideoCommon/BPMemory.h @@ -773,36 +773,38 @@ union FieldMask u32 hex; }; -#define PIXELFMT_RGB8_Z24 0 -#define PIXELFMT_RGBA6_Z24 1 -#define PIXELFMT_RGB565_Z16 2 -#define PIXELFMT_Z24 3 -#define PIXELFMT_Y8 4 -#define PIXELFMT_U8 5 -#define PIXELFMT_V8 6 -#define PIXELFMT_YUV420 7 - -#define ZC_LINEAR 0 -#define ZC_NEAR 1 -#define ZC_MID 2 -#define ZC_FAR 3 -// It seems these Z formats aren't supported/were removed ? -#define ZC_INV_LINEAR 4 -#define ZC_INV_NEAR 5 -#define ZC_INV_MID 6 -#define ZC_INV_FAR 7 - -union PE_CONTROL +union PEControl { - struct + enum PixelFormat : u32 { - u32 pixel_format : 3; // PIXELFMT_X - u32 zformat : 3; // Z Compression for 16bit Z format - u32 early_ztest : 1; // 1: before tex stage - u32 unused : 17; - u32 rid : 8; + RGB8_Z24 = 0, + RGBA6_Z24 = 1, + RGB565_Z16 = 2, + Z24 = 3, + Y8 = 4, + U8 = 5, + V8 = 6, + YUV420 = 7 }; + enum DepthFormat : u32 + { + ZLINEAR = 0, + ZNEAR = 1, + ZMID = 2, + ZFAR = 3, + + // It seems these Z formats aren't supported/were removed ? + ZINV_LINEAR = 4, + ZINV_NEAR = 5, + ZINV_MID = 6, + ZINV_FAR = 7 + }; + + BitField< 0,3,PixelFormat> pixel_format; + BitField< 3,3,DepthFormat> zformat; + BitField< 6,1,u32> early_ztest; + u32 hex; }; @@ -999,7 +1001,7 @@ struct BPMemory ZMode zmode; //40 BlendMode blendmode; //41 ConstantAlpha dstalpha; //42 - PE_CONTROL zcontrol; //43 GXSetZCompLoc, GXPixModeSync + PEControl zcontrol; //43 GXSetZCompLoc, GXPixModeSync FieldMask fieldmask; //44 u32 drawdone; //45, bit1=1 if end of list u32 unknown5; //46 clock? diff --git a/Source/Core/VideoCommon/Debugger.cpp b/Source/Core/VideoCommon/Debugger.cpp index 3197c5dd85..c5ca50f132 100644 --- a/Source/Core/VideoCommon/Debugger.cpp +++ b/Source/Core/VideoCommon/Debugger.cpp @@ -86,7 +86,7 @@ void GFXDebuggerBase::DumpPixelShader(const std::string& path) const std::string filename = StringFromFormat("%sdump_ps.txt", path.c_str()); std::string output; - bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; + bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24; if (!useDstAlpha) { output = "Destination alpha disabled:\n"; diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 0b5d890aa6..12dc7b4bfc 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -64,7 +64,7 @@ int Renderer::s_LastEFBScale; bool Renderer::s_skipSwap; bool Renderer::XFBWrited; -unsigned int Renderer::prev_efb_format = (unsigned int)-1; +PEControl::PixelFormat Renderer::prev_efb_format = (PEControl::PixelFormat)-1; unsigned int Renderer::efb_scale_numeratorX = 1; unsigned int Renderer::efb_scale_numeratorY = 1; unsigned int Renderer::efb_scale_denominatorX = 1; @@ -89,7 +89,7 @@ Renderer::Renderer() Renderer::~Renderer() { // invalidate previous efb format - prev_efb_format = (unsigned int)-1; + prev_efb_format = (PEControl::PixelFormat)-1; efb_scale_numeratorX = efb_scale_numeratorY = efb_scale_denominatorX = efb_scale_denominatorY = 1; diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index e16ee8fd40..5ae0a677eb 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -111,8 +111,8 @@ public: virtual bool SaveScreenshot(const std::string &filename, const TargetRectangle &rc) = 0; - static unsigned int GetPrevPixelFormat() { return prev_efb_format; } - static void StorePixelFormat(unsigned int new_format) { prev_efb_format = new_format; } + static PEControl::PixelFormat GetPrevPixelFormat() { return prev_efb_format; } + static void StorePixelFormat(PEControl::PixelFormat new_format) { prev_efb_format = new_format; } protected: @@ -151,7 +151,7 @@ protected: static bool XFBWrited; private: - static unsigned int prev_efb_format; + static PEControl::PixelFormat prev_efb_format; static unsigned int efb_scale_numeratorX; static unsigned int efb_scale_numeratorY; static unsigned int efb_scale_denominatorX; diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index 6c9ef30e28..04b25cb4fc 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -572,7 +572,7 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int const stage, return ReturnEntry(stage, entry); } -void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat, +void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf) { // Emulation methods: @@ -623,9 +623,9 @@ void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat ColorMask[0] = ColorMask[1] = ColorMask[2] = ColorMask[3] = 255.0f; ColorMask[4] = ColorMask[5] = ColorMask[6] = ColorMask[7] = 1.0f / 255.0f; unsigned int cbufid = -1; - bool efbHasAlpha = bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; + bool efbHasAlpha = bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24; - if (srcFormat == PIXELFMT_Z24) + if (srcFormat == PEControl::Z24) { switch (dstFormat) { diff --git a/Source/Core/VideoCommon/TextureCacheBase.h b/Source/Core/VideoCommon/TextureCacheBase.h index f66726f478..f5229f72ff 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.h +++ b/Source/Core/VideoCommon/TextureCacheBase.h @@ -77,7 +77,7 @@ public: virtual void Load(unsigned int width, unsigned int height, unsigned int expanded_width, unsigned int level) = 0; virtual void FromRenderTarget(u32 dstAddr, unsigned int dstFormat, - unsigned int srcFormat, const EFBRectangle& srcRect, + PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf, unsigned int cbufid, const float *colmat) = 0; @@ -103,7 +103,7 @@ public: static TCacheEntryBase* Load(unsigned int stage, u32 address, unsigned int width, unsigned int height, int format, unsigned int tlutaddr, int tlutfmt, bool use_mipmaps, unsigned int maxlevel, bool from_tmem); - static void CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat, + static void CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf); static void RequestInvalidateTextureCache(); diff --git a/Source/Core/VideoCommon/VertexManagerBase.cpp b/Source/Core/VideoCommon/VertexManagerBase.cpp index ee72d074cd..624631b805 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/VertexManagerBase.cpp @@ -219,7 +219,7 @@ void VertexManager::Flush() bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && - bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; + bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24; if (PerfQueryBase::ShouldEmulate()) g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); From 16105db7092707bc130a345ed1e630e2ef1f7747 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Mon, 24 Mar 2014 20:21:34 +0100 Subject: [PATCH 5/5] BPMemory: Make use of BitField in a number of structures. --- .../VideoBackends/D3D/PSTextureEncoder.cpp | 1 - .../Core/VideoBackends/D3D/TextureEncoder.h | 5 +- Source/Core/VideoBackends/OGL/Render.cpp | 12 +- .../VideoBackends/Software/EfbInterface.cpp | 290 +++++++++--------- Source/Core/VideoBackends/Software/Tev.cpp | 18 +- Source/Core/VideoCommon/BPMemory.cpp | 2 +- Source/Core/VideoCommon/BPMemory.h | 164 +++++----- Source/Core/VideoCommon/BPStructs.cpp | 15 +- 8 files changed, 266 insertions(+), 241 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp b/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp index aa35479767..d5ef9ef715 100644 --- a/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp +++ b/Source/Core/VideoBackends/D3D/PSTextureEncoder.cpp @@ -10,7 +10,6 @@ #include "VideoBackends/D3D/PSTextureEncoder.h" #include "VideoBackends/D3D/Render.h" #include "VideoBackends/D3D/TextureCache.h" -#include "VideoCommon/BPMemory.h" // "Static mode" will compile a new EFB encoder shader for every combination of // encoding configurations. It's compatible with Shader Model 4. diff --git a/Source/Core/VideoBackends/D3D/TextureEncoder.h b/Source/Core/VideoBackends/D3D/TextureEncoder.h index d5448088e1..13dacccce9 100644 --- a/Source/Core/VideoBackends/D3D/TextureEncoder.h +++ b/Source/Core/VideoBackends/D3D/TextureEncoder.h @@ -4,6 +4,7 @@ #pragma once +#include "VideoCommon/BPMemory.h" #include "VideoCommon/VideoCommon.h" namespace DX11 @@ -111,8 +112,8 @@ public: virtual void Shutdown() = 0; // Returns size in bytes of encoded block of memory virtual size_t Encode(u8* dst, unsigned int dstFormat, - PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, - bool isIntensity, bool scaleByHalf) = 0; + PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, + bool isIntensity, bool scaleByHalf) = 0; }; diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index e493150de7..a74ab6966a 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -1279,18 +1279,18 @@ void Renderer::SetBlendMode(bool forceUpdate) // adjust alpha factors if (useDualSource) { - srcidx = GX_BL_ONE; - dstidx = GX_BL_ZERO; + srcidx = BlendMode::ONE; + dstidx = BlendMode::ZERO; } else { // we can't use GL_DST_COLOR or GL_ONE_MINUS_DST_COLOR for source in alpha channel so use their alpha equivalent instead - if (srcidx == GX_BL_DSTCLR) srcidx = GX_BL_DSTALPHA; - if (srcidx == GX_BL_INVDSTCLR) srcidx = GX_BL_INVDSTALPHA; + if (srcidx == BlendMode::DSTCLR) srcidx = BlendMode::DSTALPHA; + if (srcidx == BlendMode::INVDSTCLR) srcidx = BlendMode::INVDSTALPHA; // we can't use GL_SRC_COLOR or GL_ONE_MINUS_SRC_COLOR for destination in alpha channel so use their alpha equivalent instead - if (dstidx == GX_BL_SRCCLR) dstidx = GX_BL_SRCALPHA; - if (dstidx == GX_BL_INVSRCCLR) dstidx = GX_BL_INVSRCALPHA; + if (dstidx == BlendMode::SRCCLR) dstidx = BlendMode::SRCALPHA; + if (dstidx == BlendMode::INVSRCCLR) dstidx = BlendMode::INVSRCALPHA; } GLenum srcFactorAlpha = glSrcFactors[srcidx]; GLenum dstFactorAlpha = glDestFactors[dstidx]; diff --git a/Source/Core/VideoBackends/Software/EfbInterface.cpp b/Source/Core/VideoBackends/Software/EfbInterface.cpp index b994193b09..c1ded19322 100644 --- a/Source/Core/VideoBackends/Software/EfbInterface.cpp +++ b/Source/Core/VideoBackends/Software/EfbInterface.cpp @@ -225,81 +225,83 @@ namespace EfbInterface return depth; } - u32 GetSourceFactor(u8 *srcClr, u8 *dstClr, int mode) + u32 GetSourceFactor(u8 *srcClr, u8 *dstClr, BlendMode::BlendFactor mode) { - switch (mode) { - case 0: // zero - return 0; - case 1: // one - return 0xffffffff; - case 2: // dstclr - return *(u32*)dstClr; - case 3: // invdstclr - return 0xffffffff - *(u32*)dstClr; - case 4: // srcalpha - { - u8 alpha = srcClr[ALP_C]; - u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha; - return factor; - } - case 5: // invsrcalpha - { - u8 alpha = 0xff - srcClr[ALP_C]; - u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha; - return factor; - } - case 6: // dstalpha - { - u8 alpha = dstClr[ALP_C]; - u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha; - return factor; - } - case 7: // invdstalpha - { - u8 alpha = 0xff - dstClr[ALP_C]; - u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha; - return factor; - } + switch (mode) + { + case BlendMode::ZERO: + return 0; + case BlendMode::ONE: + return 0xffffffff; + case BlendMode::DSTCLR: + return *(u32*)dstClr; + case BlendMode::INVDSTCLR: + return 0xffffffff - *(u32*)dstClr; + case BlendMode::SRCALPHA: + { + u8 alpha = srcClr[ALP_C]; + u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha; + return factor; + } + case BlendMode::INVSRCALPHA: + { + u8 alpha = 0xff - srcClr[ALP_C]; + u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha; + return factor; + } + case BlendMode::DSTALPHA: + { + u8 alpha = dstClr[ALP_C]; + u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha; + return factor; + } + case BlendMode::INVDSTALPHA: + { + u8 alpha = 0xff - dstClr[ALP_C]; + u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha; + return factor; + } } return 0; } - u32 GetDestinationFactor(u8 *srcClr, u8 *dstClr, int mode) + u32 GetDestinationFactor(u8 *srcClr, u8 *dstClr, BlendMode::BlendFactor mode) { - switch (mode) { - case 0: // zero - return 0; - case 1: // one - return 0xffffffff; - case 2: // srcclr - return *(u32*)srcClr; - case 3: // invsrcclr - return 0xffffffff - *(u32*)srcClr; - case 4: // srcalpha - { - u8 alpha = srcClr[ALP_C]; - u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha; - return factor; - } - case 5: // invsrcalpha - { - u8 alpha = 0xff - srcClr[ALP_C]; - u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha; - return factor; - } - case 6: // dstalpha - { - u8 alpha = dstClr[ALP_C] & 0xff; - u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha; - return factor; - } - case 7: // invdstalpha - { - u8 alpha = 0xff - dstClr[ALP_C]; - u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha; - return factor; - } + switch (mode) + { + case BlendMode::ZERO: + return 0; + case BlendMode::ONE: + return 0xffffffff; + case BlendMode::SRCCLR: + return *(u32*)srcClr; + case BlendMode::INVSRCCLR: + return 0xffffffff - *(u32*)srcClr; + case BlendMode::SRCALPHA: + { + u8 alpha = srcClr[ALP_C]; + u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha; + return factor; + } + case BlendMode::INVSRCALPHA: + { + u8 alpha = 0xff - srcClr[ALP_C]; + u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha; + return factor; + } + case BlendMode::DSTALPHA: + { + u8 alpha = dstClr[ALP_C] & 0xff; + u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha; + return factor; + } + case BlendMode::INVDSTALPHA: + { + u8 alpha = 0xff - dstClr[ALP_C]; + u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha; + return factor; + } } return 0; @@ -327,58 +329,58 @@ namespace EfbInterface } } - void LogicBlend(u32 srcClr, u32 &dstClr, int op) + void LogicBlend(u32 srcClr, u32 &dstClr, BlendMode::LogicOp op) { switch (op) { - case 0: // clear - dstClr = 0; - break; - case 1: // and - dstClr = srcClr & dstClr; - break; - case 2: // revand - dstClr = srcClr & (~dstClr); - break; - case 3: // copy - dstClr = srcClr; - break; - case 4: // invand - dstClr = (~srcClr) & dstClr; - break; - case 5: // noop - // Do nothing - break; - case 6: // xor - dstClr = srcClr ^ dstClr; - break; - case 7: // or - dstClr = srcClr | dstClr; - break; - case 8: // nor - dstClr = ~(srcClr | dstClr); - break; - case 9: // equiv - dstClr = ~(srcClr ^ dstClr); - break; - case 10: // inv - dstClr = ~dstClr; - break; - case 11: // revor - dstClr = srcClr | (~dstClr); - break; - case 12: // invcopy - dstClr = ~srcClr; - break; - case 13: // invor - dstClr = (~srcClr) | dstClr; - break; - case 14: // nand - dstClr = ~(srcClr & dstClr); - break; - case 15: // set - dstClr = 0xffffffff; - break; + case BlendMode::CLEAR: + dstClr = 0; + break; + case BlendMode::AND: + dstClr = srcClr & dstClr; + break; + case BlendMode::AND_REVERSE: + dstClr = srcClr & (~dstClr); + break; + case BlendMode::COPY: + dstClr = srcClr; + break; + case BlendMode::AND_INVERTED: + dstClr = (~srcClr) & dstClr; + break; + case BlendMode::NOOP: + // Do nothing + break; + case BlendMode::XOR: + dstClr = srcClr ^ dstClr; + break; + case BlendMode::OR: + dstClr = srcClr | dstClr; + break; + case BlendMode::NOR: + dstClr = ~(srcClr | dstClr); + break; + case BlendMode::EQUIV: + dstClr = ~(srcClr ^ dstClr); + break; + case BlendMode::INVERT: + dstClr = ~dstClr; + break; + case BlendMode::OR_REVERSE: + dstClr = srcClr | (~dstClr); + break; + case BlendMode::COPY_INVERTED: + dstClr = ~srcClr; + break; + case BlendMode::OR_INVERTED: + dstClr = (~srcClr) | dstClr; + break; + case BlendMode::NAND: + dstClr = ~(srcClr & dstClr); + break; + case BlendMode::SET: + dstClr = 0xffffffff; + break; } } @@ -584,33 +586,33 @@ namespace EfbInterface switch (bpmem.zmode.func) { - case COMPARE_NEVER: - pass = false; - break; - case COMPARE_LESS: - pass = z < depth; - break; - case COMPARE_EQUAL: - pass = z == depth; - break; - case COMPARE_LEQUAL: - pass = z <= depth; - break; - case COMPARE_GREATER: - pass = z > depth; - break; - case COMPARE_NEQUAL: - pass = z != depth; - break; - case COMPARE_GEQUAL: - pass = z >= depth; - break; - case COMPARE_ALWAYS: - pass = true; - break; - default: - pass = false; - ERROR_LOG(VIDEO, "Bad Z compare mode %i", bpmem.zmode.func); + case ZMode::NEVER: + pass = false; + break; + case ZMode::LESS: + pass = z < depth; + break; + case ZMode::EQUAL: + pass = z == depth; + break; + case ZMode::LEQUAL: + pass = z <= depth; + break; + case ZMode::GREATER: + pass = z > depth; + break; + case ZMode::NEQUAL: + pass = z != depth; + break; + case ZMode::GEQUAL: + pass = z >= depth; + break; + case ZMode::ALWAYS: + pass = true; + break; + default: + pass = false; + ERROR_LOG(VIDEO, "Bad Z compare mode %i", (int)bpmem.zmode.func); } if (pass && bpmem.zmode.updateenable) diff --git a/Source/Core/VideoBackends/Software/Tev.cpp b/Source/Core/VideoBackends/Software/Tev.cpp index 3b517175eb..1890aaa3e3 100644 --- a/Source/Core/VideoBackends/Software/Tev.cpp +++ b/Source/Core/VideoBackends/Software/Tev.cpp @@ -413,17 +413,17 @@ void Tev::DrawAlphaCompare(TevStageCombiner::AlphaCombiner &ac) } } -static bool AlphaCompare(int alpha, int ref, int comp) +static bool AlphaCompare(int alpha, int ref, AlphaTest::CompareMode comp) { switch (comp) { - case ALPHACMP_ALWAYS: return true; - case ALPHACMP_NEVER: return false; - case ALPHACMP_LEQUAL: return alpha <= ref; - case ALPHACMP_LESS: return alpha < ref; - case ALPHACMP_GEQUAL: return alpha >= ref; - case ALPHACMP_GREATER: return alpha > ref; - case ALPHACMP_EQUAL: return alpha == ref; - case ALPHACMP_NEQUAL: return alpha != ref; + case AlphaTest::ALWAYS: return true; + case AlphaTest::NEVER: return false; + case AlphaTest::LEQUAL: return alpha <= ref; + case AlphaTest::LESS: return alpha < ref; + case AlphaTest::GEQUAL: return alpha >= ref; + case AlphaTest::GREATER: return alpha > ref; + case AlphaTest::EQUAL: return alpha == ref; + case AlphaTest::NEQUAL: return alpha != ref; } return true; } diff --git a/Source/Core/VideoCommon/BPMemory.cpp b/Source/Core/VideoCommon/BPMemory.cpp index 356ee6c133..1f74d8d36d 100644 --- a/Source/Core/VideoCommon/BPMemory.cpp +++ b/Source/Core/VideoCommon/BPMemory.cpp @@ -292,7 +292,7 @@ void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size snprintf(desc, desc_size, "test 1: %s (ref: %#02x)\n" "test 2: %s (ref: %#02x)\n" "logic: %s\n", - functions[test.comp0], test.ref0, functions[test.comp1], test.ref1, logic[test.logic]); + functions[test.comp0], (int)test.ref0, functions[test.comp1], (int)test.ref1, logic[test.logic]); break; } diff --git a/Source/Core/VideoCommon/BPMemory.h b/Source/Core/VideoCommon/BPMemory.h index ef7c41d88d..1519d542fd 100644 --- a/Source/Core/VideoCommon/BPMemory.h +++ b/Source/Core/VideoCommon/BPMemory.h @@ -149,27 +149,6 @@ #define GX_TEVREG1 2 #define GX_TEVREG2 3 -#define ALPHACMP_NEVER 0 -#define ALPHACMP_LESS 1 -#define ALPHACMP_EQUAL 2 -#define ALPHACMP_LEQUAL 3 -#define ALPHACMP_GREATER 4 -#define ALPHACMP_NEQUAL 5 -#define ALPHACMP_GEQUAL 6 -#define ALPHACMP_ALWAYS 7 - -enum Compare -{ - COMPARE_NEVER = 0, - COMPARE_LESS, - COMPARE_EQUAL, - COMPARE_LEQUAL, - COMPARE_GREATER, - COMPARE_NEQUAL, - COMPARE_GEQUAL, - COMPARE_ALWAYS -}; - #define ZTEXTURE_DISABLE 0 #define ZTEXTURE_ADD 1 #define ZTEXTURE_REPLACE 2 @@ -179,14 +158,6 @@ enum Compare #define TevBias_SUBHALF 2 #define TevBias_COMPARE 3 -enum AlphaOp -{ - ALPHAOP_AND = 0, - ALPHAOP_OR, - ALPHAOP_XOR, - ALPHAOP_XNOR, -}; - union IND_MTXA { struct @@ -610,31 +581,52 @@ union X10Y10 // Framebuffer/pixel stuff (incl fog) -#define GX_BL_ZERO 0 -#define GX_BL_ONE 1 -#define GX_BL_SRCCLR 2 // for dst factor -#define GX_BL_INVSRCCLR 3 // for dst factor -#define GX_BL_SRCALPHA 4 -#define GX_BL_INVSRCALPHA 5 -#define GX_BL_DSTALPHA 6 -#define GX_BL_INVDSTALPHA 7 -#define GX_BL_DSTCLR GX_BL_SRCCLR // for src factor -#define GX_BL_INVDSTCLR GX_BL_INVSRCCLR // for src factor - union BlendMode { - struct + enum BlendFactor : u32 { - u32 blendenable : 1; - u32 logicopenable : 1; - u32 dither : 1; - u32 colorupdate : 1; - u32 alphaupdate : 1; - u32 dstfactor : 3; //BLEND_ONE, BLEND_INV_SRc etc - u32 srcfactor : 3; - u32 subtract : 1; - u32 logicmode : 4; + ZERO = 0, + ONE = 1, + SRCCLR = 2, // for dst factor + INVSRCCLR = 3, // for dst factor + DSTCLR = SRCCLR, // for src factor + INVDSTCLR = INVSRCCLR, // for src factor + SRCALPHA = 4, + INVSRCALPHA = 5, + DSTALPHA = 6, + INVDSTALPHA = 7 }; + + enum LogicOp : u32 + { + CLEAR = 0, + AND = 1, + AND_REVERSE = 2, + COPY = 3, + AND_INVERTED = 4, + NOOP = 5, + XOR = 6, + OR = 7, + NOR = 8, + EQUIV = 9, + INVERT = 10, + OR_REVERSE = 11, + COPY_INVERTED = 12, + OR_INVERTED = 13, + NAND = 14, + SET = 15 + }; + + BitField< 0,1,u32> blendenable; + BitField< 1,1,u32> logicopenable; + BitField< 2,1,u32> dither; + BitField< 3,1,u32> colorupdate; + BitField< 4,1,u32> alphaupdate; + BitField< 5,3,BlendFactor> dstfactor; + BitField< 8,3,BlendFactor> srcfactor; + BitField<11,1,u32> subtract; + BitField<12,4,LogicOp> logicmode; + u32 hex; }; @@ -734,12 +726,22 @@ struct FogParams union ZMode { - struct + enum CompareMode : u32 { - u32 testenable : 1; - u32 func : 3; - u32 updateenable : 1; //size? + NEVER = 0, + LESS = 1, + EQUAL = 2, + LEQUAL = 3, + GREATER = 4, + NEQUAL = 5, + GEQUAL = 6, + ALWAYS = 7 }; + + BitField<0,1,u32> testenable; + BitField<1,3,CompareMode> func; + BitField<4,1,u32> updateenable; + u32 hex; }; @@ -870,14 +872,32 @@ union TevKSel union AlphaTest { - struct + enum CompareMode : u32 { - u32 ref0 : 8; - u32 ref1 : 8; - u32 comp0 : 3; - u32 comp1 : 3; - u32 logic : 2; + NEVER = 0, + LESS = 1, + EQUAL = 2, + LEQUAL = 3, + GREATER = 4, + NEQUAL = 5, + GEQUAL = 6, + ALWAYS = 7 }; + + enum Op + { + AND = 0, + OR = 1, + XOR = 2, + XNOR = 3 + }; + + BitField< 0,8, u32> ref0; + BitField< 8,8, u32> ref1; + BitField<16,3, CompareMode> comp0; + BitField<19,3, CompareMode> comp1; + BitField<22,2, Op> logic; + u32 hex; enum TEST_RESULT @@ -891,31 +911,31 @@ union AlphaTest { switch (logic) { - case 0: // AND - if (comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS) + case AND: + if (comp0 == ALWAYS && comp1 == ALWAYS) return PASS; - if (comp0 == ALPHACMP_NEVER || comp1 == ALPHACMP_NEVER) + if (comp0 == NEVER || comp1 == NEVER) return FAIL; break; - case 1: // OR - if (comp0 == ALPHACMP_ALWAYS || comp1 == ALPHACMP_ALWAYS) + case OR: + if (comp0 == ALWAYS || comp1 == ALWAYS) return PASS; - if (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER) + if (comp0 == NEVER && comp1 == NEVER) return FAIL; break; - case 2: // XOR - if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_NEVER) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_ALWAYS)) + case XOR: + if ((comp0 == ALWAYS && comp1 == NEVER) || (comp0 == NEVER && comp1 == ALWAYS)) return PASS; - if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER)) + if ((comp0 == ALWAYS && comp1 == ALWAYS) || (comp0 == NEVER && comp1 == NEVER)) return FAIL; break; - case 3: // XNOR - if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_NEVER) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_ALWAYS)) + case XNOR: + if ((comp0 == ALWAYS && comp1 == NEVER) || (comp0 == NEVER && comp1 == ALWAYS)) return FAIL; - if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER)) + if ((comp0 == ALWAYS && comp1 == ALWAYS) || (comp0 == NEVER && comp1 == NEVER)) return PASS; break; } diff --git a/Source/Core/VideoCommon/BPStructs.cpp b/Source/Core/VideoCommon/BPStructs.cpp index e5301b555f..8b904a95f8 100644 --- a/Source/Core/VideoCommon/BPStructs.cpp +++ b/Source/Core/VideoCommon/BPStructs.cpp @@ -133,8 +133,8 @@ void BPWritten(const BPCmd& bp) SetLineWidth(); break; case BPMEM_ZMODE: // Depth Control - PRIM_LOG("zmode: test=%d, func=%d, upd=%d", bpmem.zmode.testenable, bpmem.zmode.func, - bpmem.zmode.updateenable); + PRIM_LOG("zmode: test=%d, func=%d, upd=%d", (int)bpmem.zmode.testenable, + (int)bpmem.zmode.func, (int)bpmem.zmode.updateenable); SetDepthMode(); break; case BPMEM_BLENDMODE: // Blending Control @@ -142,8 +142,9 @@ void BPWritten(const BPCmd& bp) if (bp.changes & 0xFFFF) { PRIM_LOG("blendmode: en=%d, open=%d, colupd=%d, alphaupd=%d, dst=%d, src=%d, sub=%d, mode=%d", - bpmem.blendmode.blendenable, bpmem.blendmode.logicopenable, bpmem.blendmode.colorupdate, bpmem.blendmode.alphaupdate, - bpmem.blendmode.dstfactor, bpmem.blendmode.srcfactor, bpmem.blendmode.subtract, bpmem.blendmode.logicmode); + (int)bpmem.blendmode.blendenable, (int)bpmem.blendmode.logicopenable, (int)bpmem.blendmode.colorupdate, + (int)bpmem.blendmode.alphaupdate, (int)bpmem.blendmode.dstfactor, (int)bpmem.blendmode.srcfactor, + (int)bpmem.blendmode.subtract, (int)bpmem.blendmode.logicmode); // Set LogicOp Blending Mode if (bp.changes & 0xF002) // logicopenable | logicmode @@ -304,8 +305,10 @@ void BPWritten(const BPCmd& bp) PixelShaderManager::SetFogColorChanged(); break; case BPMEM_ALPHACOMPARE: // Compare Alpha Values - PRIM_LOG("alphacmp: ref0=%d, ref1=%d, comp0=%d, comp1=%d, logic=%d", bpmem.alpha_test.ref0, - bpmem.alpha_test.ref1, bpmem.alpha_test.comp0, bpmem.alpha_test.comp1, bpmem.alpha_test.logic); + PRIM_LOG("alphacmp: ref0=%d, ref1=%d, comp0=%d, comp1=%d, logic=%d", + (int)bpmem.alpha_test.ref0, (int)bpmem.alpha_test.ref1, + (int)bpmem.alpha_test.comp0, (int)bpmem.alpha_test.comp1, + (int)bpmem.alpha_test.logic); if (bp.changes & 0xFFFF) PixelShaderManager::SetAlpha(); if (bp.changes)