Procházet zdrojové kódy

Remove Shader Model 2 mode & instancing without stream offset (D3D9) as they are hard to test. Added Graphics::GetApiName() function.

Lasse Öörni před 10 roky
rodič
revize
88080dad31
34 změnil soubory, kde provedl 106 přidání a 323 odebrání
  1. 1 2
      Docs/GettingStarted.dox
  2. 6 16
      Docs/Reference.dox
  3. 0 1
      Source/Tools/Urho3DPlayer/Urho3DPlayer.cpp
  4. 2 6
      Source/Urho3D/Engine/DebugHud.cpp
  5. 0 3
      Source/Urho3D/Engine/Engine.cpp
  6. 6 37
      Source/Urho3D/Graphics/Batch.cpp
  7. 7 26
      Source/Urho3D/Graphics/Direct3D9/D3D9Graphics.cpp
  8. 8 16
      Source/Urho3D/Graphics/Direct3D9/D3D9Graphics.h
  9. 5 21
      Source/Urho3D/Graphics/Direct3D9/D3D9ShaderVariation.cpp
  10. 1 10
      Source/Urho3D/Graphics/Light.cpp
  11. 7 11
      Source/Urho3D/Graphics/OpenGL/OGLGraphics.cpp
  12. 4 8
      Source/Urho3D/Graphics/OpenGL/OGLGraphics.h
  13. 1 4
      Source/Urho3D/Graphics/Renderer.cpp
  14. 0 19
      Source/Urho3D/Graphics/Technique.cpp
  15. 2 16
      Source/Urho3D/Graphics/Technique.h
  16. 20 23
      Source/Urho3D/Graphics/View.cpp
  17. 2 4
      Source/Urho3D/LuaScript/pkgs/Graphics/Graphics.pkg
  18. 0 4
      Source/Urho3D/LuaScript/pkgs/Graphics/Technique.pkg
  19. 1 7
      Source/Urho3D/Script/GraphicsAPI.cpp
  20. 19 47
      bin/CoreData/Shaders/HLSL/Lighting.hlsl
  21. 1 11
      bin/CoreData/Shaders/HLSL/LitSolid.hlsl
  22. 2 11
      bin/CoreData/Shaders/HLSL/Samplers.hlsl
  23. 0 5
      bin/CoreData/Shaders/HLSL/TerrainBlend.hlsl
  24. 1 5
      bin/CoreData/Shaders/HLSL/Uniforms.hlsl
  25. 1 1
      bin/CoreData/Techniques/DiffNormal.xml
  26. 1 1
      bin/CoreData/Techniques/DiffNormalAlphaMask.xml
  27. 1 1
      bin/CoreData/Techniques/DiffNormalPacked.xml
  28. 1 1
      bin/CoreData/Techniques/DiffNormalPackedAlphaMask.xml
  29. 1 1
      bin/CoreData/Techniques/DiffNormalPackedSpec.xml
  30. 1 1
      bin/CoreData/Techniques/DiffNormalPackedSpecAlphaMask.xml
  31. 1 1
      bin/CoreData/Techniques/DiffNormalSpec.xml
  32. 1 1
      bin/CoreData/Techniques/DiffNormalSpecAlphaMask.xml
  33. 1 1
      bin/CoreData/Techniques/NoTextureNormal.xml
  34. 1 1
      bin/CoreData/Techniques/NoTextureNormalPacked.xml

+ 1 - 2
Docs/GettingStarted.dox

@@ -22,7 +22,7 @@ Although all required third-party libraries are included as source code, there a
 
 To run Urho3D, the minimum system requirements are:
 
-- Windows: CPU with SSE instructions support, Windows XP or newer, DirectX 9.0c, GPU with %Shader %Model 2 support (%Shader %Model 3 recommended.)
+- Windows: CPU with SSE instructions support, Windows XP or newer, DirectX 9.0c, GPU with %Shader %Model 3 support.
 
 - Linux & Mac OS X: CPU with SSE instructions support, GPU with OpenGL 2.0 support, EXT_framebuffer_object and EXT_packed_depth_stencil extensions.
 
@@ -320,7 +320,6 @@ The engine can be configured using the following command line options.
 -nothreads   Disable worker threads
 -nosound     Disable sound output
 -noip        Disable sound mixing interpolation
--sm2         Force SM2.0 rendering
 -touch       Touch emulation on desktop platform
 \endverbatim
 

+ 6 - 16
Docs/Reference.dox

@@ -133,7 +133,6 @@ The full list of supported parameters, their datatypes and default values:
 - ResourcePaths (string) A semicolon-separated list of resource paths to use. If corresponding packages (ie. Data.pak for Data directory) exist they will be used instead. Default "Data;CoreData".
 - ResourcePackages (string) A semicolon-separated list of resource packages to use. Default empty.
 - AutoloadPaths (string) A semicolon-separated list of autoload paths to use. Any resource packages and subdirectories inside an autoload path will be added to the resource system. Default "Autoload".
-- ForceSM2 (bool) Whether to force %Shader %Model 2, effective in Direct3D9 mode only. Default false.
 - ExternalWindow (void ptr) External window handle to use instead of creating an application window. Default null.
 - WindowIcon (string) %Window icon image resource name. Default empty (use application default icon.)
 - WindowTitle (string) %Window title. Default "Urho3D".
@@ -713,19 +712,12 @@ Screen resolution, fullscreen/windowed, vertical sync and hardware multisampling
 
 When setting the initial screen mode, Graphics does a few checks:
 
-- For Direct3D9, the supported shader model is checked. 2 is minimum, but 3 will be used if available. For testing, SM2 can be forced by calling \ref Graphics::SetForceSM2 "SetForceSM2()" before setting the initial screen mode.
+- For Direct3D9, shader model 3.0 support is checked.
 - For OpenGL, version 2.0 with EXT_framebuffer_object, EXT_packed_depth_stencil and EXT_texture_filter_anisotropic extensions is checked for.
 - Is hardware instancing supported? This requires %Shader %Model 3 on Direct3D9 and the ARB_instanced_arrays extension on OpenGL.
 - Are hardware shadow maps supported? Both AMD & NVIDIA style shadow maps can be used. If neither are available, no shadows will be rendered.
 - Are light pre-pass and deferred rendering modes supported? These require sufficient multiple rendertarget support, and R32F texture format support.
 
-%Shader model 2 has the following limitations due to limited pixel shader instruction count:
-
-- Directional light shadows support a maximum of 3 cascade splits instead of 4.
-- Shadowed point lights do not support specular calculations in forward rendering.
-- Complex materials do not combine the ambient pass with the first forward light (lit base pass optimization.)
-- Complex forward rendered materials (eg. normal + specular map + alpha masking) combined with shadow mapping or height fog may not work.
-
 \section Rendering_Renderer Renderer
 
 Renderer implements the actual rendering of 3D views each frame, and controls global settings such as texture quality, material quality, specular lighting and shadow map base resolution.
@@ -992,8 +984,8 @@ For the layout definitions, see http://www.cgtextures.com/content.php?action=tut
 A technique definition looks like this:
 
 \code
-<technique vs="VertexShaderName" ps="PixelShaderName" vsdefines="DEFINE1 DEFINE2" psdefines="DEFINE3 DEFINE4" sm3="false|true" desktop="false|true" >
-    <pass name="base|litbase|light|alpha|litalpha|postopaque|refract|postalpha|prepass|material|deferred|depth|shadow" sm3="false|true" desktop="false|true" >
+<technique vs="VertexShaderName" ps="PixelShaderName" vsdefines="DEFINE1 DEFINE2" psdefines="DEFINE3 DEFINE4" desktop="false|true" >
+    <pass name="base|litbase|light|alpha|litalpha|postopaque|refract|postalpha|prepass|material|deferred|depth|shadow" desktop="false|true" >
         vs="VertexShaderName" ps="PixelShaderName" vsdefines="DEFINE1 DEFINE2" psdefines="DEFINE3 DEFINE4"
         lighting="unlit|pervertex|perpixel"
         blend="replace|add|multiply|alpha|addalpha|premulalpha|invdestalpha|subtract|subtractalpha"
@@ -1005,9 +997,7 @@ A technique definition looks like this:
 </technique>
 \endcode
 
-The "sm3" attribute in the technique root element allows the technique to specify it requires %Shader %Model 3 hardware. Omitting it is same as specifying false (works on both SM2 & 3.) The sm3 attribute can also be specified per pass, to disable for example a too complex lit base optimization pass on SM2.
-
-The "desktop" attribute in either technique or pass works similarly to allow requiring desktop hardware and excluding mobile devices.
+The "desktop" attribute in either technique or pass allows to specify it requires desktop graphics hardware (exclude mobile devices.) Omitting it is the same as specifying false.
 
 Shaders are referred to by giving the name of a shader without path and file extension. For example "Basic" or "LitSolid". The engine will add the correct path and file extension (Shaders/HLSL/LitSolid.hlsl for Direct3D9, and Shaders/GLSL/LitSolid.glsl for OpenGL) automatically. The same shader source file contains both the vertex and pixel shader. In addition, compilation defines can be specified, which are passed to the shader compiler. For example the define "DIFFMAP" typically enables diffuse mapping in the pixel shader.
 
@@ -1121,7 +1111,7 @@ vec3 worldPos = GetWorldPos(modelMatrix);
 gl_Position = GetClipPos(worldPos);
 \endcode
 
-On both Direct3D9 and OpenGL the vertex and pixel shaders are written into the same file, and the entrypoint functions must be called VS() and PS(). In OpenGL mode one of these is transformed to the main() function required by GLSL behind the scenes. When compiling a vertex shader, the compilation define "COMPILEVS" is always present, and likewise "COMPILEPS" when compiling a pixel shader. These are heavily used in the shader include files to prevent constructs that are illegal for the "wrong" type of shader, and to reduce compilation time. When compiling for %Shader %Model 3 on Direct3D9, the compilation define "SM3" is present: this can be used to separate code which would not compile on SM2.
+On both Direct3D9 and OpenGL the vertex and pixel shaders are written into the same file, and the entrypoint functions must be called VS() and PS(). In OpenGL mode one of these is transformed to the main() function required by GLSL behind the scenes. When compiling a vertex shader, the compilation define "COMPILEVS" is always present, and likewise "COMPILEPS" when compiling a pixel shader. These are heavily used in the shader include files to prevent constructs that are illegal for the "wrong" type of shader, and to reduce compilation time.
 
 The uniforms must be prefixed in a certain way so that the engine understands them:
 
@@ -2708,7 +2698,7 @@ Note: animations are stored using absolute bone transformations. Therefore only
 byte[4]    Identifier "USHD"
 
 short      Shader type (0 = vertex, 1 = pixel)
-short      Shader model (2 or 3)
+short      Shader model (3)
 
 uint       Number of constant parameters
 

+ 0 - 1
Source/Tools/Urho3DPlayer/Urho3DPlayer.cpp

@@ -114,7 +114,6 @@ void Urho3DPlayer::Setup()
             "-nothreads   Disable worker threads\n"
             "-nosound     Disable sound output\n"
             "-noip        Disable sound mixing interpolation\n"
-            "-sm2         Force SM2.0 rendering\n"
             "-touch       Touch emulation on desktop platform\n"
             #endif
         );

+ 2 - 6
Source/Urho3D/Engine/DebugHud.cpp

@@ -142,7 +142,7 @@ void DebugHud::Update()
     if (modeText_->IsVisible())
     {
         String mode;
-        mode.AppendWithFormat("Tex:%s Mat:%s Spec:%s Shadows:%s Size:%i Quality:%s Occlusion:%s Instancing:%s Mode:%s",
+        mode.AppendWithFormat("Tex:%s Mat:%s Spec:%s Shadows:%s Size:%i Quality:%s Occlusion:%s Instancing:%s API:%s",
             qualityTexts[renderer->GetTextureQuality()],
             qualityTexts[renderer->GetMaterialQuality()],
             renderer->GetSpecularLighting() ? "On" : "Off",
@@ -151,11 +151,7 @@ void DebugHud::Update()
             shadowQualityTexts[renderer->GetShadowQuality()],
             renderer->GetMaxOccluderTriangles() > 0 ? "On" : "Off",
             renderer->GetDynamicInstancing() ? "On" : "Off",
-            #ifdef URHO3D_OPENGL
-            "OGL");
-            #else
-            graphics->GetSM3Support() ? "SM3" : "SM2");
-            #endif
+            graphics->GetApiName().CString());
 
         modeText_->SetText(mode);
     }

+ 0 - 3
Source/Urho3D/Engine/Engine.cpp

@@ -310,7 +310,6 @@ bool Engine::Initialize(const VariantMap& parameters)
 
         if (HasParameter(parameters, "ExternalWindow"))
             graphics->SetExternalWindow(GetParameter(parameters, "ExternalWindow").GetVoidPtr());
-        graphics->SetForceSM2(GetParameter(parameters, "ForceSM2", false).GetBool());
         graphics->SetWindowTitle(GetParameter(parameters, "WindowTitle", "Urho3D").GetString());
         graphics->SetWindowIcon(cache->GetResource<Image>(GetParameter(parameters, "WindowIcon", String::EMPTY).GetString()));
         graphics->SetFlushGPU(GetParameter(parameters, "FlushGPU", false).GetBool());
@@ -749,8 +748,6 @@ VariantMap Engine::ParseParameters(const Vector<String>& arguments)
                 ret["LowQualityShadows"] = true;
             else if (argument == "nothreads")
                 ret["WorkerThreads"] = false;
-            else if (argument == "sm2")
-                ret["ForceSM2"] = true;
             else if (argument == "v")
                 ret["VSync"] = true;
             else if (argument == "t")

+ 6 - 37
Source/Urho3D/Graphics/Batch.cpp

@@ -623,9 +623,9 @@ void BatchGroup::Draw(View* view, bool allowDepthWrite) const
     
     if (instances_.Size() && !geometry_->IsEmpty())
     {
-        // Draw as individual objects if instancing not supported
+        // Draw as individual objects if instancing not supported or could not fill the instancing buffer
         VertexBuffer* instanceBuffer = renderer->GetInstancingBuffer();
-        if (!instanceBuffer || geometryType_ != GEOM_INSTANCED)
+        if (!instanceBuffer || geometryType_ != GEOM_INSTANCED || startIndex_ == M_MAX_UNSIGNED)
         {
             Batch::Prepare(view, false, allowDepthWrite);
             
@@ -653,41 +653,10 @@ void BatchGroup::Draw(View* view, bool allowDepthWrite) const
             vertexBuffers.Push(SharedPtr<VertexBuffer>(instanceBuffer));
             elementMasks.Push(instanceBuffer->GetElementMask());
             
-            // No stream offset support, instancing buffer not pre-filled with transforms: have to fill now
-            if (startIndex_ == M_MAX_UNSIGNED)
-            {
-                unsigned startIndex = 0;
-                while (startIndex < instances_.Size())
-                {
-                    unsigned instances = instances_.Size() - startIndex;
-                    if (instances > instanceBuffer->GetVertexCount())
-                        instances = instanceBuffer->GetVertexCount();
-                    
-                    // Copy the transforms
-                    Matrix3x4* dest = (Matrix3x4*)instanceBuffer->Lock(0, instances, true);
-                    if (dest)
-                    {
-                        for (unsigned i = 0; i < instances; ++i)
-                            dest[i] = *instances_[i + startIndex].worldTransform_;
-                        instanceBuffer->Unlock();
-                        
-                        graphics->SetIndexBuffer(geometry_->GetIndexBuffer());
-                        graphics->SetVertexBuffers(vertexBuffers, elementMasks);
-                        graphics->DrawInstanced(geometry_->GetPrimitiveType(), geometry_->GetIndexStart(),
-                            geometry_->GetIndexCount(), geometry_->GetVertexStart(), geometry_->GetVertexCount(), instances);
-                    }
-                    
-                    startIndex += instances;
-                }
-            }
-            // Stream offset supported and instancing buffer has been already filled, so just draw
-            else
-            {
-                graphics->SetIndexBuffer(geometry_->GetIndexBuffer());
-                graphics->SetVertexBuffers(vertexBuffers, elementMasks, startIndex_);
-                graphics->DrawInstanced(geometry_->GetPrimitiveType(), geometry_->GetIndexStart(), geometry_->GetIndexCount(),
-                    geometry_->GetVertexStart(), geometry_->GetVertexCount(), instances_.Size());
-            }
+            graphics->SetIndexBuffer(geometry_->GetIndexBuffer());
+            graphics->SetVertexBuffers(vertexBuffers, elementMasks, startIndex_);
+            graphics->DrawInstanced(geometry_->GetPrimitiveType(), geometry_->GetIndexStart(), geometry_->GetIndexCount(),
+                geometry_->GetVertexStart(), geometry_->GetVertexCount(), instances_.Size());
             
             // Remove the instancing buffer & element mask now
             vertexBuffers.Pop();

+ 7 - 26
Source/Urho3D/Graphics/Direct3D9/D3D9Graphics.cpp

@@ -265,12 +265,9 @@ Graphics::Graphics(Context* context) :
     queryIssued_(false),
     lightPrepassSupport_(false),
     deferredSupport_(false),
-    hardwareShadowSupport_(false),
-    streamOffsetSupport_(false),
+    instancingSupport_(false),
     sRGBSupport_(false),
     sRGBWriteSupport_(false),
-    hasSM3_(false),
-    forceSM2_(false),
     numPrimitives_(0),
     numBatches_(0),
     maxScratchBufferRequest_(0),
@@ -278,7 +275,8 @@ Graphics::Graphics(Context* context) :
     currentShaderParameters_(0),
     shaderPath_("Shaders/HLSL/"),
     shaderExtension_(".hlsl"),
-    orientations_("LandscapeLeft LandscapeRight")
+    orientations_("LandscapeLeft LandscapeRight"),
+    apiName_("D3D9")
 {
     SetTextureUnitMappings();
     
@@ -1971,14 +1969,6 @@ void Graphics::ResetStreamFrequencies()
     }
 }
 
-void Graphics::SetForceSM2(bool enable)
-{
-    if (!IsInitialized())
-        forceSM2_ = enable;
-    else
-        LOGERROR("Force Shader Model 2 can not be changed after setting the initial screen mode");
-}
-
 void Graphics::BeginDumpShaders(const String& fileName)
 {
     shaderPrecache_ = new ShaderPrecache(context_, fileName);
@@ -2553,9 +2543,9 @@ bool Graphics::CreateInterface()
         return false;
     }
     
-    if (impl_->deviceCaps_.PixelShaderVersion < D3DPS_VERSION(2, 0))
+    if (impl_->deviceCaps_.PixelShaderVersion < D3DPS_VERSION(3, 0))
     {
-        LOGERROR("Shader model 2.0 display adapter is required");
+        LOGERROR("Shader model 3.0 display adapter is required");
         return false;
     }
     
@@ -2605,8 +2595,7 @@ void Graphics::CheckFeatureSupport()
     lightPrepassSupport_ = false;
     deferredSupport_ = false;
     hardwareShadowSupport_ = false;
-    streamOffsetSupport_ = false;
-    hasSM3_ = false;
+    instancingSupport_ = false;
     readableDepthFormat = 0;
     
     // Check hardware shadow map support: prefer NVIDIA style hardware depth compared shadow maps if available
@@ -2663,14 +2652,6 @@ void Graphics::CheckFeatureSupport()
         dummyColorFormat_ = D3DFMT_R5G6B5;
     else if (impl_->CheckFormatSupport(D3DFMT_A4R4G4B4, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE))
         dummyColorFormat_ = D3DFMT_A4R4G4B4;
-        
-    // Check for Shader Model 3
-    if (!forceSM2_)
-    {
-        if (impl_->deviceCaps_.VertexShaderVersion >= D3DVS_VERSION(3, 0) && impl_->deviceCaps_.PixelShaderVersion >=
-            D3DPS_VERSION(3, 0))
-            hasSM3_ = true;
-    }
     
     // Check for light prepass and deferred rendering support
     if (impl_->deviceCaps_.NumSimultaneousRTs >= 2 && impl_->CheckFormatSupport(D3DFMT_R32F, D3DUSAGE_RENDERTARGET,
@@ -2683,7 +2664,7 @@ void Graphics::CheckFeatureSupport()
     
     // Check for stream offset (needed for instancing)
     if (impl_->deviceCaps_.DevCaps2 & D3DDEVCAPS2_STREAMOFFSET)
-        streamOffsetSupport_ = true;
+        instancingSupport_ = true;
     
     // Check for sRGB read & write
     /// \todo Should be checked for each texture format separately

+ 8 - 16
Source/Urho3D/Graphics/Direct3D9/D3D9Graphics.h

@@ -216,8 +216,6 @@ public:
     void SetStreamFrequency(unsigned index, unsigned frequency);
     /// Reset stream frequencies.
     void ResetStreamFrequencies();
-    /// Set force Shader Model 2 flag. Only effective before setting the initial screen mode.
-    void SetForceSM2(bool enable);
     /// Begin dumping shader variation names to an XML file for precaching.
     void BeginDumpShaders(const String& fileName);
     /// End dumping shader variations names.
@@ -233,6 +231,8 @@ public:
     void* GetExternalWindow() const { return externalWindow_; }
     /// Return window title.
     const String& GetWindowTitle() const { return windowTitle_; }
+    /// Return graphics API name.
+    const String& GetApiName() const { return apiName_; }
     /// Return window position.
     IntVector2 GetWindowPosition() const;
     /// Return window width.
@@ -269,10 +269,8 @@ public:
     unsigned GetShadowMapFormat() const { return shadowMapFormat_; }
     /// Return 24-bit shadow map depth texture format, or 0 if not supported.
     unsigned GetHiresShadowMapFormat() const { return hiresShadowMapFormat_; }
-    /// Return whether Shader Model 3 is supported.
-    bool GetSM3Support() const { return hasSM3_; }
-    /// Return whether hardware instancing is supported.
-    bool GetInstancingSupport() const { return hasSM3_; }
+    /// Return whether hardware instancing is supported..
+    bool GetInstancingSupport() const { return instancingSupport_; }
     /// Return whether light pre-pass rendering is supported.
     bool GetLightPrepassSupport() const { return lightPrepassSupport_; }
     /// Return whether deferred rendering is supported.
@@ -281,8 +279,6 @@ public:
     bool GetHardwareShadowSupport() const { return hardwareShadowSupport_; }
     /// Return whether a readable hardware depth format is available.
     bool GetReadableDepthSupport() const { return GetReadableDepthFormat() != 0; }
-    /// Return whether stream offset is supported.
-    bool GetStreamOffsetSupport() const { return streamOffsetSupport_; }
     /// Return whether sRGB conversion on texture sampling is supported.
     bool GetSRGBSupport() const { return sRGBSupport_; }
     /// Return whether sRGB conversion on rendertarget writing is supported.
@@ -369,8 +365,6 @@ public:
     unsigned GetStreamFrequency(unsigned index) const;
     /// Return rendertarget width and height.
     IntVector2 GetRenderTargetDimensions() const;
-    /// Return force Shader Model 2 flag.
-    bool GetForceSM2() const { return forceSM2_; }
     
     /// Window was resized through user interaction. Called by Input subsystem.
     void WindowResized();
@@ -496,16 +490,12 @@ private:
     bool deferredSupport_;
     /// Hardware shadow map depth compare support flag.
     bool hardwareShadowSupport_;
-    /// Stream offset support flag.
-    bool streamOffsetSupport_;
+    /// Instancing support flag.
+    bool instancingSupport_;
     /// sRGB conversion on read support flag.
     bool sRGBSupport_;
     /// sRGB conversion on write support flag.
     bool sRGBWriteSupport_;
-    /// Shader Model 3 flag.
-    bool hasSM3_;
-    /// Force Shader Model 2 flag.
-    bool forceSM2_;
     /// Number of primitives this frame.
     unsigned numPrimitives_;
     /// Number of batches this frame.
@@ -610,6 +600,8 @@ private:
     SharedPtr<ShaderPrecache> shaderPrecache_;
     /// Allowed screen orientations.
     String orientations_;
+    /// Graphics API name.
+    String apiName_;
 
     /// Pixel perfect UV offset.
     static const Vector2 pixelUVOffset;

+ 5 - 21
Source/Urho3D/Graphics/Direct3D9/D3D9ShaderVariation.cpp

@@ -66,13 +66,9 @@ bool ShaderVariation::Create()
     }
 
     // Check for up-to-date bytecode on disk
-    bool useSM3 = graphics_->GetSM3Support();
     String path, name, extension;
     SplitPath(owner_->GetName(), path, name, extension);
-    if (useSM3)
-        extension = type_ == VS ? ".vs3" : ".ps3";
-    else
-        extension = type_ == VS ? ".vs2" : ".ps2";
+    extension = type_ == VS ? ".vs3" : ".ps3";
     
     String binaryShaderName = path + "Cache/" + name + "_" + StringHash(defines_).ToString() + extension;
     PODVector<unsigned> byteCode;
@@ -231,33 +227,21 @@ bool ShaderVariation::Compile(PODVector<unsigned>& byteCode)
     const char* entryPoint = 0;
     const char* profile = 0;
     unsigned flags = D3DCOMPILE_OPTIMIZATION_LEVEL3;
-    bool useSM3 = graphics_->GetSM3Support();
     
     if (type_ == VS)
     {
         entryPoint = "VS";
         defines.Push("COMPILEVS");
-        if (!useSM3)
-            profile = "vs_2_0";
-        else
-            profile = "vs_3_0";
+        profile = "vs_3_0";
     }
     else
     {
         entryPoint = "PS";
         defines.Push("COMPILEPS");
-        if (!useSM3)
-            profile = "ps_2_0";
-        else
-        {
-            profile = "ps_3_0";
-            flags |= D3DCOMPILE_PREFER_FLOW_CONTROL;
-        }
+        profile = "ps_3_0";
+        flags |= D3DCOMPILE_PREFER_FLOW_CONTROL;
     }
     
-    if (useSM3)
-        defines.Push("SM3");
-    
     // Collect defines into macros
     Vector<String> defineValues;
     PODVector<D3D_SHADER_MACRO> macros;
@@ -399,7 +383,7 @@ void ShaderVariation::SaveByteCode(const PODVector<unsigned>& byteCode, const St
     
     file->WriteFileID("USHD");
     file->WriteShort((unsigned short)type_);
-    file->WriteShort(graphics_->GetSM3Support() ? 3 : 2);
+    file->WriteShort(3);
 
     file->WriteUInt(parameters_.Size());
     for (HashMap<StringHash, ShaderParameter>::ConstIterator i = parameters_.Begin(); i != parameters_.End(); ++i)

+ 1 - 10
Source/Urho3D/Graphics/Light.cpp

@@ -396,16 +396,7 @@ int Light::GetNumShadowSplits() const
         }
     }
 
-    ret = Min(ret, MAX_CASCADE_SPLITS);
-    // Shader Model 2 can only support 3 splits max. due to pixel shader instruction count limits
-    if (ret == 4)
-    {
-        Graphics* graphics = GetSubsystem<Graphics>();
-        if (graphics && !graphics->GetSM3Support())
-            --ret;
-    }
-
-    return ret;
+    return Min(ret, MAX_CASCADE_SPLITS);
 }
 
 const Matrix3x4& Light::GetVolumeTransform(Camera* camera)

+ 7 - 11
Source/Urho3D/Graphics/OpenGL/OGLGraphics.cpp

@@ -252,7 +252,12 @@ Graphics::Graphics(Context* context_) :
     defaultTextureFilterMode_(FILTER_TRILINEAR),
     shaderPath_("Shaders/GLSL/"),
     shaderExtension_(".glsl"),
-    orientations_("LandscapeLeft LandscapeRight")
+    orientations_("LandscapeLeft LandscapeRight"),
+    #ifndef GL_ES_VERSION_2_0
+    apiName_("GL2")
+    #else
+    apiName_("GLES2")
+    #endif
 {
     SetTextureUnitMappings();
     ResetCachedState();
@@ -313,7 +318,6 @@ void Graphics::SetWindowPosition(int x, int y)
 bool Graphics::SetMode(int width, int height, bool fullscreen, bool borderless, bool resizable, bool vsync, bool tripleBuffer, int multiSample)
 {
     PROFILE(SetScreenMode);
-LOGINFO("Graphics::SetMode()");
 
     bool maximize = false;
     
@@ -326,12 +330,8 @@ LOGINFO("Graphics::SetMode()");
         fullscreen = false;
 
     multiSample = Clamp(multiSample, 1, 16);
-bool isInitialized = IsInitialized();
-LOGINFO(isInitialized ? "isInitialized == true" : "isInitialized == false");
 
-    
-    //if (IsInitialized() && width == width_ && height == height_ && fullscreen == fullscreen_ && borderless == borderless_ && resizable == resizable_ &&
-    if (isInitialized && width == width_ && height == height_ && fullscreen == fullscreen_ && borderless == borderless_ && resizable == resizable_ &&
+    if (IsInitialized() && width == width_ && height == height_ && fullscreen == fullscreen_ && borderless == borderless_ && resizable == resizable_ &&
         vsync == vsync_ && tripleBuffer == tripleBuffer_ && multiSample == multiSample_)
         return true;
     
@@ -1954,10 +1954,6 @@ void Graphics::SetStencilTest(bool enable, CompareMode mode, StencilOp pass, Ste
     #endif
 }
 
-void Graphics::SetForceSM2(bool enable)
-{
-}
-
 void Graphics::BeginDumpShaders(const String& fileName)
 {
     shaderPrecache_ = new ShaderPrecache(context_, fileName);

+ 4 - 8
Source/Urho3D/Graphics/OpenGL/OGLGraphics.h

@@ -221,8 +221,6 @@ public:
     void SetStreamFrequency(unsigned index, unsigned frequency);
     /// Reset stream frequencies. No-op on OpenGL.
     void ResetStreamFrequencies();
-    /// Set force Shader Model 2 flag. No-op on OpenGL.
-    void SetForceSM2(bool enable);
     /// Begin dumping shader variation names to an XML file for precaching.
     void BeginDumpShaders(const String& fileName);
     /// End dumping shader variations names.
@@ -238,6 +236,8 @@ public:
     void* GetExternalWindow() const { return externalWindow_; }
     /// Return window title.
     const String& GetWindowTitle() const { return windowTitle_; }
+    /// Return graphics API name.
+    const String& GetApiName() const { return apiName_; }
     /// Return window position.
     IntVector2 GetWindowPosition() const;
     /// Return window width.
@@ -274,8 +274,6 @@ public:
     unsigned GetShadowMapFormat() const { return shadowMapFormat_; }
     /// Return 24-bit shadow map depth texture format, or 0 if not supported.
     unsigned GetHiresShadowMapFormat() const { return hiresShadowMapFormat_; }
-    /// Return whether Shader Model 3 is supported. Has no meaning on OpenGL, so is assumed to be true.
-    bool GetSM3Support() const { return true; }
     /// Return whether hardware instancing is supported.
     bool GetInstancingSupport() const { return instancingSupport_; }
     /// Return whether light pre-pass rendering is supported.
@@ -288,8 +286,6 @@ public:
     bool GetHardwareShadowSupport() const { return true; }
     /// Return whether a readable hardware depth format is available.
     bool GetReadableDepthSupport() const { return GetReadableDepthFormat() != 0; }
-    /// Return whether stream offset is supported. Always true on OpenGL.
-    bool GetStreamOffsetSupport() const { return true; }
     /// Return whether sRGB conversion on texture sampling is supported.
     bool GetSRGBSupport() const { return sRGBSupport_; }
     /// Return whether sRGB conversion on rendertarget writing is supported.
@@ -378,8 +374,6 @@ public:
     unsigned GetStreamFrequency(unsigned index) const;
     /// Return rendertarget width and height.
     IntVector2 GetRenderTargetDimensions() const;
-    /// Return force Shader Model 2 flag. Always false on OpenGL.
-    bool GetForceSM2() const { return false; }
 
     /// Window was resized through user interaction. Called by Input subsystem.
     void WindowResized();
@@ -615,6 +609,8 @@ private:
     SharedPtr<ShaderPrecache> shaderPrecache_;
     /// Allowed screen orientations.
     String orientations_;
+    /// Graphics API name.
+    String apiName_;
 
     /// Pixel perfect UV offset.
     static const Vector2 pixelUVOffset;

+ 1 - 4
Source/Urho3D/Graphics/Renderer.cpp

@@ -1695,11 +1695,8 @@ void Renderer::CreateInstancingBuffer()
         return;
     }
     
-    // If must lock the buffer for each batch group, set a smaller size
-    unsigned defaultSize = graphics_->GetStreamOffsetSupport() ? INSTANCING_BUFFER_DEFAULT_SIZE : INSTANCING_BUFFER_DEFAULT_SIZE / 4;
-    
     instancingBuffer_ = new VertexBuffer(context_);
-    if (!instancingBuffer_->SetSize(defaultSize, INSTANCING_BUFFER_MASK, true))
+    if (!instancingBuffer_->SetSize(INSTANCING_BUFFER_DEFAULT_SIZE, INSTANCING_BUFFER_MASK, true))
     {
         instancingBuffer_.Reset();
         dynamicInstancing_ = false;

+ 0 - 19
Source/Urho3D/Graphics/Technique.cpp

@@ -77,7 +77,6 @@ Pass::Pass(StringHash type) :
     shadersLoadedFrameNumber_(0),
     depthWrite_(true),
     alphaMask_(false),
-    isSM3_(false),
     isDesktop_(false)
 {
     // Guess default lighting mode from pass name
@@ -116,11 +115,6 @@ void Pass::SetAlphaMask(bool enable)
     alphaMask_ = enable;
 }
 
-void Pass::SetIsSM3(bool enable)
-{
-    isSM3_ = enable;
-}
-
 void Pass::SetIsDesktop(bool enable)
 {
     isDesktop_ = enable;
@@ -163,13 +157,9 @@ void Pass::MarkShadersLoaded(unsigned frameNumber)
 
 Technique::Technique(Context* context) :
     Resource(context),
-    isSM3_(false),
     isDesktop_(false),
     numPasses_(0)
 {
-    Graphics* graphics = GetSubsystem<Graphics>();
-    sm3Support_ = graphics ? graphics->GetSM3Support() : true;
-    
     #ifdef DESKTOP_GRAPHICS
     desktopSupport_ = true;
     #else
@@ -198,8 +188,6 @@ bool Technique::BeginLoad(Deserializer& source)
         return false;
     
     XMLElement rootElem = xml->GetRoot();
-    if (rootElem.HasAttribute("sm3"))
-        isSM3_ = rootElem.GetBool("sm3");
     if (rootElem.HasAttribute("desktop"))
         isDesktop_ = rootElem.GetBool("desktop");
     
@@ -225,8 +213,6 @@ bool Technique::BeginLoad(Deserializer& source)
             
             Pass* newPass = CreatePass(nameHash);
             
-            if (passElem.HasAttribute("sm3"))
-                newPass->SetIsSM3(passElem.GetBool("sm3"));
             if (passElem.HasAttribute("desktop"))
                 newPass->SetIsDesktop(passElem.GetBool("desktop"));
             
@@ -291,11 +277,6 @@ bool Technique::BeginLoad(Deserializer& source)
     return true;
 }
 
-void Technique::SetIsSM3(bool enable)
-{
-    isSM3_ = enable;
-}
-
 void Technique::SetIsDesktop(bool enable)
 {
     isDesktop_ = enable;

+ 2 - 16
Source/Urho3D/Graphics/Technique.h

@@ -58,8 +58,6 @@ public:
     void SetDepthWrite(bool enable);
     /// Set alpha masking hint. Completely opaque draw calls will be performed before alpha masked.
     void SetAlphaMask(bool enable);
-    /// Set whether requires %Shader %Model 3.
-    void SetIsSM3(bool enable);
     /// Set whether requires desktop level hardware.
     void SetIsDesktop(bool enable);
     /// Set vertex shader name.
@@ -89,8 +87,6 @@ public:
     bool GetDepthWrite() const { return depthWrite_; }
     /// Return alpha masking hint.
     bool GetAlphaMask() const { return alphaMask_; }
-    /// Return whether requires %Shader %Model 3.
-    bool IsSM3() const { return isSM3_; }
     /// Return whether requires desktop level hardware.
     bool IsDesktop() const { return isDesktop_; }
     /// Return vertex shader name.
@@ -121,8 +117,6 @@ private:
     bool depthWrite_;
     /// Alpha masking hint.
     bool alphaMask_;
-    /// Require %Shader %Model 3 flag.
-    bool isSM3_;
     /// Require desktop level hardware flag.
     bool isDesktop_;
     /// Vertex shader name.
@@ -157,8 +151,6 @@ public:
     /// Load resource from stream. May be called from a worker thread. Return true if successful.
     virtual bool BeginLoad(Deserializer& source);
     
-    /// Set whether requires %Shader %Model 3.
-    void SetIsSM3(bool enable);
     /// Set whether requires desktop level hardware.
     void SetIsDesktop(bool enable);
     /// Create a new pass.
@@ -168,12 +160,10 @@ public:
     /// Reset shader pointers in all passes.
     void ReleaseShaders();
     
-    /// Return whether requires %Shader %Model 3.
-    bool IsSM3() const { return isSM3_; }
     /// Return whether requires desktop level hardware.
     bool IsDesktop() const { return isDesktop_; }
     /// Return whether technique is supported by the current hardware.
-    bool IsSupported() const { return (!isSM3_ || sm3Support_) && (!isDesktop_ || desktopSupport_); }
+    bool IsSupported() const { return !isDesktop_ || desktopSupport_; }
     /// Return whether has a pass.
     bool HasPass(StringHash type) const { return  passes_.Find(type.Value()) != 0; }
     
@@ -189,7 +179,7 @@ public:
     {
         SharedPtr<Pass>* passPtr = passes_.Find(type.Value());
         Pass* pass = passPtr ? passPtr->Get() : 0;
-        return pass && (!pass->IsSM3() || sm3Support_) && (!pass->IsDesktop() || desktopSupport_) ? pass : 0;
+        return pass && (!pass->IsDesktop() || desktopSupport_) ? pass : 0;
     }
     
     /// Return number of passes.
@@ -200,10 +190,6 @@ public:
     PODVector<Pass*> GetPasses() const;
 
 private:
-    /// Require %Shader %Model 3 flag.
-    bool isSM3_;
-    /// Cached %Shader %Model 3 support flag.
-    bool sm3Support_;
     /// Require desktop GPU flag.
     bool isDesktop_;
     /// Cached desktop GPU support flag.

+ 20 - 23
Source/Urho3D/Graphics/View.cpp

@@ -557,9 +557,7 @@ void View::Render()
     // Forget parameter sources from the previous view
     graphics_->ClearParameterSources();
     
-    // If stream offset is supported, write all instance transforms to a single large buffer
-    // Else we must lock the instance buffer for each batch group
-    if (renderer_->GetDynamicInstancing() && graphics_->GetStreamOffsetSupport())
+    if (renderer_->GetDynamicInstancing() && graphics_->GetInstancingSupport())
         PrepareInstancingBuffer();
     
     // It is possible, though not recommended, that the same camera is used for multiple main views. Set automatic aspect ratio
@@ -2819,28 +2817,27 @@ void View::PrepareInstancingBuffer()
         totalInstances += i->litBatches_.GetNumInstances();
     }
     
-    // If fail to set buffer size, fall back to per-group locking
-    if (totalInstances && renderer_->ResizeInstancingBuffer(totalInstances))
-    {
-        VertexBuffer* instancingBuffer = renderer_->GetInstancingBuffer();
-        unsigned freeIndex = 0;
-        void* dest = instancingBuffer->Lock(0, totalInstances, true);
-        if (!dest)
-            return;
-        
-        for (HashMap<StringHash, BatchQueue>::Iterator i = batchQueues_.Begin(); i != batchQueues_.End(); ++i)
-            i->second_.SetTransforms(dest, freeIndex);
-        
-        for (Vector<LightBatchQueue>::Iterator i = lightQueues_.Begin(); i != lightQueues_.End(); ++i)
-        {
-            for (unsigned j = 0; j < i->shadowSplits_.Size(); ++j)
-                i->shadowSplits_[j].shadowBatches_.SetTransforms(dest, freeIndex);
-            i->litBaseBatches_.SetTransforms(dest, freeIndex);
-            i->litBatches_.SetTransforms(dest, freeIndex);
-        }
+    if (!totalInstances || !renderer_->ResizeInstancingBuffer(totalInstances))
+        return;
+
+    VertexBuffer* instancingBuffer = renderer_->GetInstancingBuffer();
+    unsigned freeIndex = 0;
+    void* dest = instancingBuffer->Lock(0, totalInstances, true);
+    if (!dest)
+        return;
+    
+    for (HashMap<StringHash, BatchQueue>::Iterator i = batchQueues_.Begin(); i != batchQueues_.End(); ++i)
+        i->second_.SetTransforms(dest, freeIndex);
         
-        instancingBuffer->Unlock();
+    for (Vector<LightBatchQueue>::Iterator i = lightQueues_.Begin(); i != lightQueues_.End(); ++i)
+    {
+        for (unsigned j = 0; j < i->shadowSplits_.Size(); ++j)
+            i->shadowSplits_[j].shadowBatches_.SetTransforms(dest, freeIndex);
+        i->litBaseBatches_.SetTransforms(dest, freeIndex);
+        i->litBatches_.SetTransforms(dest, freeIndex);
     }
+    
+    instancingBuffer->Unlock();
 }
 
 void View::SetupLightVolumeBatch(Batch& batch)

+ 2 - 4
Source/Urho3D/LuaScript/pkgs/Graphics/Graphics.pkg

@@ -27,6 +27,7 @@ class Graphics : public Object
     bool IsInitialized() const;
     void* GetExternalWindow() const;
     const String GetWindowTitle() const;
+    const String GetApiName() const;
     IntVector2 GetWindowPosition() const;
     int GetWidth() const;
     int GetHeight() const;
@@ -45,13 +46,11 @@ class Graphics : public Object
     unsigned GetDummyColorFormat() const;
     unsigned GetShadowMapFormat() const;
     unsigned GetHiresShadowMapFormat() const;
-    bool GetSM3Support() const;
     bool GetInstancingSupport() const;
     bool GetLightPrepassSupport() const;
     bool GetDeferredSupport() const;
     bool GetHardwareShadowSupport() const;
     bool GetReadableDepthSupport() const;
-    bool GetStreamOffsetSupport() const;
     bool GetSRGBSupport() const;
     bool GetSRGBWriteSupport() const;
     IntVector2 GetDesktopResolution() const;
@@ -76,6 +75,7 @@ class Graphics : public Object
 
     tolua_readonly tolua_property__is_set bool initialized;
     tolua_property__get_set String windowTitle;
+    tolua_readonly tolua_property__get_set String apiName;
     tolua_property__get_set IntVector2 windowPosition;
     tolua_readonly tolua_property__get_set int width;
     tolua_readonly tolua_property__get_set int height;
@@ -94,13 +94,11 @@ class Graphics : public Object
     tolua_readonly tolua_property__get_set unsigned dummyColorFormat;
     tolua_readonly tolua_property__get_set unsigned shadowMapFormat;
     tolua_readonly tolua_property__get_set unsigned hiresShadowMapFormat;
-    tolua_readonly tolua_property__get_set bool SM3Support;
     tolua_readonly tolua_property__get_set bool instancingSupport;
     tolua_readonly tolua_property__get_set bool lightPrepassSupport;
     tolua_readonly tolua_property__get_set bool deferredSupport;
     tolua_readonly tolua_property__get_set bool hardwareShadowSupport;
     tolua_readonly tolua_property__get_set bool readableDepthSupport;
-    tolua_readonly tolua_property__get_set bool streamOffsetSupport;
     tolua_readonly tolua_property__get_set bool sRGBSupport;
     tolua_readonly tolua_property__get_set bool sRGBWriteSupport;
     tolua_readonly tolua_property__get_set IntVector2 desktopResolution;

+ 0 - 4
Source/Urho3D/LuaScript/pkgs/Graphics/Technique.pkg

@@ -9,12 +9,10 @@ enum PassLightingMode
 
 class Pass : public RefCounted
 {
-    bool IsSM3() const;
     bool IsDesktop() const;
     const String GetVertexShader() const;
     const String GetPixelShader() const;
 
-    tolua_readonly tolua_property__is_set bool SM3;
     tolua_readonly tolua_property__is_set bool desktop;
     tolua_readonly tolua_property__get_set const String vertexShader;
     tolua_readonly tolua_property__get_set const String pixelShader;
@@ -26,14 +24,12 @@ class Technique : public Resource
     Pass* GetPass(const StringHash type) const;
     Pass* GetSupportedPass(const StringHash type) const;
     bool IsSupported() const;
-    bool IsSM3() const;
     bool IsDesktop() const;
     unsigned GetNumPasses() const;
     tolua_outside const Vector<StringHash>& TechniqueGetPassTypes @ GetPassTypes() const;
     tolua_outside const PODVector<Pass*>& TechniqueGetPasses @ GetPasses() const;
 
     tolua_readonly tolua_property__is_set bool supported;
-    tolua_readonly tolua_property__is_set bool SM3;
     tolua_readonly tolua_property__is_set bool desktop;
     tolua_readonly tolua_property__get_set unsigned numPasses;
 };

+ 1 - 7
Source/Urho3D/Script/GraphicsAPI.cpp

@@ -622,8 +622,6 @@ static void RegisterMaterial(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Pass", "bool get_depthWrite() const", asMETHOD(Pass, GetDepthWrite), asCALL_THISCALL);
     engine->RegisterObjectMethod("Pass", "void set_alphaMask(bool)", asMETHOD(Pass, SetAlphaMask), asCALL_THISCALL);
     engine->RegisterObjectMethod("Pass", "bool get_alphaMask() const", asMETHOD(Pass, GetAlphaMask), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Pass", "void set_sm3(bool)", asMETHOD(Technique, SetIsSM3), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Pass", "bool get_sm3() const", asMETHOD(Technique, IsSM3), asCALL_THISCALL);
     engine->RegisterObjectMethod("Pass", "void set_desktop(bool)", asMETHOD(Technique, SetIsDesktop), asCALL_THISCALL);
     engine->RegisterObjectMethod("Pass", "bool get_desktop() const", asMETHOD(Technique, IsDesktop), asCALL_THISCALL);
     engine->RegisterObjectMethod("Pass", "void set_vertexShader(const String&in)", asMETHOD(Pass, SetVertexShader), asCALL_THISCALL);
@@ -642,8 +640,6 @@ static void RegisterMaterial(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Technique", "Pass@+ GetPass(StringHash)", asMETHOD(Technique, GetPass), asCALL_THISCALL);
     engine->RegisterObjectMethod("Technique", "Pass@+ GetSupportedPass(StringHash)", asMETHOD(Technique, GetSupportedPass), asCALL_THISCALL);
     engine->RegisterObjectMethod("Technique", "bool get_supported() const", asMETHOD(Technique, IsSupported), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Technique", "void set_sm3(bool)", asMETHOD(Technique, SetIsSM3), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Technique", "bool get_sm3() const", asMETHOD(Technique, IsSM3), asCALL_THISCALL);
     engine->RegisterObjectMethod("Technique", "void set_desktop(bool)", asMETHOD(Technique, SetIsDesktop), asCALL_THISCALL);
     engine->RegisterObjectMethod("Technique", "bool get_desktop() const", asMETHOD(Technique, IsDesktop), asCALL_THISCALL);
     engine->RegisterObjectMethod("Technique", "uint get_numPasses() const", asMETHOD(Technique, GetNumPasses), asCALL_THISCALL);
@@ -1357,6 +1353,7 @@ static void RegisterGraphics(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Graphics", "void PrecacheShaders(VectorBuffer&)", asFUNCTION(GraphicsPrecacheShadersVectorBuffer), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("Graphics", "void set_windowTitle(const String&in)", asMETHOD(Graphics, SetWindowTitle), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "const String& get_windowTitle() const", asMETHOD(Graphics, GetWindowTitle), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Graphics", "const String& get_apiName() const", asMETHOD(Graphics, GetApiName), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "void set_windowIcon(Image@+)", asMETHOD(Graphics, SetWindowIcon), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "void set_windowPosition(const IntVector2&in)", asMETHODPR(Graphics, SetWindowPosition, (const IntVector2&), void), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "IntVector2 get_windowPosition() const", asMETHOD(Graphics, GetWindowPosition), asCALL_THISCALL);
@@ -1378,7 +1375,6 @@ static void RegisterGraphics(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Graphics", "bool get_deviceLost() const", asMETHOD(Graphics, IsDeviceLost), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "uint get_numPrimitives() const", asMETHOD(Graphics, GetNumPrimitives), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "uint get_numBatches() const", asMETHOD(Graphics, GetNumBatches), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Graphics", "bool get_sm3Support() const", asMETHOD(Graphics, GetSM3Support), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "bool get_instancingSupport() const", asMETHOD(Graphics, GetInstancingSupport), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "bool get_lightPrepassSupport() const", asMETHOD(Graphics, GetLightPrepassSupport), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "bool get_deferredSupport() const", asMETHOD(Graphics, GetDeferredSupport), asCALL_THISCALL);
@@ -1386,8 +1382,6 @@ static void RegisterGraphics(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Graphics", "bool get_readableDepthSupport() const", asMETHOD(Graphics, GetReadableDepthSupport), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "bool get_sRGBSupport() const", asMETHOD(Graphics, GetSRGBSupport), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "bool get_sRGBWriteSupport() const", asMETHOD(Graphics, GetSRGBWriteSupport), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Graphics", "void set_forceSM2(bool)", asMETHOD(Graphics, SetForceSM2), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Graphics", "bool get_forceSM2() const", asMETHOD(Graphics, GetForceSM2), asCALL_THISCALL);
     engine->RegisterObjectMethod("Graphics", "Array<IntVector2>@ get_resolutions() const", asFUNCTION(GraphicsGetResolutions), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("Graphics", "Array<int>@ get_multiSampleLevels() const", asFUNCTION(GraphicsGetMultiSampleLevels), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("Graphics", "IntVector2 get_desktopResolution() const", asMETHOD(Graphics, GetDesktopResolution), asCALL_THISCALL);

+ 19 - 47
bin/CoreData/Shaders/HLSL/Lighting.hlsl

@@ -65,11 +65,7 @@ float GetVertexLightVolumetric(int index, float3 worldPos)
 #ifdef SHADOW
 
 #ifdef DIRLIGHT
-    #ifdef SM3
-        #define NUMCASCADES 4
-    #else
-        #define NUMCASCADES 3
-    #endif
+    #define NUMCASCADES 4
 #else
     #define NUMCASCADES 1
 #endif
@@ -81,9 +77,7 @@ void GetShadowPos(float4 projWorldPos, out float4 shadowPos[NUMCASCADES])
         shadowPos[0] = mul(projWorldPos, cLightMatrices[0]);
         shadowPos[1] = mul(projWorldPos, cLightMatrices[1]);
         shadowPos[2] = mul(projWorldPos, cLightMatrices[2]);
-        #ifdef SM3
-            shadowPos[3] = mul(projWorldPos, cLightMatrices[3]);
-        #endif
+        shadowPos[3] = mul(projWorldPos, cLightMatrices[3]);
     #elif defined(SPOTLIGHT)
         shadowPos[0] = mul(projWorldPos, cLightMatrices[1]);
     #else
@@ -132,11 +126,7 @@ float GetIntensity(float3 color)
 #ifdef SHADOW
 
 #ifdef DIRLIGHT
-    #ifdef SM3
-        #define NUMCASCADES 4
-    #else
-        #define NUMCASCADES 3
-    #endif
+    #define NUMCASCADES 4
 #else
     #define NUMCASCADES 1
 #endif
@@ -213,23 +203,14 @@ float GetDirShadow(const float4 iShadowPos[NUMCASCADES], float depth)
 {
     float4 shadowPos;
 
-    #ifdef SM3
-        if (depth < cShadowSplits.x)
-            shadowPos = iShadowPos[0];
-        else if (depth < cShadowSplits.y)
-            shadowPos = iShadowPos[1];
-        else if (depth < cShadowSplits.z)
-            shadowPos = iShadowPos[2];
-        else
-            shadowPos = iShadowPos[3];
-    #else
-        if (depth < cShadowSplits.x)
-            shadowPos = iShadowPos[0];
-        else if (depth < cShadowSplits.y)
-            shadowPos = iShadowPos[1];
-        else
-            shadowPos = iShadowPos[2];
-    #endif
+    if (depth < cShadowSplits.x)
+        shadowPos = iShadowPos[0];
+    else if (depth < cShadowSplits.y)
+        shadowPos = iShadowPos[1];
+    else if (depth < cShadowSplits.z)
+        shadowPos = iShadowPos[2];
+    else
+        shadowPos = iShadowPos[3];
 
     return GetDirShadowFade(GetShadow(shadowPos), depth);
 }
@@ -238,23 +219,14 @@ float GetDirShadowDeferred(float4 projWorldPos, float depth)
 {
     float4 shadowPos;
 
-    #ifdef SM3
-        if (depth < cShadowSplits.x)
-            shadowPos = mul(projWorldPos, cLightMatricesPS[0]);
-        else if (depth < cShadowSplits.y)
-            shadowPos = mul(projWorldPos, cLightMatricesPS[1]);
-        else if (depth < cShadowSplits.z)
-            shadowPos = mul(projWorldPos, cLightMatricesPS[2]);
-        else
-            shadowPos = mul(projWorldPos, cLightMatricesPS[3]);
-    #else
-        if (depth < cShadowSplits.x)
-            shadowPos = mul(projWorldPos, cLightMatricesPS[0]);
-        else if (depth < cShadowSplits.y)
-            shadowPos = mul(projWorldPos, cLightMatricesPS[1]);
-        else if (depth < cShadowSplits.z)
-            shadowPos = mul(projWorldPos, cLightMatricesPS[2]);
-    #endif
+    if (depth < cShadowSplits.x)
+        shadowPos = mul(projWorldPos, cLightMatricesPS[0]);
+    else if (depth < cShadowSplits.y)
+        shadowPos = mul(projWorldPos, cLightMatricesPS[1]);
+    else if (depth < cShadowSplits.z)
+        shadowPos = mul(projWorldPos, cLightMatricesPS[2]);
+    else
+        shadowPos = mul(projWorldPos, cLightMatricesPS[3]);
 
     return GetDirShadowFade(GetShadow(shadowPos), depth);
 }

+ 1 - 11
bin/CoreData/Shaders/HLSL/LitSolid.hlsl

@@ -5,11 +5,6 @@
 #include "Lighting.hlsl"
 #include "Fog.hlsl"
 
-// When rendering a shadowed point light, disable specular calculations on Shader Model 2 to avoid exceeding the instruction limit
-#if !defined(SM3) && defined(SHADOW) && defined(POINTLIGHT)
-    #undef SPECULAR
-#endif
-
 void VS(float4 iPos : POSITION,
     float3 iNormal : NORMAL,
     float2 iTexCoord : TEXCOORD0,
@@ -176,12 +171,7 @@ void PS(
     // Get normal
     #ifdef NORMALMAP
         float3x3 tbn = float3x3(iTangent.xyz, float3(iTexCoord.zw, iTangent.w), iNormal);
-        // We may be running low on instructions on Shader Model 2, so skip normalize if necessary
-        #if defined(SM3) || !defined(SHADOW) || !defined(SPECULAR)
-            float3 normal = normalize(mul(DecodeNormal(tex2D(sNormalMap, iTexCoord.xy)), tbn));
-        #else
-            float3 normal = mul(DecodeNormal(tex2D(sNormalMap, iTexCoord.xy)), tbn);
-        #endif
+        float3 normal = normalize(mul(DecodeNormal(tex2D(sNormalMap, iTexCoord.xy)), tbn));
     #else
         float3 normal = normalize(iNormal);
     #endif

+ 2 - 11
bin/CoreData/Shaders/HLSL/Samplers.hlsl

@@ -22,12 +22,7 @@ sampler3D sZoneVolumeMap : register(S15);
 
 float4 Sample(sampler2D map, float2 texCoord)
 {
-    // Use tex2Dlod if available to avoid divergence and allow branching
-    #ifdef SM3
-        return tex2Dlod(map, float4(texCoord, 0.0, 0.0));
-    #else
-        return tex2D(map, texCoord);
-    #endif
+    return tex2Dlod(map, float4(texCoord, 0.0, 0.0));
 }
 
 float3 DecodeNormal(float4 normalInput)
@@ -35,11 +30,7 @@ float3 DecodeNormal(float4 normalInput)
     #ifdef PACKEDNORMAL
         float3 normal;
         normal.xy = normalInput.ag * 2.0 - 1.0;
-        #ifdef SM3
-            normal.z = sqrt(max(1.0 - dot(normal.xy, normal.xy), 0.0));
-        #else
-            normal.z = sqrt(1.0 - dot(normal.xy, normal.xy));
-        #endif
+        normal.z = sqrt(max(1.0 - dot(normal.xy, normal.xy), 0.0));
         return normal;
     #else
         return normalInput.rgb * 2.0 - 1.0;

+ 0 - 5
bin/CoreData/Shaders/HLSL/TerrainBlend.hlsl

@@ -5,11 +5,6 @@
 #include "Lighting.hlsl"
 #include "Fog.hlsl"
 
-// When rendering a shadowed point light, disable specular calculations on Shader Model 2 to avoid exceeding the instruction limit
-#if !defined(SM3) && defined(SHADOW) && defined(POINTLIGHT)
-    #undef SPECULAR
-#endif
-
 sampler2D sWeightMap0 : register(S0);
 sampler2D sDetailMap1 : register(S1);
 sampler2D sDetailMap2 : register(S2);

+ 1 - 5
bin/CoreData/Shaders/HLSL/Uniforms.hlsl

@@ -52,9 +52,5 @@ uniform float4 cShadowDepthFade;
 uniform float2 cShadowIntensity;
 uniform float2 cShadowMapInvSize;
 uniform float4 cShadowSplits;
-#ifdef SM3
-    uniform float4x4 cLightMatricesPS[4];
-#else
-    uniform float4x4 cLightMatricesPS[3];
-#endif
+uniform float4x4 cLightMatricesPS[4];
 #endif

+ 1 - 1
bin/CoreData/Techniques/DiffNormal.xml

@@ -1,6 +1,6 @@
 <technique vs="LitSolid" ps="LitSolid" psdefines="DIFFMAP">
     <pass name="base" />
-    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP" sm3="true" />
+    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP" />
     <pass name="light" vsdefines="NORMALMAP" psdefines="NORMALMAP" depthtest="equal" depthwrite="false" blend="add" />
     <pass name="prepass" vsdefines="NORMALMAP" psdefines="PREPASS NORMALMAP" />
     <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />

+ 1 - 1
bin/CoreData/Techniques/DiffNormalAlphaMask.xml

@@ -1,6 +1,6 @@
 <technique vs="LitSolid" ps="LitSolid" psdefines="DIFFMAP ALPHAMASK" alphamask="true">
     <pass name="base" />
-    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP" sm3="true" />
+    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP" />
     <pass name="light" vsdefines="NORMALMAP" psdefines="NORMALMAP" depthtest="equal" depthwrite="false" blend="add" />
     <pass name="prepass" vsdefines="NORMALMAP" psdefines="PREPASS NORMALMAP" />
     <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />

+ 1 - 1
bin/CoreData/Techniques/DiffNormalPacked.xml

@@ -1,6 +1,6 @@
 <technique vs="LitSolid" ps="LitSolid" psdefines="DIFFMAP">
     <pass name="base" />
-    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP PACKEDNORMAL" sm3="true" />
+    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP PACKEDNORMAL" />
     <pass name="light" vsdefines="NORMALMAP" psdefines="NORMALMAP PACKEDNORMAL" depthtest="equal" depthwrite="false" blend="add" />
     <pass name="prepass" vsdefines="NORMALMAP" psdefines="PREPASS NORMALMAP PACKEDNORMAL" />
     <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />

+ 1 - 1
bin/CoreData/Techniques/DiffNormalPackedAlphaMask.xml

@@ -1,6 +1,6 @@
 <technique vs="LitSolid" ps="LitSolid" psdefines="DIFFMAP ALPHAMASK" alphamask="true">
     <pass name="base" />
-    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP PACKEDNORMAL" sm3="true" />
+    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP PACKEDNORMAL" />
     <pass name="light" vsdefines="NORMALMAP" psdefines="NORMALMAP PACKEDNORMAL" depthtest="equal" depthwrite="false" blend="add" />
     <pass name="prepass" vsdefines="NORMALMAP" psdefines="PREPASS NORMALMAP PACKEDNORMAL" />
     <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />

+ 1 - 1
bin/CoreData/Techniques/DiffNormalPackedSpec.xml

@@ -1,6 +1,6 @@
 <technique vs="LitSolid" ps="LitSolid" psdefines="DIFFMAP">
     <pass name="base" />
-    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP PACKEDNORMAL SPECMAP" sm3="true" />
+    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP PACKEDNORMAL SPECMAP" />
     <pass name="light" vsdefines="NORMALMAP" psdefines="NORMALMAP PACKEDNORMAL SPECMAP" depthtest="equal" depthwrite="false" blend="add" />
     <pass name="prepass" vsdefines="NORMALMAP" psdefines="PREPASS NORMALMAP PACKEDNORMAL SPECMAP" />
     <pass name="material" psdefines="MATERIAL SPECMAP" depthtest="equal" depthwrite="false" />

+ 1 - 1
bin/CoreData/Techniques/DiffNormalPackedSpecAlphaMask.xml

@@ -1,6 +1,6 @@
 <technique vs="LitSolid" ps="LitSolid" psdefines="DIFFMAP ALPHAMASK" alphamask="true">
     <pass name="base" />
-    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP PACKEDNORMAL SPECMAP" sm3="true" />
+    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP PACKEDNORMAL SPECMAP" />
     <pass name="light" vsdefines="NORMALMAP" psdefines="NORMALMAP PACKEDNORMAL SPECMAP" depthtest="equal" depthwrite="false" blend="add" />
     <pass name="prepass" vsdefines="NORMALMAP" psdefines="PREPASS NORMALMAP PACKEDNORMAL SPECMAP" />
     <pass name="material" psdefines="MATERIAL SPECMAP" depthtest="equal" depthwrite="false" />

+ 1 - 1
bin/CoreData/Techniques/DiffNormalSpec.xml

@@ -1,6 +1,6 @@
 <technique vs="LitSolid" ps="LitSolid" psdefines="DIFFMAP">
     <pass name="base" />
-    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP SPECMAP" sm3="true" />
+    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP SPECMAP" />
     <pass name="light" vsdefines="NORMALMAP" psdefines="NORMALMAP SPECMAP" depthtest="equal" depthwrite="false" blend="add" />
     <pass name="prepass" vsdefines="NORMALMAP" psdefines="PREPASS NORMALMAP SPECMAP" />
     <pass name="material" psdefines="MATERIAL SPECMAP" depthtest="equal" depthwrite="false" />

+ 1 - 1
bin/CoreData/Techniques/DiffNormalSpecAlphaMask.xml

@@ -1,6 +1,6 @@
 <technique vs="LitSolid" ps="LitSolid" psdefines="DIFFMAP ALPHAMASK" alphamask="true">
     <pass name="base" />
-    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP SPECMAP" sm3="true" />
+    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP SPECMAP" />
     <pass name="light" vsdefines="NORMALMAP" psdefines="NORMALMAP SPECMAP" depthtest="equal" depthwrite="false" blend="add" />
     <pass name="prepass" vsdefines="NORMALMAP" psdefines="PREPASS NORMALMAP SPECMAP" />
     <pass name="material" psdefines="MATERIAL SPECMAP" depthtest="equal" depthwrite="false" />

+ 1 - 1
bin/CoreData/Techniques/NoTextureNormal.xml

@@ -1,6 +1,6 @@
 <technique vs="LitSolid" ps="LitSolid">
     <pass name="base" />
-    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP" sm3="true" />
+    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP" />
     <pass name="light" vsdefines="NORMALMAP" psdefines="NORMALMAP" depthtest="equal" depthwrite="false" blend="add" />
     <pass name="prepass" vsdefines="NORMALMAP" psdefines="PREPASS NORMALMAP" />
     <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />

+ 1 - 1
bin/CoreData/Techniques/NoTextureNormalPacked.xml

@@ -1,6 +1,6 @@
 <technique vs="LitSolid" ps="LitSolid">
     <pass name="base" />
-    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP PACKEDNORMAL" sm3="true" />
+    <pass name="litbase" vsdefines="NORMALMAP" psdefines="AMBIENT NORMALMAP PACKEDNORMAL" />
     <pass name="light" vsdefines="NORMALMAP" psdefines="NORMALMAP PACKEDNORMAL" depthtest="equal" depthwrite="false" blend="add" />
     <pass name="prepass" vsdefines="NORMALMAP" psdefines="PREPASS NORMALMAP PACKEDNORMAL" />
     <pass name="material" psdefines="MATERIAL" depthtest="equal" depthwrite="false" />