mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-08-02 14:19:02 +00:00
Merge pull request #204 from neobrain/bitfield_cleanup
Bitfield cleanup
This commit is contained in:
commit
b4337a2192
31 changed files with 763 additions and 446 deletions
160
Source/Core/Common/BitField.h
Normal file
160
Source/Core/Common/BitField.h
Normal file
|
@ -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 <limits>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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,Y,Z>, 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<std::size_t position, std::size_t bits, typename T>
|
||||||
|
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<T>::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<T>::type directly.
|
||||||
|
typedef typename std::conditional<std::is_enum<T>::value,
|
||||||
|
std::underlying_type<T>,
|
||||||
|
std::enable_if<true,T>>::type::type StorageType;
|
||||||
|
|
||||||
|
// Unsigned version of StorageType
|
||||||
|
typedef typename std::make_unsigned<StorageType>::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");
|
||||||
|
};
|
|
@ -46,6 +46,7 @@
|
||||||
<ClInclude Include="Atomic.h" />
|
<ClInclude Include="Atomic.h" />
|
||||||
<ClInclude Include="Atomic_GCC.h" />
|
<ClInclude Include="Atomic_GCC.h" />
|
||||||
<ClInclude Include="Atomic_Win32.h" />
|
<ClInclude Include="Atomic_Win32.h" />
|
||||||
|
<ClInclude Include="BitField.h" />
|
||||||
<ClInclude Include="BreakPoints.h" />
|
<ClInclude Include="BreakPoints.h" />
|
||||||
<ClInclude Include="CDUtils.h" />
|
<ClInclude Include="CDUtils.h" />
|
||||||
<ClInclude Include="ChunkFile.h" />
|
<ClInclude Include="ChunkFile.h" />
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
<ClInclude Include="Atomic.h" />
|
<ClInclude Include="Atomic.h" />
|
||||||
<ClInclude Include="Atomic_GCC.h" />
|
<ClInclude Include="Atomic_GCC.h" />
|
||||||
<ClInclude Include="Atomic_Win32.h" />
|
<ClInclude Include="Atomic_Win32.h" />
|
||||||
|
<ClInclude Include="BitField.h" />
|
||||||
<ClInclude Include="BreakPoints.h" />
|
<ClInclude Include="BreakPoints.h" />
|
||||||
<ClInclude Include="CDUtils.h" />
|
<ClInclude Include="CDUtils.h" />
|
||||||
<ClInclude Include="ChunkFile.h" />
|
<ClInclude Include="ChunkFile.h" />
|
||||||
|
|
|
@ -246,7 +246,7 @@ void FifoPlaybackAnalyzer::StoreEfbCopyRegion()
|
||||||
UPE_Copy peCopy = m_BpMem.triggerEFBCopy;
|
UPE_Copy peCopy = m_BpMem.triggerEFBCopy;
|
||||||
|
|
||||||
u32 copyfmt = peCopy.tp_realFormat();
|
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 address = bpmem.copyTexDest << 5;
|
||||||
|
|
||||||
u32 format = copyfmt;
|
u32 format = copyfmt;
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "VideoBackends/D3D/PSTextureEncoder.h"
|
#include "VideoBackends/D3D/PSTextureEncoder.h"
|
||||||
#include "VideoBackends/D3D/Render.h"
|
#include "VideoBackends/D3D/Render.h"
|
||||||
#include "VideoBackends/D3D/TextureCache.h"
|
#include "VideoBackends/D3D/TextureCache.h"
|
||||||
#include "VideoCommon/BPMemory.h"
|
|
||||||
|
|
||||||
// "Static mode" will compile a new EFB encoder shader for every combination of
|
// "Static mode" will compile a new EFB encoder shader for every combination of
|
||||||
// encoding configurations. It's compatible with Shader Model 4.
|
// encoding configurations. It's compatible with Shader Model 4.
|
||||||
|
@ -1031,8 +1030,8 @@ void PSTextureEncoder::Shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat,
|
size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat,
|
||||||
unsigned int srcFormat, const EFBRectangle& srcRect, bool isIntensity,
|
PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect,
|
||||||
bool scaleByHalf)
|
bool isIntensity, bool scaleByHalf)
|
||||||
{
|
{
|
||||||
if (!m_ready) // Make sure we initialized OK
|
if (!m_ready) // Make sure we initialized OK
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1122,7 +1121,7 @@ size_t PSTextureEncoder::Encode(u8* dst, unsigned int dstFormat,
|
||||||
|
|
||||||
D3D::context->OMSetRenderTargets(1, &m_outRTV, nullptr);
|
D3D::context->OMSetRenderTargets(1, &m_outRTV, nullptr);
|
||||||
|
|
||||||
ID3D11ShaderResourceView* pEFB = (srcFormat == PIXELFMT_Z24) ?
|
ID3D11ShaderResourceView* pEFB = (srcFormat == PEControl::Z24) ?
|
||||||
FramebufferManager::GetEFBDepthTexture()->GetSRV() :
|
FramebufferManager::GetEFBDepthTexture()->GetSRV() :
|
||||||
// FIXME: Instead of resolving EFB, it would be better to pick out a
|
// 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
|
// single sample from each pixel. The game may break if it isn't
|
||||||
|
@ -1208,10 +1207,10 @@ static const char* INTENSITY_FUNC_NAMES[2] = {
|
||||||
"Intensity_0", "Intensity_1"
|
"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)
|
bool isIntensity, bool scaleByHalf)
|
||||||
{
|
{
|
||||||
size_t fetchNum = srcFormat;
|
size_t fetchNum = static_cast<size_t>(srcFormat);
|
||||||
size_t scaledFetchNum = scaleByHalf ? 1 : 0;
|
size_t scaledFetchNum = scaleByHalf ? 1 : 0;
|
||||||
size_t intensityNum = isIntensity ? 1 : 0;
|
size_t intensityNum = isIntensity ? 1 : 0;
|
||||||
size_t generatorNum = dstFormat;
|
size_t generatorNum = dstFormat;
|
||||||
|
@ -1244,7 +1243,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",
|
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<int>(srcFormat), isIntensity ? 1 : 0, scaleByHalf ? 1 : 0);
|
||||||
|
|
||||||
// Shader permutation not found, so compile it
|
// Shader permutation not found, so compile it
|
||||||
D3DBlob* bytecode = nullptr;
|
D3DBlob* bytecode = nullptr;
|
||||||
|
@ -1258,7 +1257,7 @@ bool PSTextureEncoder::SetStaticShader(unsigned int dstFormat, unsigned int srcF
|
||||||
if (!D3D::CompilePixelShader(EFB_ENCODE_PS, sizeof(EFB_ENCODE_PS), &bytecode, macros))
|
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",
|
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<int>(srcFormat), isIntensity ? 1 : 0, scaleByHalf ? 1 : 0);
|
||||||
// Add dummy shader to map to prevent trying to compile over and
|
// Add dummy shader to map to prevent trying to compile over and
|
||||||
// over again
|
// over again
|
||||||
m_staticShaders[key] = nullptr;
|
m_staticShaders[key] = nullptr;
|
||||||
|
@ -1369,9 +1368,9 @@ static const char* INTENSITY_CLASS_NAMES[2] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
bool PSTextureEncoder::SetDynamicShader(unsigned int dstFormat,
|
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<size_t>(srcFormat);
|
||||||
size_t scaledFetchNum = scaleByHalf ? 1 : 0;
|
size_t scaledFetchNum = scaleByHalf ? 1 : 0;
|
||||||
size_t intensityNum = isIntensity ? 1 : 0;
|
size_t intensityNum = isIntensity ? 1 : 0;
|
||||||
size_t generatorNum = dstFormat;
|
size_t generatorNum = dstFormat;
|
||||||
|
|
|
@ -32,8 +32,8 @@ public:
|
||||||
void Init();
|
void Init();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
size_t Encode(u8* dst, unsigned int dstFormat,
|
size_t Encode(u8* dst, unsigned int dstFormat,
|
||||||
unsigned int srcFormat, const EFBRectangle& srcRect, bool isIntensity,
|
PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect,
|
||||||
bool scaleByHalf);
|
bool isIntensity, bool scaleByHalf);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -54,15 +54,15 @@ private:
|
||||||
// Stuff only used in static-linking mode (SM4.0-compatible)
|
// Stuff only used in static-linking mode (SM4.0-compatible)
|
||||||
|
|
||||||
bool InitStaticMode();
|
bool InitStaticMode();
|
||||||
bool SetStaticShader(unsigned int dstFormat, unsigned int srcFormat,
|
bool SetStaticShader(unsigned int dstFormat,
|
||||||
bool isIntensity, bool scaleByHalf);
|
PEControl::PixelFormat srcFormat, bool isIntensity, bool scaleByHalf);
|
||||||
|
|
||||||
typedef unsigned int ComboKey; // Key for a shader combination
|
typedef unsigned int ComboKey; // Key for a shader combination
|
||||||
|
|
||||||
ComboKey MakeComboKey(unsigned int dstFormat, unsigned int srcFormat,
|
ComboKey MakeComboKey(unsigned int dstFormat,
|
||||||
bool isIntensity, bool scaleByHalf)
|
PEControl::PixelFormat srcFormat, bool isIntensity, bool scaleByHalf)
|
||||||
{
|
{
|
||||||
return (dstFormat << 4) | (srcFormat << 2) | (isIntensity ? (1<<1) : 0)
|
return (dstFormat << 4) | (static_cast<int>(srcFormat) << 2) | (isIntensity ? (1<<1) : 0)
|
||||||
| (scaleByHalf ? (1<<0) : 0);
|
| (scaleByHalf ? (1<<0) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,8 +74,8 @@ private:
|
||||||
// Microsoft fixes their bloody HLSL compiler)
|
// Microsoft fixes their bloody HLSL compiler)
|
||||||
|
|
||||||
bool InitDynamicMode();
|
bool InitDynamicMode();
|
||||||
bool SetDynamicShader(unsigned int dstFormat, unsigned int srcFormat,
|
bool SetDynamicShader(unsigned int dstFormat,
|
||||||
bool isIntensity, bool scaleByHalf);
|
PEControl::PixelFormat srcFormat, bool isIntensity, bool scaleByHalf);
|
||||||
|
|
||||||
ID3D11PixelShader* m_dynamicShader;
|
ID3D11PixelShader* m_dynamicShader;
|
||||||
ID3D11ClassLinkage* m_classLinkage;
|
ID3D11ClassLinkage* m_classLinkage;
|
||||||
|
|
|
@ -315,7 +315,7 @@ void Renderer::SetColorMask()
|
||||||
UINT8 color_mask = 0;
|
UINT8 color_mask = 0;
|
||||||
if (bpmem.alpha_test.TestResult() != AlphaTest::FAIL)
|
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;
|
color_mask = D3D11_COLOR_WRITE_ENABLE_ALPHA;
|
||||||
if (bpmem.blendmode.colorupdate)
|
if (bpmem.blendmode.colorupdate)
|
||||||
color_mask |= D3D11_COLOR_WRITE_ENABLE_RED | D3D11_COLOR_WRITE_ENABLE_GREEN | D3D11_COLOR_WRITE_ENABLE_BLUE;
|
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;
|
float val = *(float*)map.pData;
|
||||||
u32 ret = 0;
|
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
|
// if Z is in 16 bit format you must return a 16 bit integer
|
||||||
ret = ((u32)(val * 0xffff));
|
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)
|
// check what to do with the alpha channel (GX_PokeAlphaRead)
|
||||||
PixelEngine::UPEAlphaReadReg alpha_read_mode = PixelEngine::GetAlphaReadMode();
|
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);
|
ret = RGBA8ToRGBA6ToRGBA8(ret);
|
||||||
}
|
}
|
||||||
else if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16)
|
else if (bpmem.zcontrol.pixel_format == PEControl::RGB565_Z16)
|
||||||
{
|
{
|
||||||
ret = RGBA8ToRGB565ToRGBA8(ret);
|
ret = RGBA8ToRGB565ToRGBA8(ret);
|
||||||
}
|
}
|
||||||
if (bpmem.zcontrol.pixel_format != PIXELFMT_RGBA6_Z24)
|
if (bpmem.zcontrol.pixel_format != PEControl::RGBA6_Z24)
|
||||||
{
|
{
|
||||||
ret |= 0xFF000000;
|
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
|
// 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.
|
// 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] =
|
const D3D11_BLEND d3dSrcFactors[8] =
|
||||||
{
|
{
|
||||||
D3D11_BLEND_ZERO,
|
D3D11_BLEND_ZERO,
|
||||||
|
|
|
@ -121,7 +121,7 @@ TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width,
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
|
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,
|
bool isIntensity, bool scaleByHalf, unsigned int cbufid,
|
||||||
const float *colmat)
|
const float *colmat)
|
||||||
{
|
{
|
||||||
|
@ -159,9 +159,9 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
|
||||||
|
|
||||||
// Create texture copy
|
// Create texture copy
|
||||||
D3D::drawShadedTexQuad(
|
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(),
|
&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());
|
VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
||||||
|
|
||||||
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
||||||
|
|
|
@ -30,7 +30,7 @@ private:
|
||||||
unsigned int expanded_width, unsigned int levels) override;
|
unsigned int expanded_width, unsigned int levels) override;
|
||||||
|
|
||||||
void FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
|
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,
|
bool isIntensity, bool scaleByHalf, unsigned int cbufid,
|
||||||
const float *colmat) override;
|
const float *colmat) override;
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "VideoCommon/BPMemory.h"
|
||||||
#include "VideoCommon/VideoCommon.h"
|
#include "VideoCommon/VideoCommon.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
|
@ -111,8 +112,8 @@ public:
|
||||||
virtual void Shutdown() = 0;
|
virtual void Shutdown() = 0;
|
||||||
// Returns size in bytes of encoded block of memory
|
// Returns size in bytes of encoded block of memory
|
||||||
virtual size_t Encode(u8* dst, unsigned int dstFormat,
|
virtual size_t Encode(u8* dst, unsigned int dstFormat,
|
||||||
unsigned int srcFormat, const EFBRectangle& srcRect, bool isIntensity,
|
PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect,
|
||||||
bool scaleByHalf) = 0;
|
bool isIntensity, bool scaleByHalf) = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -877,7 +877,7 @@ void Renderer::SetColorMask()
|
||||||
{
|
{
|
||||||
if (bpmem.blendmode.colorupdate)
|
if (bpmem.blendmode.colorupdate)
|
||||||
ColorMask = GL_TRUE;
|
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;
|
AlphaMask = GL_TRUE;
|
||||||
}
|
}
|
||||||
glColorMask(ColorMask, ColorMask, ColorMask, AlphaMask);
|
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
|
// Scale the 32-bit value returned by glReadPixels to a 24-bit
|
||||||
// value (GC uses a 24-bit Z-buffer).
|
// value (GC uses a 24-bit Z-buffer).
|
||||||
// TODO: in RE0 this value is often off by one, which causes lighting to disappear
|
// 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
|
// if Z is in 16 bit format you must return a 16 bit integer
|
||||||
z = z >> 16;
|
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)
|
// check what to do with the alpha channel (GX_PokeAlphaRead)
|
||||||
PixelEngine::UPEAlphaReadReg alpha_read_mode = PixelEngine::GetAlphaReadMode();
|
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);
|
color = RGBA8ToRGBA6ToRGBA8(color);
|
||||||
}
|
}
|
||||||
else if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16)
|
else if (bpmem.zcontrol.pixel_format == PEControl::RGB565_Z16)
|
||||||
{
|
{
|
||||||
color = RGBA8ToRGB565ToRGBA8(color);
|
color = RGBA8ToRGB565ToRGBA8(color);
|
||||||
}
|
}
|
||||||
if (bpmem.zcontrol.pixel_format != PIXELFMT_RGBA6_Z24)
|
if (bpmem.zcontrol.pixel_format != PEControl::RGBA6_Z24)
|
||||||
{
|
{
|
||||||
color |= 0xFF000000;
|
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
|
// 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.
|
// 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 useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && target_has_alpha;
|
||||||
bool useDualSource = useDstAlpha && g_ActiveConfig.backend_info.bSupportsDualSourceBlend;
|
bool useDualSource = useDstAlpha && g_ActiveConfig.backend_info.bSupportsDualSourceBlend;
|
||||||
|
@ -1279,18 +1279,18 @@ void Renderer::SetBlendMode(bool forceUpdate)
|
||||||
// adjust alpha factors
|
// adjust alpha factors
|
||||||
if (useDualSource)
|
if (useDualSource)
|
||||||
{
|
{
|
||||||
srcidx = GX_BL_ONE;
|
srcidx = BlendMode::ONE;
|
||||||
dstidx = GX_BL_ZERO;
|
dstidx = BlendMode::ZERO;
|
||||||
}
|
}
|
||||||
else
|
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
|
// 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 == BlendMode::DSTCLR) srcidx = BlendMode::DSTALPHA;
|
||||||
if (srcidx == GX_BL_INVDSTCLR) srcidx = GX_BL_INVDSTALPHA;
|
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
|
// 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 == BlendMode::SRCCLR) dstidx = BlendMode::SRCALPHA;
|
||||||
if (dstidx == GX_BL_INVSRCCLR) dstidx = GX_BL_INVSRCALPHA;
|
if (dstidx == BlendMode::INVSRCCLR) dstidx = BlendMode::INVSRCALPHA;
|
||||||
}
|
}
|
||||||
GLenum srcFactorAlpha = glSrcFactors[srcidx];
|
GLenum srcFactorAlpha = glSrcFactors[srcidx];
|
||||||
GLenum dstFactorAlpha = glDestFactors[dstidx];
|
GLenum dstFactorAlpha = glDestFactors[dstidx];
|
||||||
|
|
|
@ -258,14 +258,14 @@ TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture(
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
|
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,
|
bool isIntensity, bool scaleByHalf, unsigned int cbufid,
|
||||||
const float *colmat)
|
const float *colmat)
|
||||||
{
|
{
|
||||||
g_renderer->ResetAPIState(); // reset any game specific settings
|
g_renderer->ResetAPIState(); // reset any game specific settings
|
||||||
|
|
||||||
// Make sure to resolve anything we need to read from.
|
// 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::ResolveAndGetDepthTarget(srcRect) :
|
||||||
FramebufferManager::ResolveAndGetRenderTarget(srcRect);
|
FramebufferManager::ResolveAndGetRenderTarget(srcRect);
|
||||||
|
|
||||||
|
@ -282,7 +282,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
|
||||||
|
|
||||||
glViewport(0, 0, virtual_width, virtual_height);
|
glViewport(0, 0, virtual_width, virtual_height);
|
||||||
|
|
||||||
if (srcFormat == PIXELFMT_Z24)
|
if (srcFormat == PEControl::Z24)
|
||||||
{
|
{
|
||||||
s_DepthMatrixProgram.Bind();
|
s_DepthMatrixProgram.Bind();
|
||||||
if (s_DepthCbufid != cbufid)
|
if (s_DepthCbufid != cbufid)
|
||||||
|
@ -298,7 +298,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetRectangle R = g_renderer->ConvertEFBRectangle(srcRect);
|
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);
|
R.left, R.top, R.right, R.bottom);
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
|
@ -312,7 +312,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
|
||||||
int encoded_size = TextureConverter::EncodeToRamFromTexture(
|
int encoded_size = TextureConverter::EncodeToRamFromTexture(
|
||||||
addr,
|
addr,
|
||||||
read_texture,
|
read_texture,
|
||||||
srcFormat == PIXELFMT_Z24,
|
srcFormat == PEControl::Z24,
|
||||||
isIntensity,
|
isIntensity,
|
||||||
dstFormat,
|
dstFormat,
|
||||||
scaleByHalf,
|
scaleByHalf,
|
||||||
|
|
|
@ -43,7 +43,7 @@ private:
|
||||||
unsigned int expanded_width, unsigned int level) override;
|
unsigned int expanded_width, unsigned int level) override;
|
||||||
|
|
||||||
void FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
|
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,
|
bool isIntensity, bool scaleByHalf, unsigned int cbufid,
|
||||||
const float *colmat) override;
|
const float *colmat) override;
|
||||||
|
|
||||||
|
|
|
@ -160,11 +160,11 @@ void SWBPWritten(int address, int newvalue)
|
||||||
case BPMEM_TEV_REGISTER_L+6: // Reg 4
|
case BPMEM_TEV_REGISTER_L+6: // Reg 4
|
||||||
{
|
{
|
||||||
int regNum = (address >> 1 ) & 0x3;
|
int regNum = (address >> 1 ) & 0x3;
|
||||||
ColReg& reg = bpmem.tevregs[regNum].low;
|
TevReg& reg = bpmem.tevregs[regNum];
|
||||||
bool konst = reg.type;
|
bool konst = reg.type_ra;
|
||||||
|
|
||||||
Rasterizer::SetTevReg(regNum, Tev::ALP_C, konst, reg.b); // A
|
Rasterizer::SetTevReg(regNum, Tev::ALP_C, konst, reg.alpha);
|
||||||
Rasterizer::SetTevReg(regNum, Tev::RED_C, konst, reg.a); // R
|
Rasterizer::SetTevReg(regNum, Tev::RED_C, konst, reg.red);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -175,11 +175,11 @@ void SWBPWritten(int address, int newvalue)
|
||||||
case BPMEM_TEV_REGISTER_H+6: // Reg 4
|
case BPMEM_TEV_REGISTER_H+6: // Reg 4
|
||||||
{
|
{
|
||||||
int regNum = (address >> 1 ) & 0x3;
|
int regNum = (address >> 1 ) & 0x3;
|
||||||
ColReg& reg = bpmem.tevregs[regNum].high;
|
TevReg& reg = bpmem.tevregs[regNum];
|
||||||
bool konst = reg.type;
|
bool konst = reg.type_bg;
|
||||||
|
|
||||||
Rasterizer::SetTevReg(regNum, Tev::GRN_C, konst, reg.b); // G
|
Rasterizer::SetTevReg(regNum, Tev::GRN_C, konst, reg.green);
|
||||||
Rasterizer::SetTevReg(regNum, Tev::BLU_C, konst, reg.a); // B
|
Rasterizer::SetTevReg(regNum, Tev::BLU_C, konst, reg.blue);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,12 +35,12 @@ namespace EfbInterface
|
||||||
{
|
{
|
||||||
switch (bpmem.zcontrol.pixel_format)
|
switch (bpmem.zcontrol.pixel_format)
|
||||||
{
|
{
|
||||||
case PIXELFMT_RGB8_Z24:
|
case PEControl::RGB8_Z24:
|
||||||
case PIXELFMT_Z24:
|
case PEControl::Z24:
|
||||||
case PIXELFMT_RGB565_Z16:
|
case PEControl::RGB565_Z16:
|
||||||
// do nothing
|
// do nothing
|
||||||
break;
|
break;
|
||||||
case PIXELFMT_RGBA6_Z24:
|
case PEControl::RGBA6_Z24:
|
||||||
{
|
{
|
||||||
u32 a32 = a;
|
u32 a32 = a;
|
||||||
u32 *dst = (u32*)&efb[offset];
|
u32 *dst = (u32*)&efb[offset];
|
||||||
|
@ -50,7 +50,7 @@ namespace EfbInterface
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format);
|
ERROR_LOG(VIDEO, "Unsupported pixel format: %i", static_cast<int>(bpmem.zcontrol.pixel_format));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,8 +58,8 @@ namespace EfbInterface
|
||||||
{
|
{
|
||||||
switch (bpmem.zcontrol.pixel_format)
|
switch (bpmem.zcontrol.pixel_format)
|
||||||
{
|
{
|
||||||
case PIXELFMT_RGB8_Z24:
|
case PEControl::RGB8_Z24:
|
||||||
case PIXELFMT_Z24:
|
case PEControl::Z24:
|
||||||
{
|
{
|
||||||
u32 src = *(u32*)rgb;
|
u32 src = *(u32*)rgb;
|
||||||
u32 *dst = (u32*)&efb[offset];
|
u32 *dst = (u32*)&efb[offset];
|
||||||
|
@ -68,7 +68,7 @@ namespace EfbInterface
|
||||||
*dst = val;
|
*dst = val;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PIXELFMT_RGBA6_Z24:
|
case PEControl::RGBA6_Z24:
|
||||||
{
|
{
|
||||||
u32 src = *(u32*)rgb;
|
u32 src = *(u32*)rgb;
|
||||||
u32 *dst = (u32*)&efb[offset];
|
u32 *dst = (u32*)&efb[offset];
|
||||||
|
@ -79,9 +79,9 @@ namespace EfbInterface
|
||||||
*dst = val;
|
*dst = val;
|
||||||
}
|
}
|
||||||
break;
|
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 src = *(u32*)rgb;
|
||||||
u32 *dst = (u32*)&efb[offset];
|
u32 *dst = (u32*)&efb[offset];
|
||||||
u32 val = *dst & 0xff000000;
|
u32 val = *dst & 0xff000000;
|
||||||
|
@ -90,7 +90,7 @@ namespace EfbInterface
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format);
|
ERROR_LOG(VIDEO, "Unsupported pixel format: %i", static_cast<int>(bpmem.zcontrol.pixel_format));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,8 +98,8 @@ namespace EfbInterface
|
||||||
{
|
{
|
||||||
switch (bpmem.zcontrol.pixel_format)
|
switch (bpmem.zcontrol.pixel_format)
|
||||||
{
|
{
|
||||||
case PIXELFMT_RGB8_Z24:
|
case PEControl::RGB8_Z24:
|
||||||
case PIXELFMT_Z24:
|
case PEControl::Z24:
|
||||||
{
|
{
|
||||||
u32 src = *(u32*)color;
|
u32 src = *(u32*)color;
|
||||||
u32 *dst = (u32*)&efb[offset];
|
u32 *dst = (u32*)&efb[offset];
|
||||||
|
@ -108,7 +108,7 @@ namespace EfbInterface
|
||||||
*dst = val;
|
*dst = val;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PIXELFMT_RGBA6_Z24:
|
case PEControl::RGBA6_Z24:
|
||||||
{
|
{
|
||||||
u32 src = *(u32*)color;
|
u32 src = *(u32*)color;
|
||||||
u32 *dst = (u32*)&efb[offset];
|
u32 *dst = (u32*)&efb[offset];
|
||||||
|
@ -120,9 +120,9 @@ namespace EfbInterface
|
||||||
*dst = val;
|
*dst = val;
|
||||||
}
|
}
|
||||||
break;
|
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 src = *(u32*)color;
|
||||||
u32 *dst = (u32*)&efb[offset];
|
u32 *dst = (u32*)&efb[offset];
|
||||||
u32 val = *dst & 0xff000000;
|
u32 val = *dst & 0xff000000;
|
||||||
|
@ -131,7 +131,7 @@ namespace EfbInterface
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format);
|
ERROR_LOG(VIDEO, "Unsupported pixel format: %i", static_cast<int>(bpmem.zcontrol.pixel_format));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,8 +139,8 @@ namespace EfbInterface
|
||||||
{
|
{
|
||||||
switch (bpmem.zcontrol.pixel_format)
|
switch (bpmem.zcontrol.pixel_format)
|
||||||
{
|
{
|
||||||
case PIXELFMT_RGB8_Z24:
|
case PEControl::RGB8_Z24:
|
||||||
case PIXELFMT_Z24:
|
case PEControl::Z24:
|
||||||
{
|
{
|
||||||
u32 src = *(u32*)&efb[offset];
|
u32 src = *(u32*)&efb[offset];
|
||||||
u32 *dst = (u32*)color;
|
u32 *dst = (u32*)color;
|
||||||
|
@ -148,7 +148,7 @@ namespace EfbInterface
|
||||||
*dst = val;
|
*dst = val;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PIXELFMT_RGBA6_Z24:
|
case PEControl::RGBA6_Z24:
|
||||||
{
|
{
|
||||||
u32 src = *(u32*)&efb[offset];
|
u32 src = *(u32*)&efb[offset];
|
||||||
color[ALP_C] = Convert6To8(src & 0x3f);
|
color[ALP_C] = Convert6To8(src & 0x3f);
|
||||||
|
@ -157,9 +157,9 @@ namespace EfbInterface
|
||||||
color[RED_C] = Convert6To8((src >> 18) & 0x3f);
|
color[RED_C] = Convert6To8((src >> 18) & 0x3f);
|
||||||
}
|
}
|
||||||
break;
|
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 src = *(u32*)&efb[offset];
|
||||||
u32 *dst = (u32*)color;
|
u32 *dst = (u32*)color;
|
||||||
u32 val = 0xff | ((src & 0x00ffffff) << 8);
|
u32 val = 0xff | ((src & 0x00ffffff) << 8);
|
||||||
|
@ -167,7 +167,7 @@ namespace EfbInterface
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format);
|
ERROR_LOG(VIDEO, "Unsupported pixel format: %i", static_cast<int>(bpmem.zcontrol.pixel_format));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,9 +175,9 @@ namespace EfbInterface
|
||||||
{
|
{
|
||||||
switch (bpmem.zcontrol.pixel_format)
|
switch (bpmem.zcontrol.pixel_format)
|
||||||
{
|
{
|
||||||
case PIXELFMT_RGB8_Z24:
|
case PEControl::RGB8_Z24:
|
||||||
case PIXELFMT_RGBA6_Z24:
|
case PEControl::RGBA6_Z24:
|
||||||
case PIXELFMT_Z24:
|
case PEControl::Z24:
|
||||||
{
|
{
|
||||||
u32 *dst = (u32*)&efb[offset];
|
u32 *dst = (u32*)&efb[offset];
|
||||||
u32 val = *dst & 0xff000000;
|
u32 val = *dst & 0xff000000;
|
||||||
|
@ -185,9 +185,9 @@ namespace EfbInterface
|
||||||
*dst = val;
|
*dst = val;
|
||||||
}
|
}
|
||||||
break;
|
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 *dst = (u32*)&efb[offset];
|
||||||
u32 val = *dst & 0xff000000;
|
u32 val = *dst & 0xff000000;
|
||||||
val |= depth & 0x00ffffff;
|
val |= depth & 0x00ffffff;
|
||||||
|
@ -195,7 +195,7 @@ namespace EfbInterface
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format);
|
ERROR_LOG(VIDEO, "Unsupported pixel format: %i", static_cast<int>(bpmem.zcontrol.pixel_format));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,56 +205,57 @@ namespace EfbInterface
|
||||||
|
|
||||||
switch (bpmem.zcontrol.pixel_format)
|
switch (bpmem.zcontrol.pixel_format)
|
||||||
{
|
{
|
||||||
case PIXELFMT_RGB8_Z24:
|
case PEControl::RGB8_Z24:
|
||||||
case PIXELFMT_RGBA6_Z24:
|
case PEControl::RGBA6_Z24:
|
||||||
case PIXELFMT_Z24:
|
case PEControl::Z24:
|
||||||
{
|
{
|
||||||
depth = (*(u32*)&efb[offset]) & 0x00ffffff;
|
depth = (*(u32*)&efb[offset]) & 0x00ffffff;
|
||||||
}
|
}
|
||||||
break;
|
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;
|
depth = (*(u32*)&efb[offset]) & 0x00ffffff;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format);
|
ERROR_LOG(VIDEO, "Unsupported pixel format: %i", static_cast<int>(bpmem.zcontrol.pixel_format));
|
||||||
}
|
}
|
||||||
|
|
||||||
return depth;
|
return depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GetSourceFactor(u8 *srcClr, u8 *dstClr, int mode)
|
u32 GetSourceFactor(u8 *srcClr, u8 *dstClr, BlendMode::BlendFactor mode)
|
||||||
{
|
{
|
||||||
switch (mode) {
|
switch (mode)
|
||||||
case 0: // zero
|
{
|
||||||
|
case BlendMode::ZERO:
|
||||||
return 0;
|
return 0;
|
||||||
case 1: // one
|
case BlendMode::ONE:
|
||||||
return 0xffffffff;
|
return 0xffffffff;
|
||||||
case 2: // dstclr
|
case BlendMode::DSTCLR:
|
||||||
return *(u32*)dstClr;
|
return *(u32*)dstClr;
|
||||||
case 3: // invdstclr
|
case BlendMode::INVDSTCLR:
|
||||||
return 0xffffffff - *(u32*)dstClr;
|
return 0xffffffff - *(u32*)dstClr;
|
||||||
case 4: // srcalpha
|
case BlendMode::SRCALPHA:
|
||||||
{
|
{
|
||||||
u8 alpha = srcClr[ALP_C];
|
u8 alpha = srcClr[ALP_C];
|
||||||
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
|
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
|
||||||
return factor;
|
return factor;
|
||||||
}
|
}
|
||||||
case 5: // invsrcalpha
|
case BlendMode::INVSRCALPHA:
|
||||||
{
|
{
|
||||||
u8 alpha = 0xff - srcClr[ALP_C];
|
u8 alpha = 0xff - srcClr[ALP_C];
|
||||||
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
|
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
|
||||||
return factor;
|
return factor;
|
||||||
}
|
}
|
||||||
case 6: // dstalpha
|
case BlendMode::DSTALPHA:
|
||||||
{
|
{
|
||||||
u8 alpha = dstClr[ALP_C];
|
u8 alpha = dstClr[ALP_C];
|
||||||
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
|
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
|
||||||
return factor;
|
return factor;
|
||||||
}
|
}
|
||||||
case 7: // invdstalpha
|
case BlendMode::INVDSTALPHA:
|
||||||
{
|
{
|
||||||
u8 alpha = 0xff - dstClr[ALP_C];
|
u8 alpha = 0xff - dstClr[ALP_C];
|
||||||
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
|
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
|
||||||
|
@ -265,36 +266,37 @@ namespace EfbInterface
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GetDestinationFactor(u8 *srcClr, u8 *dstClr, int mode)
|
u32 GetDestinationFactor(u8 *srcClr, u8 *dstClr, BlendMode::BlendFactor mode)
|
||||||
{
|
{
|
||||||
switch (mode) {
|
switch (mode)
|
||||||
case 0: // zero
|
{
|
||||||
|
case BlendMode::ZERO:
|
||||||
return 0;
|
return 0;
|
||||||
case 1: // one
|
case BlendMode::ONE:
|
||||||
return 0xffffffff;
|
return 0xffffffff;
|
||||||
case 2: // srcclr
|
case BlendMode::SRCCLR:
|
||||||
return *(u32*)srcClr;
|
return *(u32*)srcClr;
|
||||||
case 3: // invsrcclr
|
case BlendMode::INVSRCCLR:
|
||||||
return 0xffffffff - *(u32*)srcClr;
|
return 0xffffffff - *(u32*)srcClr;
|
||||||
case 4: // srcalpha
|
case BlendMode::SRCALPHA:
|
||||||
{
|
{
|
||||||
u8 alpha = srcClr[ALP_C];
|
u8 alpha = srcClr[ALP_C];
|
||||||
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
|
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
|
||||||
return factor;
|
return factor;
|
||||||
}
|
}
|
||||||
case 5: // invsrcalpha
|
case BlendMode::INVSRCALPHA:
|
||||||
{
|
{
|
||||||
u8 alpha = 0xff - srcClr[ALP_C];
|
u8 alpha = 0xff - srcClr[ALP_C];
|
||||||
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
|
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
|
||||||
return factor;
|
return factor;
|
||||||
}
|
}
|
||||||
case 6: // dstalpha
|
case BlendMode::DSTALPHA:
|
||||||
{
|
{
|
||||||
u8 alpha = dstClr[ALP_C] & 0xff;
|
u8 alpha = dstClr[ALP_C] & 0xff;
|
||||||
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
|
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
|
||||||
return factor;
|
return factor;
|
||||||
}
|
}
|
||||||
case 7: // invdstalpha
|
case BlendMode::INVDSTALPHA:
|
||||||
{
|
{
|
||||||
u8 alpha = 0xff - dstClr[ALP_C];
|
u8 alpha = 0xff - dstClr[ALP_C];
|
||||||
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
|
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
|
||||||
|
@ -327,56 +329,56 @@ namespace EfbInterface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogicBlend(u32 srcClr, u32 &dstClr, int op)
|
void LogicBlend(u32 srcClr, u32 &dstClr, BlendMode::LogicOp op)
|
||||||
{
|
{
|
||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
case 0: // clear
|
case BlendMode::CLEAR:
|
||||||
dstClr = 0;
|
dstClr = 0;
|
||||||
break;
|
break;
|
||||||
case 1: // and
|
case BlendMode::AND:
|
||||||
dstClr = srcClr & dstClr;
|
dstClr = srcClr & dstClr;
|
||||||
break;
|
break;
|
||||||
case 2: // revand
|
case BlendMode::AND_REVERSE:
|
||||||
dstClr = srcClr & (~dstClr);
|
dstClr = srcClr & (~dstClr);
|
||||||
break;
|
break;
|
||||||
case 3: // copy
|
case BlendMode::COPY:
|
||||||
dstClr = srcClr;
|
dstClr = srcClr;
|
||||||
break;
|
break;
|
||||||
case 4: // invand
|
case BlendMode::AND_INVERTED:
|
||||||
dstClr = (~srcClr) & dstClr;
|
dstClr = (~srcClr) & dstClr;
|
||||||
break;
|
break;
|
||||||
case 5: // noop
|
case BlendMode::NOOP:
|
||||||
// Do nothing
|
// Do nothing
|
||||||
break;
|
break;
|
||||||
case 6: // xor
|
case BlendMode::XOR:
|
||||||
dstClr = srcClr ^ dstClr;
|
dstClr = srcClr ^ dstClr;
|
||||||
break;
|
break;
|
||||||
case 7: // or
|
case BlendMode::OR:
|
||||||
dstClr = srcClr | dstClr;
|
dstClr = srcClr | dstClr;
|
||||||
break;
|
break;
|
||||||
case 8: // nor
|
case BlendMode::NOR:
|
||||||
dstClr = ~(srcClr | dstClr);
|
dstClr = ~(srcClr | dstClr);
|
||||||
break;
|
break;
|
||||||
case 9: // equiv
|
case BlendMode::EQUIV:
|
||||||
dstClr = ~(srcClr ^ dstClr);
|
dstClr = ~(srcClr ^ dstClr);
|
||||||
break;
|
break;
|
||||||
case 10: // inv
|
case BlendMode::INVERT:
|
||||||
dstClr = ~dstClr;
|
dstClr = ~dstClr;
|
||||||
break;
|
break;
|
||||||
case 11: // revor
|
case BlendMode::OR_REVERSE:
|
||||||
dstClr = srcClr | (~dstClr);
|
dstClr = srcClr | (~dstClr);
|
||||||
break;
|
break;
|
||||||
case 12: // invcopy
|
case BlendMode::COPY_INVERTED:
|
||||||
dstClr = ~srcClr;
|
dstClr = ~srcClr;
|
||||||
break;
|
break;
|
||||||
case 13: // invor
|
case BlendMode::OR_INVERTED:
|
||||||
dstClr = (~srcClr) | dstClr;
|
dstClr = (~srcClr) | dstClr;
|
||||||
break;
|
break;
|
||||||
case 14: // nand
|
case BlendMode::NAND:
|
||||||
dstClr = ~(srcClr & dstClr);
|
dstClr = ~(srcClr & dstClr);
|
||||||
break;
|
break;
|
||||||
case 15: // set
|
case BlendMode::SET:
|
||||||
dstClr = 0xffffffff;
|
dstClr = 0xffffffff;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -584,33 +586,33 @@ namespace EfbInterface
|
||||||
|
|
||||||
switch (bpmem.zmode.func)
|
switch (bpmem.zmode.func)
|
||||||
{
|
{
|
||||||
case COMPARE_NEVER:
|
case ZMode::NEVER:
|
||||||
pass = false;
|
pass = false;
|
||||||
break;
|
break;
|
||||||
case COMPARE_LESS:
|
case ZMode::LESS:
|
||||||
pass = z < depth;
|
pass = z < depth;
|
||||||
break;
|
break;
|
||||||
case COMPARE_EQUAL:
|
case ZMode::EQUAL:
|
||||||
pass = z == depth;
|
pass = z == depth;
|
||||||
break;
|
break;
|
||||||
case COMPARE_LEQUAL:
|
case ZMode::LEQUAL:
|
||||||
pass = z <= depth;
|
pass = z <= depth;
|
||||||
break;
|
break;
|
||||||
case COMPARE_GREATER:
|
case ZMode::GREATER:
|
||||||
pass = z > depth;
|
pass = z > depth;
|
||||||
break;
|
break;
|
||||||
case COMPARE_NEQUAL:
|
case ZMode::NEQUAL:
|
||||||
pass = z != depth;
|
pass = z != depth;
|
||||||
break;
|
break;
|
||||||
case COMPARE_GEQUAL:
|
case ZMode::GEQUAL:
|
||||||
pass = z >= depth;
|
pass = z >= depth;
|
||||||
break;
|
break;
|
||||||
case COMPARE_ALWAYS:
|
case ZMode::ALWAYS:
|
||||||
pass = true;
|
pass = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pass = false;
|
pass = false;
|
||||||
ERROR_LOG(VIDEO, "Bad Z compare mode %i", bpmem.zmode.func);
|
ERROR_LOG(VIDEO, "Bad Z compare mode %i", (int)bpmem.zmode.func);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pass && bpmem.zmode.updateenable)
|
if (pass && bpmem.zmode.updateenable)
|
||||||
|
|
|
@ -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) {
|
switch (comp) {
|
||||||
case ALPHACMP_ALWAYS: return true;
|
case AlphaTest::ALWAYS: return true;
|
||||||
case ALPHACMP_NEVER: return false;
|
case AlphaTest::NEVER: return false;
|
||||||
case ALPHACMP_LEQUAL: return alpha <= ref;
|
case AlphaTest::LEQUAL: return alpha <= ref;
|
||||||
case ALPHACMP_LESS: return alpha < ref;
|
case AlphaTest::LESS: return alpha < ref;
|
||||||
case ALPHACMP_GEQUAL: return alpha >= ref;
|
case AlphaTest::GEQUAL: return alpha >= ref;
|
||||||
case ALPHACMP_GREATER: return alpha > ref;
|
case AlphaTest::GREATER: return alpha > ref;
|
||||||
case ALPHACMP_EQUAL: return alpha == ref;
|
case AlphaTest::EQUAL: return alpha == ref;
|
||||||
case ALPHACMP_NEQUAL: return alpha != ref;
|
case AlphaTest::NEQUAL: return alpha != ref;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1386,8 +1386,8 @@ void EncodeZ24halfscale(u8 *dst, u8 *src, u32 format)
|
||||||
|
|
||||||
void Encode(u8 *dest_ptr)
|
void Encode(u8 *dest_ptr)
|
||||||
{
|
{
|
||||||
int pixelformat = bpmem.zcontrol.pixel_format;
|
auto pixelformat = bpmem.zcontrol.pixel_format;
|
||||||
bool bFromZBuffer = pixelformat == PIXELFMT_Z24;
|
bool bFromZBuffer = pixelformat == PEControl::Z24;
|
||||||
bool bIsIntensityFmt = bpmem.triggerEFBCopy.intensity_fmt > 0;
|
bool bIsIntensityFmt = bpmem.triggerEFBCopy.intensity_fmt > 0;
|
||||||
u32 copyfmt = ((bpmem.triggerEFBCopy.target_pixel_format / 2) + ((bpmem.triggerEFBCopy.target_pixel_format & 1) * 8));
|
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 (bpmem.triggerEFBCopy.half_scale)
|
||||||
{
|
{
|
||||||
if (pixelformat == PIXELFMT_RGBA6_Z24)
|
if (pixelformat == PEControl::RGBA6_Z24)
|
||||||
EncodeRGBA6halfscale(dest_ptr, src, format);
|
EncodeRGBA6halfscale(dest_ptr, src, format);
|
||||||
else if (pixelformat == PIXELFMT_RGB8_Z24)
|
else if (pixelformat == PEControl::RGB8_Z24)
|
||||||
EncodeRGB8halfscale(dest_ptr, src, format);
|
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);
|
EncodeRGB8halfscale(dest_ptr, src, format);
|
||||||
else if (pixelformat == PIXELFMT_Z24)
|
else if (pixelformat == PEControl::Z24)
|
||||||
EncodeZ24halfscale(dest_ptr, src, format);
|
EncodeZ24halfscale(dest_ptr, src, format);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (pixelformat == PIXELFMT_RGBA6_Z24)
|
if (pixelformat == PEControl::RGBA6_Z24)
|
||||||
EncodeRGBA6(dest_ptr, src, format);
|
EncodeRGBA6(dest_ptr, src, format);
|
||||||
else if (pixelformat == PIXELFMT_RGB8_Z24)
|
else if (pixelformat == PEControl::RGB8_Z24)
|
||||||
EncodeRGB8(dest_ptr, src, format);
|
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);
|
EncodeRGB8(dest_ptr, src, format);
|
||||||
else if (pixelformat == PIXELFMT_Z24)
|
else if (pixelformat == PEControl::Z24)
|
||||||
EncodeZ24(dest_ptr, src, format);
|
EncodeZ24(dest_ptr, src, format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,10 +79,10 @@ void SetColorMask()
|
||||||
g_renderer->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)
|
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)
|
if (g_ActiveConfig.bEFBCopyEnable)
|
||||||
{
|
{
|
||||||
TextureCache::CopyRenderTargetToTexture(dstAddr, dstFormat, srcFormat,
|
TextureCache::CopyRenderTargetToTexture(dstAddr, dstFormat, srcFormat,
|
||||||
|
@ -111,11 +111,12 @@ void ClearScreen(const EFBRectangle &rc)
|
||||||
bool colorEnable = bpmem.blendmode.colorupdate;
|
bool colorEnable = bpmem.blendmode.colorupdate;
|
||||||
bool alphaEnable = bpmem.blendmode.alphaupdate;
|
bool alphaEnable = bpmem.blendmode.alphaupdate;
|
||||||
bool zEnable = bpmem.zmode.updateenable;
|
bool zEnable = bpmem.zmode.updateenable;
|
||||||
|
auto pixel_format = bpmem.zcontrol.pixel_format;
|
||||||
|
|
||||||
// (1): Disable unused color channels
|
// (1): Disable unused color channels
|
||||||
if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB8_Z24 ||
|
if (pixel_format == PEControl::RGB8_Z24 ||
|
||||||
bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16 ||
|
pixel_format == PEControl::RGB565_Z16 ||
|
||||||
bpmem.zcontrol.pixel_format == PIXELFMT_Z24)
|
pixel_format == PEControl::Z24)
|
||||||
{
|
{
|
||||||
alphaEnable = false;
|
alphaEnable = false;
|
||||||
}
|
}
|
||||||
|
@ -126,11 +127,11 @@ void ClearScreen(const EFBRectangle &rc)
|
||||||
u32 z = bpmem.clearZValue;
|
u32 z = bpmem.clearZValue;
|
||||||
|
|
||||||
// (2) drop additional accuracy
|
// (2) drop additional accuracy
|
||||||
if (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)
|
if (pixel_format == PEControl::RGBA6_Z24)
|
||||||
{
|
{
|
||||||
color = RGBA8ToRGBA6ToRGBA8(color);
|
color = RGBA8ToRGBA6ToRGBA8(color);
|
||||||
}
|
}
|
||||||
else if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16)
|
else if (pixel_format == PEControl::RGB565_Z16)
|
||||||
{
|
{
|
||||||
color = RGBA8ToRGB565ToRGBA8(color);
|
color = RGBA8ToRGB565ToRGBA8(color);
|
||||||
z = Z24ToZ16ToZ24(z);
|
z = Z24ToZ16ToZ24(z);
|
||||||
|
@ -156,8 +157,8 @@ void OnPixelFormatChange()
|
||||||
!g_ActiveConfig.backend_info.bSupportsFormatReinterpretation)
|
!g_ActiveConfig.backend_info.bSupportsFormatReinterpretation)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
u32 old_format = Renderer::GetPrevPixelFormat();
|
auto old_format = Renderer::GetPrevPixelFormat();
|
||||||
u32 new_format = bpmem.zcontrol.pixel_format;
|
auto new_format = bpmem.zcontrol.pixel_format;
|
||||||
|
|
||||||
// no need to reinterpret pixel data in these cases
|
// no need to reinterpret pixel data in these cases
|
||||||
if (new_format == old_format || old_format == (unsigned int)-1)
|
if (new_format == old_format || old_format == (unsigned int)-1)
|
||||||
|
@ -166,31 +167,31 @@ void OnPixelFormatChange()
|
||||||
// Check for pixel format changes
|
// Check for pixel format changes
|
||||||
switch (old_format)
|
switch (old_format)
|
||||||
{
|
{
|
||||||
case PIXELFMT_RGB8_Z24:
|
case PEControl::RGB8_Z24:
|
||||||
case PIXELFMT_Z24:
|
case PEControl::Z24:
|
||||||
// Z24 and RGB8_Z24 are treated equal, so just return in this case
|
// 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;
|
goto skip;
|
||||||
|
|
||||||
if (new_format == PIXELFMT_RGBA6_Z24)
|
if (new_format == PEControl::RGBA6_Z24)
|
||||||
convtype = 0;
|
convtype = 0;
|
||||||
else if (new_format == PIXELFMT_RGB565_Z16)
|
else if (new_format == PEControl::RGB565_Z16)
|
||||||
convtype = 1;
|
convtype = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PIXELFMT_RGBA6_Z24:
|
case PEControl::RGBA6_Z24:
|
||||||
if (new_format == PIXELFMT_RGB8_Z24 ||
|
if (new_format == PEControl::RGB8_Z24 ||
|
||||||
new_format == PIXELFMT_Z24)
|
new_format == PEControl::Z24)
|
||||||
convtype = 2;
|
convtype = 2;
|
||||||
else if (new_format == PIXELFMT_RGB565_Z16)
|
else if (new_format == PEControl::RGB565_Z16)
|
||||||
convtype = 3;
|
convtype = 3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PIXELFMT_RGB565_Z16:
|
case PEControl::RGB565_Z16:
|
||||||
if (new_format == PIXELFMT_RGB8_Z24 ||
|
if (new_format == PEControl::RGB8_Z24 ||
|
||||||
new_format == PIXELFMT_Z24)
|
new_format == PEControl::Z24)
|
||||||
convtype = 4;
|
convtype = 4;
|
||||||
else if (new_format == PIXELFMT_RGBA6_Z24)
|
else if (new_format == PEControl::RGBA6_Z24)
|
||||||
convtype = 5;
|
convtype = 5;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -200,14 +201,14 @@ void OnPixelFormatChange()
|
||||||
|
|
||||||
if (convtype == -1)
|
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<int>(old_format), static_cast<int>(new_format));
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_renderer->ReinterpretPixelData(convtype);
|
g_renderer->ReinterpretPixelData(convtype);
|
||||||
|
|
||||||
skip:
|
skip:
|
||||||
DEBUG_LOG(VIDEO, "pixelfmt: pixel=%d, zc=%d", new_format, bpmem.zcontrol.zformat);
|
DEBUG_LOG(VIDEO, "pixelfmt: pixel=%d, zc=%d", static_cast<int>(new_format), static_cast<int>(bpmem.zcontrol.zformat));
|
||||||
|
|
||||||
Renderer::StorePixelFormat(new_format);
|
Renderer::StorePixelFormat(new_format);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ void SetBlendMode();
|
||||||
void SetDitherMode();
|
void SetDitherMode();
|
||||||
void SetLogicOpMode();
|
void SetLogicOpMode();
|
||||||
void SetColorMask();
|
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);
|
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf);
|
||||||
void ClearScreen(const EFBRectangle &rc);
|
void ClearScreen(const EFBRectangle &rc);
|
||||||
void OnPixelFormatChange();
|
void OnPixelFormatChange();
|
||||||
|
|
|
@ -92,7 +92,7 @@ void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size
|
||||||
case BPMEM_ZCOMPARE:
|
case BPMEM_ZCOMPARE:
|
||||||
{
|
{
|
||||||
SetRegName(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* 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)" };
|
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"
|
snprintf(desc, desc_size, "EFB pixel format: %s\n"
|
||||||
|
@ -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.half_scale],
|
||||||
no_yes[copy.scale_invert],
|
no_yes[copy.scale_invert],
|
||||||
no_yes[copy.clear],
|
no_yes[copy.clear],
|
||||||
copy.frame_to_field,
|
(u32)copy.frame_to_field,
|
||||||
no_yes[copy.copy_to_xfb],
|
no_yes[copy.copy_to_xfb],
|
||||||
no_yes[copy.intensity_fmt],
|
no_yes[copy.intensity_fmt],
|
||||||
no_yes[copy.auto_conv]);
|
no_yes[copy.auto_conv]);
|
||||||
|
@ -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"
|
snprintf(desc, desc_size, "test 1: %s (ref: %#02x)\n"
|
||||||
"test 2: %s (ref: %#02x)\n"
|
"test 2: %s (ref: %#02x)\n"
|
||||||
"logic: %s\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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common/BitField.h"
|
||||||
#include "Common/Common.h"
|
#include "Common/Common.h"
|
||||||
|
|
||||||
#pragma pack(4)
|
#pragma pack(4)
|
||||||
|
@ -148,27 +149,6 @@
|
||||||
#define GX_TEVREG1 2
|
#define GX_TEVREG1 2
|
||||||
#define GX_TEVREG2 3
|
#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_DISABLE 0
|
||||||
#define ZTEXTURE_ADD 1
|
#define ZTEXTURE_ADD 1
|
||||||
#define ZTEXTURE_REPLACE 2
|
#define ZTEXTURE_REPLACE 2
|
||||||
|
@ -178,14 +158,6 @@ enum Compare
|
||||||
#define TevBias_SUBHALF 2
|
#define TevBias_SUBHALF 2
|
||||||
#define TevBias_COMPARE 3
|
#define TevBias_COMPARE 3
|
||||||
|
|
||||||
enum AlphaOp
|
|
||||||
{
|
|
||||||
ALPHAOP_AND = 0,
|
|
||||||
ALPHAOP_OR,
|
|
||||||
ALPHAOP_XOR,
|
|
||||||
ALPHAOP_XNOR,
|
|
||||||
};
|
|
||||||
|
|
||||||
union IND_MTXA
|
union IND_MTXA
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
|
@ -609,31 +581,52 @@ union X10Y10
|
||||||
|
|
||||||
// Framebuffer/pixel stuff (incl fog)
|
// 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
|
union BlendMode
|
||||||
{
|
{
|
||||||
struct
|
enum BlendFactor : u32
|
||||||
{
|
{
|
||||||
u32 blendenable : 1;
|
ZERO = 0,
|
||||||
u32 logicopenable : 1;
|
ONE = 1,
|
||||||
u32 dither : 1;
|
SRCCLR = 2, // for dst factor
|
||||||
u32 colorupdate : 1;
|
INVSRCCLR = 3, // for dst factor
|
||||||
u32 alphaupdate : 1;
|
DSTCLR = SRCCLR, // for src factor
|
||||||
u32 dstfactor : 3; //BLEND_ONE, BLEND_INV_SRc etc
|
INVDSTCLR = INVSRCCLR, // for src factor
|
||||||
u32 srcfactor : 3;
|
SRCALPHA = 4,
|
||||||
u32 subtract : 1;
|
INVSRCALPHA = 5,
|
||||||
u32 logicmode : 4;
|
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;
|
u32 hex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -733,12 +726,22 @@ struct FogParams
|
||||||
|
|
||||||
union ZMode
|
union ZMode
|
||||||
{
|
{
|
||||||
struct
|
enum CompareMode : u32
|
||||||
{
|
{
|
||||||
u32 testenable : 1;
|
NEVER = 0,
|
||||||
u32 func : 3;
|
LESS = 1,
|
||||||
u32 updateenable : 1; //size?
|
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;
|
u32 hex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -772,36 +775,38 @@ union FieldMask
|
||||||
u32 hex;
|
u32 hex;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PIXELFMT_RGB8_Z24 0
|
union PEControl
|
||||||
#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
|
|
||||||
{
|
{
|
||||||
struct
|
enum PixelFormat : u32
|
||||||
{
|
{
|
||||||
u32 pixel_format : 3; // PIXELFMT_X
|
RGB8_Z24 = 0,
|
||||||
u32 zformat : 3; // Z Compression for 16bit Z format
|
RGBA6_Z24 = 1,
|
||||||
u32 early_ztest : 1; // 1: before tex stage
|
RGB565_Z16 = 2,
|
||||||
u32 unused : 17;
|
Z24 = 3,
|
||||||
u32 rid : 8;
|
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;
|
u32 hex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -828,22 +833,25 @@ struct TCoordInfo
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
union ColReg
|
union TevReg
|
||||||
{
|
{
|
||||||
u32 hex;
|
u64 hex;
|
||||||
struct
|
|
||||||
{
|
|
||||||
s32 a : 11;
|
|
||||||
u32 : 1;
|
|
||||||
s32 b : 11;
|
|
||||||
u32 type : 1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TevReg
|
// Access to individual registers
|
||||||
{
|
BitField< 0, 32,u64> low;
|
||||||
ColReg low;
|
BitField<32, 32,u64> high;
|
||||||
ColReg 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
|
union TevKSel
|
||||||
|
@ -864,14 +872,32 @@ union TevKSel
|
||||||
|
|
||||||
union AlphaTest
|
union AlphaTest
|
||||||
{
|
{
|
||||||
struct
|
enum CompareMode : u32
|
||||||
{
|
{
|
||||||
u32 ref0 : 8;
|
NEVER = 0,
|
||||||
u32 ref1 : 8;
|
LESS = 1,
|
||||||
u32 comp0 : 3;
|
EQUAL = 2,
|
||||||
u32 comp1 : 3;
|
LEQUAL = 3,
|
||||||
u32 logic : 2;
|
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;
|
u32 hex;
|
||||||
|
|
||||||
enum TEST_RESULT
|
enum TEST_RESULT
|
||||||
|
@ -885,31 +911,31 @@ union AlphaTest
|
||||||
{
|
{
|
||||||
switch (logic)
|
switch (logic)
|
||||||
{
|
{
|
||||||
case 0: // AND
|
case AND:
|
||||||
if (comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS)
|
if (comp0 == ALWAYS && comp1 == ALWAYS)
|
||||||
return PASS;
|
return PASS;
|
||||||
if (comp0 == ALPHACMP_NEVER || comp1 == ALPHACMP_NEVER)
|
if (comp0 == NEVER || comp1 == NEVER)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: // OR
|
case OR:
|
||||||
if (comp0 == ALPHACMP_ALWAYS || comp1 == ALPHACMP_ALWAYS)
|
if (comp0 == ALWAYS || comp1 == ALWAYS)
|
||||||
return PASS;
|
return PASS;
|
||||||
if (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER)
|
if (comp0 == NEVER && comp1 == NEVER)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // XOR
|
case XOR:
|
||||||
if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_NEVER) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_ALWAYS))
|
if ((comp0 == ALWAYS && comp1 == NEVER) || (comp0 == NEVER && comp1 == ALWAYS))
|
||||||
return PASS;
|
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;
|
return FAIL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: // XNOR
|
case XNOR:
|
||||||
if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_NEVER) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_ALWAYS))
|
if ((comp0 == ALWAYS && comp1 == NEVER) || (comp0 == NEVER && comp1 == ALWAYS))
|
||||||
return FAIL;
|
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;
|
return PASS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -920,21 +946,20 @@ union AlphaTest
|
||||||
union UPE_Copy
|
union UPE_Copy
|
||||||
{
|
{
|
||||||
u32 Hex;
|
u32 Hex;
|
||||||
struct
|
|
||||||
{
|
BitField< 0,1,u32> clamp0; // if set clamp top
|
||||||
u32 clamp0 : 1; // if set clamp top
|
BitField< 1,1,u32> clamp1; // if set clamp bottom
|
||||||
u32 clamp1 : 1; // if set clamp bottom
|
BitField< 2,1,u32> yuv; // if set, color conversion from RGB to YUV
|
||||||
u32 yuv : 1; // 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)
|
||||||
u32 target_pixel_format : 4; // 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
|
||||||
u32 gamma : 2; // 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)
|
||||||
u32 half_scale : 1; // "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
|
||||||
u32 scale_invert : 1; // if set vertical scaling is on
|
BitField<11,1,u32> clear;
|
||||||
u32 clear : 1;
|
BitField<12,2,u32> frame_to_field; // 0 progressive ; 1 is reserved ; 2 = interlaced (even lines) ; 3 = interlaced 1 (odd lines)
|
||||||
u32 frame_to_field : 2; // 0 progressive ; 1 is reserved ; 2 = interlaced (even lines) ; 3 = interlaced 1 (odd lines)
|
BitField<14,1,u32> copy_to_xfb;
|
||||||
u32 copy_to_xfb : 1;
|
BitField<15,1,u32> intensity_fmt; // if set, is an intensity format (I4,I8,IA4,IA8)
|
||||||
u32 intensity_fmt : 1; // 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 auto_conv : 1; // if 0 automatic color conversion by texture format and pixel type
|
|
||||||
};
|
|
||||||
u32 tp_realFormat() {
|
u32 tp_realFormat() {
|
||||||
return target_pixel_format / 2 + (target_pixel_format & 1) * 8;
|
return target_pixel_format / 2 + (target_pixel_format & 1) * 8;
|
||||||
}
|
}
|
||||||
|
@ -996,7 +1021,7 @@ struct BPMemory
|
||||||
ZMode zmode; //40
|
ZMode zmode; //40
|
||||||
BlendMode blendmode; //41
|
BlendMode blendmode; //41
|
||||||
ConstantAlpha dstalpha; //42
|
ConstantAlpha dstalpha; //42
|
||||||
PE_CONTROL zcontrol; //43 GXSetZCompLoc, GXPixModeSync
|
PEControl zcontrol; //43 GXSetZCompLoc, GXPixModeSync
|
||||||
FieldMask fieldmask; //44
|
FieldMask fieldmask; //44
|
||||||
u32 drawdone; //45, bit1=1 if end of list
|
u32 drawdone; //45, bit1=1 if end of list
|
||||||
u32 unknown5; //46 clock?
|
u32 unknown5; //46 clock?
|
||||||
|
|
|
@ -133,8 +133,8 @@ void BPWritten(const BPCmd& bp)
|
||||||
SetLineWidth();
|
SetLineWidth();
|
||||||
break;
|
break;
|
||||||
case BPMEM_ZMODE: // Depth Control
|
case BPMEM_ZMODE: // Depth Control
|
||||||
PRIM_LOG("zmode: test=%d, func=%d, upd=%d", bpmem.zmode.testenable, bpmem.zmode.func,
|
PRIM_LOG("zmode: test=%d, func=%d, upd=%d", (int)bpmem.zmode.testenable,
|
||||||
bpmem.zmode.updateenable);
|
(int)bpmem.zmode.func, (int)bpmem.zmode.updateenable);
|
||||||
SetDepthMode();
|
SetDepthMode();
|
||||||
break;
|
break;
|
||||||
case BPMEM_BLENDMODE: // Blending Control
|
case BPMEM_BLENDMODE: // Blending Control
|
||||||
|
@ -142,8 +142,9 @@ void BPWritten(const BPCmd& bp)
|
||||||
if (bp.changes & 0xFFFF)
|
if (bp.changes & 0xFFFF)
|
||||||
{
|
{
|
||||||
PRIM_LOG("blendmode: en=%d, open=%d, colupd=%d, alphaupd=%d, dst=%d, src=%d, sub=%d, mode=%d",
|
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,
|
(int)bpmem.blendmode.blendenable, (int)bpmem.blendmode.logicopenable, (int)bpmem.blendmode.colorupdate,
|
||||||
bpmem.blendmode.dstfactor, bpmem.blendmode.srcfactor, bpmem.blendmode.subtract, bpmem.blendmode.logicmode);
|
(int)bpmem.blendmode.alphaupdate, (int)bpmem.blendmode.dstfactor, (int)bpmem.blendmode.srcfactor,
|
||||||
|
(int)bpmem.blendmode.subtract, (int)bpmem.blendmode.logicmode);
|
||||||
|
|
||||||
// Set LogicOp Blending Mode
|
// Set LogicOp Blending Mode
|
||||||
if (bp.changes & 0xF002) // logicopenable | logicmode
|
if (bp.changes & 0xF002) // logicopenable | logicmode
|
||||||
|
@ -304,8 +305,10 @@ void BPWritten(const BPCmd& bp)
|
||||||
PixelShaderManager::SetFogColorChanged();
|
PixelShaderManager::SetFogColorChanged();
|
||||||
break;
|
break;
|
||||||
case BPMEM_ALPHACOMPARE: // Compare Alpha Values
|
case BPMEM_ALPHACOMPARE: // Compare Alpha Values
|
||||||
PRIM_LOG("alphacmp: ref0=%d, ref1=%d, comp0=%d, comp1=%d, logic=%d", bpmem.alpha_test.ref0,
|
PRIM_LOG("alphacmp: ref0=%d, ref1=%d, comp0=%d, comp1=%d, logic=%d",
|
||||||
bpmem.alpha_test.ref1, bpmem.alpha_test.comp0, bpmem.alpha_test.comp1, bpmem.alpha_test.logic);
|
(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)
|
if (bp.changes & 0xFFFF)
|
||||||
PixelShaderManager::SetAlpha();
|
PixelShaderManager::SetAlpha();
|
||||||
if (bp.changes)
|
if (bp.changes)
|
||||||
|
@ -560,9 +563,9 @@ void BPWritten(const BPCmd& bp)
|
||||||
// don't compare with changes!
|
// don't compare with changes!
|
||||||
int num = (bp.address >> 1) & 0x3;
|
int num = (bp.address >> 1) & 0x3;
|
||||||
if ((bp.address & 1) == 0)
|
if ((bp.address & 1) == 0)
|
||||||
PixelShaderManager::SetColorChanged(bpmem.tevregs[num].low.type, num);
|
PixelShaderManager::SetColorChanged(bpmem.tevregs[num].type_ra, num);
|
||||||
else
|
else
|
||||||
PixelShaderManager::SetColorChanged(bpmem.tevregs[num].high.type, num);
|
PixelShaderManager::SetColorChanged(bpmem.tevregs[num].type_bg, num);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ void GFXDebuggerBase::DumpPixelShader(const std::string& path)
|
||||||
const std::string filename = StringFromFormat("%sdump_ps.txt", path.c_str());
|
const std::string filename = StringFromFormat("%sdump_ps.txt", path.c_str());
|
||||||
|
|
||||||
std::string output;
|
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)
|
if (!useDstAlpha)
|
||||||
{
|
{
|
||||||
output = "Destination alpha disabled:\n";
|
output = "Destination alpha disabled:\n";
|
||||||
|
|
|
@ -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)
|
void PixelShaderManager::SetColorChanged(int type, int num)
|
||||||
{
|
{
|
||||||
int4* c = type ? constants.kcolors : constants.colors;
|
int4* c = type ? constants.kcolors : constants.colors;
|
||||||
c[num][0] = bpmem.tevregs[num].low.a;
|
c[num][0] = bpmem.tevregs[num].red;
|
||||||
c[num][3] = bpmem.tevregs[num].low.b;
|
c[num][3] = bpmem.tevregs[num].alpha;
|
||||||
c[num][2] = bpmem.tevregs[num].high.a;
|
c[num][2] = bpmem.tevregs[num].blue;
|
||||||
c[num][1] = bpmem.tevregs[num].high.b;
|
c[num][1] = bpmem.tevregs[num].green;
|
||||||
dirty = true;
|
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]);
|
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]);
|
||||||
|
|
|
@ -64,7 +64,7 @@ int Renderer::s_LastEFBScale;
|
||||||
bool Renderer::s_skipSwap;
|
bool Renderer::s_skipSwap;
|
||||||
bool Renderer::XFBWrited;
|
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_numeratorX = 1;
|
||||||
unsigned int Renderer::efb_scale_numeratorY = 1;
|
unsigned int Renderer::efb_scale_numeratorY = 1;
|
||||||
unsigned int Renderer::efb_scale_denominatorX = 1;
|
unsigned int Renderer::efb_scale_denominatorX = 1;
|
||||||
|
@ -89,7 +89,7 @@ Renderer::Renderer()
|
||||||
Renderer::~Renderer()
|
Renderer::~Renderer()
|
||||||
{
|
{
|
||||||
// invalidate previous efb format
|
// 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;
|
efb_scale_numeratorX = efb_scale_numeratorY = efb_scale_denominatorX = efb_scale_denominatorY = 1;
|
||||||
|
|
||||||
|
|
|
@ -111,8 +111,8 @@ public:
|
||||||
|
|
||||||
virtual bool SaveScreenshot(const std::string &filename, const TargetRectangle &rc) = 0;
|
virtual bool SaveScreenshot(const std::string &filename, const TargetRectangle &rc) = 0;
|
||||||
|
|
||||||
static unsigned int GetPrevPixelFormat() { return prev_efb_format; }
|
static PEControl::PixelFormat GetPrevPixelFormat() { return prev_efb_format; }
|
||||||
static void StorePixelFormat(unsigned int new_format) { prev_efb_format = new_format; }
|
static void StorePixelFormat(PEControl::PixelFormat new_format) { prev_efb_format = new_format; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ protected:
|
||||||
static bool XFBWrited;
|
static bool XFBWrited;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static unsigned int prev_efb_format;
|
static PEControl::PixelFormat prev_efb_format;
|
||||||
static unsigned int efb_scale_numeratorX;
|
static unsigned int efb_scale_numeratorX;
|
||||||
static unsigned int efb_scale_numeratorY;
|
static unsigned int efb_scale_numeratorY;
|
||||||
static unsigned int efb_scale_denominatorX;
|
static unsigned int efb_scale_denominatorX;
|
||||||
|
|
|
@ -572,7 +572,7 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int const stage,
|
||||||
return ReturnEntry(stage, entry);
|
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)
|
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf)
|
||||||
{
|
{
|
||||||
// Emulation methods:
|
// 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[0] = ColorMask[1] = ColorMask[2] = ColorMask[3] = 255.0f;
|
||||||
ColorMask[4] = ColorMask[5] = ColorMask[6] = ColorMask[7] = 1.0f / 255.0f;
|
ColorMask[4] = ColorMask[5] = ColorMask[6] = ColorMask[7] = 1.0f / 255.0f;
|
||||||
unsigned int cbufid = -1;
|
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)
|
switch (dstFormat)
|
||||||
{
|
{
|
||||||
|
|
|
@ -77,7 +77,7 @@ public:
|
||||||
virtual void Load(unsigned int width, unsigned int height,
|
virtual void Load(unsigned int width, unsigned int height,
|
||||||
unsigned int expanded_width, unsigned int level) = 0;
|
unsigned int expanded_width, unsigned int level) = 0;
|
||||||
virtual void FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
|
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,
|
bool isIntensity, bool scaleByHalf, unsigned int cbufid,
|
||||||
const float *colmat) = 0;
|
const float *colmat) = 0;
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ public:
|
||||||
|
|
||||||
static TCacheEntryBase* Load(unsigned int stage, u32 address, unsigned int width, unsigned int height,
|
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);
|
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);
|
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf);
|
||||||
|
|
||||||
static void RequestInvalidateTextureCache();
|
static void RequestInvalidateTextureCache();
|
||||||
|
|
|
@ -219,7 +219,7 @@ void VertexManager::Flush()
|
||||||
bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass &&
|
bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass &&
|
||||||
bpmem.dstalpha.enable &&
|
bpmem.dstalpha.enable &&
|
||||||
bpmem.blendmode.alphaupdate &&
|
bpmem.blendmode.alphaupdate &&
|
||||||
bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
|
bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24;
|
||||||
|
|
||||||
if (PerfQueryBase::ShouldEmulate())
|
if (PerfQueryBase::ShouldEmulate())
|
||||||
g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP);
|
g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP);
|
||||||
|
|
127
Source/UnitTests/Common/BitFieldTest.cpp
Normal file
127
Source/UnitTests/Common/BitFieldTest.cpp
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
// Copyright 2014 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
add_dolphin_test(BitFieldTest BitFieldTest.cpp common)
|
||||||
add_dolphin_test(CommonFuncsTest CommonFuncsTest.cpp common)
|
add_dolphin_test(CommonFuncsTest CommonFuncsTest.cpp common)
|
||||||
add_dolphin_test(FifoQueueTest FifoQueueTest.cpp common)
|
add_dolphin_test(FifoQueueTest FifoQueueTest.cpp common)
|
||||||
add_dolphin_test(FixedSizeQueueTest FixedSizeQueueTest.cpp common)
|
add_dolphin_test(FixedSizeQueueTest FixedSizeQueueTest.cpp common)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue