GPU: Purify vertTypeIsSkinningEnabled().

This commit is contained in:
Unknown W. Brackets 2022-11-06 08:40:54 -08:00
parent 66472c39ce
commit 6c36f03a0d
24 changed files with 45 additions and 50 deletions

View file

@ -52,9 +52,7 @@ DrawEngineCommon::~DrawEngineCommon() {
}
void DrawEngineCommon::Init() {
useHWTransform_ = g_Config.bHardwareTransform;
useHWTessellation_ = UpdateUseHWTessellation(g_Config.bHardwareTessellation);
decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning;
NotifyConfigChanged();
}
VertexDecoder *DrawEngineCommon::GetVertexDecoder(u32 vtype) {
@ -170,7 +168,7 @@ static Vec3f ScreenToDrawing(const Vec3f& coords) {
return ret;
}
void DrawEngineCommon::Resized() {
void DrawEngineCommon::NotifyConfigChanged() {
decJitCache_->Clear();
lastVType_ = -1;
dec_ = nullptr;
@ -838,7 +836,7 @@ void DrawEngineCommon::SubmitPrim(const void *verts, const void *inds, GEPrimiti
numDrawCalls++;
vertexCountInDrawCalls_ += vertexCount;
if (g_Config.bSoftwareSkinning && (vertTypeID & GE_VTYPE_WEIGHT_MASK)) {
if (decOptions_.applySkinInDecode && (vertTypeID & GE_VTYPE_WEIGHT_MASK)) {
DecodeVertsStep(decoded, decodeCounter_, decodedVerts_);
decodeCounter_++;
}

View file

@ -105,7 +105,7 @@ public:
std::vector<std::string> DebugGetVertexLoaderIDs();
std::string DebugGetVertexLoaderString(std::string id, DebugShaderStringType stringType);
virtual void Resized();
virtual void NotifyConfigChanged();
bool IsCodePtrVertexDecoder(const u8 *ptr) const {
return decJitCache_->IsInSpace(ptr);

View file

@ -67,7 +67,7 @@ std::string VertexShaderDesc(const VShaderID &id) {
return desc.str();
}
void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat) {
void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat, bool useSkinInDecode) {
bool isModeThrough = (vertType & GE_VTYPE_THROUGH) != 0;
bool doTexture = gstate.isTextureMapEnabled() && !gstate.isModeClear();
bool doShadeMapping = doTexture && (gstate.getUVGenMode() == GE_TEXMAP_ENVIRONMENT_MAP);
@ -118,7 +118,7 @@ void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform,
}
// Bones.
bool enableBones = vertTypeIsSkinningEnabled(vertType);
bool enableBones = !useSkinInDecode && vertTypeIsSkinningEnabled(vertType);
id.SetBit(VS_BIT_ENABLE_BONES, enableBones);
if (enableBones) {
id.SetBits(VS_BIT_BONES, 3, TranslateNumBones(vertTypeGetNumBoneWeights(vertType)) - 1);

View file

@ -275,7 +275,7 @@ namespace Draw {
class Bugs;
}
void ComputeVertexShaderID(VShaderID *id, uint32_t vertexType, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat);
void ComputeVertexShaderID(VShaderID *id, uint32_t vertexType, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat, bool useSkinInDecode);
// Generates a compact string that describes the shader. Useful in a list to get an overview
// of the current flora of shaders.
std::string VertexShaderDesc(const VShaderID &id);

View file

@ -204,7 +204,7 @@ void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVt
vscale /= gstate_c.curTextureHeight;
}
bool skinningEnabled = vertTypeIsSkinningEnabled(vertType);
bool skinningEnabled = vertTypeIsSkinningEnabled(vertType) && !g_Config.bSoftwareSkinning;
const int w = gstate.getTextureWidth(0);
const int h = gstate.getTextureHeight(0);

View file

@ -130,8 +130,8 @@ void DrawEngineD3D11::ClearInputLayoutMap() {
inputLayoutMap_.Clear();
}
void DrawEngineD3D11::Resized() {
DrawEngineCommon::Resized();
void DrawEngineD3D11::NotifyConfigChanged() {
DrawEngineCommon::NotifyConfigChanged();
ClearInputLayoutMap();
}
@ -365,7 +365,7 @@ void DrawEngineD3D11::DoFlush() {
// Cannot cache vertex data with morph enabled.
bool useCache = g_Config.bVertexCache && !(lastVType_ & GE_VTYPE_MORPHCOUNT_MASK);
// Also avoid caching when software skinning.
if (g_Config.bSoftwareSkinning && (lastVType_ & GE_VTYPE_WEIGHT_MASK))
if (decOptions_.applySkinInDecode && (lastVType_ & GE_VTYPE_WEIGHT_MASK))
useCache = false;
if (useCache) {
@ -538,7 +538,7 @@ rotateVBO:
D3D11VertexShader *vshader;
D3D11FragmentShader *fshader;
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, pipelineState_, useHWTransform, useHWTessellation_, decOptions_.expandAllWeightsToFloat);
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, pipelineState_, useHWTransform, useHWTessellation_, decOptions_.expandAllWeightsToFloat, decOptions_.applySkinInDecode);
ID3D11InputLayout *inputLayout = SetupDecFmtForDraw(vshader, dec_->GetDecVtxFmt(), dec_->VertexType());
context_->PSSetShader(fshader->GetShader(), nullptr, 0);
context_->VSSetShader(vshader->GetShader(), nullptr, 0);
@ -648,7 +648,7 @@ rotateVBO:
if (result.action == SW_DRAW_PRIMITIVES) {
D3D11VertexShader *vshader;
D3D11FragmentShader *fshader;
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, pipelineState_, false, false, decOptions_.expandAllWeightsToFloat);
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, pipelineState_, false, false, decOptions_.expandAllWeightsToFloat, decOptions_.applySkinInDecode);
context_->PSSetShader(fshader->GetShader(), nullptr, 0);
context_->VSSetShader(vshader->GetShader(), nullptr, 0);
shaderManager_->UpdateUniforms(framebufferManager_->UseBufferedRendering());

View file

@ -150,7 +150,7 @@ public:
void ClearTrackedVertexArrays() override;
void Resized() override;
void NotifyConfigChanged() override;
void ClearInputLayoutMap();

View file

@ -176,7 +176,7 @@ void GPU_D3D11::BeginHostFrame() {
if (resized_) {
gstate_c.useFlags = CheckGPUFeatures();
framebufferManager_->Resized();
drawEngine_.Resized();
drawEngine_.NotifyConfigChanged();
textureCache_->NotifyConfigChanged();
shaderManagerD3D11_->DirtyLastShader();
resized_ = false;

View file

@ -179,13 +179,13 @@ void ShaderManagerD3D11::BindUniforms() {
context_->PSSetConstantBuffers(0, 1, ps_cbs);
}
void ShaderManagerD3D11::GetShaders(int prim, u32 vertType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, const ComputedPipelineState &pipelineState, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat) {
void ShaderManagerD3D11::GetShaders(int prim, u32 vertType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, const ComputedPipelineState &pipelineState, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat, bool useSkinInDecode) {
VShaderID VSID;
FShaderID FSID;
if (gstate_c.IsDirty(DIRTY_VERTEXSHADER_STATE)) {
gstate_c.Clean(DIRTY_VERTEXSHADER_STATE);
ComputeVertexShaderID(&VSID, vertType, useHWTransform, useHWTessellation, weightsAsFloat);
ComputeVertexShaderID(&VSID, vertType, useHWTransform, useHWTessellation, weightsAsFloat, useSkinInDecode);
} else {
VSID = lastVSID_;
}

View file

@ -85,7 +85,7 @@ public:
ShaderManagerD3D11(Draw::DrawContext *draw, ID3D11Device *device, ID3D11DeviceContext *context, D3D_FEATURE_LEVEL featureLevel);
~ShaderManagerD3D11();
void GetShaders(int prim, u32 vertType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, const ComputedPipelineState &pipelineState, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat);
void GetShaders(int prim, u32 vertType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, const ComputedPipelineState &pipelineState, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat, bool useSkinInDecode);
void ClearShaders();
void DirtyLastShader() override;

View file

@ -349,7 +349,7 @@ void DrawEngineDX9::DoFlush() {
// Cannot cache vertex data with morph enabled.
bool useCache = g_Config.bVertexCache && !(lastVType_ & GE_VTYPE_MORPHCOUNT_MASK);
// Also avoid caching when software skinning.
if (g_Config.bSoftwareSkinning && (lastVType_ & GE_VTYPE_WEIGHT_MASK))
if (decOptions_.applySkinInDecode && (lastVType_ & GE_VTYPE_WEIGHT_MASK))
useCache = false;
if (useCache) {
@ -522,7 +522,7 @@ rotateVBO:
ApplyDrawState(prim);
ApplyDrawStateLate();
VSShader *vshader = shaderManager_->ApplyShader(true, useHWTessellation_, lastVType_, decOptions_.expandAllWeightsToFloat, pipelineState_);
VSShader *vshader = shaderManager_->ApplyShader(true, useHWTessellation_, lastVType_, decOptions_.expandAllWeightsToFloat, decOptions_.applySkinInDecode, pipelineState_);
IDirect3DVertexDeclaration9 *pHardwareVertexDecl = SetupDecFmtForDraw(vshader, dec_->GetDecVtxFmt(), dec_->VertexType());
if (pHardwareVertexDecl) {
@ -613,7 +613,7 @@ rotateVBO:
ApplyDrawStateLate();
VSShader *vshader = shaderManager_->ApplyShader(false, false, lastVType_, decOptions_.expandAllWeightsToFloat, pipelineState_);
VSShader *vshader = shaderManager_->ApplyShader(false, false, lastVType_, decOptions_.expandAllWeightsToFloat, decOptions_.applySkinInDecode, pipelineState_);
if (result.action == SW_DRAW_PRIMITIVES) {
if (result.setStencil) {

View file

@ -165,9 +165,9 @@ void GPU_DX9::BeginHostFrame() {
if (resized_) {
gstate_c.useFlags = CheckGPUFeatures();
framebufferManager_->Resized();
drawEngine_.Resized();
shaderManagerDX9_->DirtyShader();
drawEngine_.NotifyConfigChanged();
textureCache_->NotifyConfigChanged();
shaderManagerDX9_->DirtyShader();
resized_ = false;
}
}

View file

@ -544,11 +544,11 @@ void ShaderManagerDX9::DirtyLastShader() { // disables vertex arrays
lastPShader_ = nullptr;
}
VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellation, u32 vertType, bool weightsAsFloat, const ComputedPipelineState &pipelineState) {
VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellation, u32 vertType, bool weightsAsFloat, bool useSkinInDecode, const ComputedPipelineState &pipelineState) {
VShaderID VSID;
if (gstate_c.IsDirty(DIRTY_VERTEXSHADER_STATE)) {
gstate_c.Clean(DIRTY_VERTEXSHADER_STATE);
ComputeVertexShaderID(&VSID, vertType, useHWTransform, useHWTessellation, weightsAsFloat);
ComputeVertexShaderID(&VSID, vertType, useHWTransform, useHWTessellation, weightsAsFloat, useSkinInDecode);
} else {
VSID = lastVSID_;
}
@ -597,7 +597,7 @@ VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellat
}
delete vs;
ComputeVertexShaderID(&VSID, vertType, false, false, weightsAsFloat);
ComputeVertexShaderID(&VSID, vertType, false, false, weightsAsFloat, useSkinInDecode);
// TODO: Look for existing shader with the appropriate ID, use that instead of generating a new one - however, need to make sure
// that that shader ID is not used when computing the linked shader ID below, because then IDs won't match

View file

@ -78,7 +78,7 @@ public:
~ShaderManagerDX9();
void ClearCache(bool deleteThem); // TODO: deleteThem currently not respected
VSShader *ApplyShader(bool useHWTransform, bool useHWTessellation, u32 vertType, bool weightsAsFloat, const ComputedPipelineState &pipelineState);
VSShader *ApplyShader(bool useHWTransform, bool useHWTessellation, u32 vertType, bool weightsAsFloat, bool useSkinInDecode, const ComputedPipelineState &pipelineState);
void DirtyShader();
void DirtyLastShader() override;

View file

@ -267,7 +267,7 @@ void DrawEngineGLES::DoFlush() {
GEPrimitiveType prim = prevPrim_;
VShaderID vsid;
Shader *vshader = shaderManager_->ApplyVertexShader(CanUseHardwareTransform(prim), useHWTessellation_, lastVType_, decOptions_.expandAllWeightsToFloat, &vsid);
Shader *vshader = shaderManager_->ApplyVertexShader(CanUseHardwareTransform(prim), useHWTessellation_, lastVType_, decOptions_.expandAllWeightsToFloat, decOptions_.applySkinInDecode, &vsid);
GLRBuffer *vertexBuffer = nullptr;
GLRBuffer *indexBuffer = nullptr;
@ -278,7 +278,7 @@ void DrawEngineGLES::DoFlush() {
int vertexCount = 0;
bool useElements = true;
if (g_Config.bSoftwareSkinning && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) {
if (decOptions_.applySkinInDecode && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) {
// If software skinning, we've already predecoded into "decoded". So push that content.
size_t size = decodedVerts_ * dec_->GetDecVtxFmt().stride;
u8 *dest = (u8 *)frameData.pushVertex->Push(size, &vertexBufferOffset, &vertexBuffer);

View file

@ -291,9 +291,9 @@ void GPU_GLES::BeginHostFrame() {
if (resized_) {
gstate_c.useFlags = CheckGPUFeatures();
framebufferManager_->Resized();
drawEngine_.Resized();
shaderManagerGL_->DirtyShader();
drawEngine_.NotifyConfigChanged();
textureCache_->NotifyConfigChanged();
shaderManagerGL_->DirtyShader();
resized_ = false;
}

View file

@ -754,10 +754,10 @@ Shader *ShaderManagerGLES::CompileVertexShader(VShaderID VSID) {
return new Shader(render_, codeBuffer_, desc, params);
}
Shader *ShaderManagerGLES::ApplyVertexShader(bool useHWTransform, bool useHWTessellation, u32 vertType, bool weightsAsFloat, VShaderID *VSID) {
Shader *ShaderManagerGLES::ApplyVertexShader(bool useHWTransform, bool useHWTessellation, u32 vertType, bool weightsAsFloat, bool useSkinInDecode, VShaderID *VSID) {
if (gstate_c.IsDirty(DIRTY_VERTEXSHADER_STATE)) {
gstate_c.Clean(DIRTY_VERTEXSHADER_STATE);
ComputeVertexShaderID(VSID, vertType, useHWTransform, useHWTessellation, weightsAsFloat);
ComputeVertexShaderID(VSID, vertType, useHWTransform, useHWTessellation, weightsAsFloat, useSkinInDecode);
} else {
*VSID = lastVSID_;
}
@ -788,7 +788,7 @@ Shader *ShaderManagerGLES::ApplyVertexShader(bool useHWTransform, bool useHWTess
// Can still work with software transform.
VShaderID vsidTemp;
ComputeVertexShaderID(&vsidTemp, vertType, false, false, weightsAsFloat);
ComputeVertexShaderID(&vsidTemp, vertType, false, false, weightsAsFloat, useSkinInDecode);
vs = CompileVertexShader(vsidTemp);
}

View file

@ -161,7 +161,7 @@ public:
// This is the old ApplyShader split into two parts, because of annoying information dependencies.
// If you call ApplyVertexShader, you MUST call ApplyFragmentShader soon afterwards.
Shader *ApplyVertexShader(bool useHWTransform, bool useHWTessellation, u32 vertType, bool weightsAsFloat, VShaderID *VSID);
Shader *ApplyVertexShader(bool useHWTransform, bool useHWTessellation, u32 vertType, bool weightsAsFloat, bool useSkinInDecode, VShaderID *VSID);
LinkedShader *ApplyFragmentShader(VShaderID VSID, Shader *vs, const ComputedPipelineState &pipelineState, u32 vertType, bool useBufferedRendering);
void DeviceLost();

View file

@ -261,10 +261,7 @@ void GPUgstate::Restore(u32_le *ptr) {
}
bool vertTypeIsSkinningEnabled(u32 vertType) {
if (g_Config.bSoftwareSkinning)
return false;
else
return ((vertType & GE_VTYPE_WEIGHT_MASK) != GE_VTYPE_WEIGHT_NONE);
return ((vertType & GE_VTYPE_WEIGHT_MASK) != GE_VTYPE_WEIGHT_NONE);
}
struct GPUStateCache_v0 {

View file

@ -257,7 +257,7 @@ void ComputeTransformState(TransformState *state, const VertexReader &vreader) {
state->enableLighting = gstate.isLightingEnabled();
state->enableFog = gstate.isFogEnabled();
state->readUV = !gstate.isModeClear() && gstate.isTextureMapEnabled() && vreader.hasUV();
state->readWeights = vreader.skinningEnabled() && state->enableTransform;
state->readWeights = vreader.skinningEnabled() && state->enableTransform && !g_Config.bSoftwareSkinning;
state->negateNormals = gstate.areNormalsReversed();
state->uvGenMode = gstate.getUVGenMode();

View file

@ -599,7 +599,7 @@ void DrawEngineVulkan::DoFlush() {
// Also avoid caching when software skinning.
VkBuffer vbuf = VK_NULL_HANDLE;
VkBuffer ibuf = VK_NULL_HANDLE;
if (g_Config.bSoftwareSkinning && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) {
if (decOptions_.applySkinInDecode && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) {
useCache = false;
}
@ -739,7 +739,7 @@ void DrawEngineVulkan::DoFlush() {
break;
}
} else {
if (g_Config.bSoftwareSkinning && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) {
if (decOptions_.applySkinInDecode && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) {
// If software skinning, we've already predecoded into "decoded". So push that content.
VkDeviceSize size = decodedVerts_ * dec_->GetDecVtxFmt().stride;
u8 *dest = (u8 *)frameData.pushVertex->Push(size, &vbOffset, &vbuf);
@ -784,7 +784,7 @@ void DrawEngineVulkan::DoFlush() {
VulkanFragmentShader *fshader = nullptr;
VulkanGeometryShader *gshader = nullptr;
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, &gshader, pipelineState_, true, useHWTessellation_, decOptions_.expandAllWeightsToFloat); // usehwtransform
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, &gshader, pipelineState_, true, useHWTessellation_, decOptions_.expandAllWeightsToFloat, decOptions_.applySkinInDecode);
if (!vshader) {
// We're screwed.
return;
@ -919,7 +919,7 @@ void DrawEngineVulkan::DoFlush() {
VulkanFragmentShader *fshader = nullptr;
VulkanGeometryShader *gshader = nullptr;
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, &gshader, pipelineState_, false, false, decOptions_.expandAllWeightsToFloat); // usehwtransform
shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, &gshader, pipelineState_, false, false, decOptions_.expandAllWeightsToFloat, decOptions_.applySkinInDecode);
_dbg_assert_msg_(!vshader->UseHWTransform(), "Bad vshader");
VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(renderManager, pipelineLayout_, pipelineKey_, &dec_->decFmt, vshader, fshader, gshader, false, 0);
if (!pipeline || !pipeline->pipeline) {

View file

@ -292,7 +292,7 @@ void GPU_Vulkan::BeginHostFrame() {
// In case the GPU changed.
BuildReportingInfo();
framebufferManager_->Resized();
drawEngine_.Resized();
drawEngine_.NotifyConfigChanged();
textureCache_->NotifyConfigChanged();
resized_ = false;
}

View file

@ -280,11 +280,11 @@ uint64_t ShaderManagerVulkan::UpdateUniforms(bool useBufferedRendering) {
return dirty;
}
void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader, VulkanGeometryShader **gshader, const ComputedPipelineState &pipelineState, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat) {
void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader, VulkanGeometryShader **gshader, const ComputedPipelineState &pipelineState, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat, bool useSkinInDecode) {
VShaderID VSID;
if (gstate_c.IsDirty(DIRTY_VERTEXSHADER_STATE)) {
gstate_c.Clean(DIRTY_VERTEXSHADER_STATE);
ComputeVertexShaderID(&VSID, vertType, useHWTransform, useHWTessellation, weightsAsFloat);
ComputeVertexShaderID(&VSID, vertType, useHWTransform, useHWTessellation, weightsAsFloat, useSkinInDecode);
} else {
VSID = lastVSID_;
}

View file

@ -115,7 +115,7 @@ public:
void DeviceLost();
void DeviceRestore(Draw::DrawContext *draw);
void GetShaders(int prim, u32 vertType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader, VulkanGeometryShader **gshader, const ComputedPipelineState &pipelineState, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat);
void GetShaders(int prim, u32 vertType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader, VulkanGeometryShader **gshader, const ComputedPipelineState &pipelineState, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat, bool useSkinInDecode);
void ClearShaders();
void DirtyShader();
void DirtyLastShader() override;