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();
|
||||
}
|
||||
|
||||
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)
|
||||
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 SetLogicOpMode(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 OnPixelFormatChange(const BPCmd &bp);
|
||||
u8 *GetPointer(const u32 &address);
|
||||
|
|
|
@ -248,10 +248,9 @@ void BPWritten(const BPCmd& bp)
|
|||
if (GetConfig(CONFIG_SHOWEFBREGIONS))
|
||||
stats.efb_regions.push_back(rc);
|
||||
|
||||
CopyEFB(bp, rc, bpmem.copyTexDest << 5,
|
||||
bpmem.zcontrol.pixel_format == PIXELFMT_Z24,
|
||||
PE_copy.intensity_fmt > 0,PE_copy.tp_realFormat(),
|
||||
PE_copy.half_scale);
|
||||
CopyEFB(bpmem.copyTexDest << 5, PE_copy.tp_realFormat(),
|
||||
bpmem.zcontrol.pixel_format, rc, PE_copy.intensity_fmt,
|
||||
PE_copy.half_scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -421,8 +421,8 @@ return_entry:
|
|||
return entry;
|
||||
}
|
||||
|
||||
void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
||||
bool bIsIntensityFmt, u32 copyfmt, bool bScaleByHalf, const EFBRectangle &source_rect)
|
||||
void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat,
|
||||
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf)
|
||||
{
|
||||
float colmat[28] = {0};
|
||||
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;
|
||||
unsigned int cbufid = -1;
|
||||
|
||||
if (bFromZBuffer)
|
||||
if (srcFormat == PIXELFMT_Z24)
|
||||
{
|
||||
switch (copyfmt)
|
||||
switch (dstFormat)
|
||||
{
|
||||
case 0: // Z4
|
||||
colmat[3] = colmat[7] = colmat[11] = colmat[15] = 1.0f;
|
||||
|
@ -476,17 +476,17 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
|||
break;
|
||||
|
||||
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;
|
||||
cbufid = 7;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else if (bIsIntensityFmt)
|
||||
else if (isIntensity)
|
||||
{
|
||||
fConstAdd[0] = fConstAdd[1] = fConstAdd[2] = 16.0f/255.0f;
|
||||
switch (copyfmt)
|
||||
switch (dstFormat)
|
||||
{
|
||||
case 0: // I4
|
||||
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[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;
|
||||
fConstAdd[3] = 16.0f/255.0f;
|
||||
if (copyfmt == 0)
|
||||
if (dstFormat == 0)
|
||||
{
|
||||
ColorMask[0] = ColorMask[1] = ColorMask[2] = 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
|
||||
{
|
||||
colmat[15] = 1;
|
||||
if (copyfmt == 2)
|
||||
if (dstFormat == 2)
|
||||
{
|
||||
ColorMask[0] = ColorMask[1] = ColorMask[2] = ColorMask[3] = 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;
|
||||
|
||||
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;
|
||||
cbufid = 23;
|
||||
break;
|
||||
|
@ -539,7 +539,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
|||
}
|
||||
else
|
||||
{
|
||||
switch (copyfmt)
|
||||
switch (dstFormat)
|
||||
{
|
||||
case 0: // R4
|
||||
colmat[0] = colmat[4] = colmat[8] = colmat[12] = 1;
|
||||
|
@ -612,22 +612,22 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
|||
break;
|
||||
|
||||
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;
|
||||
cbufid = 23;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const unsigned int tex_w = (abs(source_rect.GetWidth()) >> (int)bScaleByHalf);
|
||||
const unsigned int tex_h = (abs(source_rect.GetHeight()) >> (int)bScaleByHalf);
|
||||
const unsigned int tex_w = scaleByHalf ? srcRect.GetWidth()/2 : srcRect.GetWidth();
|
||||
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_h = g_ActiveConfig.bCopyEFBScaled ? Renderer::EFBToScaledY(tex_h) : tex_h;
|
||||
|
||||
bool texture_is_dynamic = false;
|
||||
|
||||
TCacheEntryBase *entry = textures[address];
|
||||
TCacheEntryBase *entry = textures[dstAddr];
|
||||
if (entry)
|
||||
{
|
||||
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)
|
||||
{
|
||||
// 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->realW = tex_w;
|
||||
|
@ -663,7 +663,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
|||
entry->virtualW = scaled_tex_w;
|
||||
entry->virtualH = scaled_tex_h;
|
||||
|
||||
entry->format = copyfmt;
|
||||
entry->format = dstFormat;
|
||||
entry->mipLevels = 0;
|
||||
|
||||
entry->isRenderTarget = true;
|
||||
|
@ -675,7 +675,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
|||
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -63,9 +63,10 @@ public:
|
|||
|
||||
virtual void Load(unsigned int width, unsigned int height,
|
||||
unsigned int expanded_width, unsigned int level, bool autogen_mips = false) = 0;
|
||||
virtual void FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
||||
unsigned int cbufid, const float *colmat, const EFBRectangle &source_rect,
|
||||
bool bIsIntensityFmt, u32 copyfmt) = 0;
|
||||
virtual void FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
|
||||
unsigned int srcFormat, const EFBRectangle& srcRect,
|
||||
bool isIntensity, bool scaleByHalf, unsigned int cbufid,
|
||||
const float *colmat) = 0;
|
||||
|
||||
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,
|
||||
int format, unsigned int tlutaddr, int tlutfmt, bool UseNativeMips, unsigned int maxlevel);
|
||||
static void CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt,
|
||||
u32 copyfmt, bool bScaleByHalf, const EFBRectangle &source_rect);
|
||||
static void CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat,
|
||||
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf);
|
||||
|
||||
static bool DeferredInvalidate;
|
||||
|
||||
|
|
|
@ -25,6 +25,10 @@
|
|||
namespace DX11
|
||||
{
|
||||
|
||||
HINSTANCE hD3DCompilerDll = NULL;
|
||||
D3DREFLECT PD3DReflect = NULL;
|
||||
int d3dcompiler_dll_ref = 0;
|
||||
|
||||
HINSTANCE hD3DXDll = NULL;
|
||||
D3DX11COMPILEFROMMEMORYTYPE PD3DX11CompileFromMemory = 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 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 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;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
if (!dxgi_dll_ref) return;
|
||||
|
@ -177,6 +210,16 @@ void UnloadD3D()
|
|||
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)
|
||||
{
|
||||
aa_modes.clear();
|
||||
|
@ -232,10 +275,13 @@ HRESULT Create(HWND wnd)
|
|||
hr = LoadDXGI();
|
||||
if (SUCCEEDED(hr)) hr = LoadD3D();
|
||||
if (SUCCEEDED(hr)) hr = LoadD3DX();
|
||||
if (SUCCEEDED(hr)) hr = LoadD3DCompiler();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
UnloadDXGI();
|
||||
UnloadD3D();
|
||||
UnloadD3DX();
|
||||
UnloadD3DCompiler();
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <d3dx11.h>
|
||||
#include <D3DX11.h>
|
||||
#include <D3Dcompiler.h>
|
||||
#include "Common.h"
|
||||
#include <vector>
|
||||
|
||||
|
@ -37,9 +38,11 @@ namespace D3D
|
|||
HRESULT LoadDXGI();
|
||||
HRESULT LoadD3D();
|
||||
HRESULT LoadD3DX();
|
||||
HRESULT LoadD3DCompiler();
|
||||
void UnloadDXGI();
|
||||
void UnloadD3D();
|
||||
void UnloadD3DX();
|
||||
void UnloadD3DCompiler();
|
||||
|
||||
void EnumAAModes(IDXGIAdapter* adapter, std::vector<DXGI_SAMPLE_DESC>& aa_modes);
|
||||
DXGI_SAMPLE_DESC GetAAMode(int index);
|
||||
|
@ -72,7 +75,7 @@ unsigned int GetMaxTextureSize();
|
|||
inline void SetDebugObjectName(ID3D11DeviceChild* resource, const char* name)
|
||||
{
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
resource->SetPrivateData( WKPDID_D3DDebugObjectName, strlen(name), name);
|
||||
resource->SetPrivateData( WKPDID_D3DDebugObjectName, (UINT)strlen(name), name);
|
||||
#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**);
|
||||
extern D3D11CREATEDEVICE PD3D11CreateDevice;
|
||||
|
||||
typedef HRESULT (WINAPI *D3DREFLECT)(LPCVOID, SIZE_T, REFIID, void**);
|
||||
extern D3DREFLECT PD3DReflect;
|
||||
|
||||
} // namespace DX11
|
||||
|
|
|
@ -54,8 +54,14 @@ bool CompileVertexShader(const char* code, unsigned int len, D3DBlob** blob)
|
|||
#endif
|
||||
HRESULT hr = PD3DX11CompileFromMemory(code, len, NULL, NULL, NULL, "main", D3D::VertexShaderVersionString(),
|
||||
flags, 0, NULL, &shaderBuffer, &errorBuffer, NULL);
|
||||
|
||||
if (errorBuffer)
|
||||
{
|
||||
INFO_LOG(VIDEO, "Vertex shader compiler messages:\n%s\n",
|
||||
(const char*)errorBuffer->GetBufferPointer());
|
||||
}
|
||||
|
||||
if (FAILED(hr) || errorBuffer)
|
||||
if (FAILED(hr))
|
||||
{
|
||||
if (g_ActiveConfig.bShowShaderErrors)
|
||||
{
|
||||
|
@ -90,7 +96,8 @@ ID3D11PixelShader* CreatePixelShaderFromByteCode(const void* bytecode, unsigned
|
|||
}
|
||||
|
||||
// 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* errorBuffer = NULL;
|
||||
|
@ -100,10 +107,16 @@ bool CompilePixelShader(const char* code, unsigned int len, D3DBlob** blob)
|
|||
#else
|
||||
UINT flags = D3D10_SHADER_OPTIMIZATION_LEVEL3;
|
||||
#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);
|
||||
|
||||
if (errorBuffer)
|
||||
{
|
||||
INFO_LOG(VIDEO, "Pixel shader compiler messages:\n%s",
|
||||
(const char*)errorBuffer->GetBufferPointer());
|
||||
}
|
||||
|
||||
if (FAILED(hr) || errorBuffer)
|
||||
if (FAILED(hr))
|
||||
{
|
||||
if (g_ActiveConfig.bShowShaderErrors)
|
||||
{
|
||||
|
@ -121,6 +134,7 @@ bool CompilePixelShader(const char* code, unsigned int len, D3DBlob** blob)
|
|||
*blob = new D3DBlob(shaderBuffer);
|
||||
shaderBuffer->Release();
|
||||
}
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "D3DBase.h"
|
||||
#include "D3DBlob.h"
|
||||
|
||||
struct ID3D11PixelShader;
|
||||
|
@ -32,7 +33,7 @@ namespace D3D
|
|||
|
||||
// The returned bytecode buffers should be Release()d.
|
||||
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
|
||||
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 "TextureCache.h"
|
||||
#include "VertexShaderCache.h"
|
||||
#include "TextureEncoder.h"
|
||||
#include "PSTextureEncoder.h"
|
||||
#include "HW/Memmap.h"
|
||||
#include "VideoConfig.h"
|
||||
|
||||
namespace DX11
|
||||
{
|
||||
|
||||
#define MAX_COPY_BUFFERS 25
|
||||
ID3D11Buffer* efbcopycbuf[MAX_COPY_BUFFERS] = {};
|
||||
static TextureEncoder* g_encoder = NULL;
|
||||
const size_t MAX_COPY_BUFFERS = 25;
|
||||
ID3D11Buffer* efbcopycbuf[MAX_COPY_BUFFERS] = { 0 };
|
||||
|
||||
TextureCache::TCacheEntry::~TCacheEntry()
|
||||
{
|
||||
|
@ -92,48 +97,70 @@ TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width,
|
|||
return entry;
|
||||
}
|
||||
|
||||
void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
||||
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect,
|
||||
bool bIsIntensityFmt, u32 copyfmt)
|
||||
void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
|
||||
unsigned int srcFormat, const EFBRectangle& srcRect,
|
||||
bool isIntensity, bool scaleByHalf, unsigned int cbufid,
|
||||
const float *colmat)
|
||||
{
|
||||
g_renderer->ResetAPIState();
|
||||
// stretch picture with increased internal resolution
|
||||
const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)virtualW, (float)virtualH);
|
||||
D3D::context->RSSetViewports(1, &vp);
|
||||
|
||||
// set transformation
|
||||
if (NULL == efbcopycbuf[cbufid])
|
||||
if (!isDynamic || g_ActiveConfig.bCopyEFBToTexture)
|
||||
{
|
||||
const D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(28 * sizeof(float), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT);
|
||||
D3D11_SUBRESOURCE_DATA data;
|
||||
data.pSysMem = colmat;
|
||||
HRESULT hr = D3D::device->CreateBuffer(&cbdesc, &data, &efbcopycbuf[cbufid]);
|
||||
CHECK(SUCCEEDED(hr), "Create efb copy constant buffer %d", cbufid);
|
||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)efbcopycbuf[cbufid], "a constant buffer used in TextureCache::CopyRenderTargetToTexture");
|
||||
}
|
||||
D3D::context->PSSetConstantBuffers(0, 1, &efbcopycbuf[cbufid]);
|
||||
g_renderer->ResetAPIState();
|
||||
|
||||
const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(source_rect);
|
||||
// TODO: try targetSource.asRECT();
|
||||
const D3D11_RECT sourcerect = CD3D11_RECT(targetSource.left, targetSource.top, targetSource.right, targetSource.bottom);
|
||||
// stretch picture with increased internal resolution
|
||||
const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)virtualW, (float)virtualH);
|
||||
D3D::context->RSSetViewports(1, &vp);
|
||||
|
||||
// Use linear filtering if (bScaleByHalf), use point filtering otherwise
|
||||
if (bScaleByHalf)
|
||||
D3D::SetLinearCopySampler();
|
||||
else
|
||||
D3D::SetPointCopySampler();
|
||||
// set transformation
|
||||
if (NULL == efbcopycbuf[cbufid])
|
||||
{
|
||||
const D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(28 * sizeof(float), D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT);
|
||||
D3D11_SUBRESOURCE_DATA data;
|
||||
data.pSysMem = colmat;
|
||||
HRESULT hr = D3D::device->CreateBuffer(&cbdesc, &data, &efbcopycbuf[cbufid]);
|
||||
CHECK(SUCCEEDED(hr), "Create efb copy constant buffer %d", cbufid);
|
||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)efbcopycbuf[cbufid], "a constant buffer used in TextureCache::CopyRenderTargetToTexture");
|
||||
}
|
||||
D3D::context->PSSetConstantBuffers(0, 1, &efbcopycbuf[cbufid]);
|
||||
|
||||
D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), NULL);
|
||||
const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect);
|
||||
// TODO: try targetSource.asRECT();
|
||||
const D3D11_RECT sourcerect = CD3D11_RECT(targetSource.left, targetSource.top, targetSource.right, targetSource.bottom);
|
||||
|
||||
D3D::drawShadedTexQuad(
|
||||
(bFromZBuffer) ? FramebufferManager::GetEFBDepthTexture()->GetSRV() : FramebufferManager::GetEFBColorTexture()->GetSRV(),
|
||||
&sourcerect, Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(),
|
||||
(bFromZBuffer) ? PixelShaderCache::GetDepthMatrixProgram(true) : PixelShaderCache::GetColorMatrixProgram(true),
|
||||
VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
||||
// Use linear filtering if (bScaleByHalf), use point filtering otherwise
|
||||
if (scaleByHalf)
|
||||
D3D::SetLinearCopySampler();
|
||||
else
|
||||
D3D::SetPointCopySampler();
|
||||
|
||||
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
||||
D3D::context->OMSetRenderTargets(1, &texture->GetRTV(), NULL);
|
||||
|
||||
// Create texture copy
|
||||
D3D::drawShadedTexQuad(
|
||||
(srcFormat == PIXELFMT_Z24) ? FramebufferManager::GetEFBDepthTexture()->GetSRV() : FramebufferManager::GetEFBColorTexture()->GetSRV(),
|
||||
&sourcerect, Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(),
|
||||
(srcFormat == PIXELFMT_Z24) ? PixelShaderCache::GetDepthMatrixProgram(true) : PixelShaderCache::GetColorMatrixProgram(true),
|
||||
VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
|
||||
|
||||
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
||||
|
||||
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(
|
||||
|
@ -146,12 +173,19 @@ TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture(
|
|||
|
||||
TextureCache::TextureCache()
|
||||
{
|
||||
// FIXME: Is it safe here?
|
||||
g_encoder = new PSTextureEncoder;
|
||||
g_encoder->Init();
|
||||
}
|
||||
|
||||
TextureCache::~TextureCache()
|
||||
{
|
||||
for (unsigned int k = 0; k < MAX_COPY_BUFFERS; ++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,
|
||||
unsigned int expanded_width, unsigned int levels, bool autogen_mips = false);
|
||||
|
||||
void FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
||||
unsigned int cbufid, const float* colmat, const EFBRectangle &source_rect,
|
||||
bool bIsIntensityFmt, u32 copyfmt);
|
||||
void FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
|
||||
unsigned int srcFormat, const EFBRectangle& srcRect,
|
||||
bool isIntensity, bool scaleByHalf, unsigned int cbufid,
|
||||
const float *colmat);
|
||||
|
||||
void Bind(unsigned int stage);
|
||||
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.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.bSupports3DVision = false;
|
||||
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
|
||||
}
|
||||
|
||||
void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
||||
unsigned int cbufid, const float *colmat, const EFBRectangle &source_rect,
|
||||
bool bIsIntensityFmt, u32 copyfmt)
|
||||
void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
|
||||
unsigned int srcFormat, const EFBRectangle& srcRect,
|
||||
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::GetEFBColorTexture();
|
||||
|
||||
|
@ -101,16 +102,16 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB
|
|||
destrect.top = 0;
|
||||
|
||||
PixelShaderManager::SetColorMatrix(colmat); // set transformation
|
||||
TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(source_rect);
|
||||
TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect);
|
||||
RECT sourcerect;
|
||||
sourcerect.bottom = targetSource.bottom;
|
||||
sourcerect.left = targetSource.left;
|
||||
sourcerect.right = targetSource.right;
|
||||
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_MAGFILTER, D3DTEXF_LINEAR);
|
||||
|
@ -134,7 +135,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB
|
|||
Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(),
|
||||
virtualW, virtualH,
|
||||
// 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));
|
||||
|
||||
Rendersurf->Release();
|
||||
|
@ -147,11 +148,11 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB
|
|||
read_texture,
|
||||
Renderer::GetFullTargetWidth(),
|
||||
Renderer::GetFullTargetHeight(),
|
||||
bFromZBuffer,
|
||||
bIsIntensityFmt,
|
||||
copyfmt,
|
||||
bScaleByHalf,
|
||||
source_rect);
|
||||
srcFormat == PIXELFMT_Z24,
|
||||
isIntensity,
|
||||
dstFormat,
|
||||
scaleByHalf,
|
||||
srcRect);
|
||||
}
|
||||
|
||||
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
|
||||
|
|
|
@ -46,9 +46,10 @@ private:
|
|||
void Load(unsigned int width, unsigned int height,
|
||||
unsigned int expanded_width, unsigned int levels, bool autogen_mips = false);
|
||||
|
||||
void FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
||||
unsigned int cbufid, const float* colmat, const EFBRectangle &source_rect,
|
||||
bool bIsIntensityFmt, u32 copyfmt);
|
||||
void FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
|
||||
unsigned int srcFormat, const EFBRectangle& srcRect,
|
||||
bool isIntensity, bool scaleByHalf, unsigned int cbufid,
|
||||
const float *colmat);
|
||||
|
||||
void Bind(unsigned int stage);
|
||||
bool Save(const char filename[]);
|
||||
|
|
|
@ -264,16 +264,17 @@ TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture(
|
|||
return entry;
|
||||
}
|
||||
|
||||
void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
||||
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect,
|
||||
bool bIsIntensityFmt, u32 copyfmt)
|
||||
void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
|
||||
unsigned int srcFormat, const EFBRectangle& srcRect,
|
||||
bool isIntensity, bool scaleByHalf, unsigned int cbufid,
|
||||
const float *colmat)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
// Make sure to resolve anything we need to read from.
|
||||
const GLuint read_texture = bFromZBuffer ?
|
||||
FramebufferManager::ResolveAndGetDepthTarget(source_rect) :
|
||||
FramebufferManager::ResolveAndGetRenderTarget(source_rect);
|
||||
const GLuint read_texture = (srcFormat == PIXELFMT_Z24) ?
|
||||
FramebufferManager::ResolveAndGetDepthTarget(srcRect) :
|
||||
FramebufferManager::ResolveAndGetRenderTarget(srcRect);
|
||||
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
|
@ -295,11 +296,11 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB
|
|||
|
||||
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
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(source_rect);
|
||||
TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
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(
|
||||
addr,
|
||||
read_texture,
|
||||
bFromZBuffer,
|
||||
bIsIntensityFmt,
|
||||
copyfmt,
|
||||
bScaleByHalf,
|
||||
source_rect);
|
||||
srcFormat == PIXELFMT_Z24,
|
||||
isIntensity,
|
||||
dstFormat,
|
||||
scaleByHalf,
|
||||
srcRect);
|
||||
}
|
||||
|
||||
FramebufferManager::SetFramebuffer(0);
|
||||
|
|
|
@ -56,9 +56,10 @@ private:
|
|||
void Load(unsigned int width, unsigned int height,
|
||||
unsigned int expanded_width, unsigned int level, bool autogen_mips = false);
|
||||
|
||||
void FromRenderTarget(bool bFromZBuffer, bool bScaleByHalf,
|
||||
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect,
|
||||
bool bIsIntensityFmt, u32 copyfmt);
|
||||
void FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
|
||||
unsigned int srcFormat, const EFBRectangle& srcRect,
|
||||
bool isIntensity, bool scaleByHalf, unsigned int cbufid,
|
||||
const float *colmat);
|
||||
|
||||
void Bind(unsigned int stage);
|
||||
bool Save(const char filename[]);
|
||||
|
|
Loading…
Reference in New Issue