Skip to content

Commit

Permalink
Merge pull request #11 from PatrickvL/LibYuv
Browse files Browse the repository at this point in the history
Use libyuv for YUY2ToARGB conversion
  • Loading branch information
PatrickvL committed Apr 13, 2017
2 parents 8c4c512 + cb8d9d0 commit 88a8f63
Show file tree
Hide file tree
Showing 7 changed files with 254 additions and 95 deletions.
2 changes: 2 additions & 0 deletions build/win32/Cxbx.vcxproj
Expand Up @@ -283,6 +283,7 @@ $(SOLUTIONDIR)Export.bat</Command>
<ClInclude Include="..\..\src\CxbxKrnl\HLEDataBase\XOnline.1.0.5849.h" />
<ClInclude Include="..\..\src\CxbxKrnl\HLEIntercept.h" />
<ClInclude Include="..\..\src\CxbxKrnl\LibRc4.h" />
<ClInclude Include="..\..\src\CxbxKrnl\libyuv_extract.h" />
<ClInclude Include="..\..\src\CxbxKrnl\MemoryManager.h" />
<ClInclude Include="..\..\src\CxbxKrnl\nv2a_int.h" />
<ClInclude Include="..\..\src\CxbxKrnl\OOVPA.h" />
Expand Down Expand Up @@ -543,6 +544,7 @@ $(SOLUTIONDIR)Export.bat</Command>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\..\src\CxbxKrnl\LibRc4.cpp" />
<ClCompile Include="..\..\src\CxbxKrnl\libyuv_extract.cpp" />
<ClCompile Include="..\..\src\CxbxKrnl\MemoryManager.cpp" />
<ClCompile Include="..\..\src\CxbxKrnl\ResourceTracker.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
Expand Down
6 changes: 6 additions & 0 deletions build/win32/Cxbx.vcxproj.filters
Expand Up @@ -199,6 +199,9 @@
<ClCompile Include="..\..\src\Cxbx\DlgAbout.cpp">
<Filter>GUI</Filter>
</ClCompile>
<ClCompile Include="..\..\src\CxbxKrnl\libyuv_extract.cpp">
<Filter>Emulator</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\Cxbx\DlgControllerConfig.h">
Expand Down Expand Up @@ -549,6 +552,9 @@
<ClInclude Include="..\..\src\Cxbx\DlgAbout.h">
<Filter>GUI</Filter>
</ClInclude>
<ClInclude Include="..\..\src\CxbxKrnl\libyuv_extract.h">
<Filter>Emulator</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\resource\About.jpg">
Expand Down
93 changes: 2 additions & 91 deletions src/CxbxKrnl/EmuD3D8.cpp
Expand Up @@ -53,6 +53,7 @@ namespace xboxkrnl
#include "EmuAlloc.h"
#include "MemoryManager.h"
#include "EmuXTL.h"
#include "libyuv_extract.h" // for YUY2ToARGB

#include <assert.h>
#include <process.h>
Expand Down Expand Up @@ -6060,13 +6061,6 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_EnableOverlay)
return;
}

// Based on http://codereview.stackexchange.com/questions/6502/fastest-way-to-clamp-an-integer-to-the-range-0-255
inline uint08 ClampIntToByte(int x)
{
int r = x > 255 ? 255 : x;
return r < 0 ? 0 : (uint08)r;
}

// ******************************************************************
// * patch: D3DDevice_UpdateOverlay
// ******************************************************************
Expand Down Expand Up @@ -6181,8 +6175,6 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_UpdateOverlay)
{
uint08 *pbSource = (uint08*)pSurface->Lock;
uint08 *pbDest = (uint08*)LockedRectDest.pBits;
uint32 dx = 0, dy = 0;
uint32 dwImageSize = g_dwOverlayP*g_dwOverlayH;

// Get backbuffer dimenions; TODO : remember this once, at creation/resize time
D3DSURFACE_DESC BackBufferDesc;
Expand All @@ -6194,89 +6186,8 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_UpdateOverlay)
uint32 W = min(g_dwOverlayW, BackBufferDesc.Width);
uint32 H = min(g_dwOverlayH, BackBufferDesc.Height);

// grayscale - TODO : Either remove or make configurable
if(false)
{
// Clip to backbuffer height :
for(uint32 y=0;y<H;y++)
{
uint32 stop = g_dwOverlayW *4;
for(uint32 x=0;x<stop;x+=4)
{
uint08 Y = *pbSource;

// Clip to backbuffer width :
if (x / 4 < W)
{
pbDest[x + 0] = Y;
pbDest[x + 1] = Y;
pbDest[x + 2] = Y;
pbDest[x + 3] = 0xFF;
}

pbSource += 2;
}

pbDest += LockedRectDest.Pitch;
}
}
// full color conversion (YUY2->XRGB)
else
{
// The following is a combination of https://pastebin.com/mDcwqJV3 and
// https://en.wikipedia.org/wiki/YUV#Y.E2.80.B2UV422_to_RGB888_conversion
// TODO : Improve this to use a library, or SIMD instructions like in
// https://github.com/descampsa/yuv2rgb/blob/master/yuv_rgb.c
// https://github.com/lemenkov/libyuv/blob/master/source/row_win.cc#L100
const int K1 = int(1.402f * (1 << 16));
const int K2 = int(0.334f * (1 << 16));
const int K3 = int(0.714f * (1 << 16));
const int K4 = int(1.772f * (1 << 16));

for(uint32 v=0;v<dwImageSize;v+=4)
{
// Clip to backbuffer width :
if (dx < W)
{
uint8_t Y0 = pbSource[0];
uint8_t Cb = pbSource[1];
uint8_t Y1 = pbSource[2];
uint8_t Cr = pbSource[3];

int nCb = Cb - 128;
int nCr = Cr - 128;

int Rd = (K1 * nCr) >> 16;
int Gd = ((K2 * nCb) + (K3 * nCr)) >> 16;
int Bd = (K4 * nCb) >> 16;

uint32 i = (dy * LockedRectDest.Pitch) + (dx * 4);

pbDest[i + 0] = ClampIntToByte((int)Y0 + Bd);
pbDest[i + 1] = ClampIntToByte((int)Y0 - Gd);
pbDest[i + 2] = ClampIntToByte((int)Y0 + Rd);
pbDest[i + 3] = 0xFF;

pbDest[i + 4] = ClampIntToByte((int)Y1 + Bd);
pbDest[i + 5] = ClampIntToByte((int)Y1 - Gd);
pbDest[i + 6] = ClampIntToByte((int)Y1 + Rd);
pbDest[i + 7] = 0xFF;
}

pbSource += 4;
dx += 2;
if ((dx % g_dwOverlayW) == 0)
{
dy++;
// Clip to backbuffer height :
if (dy >= H)
break;

dx = 0;
}

}
}
YUY2ToARGB(pbSource, g_dwOverlayP, pbDest, BackBufferDesc.Width * 4, W, H);

pBackBuffer->UnlockRect();
pBackBuffer->Release();
Expand Down
1 change: 0 additions & 1 deletion src/CxbxKrnl/EmuD3D8/State.cpp
Expand Up @@ -44,7 +44,6 @@ DWORD *XTL::EmuD3DDeferredRenderState;
DWORD *XTL::EmuD3DDeferredTextureState;

extern uint32 g_BuildVersion;
extern uint32 g_OrigBuildVersion;

// ******************************************************************
// * patch: UpdateDeferredStates
Expand Down
3 changes: 0 additions & 3 deletions src/CxbxKrnl/HLEIntercept.cpp
Expand Up @@ -55,7 +55,6 @@ uint32 fcount = 0;
void * funcExclude[2048] = { nullptr };

uint32 g_BuildVersion;
uint32 g_OrigBuildVersion;

static std::vector<xbaddr> vCacheOut;

Expand Down Expand Up @@ -331,7 +330,6 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
{
// Save D3D8 build version
g_BuildVersion = BuildVersion;
g_OrigBuildVersion = OrigBuildVersion;

xbaddr lower = pXbeHeader->dwBaseAddr;
xbaddr upper = pXbeHeader->dwBaseAddr + pXbeHeader->dwSizeofImage;
Expand Down Expand Up @@ -506,7 +504,6 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
// {
// // Save D3D8 build version
// g_BuildVersion = BuildVersion;
// g_OrigBuildVersion = OrigBuildVersion;

// xbaddr lower = pXbeHeader->dwBaseAddr;
// xbaddr upper = pXbeHeader->dwBaseAddr + pXbeHeader->dwSizeofImage;
Expand Down

0 comments on commit 88a8f63

Please sign in to comment.