mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Merge pull request #6205 from unknownbrackets/replace-funcs
Initial replacement for Star Ocean's stencil upload
This commit is contained in:
commit
0c7c736522
19 files changed
+258
-18
No files matched your search
@@ -1269,6 +1269,7 @@ add_library(GPU OBJECT
|
||||
GPU/GLES/Spline.cpp
|
||||
GPU/GLES/StateMapping.cpp
|
||||
GPU/GLES/StateMapping.h
|
||||
GPU/GLES/StencilBuffer.cpp
|
||||
GPU/GLES/TextureCache.cpp
|
||||
GPU/GLES/TextureCache.h
|
||||
GPU/GLES/TextureScaler.cpp
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/logging.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/Debugger/Breakpoints.h"
|
||||
#include "Core/MemMap.h"
|
||||
#include "Core/MIPS/JitCommon/JitCommon.h"
|
||||
@@ -111,8 +112,20 @@ static int Replace_memcpy() {
|
||||
}
|
||||
if (!skip && bytes != 0) {
|
||||
u8 *dst = Memory::GetPointerUnchecked(destPtr);
|
||||
u8 *src = Memory::GetPointerUnchecked(srcPtr);
|
||||
memmove(dst, src, bytes);
|
||||
const u8 *src = Memory::GetPointerUnchecked(srcPtr);
|
||||
|
||||
if (std::min(destPtr, srcPtr) + bytes > std::max(destPtr, srcPtr)) {
|
||||
// Overlap. Star Ocean breaks if it's not handled in 16 bytes blocks.
|
||||
const u32 blocks = bytes & ~0x0f;
|
||||
for (u32 offset = 0; offset < blocks; offset += 0x10) {
|
||||
memcpy(dst + offset, src + offset, 0x10);
|
||||
}
|
||||
for (u32 offset = blocks; offset < bytes; ++offset) {
|
||||
dst[offset] = src[offset];
|
||||
}
|
||||
} else {
|
||||
memmove(dst, src, bytes);
|
||||
}
|
||||
}
|
||||
RETURN(destPtr);
|
||||
#ifndef MOBILE_DEVICE
|
||||
@@ -483,6 +496,14 @@ static int Hook_hexyzforce_monoclome_thread() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Hook_starocean_write_stencil() {
|
||||
u32 fb_address = currentMIPS->r[MIPS_REG_T7];
|
||||
if (Memory::IsVRAMAddress(fb_address) && !g_Config.bDisableStencilTest) {
|
||||
gpu->PerformStencilUpload(fb_address, 0x00088000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Can either replace with C functions or functions emitted in Asm/ArmAsm.
|
||||
static const ReplacementTableEntry entries[] = {
|
||||
// TODO: I think some games can be helped quite a bit by implementing the
|
||||
@@ -524,6 +545,7 @@ static const ReplacementTableEntry entries[] = {
|
||||
|
||||
{ "godseaterburst_blit_texture", &Hook_godseaterburst_blit_texture, 0, REPFLAG_HOOKENTER},
|
||||
{ "hexyzforce_monoclome_thread", &Hook_hexyzforce_monoclome_thread, 0, REPFLAG_HOOKENTER, 0x58},
|
||||
{ "starocean_write_stencil", &Hook_starocean_write_stencil, 0, REPFLAG_HOOKENTER, 0x260},
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -586,7 +608,7 @@ void WriteReplaceInstructions(u32 address, u64 hash, int size) {
|
||||
for (u32 offset = 0; offset < (u32)size; offset += 4) {
|
||||
const u32 op = Memory::Read_U32(address + offset);
|
||||
if (op == MIPS_MAKE_JR_RA()) {
|
||||
WriteReplaceInstruction(address, index);
|
||||
WriteReplaceInstruction(address + offset, index);
|
||||
}
|
||||
}
|
||||
} else if (entry->flags & REPFLAG_HOOKENTER) {
|
||||
|
||||
@@ -347,6 +347,7 @@ static const HardHashTableEntry hardcodedHashes[] = {
|
||||
{ 0xc51519f5dab342d4, 224, "cosf", },
|
||||
{ 0xc52c14b9af8c3008, 76, "memcmp", },
|
||||
{ 0xc54eae62622f1e11, 164, "dl_write_bone_matrix_2", },
|
||||
{ 0xc6b29de7d3245198, 656, "starocean_write_stencil" }, // Star Ocean 1
|
||||
{ 0xc96e3a087ebf49a9, 100, "dl_write_light_color", },
|
||||
{ 0xcb7a2edd603ecfef, 48, "vtfm_p", },
|
||||
{ 0xcdf64d21418b2667, 24, "vzero_q", },
|
||||
|
||||
@@ -1330,6 +1330,10 @@ bool DIRECTX9_GPU::PerformMemoryDownload(u32 dest, int size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DIRECTX9_GPU::PerformStencilUpload(u32 dest, int size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void DIRECTX9_GPU::ClearCacheNextFrame() {
|
||||
textureCache_.ClearNextFrame();
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ public:
|
||||
virtual bool PerformMemoryCopy(u32 dest, u32 src, int size);
|
||||
virtual bool PerformMemorySet(u32 dest, u8 v, int size);
|
||||
virtual bool PerformMemoryDownload(u32 dest, int size);
|
||||
virtual bool PerformStencilUpload(u32 dest, int size);
|
||||
virtual void ClearCacheNextFrame();
|
||||
virtual void DeviceLost(); // Only happens on Android. Drop all textures and shaders.
|
||||
|
||||
|
||||
+17
-13
@@ -101,7 +101,7 @@ enum {
|
||||
FBO_OLD_AGE = 5,
|
||||
};
|
||||
|
||||
static bool MaskedEqual(u32 addr1, u32 addr2) {
|
||||
bool FramebufferManager::MaskedEqual(u32 addr1, u32 addr2) {
|
||||
return (addr1 & 0x03FFFFFF) == (addr2 & 0x03FFFFFF);
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ void CenterRect(float *x, float *y, float *w, float *h,
|
||||
*h = outH;
|
||||
}
|
||||
|
||||
static void ClearBuffer() {
|
||||
void FramebufferManager::ClearBuffer() {
|
||||
glstate.scissorTest.disable();
|
||||
glstate.depthWrite.set(GL_TRUE);
|
||||
glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
@@ -175,7 +175,7 @@ static void ClearBuffer() {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
|
||||
static void DisableState() {
|
||||
void FramebufferManager::DisableState() {
|
||||
glstate.blend.disable();
|
||||
glstate.cullFace.disable();
|
||||
glstate.depthTest.disable();
|
||||
@@ -322,6 +322,7 @@ FramebufferManager::FramebufferManager() :
|
||||
convBuf_(0),
|
||||
draw2dprogram_(0),
|
||||
postShaderProgram_(0),
|
||||
stencilUploadProgram_(0),
|
||||
plainColorLoc_(-1),
|
||||
timeLoc_(-1),
|
||||
textureCache_(0),
|
||||
@@ -361,6 +362,9 @@ FramebufferManager::~FramebufferManager() {
|
||||
if (draw2dprogram_) {
|
||||
glsl_destroy(draw2dprogram_);
|
||||
}
|
||||
if (stencilUploadProgram_) {
|
||||
glsl_destroy(stencilUploadProgram_);
|
||||
}
|
||||
SetNumExtraFBOs(0);
|
||||
|
||||
for (auto it = tempFBOs_.begin(), end = tempFBOs_.end(); it != end; ++it) {
|
||||
@@ -418,9 +422,9 @@ void FramebufferManager::MakePixelTexture(const u8 *srcPixels, GEBufferFormat sr
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
u16 col = src[x];
|
||||
dst[x * 4] = ((col) & 0x1f) << 3;
|
||||
dst[x * 4 + 1] = ((col >> 5) & 0x3f) << 2;
|
||||
dst[x * 4 + 2] = ((col >> 11) & 0x1f) << 3;
|
||||
dst[x * 4] = Convert5To8((col) & 0x1f);
|
||||
dst[x * 4 + 1] = Convert6To8((col >> 5) & 0x3f);
|
||||
dst[x * 4 + 2] = Convert5To8((col >> 11) & 0x1f);
|
||||
dst[x * 4 + 3] = 255;
|
||||
}
|
||||
}
|
||||
@@ -433,9 +437,9 @@ void FramebufferManager::MakePixelTexture(const u8 *srcPixels, GEBufferFormat sr
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
u16 col = src[x];
|
||||
dst[x * 4] = ((col) & 0x1f) << 3;
|
||||
dst[x * 4 + 1] = ((col >> 5) & 0x1f) << 3;
|
||||
dst[x * 4 + 2] = ((col >> 10) & 0x1f) << 3;
|
||||
dst[x * 4] = Convert5To8((col) & 0x1f);
|
||||
dst[x * 4 + 1] = Convert5To8((col >> 5) & 0x1f);
|
||||
dst[x * 4 + 2] = Convert5To8((col >> 10) & 0x1f);
|
||||
dst[x * 4 + 3] = (col >> 15) ? 255 : 0;
|
||||
}
|
||||
}
|
||||
@@ -448,10 +452,10 @@ void FramebufferManager::MakePixelTexture(const u8 *srcPixels, GEBufferFormat sr
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
u16 col = src[x];
|
||||
dst[x * 4] = ((col >> 8) & 0xf) << 4;
|
||||
dst[x * 4 + 1] = ((col >> 4) & 0xf) << 4;
|
||||
dst[x * 4 + 2] = (col & 0xf) << 4;
|
||||
dst[x * 4 + 3] = (col >> 12) << 4;
|
||||
dst[x * 4] = Convert4To8((col >> 8) & 0xf);
|
||||
dst[x * 4 + 1] = Convert4To8((col >> 4) & 0xf);
|
||||
dst[x * 4 + 2] = Convert4To8(col & 0xf);
|
||||
dst[x * 4 + 3] = Convert4To8(col >> 12);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -212,6 +212,7 @@ public:
|
||||
inline bool ShouldDownloadFramebuffer(const VirtualFramebuffer *vfb) const;
|
||||
|
||||
bool NotifyFramebufferCopy(u32 src, u32 dest, int size, bool isMemset = false);
|
||||
bool NotifyStencilUpload(u32 addr, int size);
|
||||
|
||||
void DestroyFramebuf(VirtualFramebuffer *vfb);
|
||||
|
||||
@@ -232,6 +233,10 @@ private:
|
||||
|
||||
void SetNumExtraFBOs(int num);
|
||||
|
||||
static void DisableState();
|
||||
static void ClearBuffer();
|
||||
static bool MaskedEqual(u32 addr1, u32 addr2);
|
||||
|
||||
u32 displayFramebufPtr_;
|
||||
u32 displayStride_;
|
||||
GEBufferFormat displayFormat_;
|
||||
@@ -263,6 +268,7 @@ private:
|
||||
GLSLProgram *draw2dprogram_;
|
||||
GLSLProgram *plainColorProgram_;
|
||||
GLSLProgram *postShaderProgram_;
|
||||
GLSLProgram *stencilUploadProgram_;
|
||||
int plainColorLoc_;
|
||||
int timeLoc_;
|
||||
|
||||
|
||||
@@ -674,6 +674,10 @@ void GLES_GPU::ProcessEvent(GPUEvent ev) {
|
||||
PerformMemorySetInternal(ev.fb_memset.dst, ev.fb_memset.v, ev.fb_memset.size);
|
||||
break;
|
||||
|
||||
case GPU_EVENT_FB_STENCIL_UPLOAD:
|
||||
PerformStencilUploadInternal(ev.fb_stencil_upload.dst, ev.fb_stencil_upload.size);
|
||||
break;
|
||||
|
||||
default:
|
||||
GPUCommon::ProcessEvent(ev);
|
||||
}
|
||||
@@ -2004,6 +2008,10 @@ void GLES_GPU::PerformMemorySetInternal(u32 dest, u8 v, int size) {
|
||||
}
|
||||
}
|
||||
|
||||
void GLES_GPU::PerformStencilUploadInternal(u32 dest, int size) {
|
||||
framebufferManager_.NotifyStencilUpload(dest, size);
|
||||
}
|
||||
|
||||
bool GLES_GPU::PerformMemoryCopy(u32 dest, u32 src, int size) {
|
||||
// Track stray copies of a framebuffer in RAM. MotoGP does this.
|
||||
if (framebufferManager_.MayIntersectFramebuffer(src) || framebufferManager_.MayIntersectFramebuffer(dest)) {
|
||||
@@ -2056,6 +2064,21 @@ bool GLES_GPU::PerformMemoryDownload(u32 dest, int size) {
|
||||
return gpu->PerformMemoryCopy(dest ^ 0x00400000, dest, size);
|
||||
}
|
||||
|
||||
bool GLES_GPU::PerformStencilUpload(u32 dest, int size) {
|
||||
if (framebufferManager_.MayIntersectFramebuffer(dest)) {
|
||||
if (IsOnSeparateCPUThread()) {
|
||||
GPUEvent ev(GPU_EVENT_FB_STENCIL_UPLOAD);
|
||||
ev.fb_stencil_upload.dst = dest;
|
||||
ev.fb_stencil_upload.size = size;
|
||||
ScheduleEvent(ev);
|
||||
} else {
|
||||
PerformStencilUploadInternal(dest, size);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void GLES_GPU::ClearCacheNextFrame() {
|
||||
textureCache_.ClearNextFrame();
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ public:
|
||||
virtual bool PerformMemoryCopy(u32 dest, u32 src, int size);
|
||||
virtual bool PerformMemorySet(u32 dest, u8 v, int size);
|
||||
virtual bool PerformMemoryDownload(u32 dest, int size);
|
||||
virtual bool PerformStencilUpload(u32 dest, int size);
|
||||
virtual void ClearCacheNextFrame();
|
||||
virtual void DeviceLost(); // Only happens on Android. Drop all textures and shaders.
|
||||
|
||||
@@ -158,6 +159,7 @@ private:
|
||||
void CopyDisplayToOutputInternal();
|
||||
void PerformMemoryCopyInternal(u32 dest, u32 src, int size);
|
||||
void PerformMemorySetInternal(u32 dest, u8 v, int size);
|
||||
void PerformStencilUploadInternal(u32 dest, int size);
|
||||
void InvalidateCacheInternal(u32 addr, int size, GPUInvalidationType type);
|
||||
|
||||
static CommandInfo cmdInfo_[256];
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
// Copyright (c) 2014- PPSSPP 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 or later versions.
|
||||
|
||||
// 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 git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "gfx_es2/glsl_program.h"
|
||||
#include "gfx_es2/gl_state.h"
|
||||
#include "Core/Reporting.h"
|
||||
#include "GPU/GLES/Framebuffer.h"
|
||||
#include "GPU/GLES/ShaderManager.h"
|
||||
|
||||
static const char *stencil_fs =
|
||||
#ifdef USING_GLES
|
||||
"#version 100\n"
|
||||
"precision highp float;\n"
|
||||
#endif
|
||||
"varying vec2 v_texcoord0;\n"
|
||||
"uniform float u_stencilValue;\n"
|
||||
"uniform sampler2D tex;\n"
|
||||
"float roundAndScaleTo255f(in float x) { return floor(x * 255.99); }\n"
|
||||
"void main() {\n"
|
||||
" vec4 index = texture2D(tex, v_texcoord0);\n"
|
||||
" gl_FragColor = vec4(1.0);\n"
|
||||
" float shifted = roundAndScaleTo255f(index.a) / roundAndScaleTo255f(u_stencilValue);\n"
|
||||
" if (mod(floor(shifted), 2.0) < 0.99) discard;\n"
|
||||
"}\n";
|
||||
|
||||
static const char *stencil_vs =
|
||||
#ifdef USING_GLES
|
||||
"#version 100\n"
|
||||
"precision highp float;\n"
|
||||
#endif
|
||||
"attribute vec4 a_position;\n"
|
||||
"attribute vec2 a_texcoord0;\n"
|
||||
"varying vec2 v_texcoord0;\n"
|
||||
"void main() {\n"
|
||||
" v_texcoord0 = a_texcoord0;\n"
|
||||
" gl_Position = a_position;\n"
|
||||
"}\n";
|
||||
|
||||
static bool MaskedEqual(u32 addr1, u32 addr2) {
|
||||
return (addr1 & 0x03FFFFFF) == (addr2 & 0x03FFFFFF);
|
||||
}
|
||||
|
||||
bool FramebufferManager::NotifyStencilUpload(u32 addr, int size) {
|
||||
if (!MayIntersectFramebuffer(addr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
VirtualFramebuffer *dstBuffer = 0;
|
||||
for (size_t i = 0; i < vfbs_.size(); ++i) {
|
||||
VirtualFramebuffer *vfb = vfbs_[i];
|
||||
if (MaskedEqual(vfb->fb_address, addr)) {
|
||||
dstBuffer = vfb;
|
||||
}
|
||||
}
|
||||
if (!dstBuffer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GLSLProgram *program = 0;
|
||||
if (!stencilUploadProgram_) {
|
||||
std::string errorString;
|
||||
stencilUploadProgram_ = glsl_create_source(stencil_vs, stencil_fs, &errorString);
|
||||
if (!stencilUploadProgram_) {
|
||||
ERROR_LOG_REPORT(G3D, "Failed to compile stencilUploadProgram! This shouldn't happen.\n%s", errorString.c_str());
|
||||
} else {
|
||||
glsl_bind(stencilUploadProgram_);
|
||||
}
|
||||
|
||||
GLint u_tex = glsl_uniform_loc(stencilUploadProgram_, "tex");
|
||||
glUniform1i(u_tex, 0);
|
||||
} else {
|
||||
glsl_bind(stencilUploadProgram_);
|
||||
}
|
||||
|
||||
shaderManager_->DirtyLastShader();
|
||||
|
||||
MakePixelTexture(Memory::GetPointer(addr), dstBuffer->format, dstBuffer->fb_stride, dstBuffer->width, dstBuffer->height);
|
||||
DisableState();
|
||||
glstate.blend.set(true);
|
||||
glstate.blendEquation.set(GL_FUNC_ADD);
|
||||
glstate.blendFuncSeparate.set(GL_ZERO, GL_ONE, GL_ONE, GL_ZERO);
|
||||
glstate.stencilTest.enable();
|
||||
glstate.stencilOp.set(GL_REPLACE, GL_REPLACE, GL_REPLACE);
|
||||
|
||||
// TODO: Doing it the slow way for now.
|
||||
int values = 0;
|
||||
|
||||
switch (dstBuffer->format) {
|
||||
case GE_FORMAT_565:
|
||||
// Well, this doesn't make much sense.
|
||||
return false;
|
||||
case GE_FORMAT_5551:
|
||||
values = 2;
|
||||
break;
|
||||
case GE_FORMAT_4444:
|
||||
values = 16;
|
||||
break;
|
||||
case GE_FORMAT_8888:
|
||||
values = 256;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dstBuffer->fbo) {
|
||||
fbo_bind_as_render_target(dstBuffer->fbo);
|
||||
}
|
||||
glViewport(0, 0, dstBuffer->renderWidth, dstBuffer->renderHeight);
|
||||
|
||||
glClearStencil(0);
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
glstate.stencilFunc.set(GL_ALWAYS, 0xFF, 0xFF);
|
||||
|
||||
GLint u_stencilValue = glsl_uniform_loc(stencilUploadProgram_, "u_stencilValue");
|
||||
for (int i = 1; i < values; i += i) {
|
||||
// DrawActiveTexture unbinds it, so rebind here before setting uniforms.
|
||||
glsl_bind(stencilUploadProgram_);
|
||||
if (dstBuffer->format == GE_FORMAT_4444) {
|
||||
glStencilMask(Convert4To8(i));
|
||||
glUniform1f(u_stencilValue, i * (16.0f / 255.0f));
|
||||
} else if (dstBuffer->format == GE_FORMAT_5551) {
|
||||
glStencilMask(0xFF);
|
||||
glUniform1f(u_stencilValue, i * (128.0f / 255.0f));
|
||||
} else {
|
||||
glStencilMask(i);
|
||||
glUniform1f(u_stencilValue, i * (1.0f / 255.0f));
|
||||
}
|
||||
DrawActiveTexture(0, 0, 0, dstBuffer->width, dstBuffer->height, dstBuffer->width, dstBuffer->height, false, 0.0f, 0.0f, 1.0f, 1.0f, stencilUploadProgram_);
|
||||
}
|
||||
glStencilMask(0xFF);
|
||||
|
||||
if (currentRenderVfb_) {
|
||||
RebindFramebuffer();
|
||||
} else {
|
||||
fbo_unbind();
|
||||
}
|
||||
glstate.viewport.restore();
|
||||
return true;
|
||||
}
|
||||
+2
-1
@@ -250,6 +250,7 @@
|
||||
<ClCompile Include="GLES\ShaderManager.cpp" />
|
||||
<ClCompile Include="GLES\Spline.cpp" />
|
||||
<ClCompile Include="GLES\StateMapping.cpp" />
|
||||
<ClCompile Include="GLES\StencilBuffer.cpp" />
|
||||
<ClCompile Include="GLES\TextureCache.cpp" />
|
||||
<ClCompile Include="GLES\TextureScaler.cpp" />
|
||||
<ClCompile Include="GLES\SoftwareTransform.cpp" />
|
||||
@@ -285,4 +286,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -314,8 +314,11 @@
|
||||
<ClCompile Include="GLES\DepalettizeShader.cpp">
|
||||
<Filter>GLES</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GLES\StencilBuffer.cpp">
|
||||
<Filter>GLES</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CMakeLists.txt" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -165,6 +165,7 @@ enum GPUEventType {
|
||||
GPU_EVENT_SYNC_THREAD,
|
||||
GPU_EVENT_FB_MEMCPY,
|
||||
GPU_EVENT_FB_MEMSET,
|
||||
GPU_EVENT_FB_STENCIL_UPLOAD,
|
||||
};
|
||||
|
||||
struct GPUEvent {
|
||||
@@ -189,6 +190,11 @@ struct GPUEvent {
|
||||
u8 v;
|
||||
int size;
|
||||
} fb_memset;
|
||||
// GPU_EVENT_FB_STENCIL_UPLOAD
|
||||
struct {
|
||||
u32 dst;
|
||||
int size;
|
||||
} fb_stencil_upload;
|
||||
};
|
||||
|
||||
operator GPUEventType() const {
|
||||
@@ -244,6 +250,7 @@ public:
|
||||
virtual bool PerformMemoryCopy(u32 dest, u32 src, int size) = 0;
|
||||
virtual bool PerformMemorySet(u32 dest, u8 v, int size) = 0;
|
||||
virtual bool PerformMemoryDownload(u32 dest, int size) = 0;
|
||||
virtual bool PerformStencilUpload(u32 dest, int size) = 0;
|
||||
|
||||
// Will cause the texture cache to be cleared at the start of the next frame.
|
||||
virtual void ClearCacheNextFrame() = 0;
|
||||
|
||||
@@ -674,3 +674,7 @@ bool NullGPU::PerformMemoryDownload(u32 dest, int size) {
|
||||
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NullGPU::PerformStencilUpload(u32 dest, int size) {
|
||||
return false;
|
||||
}
|
||||
@@ -37,6 +37,7 @@ public:
|
||||
virtual bool PerformMemoryCopy(u32 dest, u32 src, int size);
|
||||
virtual bool PerformMemorySet(u32 dest, u8 v, int size);
|
||||
virtual bool PerformMemoryDownload(u32 dest, int size);
|
||||
virtual bool PerformStencilUpload(u32 dest, int size);
|
||||
virtual void ClearCacheNextFrame() {};
|
||||
|
||||
virtual void DeviceLost() {}
|
||||
|
||||
@@ -876,6 +876,11 @@ bool SoftGPU::PerformMemoryDownload(u32 dest, int size)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SoftGPU::PerformStencilUpload(u32 dest, int size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SoftGPU::FramebufferDirty() {
|
||||
if (g_Config.bSeparateCPUThread) {
|
||||
// Allow it to process fully before deciding if it's dirty.
|
||||
|
||||
@@ -62,6 +62,7 @@ public:
|
||||
virtual bool PerformMemoryCopy(u32 dest, u32 src, int size);
|
||||
virtual bool PerformMemorySet(u32 dest, u8 v, int size);
|
||||
virtual bool PerformMemoryDownload(u32 dest, int size);
|
||||
virtual bool PerformStencilUpload(u32 dest, int size);
|
||||
virtual void ClearCacheNextFrame() {};
|
||||
|
||||
virtual void DeviceLost() {}
|
||||
|
||||
@@ -54,6 +54,7 @@ SOURCES += $$P/Core/*.cpp \ # Core
|
||||
$$P/GPU/GLES/SoftwareTransform.cpp \
|
||||
$$P/GPU/GLES/Spline.cpp \
|
||||
$$P/GPU/GLES/StateMapping.cpp \
|
||||
$$P/GPU/GLES/StencilBuffer.cpp \
|
||||
$$P/GPU/GLES/TextureCache.cpp \
|
||||
$$P/GPU/GLES/TextureScaler.cpp \
|
||||
$$P/GPU/GLES/TransformPipeline.cpp \
|
||||
|
||||
@@ -146,6 +146,7 @@ EXEC_AND_LIB_FILES := \
|
||||
$(SRC)/GPU/GLES/Framebuffer.cpp \
|
||||
$(SRC)/GPU/GLES/DepalettizeShader.cpp \
|
||||
$(SRC)/GPU/GLES/GLES_GPU.cpp.arm \
|
||||
$(SRC)/GPU/GLES/StencilBuffer.cpp.arm \
|
||||
$(SRC)/GPU/GLES/TextureCache.cpp.arm \
|
||||
$(SRC)/GPU/GLES/TransformPipeline.cpp.arm \
|
||||
$(SRC)/GPU/GLES/SoftwareTransform.cpp.arm \
|
||||
|
||||
Reference in new issue
Block a user