Main change: Implemented EFB pokes in DX9/DX11.
Games affected by this change: Mario Smash Football, Mario Strikers Charged Football, Monster Hunter Tri. Other games possibly affected: Shaun White Snowboarding, Resident Evil Code: Veronica, Baten Kaitos. This implementation will decrease performance if the game uses this feature, but the glitches will be gone. I'll add an option for this in a later commit. EFB pokes are somewhat slow in DX11 right now, speed should be okayish in DX9 though. Other changes: - SOMEWHAT cleaned up the EFB access code in DX9 - Fixed incompatible parameter list of AccessEFB and TVideo_AccessEFB. - Fixed a theoretical bug in ReplaceRGBATexture2D, add support for STAGING textures - Removed unused parameters in various DX9 functions git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6300 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
e9d115a8b1
commit
ef75d96655
|
@ -79,7 +79,7 @@ public:
|
||||||
|
|
||||||
static TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc);
|
static TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc);
|
||||||
|
|
||||||
static u32 AccessEFB(EFBAccessType type, int x, int y);
|
static u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data);
|
||||||
|
|
||||||
// Random utilities
|
// Random utilities
|
||||||
static void RenderText(const char* pstr, int left, int top, u32 color);
|
static void RenderText(const char* pstr, int left, int top, u32 color);
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace D3D
|
||||||
|
|
||||||
void ReplaceRGBATexture2D(ID3D11Texture2D* pTexture, const u8* buffer, unsigned int width, unsigned int height, unsigned int pitch, unsigned int level, D3D11_USAGE usage)
|
void ReplaceRGBATexture2D(ID3D11Texture2D* pTexture, const u8* buffer, unsigned int width, unsigned int height, unsigned int pitch, unsigned int level, D3D11_USAGE usage)
|
||||||
{
|
{
|
||||||
if (usage == D3D11_USAGE_DYNAMIC)
|
if (usage == D3D11_USAGE_DYNAMIC || usage == D3D11_USAGE_STAGING)
|
||||||
{
|
{
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
D3D::context->Map(pTexture, level, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
D3D::context->Map(pTexture, level, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||||
|
@ -35,7 +35,7 @@ void ReplaceRGBATexture2D(ID3D11Texture2D* pTexture, const u8* buffer, unsigned
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (unsigned int y = 0; y < height; ++y)
|
for (unsigned int y = 0; y < height; ++y)
|
||||||
memcpy((u8*)map.pData + y * map.RowPitch, (u32*)buffer + y * pitch, map.RowPitch);
|
memcpy((u8*)map.pData + y * map.RowPitch, (u32*)buffer + y * pitch, 4 * pitch);
|
||||||
}
|
}
|
||||||
D3D::context->Unmap(pTexture, level);
|
D3D::context->Unmap(pTexture, level);
|
||||||
}
|
}
|
||||||
|
|
|
@ -429,11 +429,13 @@ ID3D11SamplerState* linear_copy_sampler = NULL;
|
||||||
ID3D11SamplerState* point_copy_sampler = NULL;
|
ID3D11SamplerState* point_copy_sampler = NULL;
|
||||||
ID3D11Buffer* stqvb = NULL;
|
ID3D11Buffer* stqvb = NULL;
|
||||||
ID3D11Buffer* stsqvb = NULL;
|
ID3D11Buffer* stsqvb = NULL;
|
||||||
|
ID3D11Buffer* quadvb = NULL;
|
||||||
ID3D11Buffer* clearvb = NULL;
|
ID3D11Buffer* clearvb = NULL;
|
||||||
|
|
||||||
typedef struct { float x,y,z,u,v; } STQVertex;
|
typedef struct { float x,y,z,u,v; } STQVertex;
|
||||||
typedef struct { float x,y,z,u,v; } STSQVertex;
|
typedef struct { float x,y,z,u,v; } STSQVertex;
|
||||||
typedef struct { float x,y,z; u32 col; } ClearVertex;
|
typedef struct { float x,y,z; u32 col; } ClearVertex;
|
||||||
|
typedef struct { float x,y,z; u32 col; } ColVertex;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -446,6 +448,12 @@ struct
|
||||||
float u1, v1, u2, v2;
|
float u1, v1, u2, v2;
|
||||||
} tex_sub_quad_data;
|
} tex_sub_quad_data;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
float x1, y1, x2, y2;
|
||||||
|
u32 col;
|
||||||
|
} draw_quad_data;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
u32 col;
|
u32 col;
|
||||||
|
@ -468,6 +476,7 @@ void InitUtils()
|
||||||
// cached data used to avoid unnecessarily reloading the vertex buffers
|
// cached data used to avoid unnecessarily reloading the vertex buffers
|
||||||
memset(&tex_quad_data, 0, sizeof(tex_quad_data));
|
memset(&tex_quad_data, 0, sizeof(tex_quad_data));
|
||||||
memset(&tex_sub_quad_data, 0, sizeof(tex_sub_quad_data));
|
memset(&tex_sub_quad_data, 0, sizeof(tex_sub_quad_data));
|
||||||
|
memset(&draw_quad_data, 0, sizeof(draw_quad_data));
|
||||||
memset(&clear_quad_data, 0, sizeof(clear_quad_data));
|
memset(&clear_quad_data, 0, sizeof(clear_quad_data));
|
||||||
|
|
||||||
STQVertex stqcoords[4] = {
|
STQVertex stqcoords[4] = {
|
||||||
|
@ -480,6 +489,9 @@ void InitUtils()
|
||||||
STSQVertex stsqcoords[4];
|
STSQVertex stsqcoords[4];
|
||||||
memset(stsqcoords, 0, sizeof(stsqcoords));
|
memset(stsqcoords, 0, sizeof(stsqcoords));
|
||||||
|
|
||||||
|
ColVertex colcoords[4];
|
||||||
|
memset(colcoords, 0, sizeof(colcoords));
|
||||||
|
|
||||||
ClearVertex cqcoords[4] = {
|
ClearVertex cqcoords[4] = {
|
||||||
{-1.0f, 1.0f, 0, 0},
|
{-1.0f, 1.0f, 0, 0},
|
||||||
{ 1.0f, 1.0f, 0, 0},
|
{ 1.0f, 1.0f, 0, 0},
|
||||||
|
@ -495,6 +507,10 @@ void InitUtils()
|
||||||
CHECK(stsqvb!=NULL, "Create vertex buffer of drawShadedTexSubQuad");
|
CHECK(stsqvb!=NULL, "Create vertex buffer of drawShadedTexSubQuad");
|
||||||
SetDebugObjectName((ID3D11DeviceChild*)stsqvb, "vertex buffer of drawShadedTexSubQuad");
|
SetDebugObjectName((ID3D11DeviceChild*)stsqvb, "vertex buffer of drawShadedTexSubQuad");
|
||||||
|
|
||||||
|
quadvb = CreateQuadVertexBuffer(4*sizeof(ColVertex), colcoords);
|
||||||
|
CHECK(quadvb!=NULL, "Create vertex buffer of drawColorQuad");
|
||||||
|
SetDebugObjectName((ID3D11DeviceChild*)quadvb, "vertex buffer of drawColorQuad");
|
||||||
|
|
||||||
clearvb = CreateQuadVertexBuffer(4*sizeof(ClearVertex), cqcoords);
|
clearvb = CreateQuadVertexBuffer(4*sizeof(ClearVertex), cqcoords);
|
||||||
CHECK(clearvb!=NULL, "Create vertex buffer of drawClearQuad");
|
CHECK(clearvb!=NULL, "Create vertex buffer of drawClearQuad");
|
||||||
SetDebugObjectName((ID3D11DeviceChild*)clearvb, "vertex buffer of drawClearQuad");
|
SetDebugObjectName((ID3D11DeviceChild*)clearvb, "vertex buffer of drawClearQuad");
|
||||||
|
@ -509,6 +525,7 @@ void ShutdownUtils()
|
||||||
SAFE_RELEASE(linear_copy_sampler);
|
SAFE_RELEASE(linear_copy_sampler);
|
||||||
SAFE_RELEASE(stqvb);
|
SAFE_RELEASE(stqvb);
|
||||||
SAFE_RELEASE(stsqvb);
|
SAFE_RELEASE(stsqvb);
|
||||||
|
SAFE_RELEASE(quadvb);
|
||||||
SAFE_RELEASE(clearvb);
|
SAFE_RELEASE(clearvb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -627,6 +644,45 @@ void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
|
||||||
context->PSSetShaderResources(0, 1, &texres); // immediately unbind the texture
|
context->PSSetShaderResources(0, 1, &texres); // immediately unbind the texture
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fills a certain area of the current render target with the specified color
|
||||||
|
// destination coordinates normalized to (-1;1)
|
||||||
|
void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2)
|
||||||
|
{
|
||||||
|
if(draw_quad_data.x1 != x1 || draw_quad_data.y1 != y1 ||
|
||||||
|
draw_quad_data.x2 != x2 || draw_quad_data.y2 != y2 ||
|
||||||
|
draw_quad_data.col != Color)
|
||||||
|
{
|
||||||
|
ColVertex coords[4] = {
|
||||||
|
{ x1, y2, 0.f, Color },
|
||||||
|
{ x2, y2, 0.f, Color },
|
||||||
|
{ x1, y1, 0.f, Color },
|
||||||
|
{ x2, y1, 0.f, Color },
|
||||||
|
};
|
||||||
|
|
||||||
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
|
context->Map(quadvb, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||||
|
memcpy(map.pData, coords, sizeof(coords));
|
||||||
|
context->Unmap(quadvb, 0);
|
||||||
|
|
||||||
|
draw_quad_data.x1 = x1;
|
||||||
|
draw_quad_data.y1 = y1;
|
||||||
|
draw_quad_data.x2 = x2;
|
||||||
|
draw_quad_data.y2 = y2;
|
||||||
|
draw_quad_data.col = Color;
|
||||||
|
}
|
||||||
|
|
||||||
|
context->VSSetShader(VertexShaderCache::GetClearVertexShader(), NULL, 0);
|
||||||
|
context->PSSetShader(PixelShaderCache::GetClearProgram(), NULL, 0);
|
||||||
|
context->IASetInputLayout(VertexShaderCache::GetClearInputLayout());
|
||||||
|
|
||||||
|
UINT stride = sizeof(ColVertex);
|
||||||
|
UINT offset = 0;
|
||||||
|
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||||
|
context->IASetVertexBuffers(0, 1, &quadvb, &stride, &offset);
|
||||||
|
|
||||||
|
context->Draw(4, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout)
|
void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout)
|
||||||
{
|
{
|
||||||
if (clear_quad_data.col != Color || clear_quad_data.z != z)
|
if (clear_quad_data.col != Color || clear_quad_data.z != z)
|
||||||
|
@ -657,5 +713,4 @@ void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexS
|
||||||
context->Draw(4, 0);
|
context->Draw(4, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -80,6 +80,5 @@ namespace D3D
|
||||||
ID3D11VertexShader* Vshader,
|
ID3D11VertexShader* Vshader,
|
||||||
ID3D11InputLayout* layout);
|
ID3D11InputLayout* layout);
|
||||||
void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout);
|
void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout);
|
||||||
void SaveRenderStates();
|
void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2);
|
||||||
void RestoreRenderStates();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -594,19 +594,19 @@ void Renderer::SetColorMask()
|
||||||
D3D::gfxstate->SetRenderTargetWriteMask(color_mask);
|
D3D::gfxstate->SetRenderTargetWriteMask(color_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||||
{
|
{
|
||||||
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
ID3D11Texture2D* read_tex;
|
ID3D11Texture2D* read_tex;
|
||||||
u32 ret = 0;
|
|
||||||
|
|
||||||
if (!g_ActiveConfig.bEFBAccessEnable)
|
if (!g_ActiveConfig.bEFBAccessEnable)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (type == POKE_Z || type == POKE_COLOR)
|
if (type == POKE_Z)
|
||||||
{
|
{
|
||||||
static bool alert_only_once = true;
|
static bool alert_only_once = true;
|
||||||
if (!alert_only_once) return 0;
|
if (!alert_only_once) return 0;
|
||||||
PanicAlert("Poke EFB not implemented");
|
PanicAlert("EFB: Poke Z not implemented (tried to poke z value %#x at (%d,%d))", poke_data, x, y);
|
||||||
alert_only_once = false;
|
alert_only_once = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -619,12 +619,23 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
efbPixelRc.bottom = y + 1;
|
efbPixelRc.bottom = y + 1;
|
||||||
TargetRectangle targetPixelRc = Renderer::ConvertEFBRectangle(efbPixelRc);
|
TargetRectangle targetPixelRc = Renderer::ConvertEFBRectangle(efbPixelRc);
|
||||||
|
|
||||||
// Take the mean of the resulting dimensions; TODO: check whether this causes any bugs compared to taking the average color of the target area
|
// Take the mean of the resulting dimensions; TODO: Don't use the center pixel, compute the average color instead
|
||||||
D3D11_RECT RectToLock;
|
D3D11_RECT RectToLock;
|
||||||
RectToLock.left = (targetPixelRc.left + targetPixelRc.right) / 2;
|
if(type == PEEK_COLOR || type == PEEK_Z)
|
||||||
RectToLock.top = (targetPixelRc.top + targetPixelRc.bottom) / 2;
|
{
|
||||||
RectToLock.right = RectToLock.left + 1;
|
RectToLock.left = (targetPixelRc.left + targetPixelRc.right) / 2;
|
||||||
RectToLock.bottom = RectToLock.top + 1;
|
RectToLock.top = (targetPixelRc.top + targetPixelRc.bottom) / 2;
|
||||||
|
RectToLock.right = RectToLock.left + 1;
|
||||||
|
RectToLock.bottom = RectToLock.top + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RectToLock.left = targetPixelRc.left;
|
||||||
|
RectToLock.right = targetPixelRc.right;
|
||||||
|
RectToLock.top = targetPixelRc.top;
|
||||||
|
RectToLock.bottom = targetPixelRc.bottom;
|
||||||
|
}
|
||||||
|
|
||||||
if (type == PEEK_Z)
|
if (type == PEEK_Z)
|
||||||
{
|
{
|
||||||
ResetAPIState(); // Reset any game specific settings
|
ResetAPIState(); // Reset any game specific settings
|
||||||
|
@ -651,40 +662,59 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
D3D::context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, g_framebufferManager.GetEFBDepthReadTexture()->GetTex(), 0, &box);
|
D3D::context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, g_framebufferManager.GetEFBDepthReadTexture()->GetTex(), 0, &box);
|
||||||
|
|
||||||
RestoreAPIState(); // restore game state
|
RestoreAPIState(); // restore game state
|
||||||
|
|
||||||
|
// read the data from system memory
|
||||||
|
D3D::context->Map(read_tex, 0, D3D11_MAP_READ, 0, &map);
|
||||||
|
|
||||||
|
float val = *(float*)map.pData;
|
||||||
|
u32 ret = ((u32)(val * 0xffffff));
|
||||||
|
D3D::context->Unmap(read_tex, 0);
|
||||||
|
|
||||||
|
// TODO: in RE0 this value is often off by one in Video_DX9 (where this code is derived from), which causes lighting to disappear
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
else
|
else if (type == PEEK_COLOR)
|
||||||
{
|
{
|
||||||
// we can directly copy to system memory here
|
// we can directly copy to system memory here
|
||||||
read_tex = g_framebufferManager.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, g_framebufferManager.GetEFBColorTexture()->GetTex(), 0, &box);
|
D3D::context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, g_framebufferManager.GetEFBColorTexture()->GetTex(), 0, &box);
|
||||||
|
|
||||||
|
// read the data from system memory
|
||||||
|
D3D::context->Map(read_tex, 0, D3D11_MAP_READ, 0, &map);
|
||||||
|
u32 ret = *(u32*)map.pData;
|
||||||
|
D3D::context->Unmap(read_tex, 0);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
else //if(type == POKE_COLOR)
|
||||||
// read the data from system memory
|
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
|
||||||
D3D::context->Map(read_tex, 0, D3D11_MAP_READ, 0, &map);
|
|
||||||
|
|
||||||
switch(type)
|
|
||||||
{
|
{
|
||||||
case PEEK_Z:
|
// TODO: Speed this up by batching pokes?
|
||||||
|
// If we're only writing one pixel (native resolution), we can directly copy the data into the target. TODO: Check if this is faster than drawing quads
|
||||||
|
u32 rgbaColor = (poke_data & 0xFF00FF00) | ((poke_data >> 16) & 0xFF) | ((poke_data << 16) & 0xFF0000);
|
||||||
|
if(RectToLock.right <= RectToLock.left + 1 && RectToLock.bottom <= RectToLock.top + 1)
|
||||||
{
|
{
|
||||||
float val = *(float*)map.pData;
|
D3D::context->Map(g_framebufferManager.GetEFBColorStagingBuffer(), 0, D3D11_MAP_WRITE, 0, &map);
|
||||||
ret = ((u32)(val * 0xffffff));
|
*(u32*)map.pData = rgbaColor;
|
||||||
break;
|
D3D::context->Unmap(g_framebufferManager.GetEFBColorStagingBuffer(), 0);
|
||||||
|
|
||||||
|
D3D11_BOX box = CD3D11_BOX(0, 0, 0, 1, 1, 1);
|
||||||
|
D3D::context->CopySubresourceRegion(g_framebufferManager.GetEFBColorTexture()->GetTex(), 0, RectToLock.left, RectToLock.top, 0, g_framebufferManager.GetEFBColorStagingBuffer(), 0, &box);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ResetAPIState(); // Reset any game specific settings
|
||||||
|
|
||||||
case PEEK_COLOR:
|
D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBColorTexture()->GetRTV(), NULL);
|
||||||
ret = *(u32*)map.pData;
|
D3D::drawColorQuad(rgbaColor, (float)RectToLock.left * 2.f / (float)Renderer::GetFullTargetWidth() - 1.f,
|
||||||
break;
|
- (float)RectToLock.top * 2.f / (float)Renderer::GetFullTargetHeight() + 1.f,
|
||||||
|
(float)RectToLock.right * 2.f / (float)Renderer::GetFullTargetWidth() - 1.f,
|
||||||
|
- (float)RectToLock.bottom * 2.f / (float)Renderer::GetFullTargetHeight() + 1.f);
|
||||||
|
|
||||||
default:
|
RestoreAPIState();
|
||||||
// TODO: Implement POKE_Z and POKE_COLOR
|
return 0;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D::context->Unmap(read_tex, 0);
|
|
||||||
// TODO: in RE0 this value is often off by one in Video_DX9 (where this code is derived from), which causes lighting to disappear
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from VertexShaderManager
|
// Called from VertexShaderManager
|
||||||
|
|
|
@ -378,7 +378,7 @@ void VideoFifo_CheckEFBAccess()
|
||||||
{
|
{
|
||||||
if (Common::AtomicLoadAcquire(s_efbAccessRequested))
|
if (Common::AtomicLoadAcquire(s_efbAccessRequested))
|
||||||
{
|
{
|
||||||
s_AccessEFBResult = Renderer::AccessEFB(s_accessEFBArgs.type, s_accessEFBArgs.x, s_accessEFBArgs.y);
|
s_AccessEFBResult = Renderer::AccessEFB(s_accessEFBArgs.type, s_accessEFBArgs.x, s_accessEFBArgs.y, s_accessEFBArgs.Data);
|
||||||
|
|
||||||
Common::AtomicStoreRelease(s_efbAccessRequested, FALSE);
|
Common::AtomicStoreRelease(s_efbAccessRequested, FALSE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include "D3DBase.h"
|
#include "D3DBase.h"
|
||||||
#include "D3DUtil.h"
|
#include "D3DUtil.h"
|
||||||
#include "Render.h"
|
#include "Render.h"
|
||||||
|
#include "PixelShaderCache.h"
|
||||||
|
#include "VertexShaderCache.h"
|
||||||
|
|
||||||
namespace D3D
|
namespace D3D
|
||||||
{
|
{
|
||||||
|
@ -423,6 +425,23 @@ void drawShadedTexSubQuad(IDirect3DTexture9 *texture,
|
||||||
RestoreShaders();
|
RestoreShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fills a certain area of the current render target with the specified color
|
||||||
|
// Z buffer disabled; destination coordinates normalized to (-1;1)
|
||||||
|
void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2)
|
||||||
|
{
|
||||||
|
struct CQVertex { float x, y, z, rhw; u32 col; } coords[4] = {
|
||||||
|
{ x1, y2, 0.f, 1.f, Color },
|
||||||
|
{ x2, y2, 0.f, 1.f, Color },
|
||||||
|
{ x1, y1, 0.f, 1.f, Color },
|
||||||
|
{ x2, y1, 0.f, 1.f, Color },
|
||||||
|
};
|
||||||
|
dev->SetVertexShader(VertexShaderCache::GetClearVertexShader());
|
||||||
|
dev->SetPixelShader(PixelShaderCache::GetClearProgram());
|
||||||
|
dev->SetFVF(D3DFVF_XYZW | D3DFVF_DIFFUSE);
|
||||||
|
dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(CQVertex));
|
||||||
|
RestoreShaders();
|
||||||
|
}
|
||||||
|
|
||||||
void drawClearQuad(u32 Color,float z,IDirect3DPixelShader9 *PShader,IDirect3DVertexShader9 *Vshader)
|
void drawClearQuad(u32 Color,float z,IDirect3DPixelShader9 *PShader,IDirect3DVertexShader9 *Vshader)
|
||||||
{
|
{
|
||||||
struct Q2DVertex { float x,y,z,rhw;u32 color;} coords[4] = {
|
struct Q2DVertex { float x,y,z,rhw;u32 color;} coords[4] = {
|
||||||
|
|
|
@ -77,7 +77,9 @@ namespace D3D
|
||||||
int DestHeight,
|
int DestHeight,
|
||||||
IDirect3DPixelShader9 *PShader,
|
IDirect3DPixelShader9 *PShader,
|
||||||
IDirect3DVertexShader9 *Vshader);
|
IDirect3DVertexShader9 *Vshader);
|
||||||
void drawClearQuad(u32 Color,float z,IDirect3DPixelShader9 *PShader,IDirect3DVertexShader9 *Vshader);
|
void drawClearQuad(u32 Color, float z, IDirect3DPixelShader9 *PShader, IDirect3DVertexShader9 *Vshader);
|
||||||
|
void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2);
|
||||||
|
|
||||||
void SaveRenderStates();
|
void SaveRenderStates();
|
||||||
void RestoreRenderStates();
|
void RestoreRenderStates();
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,12 +73,12 @@ D3DFORMAT FramebufferManager::GetEFBColorRTSurfaceFormat()
|
||||||
return s_efb_color_surface_Format;
|
return s_efb_color_surface_Format;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPDIRECT3DTEXTURE9 FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc)
|
LPDIRECT3DTEXTURE9 FramebufferManager::GetEFBColorTexture()
|
||||||
{
|
{
|
||||||
return s_efb_color_texture;
|
return s_efb_color_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPDIRECT3DTEXTURE9 FramebufferManager::GetEFBDepthTexture(const EFBRectangle &sourceRc)
|
LPDIRECT3DTEXTURE9 FramebufferManager::GetEFBDepthTexture()
|
||||||
{
|
{
|
||||||
return s_efb_depth_texture;
|
return s_efb_depth_texture;
|
||||||
}
|
}
|
||||||
|
@ -305,7 +305,7 @@ void FramebufferManager::copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, c
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc);
|
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc);
|
||||||
TextureConverter::EncodeToRamYUYV(GetEFBColorTexture(sourceRc), targetRc, xfb_in_ram, fbWidth, fbHeight);
|
TextureConverter::EncodeToRamYUYV(GetEFBColorTexture(), targetRc, xfb_in_ram, 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)
|
||||||
|
@ -395,7 +395,7 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
|
||||||
// Copy EFB data to XFB and restore render target again
|
// 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();
|
||||||
|
|
||||||
Renderer::ResetAPIState(); // Reset any game specific settings
|
Renderer::ResetAPIState(); // Reset any game specific settings
|
||||||
LPDIRECT3DSURFACE9 Rendersurf = NULL;
|
LPDIRECT3DSURFACE9 Rendersurf = NULL;
|
||||||
|
|
|
@ -109,8 +109,8 @@ public:
|
||||||
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();
|
||||||
LPDIRECT3DTEXTURE9 GetEFBDepthTexture(const EFBRectangle& sourceRc);
|
LPDIRECT3DTEXTURE9 GetEFBDepthTexture();
|
||||||
|
|
||||||
LPDIRECT3DSURFACE9 GetEFBColorRTSurface();
|
LPDIRECT3DSURFACE9 GetEFBColorRTSurface();
|
||||||
LPDIRECT3DSURFACE9 GetEFBDepthRTSurface();
|
LPDIRECT3DSURFACE9 GetEFBDepthRTSurface();
|
||||||
|
|
|
@ -691,46 +691,45 @@ void Renderer::SetColorMask()
|
||||||
D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask);
|
D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||||
{
|
{
|
||||||
if (!g_ActiveConfig.bEFBAccessEnable)
|
if (!g_ActiveConfig.bEFBAccessEnable)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (type == POKE_Z || type == POKE_COLOR)
|
if (type == POKE_Z)
|
||||||
{
|
{
|
||||||
static bool alert_only_once = true;
|
static bool alert_only_once = true;
|
||||||
if (!alert_only_once) return 0;
|
if (!alert_only_once) return 0;
|
||||||
PanicAlert("Poke EFB not implemented");
|
PanicAlert("EFB: Poke Z not implemented (tried to poke z value %#x at (%d,%d))", poke_data, x, y);
|
||||||
alert_only_once = false;
|
alert_only_once = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the working buffer
|
// We're using three surfaces here:
|
||||||
LPDIRECT3DSURFACE9 pBuffer = (type == PEEK_Z || type == POKE_Z) ?
|
// - pEFBSurf: EFB Surface. Source surface when peeking, destination surface when poking.
|
||||||
g_framebufferManager.GetEFBDepthRTSurface() : g_framebufferManager.GetEFBColorRTSurface();
|
// - pBufferRT: A render target surface. When peeking, we render a textured quad to this surface.
|
||||||
// Get the temporal buffer to move 1pixel data
|
// - pSystemBuf: An offscreen surface. Used to retrieve the pixel data from pBufferRT.
|
||||||
LPDIRECT3DSURFACE9 RBuffer = (type == PEEK_Z || type == POKE_Z) ?
|
LPDIRECT3DSURFACE9 pEFBSurf, pBufferRT, pSystemBuf;
|
||||||
g_framebufferManager.GetEFBDepthReadSurface() : g_framebufferManager.GetEFBColorReadSurface();
|
if(type == PEEK_Z || type == POKE_Z)
|
||||||
// Get the memory buffer that can be locked
|
{
|
||||||
LPDIRECT3DSURFACE9 pOffScreenBuffer = (type == PEEK_Z || type == POKE_Z) ?
|
pEFBSurf = g_framebufferManager.GetEFBDepthRTSurface();
|
||||||
g_framebufferManager.GetEFBDepthOffScreenRTSurface() : g_framebufferManager.GetEFBColorOffScreenRTSurface();
|
pBufferRT = g_framebufferManager.GetEFBDepthReadSurface();
|
||||||
// Get the buffer format
|
pSystemBuf = g_framebufferManager.GetEFBDepthOffScreenRTSurface();
|
||||||
D3DFORMAT BufferFormat = (type == PEEK_Z || type == POKE_Z) ?
|
}
|
||||||
g_framebufferManager.GetEFBDepthRTSurfaceFormat() : g_framebufferManager.GetEFBColorRTSurfaceFormat();
|
else //if(type == PEEK_COLOR || type == POKE_COLOR)
|
||||||
D3DFORMAT ReadBufferFormat = (type == PEEK_Z || type == POKE_Z) ?
|
{
|
||||||
g_framebufferManager.GetEFBDepthReadSurfaceFormat() : BufferFormat;
|
pEFBSurf = g_framebufferManager.GetEFBColorRTSurface();
|
||||||
|
pBufferRT = g_framebufferManager.GetEFBColorReadSurface();
|
||||||
if (BufferFormat == D3DFMT_D24X8)
|
pSystemBuf = g_framebufferManager.GetEFBColorOffScreenRTSurface();
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
D3DLOCKED_RECT drect;
|
|
||||||
|
|
||||||
// Buffer not found alert
|
// Buffer not found alert
|
||||||
if (!pBuffer) {
|
if (!pEFBSurf) {
|
||||||
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
|
|
||||||
|
// Convert EFB dimensions to the ones of our render target
|
||||||
EFBRectangle efbPixelRc;
|
EFBRectangle efbPixelRc;
|
||||||
efbPixelRc.left = x;
|
efbPixelRc.left = x;
|
||||||
efbPixelRc.top = y;
|
efbPixelRc.top = y;
|
||||||
|
@ -740,7 +739,6 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
TargetRectangle targetPixelRc = ConvertEFBRectangle(efbPixelRc);
|
TargetRectangle targetPixelRc = ConvertEFBRectangle(efbPixelRc);
|
||||||
|
|
||||||
u32 z = 0;
|
u32 z = 0;
|
||||||
float val = 0.0f;
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
RECT RectToLock;
|
RECT RectToLock;
|
||||||
RectToLock.bottom = targetPixelRc.bottom;
|
RectToLock.bottom = targetPixelRc.bottom;
|
||||||
|
@ -749,6 +747,9 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
RectToLock.top = targetPixelRc.top;
|
RectToLock.top = targetPixelRc.top;
|
||||||
if (type == PEEK_Z)
|
if (type == PEEK_Z)
|
||||||
{
|
{
|
||||||
|
if (g_framebufferManager.GetEFBDepthRTSurfaceFormat() == D3DFMT_D24X8)
|
||||||
|
return 0;
|
||||||
|
|
||||||
RECT PixelRect;
|
RECT PixelRect;
|
||||||
PixelRect.bottom = 4;
|
PixelRect.bottom = 4;
|
||||||
PixelRect.left = 0;
|
PixelRect.left = 0;
|
||||||
|
@ -764,131 +765,105 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
RectToLock.left++;
|
RectToLock.left++;
|
||||||
|
|
||||||
ResetAPIState(); // Reset any game specific settings
|
ResetAPIState(); // Reset any game specific settings
|
||||||
hr = D3D::dev->SetDepthStencilSurface(NULL);
|
D3D::dev->SetDepthStencilSurface(NULL);
|
||||||
hr = D3D::dev->SetRenderTarget(0, RBuffer);
|
D3D::dev->SetRenderTarget(0, pBufferRT);
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
PanicAlert("unable to set pixel render buffer");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
D3DVIEWPORT9 vp;
|
|
||||||
// Stretch picture with increased internal resolution
|
// Stretch picture with increased internal resolution
|
||||||
|
D3DVIEWPORT9 vp;
|
||||||
vp.X = 0;
|
vp.X = 0;
|
||||||
vp.Y = 0;
|
vp.Y = 0;
|
||||||
vp.Width = 4;
|
vp.Width = 4;
|
||||||
vp.Height = 4;
|
vp.Height = 4;
|
||||||
vp.MinZ = 0.0f;
|
vp.MinZ = 0.0f;
|
||||||
vp.MaxZ = 1.0f;
|
vp.MaxZ = 1.0f;
|
||||||
hr = D3D::dev->SetViewport(&vp);
|
D3D::dev->SetViewport(&vp);
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
PanicAlert("unable to set pixel viewport");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
float colmat[16] = {0.0f};
|
float colmat[16] = {0.0f};
|
||||||
float fConstAdd[4] = {0.0f};
|
float fConstAdd[4] = {0.0f};
|
||||||
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;
|
LPDIRECT3DTEXTURE9 read_texture = g_framebufferManager.GetEFBDepthTexture();
|
||||||
LPDIRECT3DTEXTURE9 read_texture = g_framebufferManager.GetEFBDepthTexture(source_rect);
|
|
||||||
|
|
||||||
D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
|
D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
|
||||||
|
|
||||||
D3D::drawShadedTexQuad(
|
D3D::drawShadedTexQuad(
|
||||||
read_texture,
|
read_texture,
|
||||||
&RectToLock,
|
&RectToLock,
|
||||||
Renderer::GetFullTargetWidth(),
|
Renderer::GetFullTargetWidth(),
|
||||||
Renderer::GetFullTargetHeight(),
|
Renderer::GetFullTargetHeight(),
|
||||||
4, 4,
|
4, 4,
|
||||||
(BufferFormat == FOURCC_RAWZ) ? PixelShaderCache::GetColorMatrixProgram(0) : PixelShaderCache::GetDepthMatrixProgram(0),
|
(g_framebufferManager.GetEFBDepthRTSurfaceFormat() == FOURCC_RAWZ) ? PixelShaderCache::GetColorMatrixProgram(0) : PixelShaderCache::GetDepthMatrixProgram(0),
|
||||||
VertexShaderCache::GetSimpleVertexShader(0));
|
VertexShaderCache::GetSimpleVertexShader(0));
|
||||||
|
|
||||||
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
|
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
|
||||||
|
|
||||||
hr = D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
|
D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
|
||||||
hr = D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
|
D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
|
||||||
RestoreAPIState();
|
RestoreAPIState();
|
||||||
|
|
||||||
|
// Retrieve the pixel data to the local memory buffer
|
||||||
RectToLock.bottom = 4;
|
RectToLock.bottom = 4;
|
||||||
RectToLock.left = 0;
|
RectToLock.left = 0;
|
||||||
RectToLock.right = 4;
|
RectToLock.right = 4;
|
||||||
RectToLock.top = 0;
|
RectToLock.top = 0;
|
||||||
|
D3D::dev->GetRenderTargetData(pBufferRT, pSystemBuf);
|
||||||
|
|
||||||
|
// EFB data successfully retrieved, now get the pixel data
|
||||||
|
D3DLOCKED_RECT drect;
|
||||||
|
pSystemBuf->LockRect(&drect, &RectToLock, D3DLOCK_READONLY);
|
||||||
|
|
||||||
|
float val = 0.0f;
|
||||||
|
|
||||||
|
switch (g_framebufferManager.GetEFBDepthReadSurfaceFormat())
|
||||||
|
{
|
||||||
|
case D3DFMT_R32F:
|
||||||
|
val = ((float*)drect.pBits)[6];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
float ffrac = 1.0f/255.0f;
|
||||||
|
z = ((u32*)drect.pBits)[6];
|
||||||
|
val = ((float)((z>>16) & 0xFF)) * ffrac;
|
||||||
|
ffrac*= 1 / 255.0f;
|
||||||
|
val += ((float)((z>>8) & 0xFF)) * ffrac;
|
||||||
|
ffrac*= 1 / 255.0f;
|
||||||
|
val += ((float)(z & 0xFF)) * ffrac;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
z = ((u32)(val * 0xffffff));
|
||||||
|
|
||||||
|
pSystemBuf->UnlockRect();
|
||||||
|
// TODO: in RE0 this value is often off by one, which causes lighting to disappear
|
||||||
|
return z;
|
||||||
}
|
}
|
||||||
else
|
else if(type == PEEK_COLOR)
|
||||||
{
|
{
|
||||||
hr = D3D::dev->StretchRect(pBuffer, &RectToLock, RBuffer, NULL, D3DTEXF_NONE);
|
// TODO: Can't we directly StretchRect to System buf?
|
||||||
//change the rect to lock the entire one pixel buffer
|
hr = D3D::dev->StretchRect(pEFBSurf, &RectToLock, pBufferRT, NULL, D3DTEXF_NONE);
|
||||||
|
D3D::dev->GetRenderTargetData(pBufferRT, pSystemBuf);
|
||||||
|
|
||||||
|
// EFB data successfully retrieved, now get the pixel data
|
||||||
RectToLock.bottom = 1;
|
RectToLock.bottom = 1;
|
||||||
RectToLock.left = 0;
|
RectToLock.left = 0;
|
||||||
RectToLock.right = 1;
|
RectToLock.right = 1;
|
||||||
RectToLock.top = 0;
|
RectToLock.top = 0;
|
||||||
}
|
D3DLOCKED_RECT drect;
|
||||||
if (FAILED(hr))
|
pSystemBuf->LockRect(&drect, &RectToLock, D3DLOCK_READONLY);
|
||||||
{
|
|
||||||
PanicAlert("Unable to stretch data to buffer");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// Retrieve the pixel data to the local memory buffer
|
|
||||||
D3D::dev->GetRenderTargetData(RBuffer, pOffScreenBuffer);
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
PanicAlert("Unable to copy data to mem buffer");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// The surface is good.. lock it
|
|
||||||
if ((hr = pOffScreenBuffer->LockRect(&drect, &RectToLock, D3DLOCK_READONLY)) != D3D_OK)
|
|
||||||
{
|
|
||||||
PanicAlert("ERROR: %s", hr == D3DERR_WASSTILLDRAWING ? "Still drawing" : hr == D3DERR_INVALIDCALL ? "Invalid call" : "w00t");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case PEEK_Z:
|
|
||||||
{
|
|
||||||
switch (ReadBufferFormat)
|
|
||||||
{
|
|
||||||
case D3DFMT_R32F:
|
|
||||||
val = ((float*)drect.pBits)[6];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
float ffrac = 1.0f/255.0f;
|
|
||||||
z = ((u32*)drect.pBits)[6];
|
|
||||||
val = ((float)((z>>16) & 0xFF)) * ffrac;
|
|
||||||
ffrac*= 1 / 255.0f;
|
|
||||||
val += ((float)((z>>8) & 0xFF)) * ffrac;
|
|
||||||
ffrac*= 1 / 255.0f;
|
|
||||||
val += ((float)(z & 0xFF)) * ffrac;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
z = ((u32)(val * 0xffffff));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case POKE_Z:
|
|
||||||
// TODO: Implement
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PEEK_COLOR:
|
|
||||||
z = ((u32*)drect.pBits)[0];
|
z = ((u32*)drect.pBits)[0];
|
||||||
break;
|
pSystemBuf->UnlockRect();
|
||||||
|
return z;
|
||||||
case POKE_COLOR:
|
}
|
||||||
// TODO: Implement. One way is to draw a tiny pixel-sized rectangle at
|
else //if(type == POKE_COLOR)
|
||||||
// the exact location. Note: EFB pokes are susceptible to Z-buffering
|
{
|
||||||
// and perhaps blending.
|
// TODO: Speed this up by batching pokes?
|
||||||
//WARN_LOG(VIDEOINTERFACE, "This is probably some kind of software rendering");
|
ResetAPIState();
|
||||||
break;
|
D3D::drawColorQuad(poke_data, (float)RectToLock.left * 2.f / (float)Renderer::GetFullTargetWidth() - 1.f,
|
||||||
|
- (float)RectToLock.top * 2.f / (float)Renderer::GetFullTargetHeight() + 1.f,
|
||||||
// TODO: Implement POKE_Z and POKE_COLOR
|
(float)RectToLock.right * 2.f / (float)Renderer::GetFullTargetWidth() - 1.f,
|
||||||
default:
|
- (float)RectToLock.bottom * 2.f / (float)Renderer::GetFullTargetHeight() + 1.f);
|
||||||
break;
|
RestoreAPIState();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pOffScreenBuffer->UnlockRect();
|
|
||||||
// TODO: in RE0 this value is often off by one, which causes lighting to disappear
|
|
||||||
return z;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from VertexShaderManager
|
// Called from VertexShaderManager
|
||||||
|
@ -1190,7 +1165,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TargetRectangle targetRc = ConvertEFBRectangle(rc);
|
TargetRectangle targetRc = ConvertEFBRectangle(rc);
|
||||||
LPDIRECT3DTEXTURE9 read_texture = g_framebufferManager.GetEFBColorTexture(rc);
|
LPDIRECT3DTEXTURE9 read_texture = g_framebufferManager.GetEFBColorTexture();
|
||||||
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);
|
||||||
|
|
|
@ -74,8 +74,8 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB
|
||||||
bool bIsIntensityFmt, u32 copyfmt)
|
bool bIsIntensityFmt, u32 copyfmt)
|
||||||
{
|
{
|
||||||
const LPDIRECT3DTEXTURE9 read_texture = bFromZBuffer ?
|
const LPDIRECT3DTEXTURE9 read_texture = bFromZBuffer ?
|
||||||
g_framebufferManager.GetEFBDepthTexture(source_rect) :
|
g_framebufferManager.GetEFBDepthTexture() :
|
||||||
g_framebufferManager.GetEFBColorTexture(source_rect);
|
g_framebufferManager.GetEFBColorTexture();
|
||||||
|
|
||||||
if (!isDynamic || g_ActiveConfig.bCopyEFBToTexture)
|
if (!isDynamic || g_ActiveConfig.bCopyEFBToTexture)
|
||||||
{
|
{
|
||||||
|
|
|
@ -325,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 ? g_framebufferManager.GetEFBDepthTexture(source) : g_framebufferManager.GetEFBColorTexture(source);
|
LPDIRECT3DTEXTURE9 source_texture = bFromZBuffer ? g_framebufferManager.GetEFBDepthTexture() : g_framebufferManager.GetEFBColorTexture();
|
||||||
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;
|
||||||
|
|
||||||
|
|
|
@ -400,7 +400,7 @@ void VideoFifo_CheckEFBAccess()
|
||||||
{
|
{
|
||||||
if (Common::AtomicLoadAcquire(s_efbAccessRequested))
|
if (Common::AtomicLoadAcquire(s_efbAccessRequested))
|
||||||
{
|
{
|
||||||
s_AccessEFBResult = Renderer::AccessEFB(s_accessEFBArgs.type, s_accessEFBArgs.x, s_accessEFBArgs.y);
|
s_AccessEFBResult = Renderer::AccessEFB(s_accessEFBArgs.type, s_accessEFBArgs.x, s_accessEFBArgs.y, s_accessEFBArgs.Data);
|
||||||
|
|
||||||
Common::AtomicStoreRelease(s_efbAccessRequested, FALSE);
|
Common::AtomicStoreRelease(s_efbAccessRequested, FALSE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -854,7 +854,7 @@ void Renderer::SetColorMask()
|
||||||
glColorMask(ColorMask, ColorMask, ColorMask, AlphaMask);
|
glColorMask(ColorMask, ColorMask, ColorMask, AlphaMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||||
{
|
{
|
||||||
if (!g_ActiveConfig.bEFBAccessEnable)
|
if (!g_ActiveConfig.bEFBAccessEnable)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -430,7 +430,7 @@ void VideoFifo_CheckEFBAccess()
|
||||||
{
|
{
|
||||||
if (Common::AtomicLoadAcquire(s_efbAccessRequested))
|
if (Common::AtomicLoadAcquire(s_efbAccessRequested))
|
||||||
{
|
{
|
||||||
s_AccessEFBResult = Renderer::AccessEFB(s_accessEFBArgs.type, s_accessEFBArgs.x, s_accessEFBArgs.y);
|
s_AccessEFBResult = Renderer::AccessEFB(s_accessEFBArgs.type, s_accessEFBArgs.x, s_accessEFBArgs.y, s_accessEFBArgs.Data);
|
||||||
|
|
||||||
Common::AtomicStoreRelease(s_efbAccessRequested, FALSE);
|
Common::AtomicStoreRelease(s_efbAccessRequested, FALSE);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue