Permalink
Browse files

Merge pull request #11230 from unknownbrackets/flat-shade

Re-enable HW tess for flat shading, but disable in throughmode
  • Loading branch information...
hrydgard committed Jun 29, 2018
2 parents 5abf324 + 2a13a66 commit 5e6429abf7aec28a64395496dec1ae2ea539181f
@@ -24,6 +24,7 @@
#include "Common/MemoryUtil.h"
#include "Core/Config.h"
#include "GPU/Common/GPUStateUtils.h"
#include "GPU/Common/SplineCommon.h"
#include "GPU/Common/DrawEngineCommon.h"
#include "GPU/ge_constants.h"
@@ -223,6 +224,13 @@ static void spline_knot(int n, int type, float *knot) {
}
}
bool CanUseHardwareTessellation(GEPatchPrimType prim) {
if (g_Config.bHardwareTessellation && !g_Config.bSoftwareRendering) {
return CanUseHardwareTransform(PatchPrimToPrim(prim));
}
return false;
}
// Prepare mesh of one patch for "Instanced Tessellation".
static void TessellateSplinePatchHardware(u8 *&dest, u16 *indices, int &count, const SplinePatchLocal &spatch) {
SimpleVertex *&vertices = (SimpleVertex*&)dest;
@@ -841,9 +849,6 @@ void TessellateBezierPatch(u8 *&dest, u16 *&indices, int &count, int tess_u, int
}
}
// This maps GEPatchPrimType to GEPrimitiveType.
const GEPrimitiveType primType[] = { GE_PRIM_TRIANGLES, GE_PRIM_LINES, GE_PRIM_POINTS, GE_PRIM_POINTS };
void DrawEngineCommon::SubmitSpline(const void *control_points, const void *indices, int tess_u, int tess_v, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, bool computeNormals, bool patchFacing, u32 vertType, int *bytesRead) {
PROFILE_THIS_SCOPE("spline");
DispatchFlush();
@@ -900,8 +905,7 @@ void DrawEngineCommon::SubmitSpline(const void *control_points, const void *indi
patch.primType = prim_type;
patch.patchFacing = patchFacing;
if (g_Config.bHardwareTessellation && g_Config.bHardwareTransform && !g_Config.bSoftwareRendering) {
if (CanUseHardwareTessellation(prim_type)) {
float *pos = (float*)(decoded + 65536 * 18); // Size 4 float
float *tex = pos + count_u * count_v * 4; // Size 4 float
float *col = tex + count_u * count_v * 4; // Size 4 float
@@ -952,7 +956,7 @@ void DrawEngineCommon::SubmitSpline(const void *control_points, const void *indi
uint32_t vertTypeID = GetVertTypeID(vertTypeWithIndex16, gstate.getUVGenMode());
int generatedBytesRead;
DispatchSubmitPrim(splineBuffer, quadIndices_, primType[prim_type], count, vertTypeID, &generatedBytesRead);
DispatchSubmitPrim(splineBuffer, quadIndices_, PatchPrimToPrim(prim_type), count, vertTypeID, &generatedBytesRead);
DispatchFlush();
@@ -1006,7 +1010,7 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi
int num_patches_u = (count_u - 1) / 3;
int num_patches_v = (count_v - 1) / 3;
BezierPatch *patches = nullptr;
if (g_Config.bHardwareTessellation && g_Config.bHardwareTransform && !g_Config.bSoftwareRendering) {
if (CanUseHardwareTessellation(prim_type)) {
int posStride, texStride, colStride;
tessDataTransfer->PrepareBuffers(pos, tex, col, posStride, texStride, colStride, count_u * count_v, hasColor, hasTexCoords);
float *p = pos;
@@ -1063,7 +1067,7 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi
}
u16 *inds = quadIndices_;
if (g_Config.bHardwareTessellation && g_Config.bHardwareTransform && !g_Config.bSoftwareRendering) {
if (CanUseHardwareTessellation(prim_type)) {
tessDataTransfer->SendDataToShader(pos, tex, col, count_u * count_v, hasColor, hasTexCoords);
TessellateBezierPatchHardware(dest, inds, count, tess_u, tess_v, prim_type);
numPatches = num_patches_u * num_patches_v;
@@ -1095,7 +1099,7 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi
uint32_t vertTypeID = GetVertTypeID(vertTypeWithIndex16, gstate.getUVGenMode());
int generatedBytesRead;
DispatchSubmitPrim(splineBuffer, quadIndices_, primType[prim_type], count, vertTypeID, &generatedBytesRead);
DispatchSubmitPrim(splineBuffer, quadIndices_, PatchPrimToPrim(prim_type), count, vertTypeID, &generatedBytesRead);
DispatchFlush();
@@ -66,5 +66,6 @@ enum SplineQuality {
HIGH_QUALITY = 2,
};
bool CanUseHardwareTessellation(GEPatchPrimType prim);
void TessellateSplinePatch(u8 *&dest, u16 *indices, int &count, const SplinePatchLocal &spatch, u32 origVertType, int maxVertices);
void TessellateBezierPatch(u8 *&dest, u16 *&indices, int &count, int tess_u, int tess_v, const BezierPatch &patch, u32 origVertType);
@@ -325,14 +325,15 @@ void DrawEngineD3D11::DoFlush() {
gpuStats.numFlushes++;
gpuStats.numTrackedVertexArrays = (int)vai_.size();
// This is not done on every drawcall, we should collect vertex data
// This is not done on every drawcall, we collect vertex data
// until critical state changes. That's when we draw (flush).
GEPrimitiveType prim = prevPrim_;
ApplyDrawState(prim);
// Always use software for flat shading to fix the provoking index.
bool useHWTransform = CanUseHardwareTransform(prim) && gstate.getShadeMode() != GE_SHADE_FLAT;
bool tess = gstate_c.bezier || gstate_c.spline;
bool useHWTransform = CanUseHardwareTransform(prim) && (tess || gstate.getShadeMode() != GE_SHADE_FLAT);
if (useHWTransform) {
ID3D11Buffer *vb_ = nullptr;
@@ -539,7 +540,7 @@ void DrawEngineD3D11::DoFlush() {
memcpy(iptr, decIndex, iSize);
pushInds_->EndPush(context_);
context_->IASetIndexBuffer(pushInds_->Buf(), DXGI_FORMAT_R16_UINT, iOffset);
if (gstate_c.bezier || gstate_c.spline)
if (tess)
context_->DrawIndexedInstanced(vertexCount, numPatches, 0, 0, 0);
else
context_->DrawIndexed(vertexCount, 0, 0);
@@ -551,7 +552,7 @@ void DrawEngineD3D11::DoFlush() {
context_->IASetVertexBuffers(0, 1, &vb_, &stride, &offset);
if (useElements) {
context_->IASetIndexBuffer(ib_, DXGI_FORMAT_R16_UINT, 0);
if (gstate_c.bezier || gstate_c.spline)
if (tess)
context_->DrawIndexedInstanced(vertexCount, numPatches, 0, 0, 0);
else
context_->DrawIndexed(vertexCount, 0, 0);
@@ -538,7 +538,8 @@ void ShaderManagerDX9::DirtyLastShader() { // disables vertex arrays
VSShader *ShaderManagerDX9::ApplyShader(int prim, u32 vertType) {
// Always use software for flat shading to fix the provoking index.
bool useHWTransform = CanUseHardwareTransform(prim) && gstate.getShadeMode() != GE_SHADE_FLAT;
bool tess = gstate_c.bezier || gstate_c.spline;
bool useHWTransform = CanUseHardwareTransform(prim) && (tess || gstate.getShadeMode() != GE_SHADE_FLAT);
VShaderID VSID;
if (gstate_c.IsDirty(DIRTY_VERTEXSHADER_STATE)) {
View
@@ -24,9 +24,10 @@
#include "Core/HLE/sceGe.h"
#include "Core/Debugger/Breakpoints.h"
#include "Core/MemMapHelpers.h"
#include "GPU/Common/DrawEngineCommon.h"
#include "GPU/Common/FramebufferCommon.h"
#include "GPU/Common/SplineCommon.h"
#include "GPU/Common/TextureCacheCommon.h"
#include "GPU/Common/DrawEngineCommon.h"
#include "GPU/Debugger/Record.h"
const CommonCommandTableEntry commonCommandTable[] = {
@@ -1729,7 +1730,7 @@ void GPUCommon::Execute_Bezier(u32 op, u32 diff) {
bool computeNormals = gstate.isLightingEnabled();
bool patchFacing = gstate.patchfacing & 1;
if (g_Config.bHardwareTessellation && g_Config.bHardwareTransform && !g_Config.bSoftwareRendering) {
if (CanUseHardwareTessellation(patchPrim)) {
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE);
gstate_c.bezier = true;
if (gstate_c.spline_count_u != bz_ucount) {
@@ -1793,7 +1794,7 @@ void GPUCommon::Execute_Spline(u32 op, u32 diff) {
bool patchFacing = gstate.patchfacing & 1;
u32 vertType = gstate.vertType;
if (g_Config.bHardwareTessellation && g_Config.bHardwareTransform && !g_Config.bSoftwareRendering) {
if (CanUseHardwareTessellation(patchPrim)) {
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE);
gstate_c.spline = true;
bool countsChanged = gstate_c.spline_count_u != sp_ucount || gstate_c.spline_count_v != sp_vcount;
@@ -578,7 +578,7 @@ void DrawEngineVulkan::DoFlush() {
GEPrimitiveType prim = prevPrim_;
// Always use software for flat shading to fix the provoking index.
bool useHWTransform = CanUseHardwareTransform(prim) && gstate.getShadeMode() != GE_SHADE_FLAT;
bool useHWTransform = CanUseHardwareTransform(prim) && (tess || gstate.getShadeMode() != GE_SHADE_FLAT);
VulkanVertexShader *vshader = nullptr;
VulkanFragmentShader *fshader = nullptr;
View
@@ -563,7 +563,7 @@ inline GEPrimitiveType PatchPrimToPrim(GEPatchPrimType type) {
case GE_PATCHPRIM_TRIANGLES: return GE_PRIM_TRIANGLES;
case GE_PATCHPRIM_LINES: return GE_PRIM_LINES;
case GE_PATCHPRIM_POINTS: return GE_PRIM_POINTS;
case GE_PATCHPRIM_UNKNOWN: default: return GE_PRIM_KEEP_PREVIOUS; // just something
case GE_PATCHPRIM_UNKNOWN: default: return GE_PRIM_POINTS; // Treated as points.
}
}

0 comments on commit 5e6429a

Please sign in to comment.