mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-04 03:35:19 +02:00
CalculateDepthDraw guarded depthVertexCount_ with vertexCount, which is the index count - but depthVertexCount_ grows by the number of decoded vertices, which for an indexed draw can be far larger. Two draws with 6 indices spanning 40000 vertices each therefore passed the check and wrote ~700KB past the end of depthTransformed_. It also never bounded depthIndexCount_ against depthIndices_ at all, which only has room for 3 indices per vertex slot while draws routinely produce more. Pass the decoded count in separately and check both. DepthRasterClipIndexedTriangles duplicated culling-disabled triangles twice: once in the collect loop (added for Syphon Filter, #21498) and again in the output stage, which was the older code and should have been removed then. So it emitted four triangles per input triangle into buffers sized for one, and did twice the rasterization work it needed to in that mode. Removed the output-stage copy, and gave the function the output capacity so it stops when full - even at 2x, a culling-disabled draw over ~32k indices doesn't fit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DCPmm7FoQUoqrbMdhfqhQ2
61 lines
2.0 KiB
C++
61 lines
2.0 KiB
C++
#pragma once
|
|
|
|
#include "Common/CommonTypes.h"
|
|
#include "GPU/ge_constants.h"
|
|
|
|
struct DepthScreenVertex {
|
|
int x;
|
|
int y;
|
|
int z;
|
|
};
|
|
|
|
// X11.h, sigh.
|
|
#ifdef Always
|
|
#undef Always
|
|
#endif
|
|
|
|
// We only need to support these three modes.
|
|
enum class ZCompareMode : u8 {
|
|
Greater, // Most common
|
|
Less, // Less common
|
|
Always, // Mostly used for clears
|
|
};
|
|
|
|
struct DepthScissor {
|
|
u16 x1;
|
|
u16 y1;
|
|
u16 x2;
|
|
u16 y2;
|
|
|
|
DepthScissor Tile(int tile, int numTiles) const;
|
|
};
|
|
|
|
struct DepthDraw {
|
|
u32 depthAddr;
|
|
u16 depthStride;
|
|
u8 cullMode;
|
|
GEPrimitiveType prim;
|
|
ZCompareMode compareMode;
|
|
bool cullEnabled;
|
|
DepthScissor scissor;
|
|
int vertexOffset;
|
|
int indexOffset;
|
|
int vertexCount;
|
|
};
|
|
|
|
// Specialized, very limited depth-only rasterizer.
|
|
// Meant to run in parallel with hardware rendering, in games that read back the depth buffer
|
|
// for effects like lens flare.
|
|
// So, we can be quite inaccurate without any issues, and skip a lot of functionality.
|
|
|
|
class VertexDecoder;
|
|
struct TransformedVertex;
|
|
|
|
// maxOutCount is the capacity of each of tx/ty/tz, in elements.
|
|
int DepthRasterClipIndexedTriangles(int *tx, int *ty, float *tz, const float *transformed, const uint16_t *indexBuffer, const DepthDraw &draw, const DepthScissor scissor, int maxOutCount);
|
|
int DepthRasterClipIndexedRectangles(int *tx, int *ty, float *tz, const float *transformed, const uint16_t *indexBuffer, const DepthDraw &draw, const DepthScissor scissor);
|
|
void DecodeAndTransformForDepthRaster(float *dest, const float *worldviewproj, const void *vertexData, int indexLowerBound, int indexUpperBound, const VertexDecoder *dec, u32 vertTypeID);
|
|
void TransformPredecodedForDepthRaster(float *dest, const float *worldviewproj, const void *decodedVertexData, const VertexDecoder *dec, int count);
|
|
void ConvertPredecodedThroughForDepthRaster(float *dest, const void *decodedVertexData, const VertexDecoder *dec, int count);
|
|
void DepthRasterScreenVerts(uint16_t *depth, int depthStride, const int *tx, const int *ty, const float *tz, int count, const DepthDraw &draw, const DepthScissor scissor, bool lowQ);
|