Add EFB encode-to-RAM support in DX11 backend. It could probably be simplified a lot, and not all the possible formats are implemented. I tried to use the dynamic-linking feature of shader model 5, but Microsoft's HLSL compiler is broken. "Dynamic mode" is implemented, but disabled for now.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7253 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
8351177738
commit
f0c5cc76a9
|
@ -77,12 +77,14 @@ void SetColorMask(const BPCmd &bp)
|
||||||
g_renderer->SetColorMask();
|
g_renderer->SetColorMask();
|
||||||
}
|
}
|
||||||
|
|
||||||
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(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat,
|
||||||
|
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf)
|
||||||
{
|
{
|
||||||
// bpmem.zcontrol.pixel_format to PIXELFMT_Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format)
|
// bpmem.zcontrol.pixel_format to PIXELFMT_Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format)
|
||||||
if (g_ActiveConfig.bEFBCopyEnable)
|
if (g_ActiveConfig.bEFBCopyEnable)
|
||||||
{
|
{
|
||||||
TextureCache::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, !!scaleByHalf, rc);
|
TextureCache::CopyRenderTargetToTexture(dstAddr, dstFormat, srcFormat,
|
||||||
|
srcRect, isIntensity, scaleByHalf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,8 @@ void SetBlendMode(const BPCmd &bp);
|
||||||
void SetDitherMode(const BPCmd &bp);
|
void SetDitherMode(const BPCmd &bp);
|
||||||
void SetLogicOpMode(const BPCmd &bp);
|
void SetLogicOpMode(const BPCmd &bp);
|
||||||
void SetColorMask(const BPCmd &bp);
|
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(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat,
|
||||||
|
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf);
|
||||||
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc);
|
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc);
|
||||||
void OnPixelFormatChange(const BPCmd &bp);
|
void OnPixelFormatChange(const BPCmd &bp);
|
||||||
u8 *GetPointer(const u32 &address);
|
u8 *GetPointer(const u32 &address);
|
||||||
|
|
|
@ -248,9 +248,8 @@ void BPWritten(const BPCmd& bp)
|
||||||
if (GetConfig(CONFIG_SHOWEFBREGIONS))
|
if (GetConfig(CONFIG_SHOWEFBREGIONS))
|
||||||
stats.efb_regions.push_back(rc);
|
stats.efb_regions.push_back(rc);
|
||||||
|
|
||||||
CopyEFB(bp, rc, bpmem.copyTexDest << 5,
|
CopyEFB(bpmem.copyTexDest << 5, PE_copy.tp_realFormat(),
|
||||||
bpmem.zcontrol.pixel_format == PIXELFMT_Z24,
|
bpmem.zcontrol.pixel_format, rc, PE_copy.intensity_fmt,
|
||||||
PE_copy.intensity_fmt > 0,PE_copy.tp_realFormat(),
|
|
||||||
PE_copy.half_scale);
|
PE_copy.half_scale);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -421,8 +421,8 @@ return_entry:
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat,
|
||||||
bool bIsIntensityFmt, u32 copyfmt, bool bScaleByHalf, const EFBRectangle &source_rect)
|
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf)
|
||||||
{
|
{
|
||||||
float colmat[28] = {0};
|
float colmat[28] = {0};
|
||||||
float *const fConstAdd = colmat + 16;
|
float *const fConstAdd = colmat + 16;
|
||||||
|
@ -431,9 +431,9 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
||||||
ColorMask[4] = ColorMask[5] = ColorMask[6] = ColorMask[7] = 1.0f / 255.0f;
|
ColorMask[4] = ColorMask[5] = ColorMask[6] = ColorMask[7] = 1.0f / 255.0f;
|
||||||
unsigned int cbufid = -1;
|
unsigned int cbufid = -1;
|
||||||
|
|
||||||
if (bFromZBuffer)
|
if (srcFormat == PIXELFMT_Z24)
|
||||||
{
|
{
|
||||||
switch (copyfmt)
|
switch (dstFormat)
|
||||||
{
|
{
|
||||||
case 0: // Z4
|
case 0: // Z4
|
||||||
colmat[3] = colmat[7] = colmat[11] = colmat[15] = 1.0f;
|
colmat[3] = colmat[7] = colmat[11] = colmat[15] = 1.0f;
|
||||||
|
@ -476,17 +476,17 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ERROR_LOG(VIDEO, "Unknown copy zbuf format: 0x%x", copyfmt);
|
ERROR_LOG(VIDEO, "Unknown copy zbuf format: 0x%x", dstFormat);
|
||||||
colmat[2] = colmat[5] = colmat[8] = 1.0f;
|
colmat[2] = colmat[5] = colmat[8] = 1.0f;
|
||||||
cbufid = 7;
|
cbufid = 7;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (bIsIntensityFmt)
|
else if (isIntensity)
|
||||||
{
|
{
|
||||||
fConstAdd[0] = fConstAdd[1] = fConstAdd[2] = 16.0f/255.0f;
|
fConstAdd[0] = fConstAdd[1] = fConstAdd[2] = 16.0f/255.0f;
|
||||||
switch (copyfmt)
|
switch (dstFormat)
|
||||||
{
|
{
|
||||||
case 0: // I4
|
case 0: // I4
|
||||||
case 1: // I8
|
case 1: // I8
|
||||||
|
@ -498,11 +498,11 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
||||||
colmat[4] = 0.257f; colmat[5] = 0.504f; colmat[6] = 0.098f;
|
colmat[4] = 0.257f; colmat[5] = 0.504f; colmat[6] = 0.098f;
|
||||||
colmat[8] = 0.257f; colmat[9] = 0.504f; colmat[10] = 0.098f;
|
colmat[8] = 0.257f; colmat[9] = 0.504f; colmat[10] = 0.098f;
|
||||||
|
|
||||||
if (copyfmt < 2 || copyfmt == 8)
|
if (dstFormat < 2 || dstFormat == 8)
|
||||||
{
|
{
|
||||||
colmat[12] = 0.257f; colmat[13] = 0.504f; colmat[14] = 0.098f;
|
colmat[12] = 0.257f; colmat[13] = 0.504f; colmat[14] = 0.098f;
|
||||||
fConstAdd[3] = 16.0f/255.0f;
|
fConstAdd[3] = 16.0f/255.0f;
|
||||||
if (copyfmt == 0)
|
if (dstFormat == 0)
|
||||||
{
|
{
|
||||||
ColorMask[0] = ColorMask[1] = ColorMask[2] = 15.0f;
|
ColorMask[0] = ColorMask[1] = ColorMask[2] = 15.0f;
|
||||||
ColorMask[4] = ColorMask[5] = ColorMask[6] = 1.0f / 15.0f;
|
ColorMask[4] = ColorMask[5] = ColorMask[6] = 1.0f / 15.0f;
|
||||||
|
@ -516,7 +516,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
||||||
else// alpha
|
else// alpha
|
||||||
{
|
{
|
||||||
colmat[15] = 1;
|
colmat[15] = 1;
|
||||||
if (copyfmt == 2)
|
if (dstFormat == 2)
|
||||||
{
|
{
|
||||||
ColorMask[0] = ColorMask[1] = ColorMask[2] = ColorMask[3] = 15.0f;
|
ColorMask[0] = ColorMask[1] = ColorMask[2] = ColorMask[3] = 15.0f;
|
||||||
ColorMask[4] = ColorMask[5] = ColorMask[6] = ColorMask[7] = 1.0f / 15.0f;
|
ColorMask[4] = ColorMask[5] = ColorMask[6] = ColorMask[7] = 1.0f / 15.0f;
|
||||||
|
@ -531,7 +531,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ERROR_LOG(VIDEO, "Unknown copy intensity format: 0x%x", copyfmt);
|
ERROR_LOG(VIDEO, "Unknown copy intensity format: 0x%x", dstFormat);
|
||||||
colmat[0] = colmat[5] = colmat[10] = colmat[15] = 1.0f;
|
colmat[0] = colmat[5] = colmat[10] = colmat[15] = 1.0f;
|
||||||
cbufid = 23;
|
cbufid = 23;
|
||||||
break;
|
break;
|
||||||
|
@ -539,7 +539,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (copyfmt)
|
switch (dstFormat)
|
||||||
{
|
{
|
||||||
case 0: // R4
|
case 0: // R4
|
||||||
colmat[0] = colmat[4] = colmat[8] = colmat[12] = 1;
|
colmat[0] = colmat[4] = colmat[8] = colmat[12] = 1;
|
||||||
|
@ -612,22 +612,22 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ERROR_LOG(VIDEO, "Unknown copy color format: 0x%x", copyfmt);
|
ERROR_LOG(VIDEO, "Unknown copy color format: 0x%x", dstFormat);
|
||||||
colmat[0] = colmat[5] = colmat[10] = colmat[15] = 1.0f;
|
colmat[0] = colmat[5] = colmat[10] = colmat[15] = 1.0f;
|
||||||
cbufid = 23;
|
cbufid = 23;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned int tex_w = (abs(source_rect.GetWidth()) >> (int)bScaleByHalf);
|
const unsigned int tex_w = scaleByHalf ? srcRect.GetWidth()/2 : srcRect.GetWidth();
|
||||||
const unsigned int tex_h = (abs(source_rect.GetHeight()) >> (int)bScaleByHalf);
|
const unsigned int tex_h = scaleByHalf ? srcRect.GetHeight()/2 : srcRect.GetHeight();
|
||||||
|
|
||||||
unsigned int scaled_tex_w = g_ActiveConfig.bCopyEFBScaled ? Renderer::EFBToScaledX(tex_w) : tex_w;
|
unsigned int scaled_tex_w = g_ActiveConfig.bCopyEFBScaled ? Renderer::EFBToScaledX(tex_w) : tex_w;
|
||||||
unsigned int scaled_tex_h = g_ActiveConfig.bCopyEFBScaled ? Renderer::EFBToScaledY(tex_h) : tex_h;
|
unsigned int scaled_tex_h = g_ActiveConfig.bCopyEFBScaled ? Renderer::EFBToScaledY(tex_h) : tex_h;
|
||||||
|
|
||||||
bool texture_is_dynamic = false;
|
bool texture_is_dynamic = false;
|
||||||
|
|
||||||
TCacheEntryBase *entry = textures[address];
|
TCacheEntryBase *entry = textures[dstAddr];
|
||||||
if (entry)
|
if (entry)
|
||||||
{
|
{
|
||||||
if ((entry->isRenderTarget && entry->virtualW == scaled_tex_w && entry->virtualH == scaled_tex_h)
|
if ((entry->isRenderTarget && entry->virtualW == scaled_tex_w && entry->virtualH == scaled_tex_h)
|
||||||
|
@ -652,9 +652,9 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
||||||
if (NULL == entry)
|
if (NULL == entry)
|
||||||
{
|
{
|
||||||
// create the texture
|
// create the texture
|
||||||
textures[address] = entry = g_texture_cache->CreateRenderTargetTexture(scaled_tex_w, scaled_tex_h);
|
textures[dstAddr] = entry = g_texture_cache->CreateRenderTargetTexture(scaled_tex_w, scaled_tex_h);
|
||||||
|
|
||||||
entry->addr = address;
|
entry->addr = dstAddr;
|
||||||
entry->hash = 0;
|
entry->hash = 0;
|
||||||
|
|
||||||
entry->realW = tex_w;
|
entry->realW = tex_w;
|
||||||
|
@ -663,7 +663,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
||||||
entry->virtualW = scaled_tex_w;
|
entry->virtualW = scaled_tex_w;
|
||||||
entry->virtualH = scaled_tex_h;
|
entry->virtualH = scaled_tex_h;
|
||||||
|
|
||||||
entry->format = copyfmt;
|
entry->format = dstFormat;
|
||||||
entry->mipLevels = 0;
|
entry->mipLevels = 0;
|
||||||
|
|
||||||
entry->isRenderTarget = true;
|
entry->isRenderTarget = true;
|
||||||
|
@ -675,7 +675,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
||||||
|
|
||||||
g_renderer->ResetAPIState(); // reset any game specific settings
|
g_renderer->ResetAPIState(); // reset any game specific settings
|
||||||
|
|
||||||
entry->FromRenderTarget(bFromZBuffer, bScaleByHalf, cbufid, colmat, source_rect, bIsIntensityFmt, copyfmt);
|
entry->FromRenderTarget(dstAddr, dstFormat, srcFormat, srcRect, isIntensity, scaleByHalf, cbufid, colmat);
|
||||||
|
|
||||||
g_renderer->RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,9 +63,10 @@ public:
|
||||||
|
|
||||||
virtual void Load(unsigned int width, unsigned int height,
|
virtual void Load(unsigned int width, unsigned int height,
|
||||||
unsigned int expanded_width, unsigned int level, bool autogen_mips = false) = 0;
|
unsigned int expanded_width, unsigned int level, bool autogen_mips = false) = 0;
|
||||||
virtual void FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
virtual void FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
|
||||||
unsigned int cbufid, const float *colmat, const EFBRectangle &source_rect,
|
unsigned int srcFormat, const EFBRectangle& srcRect,
|
||||||
bool bIsIntensityFmt, u32 copyfmt) = 0;
|
bool isIntensity, bool scaleByHalf, unsigned int cbufid,
|
||||||
|
const float *colmat) = 0;
|
||||||
|
|
||||||
int IntersectsMemoryRange(u32 range_address, u32 range_size) const;
|
int IntersectsMemoryRange(u32 range_address, u32 range_size) const;
|
||||||
};
|
};
|
||||||
|
@ -87,8 +88,8 @@ public:
|
||||||
|
|
||||||
static TCacheEntryBase* Load(unsigned int stage, u32 address, unsigned int width, unsigned int height,
|
static TCacheEntryBase* Load(unsigned int stage, u32 address, unsigned int width, unsigned int height,
|
||||||
int format, unsigned int tlutaddr, int tlutfmt, bool UseNativeMips, unsigned int maxlevel);
|
int format, unsigned int tlutaddr, int tlutfmt, bool UseNativeMips, unsigned int maxlevel);
|
||||||
static void CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt,
|
static void CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat,
|
||||||
u32 copyfmt, bool bScaleByHalf, const EFBRectangle &source_rect);
|
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf);
|
||||||
|
|
||||||
static bool DeferredInvalidate;
|
static bool DeferredInvalidate;
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,10 @@
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
|
HINSTANCE hD3DCompilerDll = NULL;
|
||||||
|
D3DREFLECT PD3DReflect = NULL;
|
||||||
|
int d3dcompiler_dll_ref = 0;
|
||||||
|
|
||||||
HINSTANCE hD3DXDll = NULL;
|
HINSTANCE hD3DXDll = NULL;
|
||||||
D3DX11COMPILEFROMMEMORYTYPE PD3DX11CompileFromMemory = NULL;
|
D3DX11COMPILEFROMMEMORYTYPE PD3DX11CompileFromMemory = NULL;
|
||||||
D3DX11FILTERTEXTURETYPE PD3DX11FilterTexture = NULL;
|
D3DX11FILTERTEXTURETYPE PD3DX11FilterTexture = NULL;
|
||||||
|
@ -113,7 +117,7 @@ HRESULT LoadD3DX()
|
||||||
|
|
||||||
// try to load D3DX11 first to check whether we have proper runtime support
|
// try to load D3DX11 first to check whether we have proper runtime support
|
||||||
// try to use the dll the backend was compiled against first - don't bother about debug runtimes
|
// try to use the dll the backend was compiled against first - don't bother about debug runtimes
|
||||||
hD3DXDll = LoadLibraryA(StringFromFormat("d3dx11_%d.dll", D3DX11_SDK_VERSION).c_str());
|
hD3DXDll = LoadLibraryA(D3DX11_DLL_A);
|
||||||
if (!hD3DXDll)
|
if (!hD3DXDll)
|
||||||
{
|
{
|
||||||
// if that fails, use the dll which should be available in every SDK which officially supports DX11.
|
// if that fails, use the dll which should be available in every SDK which officially supports DX11.
|
||||||
|
@ -144,6 +148,35 @@ HRESULT LoadD3DX()
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT LoadD3DCompiler()
|
||||||
|
{
|
||||||
|
if (d3dcompiler_dll_ref++ > 0) return S_OK;
|
||||||
|
if (hD3DCompilerDll) return S_OK;
|
||||||
|
|
||||||
|
// try to load D3DCompiler first to check whether we have proper runtime support
|
||||||
|
// try to use the dll the backend was compiled against first - don't bother about debug runtimes
|
||||||
|
hD3DCompilerDll = LoadLibraryA(D3DCOMPILER_DLL_A);
|
||||||
|
if (!hD3DCompilerDll)
|
||||||
|
{
|
||||||
|
// if that fails, use the dll which should be available in every SDK which officially supports DX11.
|
||||||
|
hD3DCompilerDll = LoadLibraryA("D3DCompiler_42.dll");
|
||||||
|
if (!hD3DCompilerDll)
|
||||||
|
{
|
||||||
|
MessageBoxA(NULL, "Failed to load D3DCompiler_42.dll, update your DX11 runtime, please", "Critical error", MB_OK | MB_ICONERROR);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NOTICE_LOG(VIDEO, "Successfully loaded D3DCompiler_42.dll. If you're having trouble, try updating your DX runtime first.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PD3DReflect = (D3DREFLECT)GetProcAddress(hD3DCompilerDll, "D3DReflect");
|
||||||
|
if (PD3DReflect == NULL) MessageBoxA(NULL, "GetProcAddress failed for D3DReflect!", "Critical error", MB_OK | MB_ICONERROR);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
void UnloadDXGI()
|
void UnloadDXGI()
|
||||||
{
|
{
|
||||||
if (!dxgi_dll_ref) return;
|
if (!dxgi_dll_ref) return;
|
||||||
|
@ -177,6 +210,16 @@ void UnloadD3D()
|
||||||
PD3D11CreateDeviceAndSwapChain = NULL;
|
PD3D11CreateDeviceAndSwapChain = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UnloadD3DCompiler()
|
||||||
|
{
|
||||||
|
if (!d3dcompiler_dll_ref) return;
|
||||||
|
if (--d3dcompiler_dll_ref != 0) return;
|
||||||
|
|
||||||
|
if (hD3DCompilerDll) FreeLibrary(hD3DCompilerDll);
|
||||||
|
hD3DCompilerDll = NULL;
|
||||||
|
PD3DReflect = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void EnumAAModes(IDXGIAdapter* adapter, std::vector<DXGI_SAMPLE_DESC>& aa_modes)
|
void EnumAAModes(IDXGIAdapter* adapter, std::vector<DXGI_SAMPLE_DESC>& aa_modes)
|
||||||
{
|
{
|
||||||
aa_modes.clear();
|
aa_modes.clear();
|
||||||
|
@ -232,10 +275,13 @@ HRESULT Create(HWND wnd)
|
||||||
hr = LoadDXGI();
|
hr = LoadDXGI();
|
||||||
if (SUCCEEDED(hr)) hr = LoadD3D();
|
if (SUCCEEDED(hr)) hr = LoadD3D();
|
||||||
if (SUCCEEDED(hr)) hr = LoadD3DX();
|
if (SUCCEEDED(hr)) hr = LoadD3DX();
|
||||||
|
if (SUCCEEDED(hr)) hr = LoadD3DCompiler();
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
UnloadDXGI();
|
UnloadDXGI();
|
||||||
UnloadD3D();
|
UnloadD3D();
|
||||||
|
UnloadD3DX();
|
||||||
|
UnloadD3DCompiler();
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <d3dx11.h>
|
#include <D3DX11.h>
|
||||||
|
#include <D3Dcompiler.h>
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -37,9 +38,11 @@ namespace D3D
|
||||||
HRESULT LoadDXGI();
|
HRESULT LoadDXGI();
|
||||||
HRESULT LoadD3D();
|
HRESULT LoadD3D();
|
||||||
HRESULT LoadD3DX();
|
HRESULT LoadD3DX();
|
||||||
|
HRESULT LoadD3DCompiler();
|
||||||
void UnloadDXGI();
|
void UnloadDXGI();
|
||||||
void UnloadD3D();
|
void UnloadD3D();
|
||||||
void UnloadD3DX();
|
void UnloadD3DX();
|
||||||
|
void UnloadD3DCompiler();
|
||||||
|
|
||||||
void EnumAAModes(IDXGIAdapter* adapter, std::vector<DXGI_SAMPLE_DESC>& aa_modes);
|
void EnumAAModes(IDXGIAdapter* adapter, std::vector<DXGI_SAMPLE_DESC>& aa_modes);
|
||||||
DXGI_SAMPLE_DESC GetAAMode(int index);
|
DXGI_SAMPLE_DESC GetAAMode(int index);
|
||||||
|
@ -72,7 +75,7 @@ unsigned int GetMaxTextureSize();
|
||||||
inline void SetDebugObjectName(ID3D11DeviceChild* resource, const char* name)
|
inline void SetDebugObjectName(ID3D11DeviceChild* resource, const char* name)
|
||||||
{
|
{
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
resource->SetPrivateData( WKPDID_D3DDebugObjectName, strlen(name), name);
|
resource->SetPrivateData( WKPDID_D3DDebugObjectName, (UINT)strlen(name), name);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,4 +108,7 @@ extern CREATEDXGIFACTORY PCreateDXGIFactory;
|
||||||
typedef HRESULT (WINAPI* D3D11CREATEDEVICE)(IDXGIAdapter*, D3D_DRIVER_TYPE, HMODULE, UINT, CONST D3D_FEATURE_LEVEL*, UINT, UINT, ID3D11Device**, D3D_FEATURE_LEVEL*, ID3D11DeviceContext**);
|
typedef HRESULT (WINAPI* D3D11CREATEDEVICE)(IDXGIAdapter*, D3D_DRIVER_TYPE, HMODULE, UINT, CONST D3D_FEATURE_LEVEL*, UINT, UINT, ID3D11Device**, D3D_FEATURE_LEVEL*, ID3D11DeviceContext**);
|
||||||
extern D3D11CREATEDEVICE PD3D11CreateDevice;
|
extern D3D11CREATEDEVICE PD3D11CreateDevice;
|
||||||
|
|
||||||
|
typedef HRESULT (WINAPI *D3DREFLECT)(LPCVOID, SIZE_T, REFIID, void**);
|
||||||
|
extern D3DREFLECT PD3DReflect;
|
||||||
|
|
||||||
} // namespace DX11
|
} // namespace DX11
|
||||||
|
|
|
@ -55,7 +55,13 @@ bool CompileVertexShader(const char* code, unsigned int len, D3DBlob** blob)
|
||||||
HRESULT hr = PD3DX11CompileFromMemory(code, len, NULL, NULL, NULL, "main", D3D::VertexShaderVersionString(),
|
HRESULT hr = PD3DX11CompileFromMemory(code, len, NULL, NULL, NULL, "main", D3D::VertexShaderVersionString(),
|
||||||
flags, 0, NULL, &shaderBuffer, &errorBuffer, NULL);
|
flags, 0, NULL, &shaderBuffer, &errorBuffer, NULL);
|
||||||
|
|
||||||
if (FAILED(hr) || errorBuffer)
|
if (errorBuffer)
|
||||||
|
{
|
||||||
|
INFO_LOG(VIDEO, "Vertex shader compiler messages:\n%s\n",
|
||||||
|
(const char*)errorBuffer->GetBufferPointer());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.bShowShaderErrors)
|
if (g_ActiveConfig.bShowShaderErrors)
|
||||||
{
|
{
|
||||||
|
@ -90,7 +96,8 @@ ID3D11PixelShader* CreatePixelShaderFromByteCode(const void* bytecode, unsigned
|
||||||
}
|
}
|
||||||
|
|
||||||
// code->bytecode
|
// code->bytecode
|
||||||
bool CompilePixelShader(const char* code, unsigned int len, D3DBlob** blob)
|
bool CompilePixelShader(const char* code, unsigned int len, D3DBlob** blob,
|
||||||
|
const D3D_SHADER_MACRO* pDefines)
|
||||||
{
|
{
|
||||||
ID3D10Blob* shaderBuffer = NULL;
|
ID3D10Blob* shaderBuffer = NULL;
|
||||||
ID3D10Blob* errorBuffer = NULL;
|
ID3D10Blob* errorBuffer = NULL;
|
||||||
|
@ -100,10 +107,16 @@ bool CompilePixelShader(const char* code, unsigned int len, D3DBlob** blob)
|
||||||
#else
|
#else
|
||||||
UINT flags = D3D10_SHADER_OPTIMIZATION_LEVEL3;
|
UINT flags = D3D10_SHADER_OPTIMIZATION_LEVEL3;
|
||||||
#endif
|
#endif
|
||||||
HRESULT hr = PD3DX11CompileFromMemory(code, len, NULL, NULL, NULL, "main", D3D::PixelShaderVersionString(),
|
HRESULT hr = PD3DX11CompileFromMemory(code, len, NULL, pDefines, NULL, "main", D3D::PixelShaderVersionString(),
|
||||||
flags, 0, NULL, &shaderBuffer, &errorBuffer, NULL);
|
flags, 0, NULL, &shaderBuffer, &errorBuffer, NULL);
|
||||||
|
|
||||||
if (FAILED(hr) || errorBuffer)
|
if (errorBuffer)
|
||||||
|
{
|
||||||
|
INFO_LOG(VIDEO, "Pixel shader compiler messages:\n%s",
|
||||||
|
(const char*)errorBuffer->GetBufferPointer());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.bShowShaderErrors)
|
if (g_ActiveConfig.bShowShaderErrors)
|
||||||
{
|
{
|
||||||
|
@ -121,6 +134,7 @@ bool CompilePixelShader(const char* code, unsigned int len, D3DBlob** blob)
|
||||||
*blob = new D3DBlob(shaderBuffer);
|
*blob = new D3DBlob(shaderBuffer);
|
||||||
shaderBuffer->Release();
|
shaderBuffer->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
return SUCCEEDED(hr);
|
return SUCCEEDED(hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "D3DBase.h"
|
||||||
#include "D3DBlob.h"
|
#include "D3DBlob.h"
|
||||||
|
|
||||||
struct ID3D11PixelShader;
|
struct ID3D11PixelShader;
|
||||||
|
@ -32,7 +33,7 @@ namespace D3D
|
||||||
|
|
||||||
// The returned bytecode buffers should be Release()d.
|
// The returned bytecode buffers should be Release()d.
|
||||||
bool CompileVertexShader(const char* code, unsigned int len, D3DBlob** blob);
|
bool CompileVertexShader(const char* code, unsigned int len, D3DBlob** blob);
|
||||||
bool CompilePixelShader(const char* code, unsigned int len, D3DBlob** blob);
|
bool CompilePixelShader(const char* code, unsigned int len, D3DBlob** blob, const D3D_SHADER_MACRO* pDefines = NULL);
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
ID3D11VertexShader* CompileAndCreateVertexShader(const char* code, unsigned int len);
|
ID3D11VertexShader* CompileAndCreateVertexShader(const char* code, unsigned int len);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,119 @@
|
||||||
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
|
// Official SVN repository and contact information can be found at
|
||||||
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#ifndef _PSTEXTUREENCODER_H
|
||||||
|
#define _PSTEXTUREENCODER_H
|
||||||
|
|
||||||
|
#include "TextureEncoder.h"
|
||||||
|
|
||||||
|
struct ID3D11Texture2D;
|
||||||
|
struct ID3D11RenderTargetView;
|
||||||
|
struct ID3D11Buffer;
|
||||||
|
struct ID3D11InputLayout;
|
||||||
|
struct ID3D11VertexShader;
|
||||||
|
struct ID3D11PixelShader;
|
||||||
|
struct ID3D11ClassLinkage;
|
||||||
|
struct ID3D11ClassInstance;
|
||||||
|
struct ID3D11BlendState;
|
||||||
|
struct ID3D11DepthStencilState;
|
||||||
|
struct ID3D11RasterizerState;
|
||||||
|
struct ID3D11SamplerState;
|
||||||
|
|
||||||
|
namespace DX11
|
||||||
|
{
|
||||||
|
|
||||||
|
class PSTextureEncoder : public TextureEncoder
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
PSTextureEncoder();
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
void Shutdown();
|
||||||
|
size_t Encode(u8* dst, unsigned int dstFormat,
|
||||||
|
unsigned int srcFormat, const EFBRectangle& srcRect, bool isIntensity,
|
||||||
|
bool scaleByHalf);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool m_ready;
|
||||||
|
|
||||||
|
ID3D11Texture2D* m_out;
|
||||||
|
ID3D11RenderTargetView* m_outRTV;
|
||||||
|
ID3D11Texture2D* m_outStage;
|
||||||
|
ID3D11Buffer* m_encodeParams;
|
||||||
|
ID3D11Buffer* m_quad;
|
||||||
|
ID3D11VertexShader* m_vShader;
|
||||||
|
ID3D11InputLayout* m_quadLayout;
|
||||||
|
ID3D11BlendState* m_efbEncodeBlendState;
|
||||||
|
ID3D11DepthStencilState* m_efbEncodeDepthState;
|
||||||
|
ID3D11RasterizerState* m_efbEncodeRastState;
|
||||||
|
ID3D11SamplerState* m_efbSampler;
|
||||||
|
|
||||||
|
// Stuff only used in static-linking mode (SM4.0-compatible)
|
||||||
|
|
||||||
|
bool InitStaticMode();
|
||||||
|
bool SetStaticShader(unsigned int dstFormat, unsigned int srcFormat,
|
||||||
|
bool isIntensity, bool scaleByHalf);
|
||||||
|
|
||||||
|
typedef unsigned int ComboKey; // Key for a shader combination
|
||||||
|
|
||||||
|
ComboKey MakeComboKey(unsigned int dstFormat, unsigned int srcFormat,
|
||||||
|
bool isIntensity, bool scaleByHalf)
|
||||||
|
{
|
||||||
|
return (dstFormat << 4) | (srcFormat << 2) | (isIntensity ? (1<<1) : 0)
|
||||||
|
| (scaleByHalf ? (1<<0) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef std::map<ComboKey, ID3D11PixelShader*> ComboMap;
|
||||||
|
|
||||||
|
ComboMap m_staticShaders;
|
||||||
|
|
||||||
|
// Stuff only used for dynamic-linking mode (SM5.0+, available as soon as
|
||||||
|
// Microsoft fixes their bloody HLSL compiler)
|
||||||
|
|
||||||
|
bool InitDynamicMode();
|
||||||
|
bool SetDynamicShader(unsigned int dstFormat, unsigned int srcFormat,
|
||||||
|
bool isIntensity, bool scaleByHalf);
|
||||||
|
|
||||||
|
ID3D11PixelShader* m_dynamicShader;
|
||||||
|
ID3D11ClassLinkage* m_classLinkage;
|
||||||
|
|
||||||
|
// Interface slots
|
||||||
|
UINT m_fetchSlot;
|
||||||
|
UINT m_scaledFetchSlot;
|
||||||
|
UINT m_intensitySlot;
|
||||||
|
UINT m_generatorSlot;
|
||||||
|
|
||||||
|
// Class instances
|
||||||
|
// Fetch: 0 is RGB, 1 is RGBA, 2 is RGB565, 3 is Z
|
||||||
|
ID3D11ClassInstance* m_fetchClass[4];
|
||||||
|
// ScaledFetch: 0 is off, 1 is on
|
||||||
|
ID3D11ClassInstance* m_scaledFetchClass[2];
|
||||||
|
// Intensity: 0 is off, 1 is on
|
||||||
|
ID3D11ClassInstance* m_intensityClass[2];
|
||||||
|
// Generator: one for each dst format, 16 total
|
||||||
|
ID3D11ClassInstance* m_generatorClass[16];
|
||||||
|
|
||||||
|
std::vector<ID3D11ClassInstance*> m_linkageArray;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -23,12 +23,17 @@
|
||||||
#include "PixelShaderCache.h"
|
#include "PixelShaderCache.h"
|
||||||
#include "TextureCache.h"
|
#include "TextureCache.h"
|
||||||
#include "VertexShaderCache.h"
|
#include "VertexShaderCache.h"
|
||||||
|
#include "TextureEncoder.h"
|
||||||
|
#include "PSTextureEncoder.h"
|
||||||
|
#include "HW/Memmap.h"
|
||||||
|
#include "VideoConfig.h"
|
||||||
|
|
||||||
namespace DX11
|
namespace DX11
|
||||||
{
|
{
|
||||||
|
|
||||||
#define MAX_COPY_BUFFERS 25
|
static TextureEncoder* g_encoder = NULL;
|
||||||
ID3D11Buffer* efbcopycbuf[MAX_COPY_BUFFERS] = {};
|
const size_t MAX_COPY_BUFFERS = 25;
|
||||||
|
ID3D11Buffer* efbcopycbuf[MAX_COPY_BUFFERS] = { 0 };
|
||||||
|
|
||||||
TextureCache::TCacheEntry::~TCacheEntry()
|
TextureCache::TCacheEntry::~TCacheEntry()
|
||||||
{
|
{
|
||||||
|
@ -92,11 +97,15 @@ TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width,
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
|
||||||
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect,
|
unsigned int srcFormat, const EFBRectangle& srcRect,
|
||||||
bool bIsIntensityFmt, u32 copyfmt)
|
bool isIntensity, bool scaleByHalf, unsigned int cbufid,
|
||||||
|
const float *colmat)
|
||||||
|
{
|
||||||
|
if (!isDynamic || g_ActiveConfig.bCopyEFBToTexture)
|
||||||
{
|
{
|
||||||
g_renderer->ResetAPIState();
|
g_renderer->ResetAPIState();
|
||||||
|
|
||||||
// stretch picture with increased internal resolution
|
// stretch picture with increased internal resolution
|
||||||
const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)virtualW, (float)virtualH);
|
const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)virtualW, (float)virtualH);
|
||||||
D3D::context->RSSetViewports(1, &vp);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
|
@ -113,22 +122,23 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB
|
||||||
}
|
}
|
||||||
D3D::context->PSSetConstantBuffers(0, 1, &efbcopycbuf[cbufid]);
|
D3D::context->PSSetConstantBuffers(0, 1, &efbcopycbuf[cbufid]);
|
||||||
|
|
||||||
const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(source_rect);
|
const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect);
|
||||||
// TODO: try targetSource.asRECT();
|
// TODO: try targetSource.asRECT();
|
||||||
const D3D11_RECT sourcerect = CD3D11_RECT(targetSource.left, targetSource.top, targetSource.right, targetSource.bottom);
|
const D3D11_RECT sourcerect = CD3D11_RECT(targetSource.left, targetSource.top, targetSource.right, targetSource.bottom);
|
||||||
|
|
||||||
// Use linear filtering if (bScaleByHalf), use point filtering otherwise
|
// Use linear filtering if (bScaleByHalf), use point filtering otherwise
|
||||||
if (bScaleByHalf)
|
if (scaleByHalf)
|
||||||
D3D::SetLinearCopySampler();
|
D3D::SetLinearCopySampler();
|
||||||
else
|
else
|
||||||
D3D::SetPointCopySampler();
|
D3D::SetPointCopySampler();
|
||||||
|
|
||||||
D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), NULL);
|
D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), NULL);
|
||||||
|
|
||||||
|
// Create texture copy
|
||||||
D3D::drawShadedTexQuad(
|
D3D::drawShadedTexQuad(
|
||||||
(bFromZBuffer) ? FramebufferManager::GetEFBDepthTexture()->GetSRV() : FramebufferManager::GetEFBColorTexture()->GetSRV(),
|
(srcFormat == PIXELFMT_Z24) ? FramebufferManager::GetEFBDepthTexture()->GetSRV() : FramebufferManager::GetEFBColorTexture()->GetSRV(),
|
||||||
&sourcerect, Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(),
|
&sourcerect, Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(),
|
||||||
(bFromZBuffer) ? PixelShaderCache::GetDepthMatrixProgram(true) : PixelShaderCache::GetColorMatrixProgram(true),
|
(srcFormat == PIXELFMT_Z24) ? PixelShaderCache::GetDepthMatrixProgram(true) : PixelShaderCache::GetColorMatrixProgram(true),
|
||||||
VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
||||||
|
|
||||||
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
||||||
|
@ -136,6 +146,23 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB
|
||||||
g_renderer->RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!g_ActiveConfig.bCopyEFBToTexture)
|
||||||
|
{
|
||||||
|
u8* dst = Memory::GetPointer(dstAddr);
|
||||||
|
size_t encodeSize = g_encoder->Encode(dst, dstFormat, srcFormat, srcRect, isIntensity, scaleByHalf);
|
||||||
|
hash = GetHash64(dst, encodeSize, g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||||
|
if (g_ActiveConfig.bEFBCopyCacheEnable)
|
||||||
|
{
|
||||||
|
// If the texture in RAM is already in the texture cache,
|
||||||
|
// do not copy it again as it has not changed.
|
||||||
|
if (TextureCache::Find(dstAddr, hash))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureCache::MakeRangeDynamic(dstAddr, encodeSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture(
|
TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture(
|
||||||
unsigned int scaled_tex_w, unsigned int scaled_tex_h)
|
unsigned int scaled_tex_w, unsigned int scaled_tex_h)
|
||||||
{
|
{
|
||||||
|
@ -146,12 +173,19 @@ TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture(
|
||||||
|
|
||||||
TextureCache::TextureCache()
|
TextureCache::TextureCache()
|
||||||
{
|
{
|
||||||
|
// FIXME: Is it safe here?
|
||||||
|
g_encoder = new PSTextureEncoder;
|
||||||
|
g_encoder->Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCache::~TextureCache()
|
TextureCache::~TextureCache()
|
||||||
{
|
{
|
||||||
for (unsigned int k = 0; k < MAX_COPY_BUFFERS; ++k)
|
for (unsigned int k = 0; k < MAX_COPY_BUFFERS; ++k)
|
||||||
SAFE_RELEASE(efbcopycbuf[k]);
|
SAFE_RELEASE(efbcopycbuf[k]);
|
||||||
|
|
||||||
|
g_encoder->Shutdown();
|
||||||
|
delete g_encoder;
|
||||||
|
g_encoder = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,9 +43,10 @@ private:
|
||||||
void Load(unsigned int width, unsigned int height,
|
void Load(unsigned int width, unsigned int height,
|
||||||
unsigned int expanded_width, unsigned int levels, bool autogen_mips = false);
|
unsigned int expanded_width, unsigned int levels, bool autogen_mips = false);
|
||||||
|
|
||||||
void FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
void FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
|
||||||
unsigned int cbufid, const float* colmat, const EFBRectangle &source_rect,
|
unsigned int srcFormat, const EFBRectangle& srcRect,
|
||||||
bool bIsIntensityFmt, u32 copyfmt);
|
bool isIntensity, bool scaleByHalf, unsigned int cbufid,
|
||||||
|
const float *colmat);
|
||||||
|
|
||||||
void Bind(unsigned int stage);
|
void Bind(unsigned int stage);
|
||||||
bool Save(const char filename[]);
|
bool Save(const char filename[]);
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
// Copyright (C) 2003 Dolphin Project.
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
|
// Official SVN repository and contact information can be found at
|
||||||
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#ifndef _TEXTUREENCODER_H
|
||||||
|
#define _TEXTUREENCODER_H
|
||||||
|
|
||||||
|
#include "VideoCommon.h"
|
||||||
|
|
||||||
|
namespace DX11
|
||||||
|
{
|
||||||
|
|
||||||
|
// 4-bit format: 8x8 texels / cache line
|
||||||
|
// 8-bit format: 8x4 texels / cache line
|
||||||
|
// 16-bit format: 4x4 texels / cache line
|
||||||
|
// 32-bit format: 4x4 texels / 2 cache lines
|
||||||
|
// Compressed format: 8x8 texels / cache line
|
||||||
|
|
||||||
|
const unsigned int BLOCK_WIDTHS[16] = {
|
||||||
|
8, // R4
|
||||||
|
8, // R8 (FIXME: duplicate of R8 below?)
|
||||||
|
8, // A4 R4
|
||||||
|
4, // A8 R8
|
||||||
|
4, // R5 G6 B5
|
||||||
|
4, // 1 R5 G5 B5 or 0 A3 R4 G4 B4
|
||||||
|
4, // A8 R8 A8 R8 | G8 B8 G8 B8 (two cache lines)
|
||||||
|
8, // A8
|
||||||
|
8, // R8 (FIXME: duplicate of R8 above?)
|
||||||
|
8, // G8
|
||||||
|
8, // B8
|
||||||
|
4, // G8 R8
|
||||||
|
4, // B8 G8
|
||||||
|
0, 0, 0 // Unknown formats
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned int BLOCK_HEIGHTS[16] = {
|
||||||
|
8, // R4
|
||||||
|
4, // R8 (FIXME: duplicate of R8 below?)
|
||||||
|
4, // A4 R4
|
||||||
|
4, // A8 R8
|
||||||
|
4, // R5 G6 B5
|
||||||
|
4, // 1 R5 G5 B5 or 0 A3 R4 G4 B4
|
||||||
|
4, // A8 R8 A8 R8 | G8 B8 G8 B8 (two cache lines)
|
||||||
|
4, // A8
|
||||||
|
4, // R8 (FIXME: duplicate of R8 above?)
|
||||||
|
4, // G8
|
||||||
|
4, // B8
|
||||||
|
4, // G8 R8
|
||||||
|
4, // B8 G8
|
||||||
|
0, 0, 0 // Unknown formats
|
||||||
|
};
|
||||||
|
|
||||||
|
// Maximum number of bytes that can occur in a texture block-row generated by
|
||||||
|
// the encoder
|
||||||
|
static const UINT MAX_BYTES_PER_BLOCK_ROW = (EFB_WIDTH/4)*64;
|
||||||
|
// The maximum amount of data that the texture encoder can generate in one call
|
||||||
|
static const UINT MAX_BYTES_PER_ENCODE = MAX_BYTES_PER_BLOCK_ROW*(EFB_HEIGHT/4);
|
||||||
|
|
||||||
|
class TextureEncoder
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~TextureEncoder() { }
|
||||||
|
|
||||||
|
virtual void Init() = 0;
|
||||||
|
virtual void Shutdown() = 0;
|
||||||
|
// Returns size in bytes of encoded block of memory
|
||||||
|
virtual size_t Encode(u8* dst, unsigned int dstFormat,
|
||||||
|
unsigned int srcFormat, const EFBRectangle& srcRect, bool isIntensity,
|
||||||
|
bool scaleByHalf) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -81,7 +81,7 @@ void InitBackendInfo()
|
||||||
{
|
{
|
||||||
g_Config.backend_info.APIType = API_D3D11;
|
g_Config.backend_info.APIType = API_D3D11;
|
||||||
g_Config.backend_info.bUseRGBATextures = true; // the GX formats barely match any D3D11 formats
|
g_Config.backend_info.bUseRGBATextures = true; // the GX formats barely match any D3D11 formats
|
||||||
g_Config.backend_info.bSupportsEFBToRAM = false;
|
g_Config.backend_info.bSupportsEFBToRAM = true;
|
||||||
g_Config.backend_info.bSupportsRealXFB = false;
|
g_Config.backend_info.bSupportsRealXFB = false;
|
||||||
g_Config.backend_info.bSupports3DVision = false;
|
g_Config.backend_info.bSupports3DVision = false;
|
||||||
g_Config.backend_info.bAllowSignedBytes = true;
|
g_Config.backend_info.bAllowSignedBytes = true;
|
||||||
|
|
|
@ -69,11 +69,12 @@ void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height,
|
||||||
// D3D9 will automatically generate mip maps if necessary
|
// D3D9 will automatically generate mip maps if necessary
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
|
||||||
unsigned int cbufid, const float *colmat, const EFBRectangle &source_rect,
|
unsigned int srcFormat, const EFBRectangle& srcRect,
|
||||||
bool bIsIntensityFmt, u32 copyfmt)
|
bool isIntensity, bool scaleByHalf, unsigned int cbufid,
|
||||||
|
const float *colmat)
|
||||||
{
|
{
|
||||||
const LPDIRECT3DTEXTURE9 read_texture = bFromZBuffer ?
|
const LPDIRECT3DTEXTURE9 read_texture = (srcFormat == PIXELFMT_Z24) ?
|
||||||
FramebufferManager::GetEFBDepthTexture() :
|
FramebufferManager::GetEFBDepthTexture() :
|
||||||
FramebufferManager::GetEFBColorTexture();
|
FramebufferManager::GetEFBColorTexture();
|
||||||
|
|
||||||
|
@ -101,16 +102,16 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB
|
||||||
destrect.top = 0;
|
destrect.top = 0;
|
||||||
|
|
||||||
PixelShaderManager::SetColorMatrix(colmat); // set transformation
|
PixelShaderManager::SetColorMatrix(colmat); // set transformation
|
||||||
TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(source_rect);
|
TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect);
|
||||||
RECT sourcerect;
|
RECT sourcerect;
|
||||||
sourcerect.bottom = targetSource.bottom;
|
sourcerect.bottom = targetSource.bottom;
|
||||||
sourcerect.left = targetSource.left;
|
sourcerect.left = targetSource.left;
|
||||||
sourcerect.right = targetSource.right;
|
sourcerect.right = targetSource.right;
|
||||||
sourcerect.top = targetSource.top;
|
sourcerect.top = targetSource.top;
|
||||||
|
|
||||||
if (bFromZBuffer)
|
if (srcFormat == PIXELFMT_Z24)
|
||||||
{
|
{
|
||||||
if (bScaleByHalf || g_ActiveConfig.iMultisampleMode)
|
if (scaleByHalf || g_ActiveConfig.iMultisampleMode)
|
||||||
{
|
{
|
||||||
D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||||
D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||||
|
@ -134,7 +135,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB
|
||||||
Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(),
|
Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(),
|
||||||
virtualW, virtualH,
|
virtualW, virtualH,
|
||||||
// TODO: why is D3DFMT_D24X8 singled out here? why not D3DFMT_D24X4S4/D24S8/D24FS8/D32/D16/D15S1 too, or none of them?
|
// TODO: why is D3DFMT_D24X8 singled out here? why not D3DFMT_D24X4S4/D24S8/D24FS8/D32/D16/D15S1 too, or none of them?
|
||||||
PixelShaderCache::GetDepthMatrixProgram(SSAAMode, bFromZBuffer && bformat != FOURCC_RAWZ && bformat != D3DFMT_D24X8),
|
PixelShaderCache::GetDepthMatrixProgram(SSAAMode, (srcFormat == PIXELFMT_Z24) && bformat != FOURCC_RAWZ && bformat != D3DFMT_D24X8),
|
||||||
VertexShaderCache::GetSimpleVertexShader(SSAAMode));
|
VertexShaderCache::GetSimpleVertexShader(SSAAMode));
|
||||||
|
|
||||||
Rendersurf->Release();
|
Rendersurf->Release();
|
||||||
|
@ -147,11 +148,11 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB
|
||||||
read_texture,
|
read_texture,
|
||||||
Renderer::GetFullTargetWidth(),
|
Renderer::GetFullTargetWidth(),
|
||||||
Renderer::GetFullTargetHeight(),
|
Renderer::GetFullTargetHeight(),
|
||||||
bFromZBuffer,
|
srcFormat == PIXELFMT_Z24,
|
||||||
bIsIntensityFmt,
|
isIntensity,
|
||||||
copyfmt,
|
dstFormat,
|
||||||
bScaleByHalf,
|
scaleByHalf,
|
||||||
source_rect);
|
srcRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
|
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
|
||||||
|
|
|
@ -46,9 +46,10 @@ private:
|
||||||
void Load(unsigned int width, unsigned int height,
|
void Load(unsigned int width, unsigned int height,
|
||||||
unsigned int expanded_width, unsigned int levels, bool autogen_mips = false);
|
unsigned int expanded_width, unsigned int levels, bool autogen_mips = false);
|
||||||
|
|
||||||
void FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
void FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
|
||||||
unsigned int cbufid, const float* colmat, const EFBRectangle &source_rect,
|
unsigned int srcFormat, const EFBRectangle& srcRect,
|
||||||
bool bIsIntensityFmt, u32 copyfmt);
|
bool isIntensity, bool scaleByHalf, unsigned int cbufid,
|
||||||
|
const float *colmat);
|
||||||
|
|
||||||
void Bind(unsigned int stage);
|
void Bind(unsigned int stage);
|
||||||
bool Save(const char filename[]);
|
bool Save(const char filename[]);
|
||||||
|
|
|
@ -264,16 +264,17 @@ TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture(
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
|
||||||
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect,
|
unsigned int srcFormat, const EFBRectangle& srcRect,
|
||||||
bool bIsIntensityFmt, u32 copyfmt)
|
bool isIntensity, bool scaleByHalf, unsigned int cbufid,
|
||||||
|
const float *colmat)
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D, texture);
|
glBindTexture(GL_TEXTURE_2D, texture);
|
||||||
|
|
||||||
// Make sure to resolve anything we need to read from.
|
// Make sure to resolve anything we need to read from.
|
||||||
const GLuint read_texture = bFromZBuffer ?
|
const GLuint read_texture = (srcFormat == PIXELFMT_Z24) ?
|
||||||
FramebufferManager::ResolveAndGetDepthTarget(source_rect) :
|
FramebufferManager::ResolveAndGetDepthTarget(srcRect) :
|
||||||
FramebufferManager::ResolveAndGetRenderTarget(source_rect);
|
FramebufferManager::ResolveAndGetRenderTarget(srcRect);
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
|
@ -295,11 +296,11 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB
|
||||||
|
|
||||||
glViewport(0, 0, virtualW, virtualH);
|
glViewport(0, 0, virtualW, virtualH);
|
||||||
|
|
||||||
PixelShaderCache::SetCurrentShader(bFromZBuffer ? PixelShaderCache::GetDepthMatrixProgram() : PixelShaderCache::GetColorMatrixProgram());
|
PixelShaderCache::SetCurrentShader((srcFormat == PIXELFMT_Z24) ? PixelShaderCache::GetDepthMatrixProgram() : PixelShaderCache::GetColorMatrixProgram());
|
||||||
PixelShaderManager::SetColorMatrix(colmat); // set transformation
|
PixelShaderManager::SetColorMatrix(colmat); // set transformation
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(source_rect);
|
TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect);
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.bottom); glVertex2f(-1, 1);
|
glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.bottom); glVertex2f(-1, 1);
|
||||||
|
@ -319,11 +320,11 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB
|
||||||
hash = TextureConverter::EncodeToRamFromTexture(
|
hash = TextureConverter::EncodeToRamFromTexture(
|
||||||
addr,
|
addr,
|
||||||
read_texture,
|
read_texture,
|
||||||
bFromZBuffer,
|
srcFormat == PIXELFMT_Z24,
|
||||||
bIsIntensityFmt,
|
isIntensity,
|
||||||
copyfmt,
|
dstFormat,
|
||||||
bScaleByHalf,
|
scaleByHalf,
|
||||||
source_rect);
|
srcRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
FramebufferManager::SetFramebuffer(0);
|
FramebufferManager::SetFramebuffer(0);
|
||||||
|
|
|
@ -56,9 +56,10 @@ private:
|
||||||
void Load(unsigned int width, unsigned int height,
|
void Load(unsigned int width, unsigned int height,
|
||||||
unsigned int expanded_width, unsigned int level, bool autogen_mips = false);
|
unsigned int expanded_width, unsigned int level, bool autogen_mips = false);
|
||||||
|
|
||||||
void FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
void FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
|
||||||
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect,
|
unsigned int srcFormat, const EFBRectangle& srcRect,
|
||||||
bool bIsIntensityFmt, u32 copyfmt);
|
bool isIntensity, bool scaleByHalf, unsigned int cbufid,
|
||||||
|
const float *colmat);
|
||||||
|
|
||||||
void Bind(unsigned int stage);
|
void Bind(unsigned int stage);
|
||||||
bool Save(const char filename[]);
|
bool Save(const char filename[]);
|
||||||
|
|
Loading…
Reference in New Issue