diff --git a/Common/GPU/Vulkan/VulkanRenderManager.h b/Common/GPU/Vulkan/VulkanRenderManager.h index 95f9658510..2469ef37b2 100644 --- a/Common/GPU/Vulkan/VulkanRenderManager.h +++ b/Common/GPU/Vulkan/VulkanRenderManager.h @@ -199,7 +199,7 @@ static_assert(sizeof(PackedDescriptor::buffer) == 16, "PackedDescriptor should b struct VKRPipelineLayout { ~VKRPipelineLayout(); - enum { MAX_DESC_SET_BINDINGS = 10 }; + enum { MAX_DESC_SET_BINDINGS = 6 }; BindingType bindingTypes[MAX_DESC_SET_BINDINGS]; uint32_t bindingTypesCount = 0; diff --git a/Core/Config.cpp b/Core/Config.cpp index a29d4971b6..14c66cbbc1 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -774,7 +774,6 @@ static const ConfigSetting graphicsSettings[] = { // Not really a graphics setting... ConfigSetting("SplineBezierQuality", SETTING(g_Config, iSplineBezierQuality), 2, CfgFlag::PER_GAME | CfgFlag::REPORT), - ConfigSetting("HardwareTessellation", SETTING(g_Config, bHardwareTessellation), false, CfgFlag::PER_GAME | CfgFlag::REPORT), ConfigSetting("TextureShader", SETTING(g_Config, sTextureShaderName), "Off", CfgFlag::PER_GAME), ConfigSetting("ShaderChainRequires60FPS", SETTING(g_Config, bShaderChainRequires60FPS), false, CfgFlag::PER_GAME), diff --git a/Core/Config.h b/Core/Config.h index 6faa70303c..0fabad5be4 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -362,7 +362,6 @@ public: int iBloomHack; //0 = off, 1 = safe, 2 = balanced, 3 = aggressive int iSkipGPUReadbackMode; // 0 = off, 1 = skip, 2 = to texture int iSplineBezierQuality; // 0 = low , 1 = Intermediate , 2 = High - bool bHardwareTessellation; bool bShaderCache; // Hidden ini-only setting, useful for debugging shader compile times. bool bUberShaderVertex; int iDefaultTab; diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index 3f239901c0..f6779f3292 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -115,7 +115,6 @@ void DrawEngineCommon::NotifyConfigChanged() { decoderMap_.Clear(); useHWTransform_ = g_Config.bHardwareTransform; - useHWTessellation_ = UpdateUseHWTessellation(g_Config.bHardwareTessellation); } void DrawEngineCommon::DispatchSubmitImm(GEPrimitiveType prim, TransformedVertex *buffer, int vertexCount, int cullMode, bool continuation) { @@ -979,35 +978,6 @@ bool DrawEngineCommon::CanUseHardwareTransform(int prim) const { return !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && prim > GE_PRIM_LINE_STRIP; } -bool DrawEngineCommon::CanUseHardwareTessellation(GEPatchPrimType prim) const { - if (useHWTessellation_) { - return CanUseHardwareTransform(PatchPrimToPrim(prim)); - } - return false; -} - -void TessellationDataTransfer::CopyControlPoints(float *pos, float *tex, float *col, int posStride, int texStride, int colStride, const SimpleVertex *const *points, int size, u32 vertType) { - bool hasColor = (vertType & GE_VTYPE_COL_MASK) != 0; - bool hasTexCoord = (vertType & GE_VTYPE_TC_MASK) != 0; - - for (int i = 0; i < size; ++i) { - memcpy(pos, points[i]->pos.AsArray(), 3 * sizeof(float)); - pos += posStride; - } - if (hasTexCoord) { - for (int i = 0; i < size; ++i) { - memcpy(tex, points[i]->uv, 2 * sizeof(float)); - tex += texStride; - } - } - if (hasColor) { - for (int i = 0; i < size; ++i) { - memcpy(col, Vec4f::FromRGBA(points[i]->color_32).AsArray(), 4 * sizeof(float)); - col += colStride; - } - } -} - bool DrawEngineCommon::DescribeCodePtr(const u8 *ptr, std::string &name) const { if (!decJitCache_ || !decJitCache_->IsInSpace(ptr)) { return false; diff --git a/GPU/Common/DrawEngineCommon.h b/GPU/Common/DrawEngineCommon.h index ee2bd9e8c8..bdeca83a83 100644 --- a/GPU/Common/DrawEngineCommon.h +++ b/GPU/Common/DrawEngineCommon.h @@ -59,13 +59,6 @@ enum FBOTexState { struct SimpleVertex; namespace Spline { struct Weight2D; } -class TessellationDataTransfer { -public: - virtual ~TessellationDataTransfer() {} - static void CopyControlPoints(float *pos, float *tex, float *col, int posStride, int texStride, int colStride, const SimpleVertex *const *points, int size, u32 vertType); - virtual void SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Spline::Weight2D &weights) = 0; -}; - // Culling plane, group of 8. struct alignas(16) Plane8 { float x[8], y[8], z[8], w[8]; @@ -129,7 +122,6 @@ public: static void ClearSplineBezierWeights(); bool CanUseHardwareTransform(int prim) const; - bool CanUseHardwareTessellation(GEPatchPrimType prim) const; std::vector DebugGetVertexLoaderIDs(); std::string DebugGetVertexLoaderString(std::string_view id, DebugShaderStringType stringType); @@ -164,8 +156,6 @@ public: void FlushQueuedDepth(); protected: - virtual bool UpdateUseHWTessellation(bool enabled) const { return enabled; } - bool CheckClipFlags(bool useHwTransform) const; void DecodeVerts(const VertexDecoder *dec, u8 *dest); @@ -273,7 +263,6 @@ protected: } bool useHWTransform_ = false; - bool useHWTessellation_ = false; // Used to prevent unnecessary flushing in softgpu. bool flushOnParams_ = true; @@ -346,9 +335,6 @@ protected: ComputedPipelineState pipelineState_{}; - // Hardware tessellation - TessellationDataTransfer *tessDataTransfer = nullptr; - GPUCommon *gpuCommon_ = nullptr; // Software depth raster diff --git a/GPU/Common/ShaderCommon.h b/GPU/Common/ShaderCommon.h index 7cc848a0c1..3e5fe40d8a 100644 --- a/GPU/Common/ShaderCommon.h +++ b/GPU/Common/ShaderCommon.h @@ -68,10 +68,10 @@ enum : uint64_t { DIRTY_SHADERBLEND = 1ULL << 17, // Used only for in-shader blending. DIRTY_UVSCALEOFFSET = 1ULL << 18, - // Free bit 19! + // Free uniform bit 19! DIRTY_VIEWPORT_UNIFORMS = 1ULL << 20, - // Free bit 20! + // Free uniform bit 20! DIRTY_WORLDMATRIX = 1ULL << 21, DIRTY_VIEWMATRIX = 1ULL << 22, @@ -85,9 +85,9 @@ enum : uint64_t { DIRTY_BONEMATRIX6 = 1ULL << 30, DIRTY_BONEMATRIX7 = 1ULL << 31, - DIRTY_BEZIERSPLINE = 1ULL << 32, + // Free uniform bit 32!, DIRTY_TEXCLAMP = 1ULL << 33, - // Free bit 34! + // Free uniform bit 34! DIRTY_DEPAL = 1ULL << 35, DIRTY_COLORWRITEMASK = 1ULL << 36, diff --git a/GPU/Common/ShaderId.cpp b/GPU/Common/ShaderId.cpp index 929a85146e..7affca5b5f 100644 --- a/GPU/Common/ShaderId.cpp +++ b/GPU/Common/ShaderId.cpp @@ -55,12 +55,6 @@ std::string VertexShaderDesc(const VShaderID &id) { if (id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2)) desc << "WScale " << id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2) << " "; if (id.Bit(VS_BIT_FLATSHADE)) desc << "Flat "; - if (id.Bit(VS_BIT_BEZIER)) desc << "Bezier "; - if (id.Bit(VS_BIT_SPLINE)) desc << "Spline "; - if (id.Bit(VS_BIT_HAS_COLOR_TESS)) desc << "TessC "; - if (id.Bit(VS_BIT_HAS_TEXCOORD_TESS)) desc << "TessT "; - if (id.Bit(VS_BIT_HAS_NORMAL_TESS)) desc << "TessN "; - if (id.Bit(VS_BIT_NORM_REVERSE_TESS)) desc << "TessRevN "; if (id.Bit(VS_BIT_VERTEX_RANGE_CULLING)) desc << "RangeCull "; if (id.Bit(VS_BIT_SIMPLE_STEREO)) desc << "SimpleStereo "; @@ -70,7 +64,7 @@ std::string VertexShaderDesc(const VShaderID &id) { return desc.str(); } -void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat, bool useSkinInDecode, ClipInfoFlags clipInfoFlags) { +void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform, bool weightsAsFloat, bool useSkinInDecode, ClipInfoFlags clipInfoFlags) { const bool isModeThrough = (vertType & GE_VTYPE_THROUGH) != 0; const bool isSoftwareFallback = !isModeThrough && !useHWTransform && g_Config.bHardwareTransform; bool doTexture = gstate.isTextureMapEnabled() && !gstate.isModeClear(); @@ -151,18 +145,6 @@ void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform, id.SetBit(VS_BIT_NORM_REVERSE, gstate.areNormalsReversed()); id.SetBit(VS_BIT_HAS_TEXCOORD, vtypeHasTexcoord); - - if (useHWTessellation) { - id.SetBit(VS_BIT_BEZIER, doBezier); - id.SetBit(VS_BIT_SPLINE, doSpline); - if (doBezier || doSpline) { - // These are the original vertType's values (normalized will always have colors, etc.) - id.SetBit(VS_BIT_HAS_COLOR_TESS, (gstate.vertType & GE_VTYPE_COL_MASK) != 0); - id.SetBit(VS_BIT_HAS_TEXCOORD_TESS, (gstate.vertType & GE_VTYPE_TC_MASK) != 0); - id.SetBit(VS_BIT_HAS_NORMAL_TESS, (gstate.vertType & GE_VTYPE_NRM_MASK) != 0 || gstate.isLightingEnabled()); - } - id.SetBit(VS_BIT_NORM_REVERSE_TESS, gstate.isPatchNormalsReversed()); - } } if (clipInfoFlags & ClipInfoFlags::DepthClampFragment) { diff --git a/GPU/Common/ShaderId.h b/GPU/Common/ShaderId.h index c5a97ccff0..e8815e1bf2 100644 --- a/GPU/Common/ShaderId.h +++ b/GPU/Common/ShaderId.h @@ -36,10 +36,7 @@ enum VShaderBit : uint8_t { VS_BIT_HAS_NORMAL = 9, // conditioned on hw transform VS_BIT_NORM_REVERSE = 10, VS_BIT_HAS_TEXCOORD = 11, - VS_BIT_HAS_COLOR_TESS = 12, // 1 bit - VS_BIT_HAS_TEXCOORD_TESS = 13, // 1 bit - VS_BIT_NORM_REVERSE_TESS = 14, // 1 bit - VS_BIT_HAS_NORMAL_TESS = 15, // 1 bit + // 4 bits free: 12-15 VS_BIT_UVGEN_MODE = 16, VS_BIT_UVPROJ_MODE = 18, // 2, can overlap with LS0 VS_BIT_LS0 = 18, // 2 @@ -61,7 +58,7 @@ enum VShaderBit : uint8_t { VS_BIT_LIGHT3_COMP = 44, // 2 bits VS_BIT_LIGHT3_TYPE = 46, // 2 bits VS_BIT_MATERIAL_UPDATE = 48, // 3 bits - VS_BIT_SPLINE = 51, // 1 bit + // Bit 51 is free. VS_BIT_LIGHT0_ENABLE = 52, VS_BIT_LIGHT1_ENABLE = 53, VS_BIT_LIGHT2_ENABLE = 54, @@ -72,8 +69,7 @@ enum VShaderBit : uint8_t { VS_BIT_FS_MINMAX_DISCARD = 59, // Do min/max and/or depth clamp in the fragment shader. It just means we need to forward Z and W to the fragment shader. VS_BIT_FS_DEPTH_CLAMP = 60, // Do depth clamp in the fragment shader. VS_BIT_FLATSHADE = 62, // 1 bit - VS_BIT_BEZIER = 63, // 1 bit - // No more free + // Bit 63 is free. }; static inline VShaderBit operator +(VShaderBit bit, int i) { @@ -259,7 +255,7 @@ namespace Draw { class Bugs; } -void ComputeVertexShaderID(VShaderID *id, u32 vertType, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat, bool useSkinInDecode, ClipInfoFlags clipInfoFlags); +void ComputeVertexShaderID(VShaderID *id, u32 vertType, bool useHWTransform, bool weightsAsFloat, bool useSkinInDecode, ClipInfoFlags clipInfoFlags); // 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); diff --git a/GPU/Common/ShaderUniforms.cpp b/GPU/Common/ShaderUniforms.cpp index ddb505ad60..89a61fed3d 100644 --- a/GPU/Common/ShaderUniforms.cpp +++ b/GPU/Common/ShaderUniforms.cpp @@ -148,10 +148,6 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool useBuffe UpdateUVScaleOff(gstate, ub->uvScaleOffset); } - if (dirtyUniforms & DIRTY_BEZIERSPLINE) { - ub->spline_counts = gstate_c.spline_num_points_u; - } - if (dirtyUniforms & DIRTY_DEPAL) { ub->depal_mask_shift_off_fmt = PackDepalBits(); } diff --git a/GPU/Common/ShaderUniforms.h b/GPU/Common/ShaderUniforms.h index f6e072a919..9d8ded4038 100644 --- a/GPU/Common/ShaderUniforms.h +++ b/GPU/Common/ShaderUniforms.h @@ -13,7 +13,7 @@ enum : uint64_t { DIRTY_WORLDMATRIX | DIRTY_PROJTHROUGHMATRIX | DIRTY_VIEWMATRIX | DIRTY_TEXMATRIX | DIRTY_ALPHACOLORREF | DIRTY_PROJMATRIX | DIRTY_FOGCOLOR | DIRTY_FOGCOEF | DIRTY_TEXENV | DIRTY_TEX_ALPHA_MUL | DIRTY_STENCILREPLACEVALUE | DIRTY_ALPHACOLORMASK | DIRTY_SHADERBLEND | DIRTY_COLORWRITEMASK | DIRTY_UVSCALEOFFSET | DIRTY_TEXCLAMP | DIRTY_MATAMBIENTALPHA | - DIRTY_BEZIERSPLINE | DIRTY_DEPAL | DIRTY_VIEWPORT_UNIFORMS | DIRTY_RASTER_OFFSET, + DIRTY_DEPAL | DIRTY_VIEWPORT_UNIFORMS | DIRTY_RASTER_OFFSET, DIRTY_LIGHT_UNIFORMS = DIRTY_LIGHT_CONTROL | DIRTY_LIGHT0 | DIRTY_LIGHT1 | DIRTY_LIGHT2 | DIRTY_LIGHT3 | DIRTY_MATDIFFUSE | DIRTY_MATSPECULAR | DIRTY_MATEMISSIVE | DIRTY_AMBIENT, @@ -32,7 +32,7 @@ struct alignas(16) UB_VS_FS_Base { float rasterOffset[2]; float minZmaxZ[2]; float uvScaleOffset[4]; float matAmbient[4]; - uint32_t spline_counts; uint32_t depal_mask_shift_off_fmt; // 4 params packed into one. + uint32_t padding3; uint32_t depal_mask_shift_off_fmt; // 4 params packed into one. uint32_t colorWriteMask; float mipBias; // Fragment data float texNoAlpha; float texMul; float padding4[2]; // this vec4 will hold ubershader stuff. We won't use integer flags in the fragment shader. diff --git a/GPU/Common/SplineCommon.cpp b/GPU/Common/SplineCommon.cpp index 90ee730ddf..6f5e4d95d7 100644 --- a/GPU/Common/SplineCommon.cpp +++ b/GPU/Common/SplineCommon.cpp @@ -435,45 +435,6 @@ void SoftwareTessellation(OutputBuffers &output, const Surface &surface, u32 ori template void SoftwareTessellation(OutputBuffers &output, const BezierSurface &surface, u32 origVertType, const ControlPoints &points); template void SoftwareTessellation(OutputBuffers &output, const SplineSurface &surface, u32 origVertType, const ControlPoints &points); -template -static void HardwareTessellation(OutputBuffers &output, const Surface &surface, u32 origVertType, - const SimpleVertex *const *points, TessellationDataTransfer *tessDataTransfer) { - using WeightType = typename Surface::WeightType; - u32 key_u = WeightType::ToKey(surface.tess_u, surface.num_points_u, surface.type_u); - u32 key_v = WeightType::ToKey(surface.tess_v, surface.num_points_v, surface.type_v); - Weight2D weights(WeightType::weightsCache, key_u, key_v); - weights.size_u = WeightType::CalcSize(surface.tess_u, surface.num_points_u); - weights.size_v = WeightType::CalcSize(surface.tess_v, surface.num_points_v); - tessDataTransfer->SendDataToShader(points, surface.num_points_u, surface.num_points_v, origVertType, weights); - - // Generating simple input vertices for the spline-computing vertex shader. - float inv_u = 1.0f / (float)surface.tess_u; - float inv_v = 1.0f / (float)surface.tess_v; - for (int patch_u = 0; patch_u < surface.num_patches_u; ++patch_u) { - const int start_u = surface.GetTessStart(patch_u); - for (int patch_v = 0; patch_v < surface.num_patches_v; ++patch_v) { - const int start_v = surface.GetTessStart(patch_v); - for (int tile_u = start_u; tile_u <= surface.tess_u; ++tile_u) { - const int index_u = surface.GetIndexU(patch_u, tile_u); - for (int tile_v = start_v; tile_v <= surface.tess_v; ++tile_v) { - const int index_v = surface.GetIndexV(patch_v, tile_v); - SimpleVertex &vert = output.vertices[surface.GetIndex(index_u, index_v, patch_u, patch_v)]; - // Index for the weights - vert.pos.x = index_u; - vert.pos.y = index_v; - // For texcoord generation - vert.nrm.x = patch_u + (float)tile_u * inv_u; - vert.nrm.y = patch_v + (float)tile_v * inv_v; - // Patch position - vert.pos.z = patch_u; - vert.nrm.z = patch_v; - } - } - } - } - surface.BuildIndex(output.indices, output.count); -} - } // namespace Spline using namespace Spline; @@ -551,15 +512,11 @@ void DrawEngineCommon::SubmitCurve(const void *control_points, const void *indic surface.Init(maxVerts); - if (CanUseHardwareTessellation(surface.primType)) { - HardwareTessellation(output, surface, origVertType, points, tessDataTransfer); - } else { - ControlPoints cpoints(points, num_points, managedBuf); - if (cpoints.IsValid()) - SoftwareTessellation(output, surface, origVertType, cpoints); - else - ERROR_LOG(Log::G3D, "Failed to allocate space for control point values, skipping curve draw"); - } + ControlPoints cpoints(points, num_points, managedBuf); + if (cpoints.IsValid()) + SoftwareTessellation(output, surface, origVertType, cpoints); + else + ERROR_LOG(Log::G3D, "Failed to allocate space for control point values, skipping curve draw"); u32 vertTypeWithIndex16 = (vertType & ~GE_VTYPE_IDX_MASK) | GE_VTYPE_IDX_16BIT; diff --git a/GPU/Common/VertexShaderGenerator.cpp b/GPU/Common/VertexShaderGenerator.cpp index b66ac96252..ce8581f64a 100644 --- a/GPU/Common/VertexShaderGenerator.cpp +++ b/GPU/Common/VertexShaderGenerator.cpp @@ -202,25 +202,6 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag return false; } - // Apparently we don't support bezier/spline together with bones. - bool doBezier = id.Bit(VS_BIT_BEZIER) && !enableBones && useHWTransform; - bool doSpline = id.Bit(VS_BIT_SPLINE) && !enableBones && useHWTransform; - if (doBezier || doSpline) { - if (!hasNormal) { - // Bad usage. - *errorString = "Invalid flags - tess requires normal."; - return false; - } - if (compat.texelFetch == nullptr) { - *errorString = "Tess not supported on this shader language version"; - return false; - } - } - bool hasColorTess = id.Bit(VS_BIT_HAS_COLOR_TESS); - bool hasTexcoordTess = id.Bit(VS_BIT_HAS_TEXCOORD_TESS); - bool hasNormalTess = id.Bit(VS_BIT_HAS_NORMAL_TESS); - bool flipNormalTess = id.Bit(VS_BIT_NORM_REVERSE_TESS); - // Should we do the min/max discard in the shader and/or or use depth clamping? // In both cases we need to just forward const bool fsMinmaxDiscard = id.Bit(VS_BIT_FS_MINMAX_DISCARD); @@ -316,9 +297,6 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag // And the "varyings". if (useHWTransform) { WRITE(p, "struct VS_IN { \n"); - if ((doSpline || doBezier) && compat.shaderLanguage == HLSL_D3D11) { - WRITE(p, " uint instanceId : SV_InstanceID;\n"); - } if (enableBones) { WRITE(p, " %s", boneWeightAttrDeclHLSL[numBoneWeights]); } @@ -538,163 +516,6 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag } } - // Hardware tessellation - if (doBezier || doSpline) { - *uniformMask |= DIRTY_BEZIERSPLINE; - - if (compat.shaderLanguage == GLSL_VULKAN) { - WRITE(p, "struct TessData {\n"); - WRITE(p, " vec4 pos;\n"); - WRITE(p, " vec4 tex;\n"); - WRITE(p, " vec4 col;\n"); - WRITE(p, "};\n"); - WRITE(p, "layout (std430, set = 0, binding = %d) readonly buffer s_tess_data {\n", DRAW_BINDING_TESS_STORAGE_BUF); - WRITE(p, " TessData tess_data[];\n"); - WRITE(p, "};\n"); - - WRITE(p, "struct TessWeight {\n"); - WRITE(p, " vec4 basis;\n"); - WRITE(p, " vec4 deriv;\n"); - WRITE(p, "};\n"); - WRITE(p, "layout (std430, set = 0, binding = %d) readonly buffer s_tess_weights_u {\n", DRAW_BINDING_TESS_STORAGE_BUF_WU); - WRITE(p, " TessWeight tess_weights_u[];\n"); - WRITE(p, "};\n"); - WRITE(p, "layout (std430, set = 0, binding = %d) readonly buffer s_tess_weights_v {\n", DRAW_BINDING_TESS_STORAGE_BUF_WV); - WRITE(p, " TessWeight tess_weights_v[];\n"); - WRITE(p, "};\n"); - } else if (ShaderLanguageIsOpenGL(compat.shaderLanguage)) { - WRITE(p, "uniform sampler2D u_tess_points;\n"); // Control Points - WRITE(p, "uniform sampler2D u_tess_weights_u;\n"); - WRITE(p, "uniform sampler2D u_tess_weights_v;\n"); - - WRITE(p, "uniform int u_spline_counts;\n"); - } else if (compat.shaderLanguage == HLSL_D3D11) { - WRITE(p, "struct TessData {\n"); - WRITE(p, " vec3 pos; float pad1;\n"); - WRITE(p, " vec2 tex; vec2 pad2;\n"); - WRITE(p, " vec4 col;\n"); - WRITE(p, "};\n"); - WRITE(p, "StructuredBuffer tess_data : register(t0);\n"); - - WRITE(p, "struct TessWeight {\n"); - WRITE(p, " vec4 basis;\n"); - WRITE(p, " vec4 deriv;\n"); - WRITE(p, "};\n"); - WRITE(p, "StructuredBuffer tess_weights_u : register(t1);\n"); - WRITE(p, "StructuredBuffer tess_weights_v : register(t2);\n"); - } - - const char *init[3] = { "0.0, 0.0", "0.0, 0.0, 0.0", "0.0, 0.0, 0.0, 0.0" }; - for (int i = 2; i <= 4; i++) { - // Define 3 types vec2, vec3, vec4 - WRITE(p, "vec%d tess_sample(in vec%d points[16], mat4 weights) {\n", i, i); - WRITE(p, " vec%d pos = vec%d(%s);\n", i, i, init[i - 2]); - for (int v = 0; v < 4; ++v) { - for (int u = 0; u < 4; ++u) { - WRITE(p, " pos += weights[%i][%i] * points[%i];\n", v, u, v * 4 + u); - } - } - WRITE(p, " return pos;\n"); - WRITE(p, "}\n"); - } - - if (ShaderLanguageIsOpenGL(compat.shaderLanguage) && compat.glslVersionNumber < 130) { // For glsl version 1.10 - WRITE(p, "mat4 outerProduct(vec4 u, vec4 v) {\n"); - WRITE(p, " return mat4(u * v[0], u * v[1], u * v[2], u * v[3]);\n"); - WRITE(p, "}\n"); - } else if (compat.shaderLanguage == HLSL_D3D11) { - WRITE(p, "mat4 outerProduct(vec4 u, vec4 v) {\n"); - WRITE(p, " return mul((float4x1)v, (float1x4)u);\n"); - WRITE(p, "}\n"); - } - - WRITE(p, "struct Tess {\n"); - WRITE(p, " vec3 pos;\n"); - WRITE(p, " vec2 tex;\n"); - WRITE(p, " vec4 col;\n"); - if (hasNormalTess) - WRITE(p, " vec3 nrm;\n"); - WRITE(p, "};\n"); - - if (compat.shaderLanguage == HLSL_D3D11) { - WRITE(p, "void tessellate(in VS_IN In, out Tess tess) {\n"); - WRITE(p, " vec3 position = In.position;\n"); - WRITE(p, " vec3 normal = In.normal;\n"); - } else { - WRITE(p, "void tessellate(out Tess tess) {\n"); - } - WRITE(p, " ivec2 point_pos = ivec2(position.z, normal.z)%s;\n", doBezier ? " * 3" : ""); - WRITE(p, " ivec2 weight_idx = ivec2(position.xy);\n"); - - // Load 4x4 control points - WRITE(p, " vec3 _pos[16];\n"); - WRITE(p, " vec2 _tex[16];\n"); - WRITE(p, " vec4 _col[16];\n"); - if (compat.coefsFromBuffers) { - WRITE(p, " int index;\n"); - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - WRITE(p, " index = (%i + point_pos.y) * int(u_spline_counts) + (%i + point_pos.x);\n", i, j); - WRITE(p, " _pos[%i] = tess_data[index].pos.xyz;\n", i * 4 + j); - if (hasTexcoordTess) - WRITE(p, " _tex[%i] = tess_data[index].tex.xy;\n", i * 4 + j); - if (hasColorTess) - WRITE(p, " _col[%i] = tess_data[index].col;\n", i * 4 + j); - } - } - - // Basis polynomials as weight coefficients - WRITE(p, " vec4 basis_u = tess_weights_u[weight_idx.x].basis;\n"); - WRITE(p, " vec4 basis_v = tess_weights_v[weight_idx.y].basis;\n"); - WRITE(p, " mat4 basis = outerProduct(basis_u, basis_v);\n"); - } else { - WRITE(p, " int index_u, index_v;\n"); - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - WRITE(p, " index_u = (%i + point_pos.x);\n", j); - WRITE(p, " index_v = (%i + point_pos.y);\n", i); - WRITE(p, " _pos[%i] = %s(u_tess_points, ivec2(index_u, index_v), 0).xyz;\n", i * 4 + j, compat.texelFetch); - if (hasTexcoordTess) - WRITE(p, " _tex[%i] = %s(u_tess_points, ivec2(index_u + u_spline_counts, index_v), 0).xy;\n", i * 4 + j, compat.texelFetch); - if (hasColorTess) - WRITE(p, " _col[%i] = %s(u_tess_points, ivec2(index_u + u_spline_counts * 2, index_v), 0).rgba;\n", i * 4 + j, compat.texelFetch); - } - } - - // Basis polynomials as weight coefficients - WRITE(p, " vec4 basis_u = %s(u_tess_weights_u, %s, 0);\n", compat.texelFetch, "ivec2(weight_idx.x * 2, 0)"); - WRITE(p, " vec4 basis_v = %s(u_tess_weights_v, %s, 0);\n", compat.texelFetch, "ivec2(weight_idx.y * 2, 0)"); - WRITE(p, " mat4 basis = outerProduct(basis_u, basis_v);\n"); - } - - // Tessellate - WRITE(p, " tess.pos = tess_sample(_pos, basis);\n"); - if (hasTexcoordTess) - WRITE(p, " tess.tex = tess_sample(_tex, basis);\n"); - else - WRITE(p, " tess.tex = normal.xy;\n"); - if (hasColorTess) - WRITE(p, " tess.col = tess_sample(_col, basis);\n"); - else - WRITE(p, " tess.col = u_matambientalpha;\n"); - if (hasNormalTess) { - if (compat.coefsFromBuffers) { - // Derivatives as weight coefficients - WRITE(p, " vec4 deriv_u = tess_weights_u[weight_idx.x].deriv;\n"); - WRITE(p, " vec4 deriv_v = tess_weights_v[weight_idx.y].deriv;\n"); - } else { - // Derivatives as weight coefficients - WRITE(p, " vec4 deriv_u = %s(u_tess_weights_u, %s, 0);\n", compat.texelFetch, "ivec2(weight_idx.x * 2 + 1, 0)"); - WRITE(p, " vec4 deriv_v = %s(u_tess_weights_v, %s, 0);\n", compat.texelFetch, "ivec2(weight_idx.y * 2 + 1, 0)"); - } - - WRITE(p, " vec3 du = tess_sample(_pos, outerProduct(deriv_u, basis_v));\n"); - WRITE(p, " vec3 dv = tess_sample(_pos, outerProduct(basis_u, deriv_v));\n"); - WRITE(p, " tess.nrm = normalize(cross(du, dv));\n"); - } - WRITE(p, "}\n"); - } - if (useHWTransform) { WRITE(p, "vec3 normalizeOr001(vec3 v) {\n"); WRITE(p, " return length(v) == 0.0 ? vec3(0.0, 0.0, 1.0) : normalize(v);\n"); @@ -766,28 +587,13 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag } else { // Step 1: World Transform / Skinning if (!enableBones) { - if (doBezier || doSpline) { - // Hardware tessellation - WRITE(p, " Tess tess;\n"); - if (compat.shaderLanguage == HLSL_D3D11) { - WRITE(p, " tessellate(In, tess);\n"); - } else { - WRITE(p, " tessellate(tess);\n"); - } - - WRITE(p, " vec3 worldpos = mul(vec4(tess.pos.xyz, 1.0), u_world).xyz;\n"); - if (hasNormalTess) { - WRITE(p, " mediump vec3 worldnormal = normalizeOr001(mul(vec4(%stess.nrm, 0.0), u_world).xyz);\n", flipNormalTess ? "-" : ""); - } else { - WRITE(p, " mediump vec3 worldnormal = normalizeOr001(mul(vec4(0.0, 0.0, %s1.0, 0.0), u_world).xyz);\n", flipNormalTess ? "-" : ""); - } + + // No skinning, just standard T&L. + WRITE(p, " vec3 worldpos = mul(vec4(position, 1.0), u_world).xyz;\n"); + if (hasNormal) { + WRITE(p, " mediump vec3 worldnormal = normalizeOr001(mul(vec4(%snormal, 0.0), u_world).xyz);\n", flipNormal ? "-" : ""); } else { - // No skinning, just standard T&L. - WRITE(p, " vec3 worldpos = mul(vec4(position, 1.0), u_world).xyz;\n"); - if (hasNormal) - WRITE(p, " mediump vec3 worldnormal = normalizeOr001(mul(vec4(%snormal, 0.0), u_world).xyz);\n", flipNormal ? "-" : ""); - else - WRITE(p, " mediump vec3 worldnormal = normalizeOr001(mul(vec4(0.0, 0.0, %s1.0, 0.0), u_world).xyz);\n", flipNormal ? "-" : ""); + WRITE(p, " mediump vec3 worldnormal = normalizeOr001(mul(vec4(0.0, 0.0, %s1.0, 0.0), u_world).xyz);\n", flipNormal ? "-" : ""); } } else { static const char * const rescale[4] = {"", " * 1.9921875", " * 1.999969482421875", ""}; // 2*127.5f/128.f, 2*32767.5f/32768.f, 1.0f}; @@ -878,11 +684,6 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag // TODO: Declare variables for dots for shade mapping if needed. const char *srcCol = "color0"; - if (doBezier || doSpline) { - // TODO: Probably, should use hasColorTess but FF4 has a problem with drawing the background. - srcCol = "tess.col"; - } - if (lightUberShader && hasColor) { p.F(" vec4 ambientColor = ((u_lightControl & (1u << 0x14u)) != 0x0u) ? %s : u_matambientalpha;\n", srcCol); if (enableLighting) { @@ -1115,10 +916,7 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag } else { // Lighting doesn't affect color. if (hasColor) { - if (doBezier || doSpline) - WRITE(p, " %sv_color0 = tess.col;\n", compat.vsOutPrefix); - else - WRITE(p, " %sv_color0 = color0;\n", compat.vsOutPrefix); + WRITE(p, " %sv_color0 = color0;\n", compat.vsOutPrefix); } else { WRITE(p, " %sv_color0 = u_matambientalpha;\n", compat.vsOutPrefix); if (bugs.Has(Draw::Bugs::MALI_CONSTANT_LOAD_BUG) && g_Config.bVendorBugChecksEnabled) { @@ -1139,19 +937,13 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag case GE_TEXMAP_UNKNOWN: // Not sure what this is, but Riviera uses it. Treating as coords works. if (scaleUV) { if (hasTexcoord) { - if (doBezier || doSpline) - WRITE(p, " %sv_texcoord = vec3(tess.tex.xy * u_uvscaleoffset.xy + u_uvscaleoffset.zw, 0.0);\n", compat.vsOutPrefix); - else - WRITE(p, " %sv_texcoord = vec3(texcoord.xy * u_uvscaleoffset.xy, 0.0);\n", compat.vsOutPrefix); + WRITE(p, " %sv_texcoord = vec3(texcoord.xy * u_uvscaleoffset.xy, 0.0);\n", compat.vsOutPrefix); } else { WRITE(p, " %sv_texcoord = splat3(0.0);\n", compat.vsOutPrefix); } } else { if (hasTexcoord) { - if (doBezier || doSpline) - WRITE(p, " %sv_texcoord = vec3(tess.tex.xy * u_uvscaleoffset.xy + u_uvscaleoffset.zw, 0.0);\n", compat.vsOutPrefix); - else - WRITE(p, " %sv_texcoord = vec3(texcoord.xy * u_uvscaleoffset.xy + u_uvscaleoffset.zw, 0.0);\n", compat.vsOutPrefix); + WRITE(p, " %sv_texcoord = vec3(texcoord.xy * u_uvscaleoffset.xy + u_uvscaleoffset.zw, 0.0);\n", compat.vsOutPrefix); } else { WRITE(p, " %sv_texcoord = vec3(u_uvscaleoffset.zw, 0.0);\n", compat.vsOutPrefix); } @@ -1163,39 +955,28 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag std::string temp_tc; switch (uvProjMode) { case GE_PROJMAP_POSITION: // Use model space XYZ as source - if (doBezier || doSpline) - temp_tc = "vec4(tess.pos, 1.0)"; - else - temp_tc = "vec4(position, 1.0)"; + temp_tc = "vec4(position, 1.0)"; break; case GE_PROJMAP_UV: // Use unscaled UV as source - { - // prescale is false here. - if (hasTexcoord) { - if (doBezier || doSpline) - temp_tc = "vec4(tess.tex.xy, 0.0, 1.0)"; - else - temp_tc = "vec4(texcoord.xy, 0.0, 1.0)"; - } else { - temp_tc = "vec4(0.0, 0.0, 0.0, 1.0)"; - } + if (hasTexcoord) { + temp_tc = "vec4(texcoord.xy, 0.0, 1.0)"; + } else { + temp_tc = "vec4(0.0, 0.0, 0.0, 1.0)"; } break; case GE_PROJMAP_NORMALIZED_NORMAL: // Use normalized transformed normal as source - if ((doBezier || doSpline) && hasNormalTess) - temp_tc = StringFromFormat("length(tess.nrm) == 0.0 ? vec4(0.0, 0.0, 0.0, 1.0) : vec4(normalize(%stess.nrm), 1.0)", flipNormalTess ? "-" : ""); - else if (hasNormal) + if (hasNormal) { temp_tc = StringFromFormat("length(normal) == 0.0 ? vec4(0.0, 0.0, 0.0, 1.0) : vec4(normalize(%snormal), 1.0)", flipNormal ? "-" : ""); - else + } else { temp_tc = "vec4(0.0, 0.0, 1.0, 1.0)"; + } break; case GE_PROJMAP_NORMAL: // Use non-normalized transformed normal as source - if ((doBezier || doSpline) && hasNormalTess) - temp_tc = flipNormalTess ? "vec4(-tess.nrm, 1.0)" : "vec4(tess.nrm, 1.0)"; - else if (hasNormal) + if (hasNormal) { temp_tc = flipNormal ? "vec4(-normal, 1.0)" : "vec4(normal, 1.0)"; - else + } else { temp_tc = "vec4(0.0, 0.0, 1.0, 1.0)"; + } break; } // Transform by texture matrix. XYZ as we are doing projection mapping. diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index c1a67cdc12..c5ce1084e1 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -85,9 +85,6 @@ void DrawEngineD3D11::InitDeviceObjects() { pushVerts_ = new PushBufferD3D11(device_, VERTEX_PUSH_SIZE, D3D11_BIND_VERTEX_BUFFER); pushInds_ = new PushBufferD3D11(device_, INDEX_PUSH_SIZE, D3D11_BIND_INDEX_BUFFER); - tessDataTransferD3D11 = new TessellationDataTransferD3D11(context_, device_); - tessDataTransfer = tessDataTransferD3D11; - draw_->SetInvalidationCallback(std::bind(&DrawEngineD3D11::Invalidate, this, std::placeholders::_1)); } @@ -97,9 +94,6 @@ void DrawEngineD3D11::DestroyDeviceObjects() { } ClearInputLayoutMap(); - delete tessDataTransferD3D11; - tessDataTransferD3D11 = nullptr; - tessDataTransfer = nullptr; delete pushVerts_; delete pushInds_; pushVerts_ = nullptr; @@ -347,7 +341,7 @@ void DrawEngineD3D11::Flush() { D3D11VertexShader *vshader; D3D11FragmentShader *fshader; - shaderManager_->GetShaders(prim, dec_->VertexType(), &vshader, &fshader, pipelineState_, useHWTransform, useHWTessellation_, decOptions_.expandAllWeightsToFloat, applySkinInDecode_, clipInfoFlags_); + shaderManager_->GetShaders(prim, dec_->VertexType(), &vshader, &fshader, pipelineState_, useHWTransform, decOptions_.expandAllWeightsToFloat, applySkinInDecode_, clipInfoFlags_); ID3D11InputLayout *inputLayout; SetupDecFmtForDraw(vshader, dec_->GetDecVtxFmt(), dec_->VertexType(), &inputLayout); context_->PSSetShader(fshader->GetShader(), nullptr, 0); @@ -459,7 +453,7 @@ void DrawEngineD3D11::Flush() { if (action == SW_DRAW_INDEXED) { D3D11VertexShader *vshader; D3D11FragmentShader *fshader; - shaderManager_->GetShaders(prim, swDec->VertexType(), &vshader, &fshader, pipelineState_, false, false, decOptions_.expandAllWeightsToFloat, true, clipInfoFlags_); + shaderManager_->GetShaders(prim, swDec->VertexType(), &vshader, &fshader, pipelineState_, false, decOptions_.expandAllWeightsToFloat, true, clipInfoFlags_); context_->PSSetShader(fshader->GetShader(), nullptr, 0); context_->VSSetShader(vshader->GetShader(), nullptr, 0); shaderManager_->UpdateUniforms(framebufferManager_->UseBufferedRendering()); @@ -519,95 +513,3 @@ void DrawEngineD3D11::Flush() { framebufferManager_->SetColorUpdated(gstate_c.skipDrawReason); gpuCommon_->NotifyFlush(); } - -TessellationDataTransferD3D11::TessellationDataTransferD3D11(ID3D11DeviceContext *context, ID3D11Device *device) - : context_(context), device_(device) { - desc.Usage = D3D11_USAGE_DYNAMIC; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; -} - -TessellationDataTransferD3D11::~TessellationDataTransferD3D11() { -} - -void TessellationDataTransferD3D11::SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Spline::Weight2D &weights) { - struct TessData { - float pos[3]; float pad1; - float uv[2]; float pad2[2]; - float color[4]; - }; - - int size = size_u * size_v; - - if (prevSize < size || !buf[0]) { - prevSize = size; - buf[0].Reset(); - view[0].Reset(); - - desc.ByteWidth = size * sizeof(TessData); - desc.StructureByteStride = sizeof(TessData); - device_->CreateBuffer(&desc, nullptr, &buf[0]); - if (buf[0]) - device_->CreateShaderResourceView(buf[0].Get(), nullptr, &view[0]); - if (!buf[0] || !view[0]) - return; - context_->VSSetShaderResources(0, 1, view[0].GetAddressOf()); - } - D3D11_MAPPED_SUBRESOURCE map{}; - HRESULT hr = context_->Map(buf[0].Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &map); - if (FAILED(hr)) - return; - uint8_t *data = (uint8_t *)map.pData; - - float *pos = (float *)(data); - float *tex = (float *)(data + offsetof(TessData, uv)); - float *col = (float *)(data + offsetof(TessData, color)); - int stride = sizeof(TessData) / sizeof(float); - - CopyControlPoints(pos, tex, col, stride, stride, stride, points, size, vertType); - - context_->Unmap(buf[0].Get(), 0); - - using Spline::Weight; - - // Weights U - if (prevSizeWU < weights.size_u || !buf[1]) { - prevSizeWU = weights.size_u; - buf[1].Reset(); - view[1].Reset(); - - desc.ByteWidth = weights.size_u * sizeof(Weight); - desc.StructureByteStride = sizeof(Weight); - device_->CreateBuffer(&desc, nullptr, &buf[1]); - if (buf[1]) - device_->CreateShaderResourceView(buf[1].Get(), nullptr, &view[1]); - if (!buf[1] || !view[1]) - return; - context_->VSSetShaderResources(1, 1, view[1].GetAddressOf()); - } - hr = context_->Map(buf[1].Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &map); - if (SUCCEEDED(hr)) - memcpy(map.pData, weights.u, weights.size_u * sizeof(Weight)); - context_->Unmap(buf[1].Get(), 0); - - // Weights V - if (prevSizeWV < weights.size_v) { - prevSizeWV = weights.size_v; - buf[2].Reset(); - view[2].Reset(); - - desc.ByteWidth = weights.size_v * sizeof(Weight); - desc.StructureByteStride = sizeof(Weight); - device_->CreateBuffer(&desc, nullptr, &buf[2]); - if (buf[2]) - device_->CreateShaderResourceView(buf[2].Get(), nullptr, &view[2]); - if (!buf[2] || !view[2]) - return; - context_->VSSetShaderResources(2, 1, view[2].GetAddressOf()); - } - hr = context_->Map(buf[2].Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &map); - if (SUCCEEDED(hr)) - memcpy(map.pData, weights.v, weights.size_v * sizeof(Weight)); - context_->Unmap(buf[2].Get(), 0); -} diff --git a/GPU/D3D11/DrawEngineD3D11.h b/GPU/D3D11/DrawEngineD3D11.h index e7c567e370..3944f72a36 100644 --- a/GPU/D3D11/DrawEngineD3D11.h +++ b/GPU/D3D11/DrawEngineD3D11.h @@ -37,22 +37,6 @@ class ShaderManagerD3D11; class TextureCacheD3D11; class FramebufferManagerD3D11; -class TessellationDataTransferD3D11 : public TessellationDataTransfer { -private: - ID3D11DeviceContext *context_; - ID3D11Device *device_; - Microsoft::WRL::ComPtr buf[3]{}; - Microsoft::WRL::ComPtr view[3]{}; - D3D11_BUFFER_DESC desc{}; - int prevSize = 0; - int prevSizeWU = 0, prevSizeWV = 0; -public: - TessellationDataTransferD3D11(ID3D11DeviceContext *context, ID3D11Device *device); - ~TessellationDataTransferD3D11(); - // Send spline/bezier's control points and weights to vertex shader through structured shader buffer. - void SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Spline::Weight2D &weights) override; -}; - // Handles transform, lighting and drawing. class DrawEngineD3D11 : public DrawEngineCommon { public: @@ -140,8 +124,5 @@ private: D3D11StateKeys keys_{}; D3D11DynamicState dynState_{}; - // Hardware tessellation - TessellationDataTransferD3D11 *tessDataTransferD3D11 = nullptr; - int lastRenderStepId_ = -1; }; diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index 77e580cf86..260ffde59b 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -83,7 +83,6 @@ u32 GPU_D3D11::CheckGPUFeatures() const { u32 features = GPUCommonHW::CheckGPUFeatures(); features |= GPU_USE_TEXTURE_FLOAT; - features |= GPU_USE_INSTANCE_RENDERING; features |= GPU_USE_TEXTURE_LOD_CONTROL; uint32_t fmt4444 = draw_->GetDataFormatSupport(Draw::DataFormat::A4R4G4B4_UNORM_PACK16); diff --git a/GPU/D3D11/ShaderManagerD3D11.cpp b/GPU/D3D11/ShaderManagerD3D11.cpp index 52b006add9..337c8a49d7 100644 --- a/GPU/D3D11/ShaderManagerD3D11.cpp +++ b/GPU/D3D11/ShaderManagerD3D11.cpp @@ -186,13 +186,13 @@ void ShaderManagerD3D11::BindUniforms() { context_->PSSetConstantBuffers(0, 1, ps_cbs); } -void ShaderManagerD3D11::GetShaders(int prim, u32 vertexType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, const ComputedPipelineState &pipelineState, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat, bool useSkinInDecode, ClipInfoFlags clipInfoFlags) { +void ShaderManagerD3D11::GetShaders(int prim, u32 vertexType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, const ComputedPipelineState &pipelineState, bool useHWTransform, bool weightsAsFloat, bool useSkinInDecode, ClipInfoFlags clipInfoFlags) { VShaderID VSID; FShaderID FSID; if (gstate_c.IsDirty(DIRTY_VERTEXSHADER_STATE)) { gstate_c.Clean(DIRTY_VERTEXSHADER_STATE); - ComputeVertexShaderID(&VSID, vertexType, useHWTransform, useHWTessellation, weightsAsFloat, useSkinInDecode, clipInfoFlags); + ComputeVertexShaderID(&VSID, vertexType, useHWTransform, weightsAsFloat, useSkinInDecode, clipInfoFlags); } else { VSID = lastVSID_; } diff --git a/GPU/D3D11/ShaderManagerD3D11.h b/GPU/D3D11/ShaderManagerD3D11.h index 0935e66f44..da4f3d8899 100644 --- a/GPU/D3D11/ShaderManagerD3D11.h +++ b/GPU/D3D11/ShaderManagerD3D11.h @@ -88,7 +88,7 @@ public: ShaderManagerD3D11(Draw::DrawContext *draw, ID3D11Device *device, ID3D11DeviceContext *context, D3D_FEATURE_LEVEL featureLevel); ~ShaderManagerD3D11(); - void GetShaders(int prim, u32 vertexType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, const ComputedPipelineState &pipelineState, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat, bool useSkinInDecode, ClipInfoFlags clipInfoFlags); + void GetShaders(int prim, u32 vertexType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, const ComputedPipelineState &pipelineState, bool useHWTransform, bool weightsAsFloat, bool useSkinInDecode, ClipInfoFlags clipInfoFlags); void ClearShaders() override; void DirtyLastShader() override; diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 5bd549cf07..97bf678982 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -57,15 +57,10 @@ DrawEngineGLES::DrawEngineGLES(Draw::DrawContext *draw) : inputLayoutMap_(16), d decOptions_.expand8BitNormalsToFloat = false; InitDeviceObjects(); - - tessDataTransferGLES = new TessellationDataTransferGLES(render_); - tessDataTransfer = tessDataTransferGLES; } DrawEngineGLES::~DrawEngineGLES() { DestroyDeviceObjects(); - - delete tessDataTransferGLES; } void DrawEngineGLES::DeviceLost() { @@ -147,7 +142,6 @@ void DrawEngineGLES::EndFrame() { FrameData &frameData = frameData_[render_->GetCurFrame()]; frameData.pushIndex->End(); frameData.pushVertex->End(); - tessDataTransferGLES->EndFrame(); } struct GlTypeInfo { @@ -275,7 +269,7 @@ void DrawEngineGLES::Flush() { lastUseHwTransform_ = useHWTransform; } - Shader *vshader = shaderManager_->ApplyVertexShader(useHWTransform, useHWTessellation_, dec_->VertexType(), decOptions_.expandAllWeightsToFloat, applySkinInDecode_ || !useHWTransform, clipInfoFlags_, &vsid); + Shader *vshader = shaderManager_->ApplyVertexShader(useHWTransform, dec_->VertexType(), decOptions_.expandAllWeightsToFloat, applySkinInDecode_ || !useHWTransform, clipInfoFlags_, &vsid); useHWTransform = vshader->UseHWTransform(); // In case shader compilation failed and it fell back. However, this can no longer really happen... Need to fix this. @@ -458,80 +452,3 @@ bail: framebufferManager_->SetColorUpdated(gstate_c.skipDrawReason); gpuCommon_->NotifyFlush(); } - -// TODO: Refactor this to a single USE flag. -bool DrawEngineGLES::SupportsHWTessellation() { - bool hasTexelFetch = gl_extensions.GLES3 || (!gl_extensions.IsGLES && gl_extensions.VersionGEThan(3, 3, 0)) || gl_extensions.EXT_gpu_shader4; - return hasTexelFetch && gstate_c.UseAll(GPU_USE_VERTEX_TEXTURE_FETCH | GPU_USE_TEXTURE_FLOAT | GPU_USE_INSTANCE_RENDERING); -} - -bool DrawEngineGLES::UpdateUseHWTessellation(bool enable) const { - return enable && SupportsHWTessellation(); -} - -void TessellationDataTransferGLES::SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Spline::Weight2D &weights) { - bool hasColor = (vertType & GE_VTYPE_COL_MASK) != 0; - bool hasTexCoord = (vertType & GE_VTYPE_TC_MASK) != 0; - - int size = size_u * size_v; - float *pos = new float[size * 4]; - float *tex = hasTexCoord ? new float[size * 4] : nullptr; - float *col = hasColor ? new float[size * 4] : nullptr; - int stride = 4; - - CopyControlPoints(pos, tex, col, stride, stride, stride, points, size, vertType); - // Removed the 1D texture support, it's unlikely to be relevant for performance. - // Control Points - if (prevSizeU < size_u || prevSizeV < size_v) { - prevSizeU = size_u; - prevSizeV = size_v; - if (data_tex[0]) - renderManager_->DeleteTexture(data_tex[0]); - data_tex[0] = renderManager_->CreateTexture(GL_TEXTURE_2D, size_u * 3, size_v, 1, 1); - renderManager_->TextureImage(data_tex[0], 0, size_u * 3, size_v, 1, Draw::DataFormat::R32G32B32A32_FLOAT, nullptr, GLRAllocType::NONE, false); - renderManager_->FinalizeTexture(data_tex[0], 0, false); - } - renderManager_->BindTexture(TEX_SLOT_SPLINE_POINTS, data_tex[0]); - // Position - renderManager_->TextureSubImage(TEX_SLOT_SPLINE_POINTS, data_tex[0], 0, 0, 0, size_u, size_v, Draw::DataFormat::R32G32B32A32_FLOAT, (u8 *)pos, GLRAllocType::NEW); - // Texcoord - if (hasTexCoord) - renderManager_->TextureSubImage(TEX_SLOT_SPLINE_POINTS, data_tex[0], 0, size_u, 0, size_u, size_v, Draw::DataFormat::R32G32B32A32_FLOAT, (u8 *)tex, GLRAllocType::NEW); - // Color - if (hasColor) - renderManager_->TextureSubImage(TEX_SLOT_SPLINE_POINTS, data_tex[0], 0, size_u * 2, 0, size_u, size_v, Draw::DataFormat::R32G32B32A32_FLOAT, (u8 *)col, GLRAllocType::NEW); - - // Weight U - if (prevSizeWU < weights.size_u) { - prevSizeWU = weights.size_u; - if (data_tex[1]) - renderManager_->DeleteTexture(data_tex[1]); - data_tex[1] = renderManager_->CreateTexture(GL_TEXTURE_2D, weights.size_u * 2, 1, 1, 1); - renderManager_->TextureImage(data_tex[1], 0, weights.size_u * 2, 1, 1, Draw::DataFormat::R32G32B32A32_FLOAT, nullptr, GLRAllocType::NONE, false); - renderManager_->FinalizeTexture(data_tex[1], 0, false); - } - renderManager_->BindTexture(TEX_SLOT_SPLINE_WEIGHTS_U, data_tex[1]); - renderManager_->TextureSubImage(TEX_SLOT_SPLINE_WEIGHTS_U, data_tex[1], 0, 0, 0, weights.size_u * 2, 1, Draw::DataFormat::R32G32B32A32_FLOAT, (u8 *)weights.u, GLRAllocType::NONE); - - // Weight V - if (prevSizeWV < weights.size_v) { - prevSizeWV = weights.size_v; - if (data_tex[2]) - renderManager_->DeleteTexture(data_tex[2]); - data_tex[2] = renderManager_->CreateTexture(GL_TEXTURE_2D, weights.size_v * 2, 1, 1, 1); - renderManager_->TextureImage(data_tex[2], 0, weights.size_v * 2, 1, 1, Draw::DataFormat::R32G32B32A32_FLOAT, nullptr, GLRAllocType::NONE, false); - renderManager_->FinalizeTexture(data_tex[2], 0, false); - } - renderManager_->BindTexture(TEX_SLOT_SPLINE_WEIGHTS_V, data_tex[2]); - renderManager_->TextureSubImage(TEX_SLOT_SPLINE_WEIGHTS_V, data_tex[2], 0, 0, 0, weights.size_v * 2, 1, Draw::DataFormat::R32G32B32A32_FLOAT, (u8 *)weights.v, GLRAllocType::NONE); -} - -void TessellationDataTransferGLES::EndFrame() { - for (int i = 0; i < 3; i++) { - if (data_tex[i]) { - renderManager_->DeleteTexture(data_tex[i]); - data_tex[i] = nullptr; - } - } - prevSizeU = prevSizeV = prevSizeWU = prevSizeWV = 0; -} diff --git a/GPU/GLES/DrawEngineGLES.h b/GPU/GLES/DrawEngineGLES.h index 052b2bc92f..9220f5da25 100644 --- a/GPU/GLES/DrawEngineGLES.h +++ b/GPU/GLES/DrawEngineGLES.h @@ -40,23 +40,6 @@ struct TransformedVertex; struct DecVtxFormat; -class TessellationDataTransferGLES : public TessellationDataTransfer { -private: - GLRTexture *data_tex[3]{}; - int prevSizeU = 0, prevSizeV = 0; - int prevSizeWU = 0, prevSizeWV = 0; - GLRenderManager *renderManager_; -public: - TessellationDataTransferGLES(GLRenderManager *renderManager) - : renderManager_(renderManager) { } - ~TessellationDataTransferGLES() { - EndFrame(); - } - // Send spline/bezier's control points and weights to vertex shader through floating point texture. - void SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Spline::Weight2D &weights) override; - void EndFrame(); // Queues textures for deletion. -}; - // Handles transform, lighting and drawing. class DrawEngineGLES : public DrawEngineCommon { public: @@ -90,11 +73,6 @@ public: void ClearInputLayoutMap(); - static bool SupportsHWTessellation() ; - -protected: - bool UpdateUseHWTessellation(bool enable) const override; - private: void Invalidate(InvalidationCallbackFlags flags); @@ -131,7 +109,4 @@ private: int bufferDecimationCounter_ = 0; int lastRenderStepId_ = -1; - - // Hardware tessellation - TessellationDataTransferGLES *tessDataTransferGLES; }; diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index ea1f569fb7..96234e3a45 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -107,13 +107,6 @@ GPU_GLES::GPU_GLES(GraphicsContext *gfxCtx, Draw::DrawContext *draw) INFO_LOG(Log::G3D, "Shader cache disabled. Not loading."); } } - - if (g_Config.bHardwareTessellation) { - // Log information that we disable hardware tessellation if device is unsupported. - if (!drawEngine_.SupportsHWTessellation()) { - ERROR_LOG(Log::G3D, "Hardware Tessellation is unsupported, falling back to software tessellation"); - } - } } GPU_GLES::~GPU_GLES() { @@ -141,16 +134,6 @@ u32 GPU_GLES::CheckGPUFeatures() const { if (gl_extensions.GLES3 || !gl_extensions.IsGLES) features |= GPU_USE_TEXTURE_LOD_CONTROL; - bool canUseInstanceID = gl_extensions.EXT_draw_instanced || gl_extensions.ARB_draw_instanced; - bool canDefInstanceID = gl_extensions.IsGLES || gl_extensions.EXT_gpu_shader4 || gl_extensions.VersionGEThan(3, 1); - bool instanceRendering = gl_extensions.GLES3 || (canUseInstanceID && canDefInstanceID); - if (instanceRendering) - features |= GPU_USE_INSTANCE_RENDERING; - - int maxVertexTextureImageUnits = gl_extensions.maxVertexTextureUnits; - if (maxVertexTextureImageUnits >= 3) // At least 3 for hardware tessellation - features |= GPU_USE_VERTEX_TEXTURE_FETCH; - if (gl_extensions.ARB_texture_float || gl_extensions.OES_texture_float) features |= GPU_USE_TEXTURE_FLOAT; diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index b7752b447e..34cf666006 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -607,12 +607,6 @@ void LinkedShader::UpdateUniforms(const ShaderID &vsid, const ShaderLanguageDesc if (u_lightspecular[i] != -1) SetColorUniform3(render_, &u_lightspecular[i], gstate.lcolor[i * 3 + 2]); } } - - if (dirty & DIRTY_BEZIERSPLINE) { - if (u_spline_counts != -1) { - render_->SetUniformI1(&u_spline_counts, gstate_c.spline_num_points_u); - } - } } static constexpr size_t CODE_BUFFER_SIZE = 32768; @@ -707,10 +701,10 @@ Shader *ShaderManagerGLES::CompileVertexShader(VShaderID VSID) { return new Shader(render_, codeBuffer_, desc, params); } -Shader *ShaderManagerGLES::ApplyVertexShader(bool useHWTransform, bool useHWTessellation, u32 vertexType, bool weightsAsFloat, bool useSkinInDecode, ClipInfoFlags clipInfoFlags, VShaderID *VSID) { +Shader *ShaderManagerGLES::ApplyVertexShader(bool useHWTransform, u32 vertexType, bool weightsAsFloat, bool useSkinInDecode, ClipInfoFlags clipInfoFlags, VShaderID *VSID) { if (gstate_c.IsDirty(DIRTY_VERTEXSHADER_STATE)) { gstate_c.Clean(DIRTY_VERTEXSHADER_STATE); - ComputeVertexShaderID(VSID, vertexType, useHWTransform, useHWTessellation, weightsAsFloat, useSkinInDecode, clipInfoFlags); + ComputeVertexShaderID(VSID, vertexType, useHWTransform, weightsAsFloat, useSkinInDecode, clipInfoFlags); } else { *VSID = lastVSID_; } @@ -743,7 +737,7 @@ Shader *ShaderManagerGLES::ApplyVertexShader(bool useHWTransform, bool useHWTess // Can still work with software transform. VShaderID vsidTemp; - ComputeVertexShaderID(&vsidTemp, vertexType, false, false, weightsAsFloat, true, clipInfoFlags); + ComputeVertexShaderID(&vsidTemp, vertexType, false, weightsAsFloat, true, clipInfoFlags); vs = CompileVertexShader(vsidTemp); } diff --git a/GPU/GLES/ShaderManagerGLES.h b/GPU/GLES/ShaderManagerGLES.h index f3bd32ea29..db35142c8d 100644 --- a/GPU/GLES/ShaderManagerGLES.h +++ b/GPU/GLES/ShaderManagerGLES.h @@ -172,7 +172,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 vertexType, bool weightsAsFloat, bool useSkinInDecode, ClipInfoFlags clipInfoFlags, VShaderID *VSID); + Shader *ApplyVertexShader(bool useHWTransform, u32 vertexType, bool weightsAsFloat, bool useSkinInDecode, ClipInfoFlags clipInfoFlags, VShaderID *VSID); LinkedShader *ApplyFragmentShader(VShaderID VSID, Shader *vs, const ComputedPipelineState &pipelineState, ClipInfoFlags clipInfoFlags); void DeviceLost() override; diff --git a/GPU/GPUCommonHW.cpp b/GPU/GPUCommonHW.cpp index 84323c66a1..d8e91c112c 100644 --- a/GPU/GPUCommonHW.cpp +++ b/GPU/GPUCommonHW.cpp @@ -1328,15 +1328,7 @@ void GPUCommonHW::Execute_Bezier(u32 op, u32 diff) { // We need to dirty UVSCALEOFFSET here because we look at the submit type when setting that uniform. gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VERTEXSHADER_STATE | DIRTY_UVSCALEOFFSET); - if (drawEngineCommon_->CanUseHardwareTessellation(surface.primType)) { - gstate_c.submitType = SubmitType::HW_BEZIER; - if (gstate_c.spline_num_points_u != surface.num_points_u) { - gstate_c.Dirty(DIRTY_BEZIERSPLINE); - gstate_c.spline_num_points_u = surface.num_points_u; - } - } else { - gstate_c.submitType = SubmitType::BEZIER; - } + gstate_c.submitType = SubmitType::BEZIER; int bytesRead = 0; gstate_c.UpdateUVScaleOffset(); @@ -1408,15 +1400,7 @@ void GPUCommonHW::Execute_Spline(u32 op, u32 diff) { // We need to dirty UVSCALEOFFSET here because we look at the submit type when setting that uniform. gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VERTEXSHADER_STATE | DIRTY_UVSCALEOFFSET); - if (drawEngineCommon_->CanUseHardwareTessellation(surface.primType)) { - gstate_c.submitType = SubmitType::HW_SPLINE; - if (gstate_c.spline_num_points_u != surface.num_points_u) { - gstate_c.Dirty(DIRTY_BEZIERSPLINE); - gstate_c.spline_num_points_u = surface.num_points_u; - } - } else { - gstate_c.submitType = SubmitType::SPLINE; - } + gstate_c.submitType = SubmitType::SPLINE; int bytesRead = 0; gstate_c.UpdateUVScaleOffset(); diff --git a/GPU/GPUState.cpp b/GPU/GPUState.cpp index 157784df9a..59bd57d16c 100644 --- a/GPU/GPUState.cpp +++ b/GPU/GPUState.cpp @@ -375,29 +375,29 @@ static constexpr const char * g_gpuUseFlagNames[32] = { "GPU_USE_VS_RANGE_CULLING", "GPU_USE_BLEND_MINMAX", "GPU_USE_LOGIC_OP", - "GPU_USE_FRAGMENT_UBERSHADER", - "GPU_USE_TEXTURE_NPOT", + "N/A", + "N/A", "GPU_USE_ANISOTROPY", "GPU_USE_CLEAR_RAM_HACK", - "GPU_USE_INSTANCE_RENDERING", - "GPU_USE_VERTEX_TEXTURE_FETCH", + "N/A", + "N/A", "GPU_USE_TEXTURE_FLOAT", "GPU_USE_16BIT_FORMATS", "GPU_USE_DEPTH_CLAMP", "GPU_USE_TEXTURE_LOD_CONTROL", "GPU_USE_DEPTH_TEXTURE", - "GPU_USE_ACCURATE_DEPTH", - "GPU_USE_GS_CULLING", "N/A", + "N/A", + "GPU_USE_FRAMEBUFFER_ARRAYS", "GPU_USE_FRAMEBUFFER_FETCH", - "GPU_SCALE_DEPTH_FROM_24BIT_TO_16BIT", + "N/A", "GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT", "GPU_ROUND_DEPTH_TO_16BIT", "GPU_USE_CLIP_DISTANCE", "GPU_USE_CULL_DISTANCE", - "N/A", // bit 26 - "N/A", // bit 27 - "N/A", // bit 28 + "GPU_USE_SHADER_BLENDING", // bit 26 + "GPU_USE_NONBUFFERED_FLIP", // bit 27 + "GPU_USE_PRE_ROTATION", // bit 28 "GPU_USE_VIRTUAL_REALITY", "GPU_USE_SINGLE_PASS_STEREO", "GPU_USE_SIMPLE_STEREO_PERSPECTIVE", diff --git a/GPU/GPUState.h b/GPU/GPUState.h index e8f5e7d824..70023b638b 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -475,8 +475,8 @@ enum : u32 { // Free bits: 6-7 GPU_USE_ANISOTROPY = FLAG_BIT(8), GPU_USE_CLEAR_RAM_HACK = FLAG_BIT(9), - GPU_USE_INSTANCE_RENDERING = FLAG_BIT(10), - GPU_USE_VERTEX_TEXTURE_FETCH = FLAG_BIT(11), + // Free bit: 10 + // Free bit: 11 GPU_USE_TEXTURE_FLOAT = FLAG_BIT(12), GPU_USE_16BIT_FORMATS = FLAG_BIT(13), GPU_USE_DEPTH_CLAMP = FLAG_BIT(14), diff --git a/GPU/Software/TransformUnit.h b/GPU/Software/TransformUnit.h index c6ce6722b7..17fc2053f4 100644 --- a/GPU/Software/TransformUnit.h +++ b/GPU/Software/TransformUnit.h @@ -187,7 +187,4 @@ public: FreeAlignedMemory(p); } #endif - -protected: - bool UpdateUseHWTessellation(bool enable) const override { return false; } }; diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 9e74f06b9e..1f53b4b91c 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -64,9 +64,6 @@ void DrawEngineVulkan::InitDeviceObjects() { BindingType::UNIFORM_BUFFER_DYNAMIC_ALL, // uniforms BindingType::UNIFORM_BUFFER_DYNAMIC_VERTEX, // lights BindingType::UNIFORM_BUFFER_DYNAMIC_VERTEX, // bones - BindingType::STORAGE_BUFFER_VERTEX, // tess - BindingType::STORAGE_BUFFER_VERTEX, - BindingType::STORAGE_BUFFER_VERTEX, }; VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); @@ -94,9 +91,6 @@ void DrawEngineVulkan::InitDeviceObjects() { res = vkCreateSampler(device, &samp, nullptr, &nullSampler_); _dbg_assert_(VK_SUCCESS == res); - tessDataTransferVulkan = new TessellationDataTransferVulkan(vulkan); - tessDataTransfer = tessDataTransferVulkan; - draw_->SetInvalidationCallback(std::bind(&DrawEngineVulkan::Invalidate, this, std::placeholders::_1)); } @@ -115,10 +109,6 @@ void DrawEngineVulkan::DestroyDeviceObjects() { draw_->SetInvalidationCallback(InvalidationCallback()); - delete tessDataTransferVulkan; - tessDataTransfer = nullptr; - tessDataTransferVulkan = nullptr; - pushUBO_ = nullptr; if (pushVertex_) { @@ -166,8 +156,6 @@ void DrawEngineVulkan::BeginFrame() { pushVertex_->BeginFrame(); pushIndex_->BeginFrame(); - tessDataTransferVulkan->SetPushPool(pushUBO_); - DirtyAllUBOs(); AssertEmpty(); @@ -318,7 +306,7 @@ void DrawEngineVulkan::Flush() { VulkanVertexShader *vshader = nullptr; VulkanFragmentShader *fshader = nullptr; - shaderManager_->GetShaders(prim, dec_->VertexType(), &vshader, &fshader, pipelineState_, true, useHWTessellation_, decOptions_.expandAllWeightsToFloat, applySkinInDecode_, clipInfoFlags_); + shaderManager_->GetShaders(prim, dec_->VertexType(), &vshader, &fshader, pipelineState_, true, decOptions_.expandAllWeightsToFloat, applySkinInDecode_, clipInfoFlags_); _dbg_assert_msg_(vshader->UseHWTransform(), "Bad vshader"); VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(renderManager, pipelineLayout_, pipelineKey_, &dec_->decFmt, vshader, fshader, true, 0, framebufferManager_->GetMSAALevel(), false); if (!pipeline || !pipeline->pipeline) { @@ -351,8 +339,6 @@ void DrawEngineVulkan::Flush() { UpdateUBOs(); int descCount = 6; - if (tess) - descCount = 9; int descSetIndex; PackedDescriptor *descriptors = renderManager->PushDescriptorSet(descCount, &descSetIndex); descriptors[0].image.view = imageView; @@ -375,14 +361,7 @@ void DrawEngineVulkan::Flush() { descriptors[5].buffer.buffer = boneBuf; descriptors[5].buffer.range = sizeof(UB_VS_Bones); descriptors[5].buffer.offset = 0; - if (tess) { - const VkDescriptorBufferInfo *bufInfo = tessDataTransferVulkan->GetBufferInfo(); - for (int j = 0; j < 3; j++) { - descriptors[j + 6].buffer.buffer = bufInfo[j].buffer; - descriptors[j + 6].buffer.range = bufInfo[j].range; - descriptors[j + 6].buffer.offset = bufInfo[j].offset; - } - } + // TODO: Can we avoid binding all three when not needed? Same below for hardware transform. // Think this will require different descriptor set layouts. const uint32_t dynamicUBOOffsets[3] = { @@ -485,7 +464,7 @@ void DrawEngineVulkan::Flush() { VulkanVertexShader *vshader = nullptr; VulkanFragmentShader *fshader = nullptr; - shaderManager_->GetShaders(prim, swDec->VertexType(), &vshader, &fshader, pipelineState_, false, false, decOptions_.expandAllWeightsToFloat, true, clipInfoFlags_); + shaderManager_->GetShaders(prim, swDec->VertexType(), &vshader, &fshader, pipelineState_, false, decOptions_.expandAllWeightsToFloat, true, clipInfoFlags_); _dbg_assert_msg_(!vshader->UseHWTransform(), "Bad vshader"); VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(renderManager, pipelineLayout_, pipelineKey_, &swDec->decFmt, vshader, fshader, false, 0, framebufferManager_->GetMSAALevel(), false); if (!pipeline || !pipeline->pipeline) { @@ -605,38 +584,3 @@ void DrawEngineVulkan::UpdateUBOs() { dirtyUniforms_ &= ~DIRTY_BONE_UNIFORMS; } } - -void TessellationDataTransferVulkan::SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Spline::Weight2D &weights) { - // SSBOs that are not simply float1 or float2 need to be padded up to a float4 size. vec3 members - // also need to be 16-byte aligned, hence the padding. - struct TessData { - float pos[3]; float pad1; - float uv[2]; float pad2[2]; - float color[4]; - }; - - int size = size_u * size_v; - - int ssboAlignment = vulkan_->GetPhysicalDeviceProperties().properties.limits.minStorageBufferOffsetAlignment; - uint8_t *data = (uint8_t *)push_->Allocate(size * sizeof(TessData), ssboAlignment, &bufInfo_[0].buffer, (uint32_t *)&bufInfo_[0].offset); - bufInfo_[0].range = size * sizeof(TessData); - - float *pos = (float *)(data); - float *tex = (float *)(data + offsetof(TessData, uv)); - float *col = (float *)(data + offsetof(TessData, color)); - int stride = sizeof(TessData) / sizeof(float); - - CopyControlPoints(pos, tex, col, stride, stride, stride, points, size, vertType); - - using Spline::Weight; - - // Weights U - data = (uint8_t *)push_->Allocate(weights.size_u * sizeof(Weight), ssboAlignment, &bufInfo_[1].buffer, (uint32_t *)&bufInfo_[1].offset); - memcpy(data, weights.u, weights.size_u * sizeof(Weight)); - bufInfo_[1].range = weights.size_u * sizeof(Weight); - - // Weights V - data = (uint8_t *)push_->Allocate(weights.size_v * sizeof(Weight), ssboAlignment, &bufInfo_[2].buffer, (uint32_t *)&bufInfo_[2].offset); - memcpy(data, weights.v, weights.size_v * sizeof(Weight)); - bufInfo_[2].range = weights.size_v * sizeof(Weight); -} diff --git a/GPU/Vulkan/DrawEngineVulkan.h b/GPU/Vulkan/DrawEngineVulkan.h index 196159afb2..f941772d53 100644 --- a/GPU/Vulkan/DrawEngineVulkan.h +++ b/GPU/Vulkan/DrawEngineVulkan.h @@ -64,20 +64,6 @@ struct DrawEngineVulkanStats { class VulkanRenderManager; -class TessellationDataTransferVulkan : public TessellationDataTransfer { -public: - TessellationDataTransferVulkan(VulkanContext *vulkan) : vulkan_(vulkan) {} - - void SetPushPool(VulkanPushPool *push) { push_ = push; } - // Send spline/bezier's control points and weights to vertex shader through structured shader buffer. - void SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Spline::Weight2D &weights) override; - const VkDescriptorBufferInfo *GetBufferInfo() { return bufInfo_; } -private: - VulkanContext *vulkan_; - VulkanPushPool *push_; // Updated each frame. - VkDescriptorBufferInfo bufInfo_[3]{}; -}; - enum { DRAW_BINDING_TEXTURE = 0, DRAW_BINDING_2ND_TEXTURE = 1, @@ -227,7 +213,4 @@ private: int tessOffset_ = 0; FBOTexState fboTexBindState_ = FBO_TEX_NONE; - - // Hardware tessellation - TessellationDataTransferVulkan *tessDataTransferVulkan = nullptr; }; diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index aaa5871baa..36375f4152 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -214,8 +214,6 @@ u32 GPU_Vulkan::CheckGPUFeatures() const { // Mandatory features on Vulkan, which may be checked in "centralized" code features |= GPU_USE_TEXTURE_LOD_CONTROL; - features |= GPU_USE_INSTANCE_RENDERING; - features |= GPU_USE_VERTEX_TEXTURE_FETCH; features |= GPU_USE_TEXTURE_FLOAT; if (!draw_->GetBugs().Has(Draw::Bugs::PVR_BAD_16BIT_TEXFORMATS)) { diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index 276895ad8c..9366a1d7f1 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -244,7 +244,7 @@ uint64_t ShaderManagerVulkan::UpdateUniforms(bool useBufferedRendering) { return dirty; } -void ShaderManagerVulkan::GetShaders(int prim, u32 vertexType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader, const ComputedPipelineState &pipelineState, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat, bool useSkinInDecode, ClipInfoFlags clipInfoFlags) { +void ShaderManagerVulkan::GetShaders(int prim, u32 vertexType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader, const ComputedPipelineState &pipelineState, bool useHWTransform, bool weightsAsFloat, bool useSkinInDecode, ClipInfoFlags clipInfoFlags) { VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); VShaderID VSID; @@ -254,7 +254,7 @@ void ShaderManagerVulkan::GetShaders(int prim, u32 vertexType, VulkanVertexShade if (gstate_c.IsDirty(DIRTY_VERTEXSHADER_STATE)) { gstate_c.Clean(DIRTY_VERTEXSHADER_STATE); recomputedVS = true; - ComputeVertexShaderID(&VSID, vertexType, useHWTransform, useHWTessellation, weightsAsFloat, useSkinInDecode, clipInfoFlags); + ComputeVertexShaderID(&VSID, vertexType, useHWTransform, weightsAsFloat, useSkinInDecode, clipInfoFlags); if (VSID == lastVSID_) { _dbg_assert_(lastVShader_ != nullptr); vs = lastVShader_; diff --git a/GPU/Vulkan/ShaderManagerVulkan.h b/GPU/Vulkan/ShaderManagerVulkan.h index 5a72bda512..6104880feb 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.h +++ b/GPU/Vulkan/ShaderManagerVulkan.h @@ -102,7 +102,7 @@ public: void DeviceLost() override; void DeviceRestore(Draw::DrawContext *draw) override; - void GetShaders(int prim, u32 vertexType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader, const ComputedPipelineState &pipelineState, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat, bool useSkinInDecode, ClipInfoFlags clipInfoFlags); + void GetShaders(int prim, u32 vertexType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader, const ComputedPipelineState &pipelineState, bool useHWTransform, bool weightsAsFloat, bool useSkinInDecode, ClipInfoFlags clipInfoFlags); void ClearShaders() override; void DirtyLastShader() override; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 4b1b6fa2e7..af4cd23013 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -159,35 +159,6 @@ void GameSettingsScreen::PreCreateViews() { ReloadAllThemeInfo(); } -// This needs before run CheckGPUFeatures() -// TODO: Remove this if fix the issue -static bool CheckSupportShaderTessellationGLES() { -#if PPSSPP_PLATFORM(UWP) - return true; -#else - // TODO: Make work with non-GL backends - int maxVertexTextureImageUnits = gl_extensions.maxVertexTextureUnits; - bool vertexTexture = maxVertexTextureImageUnits >= 3; // At least 3 for hardware tessellation - - bool textureFloat = gl_extensions.ARB_texture_float || gl_extensions.OES_texture_float; - bool hasTexelFetch = gl_extensions.GLES3 || (!gl_extensions.IsGLES && gl_extensions.VersionGEThan(3, 3, 0)) || gl_extensions.EXT_gpu_shader4; - - return vertexTexture && textureFloat && hasTexelFetch; -#endif -} - -static bool DoesBackendSupportHWTess() { - switch (GetGPUBackend()) { - case GPUBackend::OPENGL: - return CheckSupportShaderTessellationGLES(); - case GPUBackend::VULKAN: - case GPUBackend::DIRECT3D11: - return true; - default: - return false; - } -} - static bool UsingHardwareTextureScaling() { // For now, Vulkan only. return g_Config.bTexHardwareScaling && GetGPUBackend() == GPUBackend::VULKAN && !g_Config.bSoftwareRendering; @@ -563,14 +534,6 @@ void GameSettingsScreen::CreateGraphicsSettings(UI::ViewGroup *graphicsSettings) swSkin->SetDisabledPtr(&g_Config.bSoftwareRendering); graphicsSettings->Add(new SettingHint(gr->T("SoftwareSkinning Tip", "Combine skinned model draws on the CPU, faster in most games"), swSkin)); - if (DoesBackendSupportHWTess()) { - CheckBox *tessellationHW = graphicsSettings->Add(new CheckBox(&g_Config.bHardwareTessellation, gr->T("Hardware Tessellation"))); - tessellationHW->SetEnabledFunc([]() { - return !g_Config.bSoftwareRendering && g_Config.bHardwareTransform; - }); - graphicsSettings->Add(new SettingHint(gr->T("HardwareTessellation Tip", "Uses hardware to make curves"), tessellationHW)); - } - graphicsSettings->Add(new ItemHeader(gr->T("Texture upscaling"))); if (GetGPUBackend() == GPUBackend::VULKAN) { diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index b66e5bf763..8bc85d61b9 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -818,15 +818,6 @@ static void check_variables(CoreParameter &coreParam) g_Config.bSoftwareSkinning = true; } - var.key = "ppsspp_hardware_tesselation"; - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - if (!strcmp(var.value, "disabled")) - g_Config.bHardwareTessellation = false; - else - g_Config.bHardwareTessellation = true; - } - var.key = "ppsspp_lower_resolution_for_effects"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {