GPU: Use skinned position always in bounding check.

Meanwhile, move to a flag on decoder options instead of global check.
This commit is contained in:
Unknown W. Brackets 2022-11-06 08:09:01 -08:00
parent a5d3af9cb0
commit 66472c39ce
9 changed files with 31 additions and 15 deletions

View File

@ -54,6 +54,7 @@ DrawEngineCommon::~DrawEngineCommon() {
void DrawEngineCommon::Init() {
useHWTransform_ = g_Config.bHardwareTransform;
useHWTessellation_ = UpdateUseHWTessellation(g_Config.bHardwareTessellation);
decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning;
}
VertexDecoder *DrawEngineCommon::GetVertexDecoder(u32 vtype) {
@ -181,10 +182,11 @@ void DrawEngineCommon::Resized() {
useHWTransform_ = g_Config.bHardwareTransform;
useHWTessellation_ = UpdateUseHWTessellation(g_Config.bHardwareTessellation);
decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning;
}
u32 DrawEngineCommon::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, int lowerBound, int upperBound, u32 vertType, int *vertexSize) {
const u32 vertTypeID = GetVertTypeID(vertType, gstate.getUVGenMode());
const u32 vertTypeID = GetVertTypeID(vertType, gstate.getUVGenMode(), decOptions_.applySkinInDecode);
VertexDecoder *dec = GetVertexDecoder(vertTypeID);
if (vertexSize)
*vertexSize = dec->VertexSize();
@ -232,7 +234,7 @@ void DrawEngineCommon::DispatchSubmitImm(GEPrimitiveType prim, TransformedVertex
}
int bytesRead;
uint32_t vertTypeID = GetVertTypeID(vtype, 0);
uint32_t vertTypeID = GetVertTypeID(vtype, 0, decOptions_.applySkinInDecode);
SubmitPrim(&temp[0], nullptr, prim, vertexCount, vertTypeID, cullMode, &bytesRead);
DispatchFlush();
@ -280,7 +282,11 @@ bool DrawEngineCommon::TestBoundingBox(const void *control_points, const void *i
GetIndexBounds(inds, vertexCount, vertType, &indexLowerBound, &indexUpperBound);
}
// Force software skinning.
bool wasApplyingSkinInDecode = decOptions_.applySkinInDecode;
decOptions_.applySkinInDecode = true;
NormalizeVertices((u8 *)corners, temp_buffer, (const u8 *)control_points, indexLowerBound, indexUpperBound, vertType);
decOptions_.applySkinInDecode = wasApplyingSkinInDecode;
IndexConverter conv(vertType, inds);
for (int i = 0; i < vertexCount; i++) {

View File

@ -52,10 +52,10 @@ enum FBOTexState {
FBO_TEX_READ_FRAMEBUFFER,
};
inline uint32_t GetVertTypeID(uint32_t vertType, int uvGenMode) {
inline uint32_t GetVertTypeID(uint32_t vertType, int uvGenMode, bool skinInDecode) {
// As the decoder depends on the UVGenMode when we use UV prescale, we simply mash it
// into the top of the verttype where there are unused bits.
return (vertType & 0xFFFFFF) | (uvGenMode << 24);
return (vertType & 0xFFFFFF) | (uvGenMode << 24) | (skinInDecode << 26);
}
struct SimpleVertex;

View File

@ -507,7 +507,7 @@ void DrawEngineCommon::SubmitCurve(const void *control_points, const void *indic
if (indices)
GetIndexBounds(indices, num_points, vertType, &index_lower_bound, &index_upper_bound);
VertexDecoder *origVDecoder = GetVertexDecoder(GetVertTypeID(vertType, gstate.getUVGenMode()));
VertexDecoder *origVDecoder = GetVertexDecoder(GetVertTypeID(vertType, gstate.getUVGenMode(), decOptions_.applySkinInDecode));
*bytesRead = num_points * origVDecoder->VertexSize();
// Simplify away bones and morph before proceeding
@ -572,7 +572,7 @@ void DrawEngineCommon::SubmitCurve(const void *control_points, const void *indic
gstate_c.uv.vOff = 0;
}
uint32_t vertTypeID = GetVertTypeID(vertTypeWithIndex16, gstate.getUVGenMode());
uint32_t vertTypeID = GetVertTypeID(vertTypeWithIndex16, gstate.getUVGenMode(), decOptions_.applySkinInDecode);
int generatedBytesRead;
if (output.count)
DispatchSubmitPrim(output.vertices, output.indices, PatchPrimToPrim(surface.primType), output.count, vertTypeID, gstate.getCullMode(), &generatedBytesRead);

View File

@ -1089,7 +1089,7 @@ void VertexDecoder::SetVertexType(u32 fmt, const VertexDecoderOptions &options,
DEBUG_LOG(G3D, "VTYPE: THRU=%i TC=%i COL=%i POS=%i NRM=%i WT=%i NW=%i IDX=%i MC=%i", (int)throughmode, tc, col, pos, nrm, weighttype, nweights, idx, morphcount);
}
skinInDecode = weighttype != 0 && g_Config.bSoftwareSkinning;
skinInDecode = weighttype != 0 && options.applySkinInDecode;
if (weighttype) { // && nweights?
weightoff = size;

View File

@ -335,6 +335,7 @@ typedef void(*JittedVertexDecoder)(const u8 *src, u8 *dst, int count);
struct VertexDecoderOptions {
bool expandAllWeightsToFloat;
bool expand8BitNormalsToFloat;
bool applySkinInDecode;
};
class VertexDecoder {

View File

@ -1834,7 +1834,7 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) {
// cull mode
int cullMode = gstate.getCullMode();
uint32_t vertTypeID = GetVertTypeID(vertexType, gstate.getUVGenMode());
uint32_t vertTypeID = GetVertTypeID(vertexType, gstate.getUVGenMode(), g_Config.bSoftwareSkinning);
drawEngineCommon_->SubmitPrim(verts, inds, prim, count, vertTypeID, cullMode, &bytesRead);
// After drawing, we advance the vertexAddr (when non indexed) or indexAddr (when indexed).
// Some games rely on this, they don't bother reloading VADDR and IADDR.
@ -1892,7 +1892,7 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) {
goto bail;
} else {
vertexType = data;
vertTypeID = GetVertTypeID(vertexType, gstate.getUVGenMode());
vertTypeID = GetVertTypeID(vertexType, gstate.getUVGenMode(), g_Config.bSoftwareSkinning);
}
break;
}

View File

@ -72,7 +72,7 @@ void SoftwareDrawEngine::DispatchSubmitPrim(const void *verts, const void *inds,
}
void SoftwareDrawEngine::DispatchSubmitImm(GEPrimitiveType prim, TransformedVertex *buffer, int vertexCount, int cullMode, bool continuation) {
uint32_t vertTypeID = GetVertTypeID(gstate.vertType | GE_VTYPE_POS_FLOAT, gstate.getUVGenMode());
uint32_t vertTypeID = GetVertTypeID(gstate.vertType | GE_VTYPE_POS_FLOAT, gstate.getUVGenMode(), decOptions_.applySkinInDecode);
int flipCull = cullMode != gstate.getCullMode() ? 1 : 0;
// TODO: For now, just setting all dirty.
@ -137,7 +137,7 @@ void SoftwareDrawEngine::DispatchSubmitImm(GEPrimitiveType prim, TransformedVert
}
VertexDecoder *SoftwareDrawEngine::FindVertexDecoder(u32 vtype) {
const u32 vertTypeID = GetVertTypeID(vtype, gstate.getUVGenMode());
const u32 vertTypeID = GetVertTypeID(vtype, gstate.getUVGenMode(), decOptions_.applySkinInDecode);
return DrawEngineCommon::GetVertexDecoder(vertTypeID);
}
@ -858,7 +858,7 @@ void TransformUnit::SubmitImmVertex(const ClipVertexData &vert, SoftwareDrawEngi
break;
}
uint32_t vertTypeID = GetVertTypeID(gstate.vertType | GE_VTYPE_POS_FLOAT, gstate.getUVGenMode());
uint32_t vertTypeID = GetVertTypeID(gstate.vertType | GE_VTYPE_POS_FLOAT, gstate.getUVGenMode(), g_Config.bSoftwareSkinning);
// This now processes the step with shared logic, given the existing data_.
isImmDraw_ = true;
SubmitPrimitive(nullptr, nullptr, GE_PRIM_KEEP_PREVIOUS, 0, vertTypeID, nullptr, drawEngine);
@ -958,6 +958,7 @@ bool TransformUnit::GetCurrentSimpleVertices(int count, std::vector<GPUDebugVert
VertexDecoder vdecoder;
VertexDecoderOptions options{};
options.applySkinInDecode = true;
vdecoder.SetVertexType(gstate.vertType, options);
if (!Memory::IsValidRange(gstate_c.vertexAddr, (indexUpperBound + 1) * vdecoder.VertexSize()))

View File

@ -306,6 +306,8 @@ int CtrlVertexList::GetRowCount() {
rowCount_ = 0;
}
VertexDecoderOptions options{};
// TODO: Maybe an option?
options.applySkinInDecode = true;
decoder->SetVertexType(state.vertType, options);
return rowCount_;
}

View File

@ -545,8 +545,10 @@ static bool TestVertexColor565() {
static bool TestVertex8Skin() {
VertexDecoderTestHarness dec;
VertexDecoderOptions opts{};
opts.applySkinInDecode = true;
dec.SetOptions(opts);
g_Config.bSoftwareSkinning = true;
for (int i = 0; i < 8 * 12; ++i) {
gstate.boneMatrix[i] = 0.0f;
}
@ -575,8 +577,10 @@ static bool TestVertex8Skin() {
static bool TestVertex16Skin() {
VertexDecoderTestHarness dec;
VertexDecoderOptions opts{};
opts.applySkinInDecode = true;
dec.SetOptions(opts);
g_Config.bSoftwareSkinning = true;
for (int i = 0; i < 8 * 12; ++i) {
gstate.boneMatrix[i] = 0.0f;
}
@ -605,8 +609,10 @@ static bool TestVertex16Skin() {
static bool TestVertexFloatSkin() {
VertexDecoderTestHarness dec;
VertexDecoderOptions opts{};
opts.applySkinInDecode = true;
dec.SetOptions(opts);
g_Config.bSoftwareSkinning = true;
for (int i = 0; i < 8 * 12; ++i) {
gstate.boneMatrix[i] = 0.0f;
}