Skip to content

Commit

Permalink
Hack that converts immediate draws to through-mode draws. This won't
Browse files Browse the repository at this point in the history
work correctly in all cases - but it's enough for Thrillville which uses
it to clear only. Works around #7459.
  • Loading branch information
hrydgard committed Nov 24, 2017
1 parent 28b60a7 commit d2150cd
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Core/HLE/sceIo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2330,7 +2330,7 @@ static int __IoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr,
case 0x01020004:
// TODO: Should not work for umd0:/, ms0:/, etc.
// TODO: Should probably move this to something common between ISOFileSystem and VirtualDiscSystem.
INFO_LOG(SCEIO, "sceIoIoctl: Asked for file offset of file %i", id);
DEBUG_LOG(SCEIO, "sceIoIoctl(0x01020004): Asked for file offset of file %d", id);
if (Memory::IsValidAddress(outdataPtr) && outlen >= 4) {
u32 offset = (u32)pspFileSystem.GetSeekPos(f->handle);
Memory::Write_U32(offset, outdataPtr);
Expand Down
2 changes: 2 additions & 0 deletions Core/MIPS/x86/JitSafeMem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ bool JitSafeMem::PrepareWrite(OpArg &dest, int size)
{
MemCheckImm(MEM_WRITE);
u32 addr = (iaddr_ & alignMask_);
_dbg_assert_msg_(JIT, Memory::IsValidAddress(addr), "Memory access - invalid address! %08x", addr);

#ifdef MASKED_PSP_MEMORY
addr &= Memory::MEMVIEW32_MASK;
#endif
Expand Down
2 changes: 2 additions & 0 deletions GPU/Common/DrawEngineCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ class DrawEngineCommon {
void SubmitSpline(const void *control_points, const void *indices, int tess_u, int tess_v, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, bool computeNormals, bool patchFacing, u32 vertType, int *bytesRead);
void SubmitBezier(const void *control_points, const void *indices, int tess_u, int tess_v, int count_u, int count_v, GEPatchPrimType prim_type, bool computeNormals, bool patchFacing, u32 vertType, int *bytesRead);

virtual void DispatchSubmitImm(const TransformedVertex *transformed, int count, GEPrimitiveType prim) {}

std::vector<std::string> DebugGetVertexLoaderIDs();
std::string DebugGetVertexLoaderString(std::string id, DebugShaderStringType stringType);

Expand Down
42 changes: 37 additions & 5 deletions GPU/GPUCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1826,14 +1826,46 @@ void GPUCommon::Execute_ImmVertexAlphaPrim(u32 op, u32 diff) {
v.color1_32 = gstate.imm_scv & 0xFFFFFF;
int prim = (op >> 8) & 0xF;
if (prim != 7) {
immPrim_ = prim;
} else {
// Time to submit! This can go through the software transform path but skipping the actual transform...
// drawEngineCommon_->SubmitImm(immBuffer_, immCount_);
immCount_ = 0;
immPrim_ = (GEPrimitiveType)prim;
} else if (prim == 7 && immCount_ == 2) {
FlushImm();
}
}

void GPUCommon::FlushImm() {
SetDrawType(DRAW_PRIM, immPrim_);
framebufferManager_->SetRenderFrameBuffer(gstate_c.IsDirty(DIRTY_FRAMEBUF), gstate_c.skipDrawReason);
if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) {
// No idea how many cycles to skip, heh.
return;
}
UpdateUVScaleOffset();
// Instead of finding a proper point to flush, we just emit a full rectangle every time one
// is finished.

// And instead of plumbing through, we'll cheat and just turn these into through vertices.
// Since the only known use is Thrillville and it only uses it to clear, we just use color and pos.
struct ImmVertex {
uint32_t color;
float xyz[3];
};
ImmVertex temp[MAX_IMMBUFFER_SIZE];
for (int i = 0; i < immCount_; i++) {
temp[i].color = immBuffer_[i].color0_32;
temp[i].xyz[0] = immBuffer_[i].pos[0];
temp[i].xyz[1] = immBuffer_[i].pos[1];
temp[i].xyz[2] = immBuffer_[i].pos[2];
}
int vtype = GE_VTYPE_POS_FLOAT | GE_VTYPE_COL_8888 | GE_VTYPE_THROUGH;

int bytesRead;
drawEngineCommon_->DispatchSubmitPrim(temp, nullptr, immPrim_, immCount_, vtype, &bytesRead);
drawEngineCommon_->DispatchFlush();
// TOOD: In the future, make a special path for these.
// drawEngineCommon_->DispatchSubmitImm(immBuffer_, immCount_);
immCount_ = 0;
}

void GPUCommon::ExecuteOp(u32 op, u32 diff) {
const u32 cmd = op >> 24;

Expand Down
3 changes: 2 additions & 1 deletion GPU/GPUCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,10 @@ class GPUCommon : public GPUInterface, public GPUDebugInterface {

TransformedVertex immBuffer_[MAX_IMMBUFFER_SIZE];
int immCount_ = 0;
int immPrim_ = 0;
GEPrimitiveType immPrim_;

private:
void FlushImm();
// Debug stats.
double timeSteppingStarted_;
double timeSpentStepping_;
Expand Down
4 changes: 4 additions & 0 deletions GPU/Vulkan/DrawEngineVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,10 @@ void MarkUnreliable(VertexArrayInfoVulkan *vai) {
// For now we just leave it in the pushbuffer.
}

void DrawEngineVulkan::SubmitImm(const TransformedVertex *transformed, int count, GEPrimitiveType prim) {

}

// The inline wrapper in the header checks for numDrawCalls == 0
void DrawEngineVulkan::DoFlush() {
PROFILE_THIS_SCOPE("Flush");
Expand Down
6 changes: 6 additions & 0 deletions GPU/Vulkan/DrawEngineVulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,13 @@ class DrawEngineVulkan : public DrawEngineCommon {

void SetLineWidth(float lineWidth);

void DispatchSubmitImm(const TransformedVertex *transformed, int count, GEPrimitiveType prim) override {
SubmitImm(transformed, count, prim);
}

private:
void SubmitImm(const TransformedVertex *transformed, int count, GEPrimitiveType prim);

struct FrameData;
void ApplyDrawStateLate(VulkanRenderManager *renderManager, bool applyStencilRef, uint8_t stencilRef, bool useBlendConstant);
void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, ShaderManagerVulkan *shaderManager, int prim, VulkanPipelineRasterStateKey &key, VulkanDynamicState &dynState);
Expand Down

0 comments on commit d2150cd

Please sign in to comment.