mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Merge pull request #16347 from unknownbrackets/softgpu-skin
Always skin in decode for software transform and rendering
This commit is contained in:
31 files changed
+104
-155
No files matched your search
@@ -52,8 +52,7 @@ DrawEngineCommon::~DrawEngineCommon() {
|
||||
}
|
||||
|
||||
void DrawEngineCommon::Init() {
|
||||
useHWTransform_ = g_Config.bHardwareTransform;
|
||||
useHWTessellation_ = UpdateUseHWTessellation(g_Config.bHardwareTessellation);
|
||||
NotifyConfigChanged();
|
||||
}
|
||||
|
||||
VertexDecoder *DrawEngineCommon::GetVertexDecoder(u32 vtype) {
|
||||
@@ -169,7 +168,7 @@ static Vec3f ScreenToDrawing(const Vec3f& coords) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DrawEngineCommon::Resized() {
|
||||
void DrawEngineCommon::NotifyConfigChanged() {
|
||||
decJitCache_->Clear();
|
||||
lastVType_ = -1;
|
||||
dec_ = nullptr;
|
||||
@@ -181,10 +180,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 = (vertType & 0xFFFFFF) | (gstate.getUVGenMode() << 24);
|
||||
const u32 vertTypeID = GetVertTypeID(vertType, gstate.getUVGenMode(), decOptions_.applySkinInDecode);
|
||||
VertexDecoder *dec = GetVertexDecoder(vertTypeID);
|
||||
if (vertexSize)
|
||||
*vertexSize = dec->VertexSize();
|
||||
@@ -232,7 +232,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 +280,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++) {
|
||||
@@ -510,7 +514,7 @@ u32 DrawEngineCommon::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr,
|
||||
};
|
||||
|
||||
// Let's have two separate loops, one for non skinning and one for skinning.
|
||||
if (!g_Config.bSoftwareSkinning && (vertType & GE_VTYPE_WEIGHT_MASK) != GE_VTYPE_WEIGHT_NONE) {
|
||||
if (!dec->skinInDecode && (vertType & GE_VTYPE_WEIGHT_MASK) != GE_VTYPE_WEIGHT_NONE) {
|
||||
int numBoneWeights = vertTypeGetNumBoneWeights(vertType);
|
||||
for (int i = lowerBound; i <= upperBound; i++) {
|
||||
reader.Goto(i - lowerBound);
|
||||
@@ -832,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_++;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -168,29 +168,6 @@ void SoftwareTransform::SetProjMatrix(float mtx[14], bool invertedX, bool invert
|
||||
projMatrix_.translateAndScale(trans, scale);
|
||||
}
|
||||
|
||||
static void ReadWeightedNormal(Vec3f &source, VertexReader &reader, u32 vertType, bool skinningEnabled) {
|
||||
if (reader.hasNormal())
|
||||
reader.ReadNrm(source.AsArray());
|
||||
if (skinningEnabled) {
|
||||
float weights[8];
|
||||
reader.ReadWeights(weights);
|
||||
|
||||
// Have to recalculate this, unfortunately. Please use software skinning...
|
||||
Vec3f nsum(0, 0, 0);
|
||||
for (int i = 0; i < vertTypeGetNumBoneWeights(vertType); i++) {
|
||||
if (weights[i] != 0.0f) {
|
||||
Vec3f norm;
|
||||
Norm3ByMatrix43(norm.AsArray(), source.AsArray(), gstate.boneMatrix + i * 12);
|
||||
nsum += norm * weights[i];
|
||||
}
|
||||
}
|
||||
|
||||
source = nsum;
|
||||
}
|
||||
if (gstate.areNormalsReversed())
|
||||
source = -source;
|
||||
}
|
||||
|
||||
void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVtxFormat, int maxIndex, SoftwareTransformResult *result) {
|
||||
u8 *decoded = params_.decoded;
|
||||
TransformedVertex *transformed = params_.transformed;
|
||||
@@ -204,8 +181,6 @@ void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVt
|
||||
vscale /= gstate_c.curTextureHeight;
|
||||
}
|
||||
|
||||
bool skinningEnabled = vertTypeIsSkinningEnabled(vertType);
|
||||
|
||||
const int w = gstate.getTextureWidth(0);
|
||||
const int h = gstate.getTextureHeight(0);
|
||||
float widthFactor = (float) w / (float) gstate_c.curTextureWidth;
|
||||
@@ -296,47 +271,13 @@ void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVt
|
||||
if (reader.hasNormal())
|
||||
reader.ReadNrm(normal.AsArray());
|
||||
|
||||
if (!skinningEnabled) {
|
||||
Vec3ByMatrix43(out, pos, gstate.worldMatrix);
|
||||
if (reader.hasNormal()) {
|
||||
if (gstate.areNormalsReversed()) {
|
||||
normal = -normal;
|
||||
}
|
||||
Norm3ByMatrix43(worldnormal.AsArray(), normal.AsArray(), gstate.worldMatrix);
|
||||
worldnormal = worldnormal.NormalizedOr001(cpu_info.bSSE4_1);
|
||||
}
|
||||
} else {
|
||||
float weights[8];
|
||||
// For flat, we need the vertex weights.
|
||||
reader.Goto(index);
|
||||
reader.ReadWeights(weights);
|
||||
|
||||
// Skinning
|
||||
Vec3f psum(0, 0, 0);
|
||||
Vec3f nsum(0, 0, 0);
|
||||
for (int i = 0; i < vertTypeGetNumBoneWeights(vertType); i++) {
|
||||
if (weights[i] != 0.0f) {
|
||||
Vec3ByMatrix43(out, pos, gstate.boneMatrix+i*12);
|
||||
Vec3f tpos(out);
|
||||
psum += tpos * weights[i];
|
||||
if (reader.hasNormal()) {
|
||||
Vec3f norm;
|
||||
Norm3ByMatrix43(norm.AsArray(), normal.AsArray(), gstate.boneMatrix+i*12);
|
||||
nsum += norm * weights[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Yes, we really must multiply by the world matrix too.
|
||||
Vec3ByMatrix43(out, psum.AsArray(), gstate.worldMatrix);
|
||||
if (reader.hasNormal()) {
|
||||
normal = nsum;
|
||||
if (gstate.areNormalsReversed()) {
|
||||
normal = -normal;
|
||||
}
|
||||
Norm3ByMatrix43(worldnormal.AsArray(), normal.AsArray(), gstate.worldMatrix);
|
||||
worldnormal = worldnormal.NormalizedOr001(cpu_info.bSSE4_1);
|
||||
Vec3ByMatrix43(out, pos, gstate.worldMatrix);
|
||||
if (reader.hasNormal()) {
|
||||
if (gstate.areNormalsReversed()) {
|
||||
normal = -normal;
|
||||
}
|
||||
Norm3ByMatrix43(worldnormal.AsArray(), normal.AsArray(), gstate.worldMatrix);
|
||||
worldnormal = worldnormal.NormalizedOr001(cpu_info.bSSE4_1);
|
||||
}
|
||||
|
||||
// Perform lighting here if enabled.
|
||||
@@ -398,7 +339,10 @@ void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVt
|
||||
source = normal.Normalized(cpu_info.bSSE4_1);
|
||||
} else {
|
||||
reader.Goto(index);
|
||||
ReadWeightedNormal(source, reader, vertType, skinningEnabled);
|
||||
if (reader.hasNormal())
|
||||
reader.ReadNrm(source.AsArray());
|
||||
if (gstate.areNormalsReversed())
|
||||
source = -source;
|
||||
source.Normalize();
|
||||
}
|
||||
if (!reader.hasNormal()) {
|
||||
@@ -413,7 +357,10 @@ void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVt
|
||||
} else {
|
||||
// Need to read the normal for this vertex and weight it again..
|
||||
reader.Goto(index);
|
||||
ReadWeightedNormal(source, reader, vertType, skinningEnabled);
|
||||
if (reader.hasNormal())
|
||||
reader.ReadNrm(source.AsArray());
|
||||
if (gstate.areNormalsReversed())
|
||||
source = -source;
|
||||
}
|
||||
if (!reader.hasNormal()) {
|
||||
ERROR_LOG_REPORT(G3D, "Normal projection mapping without normal?");
|
||||
|
||||
@@ -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((vertType & 0xFFFFFF) | (gstate.getUVGenMode() << 24));
|
||||
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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -300,8 +300,6 @@ public:
|
||||
bool hasNormal() const { return decFmt_.nrmfmt != 0; }
|
||||
bool hasUV() const { return decFmt_.uvfmt != 0; }
|
||||
bool isThrough() const { return (vtype_ & GE_VTYPE_THROUGH) != 0; }
|
||||
bool skinningEnabled() const { return vertTypeIsSkinningEnabled(vtype_); }
|
||||
int numBoneWeights() const { return vertTypeGetNumBoneWeights(vtype_); }
|
||||
void Goto(int index) {
|
||||
data_ = base_ + index * decFmt_.stride;
|
||||
}
|
||||
@@ -335,6 +333,7 @@ typedef void(*JittedVertexDecoder)(const u8 *src, u8 *dst, int count);
|
||||
struct VertexDecoderOptions {
|
||||
bool expandAllWeightsToFloat;
|
||||
bool expand8BitNormalsToFloat;
|
||||
bool applySkinInDecode;
|
||||
};
|
||||
|
||||
class VertexDecoder {
|
||||
|
||||
@@ -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);
|
||||
@@ -581,6 +581,7 @@ rotateVBO:
|
||||
}
|
||||
} else {
|
||||
PROFILE_THIS_SCOPE("soft");
|
||||
decOptions_.applySkinInDecode = true;
|
||||
DecodeVerts(decoded);
|
||||
bool hasColor = (lastVType_ & GE_VTYPE_COL_MASK) != GE_VTYPE_COL_NONE;
|
||||
if (gstate.isModeThrough()) {
|
||||
@@ -648,7 +649,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());
|
||||
@@ -709,6 +710,7 @@ rotateVBO:
|
||||
framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, clearColor);
|
||||
}
|
||||
}
|
||||
decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning;
|
||||
}
|
||||
|
||||
gpuStats.numDrawCalls += numDrawCalls;
|
||||
|
||||
@@ -150,7 +150,7 @@ public:
|
||||
|
||||
void ClearTrackedVertexArrays() override;
|
||||
|
||||
void Resized() override;
|
||||
void NotifyConfigChanged() override;
|
||||
|
||||
void ClearInputLayoutMap();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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_;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
@@ -546,6 +546,7 @@ rotateVBO:
|
||||
}
|
||||
}
|
||||
} else {
|
||||
decOptions_.applySkinInDecode = true;
|
||||
DecodeVerts(decoded);
|
||||
bool hasColor = (lastVType_ & GE_VTYPE_COL_MASK) != GE_VTYPE_COL_NONE;
|
||||
if (gstate.isModeThrough()) {
|
||||
@@ -613,7 +614,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) {
|
||||
@@ -653,6 +654,7 @@ rotateVBO:
|
||||
framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, clearColor);
|
||||
}
|
||||
}
|
||||
decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning;
|
||||
}
|
||||
|
||||
gpuStats.numDrawCalls += numDrawCalls;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
@@ -331,7 +331,9 @@ void DrawEngineGLES::DoFlush() {
|
||||
}
|
||||
} else {
|
||||
PROFILE_THIS_SCOPE("soft");
|
||||
decOptions_.applySkinInDecode = true;
|
||||
DecodeVerts(decoded);
|
||||
|
||||
bool hasColor = (lastVType_ & GE_VTYPE_COL_MASK) != GE_VTYPE_COL_NONE;
|
||||
if (gstate.isModeThrough()) {
|
||||
gstate_c.vertexFullAlpha = gstate_c.vertexFullAlpha && (hasColor || gstate.getMaterialAmbientA() == 255);
|
||||
@@ -446,6 +448,7 @@ void DrawEngineGLES::DoFlush() {
|
||||
}
|
||||
gstate_c.Dirty(DIRTY_BLEND_STATE); // Make sure the color mask gets re-applied.
|
||||
}
|
||||
decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning;
|
||||
}
|
||||
|
||||
gpuStats.numDrawCalls += numDrawCalls;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -755,10 +755,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_;
|
||||
}
|
||||
@@ -789,7 +789,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
+2
-2
@@ -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;
|
||||
}
|
||||
|
||||
+1
-4
@@ -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 {
|
||||
|
||||
@@ -62,6 +62,11 @@ SoftwareDrawEngine::~SoftwareDrawEngine() {
|
||||
FreeMemoryPages(decIndex, DECODED_INDEX_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
void SoftwareDrawEngine::NotifyConfigChanged() {
|
||||
DrawEngineCommon::NotifyConfigChanged();
|
||||
decOptions_.applySkinInDecode = true;
|
||||
}
|
||||
|
||||
void SoftwareDrawEngine::DispatchFlush() {
|
||||
transformUnit.Flush("debug");
|
||||
}
|
||||
@@ -72,7 +77,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(), true);
|
||||
|
||||
int flipCull = cullMode != gstate.getCullMode() ? 1 : 0;
|
||||
// TODO: For now, just setting all dirty.
|
||||
@@ -137,7 +142,7 @@ void SoftwareDrawEngine::DispatchSubmitImm(GEPrimitiveType prim, TransformedVert
|
||||
}
|
||||
|
||||
VertexDecoder *SoftwareDrawEngine::FindVertexDecoder(u32 vtype) {
|
||||
const u32 vertTypeID = (vtype & 0xFFFFFF) | (gstate.getUVGenMode() << 24);
|
||||
const u32 vertTypeID = GetVertTypeID(vtype, gstate.getUVGenMode(), true);
|
||||
return DrawEngineCommon::GetVertexDecoder(vertTypeID);
|
||||
}
|
||||
|
||||
@@ -245,7 +250,6 @@ struct TransformState {
|
||||
bool enableLighting : 1;
|
||||
bool enableFog : 1;
|
||||
bool readUV : 1;
|
||||
bool readWeights : 1;
|
||||
bool negateNormals : 1;
|
||||
uint8_t uvGenMode : 2;
|
||||
uint8_t matrixMode : 2;
|
||||
@@ -257,7 +261,6 @@ 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->negateNormals = gstate.areNormalsReversed();
|
||||
|
||||
state->uvGenMode = gstate.getUVGenMode();
|
||||
@@ -344,27 +347,6 @@ ClipVertexData TransformUnit::ReadVertex(VertexReader &vreader, const TransformS
|
||||
if (state.negateNormals)
|
||||
normal = -normal;
|
||||
|
||||
if (state.readWeights) {
|
||||
float W[8] = { 1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f };
|
||||
vreader.ReadWeights(W);
|
||||
|
||||
Vec3<float> tmppos(0.f, 0.f, 0.f);
|
||||
Vec3<float> tmpnrm(0.f, 0.f, 0.f);
|
||||
|
||||
for (int i = 0; i < vreader.numBoneWeights(); ++i) {
|
||||
Vec3<float> step = Vec3ByMatrix43(pos, gstate.boneMatrix + i * 12);
|
||||
tmppos += step * W[i];
|
||||
if (vreader.hasNormal()) {
|
||||
step = Norm3ByMatrix43(normal, gstate.boneMatrix + i * 12);
|
||||
tmpnrm += step * W[i];
|
||||
}
|
||||
}
|
||||
|
||||
pos = tmppos;
|
||||
if (vreader.hasNormal())
|
||||
normal = tmpnrm;
|
||||
}
|
||||
|
||||
if (vreader.hasColor0()) {
|
||||
vreader.ReadColor0_8888((u8 *)&vertex.v.color0);
|
||||
} else {
|
||||
@@ -858,7 +840,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(), true);
|
||||
// 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 +940,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()))
|
||||
|
||||
@@ -171,6 +171,7 @@ public:
|
||||
SoftwareDrawEngine();
|
||||
~SoftwareDrawEngine();
|
||||
|
||||
void NotifyConfigChanged() override;
|
||||
void DispatchFlush() override;
|
||||
void DispatchSubmitPrim(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int cullMode, int *bytesRead) override;
|
||||
void DispatchSubmitImm(GEPrimitiveType prim, TransformedVertex *buffer, int vertexCount, int cullMode, bool continuation) override;
|
||||
|
||||
@@ -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;
|
||||
@@ -841,6 +841,7 @@ void DrawEngineVulkan::DoFlush() {
|
||||
}
|
||||
} else {
|
||||
PROFILE_THIS_SCOPE("soft");
|
||||
decOptions_.applySkinInDecode = true;
|
||||
DecodeVerts(decoded);
|
||||
bool hasColor = (lastVType_ & GE_VTYPE_COL_MASK) != GE_VTYPE_COL_NONE;
|
||||
if (gstate.isModeThrough()) {
|
||||
@@ -919,7 +920,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) {
|
||||
@@ -927,6 +928,7 @@ void DrawEngineVulkan::DoFlush() {
|
||||
decodedVerts_ = 0;
|
||||
numDrawCalls = 0;
|
||||
decodeCounter_ = 0;
|
||||
decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning;
|
||||
return;
|
||||
}
|
||||
BindShaderBlendTex(); // This might cause copies so super important to do before BindPipeline.
|
||||
@@ -994,6 +996,7 @@ void DrawEngineVulkan::DoFlush() {
|
||||
framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, result.color);
|
||||
}
|
||||
}
|
||||
decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning;
|
||||
}
|
||||
|
||||
gpuStats.numDrawCalls += numDrawCalls;
|
||||
|
||||
@@ -292,7 +292,7 @@ void GPU_Vulkan::BeginHostFrame() {
|
||||
// In case the GPU changed.
|
||||
BuildReportingInfo();
|
||||
framebufferManager_->Resized();
|
||||
drawEngine_.Resized();
|
||||
drawEngine_.NotifyConfigChanged();
|
||||
textureCache_->NotifyConfigChanged();
|
||||
resized_ = false;
|
||||
}
|
||||
|
||||
@@ -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_;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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_;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user