applySkinInDecode belongs in the VertexTypeID, not in the options.

This commit is contained in:
Henrik Rydgård
2024-12-17 18:15:52 +01:00
parent ee2f221938
commit e74101a2fb
13 changed files with 64 additions and 58 deletions
+7 -7
View File
@@ -133,11 +133,11 @@ void DrawEngineCommon::NotifyConfigChanged() {
useHWTransform_ = g_Config.bHardwareTransform;
useHWTessellation_ = UpdateUseHWTessellation(g_Config.bHardwareTessellation);
decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning;
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(), decOptions_.applySkinInDecode);
const u32 vertTypeID = GetVertTypeID(vertType, gstate.getUVGenMode(), applySkinInDecode_);
VertexDecoder *dec = GetVertexDecoder(vertTypeID);
if (vertexSize)
*vertexSize = dec->VertexSize();
@@ -185,7 +185,7 @@ void DrawEngineCommon::DispatchSubmitImm(GEPrimitiveType prim, TransformedVertex
}
int bytesRead;
uint32_t vertTypeID = GetVertTypeID(vtype, 0, decOptions_.applySkinInDecode);
uint32_t vertTypeID = GetVertTypeID(vtype, 0, applySkinInDecode_);
bool clockwise = !gstate.isCullEnabled() || gstate.getCullMode() == cullMode;
SubmitPrim(&temp[0], nullptr, prim, vertexCount, vertTypeID, clockwise, &bytesRead);
@@ -303,10 +303,10 @@ bool DrawEngineCommon::TestBoundingBox(const void *vdata, const void *inds, int
}
// TODO: Avoid normalization if just plain skinning.
// Force software skinning.
bool wasApplyingSkinInDecode = decOptions_.applySkinInDecode;
decOptions_.applySkinInDecode = true;
bool wasApplyingSkinInDecode = applySkinInDecode_;
applySkinInDecode_ = true;
NormalizeVertices((u8 *)corners, temp_buffer, (const u8 *)vdata, indexLowerBound, indexUpperBound, vertType);
decOptions_.applySkinInDecode = wasApplyingSkinInDecode;
applySkinInDecode_ = wasApplyingSkinInDecode;
IndexConverter conv(vertType, inds);
for (int i = 0; i < vertexCount; i++) {
@@ -985,7 +985,7 @@ bool DrawEngineCommon::SubmitPrim(const void *verts, const void *inds, GEPrimiti
}
}
bool applySkin = (vertTypeID & GE_VTYPE_WEIGHT_MASK) && decOptions_.applySkinInDecode;
bool applySkin = dec_->skinInDecode;
DeferredInds &di = drawInds_[numDrawInds_++];
di.inds = inds;
+3 -8
View File
@@ -53,12 +53,6 @@ enum FBOTexState {
FBO_TEX_READ_FRAMEBUFFER,
};
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) | (skinInDecode << 26);
}
struct SimpleVertex;
namespace Spline { struct Weight2D; }
@@ -114,8 +108,7 @@ public:
bool TestBoundingBoxThrough(const void *vdata, int vertexCount, u32 vertType);
void FlushSkin() {
bool applySkin = (lastVType_ & GE_VTYPE_WEIGHT_MASK) && decOptions_.applySkinInDecode;
if (applySkin) {
if (dec_->skinInDecode) {
DecodeVerts(decoded_);
}
}
@@ -314,6 +307,8 @@ protected:
bool anyCCWOrIndexed_ = 0;
bool anyIndexed_ = 0;
bool applySkinInDecode_ = false;
// Vertex collector state
IndexGenerator indexGen;
int numDecodedVerts_ = 0;
+2 -2
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(), decOptions_.applySkinInDecode));
VertexDecoder *origVDecoder = GetVertexDecoder(GetVertTypeID(vertType, gstate.getUVGenMode(), applySkinInDecode_));
*bytesRead = num_points * origVDecoder->VertexSize();
// Simplify away bones and morph before proceeding
@@ -574,7 +574,7 @@ void DrawEngineCommon::SubmitCurve(const void *control_points, const void *indic
gstate_c.uv.vOff = 0;
}
uint32_t vertTypeID = GetVertTypeID(vertTypeWithIndex16, gstate.getUVGenMode(), decOptions_.applySkinInDecode);
uint32_t vertTypeID = GetVertTypeID(vertTypeWithIndex16, gstate.getUVGenMode(), applySkinInDecode_);
int generatedBytesRead;
if (output.count)
DispatchSubmitPrim(output.vertices, output.indices, PatchPrimToPrim(surface.primType), output.count, vertTypeID, true, &generatedBytesRead);
+3 -2
View File
@@ -1125,7 +1125,7 @@ void VertexDecoder::SetVertexType(u32 fmt, const VertexDecoderOptions &options,
DEBUG_LOG(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 && options.applySkinInDecode;
skinInDecode = weighttype != 0 && VertTypeIDSkinInDecode(fmt);
if (weighttype) { // && nweights?
weightoff = size;
@@ -1182,7 +1182,8 @@ void VertexDecoder::SetVertexType(u32 fmt, const VertexDecoderOptions &options,
// NOTE: That we check getUVGenMode here means that we must include it in the decoder ID!
// throughmode is automatically included though, because it's part of the vertType.
if (!throughmode && (gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_COORDS || gstate.getUVGenMode() == GE_TEXMAP_UNKNOWN)) {
GETexMapMode mode = VertTypeIDUVGenMode(fmt);
if (!throughmode && (mode == GE_TEXMAP_TEXTURE_COORDS || mode == GE_TEXMAP_UNKNOWN)) {
if (g_DoubleTextureCoordinates)
steps_[numSteps_++] = morphcount == 1 ? tcstep_prescale_remaster[tc] : tcstep_prescale_morph_remaster[tc];
else
+14 -2
View File
@@ -325,9 +325,22 @@ typedef void (*JittedVertexDecoder)(const u8 *src, u8 *dst, int count, const UVS
struct VertexDecoderOptions {
bool expandAllWeightsToFloat;
bool expand8BitNormalsToFloat;
bool applySkinInDecode;
};
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) | (skinInDecode << 26);
}
inline bool VertTypeIDSkinInDecode(uint32_t vertType) {
return ((vertType >> 26) & 1) != 0;
}
inline GETexMapMode VertTypeIDUVGenMode(uint32_t vertType) {
return (GETexMapMode)((vertType >> 24) & 3);
}
class VertexDecoder {
public:
// A jit cache is not mandatory.
@@ -512,7 +525,6 @@ public:
// Returns a pointer to the code to run.
JittedVertexDecoder Compile(const VertexDecoder &dec, int32_t *jittedSize);
bool DescribeCodePtr(const u8 *ptr, std::string &name) const;
void Clear();
void Jit_WeightsU8();
+4 -4
View File
@@ -303,7 +303,7 @@ void DrawEngineD3D11::Flush() {
D3D11VertexShader *vshader;
D3D11FragmentShader *fshader;
shaderManager_->GetShaders(prim, dec_, &vshader, &fshader, pipelineState_, useHWTransform, useHWTessellation_, decOptions_.expandAllWeightsToFloat, decOptions_.applySkinInDecode);
shaderManager_->GetShaders(prim, dec_, &vshader, &fshader, pipelineState_, useHWTransform, useHWTessellation_, decOptions_.expandAllWeightsToFloat, applySkinInDecode_);
ID3D11InputLayout *inputLayout = SetupDecFmtForDraw(vshader, dec_->GetDecVtxFmt(), dec_->VertexType());
context_->PSSetShader(fshader->GetShader(), nullptr, 0);
context_->VSSetShader(vshader->GetShader(), nullptr, 0);
@@ -346,8 +346,8 @@ void DrawEngineD3D11::Flush() {
}
} else {
PROFILE_THIS_SCOPE("soft");
if (!decOptions_.applySkinInDecode) {
decOptions_.applySkinInDecode = true;
if (!applySkinInDecode_) {
applySkinInDecode_ = true;
lastVType_ |= (1 << 26);
dec_ = GetVertexDecoder(lastVType_);
}
@@ -478,7 +478,7 @@ void DrawEngineD3D11::Flush() {
framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, clearColor);
}
}
decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning;
applySkinInDecode_ = g_Config.bSoftwareSkinning;
}
ResetAfterDrawInline();
+4 -4
View File
@@ -276,7 +276,7 @@ void DrawEngineDX9::Flush() {
ApplyDrawState(prim);
ApplyDrawStateLate();
VSShader *vshader = shaderManager_->ApplyShader(true, useHWTessellation_, dec_, decOptions_.expandAllWeightsToFloat, decOptions_.applySkinInDecode, pipelineState_);
VSShader *vshader = shaderManager_->ApplyShader(true, useHWTessellation_, dec_, decOptions_.expandAllWeightsToFloat, applySkinInDecode_, pipelineState_);
ComPtr<IDirect3DVertexDeclaration9> pHardwareVertexDecl;
SetupDecFmtForDraw(dec_->GetDecVtxFmt(), dec_->VertexType(), &pHardwareVertexDecl);
@@ -301,8 +301,8 @@ void DrawEngineDX9::Flush() {
}
}
} else {
if (!decOptions_.applySkinInDecode) {
decOptions_.applySkinInDecode = true;
if (!applySkinInDecode_) {
applySkinInDecode_ = true;
lastVType_ |= (1 << 26);
dec_ = GetVertexDecoder(lastVType_);
}
@@ -414,7 +414,7 @@ void DrawEngineDX9::Flush() {
framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, clearColor);
}
}
decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning;
applySkinInDecode_ = g_Config.bSoftwareSkinning;
}
ResetAfterDrawInline();
+5 -5
View File
@@ -264,7 +264,7 @@ void DrawEngineGLES::Flush() {
GEPrimitiveType prim = prevPrim_;
Shader *vshader = shaderManager_->ApplyVertexShader(CanUseHardwareTransform(prim), useHWTessellation_, dec_, decOptions_.expandAllWeightsToFloat, decOptions_.applySkinInDecode || !CanUseHardwareTransform(prim), &vsid);
Shader *vshader = shaderManager_->ApplyVertexShader(CanUseHardwareTransform(prim), useHWTessellation_, dec_, decOptions_.expandAllWeightsToFloat, applySkinInDecode_ || !CanUseHardwareTransform(prim), &vsid);
GLRBuffer *vertexBuffer = nullptr;
GLRBuffer *indexBuffer = nullptr;
@@ -272,7 +272,7 @@ void DrawEngineGLES::Flush() {
uint32_t indexBufferOffset = 0;
if (vshader->UseHWTransform()) {
if (decOptions_.applySkinInDecode && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) {
if (applySkinInDecode_ && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) {
// If software skinning, we're predecoding into "decoded". So make sure we're done, then push that content.
DecodeVerts(decoded_);
uint32_t size = numDecodedVerts_ * dec_->GetDecVtxFmt().stride;
@@ -328,8 +328,8 @@ void DrawEngineGLES::Flush() {
}
} else {
PROFILE_THIS_SCOPE("soft");
if (!decOptions_.applySkinInDecode) {
decOptions_.applySkinInDecode = true;
if (!applySkinInDecode_) {
applySkinInDecode_ = true;
lastVType_ |= (1 << 26);
dec_ = GetVertexDecoder(lastVType_);
}
@@ -447,7 +447,7 @@ void DrawEngineGLES::Flush() {
}
gstate_c.Dirty(DIRTY_BLEND_STATE); // Make sure the color mask gets re-applied.
}
decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning;
applySkinInDecode_ = g_Config.bSoftwareSkinning;
}
bail:
+3 -3
View File
@@ -63,7 +63,7 @@ SoftwareDrawEngine::~SoftwareDrawEngine() {}
void SoftwareDrawEngine::NotifyConfigChanged() {
DrawEngineCommon::NotifyConfigChanged();
decOptions_.applySkinInDecode = true;
applySkinInDecode_ = true;
}
void SoftwareDrawEngine::Flush() {
@@ -973,8 +973,8 @@ bool TransformUnit::GetCurrentSimpleVertices(int count, std::vector<GPUDebugVert
VertexDecoder vdecoder;
VertexDecoderOptions options{};
options.applySkinInDecode = true;
vdecoder.SetVertexType(gstate.vertType, options);
u32 vertTypeID = GetVertTypeID(gstate.vertType, gstate.getUVGenMode(), true);
vdecoder.SetVertexType(vertTypeID, options);
if (!Memory::IsValidRange(gstate_c.vertexAddr, (indexUpperBound + 1) * vdecoder.VertexSize()))
return false;
+6 -6
View File
@@ -258,7 +258,7 @@ void DrawEngineVulkan::Flush() {
uint32_t vbOffset;
VkBuffer vbuf = VK_NULL_HANDLE;
if (decOptions_.applySkinInDecode && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) {
if (applySkinInDecode_ && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) {
// If software skinning, we're predecoding into "decoded". So make sure we're done, then push that content.
DecodeVerts(decoded_);
VkDeviceSize size = numDecodedVerts_ * dec_->GetDecVtxFmt().stride;
@@ -302,7 +302,7 @@ void DrawEngineVulkan::Flush() {
VulkanFragmentShader *fshader = nullptr;
VulkanGeometryShader *gshader = nullptr;
shaderManager_->GetShaders(prim, dec_, &vshader, &fshader, &gshader, pipelineState_, true, useHWTessellation_, decOptions_.expandAllWeightsToFloat, decOptions_.applySkinInDecode);
shaderManager_->GetShaders(prim, dec_, &vshader, &fshader, &gshader, pipelineState_, true, useHWTessellation_, decOptions_.expandAllWeightsToFloat, applySkinInDecode_);
_dbg_assert_msg_(vshader->UseHWTransform(), "Bad vshader");
VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(renderManager, pipelineLayout_, pipelineKey_, &dec_->decFmt, vshader, fshader, gshader, true, 0, framebufferManager_->GetMSAALevel(), false);
if (!pipeline || !pipeline->pipeline) {
@@ -381,8 +381,8 @@ void DrawEngineVulkan::Flush() {
}
} else {
PROFILE_THIS_SCOPE("soft");
if (!decOptions_.applySkinInDecode) {
decOptions_.applySkinInDecode = true;
if (!applySkinInDecode_) {
applySkinInDecode_ = true;
lastVType_ |= (1 << 26);
dec_ = GetVertexDecoder(lastVType_);
}
@@ -563,7 +563,7 @@ void DrawEngineVulkan::Flush() {
framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, result.color);
}
}
decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning;
applySkinInDecode_ = g_Config.bSoftwareSkinning;
}
ResetAfterDrawInline();
@@ -581,7 +581,7 @@ void DrawEngineVulkan::ResetAfterDraw() {
vertexCountInDrawCalls_ = 0;
decodeIndsCounter_ = 0;
decodeVertsCounter_ = 0;
decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning;
applySkinInDecode_ = g_Config.bSoftwareSkinning;
gstate_c.vertexFullAlpha = true;
}
+3 -5
View File
@@ -1360,15 +1360,13 @@ void ImGeStateWindow::Draw(ImConfig &cfg, ImControl &control, GPUDebugInterface
if (!gpuDebug->GetCurrentSimpleVertices(rowCount_, vertices, indices)) {
rowCount_ = 0;
}
VertexDecoderOptions options{};
// TODO: Maybe an option?
options.applySkinInDecode = true;
auto buildVertexTable = [&](bool raw) {
// Ignore indices for now.
if (ImGui::BeginTable("rawverts", VERTEXLIST_COL_COUNT + 1, tableFlags)) {
static VertexDecoder decoder;
decoder.SetVertexType(state.vertType, options);
u32 vertTypeID = GetVertTypeID(state.vertType, state.getUVGenMode(), true);
VertexDecoderOptions options{};
decoder.SetVertexType(vertTypeID, options);
static const char * const colNames[] = {
"Index",
+2 -2
View File
@@ -175,8 +175,8 @@ int CtrlVertexList::GetRowCount() {
}
VertexDecoderOptions options{};
// TODO: Maybe an option?
options.applySkinInDecode = true;
decoder->SetVertexType(state.vertType, options);
u32 vertTypeID = GetVertTypeID(state.vertType, state.getUVGenMode(), true);
decoder->SetVertexType(vertTypeID, options);
return rowCount_;
}
+8 -8
View File
@@ -51,7 +51,7 @@ public:
void Reset() {
memset(src_, 0, BUFFER_SIZE);
memset(dst_, 0, BUFFER_SIZE);
memset(&options_, 0, sizeof(options_));
options_ = {};
delete dec_;
dec_ = nullptr;
indexLowerBound_ = 0;
@@ -65,7 +65,7 @@ public:
if (needsReset_) {
Reset();
}
memcpy(&options_, &opts, sizeof(options_));
options_ = opts;
}
void SetIndexLowerBound(const int lower) {
@@ -543,7 +543,6 @@ static bool TestVertexColor565() {
static bool TestVertex8Skin() {
VertexDecoderTestHarness dec;
VertexDecoderOptions opts{};
opts.applySkinInDecode = true;
dec.SetOptions(opts);
for (int i = 0; i < 8 * 12; ++i) {
@@ -558,13 +557,14 @@ static bool TestVertex8Skin() {
gstate.boneMatrix[20] = 5.0f;
int vtype = GE_VTYPE_POS_8BIT | GE_VTYPE_NRM_8BIT | GE_VTYPE_WEIGHT_8BIT | (1 << GE_VTYPE_WEIGHTCOUNT_SHIFT);
u32 vertTypeID = GetVertTypeID(vtype, 0, true); // enable skinning in decode
dec.Add8(128 + 64, 128 - 64);
dec.Add8(127, 0, 128);
dec.Add8(127, 0, 128);
for (int jit = 0; jit <= 1; ++jit) {
dec.Execute(vtype, 0, jit == 1);
dec.Execute(vertTypeID, 0, jit == 1);
dec.AssertFloat("TestVertex8Skin-Nrm", (2.0f * 1.5f + 1.0f * 0.5f) * 127.0f / 128.0f, 0.0f, 2.0f * 5.0f * -1.0f);
dec.AssertFloat("TestVertex8Skin-Pos", (2.0f * 1.5f + 1.0f * 0.5f) * 127.0f / 128.0f, 0.0f, 2.0f * 5.0f * -1.0f);
}
@@ -575,7 +575,6 @@ static bool TestVertex8Skin() {
static bool TestVertex16Skin() {
VertexDecoderTestHarness dec;
VertexDecoderOptions opts{};
opts.applySkinInDecode = true;
dec.SetOptions(opts);
for (int i = 0; i < 8 * 12; ++i) {
@@ -590,13 +589,14 @@ static bool TestVertex16Skin() {
gstate.boneMatrix[20] = 5.0f;
int vtype = GE_VTYPE_POS_16BIT | GE_VTYPE_NRM_16BIT | GE_VTYPE_WEIGHT_16BIT | (1 << GE_VTYPE_WEIGHTCOUNT_SHIFT);
u32 vertTypeID = GetVertTypeID(vtype, 0, true); // enable skinning in decode
dec.Add16(32768 + 16384, 32768 - 16384);
dec.Add16(32767, 0, 32768);
dec.Add16(32767, 0, 32768);
for (int jit = 0; jit <= 1; ++jit) {
dec.Execute(vtype, 0, jit == 1);
dec.Execute(vertTypeID, 0, jit == 1);
dec.AssertFloat("TestVertex16Skin-Nrm", (2.0f * 1.5f + 1.0f * 0.5f) * 32767.0f / 32768.0f, 0.0f, 2.0f * 5.0f * -1.0f);
dec.AssertFloat("TestVertex16Skin-Pos", (2.0f * 1.5f + 1.0f * 0.5f) * 32767.0f / 32768.0f, 0.0f, 2.0f * 5.0f * -1.0f);
}
@@ -607,7 +607,6 @@ static bool TestVertex16Skin() {
static bool TestVertexFloatSkin() {
VertexDecoderTestHarness dec;
VertexDecoderOptions opts{};
opts.applySkinInDecode = true;
dec.SetOptions(opts);
for (int i = 0; i < 8 * 12; ++i) {
@@ -622,13 +621,14 @@ static bool TestVertexFloatSkin() {
gstate.boneMatrix[20] = 5.0f;
int vtype = GE_VTYPE_POS_FLOAT | GE_VTYPE_NRM_FLOAT | GE_VTYPE_WEIGHT_FLOAT | (1 << GE_VTYPE_WEIGHTCOUNT_SHIFT);
u32 vertTypeID = GetVertTypeID(vtype, 0, true); // enable skinning in decode
dec.AddFloat(1.5f, 0.5f);
dec.AddFloat(1.0f, 0, -1.0f);
dec.AddFloat(1.0f, 0, -1.0f);
for (int jit = 0; jit <= 1; ++jit) {
dec.Execute(vtype, 0, jit == 1);
dec.Execute(vertTypeID, 0, jit == 1);
dec.AssertFloat("TestVertexFloatSkin-Nrm", (2.0f * 1.5f + 1.0f * 0.5f) * 1.0f, 0.0f, 2.0f * 5.0f * -1.0f);
dec.AssertFloat("TestVertexFloatSkin-Pos", (2.0f * 1.5f + 1.0f * 0.5f) * 1.0f, 0.0f, 2.0f * 5.0f * -1.0f);
}