Minor code formatting:
First step to bring a level of consistency between the video plug-ins - variable names, spacing, function names, function order, comments, file names. This will help us identify common code for VideoMerge. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6235 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
73f4bc4598
commit
88cd9f3df1
|
@ -716,11 +716,11 @@
|
||||||
Name="Render"
|
Name="Render"
|
||||||
>
|
>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\FBManager.cpp"
|
RelativePath=".\Src\FramebufferManager.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\FBManager.h"
|
RelativePath=".\Src\FramebufferManager.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
|
|
@ -16,16 +16,21 @@
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include "BPFunctions.h"
|
#include "BPFunctions.h"
|
||||||
#include "D3DBase.h"
|
|
||||||
#include "VideoConfig.h"
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include "D3DBase.h"
|
||||||
|
#include "Render.h"
|
||||||
#include "TextureCache.h"
|
#include "TextureCache.h"
|
||||||
#include "VertexManager.h"
|
#include "VertexManager.h"
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
#include "Render.h"
|
#include "VideoConfig.h"
|
||||||
|
|
||||||
namespace BPFunctions
|
namespace BPFunctions
|
||||||
{
|
{
|
||||||
|
// ----------------------------------------------
|
||||||
|
// State translation lookup tables
|
||||||
|
// Reference: Yet Another Gamecube Documentation
|
||||||
|
// ----------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
void FlushPipeline()
|
void FlushPipeline()
|
||||||
{
|
{
|
||||||
|
@ -72,21 +77,18 @@ void SetColorMask(const BPCmd &bp)
|
||||||
|
|
||||||
void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 ©fmt, const int &scaleByHalf)
|
void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 ©fmt, const int &scaleByHalf)
|
||||||
{
|
{
|
||||||
|
// bpmem.zcontrol.pixel_format to PIXELFMT_Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format)
|
||||||
if (!g_ActiveConfig.bEFBCopyDisable)
|
if (!g_ActiveConfig.bEFBCopyDisable)
|
||||||
{
|
{
|
||||||
// if (g_ActiveConfig.bCopyEFBToTexture)
|
|
||||||
// {
|
|
||||||
TextureCache::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
|
TextureCache::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// PanicAlert("TODO: Implement EFB copying to RAM %s %d\n", __FILE__, __LINE__);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc)
|
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc)
|
||||||
{
|
{
|
||||||
|
// it seems that the GC is able to alpha blend on color-fill
|
||||||
|
// we cant do that so if alpha is != 255 we skip it
|
||||||
|
|
||||||
bool colorEnable = bpmem.blendmode.colorupdate;
|
bool colorEnable = bpmem.blendmode.colorupdate;
|
||||||
bool alphaEnable = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 && bpmem.blendmode.alphaupdate);
|
bool alphaEnable = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 && bpmem.blendmode.alphaupdate);
|
||||||
bool zEnable = bpmem.zmode.updateenable;
|
bool zEnable = bpmem.zmode.updateenable;
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace D3D
|
||||||
|
|
||||||
CD3DFont font;
|
CD3DFont font;
|
||||||
|
|
||||||
#define MAX_NUM_VERTICES 300
|
#define MAX_NUM_VERTICES 50*6
|
||||||
struct FONT2DVERTEX {
|
struct FONT2DVERTEX {
|
||||||
float x,y,z;
|
float x,y,z;
|
||||||
float col[4];
|
float col[4];
|
||||||
|
@ -102,9 +102,10 @@ const char fontvertshader[] = {
|
||||||
|
|
||||||
int CD3DFont::Init()
|
int CD3DFont::Init()
|
||||||
{
|
{
|
||||||
|
// Create vertex buffer for the letters
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
// prepare to create a bitmap
|
// Prepare to create a bitmap
|
||||||
unsigned int* pBitmapBits;
|
unsigned int* pBitmapBits;
|
||||||
BITMAPINFO bmi;
|
BITMAPINFO bmi;
|
||||||
ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER));
|
ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER));
|
||||||
|
@ -115,7 +116,7 @@ int CD3DFont::Init()
|
||||||
bmi.bmiHeader.biCompression = BI_RGB;
|
bmi.bmiHeader.biCompression = BI_RGB;
|
||||||
bmi.bmiHeader.biBitCount = 32;
|
bmi.bmiHeader.biBitCount = 32;
|
||||||
|
|
||||||
// create a DC and a bitmap for the font
|
// Create a DC and a bitmap for the font
|
||||||
HDC hDC = CreateCompatibleDC(NULL);
|
HDC hDC = CreateCompatibleDC(NULL);
|
||||||
HBITMAP hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&pBitmapBits, NULL, 0);
|
HBITMAP hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&pBitmapBits, NULL, 0);
|
||||||
SetMapMode(hDC, MM_TEXT);
|
SetMapMode(hDC, MM_TEXT);
|
||||||
|
@ -130,7 +131,7 @@ int CD3DFont::Init()
|
||||||
HGDIOBJ hOldbmBitmap = SelectObject(hDC, hbmBitmap);
|
HGDIOBJ hOldbmBitmap = SelectObject(hDC, hbmBitmap);
|
||||||
HGDIOBJ hOldFont = SelectObject(hDC, hFont);
|
HGDIOBJ hOldFont = SelectObject(hDC, hFont);
|
||||||
|
|
||||||
// set text properties
|
// Set text properties
|
||||||
SetTextColor(hDC, 0xFFFFFF);
|
SetTextColor(hDC, 0xFFFFFF);
|
||||||
SetBkColor (hDC, 0);
|
SetBkColor (hDC, 0);
|
||||||
SetTextAlign(hDC, TA_TOP);
|
SetTextAlign(hDC, TA_TOP);
|
||||||
|
@ -139,8 +140,8 @@ int CD3DFont::Init()
|
||||||
GetTextMetricsW(hDC, &tm);
|
GetTextMetricsW(hDC, &tm);
|
||||||
m_LineHeight = tm.tmHeight;
|
m_LineHeight = tm.tmHeight;
|
||||||
|
|
||||||
// loop through all printable characters and output them to the bitmap
|
// Loop through all printable characters and output them to the bitmap
|
||||||
// meanwhile, keep track of the corresponding tex coords for each character.
|
// Meanwhile, keep track of the corresponding tex coords for each character.
|
||||||
int x = 0, y = 0;
|
int x = 0, y = 0;
|
||||||
char str[2] = "\0";
|
char str[2] = "\0";
|
||||||
for (int c = 0; c < 127 - 32; c++)
|
for (int c = 0; c < 127 - 32; c++)
|
||||||
|
@ -155,15 +156,15 @@ int CD3DFont::Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtTextOutA(hDC, x+1, y+0, ETO_OPAQUE | ETO_CLIPPED, NULL, str, 1, NULL);
|
ExtTextOutA(hDC, x+1, y+0, ETO_OPAQUE | ETO_CLIPPED, NULL, str, 1, NULL);
|
||||||
m_fTexCoords[c][0] = (float) x /m_dwTexWidth;
|
m_fTexCoords[c][0] = ((float)(x+0))/m_dwTexWidth;
|
||||||
m_fTexCoords[c][1] = (float) y /m_dwTexHeight;
|
m_fTexCoords[c][1] = ((float)(y+0))/m_dwTexHeight;
|
||||||
m_fTexCoords[c][2] = (float)(x+size.cx)/m_dwTexWidth;
|
m_fTexCoords[c][2] = ((float)(x+0+size.cx))/m_dwTexWidth;
|
||||||
m_fTexCoords[c][3] = (float)(y+size.cy)/m_dwTexHeight;
|
m_fTexCoords[c][3] = ((float)(y+0+size.cy))/m_dwTexHeight;
|
||||||
|
|
||||||
x += size.cx + 3; // 3 to work around annoying ij conflict (part of the j ends up with the i)
|
x += size.cx + 3; // 3 to work around annoying ij conflict (part of the j ends up with the i)
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a new texture for the font
|
// Create a new texture for the font
|
||||||
// possible optimization: store the converted data in a buffer and fill the texture on creation.
|
// possible optimization: store the converted data in a buffer and fill the texture on creation.
|
||||||
// That way, we can use a static texture
|
// That way, we can use a static texture
|
||||||
ID3D11Texture2D* buftex;
|
ID3D11Texture2D* buftex;
|
||||||
|
@ -178,7 +179,7 @@ int CD3DFont::Init()
|
||||||
}
|
}
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)buftex, "texture of a CD3DFont object");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)buftex, "texture of a CD3DFont object");
|
||||||
|
|
||||||
// lock the surface and write the alpha values for the set pixels
|
// Lock the surface and write the alpha values for the set pixels
|
||||||
D3D11_MAPPED_SUBRESOURCE texmap;
|
D3D11_MAPPED_SUBRESOURCE texmap;
|
||||||
hr = context->Map(buftex, 0, D3D11_MAP_WRITE_DISCARD, 0, &texmap);
|
hr = context->Map(buftex, 0, D3D11_MAP_WRITE_DISCARD, 0, &texmap);
|
||||||
if (FAILED(hr)) PanicAlert("Failed to map a texture at %s %d\n", __FILE__, __LINE__);
|
if (FAILED(hr)) PanicAlert("Failed to map a texture at %s %d\n", __FILE__, __LINE__);
|
||||||
|
@ -193,7 +194,7 @@ int CD3DFont::Init()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up
|
// Done updating texture, so clean up used objects
|
||||||
context->Unmap(buftex, 0);
|
context->Unmap(buftex, 0);
|
||||||
hr = D3D::device->CreateShaderResourceView(buftex, NULL, &m_pTexture);
|
hr = D3D::device->CreateShaderResourceView(buftex, NULL, &m_pTexture);
|
||||||
if (FAILED(hr)) PanicAlert("Failed to create shader resource view at %s %d\n", __FILE__, __LINE__);
|
if (FAILED(hr)) PanicAlert("Failed to create shader resource view at %s %d\n", __FILE__, __LINE__);
|
||||||
|
@ -274,7 +275,8 @@ int CD3DFont::Shutdown()
|
||||||
|
|
||||||
int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dwColor, const char* strText, bool center)
|
int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dwColor, const char* strText, bool center)
|
||||||
{
|
{
|
||||||
if (!m_pVB) return 0;
|
if (!m_pVB)
|
||||||
|
return 0;
|
||||||
|
|
||||||
UINT stride = sizeof(FONT2DVERTEX);
|
UINT stride = sizeof(FONT2DVERTEX);
|
||||||
UINT bufoffset = 0;
|
UINT bufoffset = 0;
|
||||||
|
@ -288,7 +290,7 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw
|
||||||
float sy = 1.f - y * scaley;
|
float sy = 1.f - y * scaley;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
// fill vertex buffer
|
// Fill vertex buffer
|
||||||
FONT2DVERTEX* pVertices;
|
FONT2DVERTEX* pVertices;
|
||||||
int dwNumTriangles = 0L;
|
int dwNumTriangles = 0L;
|
||||||
|
|
||||||
|
@ -336,7 +338,8 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw
|
||||||
sx = fStartX;
|
sx = fStartX;
|
||||||
sy -= scaley * size;
|
sy -= scaley * size;
|
||||||
}
|
}
|
||||||
if (c < (' ')) continue;
|
if (c < (' '))
|
||||||
|
continue;
|
||||||
|
|
||||||
c -= 32;
|
c -= 32;
|
||||||
float tx1 = m_fTexCoords[c][0];
|
float tx1 = m_fTexCoords[c][0];
|
||||||
|
@ -348,10 +351,10 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw
|
||||||
float h = (float)(ty1-ty2) * m_dwTexHeight * scaley * sizeratio;
|
float h = (float)(ty1-ty2) * m_dwTexHeight * scaley * sizeratio;
|
||||||
|
|
||||||
FONT2DVERTEX v[6];
|
FONT2DVERTEX v[6];
|
||||||
v[0] = InitFont2DVertex( sx, h+sy, dwColor, tx1, ty2);
|
v[0] = InitFont2DVertex(sx, sy+h, dwColor, tx1, ty2);
|
||||||
v[1] = InitFont2DVertex( sx, sy, dwColor, tx1, ty1);
|
v[1] = InitFont2DVertex(sx, sy, dwColor, tx1, ty1);
|
||||||
v[2] = InitFont2DVertex(w+sx, h+sy, dwColor, tx2, ty2);
|
v[2] = InitFont2DVertex(sx+w, sy+h, dwColor, tx2, ty2);
|
||||||
v[3] = InitFont2DVertex(w+sx, sy, dwColor, tx2, ty1);
|
v[3] = InitFont2DVertex(sx+w, sy, dwColor, tx2, ty1);
|
||||||
v[4] = v[2];
|
v[4] = v[2];
|
||||||
v[5] = v[1];
|
v[5] = v[1];
|
||||||
|
|
||||||
|
|
|
@ -19,12 +19,12 @@
|
||||||
#include "D3DTexture.h"
|
#include "D3DTexture.h"
|
||||||
#include "D3DUtil.h"
|
#include "D3DUtil.h"
|
||||||
#include "Render.h"
|
#include "Render.h"
|
||||||
#include "FBManager.h"
|
#include "FramebufferManager.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "PixelShaderCache.h"
|
#include "PixelShaderCache.h"
|
||||||
#include "VertexShaderCache.h"
|
#include "VertexShaderCache.h"
|
||||||
|
|
||||||
FramebufferManager FBManager;
|
FramebufferManager g_framebufferManager;
|
||||||
|
|
||||||
D3DTexture2D* &FramebufferManager::GetEFBColorTexture() { return m_efb.color_tex; }
|
D3DTexture2D* &FramebufferManager::GetEFBColorTexture() { return m_efb.color_tex; }
|
||||||
ID3D11Texture2D* &FramebufferManager::GetEFBColorStagingBuffer() { return m_efb.color_staging_buf; }
|
ID3D11Texture2D* &FramebufferManager::GetEFBColorStagingBuffer() { return m_efb.color_staging_buf; }
|
||||||
|
@ -120,7 +120,7 @@ FramebufferManager::VirtualXFBListType::iterator FramebufferManager::findVirtual
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
// that address is not in the Virtual XFB list.
|
// That address is not in the Virtual XFB list.
|
||||||
return m_virtualXFBList.end();
|
return m_virtualXFBList.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ void FramebufferManager::replaceVirtualXFB()
|
||||||
s32 srcUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight;
|
s32 srcUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight;
|
||||||
s32 lineSize = 2 * it->xfbWidth;
|
s32 lineSize = 2 * it->xfbWidth;
|
||||||
|
|
||||||
it++;
|
++it;
|
||||||
|
|
||||||
while (it != m_virtualXFBList.end())
|
while (it != m_virtualXFBList.end())
|
||||||
{
|
{
|
||||||
|
@ -141,7 +141,7 @@ void FramebufferManager::replaceVirtualXFB()
|
||||||
|
|
||||||
if (dstLower >= srcLower && dstUpper <= srcUpper)
|
if (dstLower >= srcLower && dstUpper <= srcUpper)
|
||||||
{
|
{
|
||||||
// invalidate the data
|
// Invalidate the data
|
||||||
it->xfbAddr = 0;
|
it->xfbAddr = 0;
|
||||||
it->xfbHeight = 0;
|
it->xfbHeight = 0;
|
||||||
it->xfbWidth = 0;
|
it->xfbWidth = 0;
|
||||||
|
@ -162,7 +162,7 @@ void FramebufferManager::replaceVirtualXFB()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,8 +195,10 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
|
||||||
targetSource.right = (int)(sourceRc.right * scaleX);
|
targetSource.right = (int)(sourceRc.right * scaleX);
|
||||||
unsigned int target_width = targetSource.right - targetSource.left;
|
unsigned int target_width = targetSource.right - targetSource.left;
|
||||||
unsigned int target_height = targetSource.bottom - targetSource.top;
|
unsigned int target_height = targetSource.bottom - targetSource.top;
|
||||||
if (it != m_virtualXFBList.end()) // overwrite an existing Virtual XFB
|
if (it != m_virtualXFBList.end())
|
||||||
{
|
{
|
||||||
|
// Overwrite an existing Virtual XFB.
|
||||||
|
|
||||||
it->xfbAddr = xfbAddr;
|
it->xfbAddr = xfbAddr;
|
||||||
it->xfbWidth = fbWidth;
|
it->xfbWidth = fbWidth;
|
||||||
it->xfbHeight = fbHeight;
|
it->xfbHeight = fbHeight;
|
||||||
|
@ -222,8 +224,9 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
|
||||||
// keep stale XFB data from being used
|
// keep stale XFB data from being used
|
||||||
replaceVirtualXFB();
|
replaceVirtualXFB();
|
||||||
}
|
}
|
||||||
else // create a new Virtual XFB and place it at the front of the list
|
else
|
||||||
{
|
{
|
||||||
|
// Create a new Virtual XFB and place it at the front of the list.
|
||||||
VirtualXFB newVirt;
|
VirtualXFB newVirt;
|
||||||
|
|
||||||
newVirt.xfbSource.tex = D3DTexture2D::Create(target_width, target_height, (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM);
|
newVirt.xfbSource.tex = D3DTexture2D::Create(target_width, target_height, (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM);
|
||||||
|
@ -253,7 +256,7 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
|
||||||
|
|
||||||
Renderer::ResetAPIState(); // reset any game specific settings
|
Renderer::ResetAPIState(); // reset any game specific settings
|
||||||
|
|
||||||
// copy EFB data to XFB and restore render target again
|
// Copy EFB data to XFB and restore render target again
|
||||||
D3D11_RECT sourcerect = CD3D11_RECT(efbSource.left, efbSource.top, efbSource.right, efbSource.bottom);
|
D3D11_RECT sourcerect = CD3D11_RECT(efbSource.left, efbSource.top, efbSource.right, efbSource.bottom);
|
||||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)target_width, (float)target_height);
|
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)target_width, (float)target_height);
|
||||||
D3D::context->RSSetViewports(1, &vp);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
|
@ -277,8 +280,11 @@ const XFBSource** FramebufferManager::getVirtualXFBSource(u32 xfbAddr, u32 fbWid
|
||||||
{
|
{
|
||||||
xfbCount = 0;
|
xfbCount = 0;
|
||||||
|
|
||||||
if (m_virtualXFBList.size() == 0) // no Virtual XFBs available
|
if (m_virtualXFBList.size() == 0)
|
||||||
|
{
|
||||||
|
// No Virtual XFBs available.
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
u32 srcLower = xfbAddr;
|
u32 srcLower = xfbAddr;
|
||||||
u32 srcUpper = xfbAddr + 2 * fbWidth * fbHeight;
|
u32 srcUpper = xfbAddr + 2 * fbWidth * fbHeight;
|
||||||
|
@ -297,5 +303,6 @@ const XFBSource** FramebufferManager::getVirtualXFBSource(u32 xfbAddr, u32 fbWid
|
||||||
xfbCount++;
|
xfbCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &m_overlappingXFBArray[0];
|
return &m_overlappingXFBArray[0];
|
||||||
}
|
}
|
|
@ -130,8 +130,8 @@ private:
|
||||||
const XFBSource** getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
const XFBSource** getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
||||||
const XFBSource** getVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
const XFBSource** getVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
||||||
|
|
||||||
XFBSource m_realXFBSource; // used in real XFB mode
|
XFBSource m_realXFBSource; // Only used in Real XFB mode
|
||||||
VirtualXFBListType m_virtualXFBList; // used in virtual XFB mode
|
VirtualXFBListType m_virtualXFBList; // Only used in Virtual XFB mode
|
||||||
|
|
||||||
const XFBSource* m_overlappingXFBArray[MAX_VIRTUAL_XFB];
|
const XFBSource* m_overlappingXFBArray[MAX_VIRTUAL_XFB];
|
||||||
|
|
||||||
|
@ -146,6 +146,6 @@ private:
|
||||||
} m_efb;
|
} m_efb;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern FramebufferManager FBManager;
|
extern FramebufferManager g_framebufferManager;
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -23,7 +23,6 @@
|
||||||
#include "ABI.h"
|
#include "ABI.h"
|
||||||
#include "MemoryUtil.h"
|
#include "MemoryUtil.h"
|
||||||
#include "VertexShaderGen.h"
|
#include "VertexShaderGen.h"
|
||||||
#include "VertexShaderCache.h"
|
|
||||||
|
|
||||||
#include "CPMemory.h"
|
#include "CPMemory.h"
|
||||||
#include "NativeVertexFormat.h"
|
#include "NativeVertexFormat.h"
|
||||||
|
|
|
@ -199,6 +199,9 @@ void PixelShaderCache::Init()
|
||||||
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
|
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
|
||||||
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));
|
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));
|
||||||
|
|
||||||
|
SETSTAT(stats.numPixelShadersCreated, 0);
|
||||||
|
SETSTAT(stats.numPixelShadersAlive, 0);
|
||||||
|
|
||||||
char cache_filename[MAX_PATH];
|
char cache_filename[MAX_PATH];
|
||||||
sprintf(cache_filename, "%sdx11-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX), globals->unique_id);
|
sprintf(cache_filename, "%sdx11-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX), globals->unique_id);
|
||||||
PixelShaderCacheInserter inserter;
|
PixelShaderCacheInserter inserter;
|
||||||
|
@ -230,7 +233,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
|
||||||
PIXELSHADERUID uid;
|
PIXELSHADERUID uid;
|
||||||
GetPixelShaderId(&uid, dstAlpha);
|
GetPixelShaderId(&uid, dstAlpha);
|
||||||
|
|
||||||
// check if the shader is already set
|
// Check if the shader is already set
|
||||||
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
|
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
|
||||||
{
|
{
|
||||||
PSCache::const_iterator iter = PixelShaders.find(uid);
|
PSCache::const_iterator iter = PixelShaders.find(uid);
|
||||||
|
@ -239,7 +242,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
|
||||||
|
|
||||||
memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID));
|
memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID));
|
||||||
|
|
||||||
// check if the shader is already in the cache
|
// Check if the shader is already in the cache
|
||||||
PSCache::iterator iter;
|
PSCache::iterator iter;
|
||||||
iter = PixelShaders.find(uid);
|
iter = PixelShaders.find(uid);
|
||||||
if (iter != PixelShaders.end())
|
if (iter != PixelShaders.end())
|
||||||
|
@ -252,7 +255,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
|
||||||
return (entry.shader != NULL);
|
return (entry.shader != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to compile a new shader
|
// Need to compile a new shader
|
||||||
const char* code = GeneratePixelShaderCode(dstAlpha, API_D3D11,components);
|
const char* code = GeneratePixelShaderCode(dstAlpha, API_D3D11,components);
|
||||||
|
|
||||||
D3DBlob* pbytecode;
|
D3DBlob* pbytecode;
|
||||||
|
@ -262,7 +265,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert the bytecode into the caches
|
// Insert the bytecode into the caches
|
||||||
g_ps_disk_cache.Append((u8*)&uid, sizeof(uid), (const u8*)pbytecode->Data(), pbytecode->Size());
|
g_ps_disk_cache.Append((u8*)&uid, sizeof(uid), (const u8*)pbytecode->Data(), pbytecode->Size());
|
||||||
g_ps_disk_cache.Sync();
|
g_ps_disk_cache.Sync();
|
||||||
|
|
||||||
|
@ -283,15 +286,19 @@ bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, void* bytecode,
|
||||||
// TODO: Somehow make the debug name a bit more specific
|
// TODO: Somehow make the debug name a bit more specific
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)shader, "a pixel shader of PixelShaderCache");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)shader, "a pixel shader of PixelShaderCache");
|
||||||
|
|
||||||
// make an entry in the table
|
// Make an entry in the table
|
||||||
PSCacheEntry newentry;
|
PSCacheEntry newentry;
|
||||||
newentry.shader = shader;
|
newentry.shader = shader;
|
||||||
newentry.frameCount = frameCount;
|
newentry.frameCount = frameCount;
|
||||||
PixelShaders[uid] = newentry;
|
PixelShaders[uid] = newentry;
|
||||||
last_entry = &PixelShaders[uid];
|
last_entry = &PixelShaders[uid];
|
||||||
|
|
||||||
|
if (!shader) {
|
||||||
|
// INCSTAT(stats.numPixelShadersFailed);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
INCSTAT(stats.numPixelShadersCreated);
|
INCSTAT(stats.numPixelShadersCreated);
|
||||||
SETSTAT(stats.numPixelShadersAlive, PixelShaders.size());
|
SETSTAT(stats.numPixelShadersAlive, PixelShaders.size());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
|
@ -42,7 +42,7 @@
|
||||||
#include "EmuWindow.h"
|
#include "EmuWindow.h"
|
||||||
#include "AVIDump.h"
|
#include "AVIDump.h"
|
||||||
#include "OnScreenDisplay.h"
|
#include "OnScreenDisplay.h"
|
||||||
#include "FBManager.h"
|
#include "FramebufferManager.h"
|
||||||
#include "Fifo.h"
|
#include "Fifo.h"
|
||||||
#include "DLCache.h"
|
#include "DLCache.h"
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ ID3D11RasterizerState* resetraststate = NULL;
|
||||||
|
|
||||||
bool reset_called = false;
|
bool reset_called = false;
|
||||||
|
|
||||||
// state translation lookup tables
|
// State translation lookup tables
|
||||||
static const D3D11_BLEND d3dSrcFactors[8] =
|
static const D3D11_BLEND d3dSrcFactors[8] =
|
||||||
{
|
{
|
||||||
D3D11_BLEND_ZERO,
|
D3D11_BLEND_ZERO,
|
||||||
|
@ -230,7 +230,7 @@ static const D3D11_TEXTURE_ADDRESS_MODE d3dClamps[4] =
|
||||||
|
|
||||||
void SetupDeviceObjects()
|
void SetupDeviceObjects()
|
||||||
{
|
{
|
||||||
FBManager.Create();
|
g_framebufferManager.Create();
|
||||||
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
float colmat[20]= {0.0f};
|
float colmat[20]= {0.0f};
|
||||||
|
@ -296,9 +296,10 @@ void SetupDeviceObjects()
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)resetraststate, "rasterizer state for Renderer::ResetAPIState");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)resetraststate, "rasterizer state for Renderer::ResetAPIState");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Kill off all POOL_DEFAULT device objects.
|
||||||
void TeardownDeviceObjects()
|
void TeardownDeviceObjects()
|
||||||
{
|
{
|
||||||
FBManager.Destroy();
|
g_framebufferManager.Destroy();
|
||||||
SAFE_RELEASE(access_efb_cbuf);
|
SAFE_RELEASE(access_efb_cbuf);
|
||||||
SAFE_RELEASE(cleardepthstates[0]);
|
SAFE_RELEASE(cleardepthstates[0]);
|
||||||
SAFE_RELEASE(cleardepthstates[1]);
|
SAFE_RELEASE(cleardepthstates[1]);
|
||||||
|
@ -342,14 +343,14 @@ bool Renderer::Init()
|
||||||
D3D::gfxstate->samplerdesc[stage].MaxAnisotropy = g_ActiveConfig.iMaxAnisotropy;
|
D3D::gfxstate->samplerdesc[stage].MaxAnisotropy = g_ActiveConfig.iMaxAnisotropy;
|
||||||
|
|
||||||
float ClearColor[4] = { 0.f, 0.f, 0.f, 0.f };
|
float ClearColor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||||
D3D::context->ClearRenderTargetView(FBManager.GetEFBColorTexture()->GetRTV(), ClearColor);
|
D3D::context->ClearRenderTargetView(g_framebufferManager.GetEFBColorTexture()->GetRTV(), ClearColor);
|
||||||
D3D::context->ClearDepthStencilView(FBManager.GetEFBDepthTexture()->GetDSV(), D3D11_CLEAR_DEPTH, 1.f, 0);
|
D3D::context->ClearDepthStencilView(g_framebufferManager.GetEFBDepthTexture()->GetDSV(), D3D11_CLEAR_DEPTH, 1.f, 0);
|
||||||
|
|
||||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)(s_Fulltarget_width - s_target_width) / 2.f,
|
D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)(s_Fulltarget_width - s_target_width) / 2.f,
|
||||||
(float)(s_Fulltarget_height - s_target_height) / 2.f,
|
(float)(s_Fulltarget_height - s_target_height) / 2.f,
|
||||||
(float)s_target_width, (float)s_target_height);
|
(float)s_target_width, (float)s_target_height);
|
||||||
D3D::context->RSSetViewports(1, &vp);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
D3D::context->OMSetRenderTargets(1, &FBManager.GetEFBColorTexture()->GetRTV(), FBManager.GetEFBDepthTexture()->GetDSV());
|
D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBColorTexture()->GetRTV(), g_framebufferManager.GetEFBDepthTexture()->GetDSV());
|
||||||
D3D::BeginFrame();
|
D3D::BeginFrame();
|
||||||
D3D::gfxstate->rastdesc.ScissorEnable = TRUE;
|
D3D::gfxstate->rastdesc.ScissorEnable = TRUE;
|
||||||
|
|
||||||
|
@ -372,16 +373,18 @@ int Renderer::GetFullTargetHeight() { return s_Fulltarget_height; }
|
||||||
float Renderer::GetTargetScaleX() { return xScale; }
|
float Renderer::GetTargetScaleX() { return xScale; }
|
||||||
float Renderer::GetTargetScaleY() { return yScale; }
|
float Renderer::GetTargetScaleY() { return yScale; }
|
||||||
|
|
||||||
|
// Return the framebuffer size
|
||||||
int Renderer::GetFrameBufferWidth()
|
int Renderer::GetFrameBufferWidth()
|
||||||
{
|
{
|
||||||
return s_backbuffer_width;
|
return s_backbuffer_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Renderer::GetFrameBufferHeight()
|
int Renderer::GetFrameBufferHeight()
|
||||||
{
|
{
|
||||||
return s_backbuffer_height;
|
return s_backbuffer_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create On-Screen-Messages
|
// Create On-Screen-Messages
|
||||||
void Renderer::DrawDebugText()
|
void Renderer::DrawDebugText()
|
||||||
{
|
{
|
||||||
// OSD menu messages
|
// OSD menu messages
|
||||||
|
@ -418,31 +421,35 @@ void Renderer::DrawDebugText()
|
||||||
g_ActiveConfig.bCrop ? " (crop)" : "";
|
g_ActiveConfig.bCrop ? " (crop)" : "";
|
||||||
std::string OSDM3 = "Disabled";
|
std::string OSDM3 = "Disabled";
|
||||||
|
|
||||||
// if there is more text than this we will have a collission
|
// If there is more text than this we will have a collision
|
||||||
if (g_ActiveConfig.bShowFPS)
|
if (g_ActiveConfig.bShowFPS)
|
||||||
{ T1 += "\n\n"; T2 += "\n\n"; }
|
{
|
||||||
|
T1 += "\n\n";
|
||||||
|
T2 += "\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// The rows
|
||||||
T0.push_back(StringFromFormat("3: Internal Resolution: %s\n", OSDM1.c_str()));
|
T0.push_back(StringFromFormat("3: Internal Resolution: %s\n", OSDM1.c_str()));
|
||||||
T0.push_back(StringFromFormat("4: Aspect Ratio: %s%s\n", OSDM21.c_str(), OSDM22.c_str()));
|
T0.push_back(StringFromFormat("4: Aspect Ratio: %s%s\n", OSDM21.c_str(), OSDM22.c_str()));
|
||||||
T0.push_back(StringFromFormat("5: Copy EFB: %s\n", OSDM3.c_str()));
|
T0.push_back(StringFromFormat("5: Copy EFB: %s\n", OSDM3.c_str()));
|
||||||
T0.push_back(StringFromFormat("6: Fog: %s\n", g_ActiveConfig.bDisableFog ? "Disabled" : "Enabled"));
|
T0.push_back(StringFromFormat("6: Fog: %s\n", g_ActiveConfig.bDisableFog ? "Disabled" : "Enabled"));
|
||||||
T0.push_back(StringFromFormat("7: Material Lighting: %s\n", g_ActiveConfig.bDisableLighting ? "Disabled" : "Enabled"));
|
T0.push_back(StringFromFormat("7: Material Lighting: %s\n", g_ActiveConfig.bDisableLighting ? "Disabled" : "Enabled"));
|
||||||
|
|
||||||
// latest changed setting in yellow
|
// The latest changed setting in yellow
|
||||||
T1 += (OSDChoice == -1) ? T0.at(0) : "\n";
|
T1 += (OSDChoice == -1) ? T0.at(0) : "\n";
|
||||||
T1 += (OSDChoice == -2) ? T0.at(1) : "\n";
|
T1 += (OSDChoice == -2) ? T0.at(1) : "\n";
|
||||||
T1 += (OSDChoice == -3) ? T0.at(2) : "\n";
|
T1 += (OSDChoice == -3) ? T0.at(2) : "\n";
|
||||||
T1 += (OSDChoice == -4) ? T0.at(3) : "\n";
|
T1 += (OSDChoice == -4) ? T0.at(3) : "\n";
|
||||||
T1 += (OSDChoice == -5) ? T0.at(4) : "\n";
|
T1 += (OSDChoice == -5) ? T0.at(4) : "\n";
|
||||||
|
|
||||||
// other settings in cyan
|
// The other settings in cyan
|
||||||
T2 += (OSDChoice != -1) ? T0.at(0) : "\n";
|
T2 += (OSDChoice != -1) ? T0.at(0) : "\n";
|
||||||
T2 += (OSDChoice != -2) ? T0.at(1) : "\n";
|
T2 += (OSDChoice != -2) ? T0.at(1) : "\n";
|
||||||
T2 += (OSDChoice != -3) ? T0.at(2) : "\n";
|
T2 += (OSDChoice != -3) ? T0.at(2) : "\n";
|
||||||
T2 += (OSDChoice != -4) ? T0.at(3) : "\n";
|
T2 += (OSDChoice != -4) ? T0.at(3) : "\n";
|
||||||
T2 += (OSDChoice != -5) ? T0.at(4) : "\n";
|
T2 += (OSDChoice != -5) ? T0.at(4) : "\n";
|
||||||
|
|
||||||
// render a shadow, and then the text
|
// Render a shadow, and then the text
|
||||||
Renderer::RenderText(T1.c_str(), 21, 21, 0xDD000000);
|
Renderer::RenderText(T1.c_str(), 21, 21, 0xDD000000);
|
||||||
Renderer::RenderText(T1.c_str(), 20, 20, 0xFFffff00);
|
Renderer::RenderText(T1.c_str(), 20, 20, 0xFFffff00);
|
||||||
Renderer::RenderText(T2.c_str(), 21, 21, 0xDD000000);
|
Renderer::RenderText(T2.c_str(), 21, 21, 0xDD000000);
|
||||||
|
@ -451,7 +458,7 @@ void Renderer::DrawDebugText()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::RenderText(const char* text, int left, int top, u32 color)
|
void Renderer::RenderText(const char *text, int left, int top, u32 color)
|
||||||
{
|
{
|
||||||
D3D::font.DrawTextScaled((float)left, (float)top, 20.f, 0.0f, color, text, false);
|
D3D::font.DrawTextScaled((float)left, (float)top, 20.f, 0.0f, color, text, false);
|
||||||
}
|
}
|
||||||
|
@ -468,6 +475,9 @@ TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// With D3D, we have to resize the backbuffer if the window changed
|
||||||
|
// size.
|
||||||
void CheckForResize()
|
void CheckForResize()
|
||||||
{
|
{
|
||||||
while (EmuWindow::IsSizing())
|
while (EmuWindow::IsSizing())
|
||||||
|
@ -475,21 +485,22 @@ void CheckForResize()
|
||||||
|
|
||||||
if (EmuWindow::GetParentWnd())
|
if (EmuWindow::GetParentWnd())
|
||||||
{
|
{
|
||||||
// re-stretch window to parent window size again, if it has a parent window.
|
// Re-stretch window to parent window size again, if it has a parent window.
|
||||||
RECT rcParentWindow;
|
RECT rcParentWindow;
|
||||||
GetWindowRect(EmuWindow::GetParentWnd(), &rcParentWindow);
|
GetWindowRect(EmuWindow::GetParentWnd(), &rcParentWindow);
|
||||||
int width = rcParentWindow.right - rcParentWindow.left;
|
int width = rcParentWindow.right - rcParentWindow.left;
|
||||||
int height = rcParentWindow.bottom - rcParentWindow.top;
|
int height = rcParentWindow.bottom - rcParentWindow.top;
|
||||||
if (width != s_backbuffer_width || height != s_backbuffer_height)
|
if (width != s_backbuffer_width || height != s_backbuffer_height)
|
||||||
::MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE);
|
MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE);
|
||||||
}
|
}
|
||||||
RECT rcWindow;
|
RECT rcWindow;
|
||||||
GetClientRect(EmuWindow::GetWnd(), &rcWindow);
|
GetClientRect(EmuWindow::GetWnd(), &rcWindow);
|
||||||
int client_width = rcWindow.right - rcWindow.left;
|
int client_width = rcWindow.right - rcWindow.left;
|
||||||
int client_height = rcWindow.bottom - rcWindow.top;
|
int client_height = rcWindow.bottom - rcWindow.top;
|
||||||
|
|
||||||
// sanity check
|
// Sanity check
|
||||||
if ((client_width != s_backbuffer_width || client_height != s_backbuffer_height) &&
|
if ((client_width != s_backbuffer_width ||
|
||||||
|
client_height != s_backbuffer_height) &&
|
||||||
client_width >= 4 && client_height >= 4)
|
client_width >= 4 && client_height >= 4)
|
||||||
{
|
{
|
||||||
WindowResized = true;
|
WindowResized = true;
|
||||||
|
@ -507,7 +518,7 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
|
||||||
// just use progressive.
|
// just use progressive.
|
||||||
if (g_ActiveConfig.bUseXFB)
|
if (g_ActiveConfig.bUseXFB)
|
||||||
{
|
{
|
||||||
FBManager.CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
|
g_framebufferManager.CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -599,7 +610,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the rectangular target region covered by the EFB pixel
|
// Get the rectangular target region covered by the EFB pixel
|
||||||
EFBRectangle efbPixelRc;
|
EFBRectangle efbPixelRc;
|
||||||
efbPixelRc.left = x;
|
efbPixelRc.left = x;
|
||||||
efbPixelRc.top = y;
|
efbPixelRc.top = y;
|
||||||
|
@ -624,15 +635,15 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
if ((RectToLock.right - RectToLock.left) > 4)
|
if ((RectToLock.right - RectToLock.left) > 4)
|
||||||
RectToLock.left++;
|
RectToLock.left++;
|
||||||
|
|
||||||
ResetAPIState(); // reset any game specific settings
|
ResetAPIState(); // Reset any game specific settings
|
||||||
|
|
||||||
// Stretch picture with increased internal resolution
|
// Stretch picture with increased internal resolution
|
||||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, 4.f, 4.f);
|
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, 4.f, 4.f);
|
||||||
D3D::context->RSSetViewports(1, &vp);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
D3D::context->PSSetConstantBuffers(0, 1, &access_efb_cbuf);
|
D3D::context->PSSetConstantBuffers(0, 1, &access_efb_cbuf);
|
||||||
D3D::context->OMSetRenderTargets(1, &FBManager.GetEFBDepthReadTexture()->GetRTV(), NULL);
|
D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBDepthReadTexture()->GetRTV(), NULL);
|
||||||
D3D::SetPointCopySampler();
|
D3D::SetPointCopySampler();
|
||||||
D3D::drawShadedTexQuad(FBManager.GetEFBDepthTexture()->GetSRV(),
|
D3D::drawShadedTexQuad(g_framebufferManager.GetEFBDepthTexture()->GetSRV(),
|
||||||
&RectToLock,
|
&RectToLock,
|
||||||
Renderer::GetFullTargetWidth(),
|
Renderer::GetFullTargetWidth(),
|
||||||
Renderer::GetFullTargetHeight(),
|
Renderer::GetFullTargetHeight(),
|
||||||
|
@ -640,21 +651,21 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
VertexShaderCache::GetSimpleVertexShader(),
|
VertexShaderCache::GetSimpleVertexShader(),
|
||||||
VertexShaderCache::GetSimpleInputLayout());
|
VertexShaderCache::GetSimpleInputLayout());
|
||||||
|
|
||||||
D3D::context->OMSetRenderTargets(1, &FBManager.GetEFBColorTexture()->GetRTV(), FBManager.GetEFBDepthTexture()->GetDSV());
|
D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBColorTexture()->GetRTV(), g_framebufferManager.GetEFBDepthTexture()->GetDSV());
|
||||||
RestoreAPIState();
|
RestoreAPIState();
|
||||||
RectToLock = CD3D11_RECT(0, 0, 4, 4);
|
RectToLock = CD3D11_RECT(0, 0, 4, 4);
|
||||||
|
|
||||||
// copy to system memory
|
// copy to system memory
|
||||||
D3D11_BOX box = CD3D11_BOX(0, 0, 0, 4, 4, 1);
|
D3D11_BOX box = CD3D11_BOX(0, 0, 0, 4, 4, 1);
|
||||||
read_tex = FBManager.GetEFBDepthStagingBuffer();
|
read_tex = g_framebufferManager.GetEFBDepthStagingBuffer();
|
||||||
D3D::context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, FBManager.GetEFBDepthReadTexture()->GetTex(), 0, &box);
|
D3D::context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, g_framebufferManager.GetEFBDepthReadTexture()->GetTex(), 0, &box);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// we can directly copy to system memory here
|
// we can directly copy to system memory here
|
||||||
read_tex = FBManager.GetEFBColorStagingBuffer();
|
read_tex = g_framebufferManager.GetEFBColorStagingBuffer();
|
||||||
D3D11_BOX box = CD3D11_BOX(RectToLock.left, RectToLock.top, 0, RectToLock.right, RectToLock.bottom, 1);
|
D3D11_BOX box = CD3D11_BOX(RectToLock.left, RectToLock.top, 0, RectToLock.right, RectToLock.bottom, 1);
|
||||||
D3D::context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, FBManager.GetEFBColorTexture()->GetTex(), 0, &box);
|
D3D::context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, g_framebufferManager.GetEFBColorTexture()->GetTex(), 0, &box);
|
||||||
RectToLock = CD3D11_RECT(0, 0, 1, 1);
|
RectToLock = CD3D11_RECT(0, 0, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -662,21 +673,35 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
D3D::context->Map(read_tex, 0, D3D11_MAP_READ, 0, &map);
|
D3D::context->Map(read_tex, 0, D3D11_MAP_READ, 0, &map);
|
||||||
|
|
||||||
switch(type) {
|
switch(type)
|
||||||
|
{
|
||||||
case PEEK_Z:
|
case PEEK_Z:
|
||||||
val = ((float*)map.pData)[0];
|
val = ((float*)map.pData)[0];
|
||||||
z = ((u32)(val * 0xffffff));
|
z = ((u32)(val * 0xffffff));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case POKE_Z:
|
||||||
|
// TODO: Implement
|
||||||
|
break;
|
||||||
|
|
||||||
case PEEK_COLOR:
|
case PEEK_COLOR:
|
||||||
z = ((u32*)map.pData)[0];
|
z = ((u32*)map.pData)[0];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case POKE_COLOR:
|
||||||
|
// TODO: Implement. One way is to draw a tiny pixel-sized rectangle at
|
||||||
|
// the exact location. Note: EFB pokes are susceptible to Z-buffering
|
||||||
|
// and perhaps blending.
|
||||||
|
//WARN_LOG(VIDEOINTERFACE, "This is probably some kind of software rendering");
|
||||||
|
break;
|
||||||
|
|
||||||
// TODO: Implement POKE_Z and POKE_COLOR
|
// TODO: Implement POKE_Z and POKE_COLOR
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D::context->Unmap(read_tex, 0);
|
D3D::context->Unmap(read_tex, 0);
|
||||||
|
// TODO: in RE0 this value is often off by one, which causes lighting to disappear
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -728,7 +753,7 @@ void UpdateViewport()
|
||||||
{
|
{
|
||||||
s_Fulltarget_height -= 2 * Y;
|
s_Fulltarget_height -= 2 * Y;
|
||||||
Y = 0;
|
Y = 0;
|
||||||
sizeChanged=true;
|
sizeChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
float newx = (float)X;
|
float newx = (float)X;
|
||||||
|
@ -755,29 +780,30 @@ void UpdateViewport()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL);
|
D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL);
|
||||||
FBManager.Destroy();
|
g_framebufferManager.Destroy();
|
||||||
FBManager.Create();
|
g_framebufferManager.Create();
|
||||||
D3D::context->OMSetRenderTargets(1, &FBManager.GetEFBColorTexture()->GetRTV(), FBManager.GetEFBDepthTexture()->GetDSV());
|
D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBColorTexture()->GetRTV(), g_framebufferManager.GetEFBDepthTexture()->GetDSV());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// some games set invalids values MinDepth and MaxDepth so fix them to the max an min allowed and let the shaders do this work
|
// Some games set invalids values for z min and z max so fix them to the max an min alowed and let the shaders do this work
|
||||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(newx, newy, newwidth, newheight,
|
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(newx, newy, newwidth, newheight,
|
||||||
0.f, // (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777216.0f;
|
0.f, // (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777216.0f;
|
||||||
1.f); // xfregs.rawViewport[5] / 16777216.0f;
|
1.f); // xfregs.rawViewport[5] / 16777216.0f;
|
||||||
D3D::context->RSSetViewports(1, &vp);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tino: color is passed in bgra mode so need to convert it to rgba
|
// Tino: color is passed in bgra mode so need to convert it to rgba
|
||||||
void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z)
|
void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z)
|
||||||
{
|
{
|
||||||
|
// Update the view port for clearing the picture
|
||||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
|
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
|
||||||
// update the view port for clearing the picture
|
|
||||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)targetRc.left, (float)targetRc.top, (float)targetRc.GetWidth(), (float)targetRc.GetHeight(),
|
D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)targetRc.left, (float)targetRc.top, (float)targetRc.GetWidth(), (float)targetRc.GetHeight(),
|
||||||
0.f,
|
0.f,
|
||||||
1.f);
|
1.f);
|
||||||
D3D::context->RSSetViewports(1, &vp);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
|
|
||||||
// always set the scissor in case it was set by the game and has not been reset
|
// Always set the scissor in case it was set by the game and has not been reset
|
||||||
D3D11_RECT sirc = CD3D11_RECT(targetRc.left, targetRc.top, targetRc.right, targetRc.bottom);
|
D3D11_RECT sirc = CD3D11_RECT(targetRc.left, targetRc.top, targetRc.right, targetRc.bottom);
|
||||||
D3D::context->RSSetScissorRects(1, &sirc);
|
D3D::context->RSSetScissorRects(1, &sirc);
|
||||||
u32 rgbaColor = (color & 0xFF00FF00) | ((color >> 16) & 0xFF) | ((color << 16) & 0xFF0000);
|
u32 rgbaColor = (color & 0xFF00FF00) | ((color >> 16) & 0xFF) | ((color << 16) & 0xFF0000);
|
||||||
|
@ -815,10 +841,10 @@ void Renderer::SetBlendMode(bool forceUpdate)
|
||||||
D3D::gfxstate->SetSrcBlend(d3dSrcFactors[bpmem.blendmode.srcfactor]);
|
D3D::gfxstate->SetSrcBlend(d3dSrcFactors[bpmem.blendmode.srcfactor]);
|
||||||
D3D::gfxstate->SetDestBlend(d3dDestFactors[bpmem.blendmode.dstfactor]);
|
D3D::gfxstate->SetDestBlend(d3dDestFactors[bpmem.blendmode.dstfactor]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function has the final picture. We adjust the aspect ratio here.
|
||||||
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc)
|
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc)
|
||||||
{
|
{
|
||||||
if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.bUseRealXFB) || !fbWidth || !fbHeight)
|
if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.bUseRealXFB) || !fbWidth || !fbHeight)
|
||||||
|
@ -832,7 +858,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
|
|
||||||
if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2;
|
if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2;
|
||||||
u32 xfbCount = 0;
|
u32 xfbCount = 0;
|
||||||
const XFBSource** xfbSourceList = FBManager.GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
const XFBSource** xfbSourceList = g_framebufferManager.GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
||||||
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
||||||
{
|
{
|
||||||
g_VideoInitialize.pCopiedToXFB(false);
|
g_VideoInitialize.pCopiedToXFB(false);
|
||||||
|
@ -841,7 +867,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
|
|
||||||
Renderer::ResetAPIState();
|
Renderer::ResetAPIState();
|
||||||
|
|
||||||
// prepare copying the XFBs to our backbuffer
|
// Prepare to copy the XFBs to our backbuffer
|
||||||
TargetRectangle dst_rect;
|
TargetRectangle dst_rect;
|
||||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
||||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)s_backbuffer_width, (float)s_backbuffer_height);
|
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)s_backbuffer_width, (float)s_backbuffer_height);
|
||||||
|
@ -893,12 +919,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
int xfbWidth = xfbSource->srcWidth;
|
int xfbWidth = xfbSource->srcWidth;
|
||||||
int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2);
|
int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2);
|
||||||
|
|
||||||
drawRc.bottom = 1.0f - 2.0f * ((hOffset) / (float)fbHeight);
|
drawRc.bottom = 1.0f - (2.0f * (hOffset) / (float)fbHeight);
|
||||||
drawRc.top = 1.0f - 2.0f * ((hOffset + xfbHeight) / (float)fbHeight);
|
drawRc.top = 1.0f - (2.0f * (hOffset + xfbHeight) / (float)fbHeight);
|
||||||
drawRc.left = -(xfbWidth / (float)fbWidth);
|
drawRc.left = -(xfbWidth / (float)fbWidth);
|
||||||
drawRc.right = (xfbWidth / (float)fbWidth);
|
drawRc.right = (xfbWidth / (float)fbWidth);
|
||||||
|
|
||||||
|
|
||||||
if (!g_ActiveConfig.bAutoScale)
|
if (!g_ActiveConfig.bAutoScale)
|
||||||
{
|
{
|
||||||
// scale draw area for a 1 to 1 pixel mapping with the draw target
|
// scale draw area for a 1 to 1 pixel mapping with the draw target
|
||||||
|
@ -918,13 +943,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
drawRc.left = -1;
|
drawRc.left = -1;
|
||||||
drawRc.right = 1;
|
drawRc.right = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D::drawShadedTexSubQuad(xfbSource->tex->GetSRV(), &sourceRc, xfbSource->texWidth, xfbSource->texHeight, &drawRc, PixelShaderCache::GetColorCopyProgram(),VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
D3D::drawShadedTexSubQuad(xfbSource->tex->GetSRV(), &sourceRc, xfbSource->texWidth, xfbSource->texHeight, &drawRc, PixelShaderCache::GetColorCopyProgram(),VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
|
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
|
||||||
D3DTexture2D* read_texture = FBManager.GetEFBColorTexture();
|
D3DTexture2D* read_texture = g_framebufferManager.GetEFBColorTexture();
|
||||||
D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), PixelShaderCache::GetColorCopyProgram(),VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), PixelShaderCache::GetColorCopyProgram(),VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
||||||
}
|
}
|
||||||
// done with drawing the game stuff, good moment to save a screenshot
|
// done with drawing the game stuff, good moment to save a screenshot
|
||||||
|
@ -958,12 +984,12 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
s_bScreenshot = false;
|
s_bScreenshot = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally present some information
|
// Finish up the current frame, print some stats
|
||||||
if (g_ActiveConfig.bShowFPS)
|
if (g_ActiveConfig.bShowFPS)
|
||||||
{
|
{
|
||||||
char fps[20];
|
char fps[20];
|
||||||
StringCchPrintfA(fps, 20, "FPS: %d\n", s_fps);
|
StringCchPrintfA(fps, 20, "FPS: %d\n", s_fps);
|
||||||
D3D::font.DrawTextScaled(0,30,20,0.0f,0xFF00FFFF,fps,false);
|
D3D::font.DrawTextScaled(0, 30, 20, 0.0f, 0xFF00FFFF, fps, false);
|
||||||
}
|
}
|
||||||
Renderer::DrawDebugText();
|
Renderer::DrawDebugText();
|
||||||
|
|
||||||
|
@ -971,13 +997,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
{
|
{
|
||||||
char buf[32768];
|
char buf[32768];
|
||||||
Statistics::ToString(buf);
|
Statistics::ToString(buf);
|
||||||
D3D::font.DrawTextScaled(0,30,20,0.0f,0xFF00FFFF,buf,false);
|
D3D::font.DrawTextScaled(0, 30, 20, 0.0f, 0xFF00FFFF, buf, false);
|
||||||
}
|
}
|
||||||
else if (g_ActiveConfig.bOverlayProjStats)
|
else if (g_ActiveConfig.bOverlayProjStats)
|
||||||
{
|
{
|
||||||
char buf[32768];
|
char buf[32768];
|
||||||
Statistics::ToStringProj(buf);
|
Statistics::ToStringProj(buf);
|
||||||
D3D::font.DrawTextScaled(0,30,20,0.0f,0xFF00FFFF,buf,false);
|
D3D::font.DrawTextScaled(0, 30, 20, 0.0f, 0xFF00FFFF, buf, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
OSD::DrawMessages();
|
OSD::DrawMessages();
|
||||||
|
@ -986,7 +1012,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
DLCache::ProgressiveCleanup();
|
DLCache::ProgressiveCleanup();
|
||||||
TextureCache::Cleanup();
|
TextureCache::Cleanup();
|
||||||
|
|
||||||
// enable any configuration changes
|
// Enable any configuration changes
|
||||||
UpdateActiveConfig();
|
UpdateActiveConfig();
|
||||||
WindowResized = false;
|
WindowResized = false;
|
||||||
CheckForResize();
|
CheckForResize();
|
||||||
|
@ -1013,12 +1039,15 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
s_fps = fpscount;
|
s_fps = fpscount;
|
||||||
fpscount = 0;
|
fpscount = 0;
|
||||||
}
|
}
|
||||||
if (XFBWrited) ++fpscount;
|
if (XFBWrited)
|
||||||
|
++fpscount;
|
||||||
|
|
||||||
// set default viewport and scissor, for the clear to work correctly
|
// Begin new frame
|
||||||
|
// Set default viewport and scissor, for the clear to work correctly
|
||||||
|
// New frame
|
||||||
stats.ResetFrame();
|
stats.ResetFrame();
|
||||||
|
|
||||||
// done. Show our work ;)
|
// Flip/present backbuffer to frontbuffer here
|
||||||
D3D::Present();
|
D3D::Present();
|
||||||
|
|
||||||
// resize the back buffers NOW to avoid flickering when resizing windows
|
// resize the back buffers NOW to avoid flickering when resizing windows
|
||||||
|
@ -1038,16 +1067,20 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
s_target_height = (int)(EFB_HEIGHT * yScale);
|
s_target_height = (int)(EFB_HEIGHT * yScale);
|
||||||
|
|
||||||
D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL);
|
D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL);
|
||||||
FBManager.Destroy();
|
g_framebufferManager.Destroy();
|
||||||
FBManager.Create();
|
g_framebufferManager.Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
// begin next frame
|
// begin next frame
|
||||||
Renderer::RestoreAPIState();
|
Renderer::RestoreAPIState();
|
||||||
D3D::BeginFrame();
|
D3D::BeginFrame();
|
||||||
D3D::context->OMSetRenderTargets(1, &FBManager.GetEFBColorTexture()->GetRTV(), FBManager.GetEFBDepthTexture()->GetDSV());
|
D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBColorTexture()->GetRTV(), g_framebufferManager.GetEFBDepthTexture()->GetDSV());
|
||||||
UpdateViewport();
|
UpdateViewport();
|
||||||
VertexShaderManager::SetViewportChanged();
|
VertexShaderManager::SetViewportChanged();
|
||||||
|
// For testing zbuffer targets.
|
||||||
|
// Renderer::SetZBufferRender();
|
||||||
|
// SaveTexture("tex.tga", GL_TEXTURE_RECTANGLE_ARB, s_FakeZTarget,
|
||||||
|
// GetTargetWidth(), GetTargetHeight());
|
||||||
g_VideoInitialize.pCopiedToXFB(XFBWrited || g_ActiveConfig.bUseRealXFB);
|
g_VideoInitialize.pCopiedToXFB(XFBWrited || g_ActiveConfig.bUseRealXFB);
|
||||||
XFBWrited = false;
|
XFBWrited = false;
|
||||||
}
|
}
|
||||||
|
@ -1065,7 +1098,7 @@ void Renderer::ResetAPIState()
|
||||||
|
|
||||||
void Renderer::RestoreAPIState()
|
void Renderer::RestoreAPIState()
|
||||||
{
|
{
|
||||||
// gets us back into a more game-like state.
|
// Gets us back into a more game-like state.
|
||||||
if (reset_called)
|
if (reset_called)
|
||||||
{
|
{
|
||||||
D3D::stateman->PopBlendState();
|
D3D::stateman->PopBlendState();
|
||||||
|
@ -1094,6 +1127,7 @@ void Renderer::SetDepthMode()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// if the test is disabled write is disabled too
|
||||||
D3D::gfxstate->depthdesc.DepthEnable = FALSE;
|
D3D::gfxstate->depthdesc.DepthEnable = FALSE;
|
||||||
D3D::gfxstate->depthdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
|
D3D::gfxstate->depthdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
|
||||||
}
|
}
|
||||||
|
@ -1184,7 +1218,7 @@ void Renderer::SetInterlacingMode()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save screenshot
|
// Save screenshot
|
||||||
void Renderer::SetScreenshot(const char* filename)
|
void Renderer::SetScreenshot(const char *filename)
|
||||||
{
|
{
|
||||||
s_criticalScreenshot.Enter();
|
s_criticalScreenshot.Enter();
|
||||||
strcpy_s(s_sScreenshotName, filename);
|
strcpy_s(s_sScreenshotName, filename);
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include "D3DBase.h"
|
#include "D3DBase.h"
|
||||||
#include "D3DTexture.h"
|
#include "D3DTexture.h"
|
||||||
#include "D3DUtil.h"
|
#include "D3DUtil.h"
|
||||||
#include "FBManager.h"
|
#include "FramebufferManager.h"
|
||||||
#include "PixelShaderCache.h"
|
#include "PixelShaderCache.h"
|
||||||
#include "PixelShaderManager.h"
|
#include "PixelShaderManager.h"
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
|
@ -59,7 +59,7 @@ void TextureCache::TCacheEntry::Destroy(bool shutdown)
|
||||||
|
|
||||||
if (!isRenderTarget && !shutdown && !g_ActiveConfig.bSafeTextureCache)
|
if (!isRenderTarget && !shutdown && !g_ActiveConfig.bSafeTextureCache)
|
||||||
{
|
{
|
||||||
u32* ptr = (u32*)g_VideoInitialize.pGetMemoryPointer(addr);
|
u32 *ptr = (u32*)g_VideoInitialize.pGetMemoryPointer(addr);
|
||||||
if (ptr && *ptr == hash)
|
if (ptr && *ptr == hash)
|
||||||
*ptr = oldpixel;
|
*ptr = oldpixel;
|
||||||
}
|
}
|
||||||
|
@ -123,30 +123,6 @@ void TextureCache::Invalidate(bool shutdown)
|
||||||
HiresTextures::Shutdown();
|
HiresTextures::Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::InvalidateRange(u32 start_address, u32 size)
|
|
||||||
{
|
|
||||||
TexCache::iterator iter = textures.begin();
|
|
||||||
while (iter != textures.end())
|
|
||||||
{
|
|
||||||
if (iter->second.IntersectsMemoryRange(start_address, size))
|
|
||||||
{
|
|
||||||
iter->second.Destroy(false);
|
|
||||||
textures.erase(iter++);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TextureCache::TCacheEntry::IntersectsMemoryRange(u32 range_address, u32 range_size)
|
|
||||||
{
|
|
||||||
if (addr + size_in_bytes < range_address) return false;
|
|
||||||
if (addr >= range_address + range_size) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextureCache::Shutdown()
|
void TextureCache::Shutdown()
|
||||||
{
|
{
|
||||||
Invalidate(true);
|
Invalidate(true);
|
||||||
|
@ -178,6 +154,31 @@ void TextureCache::Cleanup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextureCache::InvalidateRange(u32 start_address, u32 size)
|
||||||
|
{
|
||||||
|
TexCache::iterator iter = textures.begin();
|
||||||
|
while (iter != textures.end())
|
||||||
|
{
|
||||||
|
if (iter->second.IntersectsMemoryRange(start_address, size))
|
||||||
|
{
|
||||||
|
iter->second.Destroy(false);
|
||||||
|
textures.erase(iter++);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextureCache::TCacheEntry::IntersectsMemoryRange(u32 range_address, u32 range_size)
|
||||||
|
{
|
||||||
|
if (addr + size_in_bytes < range_address) return false;
|
||||||
|
if (addr >= range_address + range_size) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// returns the exponent of the smallest power of two which is greater than val
|
// returns the exponent of the smallest power of two which is greater than val
|
||||||
unsigned int GetPow2(unsigned int val)
|
unsigned int GetPow2(unsigned int val)
|
||||||
{
|
{
|
||||||
|
@ -188,21 +189,47 @@ unsigned int GetPow2(unsigned int val)
|
||||||
|
|
||||||
TextureCache::TCacheEntry* TextureCache::Load(unsigned int stage, u32 address, unsigned int width, unsigned int height, unsigned int tex_format, unsigned int tlutaddr, unsigned int tlutfmt, bool UseNativeMips, unsigned int maxlevel)
|
TextureCache::TCacheEntry* TextureCache::Load(unsigned int stage, u32 address, unsigned int width, unsigned int height, unsigned int tex_format, unsigned int tlutaddr, unsigned int tlutfmt, bool UseNativeMips, unsigned int maxlevel)
|
||||||
{
|
{
|
||||||
if (address == 0) return NULL;
|
// notes (about "UNsafe texture cache"):
|
||||||
|
// Have to be removed soon.
|
||||||
|
// But we keep it until the "safe" way became rock solid
|
||||||
|
// pros: it has an unique ID held by the texture data itself (@address) once cached.
|
||||||
|
// cons: it writes this unique ID in the gc RAM <- very dangerous (break MP1) and ugly
|
||||||
|
|
||||||
u8* ptr = g_VideoInitialize.pGetMemoryPointer(address);
|
// notes (about "safe texture cache"):
|
||||||
|
// Metroids text issue (character table):
|
||||||
|
// Same addr, same GX_TF_C4 texture data but different TLUT (hence different outputs).
|
||||||
|
// That's why we have to hash the TLUT too for TLUT tex_format dependent textures (ie. GX_TF_C4, GX_TF_C8, GX_TF_C14X2).
|
||||||
|
// And since the address and tex data don't change, the key index in the cacheEntry map can't be the address but
|
||||||
|
// have to be a real unique ID.
|
||||||
|
// DONE but not satifiying yet -> may break copyEFBToTexture sometimes.
|
||||||
|
|
||||||
|
// Pokemon Colosseum text issue (plain text):
|
||||||
|
// Use a GX_TF_I4 512x512 text-flush-texture at a const address.
|
||||||
|
// The problem here was just the sparse hash on the texture. This texture is partly overwrited (what is needed only)
|
||||||
|
// so lot's of remaning old text. Thin white chars on black bg too.
|
||||||
|
|
||||||
|
// TODO: - clean this up when ready to kill old "unsafe texture cache"
|
||||||
|
// - fix the key index situation with CopyRenderTargetToTexture.
|
||||||
|
// Could happen only for GX_TF_C4, GX_TF_C8 and GX_TF_C14X2 fmt.
|
||||||
|
// Wonder if we can't use tex width&height to know if EFB might be copied to it...
|
||||||
|
// raw idea: TOCHECK if addresses are aligned we have few bits left...
|
||||||
|
|
||||||
|
if (address == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
u8 *ptr = g_VideoInitialize.pGetMemoryPointer(address);
|
||||||
unsigned int bsw = TexDecoder_GetBlockWidthInTexels(tex_format) - 1; // TexelSizeInNibbles(format)*width*height/16;
|
unsigned int bsw = TexDecoder_GetBlockWidthInTexels(tex_format) - 1; // TexelSizeInNibbles(format)*width*height/16;
|
||||||
unsigned int bsh = TexDecoder_GetBlockHeightInTexels(tex_format) - 1; // TexelSizeInNibbles(format)*width*height/16;
|
unsigned int bsh = TexDecoder_GetBlockHeightInTexels(tex_format) - 1; // TexelSizeInNibbles(format)*width*height/16;
|
||||||
unsigned int bsdepth = TexDecoder_GetTexelSizeInNibbles(tex_format);
|
unsigned int bsdepth = TexDecoder_GetTexelSizeInNibbles(tex_format);
|
||||||
unsigned int expandedWidth = (width + bsw) & (~bsw);
|
unsigned int expandedWidth = (width + bsw) & (~bsw);
|
||||||
unsigned int expandedHeight = (height + bsh) & (~bsh);
|
unsigned int expandedHeight = (height + bsh) & (~bsh);
|
||||||
|
|
||||||
u64 hash_value;
|
u64 hash_value = 0;
|
||||||
u32 texID = address;
|
u32 texID = address;
|
||||||
u64 texHash;
|
u64 texHash = 0;
|
||||||
u32 FullFormat = tex_format;
|
u32 FullFormat = tex_format;
|
||||||
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
|
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
|
||||||
u32 FullFormat = (tex_format | (tlutfmt << 16));
|
FullFormat = (tex_format | (tlutfmt << 16));
|
||||||
|
|
||||||
// hires textures and texture dumping not supported, yet
|
// hires textures and texture dumping not supported, yet
|
||||||
if (g_ActiveConfig.bSafeTextureCache/* || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures*/)
|
if (g_ActiveConfig.bSafeTextureCache/* || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures*/)
|
||||||
|
@ -264,7 +291,7 @@ TextureCache::TCacheEntry* TextureCache::Load(unsigned int stage, u32 address, u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// make an entry in the table
|
// Make an entry in the table
|
||||||
TCacheEntry& entry = textures[texID];
|
TCacheEntry& entry = textures[texID];
|
||||||
PC_TexFormat pcfmt = PC_TEX_FMT_NONE;
|
PC_TexFormat pcfmt = PC_TEX_FMT_NONE;
|
||||||
|
|
||||||
|
@ -306,6 +333,7 @@ TextureCache::TCacheEntry* TextureCache::Load(unsigned int stage, u32 address, u
|
||||||
{
|
{
|
||||||
D3D::ReplaceRGBATexture2D(entry.texture->GetTex(), temp, width, height, expandedWidth, 0, usage);
|
D3D::ReplaceRGBATexture2D(entry.texture->GetTex(), temp, width, height, expandedWidth, 0, usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.addr = address;
|
entry.addr = address;
|
||||||
entry.size_in_bytes = TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format);
|
entry.size_in_bytes = TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format);
|
||||||
entry.isRenderTarget = false;
|
entry.isRenderTarget = false;
|
||||||
|
@ -340,7 +368,7 @@ TextureCache::TCacheEntry* TextureCache::Load(unsigned int stage, u32 address, u
|
||||||
entry.fmt = FullFormat;
|
entry.fmt = FullFormat;
|
||||||
|
|
||||||
INCSTAT(stats.numTexturesCreated);
|
INCSTAT(stats.numTexturesCreated);
|
||||||
SETSTAT(stats.numTexturesAlive, (int)textures.size());
|
SETSTAT(stats.numTexturesAlive, textures.size());
|
||||||
|
|
||||||
D3D::gfxstate->SetShaderResource(stage, entry.texture->GetSRV());
|
D3D::gfxstate->SetShaderResource(stage, entry.texture->GetSRV());
|
||||||
|
|
||||||
|
@ -370,7 +398,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, boo
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// remove it and recreate it as a render target
|
// Remove it and recreate it as a render target
|
||||||
SAFE_RELEASE(iter->second.texture);
|
SAFE_RELEASE(iter->second.texture);
|
||||||
textures.erase(iter);
|
textures.erase(iter);
|
||||||
}
|
}
|
||||||
|
@ -557,13 +585,13 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, boo
|
||||||
D3D::stateman->PushDepthState(efbcopydepthstate);
|
D3D::stateman->PushDepthState(efbcopydepthstate);
|
||||||
D3D::context->OMSetRenderTargets(1, &tex->GetRTV(), NULL);
|
D3D::context->OMSetRenderTargets(1, &tex->GetRTV(), NULL);
|
||||||
D3D::drawShadedTexQuad(
|
D3D::drawShadedTexQuad(
|
||||||
(bFromZBuffer) ? FBManager.GetEFBDepthTexture()->GetSRV() : FBManager.GetEFBColorTexture()->GetSRV(),
|
(bFromZBuffer) ? g_framebufferManager.GetEFBDepthTexture()->GetSRV() : g_framebufferManager.GetEFBColorTexture()->GetSRV(),
|
||||||
&sourcerect,
|
&sourcerect,
|
||||||
Renderer::GetFullTargetWidth(),
|
Renderer::GetFullTargetWidth(),
|
||||||
Renderer::GetFullTargetHeight(),
|
Renderer::GetFullTargetHeight(),
|
||||||
(bFromZBuffer) ? PixelShaderCache::GetDepthMatrixProgram() : PixelShaderCache::GetColorMatrixProgram(), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
(bFromZBuffer) ? PixelShaderCache::GetDepthMatrixProgram() : PixelShaderCache::GetColorMatrixProgram(), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
||||||
|
|
||||||
D3D::context->OMSetRenderTargets(1, &FBManager.GetEFBColorTexture()->GetRTV(), FBManager.GetEFBDepthTexture()->GetDSV());
|
D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBColorTexture()->GetRTV(), g_framebufferManager.GetEFBDepthTexture()->GetDSV());
|
||||||
D3D::stateman->PopBlendState();
|
D3D::stateman->PopBlendState();
|
||||||
D3D::stateman->PopDepthState();
|
D3D::stateman->PopDepthState();
|
||||||
D3D::stateman->PopRasterizerState();
|
D3D::stateman->PopRasterizerState();
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "Fifo.h"
|
#include "Fifo.h"
|
||||||
#include "Statistics.h"
|
#include "Statistics.h"
|
||||||
#include "Profiler.h"
|
#include "Profiler.h"
|
||||||
#include "FBManager.h"
|
#include "FramebufferManager.h"
|
||||||
#include "VertexManager.h"
|
#include "VertexManager.h"
|
||||||
#include "OpcodeDecoding.h"
|
#include "OpcodeDecoding.h"
|
||||||
#include "IndexGenerator.h"
|
#include "IndexGenerator.h"
|
||||||
|
@ -47,11 +47,18 @@ using std::string;
|
||||||
|
|
||||||
using namespace D3D;
|
using namespace D3D;
|
||||||
|
|
||||||
extern NativeVertexFormat* g_nativeVertexFmt;
|
// internal state for loading vertices
|
||||||
|
extern NativeVertexFormat *g_nativeVertexFmt;
|
||||||
|
|
||||||
namespace VertexManager
|
namespace VertexManager
|
||||||
{
|
{
|
||||||
|
|
||||||
|
static int lastPrimitive;
|
||||||
|
|
||||||
|
static u8 *LocalVBuffer;
|
||||||
|
static u16 *TIBuffer;
|
||||||
|
static u16 *LIBuffer;
|
||||||
|
static u16 *PIBuffer;
|
||||||
#define MAXVBUFFERSIZE 0x50000
|
#define MAXVBUFFERSIZE 0x50000
|
||||||
#define MAXIBUFFERSIZE 0x10000
|
#define MAXIBUFFERSIZE 0x10000
|
||||||
|
|
||||||
|
@ -59,12 +66,6 @@ namespace VertexManager
|
||||||
#define NUM_VERTEXBUFFERS 8
|
#define NUM_VERTEXBUFFERS 8
|
||||||
#define NUM_INDEXBUFFERS 10
|
#define NUM_INDEXBUFFERS 10
|
||||||
|
|
||||||
int lastPrimitive;
|
|
||||||
|
|
||||||
u8* LocalVBuffer = NULL;
|
|
||||||
u16* TIBuffer = NULL;
|
|
||||||
u16* LIBuffer = NULL;
|
|
||||||
u16* PIBuffer = NULL;
|
|
||||||
bool Flushed=false;
|
bool Flushed=false;
|
||||||
|
|
||||||
ID3D11Buffer* indexbuffers[NUM_INDEXBUFFERS] = {NULL};
|
ID3D11Buffer* indexbuffers[NUM_INDEXBUFFERS] = {NULL};
|
||||||
|
@ -147,17 +148,17 @@ void Shutdown()
|
||||||
ResetBuffer();
|
ResetBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddIndices(int _primitive, int _numVertices)
|
void AddIndices(int primitive, int numVertices)
|
||||||
{
|
{
|
||||||
switch (_primitive)
|
switch (primitive)
|
||||||
{
|
{
|
||||||
case GX_DRAW_QUADS: IndexGenerator::AddQuads(_numVertices); break;
|
case GX_DRAW_QUADS: IndexGenerator::AddQuads(numVertices); break;
|
||||||
case GX_DRAW_TRIANGLES: IndexGenerator::AddList(_numVertices); break;
|
case GX_DRAW_TRIANGLES: IndexGenerator::AddList(numVertices); break;
|
||||||
case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(_numVertices); break;
|
case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(numVertices); break;
|
||||||
case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(_numVertices); break;
|
case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(numVertices); break;
|
||||||
case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(_numVertices); break;
|
case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(numVertices); break;
|
||||||
case GX_DRAW_LINES: IndexGenerator::AddLineList(_numVertices); break;
|
case GX_DRAW_LINES: IndexGenerator::AddLineList(numVertices); break;
|
||||||
case GX_DRAW_POINTS: IndexGenerator::AddPoints(_numVertices); break;
|
case GX_DRAW_POINTS: IndexGenerator::AddPoints(numVertices); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,26 +185,27 @@ int GetRemainingVertices(int primitive)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddVertices(int _primitive, int _numVertices)
|
void AddVertices(int primitive, int numVertices)
|
||||||
{
|
{
|
||||||
if (_numVertices <= 0) return;
|
if (numVertices <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (_primitive)
|
switch (primitive)
|
||||||
{
|
{
|
||||||
case GX_DRAW_QUADS:
|
case GX_DRAW_QUADS:
|
||||||
case GX_DRAW_TRIANGLES:
|
case GX_DRAW_TRIANGLES:
|
||||||
case GX_DRAW_TRIANGLE_STRIP:
|
case GX_DRAW_TRIANGLE_STRIP:
|
||||||
case GX_DRAW_TRIANGLE_FAN:
|
case GX_DRAW_TRIANGLE_FAN:
|
||||||
if (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen() < 3 * _numVertices)
|
if (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen() < 3 * numVertices)
|
||||||
Flush();
|
Flush();
|
||||||
break;
|
break;
|
||||||
case GX_DRAW_LINE_STRIP:
|
case GX_DRAW_LINE_STRIP:
|
||||||
case GX_DRAW_LINES:
|
case GX_DRAW_LINES:
|
||||||
if (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen() < 2 * _numVertices)
|
if (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen() < 2 * numVertices)
|
||||||
Flush();
|
Flush();
|
||||||
break;
|
break;
|
||||||
case GX_DRAW_POINTS:
|
case GX_DRAW_POINTS:
|
||||||
if (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen() < _numVertices)
|
if (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen() < numVertices)
|
||||||
Flush();
|
Flush();
|
||||||
break;
|
break;
|
||||||
default: return;
|
default: return;
|
||||||
|
@ -213,10 +215,10 @@ void AddVertices(int _primitive, int _numVertices)
|
||||||
IndexGenerator::Start(TIBuffer,LIBuffer,PIBuffer);
|
IndexGenerator::Start(TIBuffer,LIBuffer,PIBuffer);
|
||||||
Flushed=false;
|
Flushed=false;
|
||||||
}
|
}
|
||||||
lastPrimitive = _primitive;
|
lastPrimitive = primitive;
|
||||||
ADDSTAT(stats.thisFrame.numPrims, _numVertices);
|
ADDSTAT(stats.thisFrame.numPrims, numVertices);
|
||||||
INCSTAT(stats.thisFrame.numPrimitiveJoins);
|
INCSTAT(stats.thisFrame.numPrimitiveJoins);
|
||||||
AddIndices(_primitive, _numVertices);
|
AddIndices(primitive, numVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Draw(u32 stride, bool alphapass)
|
inline void Draw(u32 stride, bool alphapass)
|
||||||
|
@ -303,10 +305,8 @@ void Flush()
|
||||||
|
|
||||||
u32 usedtextures = 0;
|
u32 usedtextures = 0;
|
||||||
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i)
|
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i)
|
||||||
{
|
if (bpmem.tevorders[i / 2].getEnable(i & 1))
|
||||||
if (bpmem.tevorders[i/2].getEnable(i & 1))
|
|
||||||
usedtextures |= 1 << bpmem.tevorders[i/2].getTexMap(i & 1);
|
usedtextures |= 1 << bpmem.tevorders[i/2].getTexMap(i & 1);
|
||||||
}
|
|
||||||
|
|
||||||
if (bpmem.genMode.numindstages > 0)
|
if (bpmem.genMode.numindstages > 0)
|
||||||
for (unsigned int i = 0; i < bpmem.genMode.numtevstages + 1; ++i)
|
for (unsigned int i = 0; i < bpmem.genMode.numtevstages + 1; ++i)
|
||||||
|
@ -329,15 +329,15 @@ void Flush()
|
||||||
|
|
||||||
if (tentry)
|
if (tentry)
|
||||||
{
|
{
|
||||||
|
// 0s are probably for no manual wrapping needed.
|
||||||
PixelShaderManager::SetTexDims(i, tentry->w, tentry->h, 0, 0);
|
PixelShaderManager::SetTexDims(i, tentry->w, tentry->h, 0, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
ERROR_LOG(VIDEO, "error loading texture");
|
ERROR_LOG(VIDEO, "error loading texture");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
// set global constants
|
||||||
VertexShaderManager::SetConstants();
|
VertexShaderManager::SetConstants();
|
||||||
PixelShaderManager::SetConstants();
|
PixelShaderManager::SetConstants();
|
||||||
|
|
||||||
|
@ -365,5 +365,4 @@ void Flush()
|
||||||
shader_fail:
|
shader_fail:
|
||||||
ResetBuffer();
|
ResetBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include "XFMemory.h"
|
#include "XFMemory.h"
|
||||||
|
|
||||||
VertexShaderCache::VSCache VertexShaderCache::vshaders;
|
VertexShaderCache::VSCache VertexShaderCache::vshaders;
|
||||||
const VertexShaderCache::VSCacheEntry* VertexShaderCache::last_entry;
|
const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry;
|
||||||
|
|
||||||
static ID3D11VertexShader* SimpleVertexShader = NULL;
|
static ID3D11VertexShader* SimpleVertexShader = NULL;
|
||||||
static ID3D11VertexShader* ClearVertexShader = NULL;
|
static ID3D11VertexShader* ClearVertexShader = NULL;
|
||||||
|
@ -83,7 +83,7 @@ void SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const
|
||||||
// this class will load the precompiled shaders into our cache
|
// this class will load the precompiled shaders into our cache
|
||||||
class VertexShaderCacheInserter : public LinearDiskCacheReader {
|
class VertexShaderCacheInserter : public LinearDiskCacheReader {
|
||||||
public:
|
public:
|
||||||
void Read(const u8* key, int key_size, const u8* value, int value_size)
|
void Read(const u8 *key, int key_size, const u8 *value, int value_size)
|
||||||
{
|
{
|
||||||
VERTEXSHADERUID uid;
|
VERTEXSHADERUID uid;
|
||||||
if (key_size != sizeof(uid))
|
if (key_size != sizeof(uid))
|
||||||
|
@ -177,6 +177,9 @@ void VertexShaderCache::Init()
|
||||||
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
|
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
|
||||||
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));
|
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));
|
||||||
|
|
||||||
|
SETSTAT(stats.numVertexShadersCreated, 0);
|
||||||
|
SETSTAT(stats.numVertexShadersAlive, 0);
|
||||||
|
|
||||||
char cache_filename[MAX_PATH];
|
char cache_filename[MAX_PATH];
|
||||||
sprintf(cache_filename, "%sdx11-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX), globals->unique_id);
|
sprintf(cache_filename, "%sdx11-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX), globals->unique_id);
|
||||||
VertexShaderCacheInserter inserter;
|
VertexShaderCacheInserter inserter;
|
||||||
|
@ -214,8 +217,7 @@ bool VertexShaderCache::SetShader(u32 components)
|
||||||
|
|
||||||
memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
|
memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
|
||||||
|
|
||||||
VSCache::iterator iter;
|
VSCache::iterator iter = vshaders.find(uid);
|
||||||
iter = vshaders.find(uid);
|
|
||||||
if (iter != vshaders.end())
|
if (iter != vshaders.end())
|
||||||
{
|
{
|
||||||
iter->second.frameCount = frameCount;
|
iter->second.frameCount = frameCount;
|
||||||
|
@ -226,7 +228,7 @@ bool VertexShaderCache::SetShader(u32 components)
|
||||||
return (entry.shader != NULL);
|
return (entry.shader != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* code = GenerateVertexShaderCode(components, API_D3D11);
|
const char *code = GenerateVertexShaderCode(components, API_D3D11);
|
||||||
|
|
||||||
D3DBlob* pbytecode = NULL;
|
D3DBlob* pbytecode = NULL;
|
||||||
D3D::CompileVertexShader(code, (int)strlen(code), &pbytecode);
|
D3D::CompileVertexShader(code, (int)strlen(code), &pbytecode);
|
||||||
|
|
|
@ -52,19 +52,9 @@
|
||||||
#include "D3DUtil.h"
|
#include "D3DUtil.h"
|
||||||
#include "W32Util/Misc.h"
|
#include "W32Util/Misc.h"
|
||||||
#include "EmuWindow.h"
|
#include "EmuWindow.h"
|
||||||
#include "FBManager.h"
|
#include "FramebufferManager.h"
|
||||||
#include "DLCache.h"
|
#include "DLCache.h"
|
||||||
|
|
||||||
|
|
||||||
#if defined(DEBUGFAST)
|
|
||||||
#define DLL_PLUGIN_NAME "Dolphin Direct3D 11 (DebugFast)"
|
|
||||||
#elif defined(_DEBUG)
|
|
||||||
#define DLL_PLUGIN_NAME "Dolphin Direct3D 11 (Debug)"
|
|
||||||
#else
|
|
||||||
#define DLL_PLUGIN_NAME "Dolphin Direct3D 11"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
HINSTANCE g_hInstance = NULL;
|
HINSTANCE g_hInstance = NULL;
|
||||||
SVideoInitialize g_VideoInitialize;
|
SVideoInitialize g_VideoInitialize;
|
||||||
PLUGIN_GLOBALS* globals = NULL;
|
PLUGIN_GLOBALS* globals = NULL;
|
||||||
|
@ -148,7 +138,7 @@ unsigned int Callback_PeekMessages()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void UpdateFPSDisplay(const char* text)
|
void UpdateFPSDisplay(const char *text)
|
||||||
{
|
{
|
||||||
char temp[512];
|
char temp[512];
|
||||||
sprintf_s(temp, 512, "SVN R%s: DX11: %s", svn_rev_str, text);
|
sprintf_s(temp, 512, "SVN R%s: DX11: %s", svn_rev_str, text);
|
||||||
|
@ -159,7 +149,13 @@ void GetDllInfo(PLUGIN_INFO* _PluginInfo)
|
||||||
{
|
{
|
||||||
_PluginInfo->Version = 0x0100;
|
_PluginInfo->Version = 0x0100;
|
||||||
_PluginInfo->Type = PLUGIN_TYPE_VIDEO;
|
_PluginInfo->Type = PLUGIN_TYPE_VIDEO;
|
||||||
sprintf_s(_PluginInfo->Name, 100, DLL_PLUGIN_NAME);
|
#ifdef DEBUGFAST
|
||||||
|
sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D11 (DebugFast)");
|
||||||
|
#elif defined _DEBUG
|
||||||
|
sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D11 (Debug)");
|
||||||
|
#else
|
||||||
|
sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D11");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals)
|
void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals)
|
||||||
|
@ -170,7 +166,7 @@ void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals)
|
||||||
|
|
||||||
void DllAbout(HWND _hParent)
|
void DllAbout(HWND _hParent)
|
||||||
{
|
{
|
||||||
MessageBoxA(NULL, "DllAbout not implemented, how did you come here? Anyway, report this to the devs.", "Error!", MB_OK);
|
//DialogBox(g_hInstance,(LPCTSTR)IDD_ABOUT,_hParent,(DLGPROC)AboutProc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DllConfig(void *_hParent)
|
void DllConfig(void *_hParent)
|
||||||
|
@ -178,11 +174,12 @@ void DllConfig(void *_hParent)
|
||||||
DlgSettings_Show(g_hInstance, (HWND)((wxWindow *)_hParent)->GetHandle());
|
DlgSettings_Show(g_hInstance, (HWND)((wxWindow *)_hParent)->GetHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize(void* init)
|
void Initialize(void *init)
|
||||||
{
|
{
|
||||||
frameCount = 0;
|
frameCount = 0;
|
||||||
SVideoInitialize* _pVideoInitialize = (SVideoInitialize*)init;
|
SVideoInitialize *_pVideoInitialize = (SVideoInitialize*)init;
|
||||||
g_VideoInitialize = *_pVideoInitialize;
|
// Create a shortcut to _pVideoInitialize that can also update it
|
||||||
|
g_VideoInitialize = *(_pVideoInitialize);
|
||||||
InitXFBConvTables();
|
InitXFBConvTables();
|
||||||
|
|
||||||
g_Config.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "gfx_dx11.ini").c_str());
|
g_Config.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "gfx_dx11.ini").c_str());
|
||||||
|
@ -201,14 +198,17 @@ void Initialize(void* init)
|
||||||
|
|
||||||
_pVideoInitialize->pPeekMessages = g_VideoInitialize.pPeekMessages;
|
_pVideoInitialize->pPeekMessages = g_VideoInitialize.pPeekMessages;
|
||||||
_pVideoInitialize->pUpdateFPSDisplay = g_VideoInitialize.pUpdateFPSDisplay;
|
_pVideoInitialize->pUpdateFPSDisplay = g_VideoInitialize.pUpdateFPSDisplay;
|
||||||
|
|
||||||
|
// Now the window handle is written
|
||||||
_pVideoInitialize->pWindowHandle = g_VideoInitialize.pWindowHandle;
|
_pVideoInitialize->pWindowHandle = g_VideoInitialize.pWindowHandle;
|
||||||
|
|
||||||
OSD::AddMessage("Dolphin Direct3D 11 Video Plugin.", 5000);
|
OSD::AddMessage("Dolphin Direct3D11 Video Plugin.", 5000);
|
||||||
s_PluginInitialized = true;
|
s_PluginInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Video_Prepare()
|
void Video_Prepare()
|
||||||
{
|
{
|
||||||
|
// Better be safe...
|
||||||
s_efbAccessRequested = FALSE;
|
s_efbAccessRequested = FALSE;
|
||||||
s_FifoShuttingDown = FALSE;
|
s_FifoShuttingDown = FALSE;
|
||||||
s_swapRequested = FALSE;
|
s_swapRequested = FALSE;
|
||||||
|
@ -232,24 +232,26 @@ void Video_Prepare()
|
||||||
PixelEngine::Init();
|
PixelEngine::Init();
|
||||||
DLCache::Init();
|
DLCache::Init();
|
||||||
|
|
||||||
// tell the host that the window is ready
|
// Tell the host that the window is ready
|
||||||
g_VideoInitialize.pCoreMessage(WM_USER_CREATE);
|
g_VideoInitialize.pCoreMessage(WM_USER_CREATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown()
|
void Shutdown()
|
||||||
{
|
{
|
||||||
|
s_PluginInitialized = false;
|
||||||
|
|
||||||
s_efbAccessRequested = FALSE;
|
s_efbAccessRequested = FALSE;
|
||||||
s_FifoShuttingDown = FALSE;
|
s_FifoShuttingDown = FALSE;
|
||||||
s_swapRequested = FALSE;
|
s_swapRequested = FALSE;
|
||||||
|
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
DLCache::Shutdown();
|
DLCache::Shutdown();
|
||||||
|
Fifo_Shutdown();
|
||||||
CommandProcessor::Shutdown();
|
CommandProcessor::Shutdown();
|
||||||
PixelShaderManager::Shutdown();
|
PixelShaderManager::Shutdown();
|
||||||
VertexShaderManager::Shutdown();
|
VertexShaderManager::Shutdown();
|
||||||
OpcodeDecoder_Shutdown();
|
OpcodeDecoder_Shutdown();
|
||||||
VertexLoaderManager::Shutdown();
|
VertexLoaderManager::Shutdown();
|
||||||
Fifo_Shutdown();
|
|
||||||
|
|
||||||
// internal interfaces
|
// internal interfaces
|
||||||
D3D::ShutdownUtils();
|
D3D::ShutdownUtils();
|
||||||
|
@ -263,13 +265,13 @@ void Shutdown()
|
||||||
s_PluginInitialized = false;
|
s_PluginInitialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoState(unsigned char** ptr, int mode)
|
void DoState(unsigned char **ptr, int mode)
|
||||||
{
|
{
|
||||||
// clear texture cache because it might have written to RAM
|
// Clear texture cache because it might have written to RAM
|
||||||
CommandProcessor::FifoCriticalEnter();
|
CommandProcessor::FifoCriticalEnter();
|
||||||
TextureCache::Invalidate(false);
|
TextureCache::Invalidate(false);
|
||||||
CommandProcessor::FifoCriticalLeave();
|
CommandProcessor::FifoCriticalLeave();
|
||||||
// no need to clear shader caches
|
// No need to clear shader caches
|
||||||
PointerWrap p(ptr, mode);
|
PointerWrap p(ptr, mode);
|
||||||
VideoCommon_DoState(p);
|
VideoCommon_DoState(p);
|
||||||
}
|
}
|
||||||
|
@ -279,6 +281,7 @@ void EmuStateChange(PLUGIN_EMUSTATE newState)
|
||||||
Fifo_RunLoop((newState == PLUGIN_EMUSTATE_PLAY) ? true : false);
|
Fifo_RunLoop((newState == PLUGIN_EMUSTATE_PLAY) ? true : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enter and exit the video loop
|
||||||
void Video_EnterLoop()
|
void Video_EnterLoop()
|
||||||
{
|
{
|
||||||
Fifo_EnterLoop(g_VideoInitialize);
|
Fifo_EnterLoop(g_VideoInitialize);
|
||||||
|
@ -349,6 +352,7 @@ void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run from the CPU thread (from VideoInterface.cpp)
|
||||||
void Video_EndField()
|
void Video_EndField()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -358,7 +362,8 @@ void Video_AddMessage(const char* pstr, u32 milliseconds)
|
||||||
OSD::AddMessage(pstr, milliseconds);
|
OSD::AddMessage(pstr, milliseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Video_Screenshot(const char* _szFilename)
|
// Screenshot
|
||||||
|
void Video_Screenshot(const char *_szFilename)
|
||||||
{
|
{
|
||||||
Renderer::SetScreenshot(_szFilename);
|
Renderer::SetScreenshot(_szFilename);
|
||||||
}
|
}
|
||||||
|
@ -391,6 +396,7 @@ u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData)
|
||||||
s_accessEFBArgs.x = x;
|
s_accessEFBArgs.x = x;
|
||||||
s_accessEFBArgs.y = y;
|
s_accessEFBArgs.y = y;
|
||||||
s_accessEFBArgs.Data = InputData;
|
s_accessEFBArgs.Data = InputData;
|
||||||
|
|
||||||
Common::AtomicStoreRelease(s_efbAccessRequested, TRUE);
|
Common::AtomicStoreRelease(s_efbAccessRequested, TRUE);
|
||||||
|
|
||||||
if (g_VideoInitialize.bOnThread)
|
if (g_VideoInitialize.bOnThread)
|
||||||
|
@ -404,6 +410,7 @@ u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData)
|
||||||
|
|
||||||
return s_AccessEFBResult;
|
return s_AccessEFBResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,24 +16,26 @@
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include "BPFunctions.h"
|
#include "BPFunctions.h"
|
||||||
#include "D3DBase.h"
|
|
||||||
#include "VideoConfig.h"
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include "D3DBase.h"
|
||||||
|
#include "Debugger/Debugger.h"
|
||||||
#include "TextureCache.h"
|
#include "TextureCache.h"
|
||||||
#include "VertexManager.h"
|
#include "VertexManager.h"
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
#include "Debugger/Debugger.h"
|
#include "VideoConfig.h"
|
||||||
#include "TextureConverter.h"
|
|
||||||
|
|
||||||
|
|
||||||
bool textureChanged[8];
|
bool textureChanged[8];
|
||||||
|
|
||||||
const bool renderFog = false;
|
const bool renderFog = false;
|
||||||
|
|
||||||
using namespace D3D;
|
using namespace D3D;
|
||||||
|
|
||||||
namespace BPFunctions
|
namespace BPFunctions
|
||||||
{
|
{
|
||||||
|
// ----------------------------------------------
|
||||||
|
// State translation lookup tables
|
||||||
|
// Reference: Yet Another Gamecube Documentation
|
||||||
|
// ----------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
void FlushPipeline()
|
void FlushPipeline()
|
||||||
{
|
{
|
||||||
|
@ -80,6 +82,7 @@ void SetColorMask(const BPCmd &bp)
|
||||||
|
|
||||||
void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 ©fmt, const int &scaleByHalf)
|
void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 ©fmt, const int &scaleByHalf)
|
||||||
{
|
{
|
||||||
|
// bpmem.zcontrol.pixel_format to PIXELFMT_Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format)
|
||||||
if (!g_ActiveConfig.bEFBCopyDisable)
|
if (!g_ActiveConfig.bEFBCopyDisable)
|
||||||
{
|
{
|
||||||
TextureCache::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
|
TextureCache::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
|
||||||
|
|
|
@ -24,22 +24,24 @@
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
|
|
||||||
// Bytecode->shader.
|
// bytecode->shader.
|
||||||
LPDIRECT3DVERTEXSHADER9 CreateVertexShaderFromByteCode(const u8 *bytecode, int len)
|
LPDIRECT3DVERTEXSHADER9 CreateVertexShaderFromByteCode(const u8 *bytecode, int len)
|
||||||
{
|
{
|
||||||
LPDIRECT3DVERTEXSHADER9 v_shader;
|
LPDIRECT3DVERTEXSHADER9 v_shader;
|
||||||
HRESULT hr = D3D::dev->CreateVertexShader((DWORD *)bytecode, &v_shader);
|
HRESULT hr = D3D::dev->CreateVertexShader((DWORD *)bytecode, &v_shader);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
v_shader = 0;
|
{
|
||||||
|
PanicAlert("CreateVertexShaderFromByteCode failed from %p (size %d) at %s %d\n", bytecode, len, __FILE__, __LINE__);
|
||||||
|
v_shader = NULL;
|
||||||
|
}
|
||||||
return v_shader;
|
return v_shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Code->bytecode.
|
// code->bytecode.
|
||||||
bool CompileVertexShader(const char *code, int len, u8 **bytecode, int *bytecodelen)
|
bool CompileVertexShader(const char *code, int len, u8 **bytecode, int *bytecodelen)
|
||||||
{
|
{
|
||||||
//try to compile
|
LPD3DXBUFFER shaderBuffer = NULL;
|
||||||
LPD3DXBUFFER shaderBuffer = 0;
|
LPD3DXBUFFER errorBuffer = NULL;
|
||||||
LPD3DXBUFFER errorBuffer = 0;
|
|
||||||
HRESULT hr = PD3DXCompileShader(code, len, 0, 0, "main", D3D::VertexShaderVersionString(),
|
HRESULT hr = PD3DXCompileShader(code, len, 0, 0, "main", D3D::VertexShaderVersionString(),
|
||||||
0, &shaderBuffer, &errorBuffer, 0);
|
0, &shaderBuffer, &errorBuffer, 0);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
@ -69,18 +71,20 @@ bool CompileVertexShader(const char *code, int len, u8 **bytecode, int *bytecode
|
||||||
return SUCCEEDED(hr) ? true : false;
|
return SUCCEEDED(hr) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bytecode->shader
|
||||||
// Bytecode->shader.
|
|
||||||
LPDIRECT3DPIXELSHADER9 CreatePixelShaderFromByteCode(const u8 *bytecode, int len)
|
LPDIRECT3DPIXELSHADER9 CreatePixelShaderFromByteCode(const u8 *bytecode, int len)
|
||||||
{
|
{
|
||||||
LPDIRECT3DPIXELSHADER9 p_shader;
|
LPDIRECT3DPIXELSHADER9 p_shader;
|
||||||
HRESULT hr = D3D::dev->CreatePixelShader((DWORD *)bytecode, &p_shader);
|
HRESULT hr = D3D::dev->CreatePixelShader((DWORD *)bytecode, &p_shader);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
p_shader = 0;
|
{
|
||||||
|
PanicAlert("CreatePixelShaderFromByteCode failed at %s %d\n", __FILE__, __LINE__);
|
||||||
|
p_shader = NULL;
|
||||||
|
}
|
||||||
return p_shader;
|
return p_shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// code->bytecode
|
||||||
bool CompilePixelShader(const char *code, int len, u8 **bytecode, int *bytecodelen)
|
bool CompilePixelShader(const char *code, int len, u8 **bytecode, int *bytecodelen)
|
||||||
{
|
{
|
||||||
LPD3DXBUFFER shaderBuffer = 0;
|
LPD3DXBUFFER shaderBuffer = 0;
|
||||||
|
@ -118,28 +122,32 @@ bool CompilePixelShader(const char *code, int len, u8 **bytecode, int *bytecodel
|
||||||
return SUCCEEDED(hr) ? true : false;
|
return SUCCEEDED(hr) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPDIRECT3DVERTEXSHADER9 CompileAndCreateVertexShader(const char *code, int len) {
|
LPDIRECT3DVERTEXSHADER9 CompileAndCreateVertexShader(const char *code, int len)
|
||||||
|
{
|
||||||
u8 *bytecode;
|
u8 *bytecode;
|
||||||
int bytecodelen;
|
int bytecodelen;
|
||||||
if (CompileVertexShader(code, len, &bytecode, &bytecodelen)) {
|
if (CompileVertexShader(code, len, &bytecode, &bytecodelen))
|
||||||
|
{
|
||||||
LPDIRECT3DVERTEXSHADER9 v_shader = CreateVertexShaderFromByteCode(bytecode, len);
|
LPDIRECT3DVERTEXSHADER9 v_shader = CreateVertexShaderFromByteCode(bytecode, len);
|
||||||
delete [] bytecode;
|
delete [] bytecode;
|
||||||
return v_shader;
|
return v_shader;
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
PanicAlert("Failed to compile and create vertex shader from %p (size %d) at %s %d\n", code, len, __FILE__, __LINE__);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPDIRECT3DPIXELSHADER9 CompileAndCreatePixelShader(const char *code, int len) {
|
LPDIRECT3DPIXELSHADER9 CompileAndCreatePixelShader(const char* code, unsigned int len)
|
||||||
|
{
|
||||||
u8 *bytecode;
|
u8 *bytecode;
|
||||||
int bytecodelen;
|
int bytecodelen;
|
||||||
if (CompilePixelShader(code, len, &bytecode, &bytecodelen)) {
|
if (CompilePixelShader(code, len, &bytecode, &bytecodelen))
|
||||||
|
{
|
||||||
LPDIRECT3DPIXELSHADER9 p_shader = CreatePixelShaderFromByteCode(bytecode, len);
|
LPDIRECT3DPIXELSHADER9 p_shader = CreatePixelShaderFromByteCode(bytecode, len);
|
||||||
delete [] bytecode;
|
delete [] bytecode;
|
||||||
return p_shader;
|
return p_shader;
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
PanicAlert("Failed to compile and create pixel shader, %s %d\n", __FILE__, __LINE__);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -30,5 +30,5 @@ namespace D3D
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
LPDIRECT3DVERTEXSHADER9 CompileAndCreateVertexShader(const char *code, int len);
|
LPDIRECT3DVERTEXSHADER9 CompileAndCreateVertexShader(const char *code, int len);
|
||||||
LPDIRECT3DPIXELSHADER9 CompileAndCreatePixelShader(const char *code, int len);
|
LPDIRECT3DPIXELSHADER9 CompileAndCreatePixelShader(const char *code, unsigned int len);
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ int CD3DFont::Init()
|
||||||
m_fTextScale = 1.0f; // Draw fonts into texture without scaling
|
m_fTextScale = 1.0f; // Draw fonts into texture without scaling
|
||||||
|
|
||||||
// Prepare to create a bitmap
|
// Prepare to create a bitmap
|
||||||
int *pBitmapBits;
|
unsigned int* pBitmapBits;
|
||||||
BITMAPINFO bmi;
|
BITMAPINFO bmi;
|
||||||
ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER));
|
ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER));
|
||||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||||
|
@ -75,7 +75,7 @@ int CD3DFont::Init()
|
||||||
|
|
||||||
// Create a DC and a bitmap for the font
|
// Create a DC and a bitmap for the font
|
||||||
HDC hDC = CreateCompatibleDC(NULL);
|
HDC hDC = CreateCompatibleDC(NULL);
|
||||||
HBITMAP hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (VOID**)&pBitmapBits, NULL, 0);
|
HBITMAP hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&pBitmapBits, NULL, 0);
|
||||||
SetMapMode(hDC, MM_TEXT);
|
SetMapMode(hDC, MM_TEXT);
|
||||||
|
|
||||||
// Create a font. By specifying ANTIALIASED_QUALITY, we might get an
|
// Create a font. By specifying ANTIALIASED_QUALITY, we might get an
|
||||||
|
@ -99,7 +99,7 @@ int CD3DFont::Init()
|
||||||
SetBkColor (hDC, 0);
|
SetBkColor (hDC, 0);
|
||||||
SetTextAlign(hDC, TA_TOP);
|
SetTextAlign(hDC, TA_TOP);
|
||||||
|
|
||||||
// Loop through all printable character and output them to the bitmap..
|
// Loop through all printable characters and output them to the bitmap
|
||||||
// Meanwhile, keep track of the corresponding tex coords for each character.
|
// Meanwhile, keep track of the corresponding tex coords for each character.
|
||||||
int x = 0, y = 0;
|
int x = 0, y = 0;
|
||||||
char str[2] = "\0";
|
char str[2] = "\0";
|
||||||
|
@ -120,10 +120,12 @@ int CD3DFont::Init()
|
||||||
m_fTexCoords[c][2] = ((float)(x+0+size.cx))/m_dwTexWidth;
|
m_fTexCoords[c][2] = ((float)(x+0+size.cx))/m_dwTexWidth;
|
||||||
m_fTexCoords[c][3] = ((float)(y+0+size.cy))/m_dwTexHeight;
|
m_fTexCoords[c][3] = ((float)(y+0+size.cy))/m_dwTexHeight;
|
||||||
|
|
||||||
x += size.cx + 3; //3 to work around annoying ij conflict (part of the j ends up with the i)
|
x += size.cx + 3; // 3 to work around annoying ij conflict (part of the j ends up with the i)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new texture for the font
|
// Create a new texture for the font
|
||||||
|
// possible optimization: store the converted data in a buffer and fill the texture on creation.
|
||||||
|
// That way, we can use a static texture
|
||||||
hr = dev->CreateTexture(m_dwTexWidth, m_dwTexHeight, 1, D3DUSAGE_DYNAMIC,
|
hr = dev->CreateTexture(m_dwTexWidth, m_dwTexHeight, 1, D3DUSAGE_DYNAMIC,
|
||||||
D3DFMT_A4R4G4B4, D3DPOOL_DEFAULT, &m_pTexture, NULL);
|
D3DFMT_A4R4G4B4, D3DPOOL_DEFAULT, &m_pTexture, NULL);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
@ -296,7 +298,7 @@ int CD3DFont::DrawTextScaled(float x, float y, float fXScale, float fYScale, flo
|
||||||
if (c < (' '))
|
if (c < (' '))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
c-=32;
|
c -= 32;
|
||||||
float tx1 = m_fTexCoords[c][0];
|
float tx1 = m_fTexCoords[c][0];
|
||||||
float ty1 = m_fTexCoords[c][1];
|
float ty1 = m_fTexCoords[c][1];
|
||||||
float tx2 = m_fTexCoords[c][2];
|
float tx2 = m_fTexCoords[c][2];
|
||||||
|
@ -329,7 +331,6 @@ int CD3DFont::DrawTextScaled(float x, float y, float fXScale, float fYScale, flo
|
||||||
m_pVB->Lock(0, 0, (void**)&pVertices, D3DLOCK_DISCARD);
|
m_pVB->Lock(0, 0, (void**)&pVertices, D3DLOCK_DISCARD);
|
||||||
dwNumTriangles = 0;
|
dwNumTriangles = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sx += w + spacing*fXScale*vpWidth;
|
sx += w + spacing*fXScale*vpWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -349,15 +349,15 @@ static void DX9DebuggerUpdateScreen()
|
||||||
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
|
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
|
||||||
D3D::dev->SetDepthStencilSurface(NULL);
|
D3D::dev->SetDepthStencilSurface(NULL);
|
||||||
|
|
||||||
D3D::dev->StretchRect(FBManager.GetEFBColorRTSurface(), NULL,
|
D3D::dev->StretchRect(g_framebufferManager.GetEFBColorRTSurface(), NULL,
|
||||||
D3D::GetBackBufferSurface(), NULL,
|
D3D::GetBackBufferSurface(), NULL,
|
||||||
D3DTEXF_LINEAR);
|
D3DTEXF_LINEAR);
|
||||||
|
|
||||||
D3D::dev->EndScene();
|
D3D::dev->EndScene();
|
||||||
D3D::dev->Present(NULL, NULL, NULL, NULL);
|
D3D::dev->Present(NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
D3D::dev->SetRenderTarget(0, FBManager.GetEFBColorRTSurface());
|
D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
|
||||||
D3D::dev->SetDepthStencilSurface(FBManager.GetEFBDepthRTSurface());
|
D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
|
||||||
D3D::dev->BeginScene();
|
D3D::dev->BeginScene();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -145,14 +145,6 @@ void OSDMenu(WPARAM wParam)
|
||||||
case '3':
|
case '3':
|
||||||
OSDChoice = 1;
|
OSDChoice = 1;
|
||||||
// Toggle native resolution
|
// Toggle native resolution
|
||||||
/*
|
|
||||||
if (!(g_Config.bNativeResolution || g_Config.b2xResolution))
|
|
||||||
g_Config.bNativeResolution = true;
|
|
||||||
else if (g_Config.bNativeResolution && Renderer::AllowCustom())
|
|
||||||
{ g_Config.bNativeResolution = false; if (Renderer::Allow2x()) {g_Config.b2xResolution = true;} }
|
|
||||||
else if (Renderer::AllowCustom())
|
|
||||||
g_Config.b2xResolution = false;
|
|
||||||
*/
|
|
||||||
OSDInternalW = D3D::GetBackBufferWidth();
|
OSDInternalW = D3D::GetBackBufferWidth();
|
||||||
OSDInternalH = D3D::GetBackBufferHeight();
|
OSDInternalH = D3D::GetBackBufferHeight();
|
||||||
break;
|
break;
|
||||||
|
@ -224,6 +216,7 @@ HWND Create(HWND hParent, HINSTANCE hInstance, const TCHAR *title)
|
||||||
// TODO:
|
// TODO:
|
||||||
// 1. Remove redundant window manipulation,
|
// 1. Remove redundant window manipulation,
|
||||||
// 2. Make DX9 in fullscreen can be overlapped by other dialogs
|
// 2. Make DX9 in fullscreen can be overlapped by other dialogs
|
||||||
|
// 3. Request window sizes which actually make the client area map to a common resolution
|
||||||
HWND Ret;
|
HWND Ret;
|
||||||
int x=0, y=0, width=640, height=480;
|
int x=0, y=0, width=640, height=480;
|
||||||
g_VideoInitialize.pRequestWindowSize(x, y, width, height);
|
g_VideoInitialize.pRequestWindowSize(x, y, width, height);
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#undef CHECK
|
#undef CHECK
|
||||||
#define CHECK(hr, Message, ...) if (FAILED(hr)) { PanicAlert(__FUNCTION__ "Failed in %s at line %d: " Message, __FILE__, __LINE__, __VA_ARGS__); }
|
#define CHECK(hr, Message, ...) if (FAILED(hr)) { PanicAlert(__FUNCTION__ "Failed in %s at line %d: " Message, __FILE__, __LINE__, __VA_ARGS__); }
|
||||||
|
|
||||||
FramebufferManager FBManager;
|
FramebufferManager g_framebufferManager;
|
||||||
|
|
||||||
LPDIRECT3DSURFACE9 FramebufferManager::GetEFBColorRTSurface()
|
LPDIRECT3DSURFACE9 FramebufferManager::GetEFBColorRTSurface()
|
||||||
{
|
{
|
||||||
|
@ -313,7 +313,6 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
|
||||||
LPDIRECT3DTEXTURE9 xfbTexture;
|
LPDIRECT3DTEXTURE9 xfbTexture;
|
||||||
HRESULT hr = 0;
|
HRESULT hr = 0;
|
||||||
|
|
||||||
|
|
||||||
VirtualXFBListType::iterator it = findVirtualXFB(xfbAddr, fbWidth, fbHeight);
|
VirtualXFBListType::iterator it = findVirtualXFB(xfbAddr, fbWidth, fbHeight);
|
||||||
|
|
||||||
if (it == m_virtualXFBList.end() && (int)m_virtualXFBList.size() >= MAX_VIRTUAL_XFB)
|
if (it == m_virtualXFBList.end() && (int)m_virtualXFBList.size() >= MAX_VIRTUAL_XFB)
|
||||||
|
@ -393,8 +392,7 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
|
||||||
m_virtualXFBList.push_front(newVirt);
|
m_virtualXFBList.push_front(newVirt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy EFB to XFB texture
|
// Copy EFB data to XFB and restore render target again
|
||||||
|
|
||||||
if(!xfbTexture)
|
if(!xfbTexture)
|
||||||
return;
|
return;
|
||||||
LPDIRECT3DTEXTURE9 read_texture = GetEFBColorTexture(sourceRc);
|
LPDIRECT3DTEXTURE9 read_texture = GetEFBColorTexture(sourceRc);
|
||||||
|
|
|
@ -107,7 +107,6 @@ public:
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
||||||
|
|
||||||
const XFBSource** GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
const XFBSource** GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
||||||
|
|
||||||
LPDIRECT3DTEXTURE9 GetEFBColorTexture(const EFBRectangle& sourceRc);
|
LPDIRECT3DTEXTURE9 GetEFBColorTexture(const EFBRectangle& sourceRc);
|
||||||
|
@ -168,6 +167,6 @@ private:
|
||||||
D3DFORMAT s_efb_depth_ReadBuffer_Format;//Format of the Depth color Read Surface
|
D3DFORMAT s_efb_depth_ReadBuffer_Format;//Format of the Depth color Read Surface
|
||||||
};
|
};
|
||||||
|
|
||||||
extern FramebufferManager FBManager;
|
extern FramebufferManager g_framebufferManager;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include "CPMemory.h"
|
#include "CPMemory.h"
|
||||||
#include "NativeVertexFormat.h"
|
#include "NativeVertexFormat.h"
|
||||||
|
|
||||||
|
|
||||||
class D3DVertexFormat : public NativeVertexFormat
|
class D3DVertexFormat : public NativeVertexFormat
|
||||||
{
|
{
|
||||||
LPDIRECT3DVERTEXDECLARATION9 d3d_decl;
|
LPDIRECT3DVERTEXDECLARATION9 d3d_decl;
|
||||||
|
@ -76,12 +75,13 @@ D3DDECLTYPE VarToD3D(VarType t, int size)
|
||||||
D3DDECLTYPE_UNUSED, D3DDECLTYPE_UBYTE4N, D3DDECLTYPE_SHORT4N, D3DDECLTYPE_USHORT4N, D3DDECLTYPE_FLOAT4,
|
D3DDECLTYPE_UNUSED, D3DDECLTYPE_UBYTE4N, D3DDECLTYPE_SHORT4N, D3DDECLTYPE_USHORT4N, D3DDECLTYPE_FLOAT4,
|
||||||
};
|
};
|
||||||
D3DDECLTYPE retval = D3DDECLTYPE_UNUSED;
|
D3DDECLTYPE retval = D3DDECLTYPE_UNUSED;
|
||||||
switch (size) {
|
switch (size)
|
||||||
|
{
|
||||||
case 1: retval = lookup1[t]; break;
|
case 1: retval = lookup1[t]; break;
|
||||||
case 2: retval = lookup2[t]; break;
|
case 2: retval = lookup2[t]; break;
|
||||||
case 3: retval = lookup3[t]; break;
|
case 3: retval = lookup3[t]; break;
|
||||||
case 4: retval = lookup4[t]; break;
|
case 4: retval = lookup4[t]; break;
|
||||||
default: PanicAlert("VarToD3D: size wrong (%i)", size); break;
|
default: break;
|
||||||
}
|
}
|
||||||
if (retval == D3DDECLTYPE_UNUSED) {
|
if (retval == D3DDECLTYPE_UNUSED) {
|
||||||
PanicAlert("VarToD3D: Invalid type/size combo %i , %i", (int)t, size);
|
PanicAlert("VarToD3D: Invalid type/size combo %i , %i", (int)t, size);
|
||||||
|
|
|
@ -239,14 +239,13 @@ void PixelShaderCache::Init()
|
||||||
char cache_filename[MAX_PATH];
|
char cache_filename[MAX_PATH];
|
||||||
sprintf(cache_filename, "%sdx9-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX), globals->unique_id);
|
sprintf(cache_filename, "%sdx9-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX), globals->unique_id);
|
||||||
PixelShaderCacheInserter inserter;
|
PixelShaderCacheInserter inserter;
|
||||||
int read_items = g_ps_disk_cache.OpenAndRead(cache_filename, &inserter);
|
g_ps_disk_cache.OpenAndRead(cache_filename, &inserter);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ONLY to be used during shutdown.
|
// ONLY to be used during shutdown.
|
||||||
void PixelShaderCache::Clear()
|
void PixelShaderCache::Clear()
|
||||||
{
|
{
|
||||||
PSCache::iterator iter = PixelShaders.begin();
|
for (PSCache::iterator iter = PixelShaders.begin(); iter != PixelShaders.end(); iter++)
|
||||||
for (; iter != PixelShaders.end(); ++iter)
|
|
||||||
iter->second.Destroy();
|
iter->second.Destroy();
|
||||||
PixelShaders.clear();
|
PixelShaders.clear();
|
||||||
|
|
||||||
|
@ -279,19 +278,16 @@ bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
|
||||||
PIXELSHADERUID uid;
|
PIXELSHADERUID uid;
|
||||||
GetPixelShaderId(&uid, dstAlpha);
|
GetPixelShaderId(&uid, dstAlpha);
|
||||||
|
|
||||||
// Is the shader already set?
|
// Check if the shader is already set
|
||||||
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
|
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
|
||||||
{
|
{
|
||||||
PSCache::const_iterator iter = PixelShaders.find(uid);
|
PSCache::const_iterator iter = PixelShaders.find(uid);
|
||||||
if (iter != PixelShaders.end() && iter->second.shader)
|
return (iter != PixelShaders.end() && iter->second.shader);
|
||||||
return true; // Sure, we're done.
|
|
||||||
else
|
|
||||||
return false; // ?? something is wrong.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID));
|
memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID));
|
||||||
|
|
||||||
// Is the shader already in the cache?
|
// Check if the shader is already in the cache
|
||||||
PSCache::iterator iter;
|
PSCache::iterator iter;
|
||||||
iter = PixelShaders.find(uid);
|
iter = PixelShaders.find(uid);
|
||||||
if (iter != PixelShaders.end())
|
if (iter != PixelShaders.end())
|
||||||
|
@ -311,14 +307,14 @@ bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// OK, need to generate and compile it.
|
// Need to compile a new shader
|
||||||
const char *code = GeneratePixelShaderCode(dstAlpha, API_D3D9,components);
|
const char *code = GeneratePixelShaderCode(dstAlpha, API_D3D9,components);
|
||||||
|
|
||||||
u32 code_hash = HashAdler32((const u8 *)code, strlen(code));
|
u32 code_hash = HashAdler32((const u8 *)code, strlen(code));
|
||||||
unique_shaders.insert(code_hash);
|
unique_shaders.insert(code_hash);
|
||||||
SETSTAT(stats.numUniquePixelShaders, unique_shaders.size());
|
SETSTAT(stats.numUniquePixelShaders, unique_shaders.size());
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {
|
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {
|
||||||
static int counter = 0;
|
static int counter = 0;
|
||||||
char szTemp[MAX_PATH];
|
char szTemp[MAX_PATH];
|
||||||
|
@ -326,7 +322,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
|
||||||
|
|
||||||
SaveData(szTemp, code);
|
SaveData(szTemp, code);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
u8 *bytecode = 0;
|
u8 *bytecode = 0;
|
||||||
int bytecodelen = 0;
|
int bytecodelen = 0;
|
||||||
|
@ -342,7 +338,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here we have the UID and the byte code. Insert it into the disk cache.
|
// Insert the bytecode into the caches
|
||||||
g_ps_disk_cache.Append((u8 *)&uid, sizeof(uid), bytecode, bytecodelen);
|
g_ps_disk_cache.Append((u8 *)&uid, sizeof(uid), bytecode, bytecodelen);
|
||||||
g_ps_disk_cache.Sync();
|
g_ps_disk_cache.Sync();
|
||||||
|
|
||||||
|
@ -352,7 +348,8 @@ bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate) {
|
bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate)
|
||||||
|
{
|
||||||
LPDIRECT3DPIXELSHADER9 shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen);
|
LPDIRECT3DPIXELSHADER9 shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen);
|
||||||
|
|
||||||
// Make an entry in the table
|
// Make an entry in the table
|
||||||
|
@ -368,7 +365,7 @@ bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytec
|
||||||
}
|
}
|
||||||
|
|
||||||
INCSTAT(stats.numPixelShadersCreated);
|
INCSTAT(stats.numPixelShadersCreated);
|
||||||
SETSTAT(stats.numPixelShadersAlive, (int)PixelShaders.size());
|
SETSTAT(stats.numPixelShadersAlive, PixelShaders.size());
|
||||||
if (activate)
|
if (activate)
|
||||||
{
|
{
|
||||||
D3D::SetPixelShader(shader);
|
D3D::SetPixelShader(shader);
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
|
|
||||||
#include "debugger/debugger.h"
|
#include "debugger/debugger.h"
|
||||||
|
|
||||||
int s_fps=0;
|
static int s_fps = 0;
|
||||||
|
|
||||||
static bool WindowResized;
|
static bool WindowResized;
|
||||||
static int s_target_width;
|
static int s_target_width;
|
||||||
|
@ -75,14 +75,14 @@ static float EFByScale;
|
||||||
static int s_recordWidth;
|
static int s_recordWidth;
|
||||||
static int s_recordHeight;
|
static int s_recordHeight;
|
||||||
|
|
||||||
static bool s_LastFrameDumped;
|
static bool s_bLastFrameDumped;
|
||||||
static bool s_AVIDumping;
|
static bool s_bAVIDumping;
|
||||||
|
|
||||||
static u32 s_blendMode;
|
static u32 s_blendMode;
|
||||||
static u32 s_LastAA;
|
static u32 s_LastAA;
|
||||||
static u32 s_LastEFBScale;
|
static u32 s_LastEFBScale;
|
||||||
static bool IS_AMD;
|
static bool IS_AMD;
|
||||||
static bool XFBWrited;
|
static bool XFBWrited = false;
|
||||||
|
|
||||||
// used extern by other files. need to clean this up at some point.
|
// used extern by other files. need to clean this up at some point.
|
||||||
int frameCount;
|
int frameCount;
|
||||||
|
@ -120,6 +120,24 @@ static const D3DBLEND d3dDestFactors[8] =
|
||||||
D3DBLEND_INVDESTALPHA
|
D3DBLEND_INVDESTALPHA
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 0 0x00
|
||||||
|
// 1 Source & destination
|
||||||
|
// 2 Source & ~destination
|
||||||
|
// 3 Source
|
||||||
|
// 4 ~Source & destination
|
||||||
|
// 5 Destination
|
||||||
|
// 6 Source ^ destination = Source & ~destination | ~Source & destination
|
||||||
|
// 7 Source | destination
|
||||||
|
|
||||||
|
// 8 ~(Source | destination)
|
||||||
|
// 9 ~(Source ^ destination) = ~Source & ~destination | Source & destination
|
||||||
|
// 10 ~Destination
|
||||||
|
// 11 Source | ~destination
|
||||||
|
// 12 ~Source
|
||||||
|
// 13 ~Source | destination
|
||||||
|
// 14 ~(Source & destination)
|
||||||
|
// 15 0xff
|
||||||
|
|
||||||
static const D3DBLENDOP d3dLogicOpop[16] =
|
static const D3DBLENDOP d3dLogicOpop[16] =
|
||||||
{
|
{
|
||||||
D3DBLENDOP_ADD,
|
D3DBLENDOP_ADD,
|
||||||
|
@ -223,7 +241,7 @@ void SetupDeviceObjects()
|
||||||
{
|
{
|
||||||
D3D::font.Init();
|
D3D::font.Init();
|
||||||
VertexLoaderManager::Init();
|
VertexLoaderManager::Init();
|
||||||
FBManager.Create();
|
g_framebufferManager.Create();
|
||||||
|
|
||||||
VertexShaderManager::Dirty();
|
VertexShaderManager::Dirty();
|
||||||
PixelShaderManager::Dirty();
|
PixelShaderManager::Dirty();
|
||||||
|
@ -243,7 +261,7 @@ void TeardownDeviceObjects()
|
||||||
ScreenShootMEMSurface = NULL;
|
ScreenShootMEMSurface = NULL;
|
||||||
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
|
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
|
||||||
D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface());
|
D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface());
|
||||||
FBManager.Destroy();
|
g_framebufferManager.Destroy();
|
||||||
D3D::font.Shutdown();
|
D3D::font.Shutdown();
|
||||||
TextureCache::Invalidate(false);
|
TextureCache::Invalidate(false);
|
||||||
VertexLoaderManager::Shutdown();
|
VertexLoaderManager::Shutdown();
|
||||||
|
@ -252,6 +270,7 @@ void TeardownDeviceObjects()
|
||||||
TextureConverter::Shutdown();
|
TextureConverter::Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Init functions
|
||||||
bool Renderer::Init()
|
bool Renderer::Init()
|
||||||
{
|
{
|
||||||
st = new char[32768];
|
st = new char[32768];
|
||||||
|
@ -276,6 +295,8 @@ bool Renderer::Init()
|
||||||
fullScreenRes, backbuffer_ms_mode, false);
|
fullScreenRes, backbuffer_ms_mode, false);
|
||||||
|
|
||||||
IS_AMD = D3D::IsATIDevice();
|
IS_AMD = D3D::IsATIDevice();
|
||||||
|
|
||||||
|
// Decide frambuffer size
|
||||||
s_backbuffer_width = D3D::GetBackBufferWidth();
|
s_backbuffer_width = D3D::GetBackBufferWidth();
|
||||||
s_backbuffer_height = D3D::GetBackBufferHeight();
|
s_backbuffer_height = D3D::GetBackBufferHeight();
|
||||||
|
|
||||||
|
@ -323,8 +344,8 @@ bool Renderer::Init()
|
||||||
s_Fulltarget_width = s_target_width;
|
s_Fulltarget_width = s_target_width;
|
||||||
s_Fulltarget_height = s_target_height;
|
s_Fulltarget_height = s_target_height;
|
||||||
|
|
||||||
s_LastFrameDumped = false;
|
s_bLastFrameDumped = false;
|
||||||
s_AVIDumping = false;
|
s_bAVIDumping = false;
|
||||||
|
|
||||||
// We're not using fixed function.
|
// We're not using fixed function.
|
||||||
// Let's just set the matrices to identity to be sure.
|
// Let's just set the matrices to identity to be sure.
|
||||||
|
@ -348,8 +369,8 @@ bool Renderer::Init()
|
||||||
D3D::dev->SetViewport(&vp);
|
D3D::dev->SetViewport(&vp);
|
||||||
D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 0, 0);
|
D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 0, 0);
|
||||||
|
|
||||||
D3D::dev->SetRenderTarget(0, FBManager.GetEFBColorRTSurface());
|
D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
|
||||||
D3D::dev->SetDepthStencilSurface(FBManager.GetEFBDepthRTSurface());
|
D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
|
||||||
vp.X = (s_Fulltarget_width - s_target_width) / 2;
|
vp.X = (s_Fulltarget_width - s_target_width) / 2;
|
||||||
vp.Y = (s_Fulltarget_height - s_target_height) / 2;
|
vp.Y = (s_Fulltarget_height - s_target_height) / 2;
|
||||||
vp.Width = s_target_width;
|
vp.Width = s_target_width;
|
||||||
|
@ -369,28 +390,60 @@ void Renderer::Shutdown()
|
||||||
D3D::Present();
|
D3D::Present();
|
||||||
D3D::Close();
|
D3D::Close();
|
||||||
|
|
||||||
if (s_AVIDumping)
|
if (s_bAVIDumping)
|
||||||
{
|
{
|
||||||
AVIDump::Stop();
|
AVIDump::Stop();
|
||||||
}
|
}
|
||||||
delete [] st;
|
delete [] st;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Renderer::GetTargetWidth() { return s_target_width; }
|
// Return the rendering target width and height
|
||||||
int Renderer::GetTargetHeight() { return s_target_height; }
|
int Renderer::GetTargetWidth()
|
||||||
int Renderer::GetFullTargetWidth() { return s_Fulltarget_width; }
|
{
|
||||||
int Renderer::GetFullTargetHeight() { return s_Fulltarget_height; }
|
return s_target_width;
|
||||||
float Renderer::GetTargetScaleX() { return EFBxScale; }
|
}
|
||||||
float Renderer::GetTargetScaleY() { return EFByScale; }
|
|
||||||
|
|
||||||
float Renderer::GetXFBScaleX() { return xScale; }
|
int Renderer::GetTargetHeight()
|
||||||
float Renderer::GetXFBScaleY() { return yScale; }
|
{
|
||||||
|
return s_target_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Renderer::GetFullTargetWidth()
|
||||||
|
{
|
||||||
|
return s_Fulltarget_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Renderer::GetFullTargetHeight()
|
||||||
|
{
|
||||||
|
return s_Fulltarget_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Renderer::GetTargetScaleX()
|
||||||
|
{
|
||||||
|
return EFBxScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Renderer::GetTargetScaleY()
|
||||||
|
{
|
||||||
|
return EFByScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Renderer::GetXFBScaleX()
|
||||||
|
{
|
||||||
|
return xScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Renderer::GetXFBScaleY()
|
||||||
|
{
|
||||||
|
return yScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the framebuffer size
|
||||||
int Renderer::GetFrameBufferWidth()
|
int Renderer::GetFrameBufferWidth()
|
||||||
{
|
{
|
||||||
return s_backbuffer_width;
|
return s_backbuffer_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Renderer::GetFrameBufferHeight()
|
int Renderer::GetFrameBufferHeight()
|
||||||
{
|
{
|
||||||
return s_backbuffer_height;
|
return s_backbuffer_height;
|
||||||
|
@ -399,7 +452,7 @@ int Renderer::GetFrameBufferHeight()
|
||||||
// Create On-Screen-Messages
|
// Create On-Screen-Messages
|
||||||
void Renderer::DrawDebugText()
|
void Renderer::DrawDebugText()
|
||||||
{
|
{
|
||||||
// OSD Menu messages
|
// OSD menu messages
|
||||||
if (g_ActiveConfig.bOSDHotKey)
|
if (g_ActiveConfig.bOSDHotKey)
|
||||||
{
|
{
|
||||||
if (OSDChoice > 0)
|
if (OSDChoice > 0)
|
||||||
|
@ -434,9 +487,12 @@ void Renderer::DrawDebugText()
|
||||||
std::string OSDM3 = g_ActiveConfig.bEFBCopyDisable ? "Disabled" :
|
std::string OSDM3 = g_ActiveConfig.bEFBCopyDisable ? "Disabled" :
|
||||||
g_ActiveConfig.bCopyEFBToTexture ? "To Texture" : "To RAM";
|
g_ActiveConfig.bCopyEFBToTexture ? "To Texture" : "To RAM";
|
||||||
|
|
||||||
// If there is more text than this we will have a collission
|
// If there is more text than this we will have a collision
|
||||||
if (g_ActiveConfig.bShowFPS)
|
if (g_ActiveConfig.bShowFPS)
|
||||||
{ T1 += "\n\n"; T2 += "\n\n"; }
|
{
|
||||||
|
T1 += "\n\n";
|
||||||
|
T2 += "\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
// The rows
|
// The rows
|
||||||
T0.push_back(StringFromFormat("3: Internal Resolution: %s\n", OSDM1.c_str()));
|
T0.push_back(StringFromFormat("3: Internal Resolution: %s\n", OSDM1.c_str()));
|
||||||
|
@ -504,9 +560,7 @@ void formatBufferDump(const char *in, char *out, int w, int h, int p)
|
||||||
void CheckForResize()
|
void CheckForResize()
|
||||||
{
|
{
|
||||||
while (EmuWindow::IsSizing())
|
while (EmuWindow::IsSizing())
|
||||||
{
|
|
||||||
Sleep(10);
|
Sleep(10);
|
||||||
}
|
|
||||||
|
|
||||||
if (EmuWindow::GetParentWnd())
|
if (EmuWindow::GetParentWnd())
|
||||||
{
|
{
|
||||||
|
@ -522,7 +576,8 @@ void CheckForResize()
|
||||||
GetClientRect(EmuWindow::GetWnd(), &rcWindow);
|
GetClientRect(EmuWindow::GetWnd(), &rcWindow);
|
||||||
int client_width = rcWindow.right - rcWindow.left;
|
int client_width = rcWindow.right - rcWindow.left;
|
||||||
int client_height = rcWindow.bottom - rcWindow.top;
|
int client_height = rcWindow.bottom - rcWindow.top;
|
||||||
// Sanity check.
|
|
||||||
|
// Sanity check
|
||||||
if ((client_width != s_backbuffer_width ||
|
if ((client_width != s_backbuffer_width ||
|
||||||
client_height != s_backbuffer_height) &&
|
client_height != s_backbuffer_height) &&
|
||||||
client_width >= 4 && client_height >= 4)
|
client_width >= 4 && client_height >= 4)
|
||||||
|
@ -539,8 +594,6 @@ void CheckForResize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
||||||
{
|
{
|
||||||
if (!fbWidth || !fbHeight)
|
if (!fbWidth || !fbHeight)
|
||||||
|
@ -552,7 +605,7 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
|
||||||
// just use progressive.
|
// just use progressive.
|
||||||
if (g_ActiveConfig.bUseXFB)
|
if (g_ActiveConfig.bUseXFB)
|
||||||
{
|
{
|
||||||
FBManager.CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
|
g_framebufferManager.CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -644,18 +697,18 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
|
|
||||||
// Get the working buffer
|
// Get the working buffer
|
||||||
LPDIRECT3DSURFACE9 pBuffer = (type == PEEK_Z || type == POKE_Z) ?
|
LPDIRECT3DSURFACE9 pBuffer = (type == PEEK_Z || type == POKE_Z) ?
|
||||||
FBManager.GetEFBDepthRTSurface() : FBManager.GetEFBColorRTSurface();
|
g_framebufferManager.GetEFBDepthRTSurface() : g_framebufferManager.GetEFBColorRTSurface();
|
||||||
// Get the temporal buffer to move 1pixel data
|
// Get the temporal buffer to move 1pixel data
|
||||||
LPDIRECT3DSURFACE9 RBuffer = (type == PEEK_Z || type == POKE_Z) ?
|
LPDIRECT3DSURFACE9 RBuffer = (type == PEEK_Z || type == POKE_Z) ?
|
||||||
FBManager.GetEFBDepthReadSurface() : FBManager.GetEFBColorReadSurface();
|
g_framebufferManager.GetEFBDepthReadSurface() : g_framebufferManager.GetEFBColorReadSurface();
|
||||||
// Get the memory buffer that can be locked
|
// Get the memory buffer that can be locked
|
||||||
LPDIRECT3DSURFACE9 pOffScreenBuffer = (type == PEEK_Z || type == POKE_Z) ?
|
LPDIRECT3DSURFACE9 pOffScreenBuffer = (type == PEEK_Z || type == POKE_Z) ?
|
||||||
FBManager.GetEFBDepthOffScreenRTSurface() : FBManager.GetEFBColorOffScreenRTSurface();
|
g_framebufferManager.GetEFBDepthOffScreenRTSurface() : g_framebufferManager.GetEFBColorOffScreenRTSurface();
|
||||||
// Get the buffer format
|
// Get the buffer format
|
||||||
D3DFORMAT BufferFormat = (type == PEEK_Z || type == POKE_Z) ?
|
D3DFORMAT BufferFormat = (type == PEEK_Z || type == POKE_Z) ?
|
||||||
FBManager.GetEFBDepthRTSurfaceFormat() : FBManager.GetEFBColorRTSurfaceFormat();
|
g_framebufferManager.GetEFBDepthRTSurfaceFormat() : g_framebufferManager.GetEFBColorRTSurfaceFormat();
|
||||||
D3DFORMAT ReadBufferFormat = (type == PEEK_Z || type == POKE_Z) ?
|
D3DFORMAT ReadBufferFormat = (type == PEEK_Z || type == POKE_Z) ?
|
||||||
FBManager.GetEFBDepthReadSurfaceFormat() : BufferFormat;
|
g_framebufferManager.GetEFBDepthReadSurfaceFormat() : BufferFormat;
|
||||||
|
|
||||||
if (BufferFormat == D3DFMT_D24X8)
|
if (BufferFormat == D3DFMT_D24X8)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -667,8 +720,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
PanicAlert("No %s!", (type == PEEK_Z || type == POKE_Z) ? "Z-Buffer" : "Color EFB");
|
PanicAlert("No %s!", (type == PEEK_Z || type == POKE_Z) ? "Z-Buffer" : "Color EFB");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// Get the rectangular target region covered by the EFB pixel.
|
// Get the rectangular target region covered by the EFB pixel
|
||||||
|
|
||||||
EFBRectangle efbPixelRc;
|
EFBRectangle efbPixelRc;
|
||||||
efbPixelRc.left = x;
|
efbPixelRc.left = x;
|
||||||
efbPixelRc.top = y;
|
efbPixelRc.top = y;
|
||||||
|
@ -700,6 +752,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
RectToLock.bottom--;
|
RectToLock.bottom--;
|
||||||
if ((RectToLock.right - RectToLock.left) > 4)
|
if ((RectToLock.right - RectToLock.left) > 4)
|
||||||
RectToLock.left++;
|
RectToLock.left++;
|
||||||
|
|
||||||
ResetAPIState(); // Reset any game specific settings
|
ResetAPIState(); // Reset any game specific settings
|
||||||
hr = D3D::dev->SetDepthStencilSurface(NULL);
|
hr = D3D::dev->SetDepthStencilSurface(NULL);
|
||||||
hr = D3D::dev->SetRenderTarget(0, RBuffer);
|
hr = D3D::dev->SetRenderTarget(0, RBuffer);
|
||||||
|
@ -727,7 +780,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
colmat[0] = colmat[5] = colmat[10] = 1.0f;
|
colmat[0] = colmat[5] = colmat[10] = 1.0f;
|
||||||
PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation
|
PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation
|
||||||
EFBRectangle source_rect;
|
EFBRectangle source_rect;
|
||||||
LPDIRECT3DTEXTURE9 read_texture = FBManager.GetEFBDepthTexture(source_rect);
|
LPDIRECT3DTEXTURE9 read_texture = g_framebufferManager.GetEFBDepthTexture(source_rect);
|
||||||
|
|
||||||
D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
|
D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
|
||||||
|
|
||||||
|
@ -742,8 +795,8 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
|
|
||||||
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
|
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
|
||||||
|
|
||||||
hr = D3D::dev->SetRenderTarget(0, FBManager.GetEFBColorRTSurface());
|
hr = D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
|
||||||
hr = D3D::dev->SetDepthStencilSurface(FBManager.GetEFBDepthRTSurface());
|
hr = D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
|
||||||
RestoreAPIState();
|
RestoreAPIState();
|
||||||
RectToLock.bottom = 4;
|
RectToLock.bottom = 4;
|
||||||
RectToLock.left = 0;
|
RectToLock.left = 0;
|
||||||
|
@ -773,7 +826,6 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// The surface is good.. lock it
|
// The surface is good.. lock it
|
||||||
if ((hr = pOffScreenBuffer->LockRect(&drect, &RectToLock, D3DLOCK_READONLY)) != D3D_OK)
|
if ((hr = pOffScreenBuffer->LockRect(&drect, &RectToLock, D3DLOCK_READONLY)) != D3D_OK)
|
||||||
{
|
{
|
||||||
|
@ -781,7 +833,8 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type)
|
||||||
|
{
|
||||||
case PEEK_Z:
|
case PEEK_Z:
|
||||||
{
|
{
|
||||||
switch (ReadBufferFormat)
|
switch (ReadBufferFormat)
|
||||||
|
@ -803,10 +856,20 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PEEK_COLOR:
|
case POKE_Z:
|
||||||
z = ((u32 *)drect.pBits)[0];
|
// TODO: Implement
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PEEK_COLOR:
|
||||||
|
z = ((u32*)drect.pBits)[0];
|
||||||
|
break;
|
||||||
|
|
||||||
case POKE_COLOR:
|
case POKE_COLOR:
|
||||||
|
// TODO: Implement. One way is to draw a tiny pixel-sized rectangle at
|
||||||
|
// the exact location. Note: EFB pokes are susceptible to Z-buffering
|
||||||
|
// and perhaps blending.
|
||||||
|
//WARN_LOG(VIDEOINTERFACE, "This is probably some kind of software rendering");
|
||||||
|
break;
|
||||||
|
|
||||||
// TODO: Implement POKE_Z and POKE_COLOR
|
// TODO: Implement POKE_Z and POKE_COLOR
|
||||||
default:
|
default:
|
||||||
|
@ -905,10 +968,10 @@ void UpdateViewport()
|
||||||
{
|
{
|
||||||
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
|
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
|
||||||
D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface());
|
D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface());
|
||||||
FBManager.Destroy();
|
g_framebufferManager.Destroy();
|
||||||
FBManager.Create();
|
g_framebufferManager.Create();
|
||||||
D3D::dev->SetRenderTarget(0, FBManager.GetEFBColorRTSurface());
|
D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
|
||||||
D3D::dev->SetDepthStencilSurface(FBManager.GetEFBDepthRTSurface());
|
D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vp.X = X;
|
vp.X = X;
|
||||||
|
@ -978,7 +1041,7 @@ void Renderer::SetBlendMode(bool forceUpdate)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool RightFrame = false;
|
static bool RightFrame = false;
|
||||||
|
// This function has the final picture. We adjust the aspect ratio here.
|
||||||
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc)
|
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc)
|
||||||
{
|
{
|
||||||
if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.bUseRealXFB) || !fbWidth || !fbHeight)
|
if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.bUseRealXFB) || !fbWidth || !fbHeight)
|
||||||
|
@ -992,7 +1055,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
|
|
||||||
if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2;
|
if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2;
|
||||||
u32 xfbCount = 0;
|
u32 xfbCount = 0;
|
||||||
const XFBSource** xfbSourceList = FBManager.GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
const XFBSource** xfbSourceList = g_framebufferManager.GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
||||||
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
||||||
{
|
{
|
||||||
g_VideoInitialize.pCopiedToXFB(false);
|
g_VideoInitialize.pCopiedToXFB(false);
|
||||||
|
@ -1019,7 +1082,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
RightFrame = true;
|
RightFrame = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Set the backbuffer as the rendering target
|
|
||||||
|
// Prepare to copy the XFBs to our backbuffer
|
||||||
D3D::dev->SetDepthStencilSurface(NULL);
|
D3D::dev->SetDepthStencilSurface(NULL);
|
||||||
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
|
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
|
||||||
|
|
||||||
|
@ -1085,12 +1149,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
int xfbWidth = xfbSource->srcWidth;
|
int xfbWidth = xfbSource->srcWidth;
|
||||||
int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2);
|
int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2);
|
||||||
|
|
||||||
drawRc.bottom = 1.0f - 2.0f * ((hOffset) / (float)fbHeight);
|
drawRc.bottom = 1.0f - (2.0f * (hOffset) / (float)fbHeight);
|
||||||
drawRc.top = 1.0f - 2.0f * ((hOffset + xfbHeight) / (float)fbHeight);
|
drawRc.top = 1.0f - (2.0f * (hOffset + xfbHeight) / (float)fbHeight);
|
||||||
drawRc.left = -(xfbWidth / (float)fbWidth);
|
drawRc.left = -(xfbWidth / (float)fbWidth);
|
||||||
drawRc.right = (xfbWidth / (float)fbWidth);
|
drawRc.right = (xfbWidth / (float)fbWidth);
|
||||||
|
|
||||||
|
|
||||||
if (!g_ActiveConfig.bAutoScale)
|
if (!g_ActiveConfig.bAutoScale)
|
||||||
{
|
{
|
||||||
// scale draw area for a 1 to 1 pixel mapping with the draw target
|
// scale draw area for a 1 to 1 pixel mapping with the draw target
|
||||||
|
@ -1117,7 +1180,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
|
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
|
||||||
LPDIRECT3DTEXTURE9 read_texture = FBManager.GetEFBColorTexture(rc);
|
LPDIRECT3DTEXTURE9 read_texture = g_framebufferManager.GetEFBColorTexture(rc);
|
||||||
D3D::drawShadedTexQuad(read_texture,targetRc.AsRECT(),Renderer::GetFullTargetWidth(),Renderer::GetFullTargetHeight(),Width,Height,PixelShaderCache::GetColorCopyProgram(g_Config.iMultisampleMode),VertexShaderCache::GetSimpleVertexShader(g_Config.iMultisampleMode));
|
D3D::drawShadedTexQuad(read_texture,targetRc.AsRECT(),Renderer::GetFullTargetWidth(),Renderer::GetFullTargetHeight(),Width,Height,PixelShaderCache::GetColorCopyProgram(g_Config.iMultisampleMode),VertexShaderCache::GetSimpleVertexShader(g_Config.iMultisampleMode));
|
||||||
}
|
}
|
||||||
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
|
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
|
||||||
|
@ -1134,7 +1197,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
vp.MinZ = 0.0f;
|
vp.MinZ = 0.0f;
|
||||||
vp.MaxZ = 1.0f;
|
vp.MaxZ = 1.0f;
|
||||||
D3D::dev->SetViewport(&vp);
|
D3D::dev->SetViewport(&vp);
|
||||||
if(s_bScreenshot)
|
if (s_bScreenshot)
|
||||||
{
|
{
|
||||||
s_criticalScreenshot.Enter();
|
s_criticalScreenshot.Enter();
|
||||||
HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface);
|
HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface);
|
||||||
|
@ -1153,12 +1216,12 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
if (g_ActiveConfig.bDumpFrames)
|
if (g_ActiveConfig.bDumpFrames)
|
||||||
{
|
{
|
||||||
HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface);
|
HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface);
|
||||||
if (!s_LastFrameDumped)
|
if (!s_bLastFrameDumped)
|
||||||
{
|
{
|
||||||
s_recordWidth = dst_rect.GetWidth();
|
s_recordWidth = dst_rect.GetWidth();
|
||||||
s_recordHeight = dst_rect.GetHeight();
|
s_recordHeight = dst_rect.GetHeight();
|
||||||
s_AVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight);
|
s_bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight);
|
||||||
if (!s_AVIDumping)
|
if (!s_bAVIDumping)
|
||||||
{
|
{
|
||||||
PanicAlert("Error dumping frames to AVI.");
|
PanicAlert("Error dumping frames to AVI.");
|
||||||
}
|
}
|
||||||
|
@ -1169,7 +1232,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
OSD::AddMessage(msg, 2000);
|
OSD::AddMessage(msg, 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (s_AVIDumping)
|
if (s_bAVIDumping)
|
||||||
{
|
{
|
||||||
D3DLOCKED_RECT rect;
|
D3DLOCKED_RECT rect;
|
||||||
if (SUCCEEDED(ScreenShootMEMSurface->LockRect(&rect, dst_rect.AsRECT(), D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY)))
|
if (SUCCEEDED(ScreenShootMEMSurface->LockRect(&rect, dst_rect.AsRECT(), D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY)))
|
||||||
|
@ -1181,16 +1244,17 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
ScreenShootMEMSurface->UnlockRect();
|
ScreenShootMEMSurface->UnlockRect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s_LastFrameDumped = true;
|
s_bLastFrameDumped = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (s_LastFrameDumped && s_AVIDumping)
|
if (s_bLastFrameDumped && s_bAVIDumping)
|
||||||
{
|
{
|
||||||
AVIDump::Stop();
|
AVIDump::Stop();
|
||||||
s_AVIDumping = false;
|
s_bAVIDumping = false;
|
||||||
|
OSD::AddMessage("Stop dumping frames to AVI", 2000);
|
||||||
}
|
}
|
||||||
s_LastFrameDumped = false;
|
s_bLastFrameDumped = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finish up the current frame, print some stats
|
// Finish up the current frame, print some stats
|
||||||
|
@ -1213,16 +1277,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
D3D::font.DrawTextScaled(0, 30, 20, 20, 0.0f, 0xFF00FFFF, st, false);
|
D3D::font.DrawTextScaled(0, 30, 20, 20, 0.0f, 0xFF00FFFF, st, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
OSD::DrawMessages();
|
OSD::DrawMessages();
|
||||||
|
|
||||||
D3D::EndFrame();
|
D3D::EndFrame();
|
||||||
|
|
||||||
frameCount++;
|
frameCount++;
|
||||||
DLCache::ProgressiveCleanup();
|
DLCache::ProgressiveCleanup();
|
||||||
TextureCache::Cleanup();
|
TextureCache::Cleanup();
|
||||||
|
|
||||||
// Make any new configuration settings active.
|
// Enable any configuration changes
|
||||||
UpdateActiveConfig();
|
UpdateActiveConfig();
|
||||||
WindowResized = false;
|
WindowResized = false;
|
||||||
CheckForResize();
|
CheckForResize();
|
||||||
|
@ -1288,13 +1349,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FBManager.Destroy();
|
g_framebufferManager.Destroy();
|
||||||
FBManager.Create();
|
g_framebufferManager.Create();
|
||||||
}
|
}
|
||||||
D3D::dev->SetRenderTarget(0, FBManager.GetEFBColorRTSurface());
|
D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
|
||||||
D3D::dev->SetDepthStencilSurface(FBManager.GetEFBDepthRTSurface());
|
D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Place messages on the picture, then copy it to the screen
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
// Count FPS.
|
// Count FPS.
|
||||||
// -------------
|
// -------------
|
||||||
|
@ -1311,20 +1373,26 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
|
|
||||||
// Begin new frame
|
// Begin new frame
|
||||||
// Set default viewport and scissor, for the clear to work correctly
|
// Set default viewport and scissor, for the clear to work correctly
|
||||||
|
// New frame
|
||||||
stats.ResetFrame();
|
stats.ResetFrame();
|
||||||
|
|
||||||
// Flip/present backbuffer to frontbuffer here
|
// Flip/present backbuffer to frontbuffer here
|
||||||
D3D::Present();
|
D3D::Present();
|
||||||
D3D::BeginFrame();
|
D3D::BeginFrame();
|
||||||
Renderer::RestoreAPIState();
|
Renderer::RestoreAPIState();
|
||||||
D3D::dev->SetRenderTarget(0, FBManager.GetEFBColorRTSurface());
|
D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
|
||||||
D3D::dev->SetDepthStencilSurface(FBManager.GetEFBDepthRTSurface());
|
D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
|
||||||
UpdateViewport();
|
UpdateViewport();
|
||||||
VertexShaderManager::SetViewportChanged();
|
VertexShaderManager::SetViewportChanged();
|
||||||
|
// For testing zbuffer targets.
|
||||||
|
// Renderer::SetZBufferRender();
|
||||||
|
// SaveTexture("tex.tga", GL_TEXTURE_RECTANGLE_ARB, s_FakeZTarget,
|
||||||
|
// GetTargetWidth(), GetTargetHeight());
|
||||||
g_VideoInitialize.pCopiedToXFB(XFBWrited || g_ActiveConfig.bUseRealXFB);
|
g_VideoInitialize.pCopiedToXFB(XFBWrited || g_ActiveConfig.bUseRealXFB);
|
||||||
XFBWrited = false;
|
XFBWrited = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ALWAYS call RestoreAPIState for each ResetAPIState call you're doing
|
||||||
void Renderer::ResetAPIState()
|
void Renderer::ResetAPIState()
|
||||||
{
|
{
|
||||||
D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
|
D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
|
||||||
|
@ -1365,6 +1433,7 @@ void Renderer::SetDepthMode()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// if the test is disabled write is disabled too
|
||||||
D3D::SetRenderState(D3DRS_ZENABLE, FALSE);
|
D3D::SetRenderState(D3DRS_ZENABLE, FALSE);
|
||||||
D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE); // ??
|
D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE); // ??
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,30 @@ void TextureCache::Invalidate(bool shutdown)
|
||||||
HiresTextures::Shutdown();
|
HiresTextures::Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextureCache::Shutdown()
|
||||||
|
{
|
||||||
|
Invalidate(true);
|
||||||
|
FreeMemoryPages(temp, TEMP_SIZE);
|
||||||
|
temp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureCache::Cleanup()
|
||||||
|
{
|
||||||
|
TexCache::iterator iter = textures.begin();
|
||||||
|
while (iter != textures.end())
|
||||||
|
{
|
||||||
|
if (frameCount > TEXTURE_KILL_THRESHOLD + iter->second.frameCount)
|
||||||
|
{
|
||||||
|
iter->second.Destroy(false);
|
||||||
|
iter = textures.erase(iter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TextureCache::InvalidateRange(u32 start_address, u32 size)
|
void TextureCache::InvalidateRange(u32 start_address, u32 size)
|
||||||
{
|
{
|
||||||
TexCache::iterator iter = textures.begin();
|
TexCache::iterator iter = textures.begin();
|
||||||
|
@ -120,49 +144,50 @@ int TextureCache::TCacheEntry::IntersectsMemoryRange(u32 range_address, u32 rang
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::Shutdown()
|
|
||||||
{
|
|
||||||
Invalidate(true);
|
|
||||||
FreeMemoryPages(temp, TEMP_SIZE);
|
|
||||||
temp = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextureCache::Cleanup()
|
|
||||||
{
|
|
||||||
TexCache::iterator iter = textures.begin();
|
|
||||||
while (iter != textures.end())
|
|
||||||
{
|
|
||||||
if (frameCount > TEXTURE_KILL_THRESHOLD + iter->second.frameCount)
|
|
||||||
{
|
|
||||||
iter->second.Destroy(false);
|
|
||||||
textures.erase(iter++);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, int height, int tex_format, int tlutaddr, int tlutfmt,bool UseNativeMips, int maxlevel)
|
TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, int height, int tex_format, int tlutaddr, int tlutfmt,bool UseNativeMips, int maxlevel)
|
||||||
{
|
{
|
||||||
|
// notes (about "UNsafe texture cache"):
|
||||||
|
// Have to be removed soon.
|
||||||
|
// But we keep it until the "safe" way became rock solid
|
||||||
|
// pros: it has an unique ID held by the texture data itself (@address) once cached.
|
||||||
|
// cons: it writes this unique ID in the gc RAM <- very dangerous (break MP1) and ugly
|
||||||
|
|
||||||
|
// notes (about "safe texture cache"):
|
||||||
|
// Metroids text issue (character table):
|
||||||
|
// Same addr, same GX_TF_C4 texture data but different TLUT (hence different outputs).
|
||||||
|
// That's why we have to hash the TLUT too for TLUT tex_format dependent textures (ie. GX_TF_C4, GX_TF_C8, GX_TF_C14X2).
|
||||||
|
// And since the address and tex data don't change, the key index in the cacheEntry map can't be the address but
|
||||||
|
// have to be a real unique ID.
|
||||||
|
// DONE but not satifiying yet -> may break copyEFBToTexture sometimes.
|
||||||
|
|
||||||
|
// Pokemon Colosseum text issue (plain text):
|
||||||
|
// Use a GX_TF_I4 512x512 text-flush-texture at a const address.
|
||||||
|
// The problem here was just the sparse hash on the texture. This texture is partly overwrited (what is needed only)
|
||||||
|
// so lot's of remaning old text. Thin white chars on black bg too.
|
||||||
|
|
||||||
|
// TODO: - clean this up when ready to kill old "unsafe texture cache"
|
||||||
|
// - fix the key index situation with CopyRenderTargetToTexture.
|
||||||
|
// Could happen only for GX_TF_C4, GX_TF_C8 and GX_TF_C14X2 fmt.
|
||||||
|
// Wonder if we can't use tex width&height to know if EFB might be copied to it...
|
||||||
|
// raw idea: TOCHECK if addresses are aligned we have few bits left...
|
||||||
|
|
||||||
if (address == 0)
|
if (address == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
u8 *ptr = g_VideoInitialize.pGetMemoryPointer(address);
|
u8 *ptr = g_VideoInitialize.pGetMemoryPointer(address);
|
||||||
int bsw = TexDecoder_GetBlockWidthInTexels(tex_format) - 1; //TexelSizeInNibbles(format)*width*height/16;
|
int bsw = TexDecoder_GetBlockWidthInTexels(tex_format) - 1; // TexelSizeInNibbles(format)*width*height/16;
|
||||||
int bsh = TexDecoder_GetBlockHeightInTexels(tex_format) - 1; //TexelSizeInNibbles(format)*width*height/16;
|
int bsh = TexDecoder_GetBlockHeightInTexels(tex_format) - 1; // TexelSizeInNibbles(format)*width*height/16;
|
||||||
int bsdepth = TexDecoder_GetTexelSizeInNibbles(tex_format);
|
int bsdepth = TexDecoder_GetTexelSizeInNibbles(tex_format);
|
||||||
int expandedWidth = (width + bsw) & (~bsw);
|
int expandedWidth = (width + bsw) & (~bsw);
|
||||||
int expandedHeight = (height + bsh) & (~bsh);
|
int expandedHeight = (height + bsh) & (~bsh);
|
||||||
|
|
||||||
u64 hash_value;
|
u64 hash_value = 0;
|
||||||
u32 texID = address;
|
u32 texID = address;
|
||||||
u64 texHash;
|
u64 texHash = 0;
|
||||||
u32 FullFormat = tex_format;
|
u32 FullFormat = tex_format;
|
||||||
bool TextureisDynamic = false;
|
bool TextureisDynamic = false;
|
||||||
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
|
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
|
||||||
u32 FullFormat = (tex_format | (tlutfmt << 16));
|
FullFormat = (tex_format | (tlutfmt << 16));
|
||||||
|
|
||||||
if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures)
|
if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures)
|
||||||
{
|
{
|
||||||
|
@ -325,7 +350,7 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
|
||||||
bool isPow2 = !((width & (width - 1)) || (height & (height - 1)));
|
bool isPow2 = !((width & (width - 1)) || (height & (height - 1)));
|
||||||
entry.isNonPow2 = false;
|
entry.isNonPow2 = false;
|
||||||
int TexLevels = (width > height)?width:height;
|
int TexLevels = (width > height)?width:height;
|
||||||
TexLevels = (isPow2 && UseNativeMips && (maxlevel > 0)) ? (int)(log((double)TexLevels)/log((double)2)) + 1 : ((isPow2)? 0 : 1);
|
TexLevels = (isPow2 && UseNativeMips && (maxlevel > 0)) ? (int)(log((double)TexLevels)/log((double)2)) + 1 : (isPow2? 0 : 1);
|
||||||
if(TexLevels > (maxlevel + 1) && maxlevel > 0)
|
if(TexLevels > (maxlevel + 1) && maxlevel > 0)
|
||||||
TexLevels = (maxlevel + 1);
|
TexLevels = (maxlevel + 1);
|
||||||
entry.MipLevels = maxlevel;
|
entry.MipLevels = maxlevel;
|
||||||
|
@ -371,7 +396,7 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
|
||||||
char szTemp[MAX_PATH];
|
char szTemp[MAX_PATH];
|
||||||
char szDir[MAX_PATH];
|
char szDir[MAX_PATH];
|
||||||
const char* uniqueId = globals->unique_id;
|
const char* uniqueId = globals->unique_id;
|
||||||
bool bCheckedDumpDir = false;
|
static bool bCheckedDumpDir = false;
|
||||||
|
|
||||||
sprintf(szDir, "%s%s", File::GetUserPath(D_DUMPTEXTURES_IDX), uniqueId);
|
sprintf(szDir, "%s%s", File::GetUserPath(D_DUMPTEXTURES_IDX), uniqueId);
|
||||||
|
|
||||||
|
@ -390,7 +415,7 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
|
||||||
}
|
}
|
||||||
|
|
||||||
INCSTAT(stats.numTexturesCreated);
|
INCSTAT(stats.numTexturesCreated);
|
||||||
SETSTAT(stats.numTexturesAlive, (int)textures.size());
|
SETSTAT(stats.numTexturesAlive, textures.size());
|
||||||
|
|
||||||
//Set the texture!
|
//Set the texture!
|
||||||
D3D::SetTexture(stage, entry.texture);
|
D3D::SetTexture(stage, entry.texture);
|
||||||
|
@ -434,12 +459,12 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, boo
|
||||||
textures.erase(iter);
|
textures.erase(iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(TextureisDynamic)
|
if (TextureisDynamic)
|
||||||
{
|
{
|
||||||
Scaledtex_w = tex_w;
|
Scaledtex_w = tex_w;
|
||||||
Scaledtex_h = tex_h;
|
Scaledtex_h = tex_h;
|
||||||
}
|
}
|
||||||
if(!tex)
|
if (!tex)
|
||||||
{
|
{
|
||||||
TCacheEntry entry;
|
TCacheEntry entry;
|
||||||
entry.addr = address;
|
entry.addr = address;
|
||||||
|
@ -459,7 +484,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, boo
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure to resolve anything we need to read from.
|
// Make sure to resolve anything we need to read from.
|
||||||
LPDIRECT3DTEXTURE9 read_texture = bFromZBuffer ? FBManager.GetEFBDepthTexture(source_rect) : FBManager.GetEFBColorTexture(source_rect);
|
LPDIRECT3DTEXTURE9 read_texture = bFromZBuffer ? g_framebufferManager.GetEFBDepthTexture(source_rect) : g_framebufferManager.GetEFBColorTexture(source_rect);
|
||||||
|
|
||||||
// We have to run a pixel shader, for color conversion.
|
// We have to run a pixel shader, for color conversion.
|
||||||
Renderer::ResetAPIState(); // reset any game specific settings
|
Renderer::ResetAPIState(); // reset any game specific settings
|
||||||
|
@ -625,7 +650,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, boo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
D3DFORMAT bformat = FBManager.GetEFBDepthRTSurfaceFormat();
|
D3DFORMAT bformat = g_framebufferManager.GetEFBDepthRTSurfaceFormat();
|
||||||
int SSAAMode = g_ActiveConfig.iMultisampleMode;
|
int SSAAMode = g_ActiveConfig.iMultisampleMode;
|
||||||
D3D::drawShadedTexQuad(
|
D3D::drawShadedTexQuad(
|
||||||
read_texture,
|
read_texture,
|
||||||
|
@ -660,9 +685,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, boo
|
||||||
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
|
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
|
||||||
D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER);
|
D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER);
|
||||||
D3D::SetTexture(0,NULL);
|
D3D::SetTexture(0,NULL);
|
||||||
D3D::dev->SetRenderTarget(0, FBManager.GetEFBColorRTSurface());
|
D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
|
||||||
D3D::dev->SetDepthStencilSurface(FBManager.GetEFBDepthRTSurface());
|
D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
|
||||||
Renderer::RestoreAPIState();
|
Renderer::RestoreAPIState();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -156,7 +156,6 @@ void Init()
|
||||||
}
|
}
|
||||||
CreateRgbToYuyvProgram();
|
CreateRgbToYuyvProgram();
|
||||||
CreateYuyvToRgbProgram();
|
CreateYuyvToRgbProgram();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown()
|
void Shutdown()
|
||||||
|
@ -277,16 +276,8 @@ void EncodeToRamUsingShader(LPDIRECT3DPIXELSHADER9 shader, LPDIRECT3DTEXTURE9 sr
|
||||||
|
|
||||||
D3DLOCKED_RECT drect;
|
D3DLOCKED_RECT drect;
|
||||||
|
|
||||||
|
|
||||||
hr = D3D::dev->GetRenderTargetData(Rendersurf,s_texConvReadSurface);
|
hr = D3D::dev->GetRenderTargetData(Rendersurf,s_texConvReadSurface);
|
||||||
if((hr = s_texConvReadSurface->LockRect(&drect, &DstRect, D3DLOCK_READONLY)) != D3D_OK)
|
hr = s_texConvReadSurface->LockRect(&drect, &DstRect, D3DLOCK_READONLY);
|
||||||
{
|
|
||||||
PanicAlert("ERROR: %s", hr == D3DERR_WASSTILLDRAWING ? "Still drawing" :
|
|
||||||
hr == D3DERR_INVALIDCALL ? "Invalid call" : "w00t");
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int writeStride = bpmem.copyMipMapStrideChannels * 32;
|
int writeStride = bpmem.copyMipMapStrideChannels * 32;
|
||||||
|
|
||||||
if (writeStride != readStride && toTexture)
|
if (writeStride != readStride && toTexture)
|
||||||
|
@ -310,7 +301,6 @@ void EncodeToRamUsingShader(LPDIRECT3DPIXELSHADER9 shader, LPDIRECT3DTEXTURE9 sr
|
||||||
memcpy(destAddr,drect.pBits,dstWidth*dstHeight*4);// 4 bytes per pixel
|
memcpy(destAddr,drect.pBits,dstWidth*dstHeight*4);// 4 bytes per pixel
|
||||||
|
|
||||||
hr = s_texConvReadSurface->UnlockRect();
|
hr = s_texConvReadSurface->UnlockRect();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
|
void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
|
||||||
|
@ -335,7 +325,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
|
||||||
|
|
||||||
u8 *dest_ptr = Memory_GetPtr(address);
|
u8 *dest_ptr = Memory_GetPtr(address);
|
||||||
|
|
||||||
LPDIRECT3DTEXTURE9 source_texture = bFromZBuffer ? FBManager.GetEFBDepthTexture(source) : FBManager.GetEFBColorTexture(source);
|
LPDIRECT3DTEXTURE9 source_texture = bFromZBuffer ? g_framebufferManager.GetEFBDepthTexture(source) : g_framebufferManager.GetEFBColorTexture(source);
|
||||||
int width = (source.right - source.left) >> bScaleByHalf;
|
int width = (source.right - source.left) >> bScaleByHalf;
|
||||||
int height = (source.bottom - source.top) >> bScaleByHalf;
|
int height = (source.bottom - source.top) >> bScaleByHalf;
|
||||||
|
|
||||||
|
@ -383,9 +373,9 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
|
||||||
|
|
||||||
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
|
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
|
||||||
Renderer::ResetAPIState();
|
Renderer::ResetAPIState();
|
||||||
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight,readStride, true, bScaleByHalf > 0);
|
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0);
|
||||||
D3D::dev->SetRenderTarget(0, FBManager.GetEFBColorRTSurface());
|
D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
|
||||||
D3D::dev->SetDepthStencilSurface(FBManager.GetEFBDepthRTSurface());
|
D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
|
||||||
Renderer::RestoreAPIState();
|
Renderer::RestoreAPIState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,8 +444,7 @@ u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture,u32 Sou
|
||||||
return Hashvalue;
|
return Hashvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight)
|
||||||
void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc,u8* destAddr, int dstWidth, int dstHeight)
|
|
||||||
{
|
{
|
||||||
TextureConversionShader::SetShaderParameters(
|
TextureConversionShader::SetShaderParameters(
|
||||||
(float)dstWidth,
|
(float)dstWidth,
|
||||||
|
@ -468,8 +457,8 @@ void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourc
|
||||||
(float)Renderer::GetFullTargetHeight());
|
(float)Renderer::GetFullTargetHeight());
|
||||||
Renderer::ResetAPIState();
|
Renderer::ResetAPIState();
|
||||||
EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false);
|
EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false);
|
||||||
D3D::dev->SetRenderTarget(0, FBManager.GetEFBColorRTSurface());
|
D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
|
||||||
D3D::dev->SetDepthStencilSurface(FBManager.GetEFBDepthRTSurface());
|
D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
|
||||||
Renderer::RestoreAPIState();
|
Renderer::RestoreAPIState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,8 +530,8 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE
|
||||||
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
|
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
|
||||||
D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER);
|
D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER);
|
||||||
D3D::SetTexture(0,NULL);
|
D3D::SetTexture(0,NULL);
|
||||||
D3D::dev->SetRenderTarget(0, FBManager.GetEFBColorRTSurface());
|
D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
|
||||||
D3D::dev->SetDepthStencilSurface(FBManager.GetEFBDepthRTSurface());
|
D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
|
||||||
Renderer::RestoreAPIState();
|
Renderer::RestoreAPIState();
|
||||||
Rendersurf->Release();
|
Rendersurf->Release();
|
||||||
s_srcTexture->Release();
|
s_srcTexture->Release();
|
||||||
|
|
|
@ -85,22 +85,20 @@ void Shutdown()
|
||||||
ResetBuffer();
|
ResetBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddIndices(int _primitive, int _numVertices)
|
void AddIndices(int primitive, int numVertices)
|
||||||
{
|
{
|
||||||
switch (_primitive)
|
switch (primitive)
|
||||||
{
|
{
|
||||||
case GX_DRAW_QUADS: IndexGenerator::AddQuads(_numVertices); break;
|
case GX_DRAW_QUADS: IndexGenerator::AddQuads(numVertices); break;
|
||||||
case GX_DRAW_TRIANGLES: IndexGenerator::AddList(_numVertices); break;
|
case GX_DRAW_TRIANGLES: IndexGenerator::AddList(numVertices); break;
|
||||||
case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(_numVertices); break;
|
case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(numVertices); break;
|
||||||
case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(_numVertices); break;
|
case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(numVertices); break;
|
||||||
case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(_numVertices); break;
|
case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(numVertices); break;
|
||||||
case GX_DRAW_LINES: IndexGenerator::AddLineList(_numVertices); break;
|
case GX_DRAW_LINES: IndexGenerator::AddLineList(numVertices); break;
|
||||||
case GX_DRAW_POINTS: IndexGenerator::AddPoints(_numVertices); break;
|
case GX_DRAW_POINTS: IndexGenerator::AddPoints(numVertices); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int GetRemainingSize()
|
int GetRemainingSize()
|
||||||
{
|
{
|
||||||
return MAXVBUFFERSIZE - (int)(s_pCurBufferPointer - LocalVBuffer);
|
return MAXVBUFFERSIZE - (int)(s_pCurBufferPointer - LocalVBuffer);
|
||||||
|
@ -124,39 +122,40 @@ int GetRemainingVertices(int primitive)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddVertices(int _primitive, int _numVertices)
|
void AddVertices(int primitive, int numVertices)
|
||||||
{
|
{
|
||||||
if (_numVertices <= 0)
|
if (numVertices <= 0)
|
||||||
return;
|
return;
|
||||||
switch (_primitive)
|
|
||||||
|
switch (primitive)
|
||||||
{
|
{
|
||||||
case GX_DRAW_QUADS:
|
case GX_DRAW_QUADS:
|
||||||
case GX_DRAW_TRIANGLES:
|
case GX_DRAW_TRIANGLES:
|
||||||
case GX_DRAW_TRIANGLE_STRIP:
|
case GX_DRAW_TRIANGLE_STRIP:
|
||||||
case GX_DRAW_TRIANGLE_FAN:
|
case GX_DRAW_TRIANGLE_FAN:
|
||||||
if(MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen() < 3 * _numVertices)
|
if (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen() < 3 * numVertices)
|
||||||
Flush();
|
Flush();
|
||||||
break;
|
break;
|
||||||
case GX_DRAW_LINE_STRIP:
|
case GX_DRAW_LINE_STRIP:
|
||||||
case GX_DRAW_LINES:
|
case GX_DRAW_LINES:
|
||||||
if(MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen() < 2 * _numVertices)
|
if (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen() < 2 * numVertices)
|
||||||
Flush();
|
Flush();
|
||||||
break;
|
break;
|
||||||
case GX_DRAW_POINTS:
|
case GX_DRAW_POINTS:
|
||||||
if(MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen() < _numVertices)
|
if (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen() < numVertices)
|
||||||
Flush();
|
Flush();
|
||||||
break;
|
break;
|
||||||
default: return;
|
default: return;
|
||||||
}
|
}
|
||||||
if(Flushed)
|
if (Flushed)
|
||||||
{
|
{
|
||||||
IndexGenerator::Start(TIBuffer,LIBuffer,PIBuffer);
|
IndexGenerator::Start(TIBuffer,LIBuffer,PIBuffer);
|
||||||
Flushed=false;
|
Flushed=false;
|
||||||
}
|
}
|
||||||
lastPrimitive = _primitive;
|
lastPrimitive = primitive;
|
||||||
ADDSTAT(stats.thisFrame.numPrims, _numVertices);
|
ADDSTAT(stats.thisFrame.numPrims, numVertices);
|
||||||
INCSTAT(stats.thisFrame.numPrimitiveJoins);
|
INCSTAT(stats.thisFrame.numPrimitiveJoins);
|
||||||
AddIndices(_primitive, _numVertices);
|
AddIndices(primitive, numVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void DumpBadShaders()
|
inline void DumpBadShaders()
|
||||||
|
@ -179,7 +178,7 @@ inline void DumpBadShaders()
|
||||||
|
|
||||||
inline void Draw(int stride)
|
inline void Draw(int stride)
|
||||||
{
|
{
|
||||||
if(IndexGenerator::GetNumTriangles() > 0)
|
if (IndexGenerator::GetNumTriangles() > 0)
|
||||||
{
|
{
|
||||||
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
|
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
|
||||||
D3DPT_TRIANGLELIST,
|
D3DPT_TRIANGLELIST,
|
||||||
|
@ -193,7 +192,7 @@ inline void Draw(int stride)
|
||||||
}
|
}
|
||||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||||
}
|
}
|
||||||
if(IndexGenerator::GetNumLines() > 0)
|
if (IndexGenerator::GetNumLines() > 0)
|
||||||
{
|
{
|
||||||
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
|
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
|
||||||
D3DPT_LINELIST,
|
D3DPT_LINELIST,
|
||||||
|
@ -207,7 +206,7 @@ inline void Draw(int stride)
|
||||||
}
|
}
|
||||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||||
}
|
}
|
||||||
if(IndexGenerator::GetNumPoints() > 0)
|
if (IndexGenerator::GetNumPoints() > 0)
|
||||||
{
|
{
|
||||||
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
|
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
|
||||||
D3DPT_POINTLIST,
|
D3DPT_POINTLIST,
|
||||||
|
@ -226,28 +225,26 @@ inline void Draw(int stride)
|
||||||
void Flush()
|
void Flush()
|
||||||
{
|
{
|
||||||
if (LocalVBuffer == s_pCurBufferPointer) return;
|
if (LocalVBuffer == s_pCurBufferPointer) return;
|
||||||
if(Flushed) return;
|
if (Flushed) return;
|
||||||
Flushed=true;
|
Flushed=true;
|
||||||
VideoFifo_CheckEFBAccess();
|
VideoFifo_CheckEFBAccess();
|
||||||
|
|
||||||
DVSTARTPROFILE();
|
DVSTARTPROFILE();
|
||||||
|
|
||||||
u32 usedtextures = 0;
|
u32 usedtextures = 0;
|
||||||
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i) {
|
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i)
|
||||||
if (bpmem.tevorders[i/2].getEnable(i & 1))
|
if (bpmem.tevorders[i / 2].getEnable(i & 1))
|
||||||
usedtextures |= 1 << bpmem.tevorders[i/2].getTexMap(i & 1);
|
usedtextures |= 1 << bpmem.tevorders[i/2].getTexMap(i & 1);
|
||||||
}
|
|
||||||
|
|
||||||
if (bpmem.genMode.numindstages > 0) {
|
if (bpmem.genMode.numindstages > 0)
|
||||||
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i) {
|
for (unsigned int i = 0; i < bpmem.genMode.numtevstages + 1; ++i)
|
||||||
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) {
|
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
|
||||||
usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt);
|
usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++)
|
for (unsigned int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
if (usedtextures & (1 << i))
|
||||||
{
|
{
|
||||||
if (usedtextures & (1 << i)) {
|
|
||||||
Renderer::SetSamplerState(i & 3, i >> 2);
|
Renderer::SetSamplerState(i & 3, i >> 2);
|
||||||
FourTexUnits &tex = bpmem.tex[i >> 2];
|
FourTexUnits &tex = bpmem.tex[i >> 2];
|
||||||
TextureCache::TCacheEntry* tentry = TextureCache::Load(i,
|
TextureCache::TCacheEntry* tentry = TextureCache::Load(i,
|
||||||
|
@ -258,16 +255,14 @@ void Flush()
|
||||||
(tex.texMode0[i&3].min_filter & 3) && (tex.texMode0[i&3].min_filter != 8) && g_ActiveConfig.bUseNativeMips,
|
(tex.texMode0[i&3].min_filter & 3) && (tex.texMode0[i&3].min_filter != 8) && g_ActiveConfig.bUseNativeMips,
|
||||||
(tex.texMode1[i&3].max_lod >> 4));
|
(tex.texMode1[i&3].max_lod >> 4));
|
||||||
|
|
||||||
if (tentry) {
|
if (tentry)
|
||||||
|
{
|
||||||
|
// 0s are probably for no manual wrapping needed.
|
||||||
PixelShaderManager::SetTexDims(i, tentry->w, tentry->h, 0, 0);
|
PixelShaderManager::SetTexDims(i, tentry->w, tentry->h, 0, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to load texture\n");});
|
|
||||||
ERROR_LOG(VIDEO, "error loading texture");
|
ERROR_LOG(VIDEO, "error loading texture");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set global constants
|
// set global constants
|
||||||
|
@ -311,7 +306,5 @@ void Flush()
|
||||||
|
|
||||||
shader_fail:
|
shader_fail:
|
||||||
ResetBuffer();
|
ResetBuffer();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -84,16 +84,19 @@ void SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const
|
||||||
D3D::dev->SetVertexShaderConstantF(const_number, f, count);
|
D3D::dev->SetVertexShaderConstantF(const_number, f, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this class will load the precompiled shaders into our cache
|
||||||
class VertexShaderCacheInserter : public LinearDiskCacheReader {
|
class VertexShaderCacheInserter : public LinearDiskCacheReader {
|
||||||
public:
|
public:
|
||||||
void Read(const u8 *key, int key_size, const u8 *value, int value_size)
|
void Read(const u8 *key, int key_size, const u8 *value, int value_size)
|
||||||
{
|
{
|
||||||
VERTEXSHADERUID uid;
|
VERTEXSHADERUID uid;
|
||||||
if (key_size != sizeof(uid)) {
|
if (key_size != sizeof(uid))
|
||||||
|
{
|
||||||
ERROR_LOG(VIDEO, "Wrong key size in vertex shader cache");
|
ERROR_LOG(VIDEO, "Wrong key size in vertex shader cache");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(&uid, key, key_size);
|
memcpy(&uid, key, key_size);
|
||||||
|
|
||||||
VertexShaderCache::InsertByteCode(uid, value, value_size, false);
|
VertexShaderCache::InsertByteCode(uid, value, value_size, false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -179,13 +182,12 @@ void VertexShaderCache::Init()
|
||||||
char cache_filename[MAX_PATH];
|
char cache_filename[MAX_PATH];
|
||||||
sprintf(cache_filename, "%sdx9-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX), globals->unique_id);
|
sprintf(cache_filename, "%sdx9-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX), globals->unique_id);
|
||||||
VertexShaderCacheInserter inserter;
|
VertexShaderCacheInserter inserter;
|
||||||
int read_items = g_vs_disk_cache.OpenAndRead(cache_filename, &inserter);
|
g_vs_disk_cache.OpenAndRead(cache_filename, &inserter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexShaderCache::Clear()
|
void VertexShaderCache::Clear()
|
||||||
{
|
{
|
||||||
VSCache::iterator iter = vshaders.begin();
|
for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter)
|
||||||
for (; iter != vshaders.end(); ++iter)
|
|
||||||
iter->second.Destroy();
|
iter->second.Destroy();
|
||||||
vshaders.clear();
|
vshaders.clear();
|
||||||
|
|
||||||
|
@ -217,16 +219,11 @@ bool VertexShaderCache::SetShader(u32 components)
|
||||||
VERTEXSHADERUID uid;
|
VERTEXSHADERUID uid;
|
||||||
GetVertexShaderId(&uid, components);
|
GetVertexShaderId(&uid, components);
|
||||||
if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount)
|
if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount)
|
||||||
{
|
return (vshaders[uid].shader != NULL);
|
||||||
if (vshaders[uid].shader)
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
|
memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
|
||||||
|
|
||||||
VSCache::iterator iter;
|
VSCache::iterator iter = vshaders.find(uid);
|
||||||
iter = vshaders.find(uid);
|
|
||||||
if (iter != vshaders.end())
|
if (iter != vshaders.end())
|
||||||
{
|
{
|
||||||
iter->second.frameCount = frameCount;
|
iter->second.frameCount = frameCount;
|
||||||
|
|
|
@ -148,18 +148,16 @@ void UpdateFPSDisplay(const char *text)
|
||||||
SetWindowText(EmuWindow::GetWnd(), temp);
|
SetWindowText(EmuWindow::GetWnd(), temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetDllInfo (PLUGIN_INFO* _PluginInfo)
|
void GetDllInfo(PLUGIN_INFO* _PluginInfo)
|
||||||
{
|
{
|
||||||
_PluginInfo->Version = 0x0100;
|
_PluginInfo->Version = 0x0100;
|
||||||
_PluginInfo->Type = PLUGIN_TYPE_VIDEO;
|
_PluginInfo->Type = PLUGIN_TYPE_VIDEO;
|
||||||
#ifdef DEBUGFAST
|
#ifdef DEBUGFAST
|
||||||
sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D9 (DebugFast)");
|
sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D9 (DebugFast)");
|
||||||
#else
|
#elif defined _DEBUG
|
||||||
#ifndef _DEBUG
|
|
||||||
sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D9");
|
|
||||||
#else
|
|
||||||
sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D9 (Debug)");
|
sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D9 (Debug)");
|
||||||
#endif
|
#else
|
||||||
|
sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D9");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,7 +195,8 @@ void Initialize(void *init)
|
||||||
{
|
{
|
||||||
frameCount = 0;
|
frameCount = 0;
|
||||||
SVideoInitialize *_pVideoInitialize = (SVideoInitialize*)init;
|
SVideoInitialize *_pVideoInitialize = (SVideoInitialize*)init;
|
||||||
g_VideoInitialize = *_pVideoInitialize;
|
// Create a shortcut to _pVideoInitialize that can also update it
|
||||||
|
g_VideoInitialize = *(_pVideoInitialize);
|
||||||
InitXFBConvTables();
|
InitXFBConvTables();
|
||||||
|
|
||||||
g_Config.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "gfx_dx9.ini").c_str());
|
g_Config.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "gfx_dx9.ini").c_str());
|
||||||
|
@ -222,6 +221,8 @@ void Initialize(void *init)
|
||||||
|
|
||||||
_pVideoInitialize->pPeekMessages = g_VideoInitialize.pPeekMessages;
|
_pVideoInitialize->pPeekMessages = g_VideoInitialize.pPeekMessages;
|
||||||
_pVideoInitialize->pUpdateFPSDisplay = g_VideoInitialize.pUpdateFPSDisplay;
|
_pVideoInitialize->pUpdateFPSDisplay = g_VideoInitialize.pUpdateFPSDisplay;
|
||||||
|
|
||||||
|
// Now the window handle is written
|
||||||
_pVideoInitialize->pWindowHandle = g_VideoInitialize.pWindowHandle;
|
_pVideoInitialize->pWindowHandle = g_VideoInitialize.pWindowHandle;
|
||||||
|
|
||||||
OSD::AddMessage("Dolphin Direct3D9 Video Plugin.", 5000);
|
OSD::AddMessage("Dolphin Direct3D9 Video Plugin.", 5000);
|
||||||
|
@ -234,10 +235,13 @@ void Video_Prepare()
|
||||||
s_efbAccessRequested = FALSE;
|
s_efbAccessRequested = FALSE;
|
||||||
s_FifoShuttingDown = FALSE;
|
s_FifoShuttingDown = FALSE;
|
||||||
s_swapRequested = FALSE;
|
s_swapRequested = FALSE;
|
||||||
|
|
||||||
|
// internal interfaces
|
||||||
Renderer::Init();
|
Renderer::Init();
|
||||||
TextureCache::Init();
|
TextureCache::Init();
|
||||||
BPInit();
|
|
||||||
VertexManager::Init();
|
VertexManager::Init();
|
||||||
|
// VideoCommon
|
||||||
|
BPInit();
|
||||||
Fifo_Init();
|
Fifo_Init();
|
||||||
VertexLoaderManager::Init();
|
VertexLoaderManager::Init();
|
||||||
OpcodeDecoder_Init();
|
OpcodeDecoder_Init();
|
||||||
|
@ -246,36 +250,45 @@ void Video_Prepare()
|
||||||
CommandProcessor::Init();
|
CommandProcessor::Init();
|
||||||
PixelEngine::Init();
|
PixelEngine::Init();
|
||||||
DLCache::Init();
|
DLCache::Init();
|
||||||
// Tell the host the window is ready
|
|
||||||
|
// Notify the core that the video plugin is ready
|
||||||
g_VideoInitialize.pCoreMessage(WM_USER_CREATE);
|
g_VideoInitialize.pCoreMessage(WM_USER_CREATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown()
|
void Shutdown()
|
||||||
{
|
{
|
||||||
|
s_PluginInitialized = false;
|
||||||
|
|
||||||
s_efbAccessRequested = FALSE;
|
s_efbAccessRequested = FALSE;
|
||||||
s_FifoShuttingDown = FALSE;
|
s_FifoShuttingDown = FALSE;
|
||||||
s_swapRequested = FALSE;
|
s_swapRequested = FALSE;
|
||||||
|
|
||||||
|
// VideoCommon
|
||||||
DLCache::Shutdown();
|
DLCache::Shutdown();
|
||||||
Fifo_Shutdown();
|
Fifo_Shutdown();
|
||||||
CommandProcessor::Shutdown();
|
CommandProcessor::Shutdown();
|
||||||
VertexManager::Shutdown();
|
|
||||||
VertexLoaderManager::Shutdown();
|
|
||||||
VertexShaderManager::Shutdown();
|
|
||||||
PixelShaderManager::Shutdown();
|
PixelShaderManager::Shutdown();
|
||||||
TextureCache::Shutdown();
|
VertexShaderManager::Shutdown();
|
||||||
OpcodeDecoder_Shutdown();
|
OpcodeDecoder_Shutdown();
|
||||||
|
VertexLoaderManager::Shutdown();
|
||||||
|
|
||||||
|
// internal interfaces
|
||||||
|
PixelShaderCache::Shutdown();
|
||||||
|
VertexShaderCache::Shutdown();
|
||||||
|
VertexManager::Shutdown();
|
||||||
|
TextureCache::Shutdown();
|
||||||
Renderer::Shutdown();
|
Renderer::Shutdown();
|
||||||
D3D::Shutdown();
|
D3D::Shutdown();
|
||||||
EmuWindow::Close();
|
EmuWindow::Close();
|
||||||
s_PluginInitialized = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoState(unsigned char **ptr, int mode) {
|
void DoState(unsigned char **ptr, int mode)
|
||||||
|
{
|
||||||
// Clear texture cache because it might have written to RAM
|
// Clear texture cache because it might have written to RAM
|
||||||
CommandProcessor::FifoCriticalEnter();
|
CommandProcessor::FifoCriticalEnter();
|
||||||
TextureCache::Invalidate(false);
|
TextureCache::Invalidate(false);
|
||||||
CommandProcessor::FifoCriticalLeave();
|
CommandProcessor::FifoCriticalLeave();
|
||||||
// No need to clear shader caches.
|
// No need to clear shader caches
|
||||||
PointerWrap p(ptr, mode);
|
PointerWrap p(ptr, mode);
|
||||||
VideoCommon_DoState(p);
|
VideoCommon_DoState(p);
|
||||||
}
|
}
|
||||||
|
@ -285,6 +298,7 @@ void EmuStateChange(PLUGIN_EMUSTATE newState)
|
||||||
Fifo_RunLoop((newState == PLUGIN_EMUSTATE_PLAY) ? true : false);
|
Fifo_RunLoop((newState == PLUGIN_EMUSTATE_PLAY) ? true : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enter and exit the video loop
|
||||||
void Video_EnterLoop()
|
void Video_EnterLoop()
|
||||||
{
|
{
|
||||||
Fifo_EnterLoop(g_VideoInitialize);
|
Fifo_EnterLoop(g_VideoInitialize);
|
||||||
|
@ -293,11 +307,11 @@ void Video_EnterLoop()
|
||||||
void Video_ExitLoop()
|
void Video_ExitLoop()
|
||||||
{
|
{
|
||||||
Fifo_ExitLoop();
|
Fifo_ExitLoop();
|
||||||
|
|
||||||
s_FifoShuttingDown = TRUE;
|
s_FifoShuttingDown = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Video_SetRendering(bool bEnabled) {
|
void Video_SetRendering(bool bEnabled)
|
||||||
|
{
|
||||||
Fifo_SetRendering(bEnabled);
|
Fifo_SetRendering(bEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +329,7 @@ void VideoFifo_CheckSwapRequest()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
|
static inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
|
||||||
{
|
{
|
||||||
return !((aLower >= bUpper) || (bLower >= aUpper));
|
return !((aLower >= bUpper) || (bLower >= aUpper));
|
||||||
}
|
}
|
||||||
|
@ -360,30 +374,20 @@ void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run from the CPU thread (from VideoInterface.cpp)
|
||||||
void Video_EndField()
|
void Video_EndField()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Video_AddMessage(const char* pstr, u32 milliseconds)
|
void Video_AddMessage(const char* pstr, u32 milliseconds)
|
||||||
{
|
{
|
||||||
OSD::AddMessage(pstr,milliseconds);
|
OSD::AddMessage(pstr, milliseconds);
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT ScreenShot(const char *File)
|
|
||||||
{
|
|
||||||
Renderer::SetScreenshot(File);
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Screenshot
|
||||||
void Video_Screenshot(const char *_szFilename)
|
void Video_Screenshot(const char *_szFilename)
|
||||||
{
|
{
|
||||||
if (ScreenShot(_szFilename) != S_OK)
|
Renderer::SetScreenshot(_szFilename);
|
||||||
PanicAlert("Error while capturing screen");
|
|
||||||
else {
|
|
||||||
std::string message = "Saved ";
|
|
||||||
message += _szFilename;
|
|
||||||
OSD::AddMessage(message.c_str(), 2000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
|
@ -406,7 +410,7 @@ void VideoFifo_CheckEFBAccess()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y,u32 InputData)
|
u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData)
|
||||||
{
|
{
|
||||||
if (s_PluginInitialized)
|
if (s_PluginInitialized)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,4 +23,3 @@
|
||||||
|
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
|
|
@ -766,11 +766,11 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\TextureMngr.cpp"
|
RelativePath=".\Src\TextureCache.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\TextureMngr.h"
|
RelativePath=".\Src\TextureCache.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "VertexManager.h"
|
#include "VertexManager.h"
|
||||||
#include "Render.h"
|
#include "Render.h"
|
||||||
#include "TextureMngr.h"
|
#include "TextureCache.h"
|
||||||
#include "TextureConverter.h"
|
#include "TextureConverter.h"
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
#include "XFB.h"
|
#include "XFB.h"
|
||||||
|
@ -39,6 +39,7 @@ void FlushPipeline()
|
||||||
{
|
{
|
||||||
VertexManager::Flush();
|
VertexManager::Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetGenerationMode(const BPCmd &bp)
|
void SetGenerationMode(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
Renderer::SetGenerationMode();
|
Renderer::SetGenerationMode();
|
||||||
|
@ -46,18 +47,19 @@ void SetGenerationMode(const BPCmd &bp)
|
||||||
|
|
||||||
void SetScissor(const BPCmd &bp)
|
void SetScissor(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
if (!Renderer::SetScissorRect())
|
Renderer::SetScissorRect();
|
||||||
if (bp.address == BPMEM_SCISSORBR)
|
|
||||||
ERROR_LOG(VIDEO, "bad scissor!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetLineWidth(const BPCmd &bp)
|
void SetLineWidth(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
Renderer::SetLineWidth();
|
Renderer::SetLineWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetDepthMode(const BPCmd &bp)
|
void SetDepthMode(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
Renderer::SetDepthMode();
|
Renderer::SetDepthMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetBlendMode(const BPCmd &bp)
|
void SetBlendMode(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
Renderer::SetBlendMode(false);
|
Renderer::SetBlendMode(false);
|
||||||
|
@ -81,12 +83,15 @@ void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const
|
||||||
// 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 PIXELFMT_Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format)
|
||||||
if (!g_ActiveConfig.bEFBCopyDisable)
|
if (!g_ActiveConfig.bEFBCopyDisable)
|
||||||
{
|
{
|
||||||
TextureMngr::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
|
TextureCache::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc)
|
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc)
|
||||||
{
|
{
|
||||||
|
// it seems that the GC is able to alpha blend on color-fill
|
||||||
|
// we cant do that so if alpha is != 255 we skip it
|
||||||
|
|
||||||
bool colorEnable = bpmem.blendmode.colorupdate;
|
bool colorEnable = bpmem.blendmode.colorupdate;
|
||||||
bool alphaEnable = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 && bpmem.blendmode.alphaupdate);
|
bool alphaEnable = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 && bpmem.blendmode.alphaupdate);
|
||||||
bool zEnable = bpmem.zmode.updateenable;
|
bool zEnable = bpmem.zmode.updateenable;
|
||||||
|
|
|
@ -186,22 +186,6 @@ void FramebufferManager::Shutdown()
|
||||||
m_virtualXFBList.clear();
|
m_virtualXFBList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferManager::CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
|
||||||
{
|
|
||||||
if (g_ActiveConfig.bUseRealXFB)
|
|
||||||
copyToRealXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
|
|
||||||
else
|
|
||||||
copyToVirtualXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
|
|
||||||
}
|
|
||||||
|
|
||||||
const XFBSource** FramebufferManager::GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
|
|
||||||
{
|
|
||||||
if (g_ActiveConfig.bUseRealXFB)
|
|
||||||
return getRealXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
|
||||||
else
|
|
||||||
return getVirtualXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLuint FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc) const
|
GLuint FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc) const
|
||||||
{
|
{
|
||||||
if (m_msaaSamples <= 1)
|
if (m_msaaSamples <= 1)
|
||||||
|
@ -262,6 +246,22 @@ GLuint FramebufferManager::GetEFBDepthTexture(const EFBRectangle& sourceRc) cons
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FramebufferManager::CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
||||||
|
{
|
||||||
|
if (g_ActiveConfig.bUseRealXFB)
|
||||||
|
copyToRealXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
|
||||||
|
else
|
||||||
|
copyToVirtualXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
|
||||||
|
}
|
||||||
|
|
||||||
|
const XFBSource** FramebufferManager::GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
|
||||||
|
{
|
||||||
|
if (g_ActiveConfig.bUseRealXFB)
|
||||||
|
return getRealXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
||||||
|
else
|
||||||
|
return getVirtualXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
||||||
|
}
|
||||||
|
|
||||||
TargetRectangle FramebufferManager::ConvertEFBRectangle(const EFBRectangle& rc) const
|
TargetRectangle FramebufferManager::ConvertEFBRectangle(const EFBRectangle& rc) const
|
||||||
{
|
{
|
||||||
TargetRectangle result;
|
TargetRectangle result;
|
||||||
|
@ -274,8 +274,7 @@ TargetRectangle FramebufferManager::ConvertEFBRectangle(const EFBRectangle& rc)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
FramebufferManager::VirtualXFBListType::iterator
|
FramebufferManager::VirtualXFBListType::iterator FramebufferManager::findVirtualXFB(u32 xfbAddr, u32 width, u32 height)
|
||||||
FramebufferManager::findVirtualXFB(u32 xfbAddr, u32 width, u32 height)
|
|
||||||
{
|
{
|
||||||
u32 srcLower = xfbAddr;
|
u32 srcLower = xfbAddr;
|
||||||
u32 srcUpper = xfbAddr + 2 * width * height;
|
u32 srcUpper = xfbAddr + 2 * width * height;
|
||||||
|
@ -311,7 +310,7 @@ void FramebufferManager::replaceVirtualXFB()
|
||||||
|
|
||||||
if (dstLower >= srcLower && dstUpper <= srcUpper)
|
if (dstLower >= srcLower && dstUpper <= srcUpper)
|
||||||
{
|
{
|
||||||
// invalidate the data
|
// Invalidate the data
|
||||||
it->xfbAddr = 0;
|
it->xfbAddr = 0;
|
||||||
it->xfbHeight = 0;
|
it->xfbHeight = 0;
|
||||||
it->xfbWidth = 0;
|
it->xfbWidth = 0;
|
||||||
|
@ -338,14 +337,14 @@ void FramebufferManager::replaceVirtualXFB()
|
||||||
|
|
||||||
void FramebufferManager::copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
void FramebufferManager::copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
||||||
{
|
{
|
||||||
u8* pXFB = Memory_GetPtr(xfbAddr);
|
u8* xfb_in_ram = Memory_GetPtr(xfbAddr);
|
||||||
if (!pXFB)
|
if (!xfb_in_ram)
|
||||||
{
|
{
|
||||||
WARN_LOG(VIDEO, "Tried to copy to invalid XFB address");
|
WARN_LOG(VIDEO, "Tried to copy to invalid XFB address");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
XFB_Write(pXFB, sourceRc, fbWidth, fbHeight);
|
XFB_Write(xfb_in_ram, sourceRc, fbWidth, fbHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
||||||
|
@ -356,7 +355,7 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
|
||||||
|
|
||||||
if (it == m_virtualXFBList.end() && (int)m_virtualXFBList.size() >= MAX_VIRTUAL_XFB)
|
if (it == m_virtualXFBList.end() && (int)m_virtualXFBList.size() >= MAX_VIRTUAL_XFB)
|
||||||
{
|
{
|
||||||
// replace the last virtual XFB
|
// Replace the last virtual XFB
|
||||||
--it;
|
--it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,7 +431,7 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
|
||||||
m_virtualXFBList.push_front(newVirt);
|
m_virtualXFBList.push_front(newVirt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy EFB to XFB texture
|
// Copy EFB data to XFB and restore render target again
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (m_msaaSamples <= 1)
|
if (m_msaaSamples <= 1)
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include "ConfigDlg.h"
|
#include "ConfigDlg.h"
|
||||||
#include "../Globals.h"
|
#include "../Globals.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "../TextureMngr.h"
|
#include "../TextureCache.h"
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
#include "../PostProcessing.h"
|
#include "../PostProcessing.h"
|
||||||
#include "Render.h"
|
#include "Render.h"
|
||||||
|
@ -668,11 +668,11 @@ void GFXConfigDialogOGL::AdvancedSettingsChanged(wxCommandEvent& event)
|
||||||
case ID_TEXFMTOVERLAY:
|
case ID_TEXFMTOVERLAY:
|
||||||
g_Config.bTexFmtOverlayEnable = m_TexFmtOverlay->IsChecked();
|
g_Config.bTexFmtOverlayEnable = m_TexFmtOverlay->IsChecked();
|
||||||
m_TexFmtCenter->Enable(m_TexFmtOverlay->IsChecked());
|
m_TexFmtCenter->Enable(m_TexFmtOverlay->IsChecked());
|
||||||
TextureMngr::Invalidate(false);
|
TextureCache::Invalidate(false);
|
||||||
break;
|
break;
|
||||||
case ID_TEXFMTCENTER:
|
case ID_TEXFMTCENTER:
|
||||||
g_Config.bTexFmtOverlayCenter = m_TexFmtCenter->IsChecked();
|
g_Config.bTexFmtOverlayCenter = m_TexFmtCenter->IsChecked();
|
||||||
TextureMngr::Invalidate(false);
|
TextureCache::Invalidate(false);
|
||||||
break;
|
break;
|
||||||
case ID_SHOWEFBCOPYREGIONS:
|
case ID_SHOWEFBCOPYREGIONS:
|
||||||
g_Config.bShowEFBCopyRegions = m_ShowEFBCopyRegions->IsChecked();
|
g_Config.bShowEFBCopyRegions = m_ShowEFBCopyRegions->IsChecked();
|
||||||
|
|
|
@ -43,6 +43,15 @@ bool PixelShaderCache::ShaderEnabled;
|
||||||
|
|
||||||
static FRAGMENTSHADER* pShaderLast = NULL;
|
static FRAGMENTSHADER* pShaderLast = NULL;
|
||||||
|
|
||||||
|
GLuint PixelShaderCache::GetDepthMatrixProgram()
|
||||||
|
{
|
||||||
|
return s_DepthMatrixProgram;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint PixelShaderCache::GetColorMatrixProgram()
|
||||||
|
{
|
||||||
|
return s_ColorMatrixProgram;
|
||||||
|
}
|
||||||
|
|
||||||
void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
|
void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
|
||||||
{
|
{
|
||||||
|
@ -174,18 +183,7 @@ void PixelShaderCache::Shutdown()
|
||||||
pshaders.clear();
|
pshaders.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint PixelShaderCache::GetColorMatrixProgram()
|
FRAGMENTSHADER* PixelShaderCache::SetShader(bool dstAlphaEnable,u32 components)
|
||||||
{
|
|
||||||
return s_ColorMatrixProgram;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLuint PixelShaderCache::GetDepthMatrixProgram()
|
|
||||||
{
|
|
||||||
return s_DepthMatrixProgram;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
FRAGMENTSHADER* PixelShaderCache::GetShader(bool dstAlphaEnable,u32 components)
|
|
||||||
{
|
{
|
||||||
DVSTARTPROFILE();
|
DVSTARTPROFILE();
|
||||||
PIXELSHADERUID uid;
|
PIXELSHADERUID uid;
|
||||||
|
|
|
@ -71,7 +71,7 @@ public:
|
||||||
static void Init();
|
static void Init();
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
|
|
||||||
static FRAGMENTSHADER* GetShader(bool dstAlphaEnable,u32 components);
|
static FRAGMENTSHADER* SetShader(bool dstAlphaEnable,u32 components);
|
||||||
static bool CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram);
|
static bool CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram);
|
||||||
|
|
||||||
static GLuint GetColorMatrixProgram();
|
static GLuint GetColorMatrixProgram();
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,7 +10,7 @@ files = [
|
||||||
'BPFunctions.cpp',
|
'BPFunctions.cpp',
|
||||||
'RasterFont.cpp',
|
'RasterFont.cpp',
|
||||||
'Render.cpp',
|
'Render.cpp',
|
||||||
'TextureMngr.cpp',
|
'TextureCache.cpp',
|
||||||
'NativeVertexFormat.cpp',
|
'NativeVertexFormat.cpp',
|
||||||
'PixelShaderCache.cpp',
|
'PixelShaderCache.cpp',
|
||||||
'VertexShaderCache.cpp',
|
'VertexShaderCache.cpp',
|
||||||
|
|
|
@ -18,9 +18,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "Globals.h"
|
|
||||||
#include "CommonPaths.h"
|
|
||||||
#include "StringUtil.h"
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define _interlockedbittestandset workaround_ms_header_bug_platform_sdk6_set
|
#define _interlockedbittestandset workaround_ms_header_bug_platform_sdk6_set
|
||||||
|
@ -34,28 +32,29 @@
|
||||||
#undef _interlockedbittestandreset64
|
#undef _interlockedbittestandreset64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "VideoConfig.h"
|
|
||||||
#include "Hash.h"
|
|
||||||
#include "Statistics.h"
|
|
||||||
#include "Profiler.h"
|
|
||||||
#include "ImageWrite.h"
|
|
||||||
|
|
||||||
#include "Render.h"
|
|
||||||
|
|
||||||
#include "MemoryUtil.h"
|
|
||||||
#include "BPStructs.h"
|
#include "BPStructs.h"
|
||||||
#include "TextureDecoder.h"
|
#include "CommonPaths.h"
|
||||||
#include "TextureMngr.h"
|
#include "FileUtil.h"
|
||||||
|
#include "FramebufferManager.h"
|
||||||
|
#include "Globals.h"
|
||||||
|
#include "Hash.h"
|
||||||
|
#include "HiresTextures.h"
|
||||||
|
#include "ImageWrite.h"
|
||||||
|
#include "MemoryUtil.h"
|
||||||
#include "PixelShaderCache.h"
|
#include "PixelShaderCache.h"
|
||||||
#include "PixelShaderManager.h"
|
#include "PixelShaderManager.h"
|
||||||
#include "VertexShaderManager.h"
|
#include "Profiler.h"
|
||||||
#include "FramebufferManager.h"
|
#include "Render.h"
|
||||||
#include "FileUtil.h"
|
#include "Statistics.h"
|
||||||
#include "HiresTextures.h"
|
#include "StringUtil.h"
|
||||||
|
#include "TextureCache.h"
|
||||||
#include "TextureConverter.h"
|
#include "TextureConverter.h"
|
||||||
|
#include "TextureDecoder.h"
|
||||||
|
#include "VertexShaderManager.h"
|
||||||
|
#include "VideoConfig.h"
|
||||||
|
|
||||||
u8 *TextureMngr::temp = NULL;
|
u8 *TextureCache::temp = NULL;
|
||||||
TextureMngr::TexCache TextureMngr::textures;
|
TextureCache::TexCache TextureCache::textures;
|
||||||
|
|
||||||
extern int frameCount;
|
extern int frameCount;
|
||||||
static u32 s_TempFramebuffer = 0;
|
static u32 s_TempFramebuffer = 0;
|
||||||
|
@ -96,16 +95,7 @@ bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int he
|
||||||
return SaveTGA(filename, width, height, &data[0]);
|
return SaveTGA(filename, width, height, &data[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int TextureMngr::TCacheEntry::IntersectsMemoryRange(u32 range_address, u32 range_size)
|
void TextureCache::TCacheEntry::SetTextureParameters(TexMode0 &newmode,TexMode1 &newmode1)
|
||||||
{
|
|
||||||
if (addr + size_in_bytes < range_address)
|
|
||||||
return -1;
|
|
||||||
if (addr >= range_address + range_size)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextureMngr::TCacheEntry::SetTextureParameters(TexMode0 &newmode,TexMode1 &newmode1)
|
|
||||||
{
|
{
|
||||||
mode = newmode;
|
mode = newmode;
|
||||||
mode1 = newmode1;
|
mode1 = newmode1;
|
||||||
|
@ -134,27 +124,27 @@ void TextureMngr::TCacheEntry::SetTextureParameters(TexMode0 &newmode,TexMode1 &
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)(1 << g_ActiveConfig.iMaxAnisotropy));
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)(1 << g_ActiveConfig.iMaxAnisotropy));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureMngr::TCacheEntry::Destroy(bool shutdown)
|
void TextureCache::TCacheEntry::Destroy(bool shutdown)
|
||||||
{
|
{
|
||||||
if (!texture)
|
if (texture)
|
||||||
return;
|
|
||||||
glDeleteTextures(1, &texture);
|
glDeleteTextures(1, &texture);
|
||||||
if (!isRenderTarget && !shutdown && !g_ActiveConfig.bSafeTextureCache) {
|
texture = 0;
|
||||||
|
if (!isRenderTarget && !shutdown && !g_ActiveConfig.bSafeTextureCache)
|
||||||
|
{
|
||||||
u32 *ptr = (u32*)g_VideoInitialize.pGetMemoryPointer(addr);
|
u32 *ptr = (u32*)g_VideoInitialize.pGetMemoryPointer(addr);
|
||||||
if (ptr && *ptr == hash)
|
if (ptr && *ptr == hash)
|
||||||
*ptr = oldpixel;
|
*ptr = oldpixel;
|
||||||
}
|
}
|
||||||
texture = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureMngr::Init()
|
void TextureCache::Init()
|
||||||
{
|
{
|
||||||
temp = (u8*)AllocateMemoryPages(TEMP_SIZE);
|
temp = (u8*)AllocateMemoryPages(TEMP_SIZE);
|
||||||
TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable, g_ActiveConfig.bTexFmtOverlayCenter);
|
TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable, g_ActiveConfig.bTexFmtOverlayCenter);
|
||||||
HiresTextures::Init(globals->unique_id);
|
HiresTextures::Init(globals->unique_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureMngr::Invalidate(bool shutdown)
|
void TextureCache::Invalidate(bool shutdown)
|
||||||
{
|
{
|
||||||
for (TexCache::iterator iter = textures.begin(); iter != textures.end(); ++iter)
|
for (TexCache::iterator iter = textures.begin(); iter != textures.end(); ++iter)
|
||||||
iter->second.Destroy(shutdown);
|
iter->second.Destroy(shutdown);
|
||||||
|
@ -162,11 +152,12 @@ void TextureMngr::Invalidate(bool shutdown)
|
||||||
HiresTextures::Shutdown();
|
HiresTextures::Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureMngr::Shutdown()
|
void TextureCache::Shutdown()
|
||||||
{
|
{
|
||||||
Invalidate(true);
|
Invalidate(true);
|
||||||
|
|
||||||
if (s_TempFramebuffer) {
|
if (s_TempFramebuffer)
|
||||||
|
{
|
||||||
glDeleteFramebuffersEXT(1, (GLuint *)&s_TempFramebuffer);
|
glDeleteFramebuffersEXT(1, (GLuint *)&s_TempFramebuffer);
|
||||||
s_TempFramebuffer = 0;
|
s_TempFramebuffer = 0;
|
||||||
}
|
}
|
||||||
|
@ -175,7 +166,7 @@ void TextureMngr::Shutdown()
|
||||||
temp = NULL;
|
temp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureMngr::ProgressiveCleanup()
|
void TextureCache::Cleanup()
|
||||||
{
|
{
|
||||||
TexCache::iterator iter = textures.begin();
|
TexCache::iterator iter = textures.begin();
|
||||||
while (iter != textures.end())
|
while (iter != textures.end())
|
||||||
|
@ -186,11 +177,13 @@ void TextureMngr::ProgressiveCleanup()
|
||||||
textures.erase(iter++);
|
textures.erase(iter++);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureMngr::InvalidateRange(u32 start_address, u32 size)
|
void TextureCache::InvalidateRange(u32 start_address, u32 size)
|
||||||
{
|
{
|
||||||
TexCache::iterator iter = textures.begin();
|
TexCache::iterator iter = textures.begin();
|
||||||
while (iter != textures.end())
|
while (iter != textures.end())
|
||||||
|
@ -208,7 +201,7 @@ void TextureMngr::InvalidateRange(u32 start_address, u32 size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureMngr::MakeRangeDynamic(u32 start_address, u32 size)
|
void TextureCache::MakeRangeDynamic(u32 start_address, u32 size)
|
||||||
{
|
{
|
||||||
TexCache::iterator iter = textures.begin();
|
TexCache::iterator iter = textures.begin();
|
||||||
while (iter != textures.end())
|
while (iter != textures.end())
|
||||||
|
@ -222,8 +215,16 @@ void TextureMngr::MakeRangeDynamic(u32 start_address, u32 size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TextureCache::TCacheEntry::IntersectsMemoryRange(u32 range_address, u32 range_size)
|
||||||
|
{
|
||||||
|
if (addr + size_in_bytes < range_address)
|
||||||
|
return -1;
|
||||||
|
if (addr >= range_address + range_size)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width, int height, u32 tex_format, int tlutaddr, int tlutfmt)
|
TextureCache::TCacheEntry* TextureCache::Load(int texstage, u32 address, int width, int height, u32 tex_format, int tlutaddr, int tlutfmt)
|
||||||
{
|
{
|
||||||
// notes (about "UNsafe texture cache"):
|
// notes (about "UNsafe texture cache"):
|
||||||
// Have to be removed soon.
|
// Have to be removed soon.
|
||||||
|
@ -259,8 +260,8 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
bool UseNativeMips = (tm0.min_filter & 3) && (tm0.min_filter != 8) && g_ActiveConfig.bUseNativeMips;
|
bool UseNativeMips = (tm0.min_filter & 3) && (tm0.min_filter != 8) && g_ActiveConfig.bUseNativeMips;
|
||||||
|
|
||||||
u8 *ptr = g_VideoInitialize.pGetMemoryPointer(address);
|
u8 *ptr = g_VideoInitialize.pGetMemoryPointer(address);
|
||||||
int bsw = TexDecoder_GetBlockWidthInTexels(tex_format) - 1;
|
int bsw = TexDecoder_GetBlockWidthInTexels(tex_format) - 1; // TexelSizeInNibbles(format)*width*height/16;
|
||||||
int bsh = TexDecoder_GetBlockHeightInTexels(tex_format) - 1;
|
int bsh = TexDecoder_GetBlockHeightInTexels(tex_format) - 1; // TexelSizeInNibbles(format)*width*height/16;
|
||||||
int bsdepth = TexDecoder_GetTexelSizeInNibbles(tex_format);
|
int bsdepth = TexDecoder_GetTexelSizeInNibbles(tex_format);
|
||||||
int expandedWidth = (width + bsw) & (~bsw);
|
int expandedWidth = (width + bsw) & (~bsw);
|
||||||
int expandedHeight = (height + bsh) & (~bsh);
|
int expandedHeight = (height + bsh) & (~bsh);
|
||||||
|
@ -272,6 +273,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
bool TextureisDynamic = false;
|
bool TextureisDynamic = false;
|
||||||
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
|
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
|
||||||
FullFormat = (tex_format | (tlutfmt << 16));
|
FullFormat = (tex_format | (tlutfmt << 16));
|
||||||
|
|
||||||
if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures)
|
if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures)
|
||||||
{
|
{
|
||||||
texHash = GetHash64(ptr,TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
texHash = GetHash64(ptr,TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||||
|
@ -334,7 +336,6 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((entry.isRenderTarget || entry.isDynamic) && hash_value == entry.hash && address == entry.addr)
|
if (((entry.isRenderTarget || entry.isDynamic) && hash_value == entry.hash && address == entry.addr)
|
||||||
|| ((address == entry.addr) && (hash_value == entry.hash) && ((int) FullFormat == entry.fmt) && entry.MipLevels >= maxlevel))
|
|| ((address == entry.addr) && (hash_value == entry.hash) && ((int) FullFormat == entry.fmt) && entry.MipLevels >= maxlevel))
|
||||||
{
|
{
|
||||||
|
@ -368,29 +369,29 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Make an entry in the table
|
// Make an entry in the table
|
||||||
TCacheEntry& entry = textures[texID];
|
TCacheEntry& entry = textures[texID];
|
||||||
entry.isDynamic = TextureisDynamic;
|
entry.isDynamic = TextureisDynamic;
|
||||||
entry.isRenderTarget = false;
|
entry.isRenderTarget = false;
|
||||||
PC_TexFormat dfmt = PC_TEX_FMT_NONE;
|
PC_TexFormat pcfmt = PC_TEX_FMT_NONE;
|
||||||
|
|
||||||
if (g_ActiveConfig.bHiresTextures)
|
if (g_ActiveConfig.bHiresTextures)
|
||||||
{
|
{
|
||||||
//Load Custom textures
|
// Load Custom textures
|
||||||
char texPathTemp[MAX_PATH];
|
char texPathTemp[MAX_PATH];
|
||||||
|
|
||||||
sprintf(texPathTemp, "%s_%08x_%i", globals->unique_id, (unsigned int) texHash, tex_format);
|
sprintf(texPathTemp, "%s_%08x_%i", globals->unique_id, (unsigned int) texHash, tex_format);
|
||||||
dfmt = HiresTextures::GetHiresTex(texPathTemp, &width, &height, tex_format, temp);
|
pcfmt = HiresTextures::GetHiresTex(texPathTemp, &width, &height, tex_format, temp);
|
||||||
|
|
||||||
if (dfmt != PC_TEX_FMT_NONE)
|
if (pcfmt != PC_TEX_FMT_NONE)
|
||||||
{
|
{
|
||||||
expandedWidth = width;
|
expandedWidth = width;
|
||||||
expandedHeight = height;
|
expandedHeight = height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dfmt == PC_TEX_FMT_NONE)
|
if (pcfmt == PC_TEX_FMT_NONE)
|
||||||
dfmt = TexDecoder_Decode(temp, ptr, expandedWidth, expandedHeight, tex_format, tlutaddr, tlutfmt);
|
pcfmt = TexDecoder_Decode(temp, ptr, expandedWidth, expandedHeight, tex_format, tlutaddr, tlutfmt);
|
||||||
|
|
||||||
entry.oldpixel = ((u32 *)ptr)[0];
|
entry.oldpixel = ((u32 *)ptr)[0];
|
||||||
|
|
||||||
|
@ -413,7 +414,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
|
|
||||||
bool isPow2 = !((width & (width - 1)) || (height & (height - 1)));
|
bool isPow2 = !((width & (width - 1)) || (height & (height - 1)));
|
||||||
int TexLevels = (width > height)?width:height;
|
int TexLevels = (width > height)?width:height;
|
||||||
TexLevels = (isPow2 && UseNativeMips && (maxlevel > 0)) ? (int)(log((double)TexLevels)/log((double)2))+ 1 : (isPow2? 0 : 1);
|
TexLevels = (isPow2 && UseNativeMips && (maxlevel > 0)) ? (int)(log((double)TexLevels)/log((double)2)) + 1 : (isPow2? 0 : 1);
|
||||||
if(TexLevels > (maxlevel + 1) && maxlevel > 0)
|
if(TexLevels > (maxlevel + 1) && maxlevel > 0)
|
||||||
TexLevels = (maxlevel + 1);
|
TexLevels = (maxlevel + 1);
|
||||||
entry.MipLevels = maxlevel;
|
entry.MipLevels = maxlevel;
|
||||||
|
@ -423,13 +424,13 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
int gl_iformat = 0;
|
int gl_iformat = 0;
|
||||||
int gl_type = 0;
|
int gl_type = 0;
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
if (dfmt != PC_TEX_FMT_DXT1)
|
if (pcfmt != PC_TEX_FMT_DXT1)
|
||||||
{
|
{
|
||||||
switch (dfmt)
|
switch (pcfmt)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case PC_TEX_FMT_NONE:
|
case PC_TEX_FMT_NONE:
|
||||||
PanicAlert("Invalid PC texture format %i", dfmt);
|
PanicAlert("Invalid PC texture format %i", pcfmt);
|
||||||
case PC_TEX_FMT_BGRA32:
|
case PC_TEX_FMT_BGRA32:
|
||||||
gl_format = GL_BGRA;
|
gl_format = GL_BGRA;
|
||||||
gl_iformat = 4;
|
gl_iformat = 4;
|
||||||
|
@ -511,7 +512,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
if(TexLevels > 1 && dfmt != PC_TEX_FMT_NONE)
|
if(TexLevels > 1 && pcfmt != PC_TEX_FMT_NONE)
|
||||||
{
|
{
|
||||||
int level = 1;
|
int level = 1;
|
||||||
int mipWidth = width >> 1;
|
int mipWidth = width >> 1;
|
||||||
|
@ -524,7 +525,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
expandedWidth = (currentWidth + bsw) & (~bsw);
|
expandedWidth = (currentWidth + bsw) & (~bsw);
|
||||||
expandedHeight = (currentHeight + bsh) & (~bsh);
|
expandedHeight = (currentHeight + bsh) & (~bsh);
|
||||||
TexDecoder_Decode(temp, ptr, expandedWidth, expandedHeight, tex_format, tlutaddr, tlutfmt);
|
TexDecoder_Decode(temp, ptr, expandedWidth, expandedHeight, tex_format, tlutaddr, tlutfmt);
|
||||||
if (dfmt != PC_TEX_FMT_DXT1)
|
if (pcfmt != PC_TEX_FMT_DXT1)
|
||||||
{
|
{
|
||||||
if (expandedWidth != (int)currentWidth)
|
if (expandedWidth != (int)currentWidth)
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, expandedWidth);
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, expandedWidth);
|
||||||
|
@ -551,16 +552,17 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
entry.Scaledh = height;
|
entry.Scaledh = height;
|
||||||
entry.fmt = FullFormat;
|
entry.fmt = FullFormat;
|
||||||
entry.SetTextureParameters(tm0,tm1);
|
entry.SetTextureParameters(tm0,tm1);
|
||||||
if (g_ActiveConfig.bDumpTextures) // dump texture to file
|
if (g_ActiveConfig.bDumpTextures)
|
||||||
{
|
{
|
||||||
|
// dump texture to file
|
||||||
char szTemp[MAX_PATH];
|
char szTemp[MAX_PATH];
|
||||||
char szDir[MAX_PATH];
|
char szDir[MAX_PATH];
|
||||||
const char* uniqueId = globals->unique_id;
|
const char* uniqueId = globals->unique_id;
|
||||||
static bool bCheckedDumpDir = false;
|
static bool bCheckedDumpDir = false;
|
||||||
|
|
||||||
sprintf(szDir,"%s%s", File::GetUserPath(D_DUMPTEXTURES_IDX), uniqueId);
|
sprintf(szDir, "%s%s", File::GetUserPath(D_DUMPTEXTURES_IDX), uniqueId);
|
||||||
|
|
||||||
if(!bCheckedDumpDir)
|
if (!bCheckedDumpDir)
|
||||||
{
|
{
|
||||||
if (!File::Exists(szDir) || !File::IsDirectory(szDir))
|
if (!File::Exists(szDir) || !File::IsDirectory(szDir))
|
||||||
File::CreateDir(szDir);
|
File::CreateDir(szDir);
|
||||||
|
@ -578,8 +580,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||||
return &entry;
|
return &entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle &source_rect)
|
||||||
void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle &source_rect)
|
|
||||||
{
|
{
|
||||||
DVSTARTPROFILE();
|
DVSTARTPROFILE();
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
@ -836,7 +837,7 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
|
||||||
g_framebufferManager.SetFramebuffer(0);
|
g_framebufferManager.SetFramebuffer(0);
|
||||||
Renderer::RestoreAPIState();
|
Renderer::RestoreAPIState();
|
||||||
VertexShaderManager::SetViewportChanged();
|
VertexShaderManager::SetViewportChanged();
|
||||||
TextureMngr::DisableStage(0);
|
TextureCache::DisableStage(0);
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
|
@ -847,14 +848,14 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureMngr::DisableStage(int stage)
|
void TextureCache::DisableStage(int stage)
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE0 + stage);
|
glActiveTexture(GL_TEXTURE0 + stage);
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
glDisable(GL_TEXTURE_RECTANGLE_ARB);
|
glDisable(GL_TEXTURE_RECTANGLE_ARB);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureMngr::ClearRenderTargets()
|
void TextureCache::ClearRenderTargets()
|
||||||
{
|
{
|
||||||
for (TexCache::iterator iter = textures.begin(); iter != textures.end(); ++iter)
|
for (TexCache::iterator iter = textures.begin(); iter != textures.end(); ++iter)
|
||||||
iter->second.isRenderTarget = false;
|
iter->second.isRenderTarget = false;
|
|
@ -24,7 +24,7 @@
|
||||||
#include "GLUtil.h"
|
#include "GLUtil.h"
|
||||||
#include "BPStructs.h"
|
#include "BPStructs.h"
|
||||||
|
|
||||||
class TextureMngr
|
class TextureCache
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct TCacheEntry
|
struct TCacheEntry
|
||||||
|
@ -66,7 +66,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void Init();
|
static void Init();
|
||||||
static void ProgressiveCleanup();
|
static void Cleanup();
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
static void Invalidate(bool shutdown);
|
static void Invalidate(bool shutdown);
|
||||||
static void InvalidateRange(u32 start_address, u32 size);
|
static void InvalidateRange(u32 start_address, u32 size);
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#include "TextureConverter.h"
|
#include "TextureConverter.h"
|
||||||
#include "TextureConversionShader.h"
|
#include "TextureConversionShader.h"
|
||||||
#include "TextureMngr.h"
|
#include "TextureCache.h"
|
||||||
#include "PixelShaderCache.h"
|
#include "PixelShaderCache.h"
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
#include "FramebufferManager.h"
|
#include "FramebufferManager.h"
|
||||||
|
@ -128,7 +128,6 @@ FRAGMENTSHADER &GetOrCreateEncodingShader(u32 format)
|
||||||
ERROR_LOG(VIDEO, "Failed to create encoding fragment program");
|
ERROR_LOG(VIDEO, "Failed to create encoding fragment program");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return s_encodingPrograms[format];
|
return s_encodingPrograms[format];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +179,7 @@ void EncodeToRamUsingShader(FRAGMENTSHADER& shader, GLuint srcTexture, const Tar
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
for (int i = 1; i < 8; ++i)
|
for (int i = 1; i < 8; ++i)
|
||||||
TextureMngr::DisableStage(i);
|
TextureCache::DisableStage(i);
|
||||||
|
|
||||||
// set source texture
|
// set source texture
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
@ -230,7 +229,6 @@ void EncodeToRamUsingShader(FRAGMENTSHADER& shader, GLuint srcTexture, const Tar
|
||||||
for (int i = 0; i < readLoops; i++)
|
for (int i = 0; i < readLoops; i++)
|
||||||
{
|
{
|
||||||
glReadPixels(0, readStart, (GLsizei)dstWidth, (GLsizei)readHeight, GL_BGRA, GL_UNSIGNED_BYTE, destAddr);
|
glReadPixels(0, readStart, (GLsizei)dstWidth, (GLsizei)readHeight, GL_BGRA, GL_UNSIGNED_BYTE, destAddr);
|
||||||
|
|
||||||
readStart += readHeight;
|
readStart += readHeight;
|
||||||
destAddr += writeStride;
|
destAddr += writeStride;
|
||||||
}
|
}
|
||||||
|
@ -273,7 +271,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
|
||||||
|
|
||||||
// Invalidate any existing texture covering this memory range.
|
// Invalidate any existing texture covering this memory range.
|
||||||
// TODO - don't delete the texture if it already exists, just replace the contents.
|
// TODO - don't delete the texture if it already exists, just replace the contents.
|
||||||
TextureMngr::InvalidateRange(address, size_in_bytes);
|
TextureCache::InvalidateRange(address, size_in_bytes);
|
||||||
|
|
||||||
u16 blkW = TexDecoder_GetBlockWidthInTexels(format) - 1;
|
u16 blkW = TexDecoder_GetBlockWidthInTexels(format) - 1;
|
||||||
u16 blkH = TexDecoder_GetBlockHeightInTexels(format) - 1;
|
u16 blkH = TexDecoder_GetBlockHeightInTexels(format) - 1;
|
||||||
|
@ -303,8 +301,6 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
|
||||||
scaledSource.bottom = expandedHeight;
|
scaledSource.bottom = expandedHeight;
|
||||||
scaledSource.left = 0;
|
scaledSource.left = 0;
|
||||||
scaledSource.right = expandedWidth / samples;
|
scaledSource.right = expandedWidth / samples;
|
||||||
|
|
||||||
|
|
||||||
int cacheBytes = 32;
|
int cacheBytes = 32;
|
||||||
if ((format & 0x0f) == 6)
|
if ((format & 0x0f) == 6)
|
||||||
cacheBytes = 64;
|
cacheBytes = 64;
|
||||||
|
@ -315,12 +311,11 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
|
||||||
g_framebufferManager.SetFramebuffer(0);
|
g_framebufferManager.SetFramebuffer(0);
|
||||||
VertexShaderManager::SetViewportChanged();
|
VertexShaderManager::SetViewportChanged();
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||||
TextureMngr::DisableStage(0);
|
TextureCache::DisableStage(0);
|
||||||
Renderer::RestoreAPIState();
|
Renderer::RestoreAPIState();
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float MValueY,bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
|
u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float MValueY,bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
|
||||||
{
|
{
|
||||||
u32 format = copyfmt;
|
u32 format = copyfmt;
|
||||||
|
@ -371,8 +366,6 @@ u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float
|
||||||
scaledSource.bottom = expandedHeight;
|
scaledSource.bottom = expandedHeight;
|
||||||
scaledSource.left = 0;
|
scaledSource.left = 0;
|
||||||
scaledSource.right = expandedWidth / samples;
|
scaledSource.right = expandedWidth / samples;
|
||||||
|
|
||||||
|
|
||||||
int cacheBytes = 32;
|
int cacheBytes = 32;
|
||||||
if ((format & 0x0f) == 6)
|
if ((format & 0x0f) == 6)
|
||||||
cacheBytes = 64;
|
cacheBytes = 64;
|
||||||
|
@ -380,19 +373,18 @@ u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float
|
||||||
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
|
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
|
||||||
|
|
||||||
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0 && !bFromZBuffer);
|
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0 && !bFromZBuffer);
|
||||||
TextureMngr::MakeRangeDynamic(address,size_in_bytes);
|
TextureCache::MakeRangeDynamic(address,size_in_bytes);
|
||||||
return GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
return GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc,
|
void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight)
|
||||||
u8* destAddr, int dstWidth, int dstHeight)
|
|
||||||
{
|
{
|
||||||
Renderer::ResetAPIState();
|
Renderer::ResetAPIState();
|
||||||
EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false);
|
EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false);
|
||||||
g_framebufferManager.SetFramebuffer(0);
|
g_framebufferManager.SetFramebuffer(0);
|
||||||
VertexShaderManager::SetViewportChanged();
|
VertexShaderManager::SetViewportChanged();
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||||
TextureMngr::DisableStage(0);
|
TextureCache::DisableStage(0);
|
||||||
Renderer::RestoreAPIState();
|
Renderer::RestoreAPIState();
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
}
|
}
|
||||||
|
@ -421,7 +413,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
|
||||||
GL_REPORT_FBO_ERROR();
|
GL_REPORT_FBO_ERROR();
|
||||||
|
|
||||||
for (int i = 1; i < 8; ++i)
|
for (int i = 1; i < 8; ++i)
|
||||||
TextureMngr::DisableStage(i);
|
TextureCache::DisableStage(i);
|
||||||
|
|
||||||
// activate source texture
|
// activate source texture
|
||||||
// set srcAddr as data for source texture
|
// set srcAddr as data for source texture
|
||||||
|
@ -457,7 +449,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
|
||||||
// reset state
|
// reset state
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
|
||||||
TextureMngr::DisableStage(0);
|
TextureCache::DisableStage(0);
|
||||||
|
|
||||||
VertexShaderManager::SetViewportChanged();
|
VertexShaderManager::SetViewportChanged();
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#include "Render.h"
|
#include "Render.h"
|
||||||
#include "ImageWrite.h"
|
#include "ImageWrite.h"
|
||||||
#include "BPMemory.h"
|
#include "BPMemory.h"
|
||||||
#include "TextureMngr.h"
|
#include "TextureCache.h"
|
||||||
#include "PixelShaderCache.h"
|
#include "PixelShaderCache.h"
|
||||||
#include "PixelShaderManager.h"
|
#include "PixelShaderManager.h"
|
||||||
#include "VertexShaderCache.h"
|
#include "VertexShaderCache.h"
|
||||||
|
@ -90,6 +90,12 @@ bool Init()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResetBuffer()
|
||||||
|
{
|
||||||
|
//s_nCurVBOIndex = (s_nCurVBOIndex + 1) % ARRAYSIZE(s_vboBuffers);
|
||||||
|
s_pCurBufferPointer = LocalVBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
void Shutdown()
|
void Shutdown()
|
||||||
{
|
{
|
||||||
delete [] LocalVBuffer;
|
delete [] LocalVBuffer;
|
||||||
|
@ -100,22 +106,16 @@ void Shutdown()
|
||||||
//s_nCurVBOIndex = 0;
|
//s_nCurVBOIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResetBuffer()
|
|
||||||
{
|
|
||||||
//s_nCurVBOIndex = (s_nCurVBOIndex + 1) % ARRAYSIZE(s_vboBuffers);
|
|
||||||
s_pCurBufferPointer = LocalVBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddIndices(int primitive, int numVertices)
|
void AddIndices(int primitive, int numVertices)
|
||||||
{
|
{
|
||||||
switch (primitive)
|
switch (primitive)
|
||||||
{
|
{
|
||||||
case GX_DRAW_QUADS: IndexGenerator::AddQuads(numVertices);break;
|
case GX_DRAW_QUADS: IndexGenerator::AddQuads(numVertices); break;
|
||||||
case GX_DRAW_TRIANGLES: IndexGenerator::AddList(numVertices);break;
|
case GX_DRAW_TRIANGLES: IndexGenerator::AddList(numVertices); break;
|
||||||
case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(numVertices); break;
|
case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(numVertices); break;
|
||||||
case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(numVertices); break;
|
case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(numVertices); break;
|
||||||
case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(numVertices); break;
|
case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(numVertices); break;
|
||||||
case GX_DRAW_LINES: IndexGenerator::AddLineList(numVertices);break;
|
case GX_DRAW_LINES: IndexGenerator::AddLineList(numVertices); break;
|
||||||
case GX_DRAW_POINTS: IndexGenerator::AddPoints(numVertices); break;
|
case GX_DRAW_POINTS: IndexGenerator::AddPoints(numVertices); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,9 +143,9 @@ int GetRemainingVertices(int primitive)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddVertices(int primitive, int numvertices)
|
void AddVertices(int primitive, int numVertices)
|
||||||
{
|
{
|
||||||
if (numvertices <= 0)
|
if (numVertices <= 0)
|
||||||
return;
|
return;
|
||||||
(void)GL_REPORT_ERROR();
|
(void)GL_REPORT_ERROR();
|
||||||
switch (primitive)
|
switch (primitive)
|
||||||
|
@ -154,16 +154,16 @@ void AddVertices(int primitive, int numvertices)
|
||||||
case GX_DRAW_TRIANGLES:
|
case GX_DRAW_TRIANGLES:
|
||||||
case GX_DRAW_TRIANGLE_STRIP:
|
case GX_DRAW_TRIANGLE_STRIP:
|
||||||
case GX_DRAW_TRIANGLE_FAN:
|
case GX_DRAW_TRIANGLE_FAN:
|
||||||
if(max_Index_size - IndexGenerator::GetTriangleindexLen() < 3 * numvertices)
|
if(max_Index_size - IndexGenerator::GetTriangleindexLen() < 3 * numVertices)
|
||||||
Flush();
|
Flush();
|
||||||
break;
|
break;
|
||||||
case GX_DRAW_LINE_STRIP:
|
case GX_DRAW_LINE_STRIP:
|
||||||
case GX_DRAW_LINES:
|
case GX_DRAW_LINES:
|
||||||
if(max_Index_size - IndexGenerator::GetLineindexLen() < 2 * numvertices)
|
if(max_Index_size - IndexGenerator::GetLineindexLen() < 2 * numVertices)
|
||||||
Flush();
|
Flush();
|
||||||
break;
|
break;
|
||||||
case GX_DRAW_POINTS:
|
case GX_DRAW_POINTS:
|
||||||
if(max_Index_size - IndexGenerator::GetPointindexLen() < numvertices)
|
if(max_Index_size - IndexGenerator::GetPointindexLen() < numVertices)
|
||||||
Flush();
|
Flush();
|
||||||
break;
|
break;
|
||||||
default: return;
|
default: return;
|
||||||
|
@ -174,11 +174,9 @@ void AddVertices(int primitive, int numvertices)
|
||||||
Flushed=false;
|
Flushed=false;
|
||||||
}
|
}
|
||||||
lastPrimitive = primitive;
|
lastPrimitive = primitive;
|
||||||
ADDSTAT(stats.thisFrame.numPrims, numvertices);
|
ADDSTAT(stats.thisFrame.numPrims, numVertices);
|
||||||
INCSTAT(stats.thisFrame.numPrimitiveJoins);
|
INCSTAT(stats.thisFrame.numPrimitiveJoins);
|
||||||
AddIndices(primitive, numvertices);
|
AddIndices(primitive, numVertices);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Draw()
|
inline void Draw()
|
||||||
|
@ -203,7 +201,7 @@ inline void Draw()
|
||||||
void Flush()
|
void Flush()
|
||||||
{
|
{
|
||||||
if (LocalVBuffer == s_pCurBufferPointer) return;
|
if (LocalVBuffer == s_pCurBufferPointer) return;
|
||||||
if(Flushed) return;
|
if (Flushed) return;
|
||||||
Flushed=true;
|
Flushed=true;
|
||||||
VideoFifo_CheckEFBAccess();
|
VideoFifo_CheckEFBAccess();
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
|
@ -265,11 +263,12 @@ void Flush()
|
||||||
if (usedtextures & (1 << i))
|
if (usedtextures & (1 << i))
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE0 + i);
|
glActiveTexture(GL_TEXTURE0 + i);
|
||||||
|
|
||||||
FourTexUnits &tex = bpmem.tex[i >> 2];
|
FourTexUnits &tex = bpmem.tex[i >> 2];
|
||||||
TextureMngr::TCacheEntry* tentry = TextureMngr::Load(i, (tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5,
|
TextureCache::TCacheEntry* tentry = TextureCache::Load(i,
|
||||||
|
(tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5,
|
||||||
tex.texImage0[i&3].width + 1, tex.texImage0[i&3].height + 1,
|
tex.texImage0[i&3].width + 1, tex.texImage0[i&3].height + 1,
|
||||||
tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9, tex.texTlut[i&3].tlut_format);
|
tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9,
|
||||||
|
tex.texTlut[i&3].tlut_format);
|
||||||
|
|
||||||
if (tentry)
|
if (tentry)
|
||||||
{
|
{
|
||||||
|
@ -285,12 +284,12 @@ void Flush()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ERROR_LOG(VIDEO, "error loading tex\n");
|
ERROR_LOG(VIDEO, "error loading texture");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FRAGMENTSHADER* ps = PixelShaderCache::GetShader(false,g_nativeVertexFmt->m_components);
|
FRAGMENTSHADER* ps = PixelShaderCache::SetShader(false,g_nativeVertexFmt->m_components);
|
||||||
VERTEXSHADER* vs = VertexShaderCache::GetShader(g_nativeVertexFmt->m_components);
|
VERTEXSHADER* vs = VertexShaderCache::SetShader(g_nativeVertexFmt->m_components);
|
||||||
|
|
||||||
// set global constants
|
// set global constants
|
||||||
VertexShaderManager::SetConstants();
|
VertexShaderManager::SetConstants();
|
||||||
|
@ -306,7 +305,7 @@ void Flush()
|
||||||
// run through vertex groups again to set alpha
|
// run through vertex groups again to set alpha
|
||||||
if (!g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate)
|
if (!g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate)
|
||||||
{
|
{
|
||||||
ps = PixelShaderCache::GetShader(true,g_nativeVertexFmt->m_components);
|
ps = PixelShaderCache::SetShader(true,g_nativeVertexFmt->m_components);
|
||||||
|
|
||||||
if (ps)PixelShaderCache::SetCurrentShader(ps->glprogid);
|
if (ps)PixelShaderCache::SetCurrentShader(ps->glprogid);
|
||||||
|
|
||||||
|
@ -357,4 +356,3 @@ void Flush()
|
||||||
|
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
|
@ -93,27 +93,25 @@ void VertexShaderCache::Init()
|
||||||
|
|
||||||
void VertexShaderCache::Shutdown()
|
void VertexShaderCache::Shutdown()
|
||||||
{
|
{
|
||||||
for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); iter++)
|
for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter)
|
||||||
iter->second.Destroy();
|
iter->second.Destroy();
|
||||||
vshaders.clear();
|
vshaders.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VERTEXSHADER* VertexShaderCache::GetShader(u32 components)
|
VERTEXSHADER* VertexShaderCache::SetShader(u32 components)
|
||||||
{
|
{
|
||||||
DVSTARTPROFILE();
|
DVSTARTPROFILE();
|
||||||
|
|
||||||
VERTEXSHADERUID uid;
|
VERTEXSHADERUID uid;
|
||||||
GetVertexShaderId(&uid, components);
|
GetVertexShaderId(&uid, components);
|
||||||
|
|
||||||
if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount)
|
if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount)
|
||||||
{
|
|
||||||
return pShaderLast;
|
return pShaderLast;
|
||||||
}
|
|
||||||
memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
|
memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
|
||||||
|
|
||||||
VSCache::iterator iter = vshaders.find(uid);
|
VSCache::iterator iter = vshaders.find(uid);
|
||||||
|
if (iter != vshaders.end())
|
||||||
if (iter != vshaders.end()) {
|
{
|
||||||
iter->second.frameCount = frameCount;
|
iter->second.frameCount = frameCount;
|
||||||
VSCacheEntry &entry = iter->second;
|
VSCacheEntry &entry = iter->second;
|
||||||
if (&entry.shader != pShaderLast) {
|
if (&entry.shader != pShaderLast) {
|
||||||
|
|
|
@ -61,7 +61,7 @@ public:
|
||||||
static void Init();
|
static void Init();
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
|
|
||||||
static VERTEXSHADER* GetShader(u32 components);
|
static VERTEXSHADER* SetShader(u32 components);
|
||||||
static bool CompileVertexShader(VERTEXSHADER& ps, const char* pstrprogram);
|
static bool CompileVertexShader(VERTEXSHADER& ps, const char* pstrprogram);
|
||||||
|
|
||||||
static void SetCurrentShader(GLuint Shader);
|
static void SetCurrentShader(GLuint Shader);
|
||||||
|
|
|
@ -73,7 +73,7 @@ GFXConfigDialogOGL *m_ConfigFrame = NULL;
|
||||||
#include "GLUtil.h"
|
#include "GLUtil.h"
|
||||||
#include "Fifo.h"
|
#include "Fifo.h"
|
||||||
#include "OpcodeDecoding.h"
|
#include "OpcodeDecoding.h"
|
||||||
#include "TextureMngr.h"
|
#include "TextureCache.h"
|
||||||
#include "BPStructs.h"
|
#include "BPStructs.h"
|
||||||
#include "VertexLoader.h"
|
#include "VertexLoader.h"
|
||||||
#include "VertexLoaderManager.h"
|
#include "VertexLoaderManager.h"
|
||||||
|
@ -109,6 +109,16 @@ static volatile u32 s_doStateRequested = FALSE;
|
||||||
static u32 s_efbAccessRequested = FALSE;
|
static u32 s_efbAccessRequested = FALSE;
|
||||||
static volatile u32 s_FifoShuttingDown = FALSE;
|
static volatile u32 s_FifoShuttingDown = FALSE;
|
||||||
|
|
||||||
|
static volatile struct
|
||||||
|
{
|
||||||
|
u32 xfbAddr;
|
||||||
|
FieldType field;
|
||||||
|
u32 fbWidth;
|
||||||
|
u32 fbHeight;
|
||||||
|
} s_beginFieldArgs;
|
||||||
|
|
||||||
|
static volatile EFBAccessType s_AccessEFBType;
|
||||||
|
|
||||||
bool IsD3D()
|
bool IsD3D()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -191,7 +201,8 @@ void Initialize(void *init)
|
||||||
// Now the window handle is written
|
// Now the window handle is written
|
||||||
_pVideoInitialize->pWindowHandle = g_VideoInitialize.pWindowHandle;
|
_pVideoInitialize->pWindowHandle = g_VideoInitialize.pWindowHandle;
|
||||||
|
|
||||||
OSD::AddMessage("Dolphin OpenGL Video Plugin", 5000);
|
OSD::AddMessage("Dolphin Direct3D9 Video Plugin.", 5000);
|
||||||
|
s_PluginInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static volatile struct
|
static volatile struct
|
||||||
|
@ -207,7 +218,7 @@ static void check_DoState() {
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
// Clear all caches that touch RAM
|
// Clear all caches that touch RAM
|
||||||
TextureMngr::Invalidate(false);
|
TextureCache::Invalidate(false);
|
||||||
VertexLoaderManager::MarkAllDirty();
|
VertexLoaderManager::MarkAllDirty();
|
||||||
|
|
||||||
PointerWrap p(s_doStateArgs.ptr, s_doStateArgs.mode);
|
PointerWrap p(s_doStateArgs.ptr, s_doStateArgs.mode);
|
||||||
|
@ -259,14 +270,14 @@ void Video_Prepare(void)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
s_swapRequested = FALSE;
|
|
||||||
s_efbAccessRequested = FALSE;
|
s_efbAccessRequested = FALSE;
|
||||||
s_FifoShuttingDown = FALSE;
|
s_FifoShuttingDown = FALSE;
|
||||||
|
s_swapRequested = FALSE;
|
||||||
|
|
||||||
CommandProcessor::Init();
|
CommandProcessor::Init();
|
||||||
PixelEngine::Init();
|
PixelEngine::Init();
|
||||||
|
|
||||||
TextureMngr::Init();
|
TextureCache::Init();
|
||||||
|
|
||||||
BPInit();
|
BPInit();
|
||||||
VertexManager::Init();
|
VertexManager::Init();
|
||||||
|
@ -289,14 +300,13 @@ void Video_Prepare(void)
|
||||||
INFO_LOG(VIDEO, "Video plugin initialized.");
|
INFO_LOG(VIDEO, "Video plugin initialized.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown(void)
|
void Shutdown()
|
||||||
{
|
{
|
||||||
s_PluginInitialized = false;
|
s_PluginInitialized = false;
|
||||||
|
|
||||||
s_efbAccessRequested = FALSE;
|
s_efbAccessRequested = FALSE;
|
||||||
s_swapRequested = FALSE;
|
|
||||||
s_FifoShuttingDown = FALSE;
|
s_FifoShuttingDown = FALSE;
|
||||||
|
s_swapRequested = FALSE;
|
||||||
DLCache::Shutdown();
|
DLCache::Shutdown();
|
||||||
Fifo_Shutdown();
|
Fifo_Shutdown();
|
||||||
PostProcessing::Shutdown();
|
PostProcessing::Shutdown();
|
||||||
|
@ -310,7 +320,7 @@ void Shutdown(void)
|
||||||
PixelShaderManager::Shutdown();
|
PixelShaderManager::Shutdown();
|
||||||
PixelShaderCache::Shutdown();
|
PixelShaderCache::Shutdown();
|
||||||
VertexManager::Shutdown();
|
VertexManager::Shutdown();
|
||||||
TextureMngr::Shutdown();
|
TextureCache::Shutdown();
|
||||||
OpcodeDecoder_Shutdown();
|
OpcodeDecoder_Shutdown();
|
||||||
Renderer::Shutdown();
|
Renderer::Shutdown();
|
||||||
OpenGL_Shutdown();
|
OpenGL_Shutdown();
|
||||||
|
@ -325,35 +335,14 @@ void Video_EnterLoop()
|
||||||
void Video_ExitLoop()
|
void Video_ExitLoop()
|
||||||
{
|
{
|
||||||
Fifo_ExitLoop();
|
Fifo_ExitLoop();
|
||||||
|
|
||||||
s_FifoShuttingDown = TRUE;
|
s_FifoShuttingDown = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Screenshot and screen message
|
|
||||||
|
|
||||||
void Video_Screenshot(const char *_szFilename)
|
|
||||||
{
|
|
||||||
Renderer::SetScreenshot(_szFilename);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Video_AddMessage(const char* pstr, u32 milliseconds)
|
|
||||||
{
|
|
||||||
OSD::AddMessage(pstr, milliseconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Video_SetRendering(bool bEnabled)
|
void Video_SetRendering(bool bEnabled)
|
||||||
{
|
{
|
||||||
Fifo_SetRendering(bEnabled);
|
Fifo_SetRendering(bEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
static volatile struct
|
|
||||||
{
|
|
||||||
u32 xfbAddr;
|
|
||||||
FieldType field;
|
|
||||||
u32 fbWidth;
|
|
||||||
u32 fbHeight;
|
|
||||||
} s_beginFieldArgs;
|
|
||||||
|
|
||||||
// Run from the graphics thread (from Fifo.cpp)
|
// Run from the graphics thread (from Fifo.cpp)
|
||||||
void VideoFifo_CheckSwapRequest()
|
void VideoFifo_CheckSwapRequest()
|
||||||
{
|
{
|
||||||
|
@ -418,6 +407,17 @@ void Video_EndField()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Video_AddMessage(const char* pstr, u32 milliseconds)
|
||||||
|
{
|
||||||
|
OSD::AddMessage(pstr, milliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Screenshot
|
||||||
|
void Video_Screenshot(const char *_szFilename)
|
||||||
|
{
|
||||||
|
Renderer::SetScreenshot(_szFilename);
|
||||||
|
}
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
EFBAccessType type;
|
EFBAccessType type;
|
||||||
|
@ -446,6 +446,7 @@ u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData)
|
||||||
s_accessEFBArgs.x = x;
|
s_accessEFBArgs.x = x;
|
||||||
s_accessEFBArgs.y = y;
|
s_accessEFBArgs.y = y;
|
||||||
s_accessEFBArgs.Data = InputData;
|
s_accessEFBArgs.Data = InputData;
|
||||||
|
|
||||||
Common::AtomicStoreRelease(s_efbAccessRequested, TRUE);
|
Common::AtomicStoreRelease(s_efbAccessRequested, TRUE);
|
||||||
|
|
||||||
if (g_VideoInitialize.bOnThread)
|
if (g_VideoInitialize.bOnThread)
|
||||||
|
@ -496,7 +497,7 @@ void Video_PixelEngineWrite32(const u32 _Data, const u32 _Address)
|
||||||
PixelEngine::Write32(_Data, _Address);
|
PixelEngine::Write32(_Data, _Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Video_GatherPipeBursted(void)
|
inline void Video_GatherPipeBursted(void)
|
||||||
{
|
{
|
||||||
CommandProcessor::GatherPipeBursted();
|
CommandProcessor::GatherPipeBursted();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (C) 2003 Dolphin Project..
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
@ -23,4 +23,3 @@
|
||||||
|
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue