1. /*
  2.  
  3. This source file is part of OGRE
  4. (Object-oriented Graphics Rendering Engine)
  5. For the latest info, see http://www.ogre3d.org/
  6.  
  7. Copyright (c) 2000-2011 Torus Knot Software Ltd
  8.  
  9. Permission is hereby granted, free of charge, to any person obtaining a copy
  10. of this software and associated documentation files (the "Software"), to deal
  11. in the Software without restriction, including without limitation the rights
  12. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. copies of the Software, and to permit persons to whom the Software is
  14. furnished to do so, subject to the following conditions:
  15.  
  16. The above copyright notice and this permission notice shall be included in
  17. all copies or substantial portions of the Software.
  18.  
  19. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. THE SOFTWARE.
  26.  
  27. */
  28. #include "OgreD3D11RenderSystem.h"
  29. #include "OgreD3D11Prerequisites.h"
  30. #include "OgreD3D11DriverList.h"
  31. #include "OgreD3D11Driver.h"
  32. #include "OgreD3D11VideoModeList.h"
  33. #include "OgreD3D11VideoMode.h"
  34. #include "OgreD3D11RenderWindow.h"
  35. #include "OgreD3D11TextureManager.h"
  36. #include "OgreD3D11Texture.h"
  37. #include "OgreLogManager.h"
  38. #include "OgreD3D11HardwareBufferManager.h"
  39. #include "OgreD3D11HardwareIndexBuffer.h"
  40. #include "OgreD3D11HardwareVertexBuffer.h"
  41. #include "OgreD3D11VertexDeclaration.h"
  42. #include "OgreD3D11GpuProgram.h"
  43. #include "OgreD3D11GpuProgramManager.h"
  44. #include "OgreD3D11HLSLProgramFactory.h"
  45.  
  46. #include "OgreD3D11HardwareOcclusionQuery.h"
  47. #include "OgreFrustum.h"
  48. #include "OgreD3D11MultiRenderTarget.h"
  49. #include "OgreD3D11HLSLProgram.h"
  50. #include "OgreD3D11VertexDeclaration.h"
  51.  
  52. #include "OgreD3D11DepthBuffer.h"
  53. #include "OgreD3D11HardwarePixelBuffer.h"
  54. #include "OgreException.h"
  55.  
  56. // DXGetErrorDescription
  57. #include "DXErr.h"
  58.  
  59. //---------------------------------------------------------------------
  60. #define FLOAT2DWORD(f) *((DWORD*)&f)
  61. //---------------------------------------------------------------------
  62.  
  63. namespace Ogre
  64. {
  65.  
  66.     //---------------------------------------------------------------------
  67.     D3D11RenderSystem::D3D11RenderSystem( HINSTANCE hInstance ) : mDevice(NULL)
  68.     {
  69.         LogManager::getSingleton().logMessage( "D3D11 : " + getName() + " created." );
  70.  
  71. #ifdef RTSHADER_SYSTEM_BUILD_CORE_SHADERS
  72.         mEnableFixedPipeline = false;
  73. #endif
  74.  
  75.         // set the instance being passed
  76.         mhInstance = hInstance;
  77.  
  78.         mRenderSystemWasInited = false;
  79.         initRenderSystem();
  80.  
  81.         // set config options defaults
  82.         initConfigOptions();
  83.  
  84.  
  85.  
  86.     }
  87.     //---------------------------------------------------------------------
  88.     D3D11RenderSystem::~D3D11RenderSystem()
  89.     {
  90.         shutdown();
  91.  
  92.         // Deleting the HLSL program factory
  93.         if (mHLSLProgramFactory)
  94.         {
  95.             // Remove from manager safely
  96.             if (HighLevelGpuProgramManager::getSingletonPtr())
  97.                 HighLevelGpuProgramManager::getSingleton().removeFactory(mHLSLProgramFactory);
  98.             delete mHLSLProgramFactory;
  99.             mHLSLProgramFactory = 0;
  100.         }
  101.  
  102.         //SAFE_RELEASE( mpD3D );
  103.  
  104.         LogManager::getSingleton().logMessage( "D3D11 : " + getName() + " destroyed." );
  105.     }
  106.     //---------------------------------------------------------------------
  107.     const String& D3D11RenderSystem::getName() const
  108.     {
  109.         static String strName( "Direct3D11 Rendering Subsystem");
  110.         return strName;
  111.     }
  112.     //---------------------------------------------------------------------
  113.     D3D11DriverList* D3D11RenderSystem::getDirect3DDrivers()
  114.     {
  115.         if( !mDriverList )
  116.             mDriverList = new D3D11DriverList( mpDXGIFactory );
  117.  
  118.         return mDriverList;
  119.     }
  120.     //---------------------------------------------------------------------
  121.     bool D3D11RenderSystem::_checkMultiSampleQuality(UINT SampleCount, UINT *outQuality, DXGI_FORMAT format)
  122.     {
  123.         // TODO: check if we need this function
  124.         HRESULT hr;
  125.         hr = mDevice->CheckMultisampleQualityLevels(
  126.                 format,
  127.             SampleCount,
  128.             outQuality);
  129.  
  130.         if (SUCCEEDED(hr))
  131.             return true;
  132.         else
  133.             return false;
  134.     }
  135.     //---------------------------------------------------------------------
  136.     void D3D11RenderSystem::initConfigOptions()
  137.     {
  138.         D3D11DriverList* driverList;
  139.         D3D11Driver* driver;
  140.  
  141.         ConfigOption optDevice;
  142.         ConfigOption optVideoMode;
  143.         ConfigOption optFullScreen;
  144.         ConfigOption optVSync;
  145.         ConfigOption optVSyncInterval;
  146.         ConfigOption optAA;
  147.         ConfigOption optFPUMode;
  148.         ConfigOption optNVPerfHUD;
  149.         ConfigOption optSRGB;
  150.         ConfigOption optExceptionsErrorLevel;
  151.         ConfigOption optDriverType;
  152.  
  153.  
  154.  
  155.         driverList = this->getDirect3DDrivers();
  156.  
  157.         optDevice.name = "Rendering Device";
  158.         optDevice.currentValue.clear();
  159.         optDevice.possibleValues.clear();
  160.         optDevice.immutable = false;
  161.  
  162.         optVideoMode.name = "Video Mode";
  163.         optVideoMode.currentValue = "800 x 600 @ 32-bit colour";
  164.         optVideoMode.immutable = false;
  165.  
  166.         optFullScreen.name = "Full Screen";
  167.         optFullScreen.possibleValues.push_back( "Yes" );
  168.         optFullScreen.possibleValues.push_back( "No" );
  169.         optFullScreen.currentValue = "Yes";
  170.         optFullScreen.immutable = false;
  171.  
  172.         for( unsigned j=0; j < driverList->count(); j++ )
  173.         {
  174.             driver = driverList->item(j);
  175.             optDevice.possibleValues.push_back( driver->DriverDescription() );
  176.             // Make first one default
  177.             if( j==0 )
  178.                 optDevice.currentValue = driver->DriverDescription();
  179.         }
  180.  
  181.         optVSync.name = "VSync";
  182.         optVSync.immutable = false;
  183.         optVSync.possibleValues.push_back( "Yes" );
  184.         optVSync.possibleValues.push_back( "No" );
  185.         optVSync.currentValue = "No";
  186.  
  187.         optVSyncInterval.name = "VSync Interval";
  188.         optVSyncInterval.immutable = false;
  189.         optVSyncInterval.possibleValues.push_back( "1" );
  190.         optVSyncInterval.possibleValues.push_back( "2" );
  191.         optVSyncInterval.possibleValues.push_back( "3" );
  192.         optVSyncInterval.possibleValues.push_back( "4" );
  193.         optVSyncInterval.currentValue = "1";
  194.  
  195.         optAA.name = "FSAA";
  196.         optAA.immutable = false;
  197.         optAA.possibleValues.push_back( "None" );
  198.         optAA.currentValue = "None";
  199.  
  200.         optFPUMode.name = "Floating-point mode";
  201. #if OGRE_DOUBLE_PRECISION
  202.         optFPUMode.currentValue = "Consistent";
  203. #else
  204.         optFPUMode.currentValue = "Fastest";
  205. #endif
  206.         optFPUMode.possibleValues.clear();
  207.         optFPUMode.possibleValues.push_back("Fastest");
  208.         optFPUMode.possibleValues.push_back("Consistent");
  209.         optFPUMode.immutable = false;
  210.  
  211.         optNVPerfHUD.currentValue = "No";
  212.         optNVPerfHUD.immutable = false;
  213.         optNVPerfHUD.name = "Allow NVPerfHUD";
  214.         optNVPerfHUD.possibleValues.push_back( "Yes" );
  215.         optNVPerfHUD.possibleValues.push_back( "No" );
  216.  
  217.         // SRGB on auto window
  218.         optSRGB.name = "sRGB Gamma Conversion";
  219.         optSRGB.possibleValues.push_back("Yes");
  220.         optSRGB.possibleValues.push_back("No");
  221.         optSRGB.currentValue = "No";
  222.         optSRGB.immutable = false;     
  223.  
  224.  
  225.         // Exceptions Error Level
  226.         optExceptionsErrorLevel.name = "Information Queue Exceptions Bottom Level";
  227.         optExceptionsErrorLevel.possibleValues.push_back("No information queue exceptions");
  228.         optExceptionsErrorLevel.possibleValues.push_back("Corruption");
  229.         optExceptionsErrorLevel.possibleValues.push_back("Error");
  230.         optExceptionsErrorLevel.possibleValues.push_back("Warning");
  231.         optExceptionsErrorLevel.possibleValues.push_back("Info (exception on any message)");
  232. #ifdef OGRE_DEBUG_MODE
  233.         optExceptionsErrorLevel.currentValue = "Info (exception on any message)";
  234. #else
  235.         optExceptionsErrorLevel.currentValue = "No information queue exceptions";
  236. #endif
  237.         optExceptionsErrorLevel.immutable = false;
  238.        
  239.  
  240.         // Driver type
  241.         optDriverType.name = "Driver type";
  242.         optDriverType.possibleValues.push_back("Hardware");
  243.         optDriverType.possibleValues.push_back("Software");
  244.         optDriverType.possibleValues.push_back("Warp");
  245.         optDriverType.currentValue = "Hardware";
  246.         optDriverType.immutable = false;
  247.  
  248.  
  249.         mOptions[optDevice.name] = optDevice;
  250.         mOptions[optVideoMode.name] = optVideoMode;
  251.         mOptions[optFullScreen.name] = optFullScreen;
  252.         mOptions[optVSync.name] = optVSync;
  253.         mOptions[optVSyncInterval.name] = optVSyncInterval;
  254.         mOptions[optAA.name] = optAA;
  255.         mOptions[optFPUMode.name] = optFPUMode;
  256.         mOptions[optNVPerfHUD.name] = optNVPerfHUD;
  257.         mOptions[optSRGB.name] = optSRGB;
  258.         mOptions[optExceptionsErrorLevel.name] = optExceptionsErrorLevel;
  259.         mOptions[optDriverType.name] = optDriverType;
  260.        
  261.         refreshD3DSettings();
  262.  
  263.     }
  264.     //---------------------------------------------------------------------
  265.     void D3D11RenderSystem::refreshD3DSettings()
  266.     {
  267.         ConfigOption* optVideoMode;
  268.         D3D11Driver* driver = 0;
  269.         D3D11VideoMode* videoMode;
  270.  
  271.         ConfigOptionMap::iterator opt = mOptions.find( "Rendering Device" );
  272.         if( opt != mOptions.end() )
  273.         {
  274.             for( unsigned j=0; j < getDirect3DDrivers()->count(); j++ )
  275.             {
  276.                 driver = getDirect3DDrivers()->item(j);
  277.                 if( driver->DriverDescription() == opt->second.currentValue )
  278.                     break;
  279.             }
  280.  
  281.             if (driver)
  282.             {
  283.                 opt = mOptions.find( "Video Mode" );
  284.                 optVideoMode = &opt->second;
  285.                 optVideoMode->possibleValues.clear();
  286.                 // get vide modes for this device
  287.                 for( unsigned k=0; k < driver->getVideoModeList()->count(); k++ )
  288.                 {
  289.                     videoMode = driver->getVideoModeList()->item( k );
  290.                     optVideoMode->possibleValues.push_back( videoMode->getDescription() );
  291.                 }
  292.  
  293.                 // Reset video mode to default if previous doesn't avail in new possible values
  294.                 StringVector::const_iterator itValue =
  295.                     std::find(optVideoMode->possibleValues.begin(),
  296.                               optVideoMode->possibleValues.end(),
  297.                               optVideoMode->currentValue);
  298.                 if (itValue == optVideoMode->possibleValues.end())
  299.                 {
  300.                     optVideoMode->currentValue = "800 x 600 @ 32-bit colour";
  301.                 }
  302.  
  303.                 // Also refresh FSAA options
  304.                 refreshFSAAOptions();
  305.             }
  306.         }
  307.  
  308.     }
  309.     //---------------------------------------------------------------------
  310.     void D3D11RenderSystem::setConfigOption( const String &name, const String &value )
  311.     {
  312.         initRenderSystem();
  313.  
  314.         LogManager::getSingleton().stream()
  315.             << "D3D11 : RenderSystem Option: " << name << " = " << value;
  316.  
  317.         bool viewModeChanged = false;
  318.  
  319.         // Find option
  320.         ConfigOptionMap::iterator it = mOptions.find( name );
  321.  
  322.         // Update
  323.         if( it != mOptions.end() )
  324.             it->second.currentValue = value;
  325.         else
  326.         {
  327.             StringUtil::StrStreamType str;
  328.             str << "Option named '" << name << "' does not exist.";
  329.             OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, str.str(), "D3D11RenderSystem::setConfigOption" );
  330.         }
  331.  
  332.         // Refresh other options if D3DDriver changed
  333.         if( name == "Rendering Device" )
  334.             refreshD3DSettings();
  335.  
  336.         if( name == "Full Screen" )
  337.         {
  338.             // Video mode is applicable
  339.             it = mOptions.find( "Video Mode" );
  340.             if (it->second.currentValue.empty())
  341.             {
  342.                 it->second.currentValue = "800 x 600 @ 32-bit colour";
  343.                 viewModeChanged = true;
  344.             }
  345.         }
  346.  
  347.  
  348.         if( name == "VSync" )
  349.         {
  350.             if (value == "Yes")
  351.                 mVSync = true;
  352.             else
  353.                 mVSync = false;
  354.         }
  355.  
  356.         if( name == "VSync Interval" )
  357.         {
  358.             mVSyncInterval = StringConverter::parseUnsignedInt(value);
  359.         }
  360.  
  361.         if( name == "Allow NVPerfHUD" )
  362.         {
  363.             if (value == "Yes")
  364.                 mUseNVPerfHUD = true;
  365.             else
  366.                 mUseNVPerfHUD = false;
  367.         }
  368.  
  369.         if (viewModeChanged || name == "Video Mode")
  370.         {
  371.             refreshFSAAOptions();
  372.         }
  373.  
  374.     }
  375.     //---------------------------------------------------------------------
  376.     void D3D11RenderSystem::refreshFSAAOptions(void)
  377.     {
  378.  
  379.         ConfigOptionMap::iterator it = mOptions.find( "FSAA" );
  380.         ConfigOption* optFSAA = &it->second;
  381.         optFSAA->possibleValues.clear();
  382.         optFSAA->possibleValues.push_back("0");
  383.  
  384.         it = mOptions.find("Rendering Device");
  385.         D3D11Driver *driver = getDirect3DDrivers()->item(it->second.currentValue);
  386.         if (driver)
  387.         {
  388.             it = mOptions.find("Video Mode");
  389.             D3D11VideoMode *videoMode = driver->getVideoModeList()->item(it->second.currentValue);
  390.             if (videoMode)
  391.             {
  392.                 UINT numLevels = 0;
  393.                  bool bOK=false;
  394.                 // set maskable levels supported
  395.                 for (unsigned int n = 2; n < 17; n++)
  396.                 {
  397.                     bOK = this->_checkMultiSampleQuality(
  398.                         n,
  399.                         &numLevels,
  400.                         videoMode->getFormat()
  401.                         );
  402.                     if (bOK)
  403.                     {
  404.                         optFSAA->possibleValues.push_back(StringConverter::toString(n));
  405.                         if (n >=8)
  406.                         {
  407.                             optFSAA->possibleValues.push_back(StringConverter::toString(n) + " [Quality]");
  408.                         }
  409.                     }
  410.                 }
  411.             }
  412.         }
  413.  
  414.         // Reset FSAA to none if previous doesn't avail in new possible values
  415.         StringVector::const_iterator itValue =
  416.             std::find(optFSAA->possibleValues.begin(),
  417.                       optFSAA->possibleValues.end(),
  418.                       optFSAA->currentValue);
  419.         if (itValue == optFSAA->possibleValues.end())
  420.         {
  421.             optFSAA->currentValue = "0";
  422.         }
  423.  
  424.     }
  425.     //---------------------------------------------------------------------
  426.     String D3D11RenderSystem::validateConfigOptions()
  427.     {
  428.         ConfigOptionMap::iterator it;
  429.        
  430.         // check if video mode is selected
  431.         it = mOptions.find( "Video Mode" );
  432.         if (it->second.currentValue.empty())
  433.             return "A video mode must be selected.";
  434.  
  435.         it = mOptions.find( "Rendering Device" );
  436.         bool foundDriver = false;
  437.         D3D11DriverList* driverList = getDirect3DDrivers();
  438.         for( ushort j=0; j < driverList->count(); j++ )
  439.         {
  440.             if( driverList->item(j)->DriverDescription() == it->second.currentValue )
  441.             {
  442.                 foundDriver = true;
  443.                 break;
  444.             }
  445.         }
  446.  
  447.         if (!foundDriver)
  448.         {
  449.             // Just pick the first driver
  450.             setConfigOption("Rendering Device", driverList->item(0)->DriverDescription());
  451.             return "Your DirectX driver name has changed since the last time you ran OGRE; "
  452.                 "the 'Rendering Device' has been changed.";
  453.         }
  454.  
  455.         it = mOptions.find( "VSync" );
  456.         if( it->second.currentValue == "Yes" )
  457.             mVSync = true;
  458.         else
  459.             mVSync = false;
  460.  
  461.         return StringUtil::BLANK;
  462.     }
  463.     //---------------------------------------------------------------------
  464.     ConfigOptionMap& D3D11RenderSystem::getConfigOptions()
  465.     {
  466.         // return a COPY of the current config options
  467.         return mOptions;
  468.     }
  469.     //---------------------------------------------------------------------
  470.     RenderWindow* D3D11RenderSystem::_initialise( bool autoCreateWindow, const String& windowTitle )
  471.     {
  472.         RenderWindow* autoWindow = NULL;
  473.         LogManager::getSingleton().logMessage( "D3D11 : Subsystem Initialising" );
  474.  
  475.         // Init using current settings
  476.         mActiveD3DDriver = NULL;
  477.         ConfigOptionMap::iterator opt = mOptions.find( "Rendering Device" );
  478.         for( unsigned j=0; j < getDirect3DDrivers()->count(); j++ )
  479.         {
  480.             if( getDirect3DDrivers()->item(j)->DriverDescription() == opt->second.currentValue )
  481.             {
  482.                 mActiveD3DDriver = getDirect3DDrivers()->item(j);
  483.                 break;
  484.             }
  485.         }
  486.  
  487.         if( !mActiveD3DDriver )
  488.             OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "Problems finding requested Direct3D driver!", "D3D11RenderSystem::initialise" );
  489.  
  490.         //AIZ:recreate the device for the selected adapter
  491.         {
  492.             if (!mDevice.isNull())
  493.             {
  494.                 mDevice.release();
  495.             }
  496.  
  497.        
  498.             opt = mOptions.find( "Information Queue Exceptions Bottom Level" );
  499.             if( opt == mOptions.end() )
  500.                 OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find Information Queue Exceptions Bottom Level option!", "D3D11RenderSystem::initialise" );
  501.             String infoQType = opt->second.currentValue;
  502.  
  503.             if ("No information queue exceptions" == infoQType)
  504.             {
  505.                 D3D11Device::setExceptionsErrorLevel(D3D11Device::D3D_NO_EXCEPTION);
  506.             }
  507.             else if ("Corruption" == infoQType)
  508.             {
  509.                 D3D11Device::setExceptionsErrorLevel(D3D11Device::D3D_CORRUPTION);
  510.             }
  511.             else if ("Error" == infoQType)
  512.             {
  513.                 D3D11Device::setExceptionsErrorLevel(D3D11Device::D3D_ERROR);
  514.             }
  515.             else if ("Warning" == infoQType)
  516.             {
  517.                 D3D11Device::setExceptionsErrorLevel(D3D11Device::D3D_WARNING);
  518.             }
  519.             else if ("Info (exception on any message)" == infoQType)
  520.             {
  521.                 D3D11Device::setExceptionsErrorLevel(D3D11Device::D3D_INFO);
  522.             }
  523.  
  524.  
  525.  
  526.             // Driver type
  527.             opt = mOptions.find( "Driver type" );
  528.             if( opt == mOptions.end() )
  529.                 OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find driver type!", "D3D11RenderSystem::initialise" );
  530.             String driverTypeName = opt->second.currentValue;
  531.  
  532.             mDriverType = DT_HARDWARE;
  533.             if ("Hardware" == driverTypeName)
  534.             {
  535.                  mDriverType = DT_HARDWARE;
  536.             }
  537.             if ("Software" == driverTypeName)
  538.             {
  539.                 mDriverType = DT_SOFTWARE;
  540.             }
  541.             if ("Warp" == driverTypeName)
  542.             {
  543.                 mDriverType = DT_WARP;
  544.             }
  545.  
  546.  
  547.  
  548.             UINT deviceFlags = 0;
  549.             if (D3D11Device::D3D_NO_EXCEPTION != D3D11Device::getExceptionsErrorLevel() && OGRE_DEBUG_MODE)
  550.             {
  551.                 deviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
  552.             }
  553.             if (!OGRE_THREAD_SUPPORT)
  554.             {
  555.                 deviceFlags |= D3D11_CREATE_DEVICE_SINGLETHREADED;
  556.             }
  557.             D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_UNKNOWN ;
  558.  
  559.             // Search for a PerfHUD adapter
  560.             UINT nAdapter = 0;
  561.             IDXGIAdapter1* pAdapter = NULL;
  562.             IDXGIAdapter1* pSelectedAdapter = mActiveD3DDriver->getDeviceAdapter();
  563.             if ( mUseNVPerfHUD )
  564.             {
  565.                 // Search for a PerfHUD adapter
  566.                 while( mpDXGIFactory->EnumAdapters1( nAdapter, &pAdapter ) != DXGI_ERROR_NOT_FOUND )
  567.                 {
  568.                     if ( pAdapter )
  569.                     {
  570.                         DXGI_ADAPTER_DESC1 adaptDesc;
  571.                         if ( SUCCEEDED( pAdapter->GetDesc1( &adaptDesc ) ) )
  572.                         {
  573.                             const bool isPerfHUD = wcscmp( adaptDesc.Description, L"NVIDIA PerfHUD" ) == 0;
  574.                             if ( isPerfHUD )
  575.                             {
  576.                                 pSelectedAdapter = pAdapter;
  577.                                 driverType = D3D_DRIVER_TYPE_REFERENCE;
  578.                             }
  579.                         }
  580.                         ++nAdapter;
  581.                     }
  582.                 }
  583.  
  584.             }
  585.  
  586.             ID3D11Device * device;
  587.  
  588.             HMODULE Software3d310Dll = NULL;
  589.             if (mDriverType == DT_SOFTWARE)
  590.             {
  591.                 driverType = D3D_DRIVER_TYPE_SOFTWARE;
  592.                 pSelectedAdapter = NULL;
  593.                 Software3d310Dll = LoadLibrary(TEXT("D3D11Ref.dll"));
  594.                 if (Software3d310Dll == NULL)
  595.                 {
  596.                     OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR,
  597.                         "Failed to load Direct3D11 software DLL (D3D11Ref.dll)",
  598.                         "D3D11RenderSystem::D3D11RenderSystem" );
  599.  
  600.                 }
  601.             }
  602.             else if (mDriverType == DT_WARP)
  603.             {
  604.                 // you have to use D3D_DRIVER_TYPE_SOFTWARE (D3D_DRIVER_TYPE_WARP doesn't work)
  605.                 driverType = D3D_DRIVER_TYPE_SOFTWARE;
  606.                 pSelectedAdapter = NULL;
  607.  
  608.                 Software3d310Dll = LoadLibrary(TEXT("D3D10WARP.dll"));
  609.                 if (Software3d310Dll == NULL)
  610.                 {
  611.                     // try to load the beta that was released
  612.                     Software3d310Dll = LoadLibrary(TEXT("D3D10WARP_beta.dll"));
  613.                     if (Software3d310Dll == NULL)
  614.                     {
  615.                         OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR,
  616.                             "Failed to load Direct3D11 Wrap DLL (D3D11WARP.dll or D3D11WARP_beta.dll)",
  617.                             "D3D11RenderSystem::D3D11RenderSystem" );
  618.  
  619.                     }
  620.                 }
  621.             }
  622.  
  623.             HRESULT hr = D3D11CreateDevice(pSelectedAdapter, driverType , Software3d310Dll, deviceFlags, NULL, 0, D3D11_SDK_VERSION, &device, 0, 0);
  624.  
  625.             if(FAILED(hr))        
  626.             {
  627.                 std::stringstream error;
  628.                 error<<"Failed to create Direct3D11 object."<<std::endl<<DXGetErrorDescription(hr)<<std::endl;
  629.  
  630.                 OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR,
  631.                     error.str(),
  632.                     "D3D11RenderSystem::D3D11RenderSystem" );
  633.             }
  634.  
  635.             if (Software3d310Dll != NULL)
  636.             {
  637.                 // get the IDXGIFactory1 from the device for software drivers
  638.                 // Remark(dec-09):
  639.                 //  Seems that IDXGIFactory1::CreateSoftwareAdapter doesn't work with
  640.                 // D3D11CreateDevice - so I needed to create with pSelectedAdapter = 0.
  641.                 // If pSelectedAdapter == 0 then you have to get the IDXGIFactory1 from
  642.                 // the device - else CreateSwapChain fails later.
  643.                 SAFE_RELEASE(mpDXGIFactory);
  644.  
  645.                 IDXGIDevice1 * pDXGIDevice;
  646.                 device->QueryInterface(__uuidof(IDXGIDevice1), (void **)&pDXGIDevice);
  647.  
  648.                 IDXGIAdapter1 * pDXGIAdapter;
  649.                 pDXGIDevice->GetParent(__uuidof(IDXGIAdapter1), (void **)&pDXGIAdapter);
  650.  
  651.                 pDXGIAdapter->GetParent(__uuidof(IDXGIFactory1), (void **)&mpDXGIFactory);
  652.  
  653.                 SAFE_RELEASE(pDXGIAdapter);
  654.                 SAFE_RELEASE(pDXGIDevice);
  655.             }
  656.  
  657.  
  658.             mDevice = D3D11Device(device) ;
  659.         }
  660.  
  661.  
  662.  
  663.  
  664.         // get driver version
  665.         // TODO: no wayto do this on Dx11? Can't find a driver version structure
  666.         /*
  667.         mDriverVersion.major = HIWORD(mActiveD3DDriver->getAdapterIdentifier().DriverVersion.HighPart);
  668.         mDriverVersion.minor = LOWORD(mActiveD3DDriver->getAdapterIdentifier().DriverVersion.HighPart);
  669.         mDriverVersion.release = HIWORD(mActiveD3DDriver->getAdapterIdentifier().DriverVersion.LowPart);
  670.         mDriverVersion.build = LOWORD(mActiveD3DDriver->getAdapterIdentifier().DriverVersion.LowPart);
  671.         */
  672.  
  673.  
  674.         if( autoCreateWindow )
  675.         {
  676.             bool fullScreen;
  677.             opt = mOptions.find( "Full Screen" );
  678.             if( opt == mOptions.end() )
  679.                 OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find full screen option!", "D3D11RenderSystem::initialise" );
  680.             fullScreen = opt->second.currentValue == "Yes";
  681.  
  682.             D3D11VideoMode* videoMode = NULL;
  683.             unsigned int width, height;
  684.             String temp;
  685.  
  686.             opt = mOptions.find( "Video Mode" );
  687.             if( opt == mOptions.end() )
  688.                 OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find Video Mode option!", "D3D11RenderSystem::initialise" );
  689.  
  690.             // The string we are manipulating looks like this :width x height @ colourDepth
  691.             // Pull out the colour depth by getting what comes after the @ and a space
  692.             String colourDepth = opt->second.currentValue.substr(opt->second.currentValue.rfind('@')+1);
  693.             // Now we know that the width starts a 0, so if we can find the end we can parse that out
  694.             String::size_type widthEnd = opt->second.currentValue.find(' ');
  695.             // we know that the height starts 3 characters after the width and goes until the next space
  696.             String::size_type heightEnd = opt->second.currentValue.find(' ', widthEnd+3);
  697.             // Now we can parse out the values
  698.             width = StringConverter::parseInt(opt->second.currentValue.substr(0, widthEnd));
  699.             height = StringConverter::parseInt(opt->second.currentValue.substr(widthEnd+3, heightEnd));
  700.  
  701.             for( unsigned j=0; j < mActiveD3DDriver->getVideoModeList()->count(); j++ )
  702.             {
  703.                 temp = mActiveD3DDriver->getVideoModeList()->item(j)->getDescription();
  704.  
  705.                 // In full screen we only want to allow supported resolutions, so temp and opt->second.currentValue need to
  706.                 // match exacly, but in windowed mode we can allow for arbitrary window sized, so we only need
  707.                 // to match the colour values
  708.                 if(fullScreen && (temp == opt->second.currentValue) ||
  709.                   !fullScreen && (temp.substr(temp.rfind('@')+1) == colourDepth))
  710.                 {
  711.                     videoMode = mActiveD3DDriver->getVideoModeList()->item(j);
  712.                     break;
  713.                 }
  714.             }
  715.  
  716.             if( !videoMode )
  717.                 OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find requested video mode.", "D3D11RenderSystem::initialise" );
  718.            
  719.             // sRGB window option
  720.             bool hwGamma = false;
  721.             opt = mOptions.find( "sRGB Gamma Conversion" );
  722.             if( opt == mOptions.end() )
  723.                 OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find sRGB option!", "D3D9RenderSystem::initialise" );
  724.             hwGamma = opt->second.currentValue == "Yes";
  725.             uint fsaa = 0;
  726.             String fsaaHint;
  727.             if( (opt = mOptions.find("FSAA")) != mOptions.end() )
  728.             {
  729.                 StringVector values = StringUtil::split(opt->second.currentValue, " ", 1);
  730.                 fsaa = StringConverter::parseUnsignedInt(values[0]);
  731.                 if (values.size() > 1)
  732.                     fsaaHint = values[1];
  733.             }              
  734.            
  735.  
  736.             NameValuePairList miscParams;
  737.             miscParams["colourDepth"] = StringConverter::toString(videoMode->getColourDepth());
  738.             miscParams["FSAA"] = StringConverter::toString(fsaa);
  739.             miscParams["FSAAHint"] = fsaaHint;
  740.             miscParams["vsync"] = StringConverter::toString(mVSync);
  741.             miscParams["vsyncInterval"] = StringConverter::toString(mVSyncInterval);
  742.             miscParams["useNVPerfHUD"] = StringConverter::toString(mUseNVPerfHUD);
  743.             miscParams["gamma"] = StringConverter::toString(hwGamma);
  744.  
  745.             autoWindow = this->_createRenderWindow( windowTitle, width, height,
  746.                 fullScreen, &miscParams );
  747.  
  748.             // If we have 16bit depth buffer enable w-buffering.
  749.             assert( autoWindow );
  750.             if ( autoWindow->getColourDepth() == 16 )
  751.             {
  752.                 mWBuffer = true;
  753.             }
  754.             else
  755.             {
  756.                 mWBuffer = false;
  757.             }          
  758.         }
  759.  
  760.         LogManager::getSingleton().logMessage("***************************************");
  761.         LogManager::getSingleton().logMessage("*** D3D11 : Subsystem Initialized OK ***");
  762.         LogManager::getSingleton().logMessage("***************************************");
  763.  
  764.         // call superclass method
  765.         RenderSystem::_initialise( autoCreateWindow );
  766.  
  767.  
  768.         return autoWindow;
  769.     }
  770.     //---------------------------------------------------------------------
  771.     void D3D11RenderSystem::reinitialise()
  772.     {
  773.         LogManager::getSingleton().logMessage( "D3D11 : Reinitializing" );
  774.         this->shutdown();
  775.     //  this->initialise( true );
  776.     }
  777.     //---------------------------------------------------------------------
  778.     void D3D11RenderSystem::shutdown()
  779.     {
  780.         RenderSystem::shutdown();
  781.  
  782.         mRenderSystemWasInited = false;
  783.  
  784.         mPrimaryWindow = NULL; // primary window deleted by base class.
  785.         freeDevice();
  786.         SAFE_DELETE( mDriverList );
  787.         SAFE_RELEASE( mpDXGIFactory );
  788.         mActiveD3DDriver = NULL;
  789.         mDevice = NULL;
  790.         mBasicStatesInitialised = false;
  791.         LogManager::getSingleton().logMessage("D3D11 : Shutting down cleanly.");
  792.         SAFE_DELETE( mTextureManager );
  793.         SAFE_DELETE( mHardwareBufferManager );
  794.         SAFE_DELETE( mGpuProgramManager );
  795.  
  796.     }
  797.     //---------------------------------------------------------------------
  798.     RenderWindow* D3D11RenderSystem::_createRenderWindow(const String &name,
  799.         unsigned int width, unsigned int height, bool fullScreen,
  800.         const NameValuePairList *miscParams)
  801.     {
  802.  
  803.         // Check we're not creating a secondary window when the primary
  804.         // was fullscreen
  805.         if (mPrimaryWindow && mPrimaryWindow->isFullScreen())
  806.         {
  807.             OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
  808.                 "Cannot create secondary windows when the primary is full screen",
  809.                 "D3D11RenderSystem::_createRenderWindow");
  810.         }
  811.         if (mPrimaryWindow && fullScreen)
  812.         {
  813.             OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
  814.                 "Cannot create full screen secondary windows",
  815.                 "D3D11RenderSystem::_createRenderWindow");
  816.         }
  817.        
  818.         // Log a message
  819.         StringStream ss;
  820.         ss << "D3D11RenderSystem::_createRenderWindow \"" << name << "\", " <<
  821.             width << "x" << height << " ";
  822.         if(fullScreen)
  823.             ss << "fullscreen ";
  824.         else
  825.             ss << "windowed ";
  826.         if(miscParams)
  827.         {
  828.             ss << " miscParams: ";
  829.             NameValuePairList::const_iterator it;
  830.             for(it=miscParams->begin(); it!=miscParams->end(); ++it)
  831.             {
  832.                 ss << it->first << "=" << it->second << " ";
  833.             }
  834.             LogManager::getSingleton().logMessage(ss.str());
  835.         }
  836.        
  837.         String msg;
  838.  
  839.         // Make sure we don't already have a render target of the
  840.         // sam name as the one supplied
  841.         if( mRenderTargets.find( name ) != mRenderTargets.end() )
  842.         {
  843.             msg = "A render target of the same name '" + name + "' already "
  844.                 "exists.  You cannot create a new window with this name.";
  845.             OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, msg, "D3D11RenderSystem::_createRenderWindow" );
  846.         }
  847.  
  848.         RenderWindow* win = new D3D11RenderWindow(mhInstance, mDevice, mpDXGIFactory);
  849.  
  850.         win->create( name, width, height, fullScreen, miscParams);
  851.  
  852.         attachRenderTarget( *win );
  853.  
  854.         // If this is the first window, get the D3D device and create the texture manager
  855.         if( !mPrimaryWindow )
  856.         {
  857.             mPrimaryWindow = (D3D11RenderWindow *)win;
  858.             win->getCustomAttribute( "D3DDEVICE", &mDevice );
  859.  
  860.             // Create the texture manager for use by others
  861.             mTextureManager = new D3D11TextureManager( mDevice );
  862.             // Also create hardware buffer manager
  863.             mHardwareBufferManager = new D3D11HardwareBufferManager(mDevice);
  864.  
  865.             // Create the GPU program manager
  866.             mGpuProgramManager = new D3D11GpuProgramManager(mDevice);
  867.             // create & register HLSL factory
  868.             if (mHLSLProgramFactory == NULL)
  869.                 mHLSLProgramFactory = new D3D11HLSLProgramFactory(mDevice);
  870.             mRealCapabilities = createRenderSystemCapabilities();                          
  871.             mRealCapabilities->addShaderProfile("hlsl");
  872.  
  873.             // if we are using custom capabilities, then
  874.             // mCurrentCapabilities has already been loaded
  875.             if(!mUseCustomCapabilities)
  876.                 mCurrentCapabilities = mRealCapabilities;
  877.  
  878.             initialiseFromRenderSystemCapabilities(mCurrentCapabilities, mPrimaryWindow);
  879.  
  880.         }
  881.         else
  882.         {
  883.             mSecondaryWindows.push_back(static_cast<D3D11RenderWindow *>(win));
  884.         }
  885.  
  886.         return win;
  887.  
  888.     }
  889.     //---------------------------------------------------------------------
  890.     RenderSystemCapabilities* D3D11RenderSystem::createRenderSystemCapabilities() const
  891.     {
  892.         RenderSystemCapabilities* rsc = new RenderSystemCapabilities();
  893.         rsc->setDriverVersion(mDriverVersion);
  894.         rsc->setDeviceName(mActiveD3DDriver->DriverDescription());
  895.         rsc->setRenderSystemName(getName());
  896.  
  897.         // Does NOT support fixed-function!
  898.         //rsc->setCapability(RSC_FIXED_FUNCTION);
  899.  
  900.         rsc->setCapability(RSC_HWSTENCIL);
  901.         rsc->setStencilBufferBitDepth(8);
  902.  
  903.         // Set number of texture units, always 16
  904.         rsc->setNumTextureUnits(16);
  905.         rsc->setCapability(RSC_ANISOTROPY);
  906.         rsc->setCapability(RSC_AUTOMIPMAP);
  907.         rsc->setCapability(RSC_BLENDING);
  908.         rsc->setCapability(RSC_DOT3);
  909.         // Cube map
  910.         rsc->setCapability(RSC_CUBEMAPPING);
  911.  
  912.         // We always support compression, D3DX will decompress if device does not support
  913.         rsc->setCapability(RSC_TEXTURE_COMPRESSION);
  914.         rsc->setCapability(RSC_TEXTURE_COMPRESSION_DXT);
  915.         rsc->setCapability(RSC_VBO);
  916.         rsc->setCapability(RSC_SCISSOR_TEST);
  917.         rsc->setCapability(RSC_TWO_SIDED_STENCIL);
  918.         rsc->setCapability(RSC_STENCIL_WRAP);
  919.         rsc->setCapability(RSC_HWOCCLUSION);
  920.  
  921.         convertVertexShaderCaps(rsc);
  922.         convertPixelShaderCaps(rsc);
  923.         convertGeometryShaderCaps(rsc);
  924.  
  925.         rsc->setCapability(RSC_USER_CLIP_PLANES);
  926.         rsc->setCapability(RSC_VERTEX_FORMAT_UBYTE4);
  927.  
  928.         rsc->setCapability(RSC_RTT_SEPARATE_DEPTHBUFFER);
  929.         rsc->setCapability(RSC_RTT_MAIN_DEPTHBUFFER_ATTACHABLE);
  930.  
  931.  
  932.         // Adapter details
  933.         const DXGI_ADAPTER_DESC1& adapterID = mActiveD3DDriver->getAdapterIdentifier();
  934.  
  935.         switch(mDriverType) {
  936.         case DT_HARDWARE:
  937.             // determine vendor
  938.             // Full list of vendors here: http://www.pcidatabase.com/vendors.php?sort=id
  939.             switch(adapterID.VendorId)
  940.             {
  941.             case 0x10DE:
  942.                 rsc->setVendor(GPU_NVIDIA);
  943.                 break;
  944.             case 0x1002:
  945.                 rsc->setVendor(GPU_ATI);
  946.                 break;
  947.             case 0x163C:
  948.             case 0x8086:
  949.                 rsc->setVendor(GPU_INTEL);
  950.                 break;
  951.             case 0x5333:
  952.                 rsc->setVendor(GPU_S3);
  953.                 break;
  954.             case 0x3D3D:
  955.                 rsc->setVendor(GPU_3DLABS);
  956.                 break;
  957.             case 0x102B:
  958.                 rsc->setVendor(GPU_MATROX);
  959.                 break;
  960.             default:
  961.                 rsc->setVendor(GPU_UNKNOWN);
  962.                 break;
  963.             };
  964.             break;
  965.         case DT_SOFTWARE:
  966.             rsc->setVendor(GPU_MS_SOFTWARE);
  967.             break;
  968.         case DT_WARP:
  969.             rsc->setVendor(GPU_MS_WARP);
  970.             break;
  971.         default:
  972.             rsc->setVendor(GPU_UNKNOWN);
  973.             break;
  974.         }
  975.  
  976.         rsc->setCapability(RSC_INFINITE_FAR_PLANE);
  977.  
  978.         rsc->setCapability(RSC_TEXTURE_3D);
  979.         rsc->setCapability(RSC_NON_POWER_OF_2_TEXTURES);
  980.         rsc->setCapability(RSC_HWRENDER_TO_TEXTURE);
  981.         rsc->setCapability(RSC_TEXTURE_FLOAT);
  982.  
  983.         rsc->setNumMultiRenderTargets(std::min(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, (int)OGRE_MAX_MULTIPLE_RENDER_TARGETS));
  984.         rsc->setCapability(RSC_MRT_DIFFERENT_BIT_DEPTHS);
  985.  
  986.         rsc->setCapability(RSC_POINT_SPRITES);
  987.         rsc->setCapability(RSC_POINT_EXTENDED_PARAMETERS);
  988.         rsc->setMaxPointSize(256); // TODO: guess!
  989.    
  990.         rsc->setCapability(RSC_VERTEX_TEXTURE_FETCH);
  991.         rsc->setNumVertexTextureUnits(4);
  992.         rsc->setVertexTextureUnitsShared(false);
  993.  
  994.         rsc->setCapability(RSC_MIPMAP_LOD_BIAS);
  995.  
  996.         // actually irrelevant, but set
  997.         rsc->setCapability(RSC_PERSTAGECONSTANT);
  998.  
  999.         rsc->setCapability(RSC_VERTEX_BUFFER_INSTANCE_DATA);
  1000.         rsc->setCapability(RSC_CAN_GET_COMPILED_SHADER_BUFFER);
  1001.  
  1002.         return rsc;
  1003.  
  1004.     }
  1005.     //-----------------------------------------------------------------------
  1006.     void D3D11RenderSystem::initialiseFromRenderSystemCapabilities(
  1007.         RenderSystemCapabilities* caps, RenderTarget* primary)
  1008.     {
  1009.         if(caps->getRenderSystemName() != getName())
  1010.         {
  1011.             OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
  1012.                 "Trying to initialize GLRenderSystem from RenderSystemCapabilities that do not support Direct3D11",
  1013.                 "D3D11RenderSystem::initialiseFromRenderSystemCapabilities");
  1014.         }
  1015.        
  1016.         // add hlsl
  1017.         HighLevelGpuProgramManager::getSingleton().addFactory(mHLSLProgramFactory);
  1018.  
  1019.         Log* defaultLog = LogManager::getSingleton().getDefaultLog();
  1020.         if (defaultLog)
  1021.         {
  1022.             caps->log(defaultLog);
  1023.         }
  1024.     }
  1025.     //---------------------------------------------------------------------
  1026.     void D3D11RenderSystem::convertVertexShaderCaps(RenderSystemCapabilities* rsc) const
  1027.     {
  1028.  
  1029.         rsc->addShaderProfile("vs_4_0");
  1030.         rsc->addShaderProfile("vs_4_1");
  1031.         rsc->addShaderProfile("vs_5_0");
  1032.  
  1033.         rsc->setCapability(RSC_VERTEX_PROGRAM);
  1034.  
  1035.         // TODO: constant buffers have no limits but lower models do
  1036.         // 16 boolean params allowed
  1037.         rsc->setVertexProgramConstantBoolCount(16);
  1038.         // 16 integer params allowed, 4D
  1039.         rsc->setVertexProgramConstantIntCount(16);
  1040.         // float params, always 4D
  1041.         rsc->setVertexProgramConstantFloatCount(512);
  1042.  
  1043.     }
  1044.     //---------------------------------------------------------------------
  1045.     void D3D11RenderSystem::convertPixelShaderCaps(RenderSystemCapabilities* rsc) const
  1046.     {
  1047.        
  1048.         rsc->addShaderProfile("ps_4_0");
  1049.         rsc->addShaderProfile("ps_4_1");
  1050.         rsc->addShaderProfile("ps_5_0");
  1051.  
  1052.         rsc->setCapability(RSC_FRAGMENT_PROGRAM);
  1053.  
  1054.  
  1055.         // TODO: constant buffers have no limits but lower models do
  1056.         // 16 boolean params allowed
  1057.         rsc->setFragmentProgramConstantBoolCount(16);
  1058.         // 16 integer params allowed, 4D
  1059.         rsc->setFragmentProgramConstantIntCount(16);
  1060.         // float params, always 4D
  1061.         rsc->setFragmentProgramConstantFloatCount(512);
  1062.  
  1063.     }
  1064.     //---------------------------------------------------------------------
  1065.     void D3D11RenderSystem::convertGeometryShaderCaps(RenderSystemCapabilities* rsc) const
  1066.     {
  1067.  
  1068.         rsc->addShaderProfile("gs_4_0");
  1069.         rsc->addShaderProfile("gs_4_1");
  1070.         rsc->addShaderProfile("gs_5_0");
  1071.  
  1072.         rsc->setCapability(RSC_GEOMETRY_PROGRAM);
  1073.         rsc->setCapability(RSC_HWRENDER_TO_VERTEX_BUFFER);
  1074.  
  1075.         rsc->setGeometryProgramConstantFloatCount(0);
  1076.         rsc->setGeometryProgramConstantIntCount(0);
  1077.         rsc->setGeometryProgramConstantBoolCount(0);
  1078.         rsc->setGeometryProgramNumOutputVertices(0);
  1079.         /*
  1080.         /// The number of floating-point constants geometry programs support
  1081.         void setGeometryProgramConstantFloatCount(ushort c)
  1082.         {
  1083.             mGeometryProgramConstantFloatCount = c;          
  1084.         }
  1085.         /// The number of integer constants geometry programs support
  1086.         void setGeometryProgramConstantIntCount(ushort c)
  1087.         {
  1088.             mGeometryProgramConstantIntCount = c;          
  1089.         }
  1090.         /// The number of boolean constants geometry programs support
  1091.         void setGeometryProgramConstantBoolCount(ushort c)
  1092.         {
  1093.             mGeometryProgramConstantBoolCount = c;          
  1094.         }
  1095.         /// Set the number of vertices a single geometry program run can emit
  1096.         void setGeometryProgramNumOutputVertices(int numOutputVertices)
  1097.         {
  1098.         mGeometryProgramNumOutputVertices = numOutputVertices;
  1099.         }
  1100.         /// Get the number of vertices a single geometry program run can emit
  1101.         int getGeometryProgramNumOutputVertices(void) const
  1102.         {
  1103.         return mGeometryProgramNumOutputVertices;
  1104.         }
  1105.  
  1106. */
  1107. /*      // TODO: constant buffers have no limits but lower models do
  1108.         // 16 boolean params allowed
  1109.         rsc->setFragmentProgramConstantBoolCount(16);
  1110.         // 16 integer params allowed, 4D
  1111.         rsc->setFragmentProgramConstantIntCount(16);
  1112.         // float params, always 4D
  1113.         rsc->setFragmentProgramConstantFloatCount(512);
  1114. */
  1115.     }
  1116.  
  1117.     //-----------------------------------------------------------------------
  1118.     bool D3D11RenderSystem::checkVertexTextureFormats(void)
  1119.     {
  1120.         return true;
  1121.     }
  1122.     //-----------------------------------------------------------------------
  1123.     bool D3D11RenderSystem::_checkTextureFilteringSupported(TextureType ttype, PixelFormat format, int usage)
  1124.     {
  1125.         return true;
  1126.     }
  1127.     //-----------------------------------------------------------------------
  1128.     MultiRenderTarget * D3D11RenderSystem::createMultiRenderTarget(const String & name)
  1129.     {
  1130.         MultiRenderTarget *retval;
  1131.         retval = new D3D11MultiRenderTarget(name);
  1132.         attachRenderTarget(*retval);
  1133.  
  1134.         return retval;
  1135.     }
  1136.     //-----------------------------------------------------------------------
  1137.     DepthBuffer* D3D11RenderSystem::_createDepthBufferFor( RenderTarget *renderTarget )
  1138.     {
  1139.         //Get surface data (mainly to get MSAA data)
  1140.         D3D11HardwarePixelBuffer *pBuffer;
  1141.         renderTarget->getCustomAttribute( "BUFFER", &pBuffer );
  1142.         D3D11_TEXTURE2D_DESC BBDesc;
  1143.         static_cast<ID3D11Texture2D*>(pBuffer->getParentTexture()->getTextureResource())->GetDesc( &BBDesc );
  1144.  
  1145.         // Create depth stencil texture
  1146.         ID3D11Texture2D* pDepthStencil = NULL;
  1147.         D3D11_TEXTURE2D_DESC descDepth;
  1148.  
  1149.         descDepth.Width                 = renderTarget->getWidth();
  1150.         descDepth.Height                = renderTarget->getHeight();
  1151.         descDepth.MipLevels             = 1;
  1152.         descDepth.ArraySize             = BBDesc.ArraySize;
  1153.         descDepth.Format                = DXGI_FORMAT_D32_FLOAT;
  1154.         descDepth.SampleDesc.Count      = BBDesc.SampleDesc.Count;
  1155.         descDepth.SampleDesc.Quality    = BBDesc.SampleDesc.Quality;
  1156.         descDepth.Usage                 = D3D11_USAGE_DEFAULT;
  1157.         descDepth.BindFlags             = D3D11_BIND_DEPTH_STENCIL;
  1158.         descDepth.CPUAccessFlags        = 0;
  1159.         descDepth.MiscFlags             = 0;
  1160.  
  1161.         if (descDepth.ArraySize == 6)
  1162.         {
  1163.             descDepth.MiscFlags     |= D3D11_RESOURCE_MISC_TEXTURECUBE;
  1164.         }
  1165.  
  1166.  
  1167.         HRESULT hr = mDevice->CreateTexture2D( &descDepth, NULL, &pDepthStencil );
  1168.         if( FAILED(hr) || mDevice.isError())
  1169.         {
  1170.             String errorDescription = mDevice.getErrorDescription(hr);
  1171.             OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  1172.                 "Unable to create depth texture\nError Description:" + errorDescription,
  1173.                 "D3D11RenderSystem::_createDepthBufferFor");
  1174.         }
  1175.  
  1176.         // Create the depth stencil view
  1177.         ID3D11DepthStencilView      *depthStencilView;
  1178.         D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
  1179.         ZeroMemory( &descDSV, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC) );
  1180.  
  1181.         descDSV.Format = DXGI_FORMAT_D32_FLOAT;
  1182.         descDSV.ViewDimension = (BBDesc.SampleDesc.Count > 1) ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D;
  1183.         descDSV.Texture2D.MipSlice = 0;
  1184.         hr = mDevice->CreateDepthStencilView( pDepthStencil, &descDSV, &depthStencilView );
  1185.         SAFE_RELEASE( pDepthStencil );
  1186.         if( FAILED(hr) )
  1187.         {
  1188.             String errorDescription = mDevice.getErrorDescription();
  1189.             OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  1190.                 "Unable to create depth stencil view\nError Description:" + errorDescription,
  1191.                 "D3D11RenderSystem::_createDepthBufferFor");
  1192.         }
  1193.  
  1194.         //Create the abstract container
  1195.         D3D11DepthBuffer *newDepthBuffer = new D3D11DepthBuffer( DepthBuffer::POOL_DEFAULT,this, depthStencilView,
  1196.                                                 descDepth.Width, descDepth.Height,
  1197.                                                 descDepth.SampleDesc.Count, descDepth.SampleDesc.Quality,
  1198.                                                 false );
  1199.  
  1200.         return newDepthBuffer;
  1201.     }
  1202.     //---------------------------------------------------------------------
  1203.     DepthBuffer* D3D11RenderSystem::_addManualDepthBuffer( ID3D11DepthStencilView *depthSurface,
  1204.                                                             uint32 width, uint32 height,
  1205.                                                             uint32 fsaa, uint32 fsaaQuality )
  1206.     {
  1207.         //If this depth buffer was already added, return that one
  1208.         DepthBufferVec::const_iterator itor = mDepthBufferPool[DepthBuffer::POOL_DEFAULT].begin();
  1209.         DepthBufferVec::const_iterator end  = mDepthBufferPool[DepthBuffer::POOL_DEFAULT].end();
  1210.  
  1211.         while( itor != end )
  1212.         {
  1213.             if( static_cast<D3D11DepthBuffer*>(*itor)->getDepthStencilView() == depthSurface )
  1214.                 return *itor;
  1215.  
  1216.             ++itor;
  1217.         }
  1218.  
  1219.         //Create a new container for it
  1220.         D3D11DepthBuffer *newDepthBuffer = new D3D11DepthBuffer( DepthBuffer::POOL_DEFAULT,this, depthSurface,
  1221.                                                                     width, height, fsaa, fsaaQuality, true );
  1222.  
  1223.         //Add the 'main' depth buffer to the pool
  1224.         mDepthBufferPool[newDepthBuffer->getPoolId()].push_back( newDepthBuffer );
  1225.  
  1226.         return newDepthBuffer;
  1227.     }
  1228.     //---------------------------------------------------------------------
  1229.     void D3D11RenderSystem::destroyRenderTarget(const String& name)
  1230.     {
  1231.         // Check in specialised lists
  1232.         if (mPrimaryWindow->getName() == name)
  1233.         {
  1234.             // We're destroying the primary window, so reset device and window
  1235.             mPrimaryWindow = 0;
  1236.         }
  1237.         else
  1238.         {
  1239.             // Check secondary windows
  1240.             SecondaryWindowList::iterator sw;
  1241.             for (sw = mSecondaryWindows.begin(); sw != mSecondaryWindows.end(); ++sw)
  1242.             {
  1243.                 if ((*sw)->getName() == name)
  1244.                 {
  1245.                     mSecondaryWindows.erase(sw);
  1246.                     break;
  1247.                 }
  1248.             }
  1249.         }
  1250.         // Do the real removal
  1251.         RenderSystem::destroyRenderTarget(name);
  1252.  
  1253.         // Did we destroy the primary?
  1254.         if (!mPrimaryWindow)
  1255.         {
  1256.             // device is no longer valid, so free it all up
  1257.             freeDevice();
  1258.         }
  1259.  
  1260.     }
  1261.     //-----------------------------------------------------------------------
  1262.     void D3D11RenderSystem::freeDevice(void)
  1263.     {
  1264.         if (!mDevice.isNull() && mCurrentCapabilities)
  1265.         {
  1266.             // Set all texture units to nothing to release texture surfaces
  1267.             _disableTextureUnitsFrom(0);
  1268.             // Unbind any vertex streams to avoid memory leaks
  1269.             /*for (unsigned int i = 0; i < mLastVertexSourceCount; ++i)
  1270.             {
  1271.                 HRESULT hr = mDevice->SetStreamSource(i, NULL, 0, 0);
  1272.             }
  1273.             */
  1274.             // Clean up depth stencil surfaces
  1275.             mDevice.release();
  1276.             //mActiveD3DDriver->setDevice(D3D11Device(NULL));
  1277.             mDevice = 0;
  1278.  
  1279.         }
  1280.  
  1281.  
  1282.     }
  1283.     //---------------------------------------------------------------------
  1284.     VertexElementType D3D11RenderSystem::getColourVertexElementType(void) const
  1285.     {
  1286.         return VET_COLOUR_ABGR;
  1287.     }
  1288.     //---------------------------------------------------------------------
  1289.     void D3D11RenderSystem::_convertProjectionMatrix(const Matrix4& matrix,
  1290.         Matrix4& dest, bool forGpuProgram)
  1291.     {
  1292.         dest = matrix;
  1293.     }
  1294.     //---------------------------------------------------------------------
  1295.     void D3D11RenderSystem::_makeProjectionMatrix(const Radian& fovy, Real aspect, Real nearPlane,
  1296.         Real farPlane, Matrix4& dest, bool forGpuProgram)
  1297.     {
  1298.         Radian theta ( fovy * 0.5 );
  1299.         Real h = 1 / Math::Tan(theta);
  1300.         Real w = h / aspect;
  1301.         Real q, qn;
  1302.         if (farPlane == 0)
  1303.         {
  1304.             q = 1 - Frustum::INFINITE_FAR_PLANE_ADJUST;
  1305.             qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 1);
  1306.         }
  1307.         else
  1308.         {
  1309.             q = farPlane / ( farPlane - nearPlane );
  1310.             qn = -q * nearPlane;
  1311.         }
  1312.  
  1313.         dest = Matrix4::ZERO;
  1314.         dest[0][0] = w;
  1315.         dest[1][1] = h;
  1316.  
  1317.         if (forGpuProgram)
  1318.         {
  1319.             dest[2][2] = -q;
  1320.             dest[3][2] = -1.0f;
  1321.         }
  1322.         else
  1323.         {
  1324.             dest[2][2] = q;
  1325.             dest[3][2] = 1.0f;
  1326.         }
  1327.  
  1328.         dest[2][3] = qn;
  1329.     }
  1330.     //---------------------------------------------------------------------
  1331.     void D3D11RenderSystem::_makeOrthoMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane,
  1332.         Matrix4& dest, bool forGpuProgram )
  1333.     {
  1334.         Radian thetaY (fovy / 2.0f);
  1335.         Real tanThetaY = Math::Tan(thetaY);
  1336.  
  1337.         //Real thetaX = thetaY * aspect;
  1338.         Real tanThetaX = tanThetaY * aspect; //Math::Tan(thetaX);
  1339.         Real half_w = tanThetaX * nearPlane;
  1340.         Real half_h = tanThetaY * nearPlane;
  1341.         Real iw = 1.0f / half_w;
  1342.         Real ih = 1.0f / half_h;
  1343.         Real q;
  1344.         if (farPlane == 0)
  1345.         {
  1346.             q = 0;
  1347.         }
  1348.         else
  1349.         {
  1350.             q = 1.0f / (farPlane - nearPlane);
  1351.         }
  1352.  
  1353.         dest = Matrix4::ZERO;
  1354.         dest[0][0] = iw;
  1355.         dest[1][1] = ih;
  1356.         dest[2][2] = q;
  1357.         dest[2][3] = -nearPlane / (farPlane - nearPlane);
  1358.         dest[3][3] = 1;
  1359.  
  1360.         if (forGpuProgram)
  1361.         {
  1362.             dest[2][2] = -dest[2][2];
  1363.         }
  1364.     }
  1365.     //---------------------------------------------------------------------
  1366.     void D3D11RenderSystem::setAmbientLight( float r, float g, float b )
  1367.     {
  1368.     }
  1369.     //---------------------------------------------------------------------
  1370.     void D3D11RenderSystem::_useLights(const LightList& lights, unsigned short limit)
  1371.     {
  1372.     }
  1373.     //---------------------------------------------------------------------
  1374.     void D3D11RenderSystem::setShadingType( ShadeOptions so )
  1375.     {
  1376.     }
  1377.     //---------------------------------------------------------------------
  1378.     void D3D11RenderSystem::setLightingEnabled( bool enabled )
  1379.     {
  1380.     }
  1381.     //---------------------------------------------------------------------
  1382.     void D3D11RenderSystem::_setViewMatrix( const Matrix4 &m )
  1383.     {
  1384.     }
  1385.     //---------------------------------------------------------------------
  1386.     void D3D11RenderSystem::_setProjectionMatrix( const Matrix4 &m )
  1387.     {
  1388.     }
  1389.     //---------------------------------------------------------------------
  1390.     void D3D11RenderSystem::_setWorldMatrix( const Matrix4 &m )
  1391.     {
  1392.     }
  1393.     //---------------------------------------------------------------------
  1394.     void D3D11RenderSystem::_setSurfaceParams( const ColourValue &ambient, const ColourValue &diffuse,
  1395.         const ColourValue &specular, const ColourValue &emissive, Real shininess,
  1396.         TrackVertexColourType tracking )
  1397.     {
  1398.     }
  1399.     //---------------------------------------------------------------------
  1400.     void D3D11RenderSystem::_setPointParameters(Real size,
  1401.         bool attenuationEnabled, Real constant, Real linear, Real quadratic,
  1402.         Real minSize, Real maxSize)
  1403.     {
  1404.     }
  1405.     //---------------------------------------------------------------------
  1406.     void D3D11RenderSystem::_setPointSpritesEnabled(bool enabled)
  1407.     {
  1408.     }
  1409.     //---------------------------------------------------------------------
  1410.     void D3D11RenderSystem::_setTexture( size_t stage, bool enabled, const TexturePtr& tex )
  1411.     {
  1412.         static D3D11TexturePtr dt;
  1413.         dt = tex;
  1414.         if (enabled)
  1415.         {
  1416.             // note used
  1417.             dt->touch();
  1418.             ID3D11ShaderResourceView * pTex = dt->getTexture();
  1419.             mTexStageDesc[stage].pTex = pTex;
  1420.             mTexStageDesc[stage].used = true;
  1421.             mTexStageDesc[stage].type = dt->getTextureType();
  1422.         }
  1423.         else
  1424.         {
  1425.             mTexStageDesc[stage].used = false;
  1426.         }
  1427.     }
  1428.     //---------------------------------------------------------------------
  1429.     void D3D11RenderSystem::_setVertexTexture(size_t stage, const TexturePtr& tex)
  1430.     {
  1431.         if (tex.isNull())
  1432.             _setTexture(stage, false, tex);
  1433.         else
  1434.             _setTexture(stage, true, tex); 
  1435.     }
  1436.     //---------------------------------------------------------------------
  1437.     void D3D11RenderSystem::_disableTextureUnit(size_t texUnit)
  1438.     {
  1439.         RenderSystem::_disableTextureUnit(texUnit);
  1440.         // also disable vertex texture unit
  1441.         static TexturePtr nullPtr;
  1442.         _setVertexTexture(texUnit, nullPtr);
  1443.     }
  1444.     //---------------------------------------------------------------------
  1445.     void D3D11RenderSystem::_setTextureCoordSet( size_t stage, size_t index )
  1446.     {
  1447.         mTexStageDesc[stage].coordIndex = index;
  1448.     }
  1449.     //---------------------------------------------------------------------
  1450.     void D3D11RenderSystem::_setTextureCoordCalculation( size_t stage, TexCoordCalcMethod m,
  1451.         const Frustum* frustum)
  1452.     {
  1453.         // record the stage state
  1454.         mTexStageDesc[stage].autoTexCoordType = m;
  1455.         mTexStageDesc[stage].frustum = frustum;
  1456.     }
  1457.     //---------------------------------------------------------------------
  1458.     void D3D11RenderSystem::_setTextureMipmapBias(size_t unit, float bias)
  1459.     {
  1460.  
  1461.     }
  1462.     //---------------------------------------------------------------------
  1463.     void D3D11RenderSystem::_setTextureMatrix( size_t stage, const Matrix4& xForm )
  1464.     {
  1465.     }
  1466.     //---------------------------------------------------------------------
  1467.     void D3D11RenderSystem::_setTextureAddressingMode( size_t stage,
  1468.         const TextureUnitState::UVWAddressingMode& uvw )
  1469.     {
  1470.         // record the stage state
  1471.         mTexStageDesc[stage].samplerDesc.AddressU = D3D11Mappings::get(uvw.u);
  1472.         mTexStageDesc[stage].samplerDesc.AddressV = D3D11Mappings::get(uvw.v);
  1473.         mTexStageDesc[stage].samplerDesc.AddressW = D3D11Mappings::get(uvw.w);
  1474.     }
  1475.     //-----------------------------------------------------------------------------
  1476.     void D3D11RenderSystem::_setTextureBorderColour(size_t stage,
  1477.         const ColourValue& colour)
  1478.     {
  1479.         D3D11Mappings::get(colour, mTexStageDesc[stage].samplerDesc.BorderColor);
  1480.     }
  1481.     //---------------------------------------------------------------------
  1482.     void D3D11RenderSystem::_setTextureBlendMode( size_t stage, const LayerBlendModeEx& bm )
  1483.     {
  1484.         if (bm.blendType == LBT_COLOUR)
  1485.         {
  1486.             mTexStageDesc[stage].layerBlendMode = bm;
  1487.         }
  1488.     }
  1489.     //---------------------------------------------------------------------
  1490.     void D3D11RenderSystem::_setSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op /*= SBO_ADD*/ )
  1491.     {
  1492.         if( sourceFactor == SBF_ONE && destFactor == SBF_ZERO)
  1493.         {
  1494.             mBlendDesc.RenderTarget[0].BlendEnable = FALSE;
  1495.         }
  1496.         else
  1497.         {
  1498.             mBlendDesc.RenderTarget[0].BlendEnable = TRUE;
  1499.             mBlendDesc.RenderTarget[0].SrcBlend = D3D11Mappings::get(sourceFactor);
  1500.             mBlendDesc.RenderTarget[0].DestBlend = D3D11Mappings::get(destFactor);
  1501.             mBlendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD ;
  1502.             mBlendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD ;
  1503.             mBlendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO;
  1504.             mBlendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
  1505.             mBlendDesc.AlphaToCoverageEnable = mSceneAlphaToCoverage;
  1506.  
  1507.             mBlendDesc.RenderTarget[0].RenderTargetWriteMask = 0x0F;
  1508.         }
  1509.     }
  1510.     //---------------------------------------------------------------------
  1511.     void D3D11RenderSystem::_setSeparateSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha, SceneBlendOperation op /*= SBO_ADD*/, SceneBlendOperation alphaOp /*= SBO_ADD*/ )
  1512.     {
  1513.     }
  1514.     //---------------------------------------------------------------------
  1515.     void D3D11RenderSystem::_setAlphaRejectSettings( CompareFunction func, unsigned char value, bool alphaToCoverage )
  1516.     {
  1517.         mSceneAlphaRejectFunc   = func;
  1518.         mSceneAlphaRejectValue  = value;
  1519.  
  1520.  
  1521.         mSceneAlphaToCoverage   = alphaToCoverage;
  1522.         //Do nothing, alpha rejection unavailable in Direct3D11
  1523.     }
  1524.     //---------------------------------------------------------------------
  1525.     void D3D11RenderSystem::_setCullingMode( CullingMode mode )
  1526.     {
  1527.         mCullingMode = mode;
  1528.         mRasterizerDesc.CullMode = D3D11Mappings::get(mode);
  1529.     }
  1530.     //---------------------------------------------------------------------
  1531.     void D3D11RenderSystem::_setDepthBufferParams( bool depthTest, bool depthWrite, CompareFunction depthFunction )
  1532.     {
  1533.         _setDepthBufferCheckEnabled( depthTest );
  1534.         _setDepthBufferWriteEnabled( depthWrite );
  1535.         _setDepthBufferFunction( depthFunction );
  1536.     }
  1537.     //---------------------------------------------------------------------
  1538.     void D3D11RenderSystem::_setDepthBufferCheckEnabled( bool enabled )
  1539.     {
  1540.         mDepthStencilDesc.DepthEnable = enabled;
  1541.         //mRasterizerDesc.DepthClipEnable = enabled;
  1542.     }
  1543.     //---------------------------------------------------------------------
  1544.     void D3D11RenderSystem::_setDepthBufferWriteEnabled( bool enabled )
  1545.     {
  1546.         if (enabled)
  1547.         {
  1548.             mDepthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
  1549.         }
  1550.         else
  1551.         {
  1552.             mDepthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
  1553.         }
  1554.     }
  1555.     //---------------------------------------------------------------------
  1556.     void D3D11RenderSystem::_setDepthBufferFunction( CompareFunction func )
  1557.     {
  1558.         mDepthStencilDesc.DepthFunc = D3D11Mappings::get(func);
  1559.     }
  1560.     //---------------------------------------------------------------------
  1561.     void D3D11RenderSystem::_setDepthBias(float constantBias, float slopeScaleBias)
  1562.     {
  1563.         mRasterizerDesc.DepthBiasClamp = constantBias;
  1564.         mRasterizerDesc.SlopeScaledDepthBias = slopeScaleBias;
  1565.  
  1566.     }
  1567.     //---------------------------------------------------------------------
  1568.     void D3D11RenderSystem::_setColourBufferWriteEnabled(bool red, bool green,
  1569.         bool blue, bool alpha)
  1570.     {
  1571.         UINT8 val = 0;
  1572.         if (red)
  1573.             val |= D3D11_COLOR_WRITE_ENABLE_RED;
  1574.         if (green)
  1575.             val |= D3D11_COLOR_WRITE_ENABLE_GREEN;
  1576.         if (blue)
  1577.             val |= D3D11_COLOR_WRITE_ENABLE_BLUE;
  1578.         if (alpha)
  1579.             val |= D3D11_COLOR_WRITE_ENABLE_ALPHA;
  1580.  
  1581.         mBlendDesc.RenderTarget[0].RenderTargetWriteMask = val;
  1582.     }
  1583.     //---------------------------------------------------------------------
  1584.     void D3D11RenderSystem::_setFog( FogMode mode, const ColourValue& colour, Real densitiy, Real start, Real end )
  1585.     {
  1586.     }
  1587.     //---------------------------------------------------------------------
  1588.     void D3D11RenderSystem::_setPolygonMode(PolygonMode level)
  1589.     {
  1590.         mPolygonMode = level;
  1591.         mRasterizerDesc.FillMode = D3D11Mappings::get(mPolygonMode);
  1592.     }
  1593.     //---------------------------------------------------------------------
  1594.     void D3D11RenderSystem::setStencilCheckEnabled(bool enabled)
  1595.     {
  1596.         mDepthStencilDesc.StencilEnable = enabled;
  1597.     }
  1598.     //---------------------------------------------------------------------
  1599.     void D3D11RenderSystem::setStencilBufferParams(CompareFunction func,
  1600.         uint32 refValue, uint32 mask, StencilOperation stencilFailOp,
  1601.         StencilOperation depthFailOp, StencilOperation passOp,
  1602.         bool twoSidedOperation)
  1603.     {
  1604.         mDepthStencilDesc.FrontFace.StencilFunc = D3D11Mappings::get(func);
  1605.         mDepthStencilDesc.BackFace.StencilFunc = D3D11Mappings::get(func);
  1606.  
  1607.         mStencilRef = refValue;
  1608.         mDepthStencilDesc.StencilReadMask = refValue;
  1609.         mDepthStencilDesc.StencilWriteMask = mask;
  1610.  
  1611.         mDepthStencilDesc.FrontFace.StencilFailOp = D3D11Mappings::get(stencilFailOp);
  1612.         mDepthStencilDesc.BackFace.StencilFailOp = D3D11Mappings::get(stencilFailOp);
  1613.  
  1614.         mDepthStencilDesc.FrontFace.StencilDepthFailOp = D3D11Mappings::get(stencilFailOp);
  1615.         mDepthStencilDesc.BackFace.StencilDepthFailOp = D3D11Mappings::get(stencilFailOp);
  1616.  
  1617.         mDepthStencilDesc.FrontFace.StencilPassOp = D3D11Mappings::get(passOp);
  1618.         mDepthStencilDesc.BackFace.StencilPassOp = D3D11Mappings::get(passOp);
  1619.  
  1620.         if (!twoSidedOperation)
  1621.         {
  1622.             mDepthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_NEVER;
  1623.         }
  1624.  
  1625.     }
  1626.     //---------------------------------------------------------------------
  1627.     void D3D11RenderSystem::_setTextureUnitFiltering(size_t unit, FilterType ftype,
  1628.         FilterOptions filter)
  1629.     {
  1630.         switch(ftype) {
  1631.         case FT_MIN:
  1632.             FilterMinification[unit] = filter;
  1633.             break;
  1634.         case FT_MAG:
  1635.             FilterMagnification[unit] = filter;
  1636.             break;
  1637.         case FT_MIP:
  1638.             FilterMips[unit] = filter;
  1639.             break;
  1640.         }
  1641.  
  1642.         mTexStageDesc[unit].samplerDesc.Filter = D3D11Mappings::get(FilterMinification[unit], FilterMagnification[unit], FilterMips[unit],CompareEnabled[unit]);
  1643.  
  1644.     }
  1645.     //---------------------------------------------------------------------
  1646.     void D3D11RenderSystem::_setTextureUnitCompareEnabled(size_t unit, bool compare)
  1647.     {
  1648.         CompareEnabled[unit] = compare;
  1649.     }
  1650.     //---------------------------------------------------------------------
  1651.     void D3D11RenderSystem::_setTextureUnitCompareFunction(size_t unit, CompareFunction function)
  1652.     {
  1653.         mTexStageDesc[unit].samplerDesc.ComparisonFunc = D3D11Mappings::get(function);
  1654.     }
  1655.     //---------------------------------------------------------------------
  1656.     DWORD D3D11RenderSystem::_getCurrentAnisotropy(size_t unit)
  1657.     {
  1658.         return 0;
  1659.     }
  1660.     //---------------------------------------------------------------------
  1661.     void D3D11RenderSystem::_setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy)
  1662.     {
  1663.     }
  1664.     //---------------------------------------------------------------------
  1665.     void D3D11RenderSystem::_setRenderTarget(RenderTarget *target)
  1666.     {
  1667.         mActiveRenderTarget = target;
  1668.         if (mActiveRenderTarget)
  1669.         {
  1670.             ID3D11RenderTargetView * pRTView[OGRE_MAX_MULTIPLE_RENDER_TARGETS];
  1671.             memset(pRTView, 0, sizeof(pRTView));
  1672.  
  1673.             uint count = 0;
  1674.             target->getCustomAttribute( "ID3D11RenderTargetView", &pRTView );
  1675.  
  1676.             while(pRTView[count] != NULL)
  1677.             {
  1678.                 count++;
  1679.             }
  1680.  
  1681.             //Retrieve depth buffer
  1682.             D3D11DepthBuffer *depthBuffer = static_cast<D3D11DepthBuffer*>(target->getDepthBuffer());
  1683.  
  1684.             if( target->getDepthBufferPool() != DepthBuffer::POOL_NO_DEPTH && !depthBuffer )
  1685.             {
  1686.                 //Depth is automatically managed and there is no depth buffer attached to this RT
  1687.                 //or the Current D3D device doesn't match the one this Depth buffer was created
  1688.                 setDepthBufferFor( target );
  1689.             }
  1690.  
  1691.             //Retrieve depth buffer again (it may have changed)
  1692.             depthBuffer = static_cast<D3D11DepthBuffer*>(target->getDepthBuffer());
  1693.  
  1694.             // we need to clear the state
  1695.             mDevice.GetImmediateContext()->ClearState();
  1696.  
  1697.             if (mDevice.isError())
  1698.             {
  1699.                 String errorDescription = mDevice.getErrorDescription();
  1700.                 OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  1701.                     "D3D11 device cannot Clear State\nError Description:" + errorDescription,
  1702.                     "D3D11RenderSystem::_setViewport");
  1703.             }
  1704.  
  1705.  
  1706.  
  1707.             // now switch to the new render target
  1708.             mDevice.GetImmediateContext()->OMSetRenderTargets(count,
  1709.                 pRTView,
  1710.                 depthBuffer ? depthBuffer->getDepthStencilView() : 0 );
  1711.  
  1712.  
  1713.             if (mDevice.isError())
  1714.             {
  1715.                 String errorDescription = mDevice.getErrorDescription();
  1716.                 OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  1717.                     "D3D11 device cannot set render target\nError Description:" + errorDescription,
  1718.                     "D3D11RenderSystem::_setViewport");
  1719.             }
  1720.         }
  1721.  
  1722.     }
  1723.     //---------------------------------------------------------------------
  1724.     void D3D11RenderSystem::_setViewport( Viewport *vp )
  1725.     {
  1726.         if (!vp)
  1727.         {
  1728.             mActiveViewport = NULL;
  1729.             _setRenderTarget(NULL);
  1730.         }
  1731.         else if( vp != mActiveViewport || vp->_isUpdated() )
  1732.         {
  1733.             mActiveViewport = vp;
  1734.            
  1735.  
  1736.  
  1737.             // ok, it's different, time to set render target and viewport params
  1738.             D3D11_VIEWPORT d3dvp;
  1739.         //  HRESULT hr;
  1740.  
  1741.             // Set render target
  1742.             RenderTarget* target;
  1743.             target = vp->getTarget();
  1744.  
  1745.             _setRenderTarget(target);
  1746.             _setCullingMode( mCullingMode );
  1747.  
  1748.             // set viewport dimensions
  1749.             d3dvp.TopLeftX = static_cast<FLOAT>(vp->getActualLeft());
  1750.             d3dvp.TopLeftY = static_cast<FLOAT>(vp->getActualTop());
  1751.             d3dvp.Width = static_cast<FLOAT>(vp->getActualWidth());
  1752.             d3dvp.Height = static_cast<FLOAT>(vp->getActualHeight());
  1753.             if (target->requiresTextureFlipping())
  1754.             {
  1755.                 // Convert "top-left" to "bottom-left"
  1756.                 d3dvp.TopLeftY = target->getHeight() - d3dvp.Height - d3dvp.TopLeftY;
  1757.             }
  1758.  
  1759.             // Z-values from 0.0 to 1.0 (TODO: standardise with OpenGL)
  1760.             d3dvp.MinDepth = 0.0f;
  1761.             d3dvp.MaxDepth = 1.0f;
  1762.  
  1763.             mDevice.GetImmediateContext()->RSSetViewports(1, &d3dvp);
  1764.             if (mDevice.isError())
  1765.             {
  1766.                 String errorDescription = mDevice.getErrorDescription();
  1767.                 OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  1768.                     "D3D11 device cannot set viewports\nError Description:" + errorDescription,
  1769.                     "D3D11RenderSystem::_setViewport");
  1770.             }
  1771.  
  1772.             // Set sRGB write mode
  1773.             //__SetRenderState(D3DRS_SRGBWRITEENABLE, target->isHardwareGammaEnabled());
  1774.             // TODO where has sRGB state gone?
  1775.            
  1776.             vp->_clearUpdatedFlag();
  1777.         }
  1778.     }
  1779.     //---------------------------------------------------------------------
  1780.     void D3D11RenderSystem::_beginFrame()
  1781.     {
  1782.    
  1783.         if( !mActiveViewport )
  1784.             OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Cannot begin frame - no viewport selected.", "D3D11RenderSystem::_beginFrame" );
  1785.     }
  1786.     //---------------------------------------------------------------------
  1787.     void D3D11RenderSystem::_endFrame()
  1788.     {
  1789.     }
  1790.     //---------------------------------------------------------------------
  1791.     void D3D11RenderSystem::setVertexDeclaration(VertexDeclaration* decl)
  1792.     {
  1793.             OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR,
  1794.                     "Cannot directly call setVertexDeclaration in the d3d11 render system - cast then use 'setVertexDeclaration(VertexDeclaration* decl, VertexBufferBinding* binding)' .",
  1795.                     "D3D11RenderSystem::setVertexDeclaration" );
  1796.     }
  1797.     //---------------------------------------------------------------------
  1798.     void D3D11RenderSystem::setVertexDeclaration(VertexDeclaration* decl, VertexBufferBinding* binding)
  1799.     {
  1800.         D3D11VertexDeclaration* d3ddecl =
  1801.             static_cast<D3D11VertexDeclaration*>(decl);
  1802.  
  1803.         d3ddecl->bindToShader(mBoundVertexProgram, binding);
  1804.     }
  1805.     //---------------------------------------------------------------------
  1806.     void D3D11RenderSystem::setVertexBufferBinding(VertexBufferBinding* binding)
  1807.     {
  1808.         // TODO: attempt to detect duplicates
  1809.         const VertexBufferBinding::VertexBufferBindingMap& binds = binding->getBindings();
  1810.         VertexBufferBinding::VertexBufferBindingMap::const_iterator i, iend;
  1811.         iend = binds.end();
  1812.         for (i = binds.begin(); i != iend; ++i)
  1813.         {
  1814.             const D3D11HardwareVertexBuffer* d3d11buf =
  1815.                 static_cast<const D3D11HardwareVertexBuffer*>(i->second.get());
  1816.  
  1817.             UINT stride = static_cast<UINT>(d3d11buf->getVertexSize());
  1818.             UINT offset = 0; // no stream offset, this is handled in _render instead
  1819.             UINT slot = static_cast<UINT>(i->first);
  1820.             ID3D11Buffer * pVertexBuffers = d3d11buf->getD3DVertexBuffer();
  1821.             mDevice.GetImmediateContext()->IASetVertexBuffers(
  1822.                 slot, // The first input slot for binding.
  1823.                 1, // The number of vertex buffers in the array.
  1824.                 &pVertexBuffers,
  1825.                 &stride,
  1826.                 &offset
  1827.                 );
  1828.  
  1829.             if (mDevice.isError())
  1830.             {
  1831.                 String errorDescription = mDevice.getErrorDescription();
  1832.                 OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  1833.                     "D3D11 device cannot set vertex buffers\nError Description:" + errorDescription,
  1834.                     "D3D11RenderSystem::setVertexBufferBinding");
  1835.             }
  1836.         }
  1837.  
  1838.         mLastVertexSourceCount = binds.size();     
  1839.     }
  1840.  
  1841.     //---------------------------------------------------------------------
  1842.     // TODO: Move this class to the right place.
  1843.     class D3D11RenderOperationState : public Renderable::RenderSystemData
  1844.     {
  1845.     public:
  1846.         ID3D11BlendState * mBlendState;
  1847.         ID3D11RasterizerState * mRasterizer;
  1848.         ID3D11DepthStencilState * mDepthStencilState;
  1849.  
  1850.         ID3D11SamplerState * mSamplerStates[OGRE_MAX_TEXTURE_LAYERS];
  1851.         size_t mSamplerStatesCount;
  1852.  
  1853.         ID3D11ShaderResourceView * mTextures[OGRE_MAX_TEXTURE_LAYERS];
  1854.         size_t mTexturesCount;
  1855.  
  1856.         D3D11RenderOperationState() :
  1857.               mBlendState(NULL)
  1858.             , mRasterizer(NULL)
  1859.             , mDepthStencilState(NULL)
  1860.             , mSamplerStatesCount(0)
  1861.             , mTexturesCount(0)
  1862.         {
  1863.             for (size_t i = 0 ; i < OGRE_MAX_TEXTURE_LAYERS ; i++)
  1864.             {
  1865.                 mSamplerStates[i] = 0;
  1866.             }
  1867.         }
  1868.  
  1869.  
  1870.         ~D3D11RenderOperationState()
  1871.         {
  1872.             SAFE_RELEASE( mBlendState );
  1873.             SAFE_RELEASE( mRasterizer );
  1874.             SAFE_RELEASE( mDepthStencilState );
  1875.  
  1876.             for (size_t i = 0 ; i < OGRE_MAX_TEXTURE_LAYERS ; i++)
  1877.             {
  1878.                 SAFE_RELEASE( mSamplerStates[i] );
  1879.             }
  1880.         }
  1881.     };
  1882.  
  1883.     //---------------------------------------------------------------------
  1884.     void D3D11RenderSystem::_render(const RenderOperation& op)
  1885.     {
  1886.  
  1887.         // Exit immediately if there is nothing to render
  1888.         if (op.vertexData==0 || op.vertexData->vertexCount == 0)
  1889.         {
  1890.             return;
  1891.         }
  1892.  
  1893.         HardwareVertexBufferSharedPtr globalInstanceVertexBuffer = getGlobalInstanceVertexBuffer();
  1894.         VertexDeclaration* globalVertexDeclaration = getGlobalInstanceVertexBufferVertexDeclaration();
  1895.  
  1896.         bool hasInstanceData = op.useGlobalInstancingVertexBufferIsAvailable &&
  1897.                     !globalInstanceVertexBuffer.isNull() && globalVertexDeclaration != NULL
  1898.                 || op.vertexData->vertexBufferBinding->getHasInstanceData();
  1899.  
  1900.         size_t numberOfInstances = op.numberOfInstances;
  1901.  
  1902.         if (op.useGlobalInstancingVertexBufferIsAvailable)
  1903.         {
  1904.             numberOfInstances *= getGlobalNumberOfInstances();
  1905.         }
  1906.  
  1907.         // Call super class
  1908.         RenderSystem::_render(op);
  1909.        
  1910.         D3D11RenderOperationState stackOpState;
  1911.         D3D11RenderOperationState * opState = &stackOpState;
  1912.  
  1913.         //if(!opState)
  1914.         {
  1915.             //opState = new D3D11RenderOperationState;
  1916.  
  1917.             HRESULT hr = mDevice->CreateBlendState(&mBlendDesc, &opState->mBlendState) ;
  1918.             if (FAILED(hr))
  1919.             {
  1920.                 String errorDescription = mDevice.getErrorDescription();
  1921.                 OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  1922.                     "Failed to create blend state\nError Description:" + errorDescription,
  1923.                     "D3D11RenderSystem::_render" );
  1924.             }
  1925.  
  1926.             hr = mDevice->CreateRasterizerState(&mRasterizerDesc, &opState->mRasterizer) ;
  1927.             if (FAILED(hr))
  1928.             {
  1929.                 String errorDescription = mDevice.getErrorDescription();
  1930.                 OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  1931.                     "Failed to create rasterizer state\nError Description:" + errorDescription,
  1932.                     "D3D11RenderSystem::_render" );
  1933.             }
  1934.  
  1935.             hr = mDevice->CreateDepthStencilState(&mDepthStencilDesc, &opState->mDepthStencilState) ;
  1936.             if (FAILED(hr))
  1937.             {
  1938.                 String errorDescription = mDevice.getErrorDescription();
  1939.                 OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  1940.                     "Failed to create depth stencil state\nError Description:" + errorDescription,
  1941.                     "D3D11RenderSystem::_render" );
  1942.             }
  1943.  
  1944.             // samplers mapping
  1945.             size_t numberOfSamplers = 0;
  1946.             opState->mTexturesCount = 0;
  1947.  
  1948.             for (size_t n = 0; n < OGRE_MAX_TEXTURE_LAYERS; n++)
  1949.             {
  1950.                 sD3DTextureStageDesc & stage = mTexStageDesc[n];
  1951.                 if(!stage.used)
  1952.                 {
  1953.                     break;
  1954.                 }
  1955.  
  1956.                 numberOfSamplers++;
  1957.  
  1958.                 ID3D11ShaderResourceView * texture;
  1959.                 texture = stage.pTex;
  1960.                 opState->mTextures[opState->mTexturesCount] = texture;
  1961.                 opState->mTexturesCount++;
  1962.  
  1963.                 stage.samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
  1964.                 stage.currentSamplerDesc = stage.samplerDesc;
  1965.  
  1966.                 ID3D11SamplerState * samplerState;
  1967.  
  1968.                 HRESULT hr = mDevice->CreateSamplerState(&stage.samplerDesc, &samplerState) ;
  1969.                 if (FAILED(hr))
  1970.                 {
  1971.                     String errorDescription = mDevice.getErrorDescription();
  1972.                     OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  1973.                         "Failed to create sampler state\nError Description:" + errorDescription,
  1974.                         "D3D11RenderSystem::_render" );
  1975.                 }
  1976.                 opState->mSamplerStates[n] = (samplerState);       
  1977.             }
  1978.             opState->mSamplerStatesCount = numberOfSamplers;
  1979.         }
  1980.  
  1981.         //if (opState->mBlendState != mBoundBlendState)
  1982.         {
  1983.             mBoundBlendState = opState->mBlendState ;
  1984.             mDevice.GetImmediateContext()->OMSetBlendState(opState->mBlendState, 0, 0xffffffff); // TODO - find out where to get the parameters
  1985.             if (mDevice.isError())
  1986.             {
  1987.                 String errorDescription = mDevice.getErrorDescription();
  1988.                 OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  1989.                     "D3D11 device cannot set blend state\nError Description:" + errorDescription,
  1990.                     "D3D11RenderSystem::_render");
  1991.             }
  1992.             // PPP: TO DO. Must bind only if the Geometry shader expects this
  1993.             if (mBoundGeometryProgram)
  1994.             {
  1995.                 {
  1996.                     mDevice.GetImmediateContext()->GSSetSamplers(static_cast<UINT>(0), static_cast<UINT>(opState->mSamplerStatesCount), opState->mSamplerStates);
  1997.                     if (mDevice.isError())
  1998.                     {
  1999.                         String errorDescription = mDevice.getErrorDescription();
  2000.                         OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2001.                             "D3D11 device cannot set pixel shader samplers\nError Description:" + errorDescription,
  2002.                             "D3D11RenderSystem::_render");
  2003.                     }
  2004.                 }
  2005.                 mDevice.GetImmediateContext()->GSSetShaderResources(static_cast<UINT>(0), static_cast<UINT>(opState->mTexturesCount), &opState->mTextures[0]);
  2006.                 if (mDevice.isError())
  2007.                 {
  2008.                     String errorDescription = mDevice.getErrorDescription();
  2009.                     OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2010.                         "D3D11 device cannot set pixel shader resources\nError Description:" + errorDescription,
  2011.                         "D3D11RenderSystem::_render");
  2012.                 }
  2013.             }
  2014.         }
  2015.  
  2016.  
  2017.  
  2018.         //if (opState->mRasterizer != mBoundRasterizer)
  2019.         {
  2020.             mBoundRasterizer = opState->mRasterizer ;
  2021.  
  2022.             mDevice.GetImmediateContext()->RSSetState(opState->mRasterizer);
  2023.             if (mDevice.isError())
  2024.             {
  2025.                 String errorDescription = mDevice.getErrorDescription();
  2026.                 OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2027.                     "D3D11 device cannot set rasterizer state\nError Description:" + errorDescription,
  2028.                     "D3D11RenderSystem::_render");
  2029.             }
  2030.         }
  2031.        
  2032.  
  2033.         //if (opState->mDepthStencilState != mBoundDepthStencilState)
  2034.         {
  2035.             mBoundDepthStencilState = opState->mDepthStencilState ;
  2036.  
  2037.             mDevice.GetImmediateContext()->OMSetDepthStencilState(opState->mDepthStencilState, mStencilRef);
  2038.             if (mDevice.isError())
  2039.             {
  2040.                 String errorDescription = mDevice.getErrorDescription();
  2041.                 OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2042.                     "D3D11 device cannot set depth stencil state\nError Description:" + errorDescription,
  2043.                     "D3D11RenderSystem::_render");
  2044.             }
  2045.         }
  2046.  
  2047.         if (opState->mSamplerStatesCount > 0 ) //  if the NumSamplers is 0, the operation effectively does nothing.
  2048.         {
  2049.             // Assaf: seem I have better performance without this check... TODO - remove?
  2050.         //  // if ((mBoundSamplerStatesCount != opState->mSamplerStatesCount) || ( 0 != memcmp(opState->mSamplerStates, mBoundSamplerStates, mBoundSamplerStatesCount) ) )
  2051.             {
  2052.                 //mBoundSamplerStatesCount = opState->mSamplerStatesCount;
  2053.                 //memcpy(mBoundSamplerStates,opState->mSamplerStates, mBoundSamplerStatesCount);
  2054.                 mDevice.GetImmediateContext()->PSSetSamplers(static_cast<UINT>(0), static_cast<UINT>(opState->mSamplerStatesCount), opState->mSamplerStates);
  2055.                 if (mDevice.isError())
  2056.                 {
  2057.                     String errorDescription = mDevice.getErrorDescription();
  2058.                     OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2059.                         "D3D11 device cannot set pixel shader samplers\nError Description:" + errorDescription,
  2060.                         "D3D11RenderSystem::_render");
  2061.                 }
  2062.  
  2063.  
  2064.             }
  2065.             mDevice.GetImmediateContext()->PSSetShaderResources(static_cast<UINT>(0), static_cast<UINT>(opState->mTexturesCount), &opState->mTextures[0]);
  2066.             if (mDevice.isError())
  2067.             {
  2068.                 String errorDescription = mDevice.getErrorDescription();
  2069.                 OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2070.                     "D3D11 device cannot set pixel shader resources\nError Description:" + errorDescription,
  2071.                     "D3D11RenderSystem::_render");
  2072.             }
  2073.         }
  2074.  
  2075.         ID3D11Buffer* pSOTarget=0;
  2076.         // Mustn't bind a emulated vertex, pixel shader (see below), if we are rendering to a stream out buffer
  2077.         mDevice.GetImmediateContext()->SOGetTargets(1, &pSOTarget);
  2078.  
  2079.         if (!mBoundVertexProgram ||
  2080.              (!mBoundFragmentProgram && op.operationType != RenderOperation::OT_POINT_LIST && pSOTarget==0 )
  2081.            )
  2082.         {
  2083.            
  2084.             OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2085.                 "Attempted to render to a D3D11 device without both vertex and fragment shaders there is no fixed pipeline in d3d11 - use the RTSS or write custom shaders.",
  2086.                 "D3D11RenderSystem::_render");
  2087.         }
  2088.  
  2089.         if (mDevice.isError())
  2090.         {
  2091.             // this will never happen but we want to be consistent with the error checks...
  2092.             String errorDescription = mDevice.getErrorDescription();
  2093.             OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2094.                 "D3D11 device cannot set geometry shader to null\nError Description:" + errorDescription,
  2095.                 "D3D11RenderSystem::_render");
  2096.         }
  2097.  
  2098.         setVertexDeclaration(op.vertexData->vertexDeclaration, op.vertexData->vertexBufferBinding);
  2099.         setVertexBufferBinding(op.vertexData->vertexBufferBinding);
  2100.  
  2101.  
  2102.         // Determine rendering operation
  2103.         D3D11_PRIMITIVE_TOPOLOGY primType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
  2104.         DWORD primCount = 0;
  2105.         bool useAdjacency = (mGeometryProgramBound && mBoundGeometryProgram && mBoundGeometryProgram->isAdjacencyInfoRequired());
  2106.         switch( op.operationType )
  2107.         {
  2108.         case RenderOperation::OT_POINT_LIST:
  2109.             primType = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;
  2110.             primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount);
  2111.             break;
  2112.  
  2113.         case RenderOperation::OT_LINE_LIST:
  2114.             primType = useAdjacency ? D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ : D3D11_PRIMITIVE_TOPOLOGY_LINELIST;
  2115.             primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) / 2;
  2116.             break;
  2117.  
  2118.         case RenderOperation::OT_LINE_STRIP:
  2119.             primType = useAdjacency ? D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ : D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP;
  2120.             primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 1;
  2121.             break;
  2122.  
  2123.         case RenderOperation::OT_TRIANGLE_LIST:
  2124.             primType = useAdjacency ? D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ : D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
  2125.             primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) / 3;
  2126.             break;
  2127.  
  2128.         case RenderOperation::OT_TRIANGLE_STRIP:
  2129.             primType = useAdjacency ? D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ : D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
  2130.             primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 2;
  2131.             break;
  2132.  
  2133.         case RenderOperation::OT_TRIANGLE_FAN:
  2134.             OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error - DX11 render - no support for triangle fan (OT_TRIANGLE_FAN)", "D3D11RenderSystem::_render");
  2135.             primType = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; // todo - no TRIANGLE_FAN in DX 11
  2136.             primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 2;
  2137.             break;
  2138.         }
  2139.  
  2140.         if (primCount)
  2141.         {
  2142.             // Issue the op
  2143.             //HRESULT hr;
  2144.             if( op.useIndexes  )
  2145.             {
  2146.                 D3D11HardwareIndexBuffer* d3dIdxBuf =
  2147.                     static_cast<D3D11HardwareIndexBuffer*>(op.indexData->indexBuffer.get());
  2148.                 mDevice.GetImmediateContext()->IASetIndexBuffer( d3dIdxBuf->getD3DIndexBuffer(), D3D11Mappings::getFormat(d3dIdxBuf->getType()), 0 );
  2149.                 if (mDevice.isError())
  2150.                 {
  2151.                     String errorDescription = mDevice.getErrorDescription();
  2152.                     OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2153.                         "D3D11 device cannot set index buffer\nError Description:" + errorDescription,
  2154.                         "D3D11RenderSystem::_render");
  2155.                 }
  2156.  
  2157.                 do
  2158.                 {
  2159.                     // do indexed draw operation
  2160.                     mDevice.GetImmediateContext()->IASetPrimitiveTopology( primType );
  2161.                     if (mDevice.isError())
  2162.                     {
  2163.                         String errorDescription = mDevice.getErrorDescription();
  2164.                         OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2165.                             "D3D11 device cannot set primitive topology\nError Description:" + errorDescription,
  2166.                             "D3D11RenderSystem::_render");
  2167.                     }
  2168.                    
  2169.                     if (hasInstanceData)
  2170.                     {
  2171.                         mDevice.GetImmediateContext()->DrawIndexedInstanced(    
  2172.                             static_cast<UINT>(op.indexData->indexCount),
  2173.                             static_cast<UINT>(numberOfInstances),
  2174.                             static_cast<UINT>(op.indexData->indexStart),
  2175.                             static_cast<INT>(op.vertexData->vertexStart),
  2176.                             0
  2177.                             );
  2178.                         if (mDevice.isError())
  2179.                         {
  2180.                             String errorDescription = mDevice.getErrorDescription();
  2181.                             OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2182.                                 "D3D11 device cannot draw indexed instanced\nError Description:" + errorDescription,
  2183.                                 "D3D11RenderSystem::_render");
  2184.                         }
  2185.                     }
  2186.                     else
  2187.                     {
  2188.                         mDevice.GetImmediateContext()->DrawIndexed(    
  2189.                             static_cast<UINT>(op.indexData->indexCount),
  2190.                             static_cast<UINT>(op.indexData->indexStart),
  2191.                             static_cast<INT>(op.vertexData->vertexStart)
  2192.                             );
  2193.                         if (mDevice.isError())
  2194.                         {
  2195.                             String errorDescription = mDevice.getErrorDescription();
  2196.                             OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2197.                                 "D3D11 device cannot draw indexed\nError Description:" + errorDescription,
  2198.                                 "D3D11RenderSystem::_render");
  2199.                         }
  2200.                     }
  2201.                 } while (updatePassIterationRenderState());
  2202.             }
  2203.             else
  2204.             {
  2205.                 // nfz: gpu_iterate
  2206.                 do
  2207.                 {
  2208.                     // Unindexed, a little simpler!
  2209.                     mDevice.GetImmediateContext()->IASetPrimitiveTopology( primType );
  2210.                     if (mDevice.isError())
  2211.                     {
  2212.                         String errorDescription = mDevice.getErrorDescription();
  2213.                         OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2214.                             "D3D11 device cannot set primitive topology\nError Description:" + errorDescription,
  2215.                             "D3D11RenderSystem::_render");
  2216.                     }      
  2217.                    
  2218.                     if (op.vertexData->vertexCount == -1) // -1 is a sign to use DrawAuto
  2219.                     {
  2220.                         mDevice.GetImmediateContext()->DrawAuto();
  2221.                     }
  2222.                     else
  2223.                     {
  2224.                         if (hasInstanceData)
  2225.                         {
  2226.                             mDevice.GetImmediateContext()->DrawInstanced(
  2227.                                 static_cast<UINT>(numberOfInstances),
  2228.                                 static_cast<UINT>(op.vertexData->vertexCount),
  2229.                                 static_cast<INT>(op.vertexData->vertexStart),
  2230.                                 0
  2231.                                 );
  2232.                         }
  2233.                         else
  2234.                         {
  2235.                             mDevice.GetImmediateContext()->Draw(
  2236.                                 static_cast<UINT>(op.vertexData->vertexCount),
  2237.                                 static_cast<INT>(op.vertexData->vertexStart)
  2238.                                 );
  2239.                         }
  2240.                     }
  2241.                     if (mDevice.isError())
  2242.                     {
  2243.                         String errorDescription = mDevice.getErrorDescription();
  2244.                         OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2245.                             "D3D11 device cannot draw\nError Description:" + errorDescription,
  2246.                             "D3D11RenderSystem::_render");
  2247.                     }      
  2248.  
  2249.  
  2250.                 } while (updatePassIterationRenderState());
  2251.             }
  2252.  
  2253.         }
  2254.  
  2255.  
  2256.         if (true) // for now - clear the render state
  2257.         {
  2258.             mDevice.GetImmediateContext()->OMSetBlendState(0, 0, 0xffffffff);
  2259.             mDevice.GetImmediateContext()->RSSetState(0);
  2260.             mDevice.GetImmediateContext()->OMSetDepthStencilState(0, 0);
  2261. //          mDevice->PSSetSamplers(static_cast<UINT>(0), static_cast<UINT>(0), 0);
  2262.             //delete opState;
  2263.         }
  2264.  
  2265.  
  2266.     }
  2267.     //---------------------------------------------------------------------
  2268.     void D3D11RenderSystem::setNormaliseNormals(bool normalise)
  2269.     {
  2270.     }
  2271.     //---------------------------------------------------------------------
  2272.     void D3D11RenderSystem::bindGpuProgram(GpuProgram* prg)
  2273.     {
  2274.         if (!prg)
  2275.         {
  2276.             OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2277.                 "Null program bound.",
  2278.                 "D3D11RenderSystem::bindGpuProgram");
  2279.         }
  2280.  
  2281.         switch (prg->getType())
  2282.         {
  2283.         case GPT_VERTEX_PROGRAM:
  2284.             {
  2285.                 // get the shader
  2286.                 mBoundVertexProgram = static_cast<D3D11HLSLProgram*>(prg);
  2287.                 ID3D11VertexShader * vsShaderToSet = mBoundVertexProgram->getVertexShader();
  2288.  
  2289.                 // set the shader
  2290.                 mDevice.GetImmediateContext()->VSSetShader(vsShaderToSet, NULL, 0);
  2291.                 if (mDevice.isError())
  2292.                 {
  2293.                     String errorDescription = mDevice.getErrorDescription();
  2294.                     OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2295.                         "D3D11 device cannot set vertex shader\nError Description:" + errorDescription,
  2296.                         "D3D11RenderSystem::bindGpuProgram");
  2297.                 }      
  2298.             }
  2299.             break;
  2300.         case GPT_FRAGMENT_PROGRAM:
  2301.             {
  2302.                 mBoundFragmentProgram = static_cast<D3D11HLSLProgram*>(prg);
  2303.                 ID3D11PixelShader* psShaderToSet = mBoundFragmentProgram->getPixelShader();
  2304.  
  2305.                 mDevice.GetImmediateContext()->PSSetShader(psShaderToSet, NULL, 0);
  2306.                 if (mDevice.isError())
  2307.                 {
  2308.                     String errorDescription = mDevice.getErrorDescription();
  2309.                     OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2310.                         "D3D11 device cannot set fragment shader\nError Description:" + errorDescription,
  2311.                         "D3D11RenderSystem::bindGpuProgram");
  2312.                 }      
  2313.             }
  2314.             break;
  2315.         case GPT_GEOMETRY_PROGRAM:
  2316.             {
  2317.                 mBoundGeometryProgram = static_cast<D3D11HLSLProgram*>(prg);
  2318.                 ID3D11GeometryShader* gsShaderToSet = mBoundGeometryProgram->getGeometryShader();
  2319.  
  2320.                 mDevice.GetImmediateContext()->GSSetShader(gsShaderToSet, NULL, 0);
  2321.                 if (mDevice.isError())
  2322.                 {
  2323.                     String errorDescription = mDevice.getErrorDescription();
  2324.                     OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2325.                         "D3D11 device cannot set geometry shader\nError Description:" + errorDescription,
  2326.                         "D3D11RenderSystem::bindGpuProgram");
  2327.                 }      
  2328.  
  2329.             }
  2330.             break;
  2331.         };
  2332.  
  2333.         RenderSystem::bindGpuProgram(prg);
  2334.    }
  2335.     //---------------------------------------------------------------------
  2336.     void D3D11RenderSystem::unbindGpuProgram(GpuProgramType gptype)
  2337.     {
  2338.  
  2339.         switch(gptype)
  2340.         {
  2341.         case GPT_VERTEX_PROGRAM:
  2342.             {
  2343.                 mActiveVertexGpuProgramParameters.setNull();
  2344.                 mBoundVertexProgram = NULL;
  2345.                 //mDevice->VSSetShader(NULL);
  2346.                 mDevice.GetImmediateContext()->VSSetShader(NULL, NULL, 0);
  2347.             }
  2348.             break;
  2349.         case GPT_FRAGMENT_PROGRAM:
  2350.             {
  2351.                 mActiveFragmentGpuProgramParameters.setNull();
  2352.                 mBoundFragmentProgram = NULL;
  2353.                 //mDevice->PSSetShader(NULL);
  2354.                 mDevice.GetImmediateContext()->PSSetShader(NULL, NULL, 0);
  2355.             }
  2356.  
  2357.             break;
  2358.         case GPT_GEOMETRY_PROGRAM:
  2359.             {
  2360.                 mActiveGeometryGpuProgramParameters.setNull();
  2361.                 mBoundGeometryProgram = NULL;
  2362.                 mDevice.GetImmediateContext()->GSSetShader( NULL, NULL, 0 );
  2363.             }
  2364.             break;
  2365.         default:
  2366.             assert(false && "Undefined Program Type!");
  2367.         };
  2368.         RenderSystem::unbindGpuProgram(gptype);
  2369.     }
  2370.     //---------------------------------------------------------------------
  2371.     void D3D11RenderSystem::bindGpuProgramParameters(GpuProgramType gptype, GpuProgramParametersSharedPtr params, uint16 mask)
  2372.     {
  2373.         if (mask & (uint16)GPV_GLOBAL)
  2374.         {
  2375.             // TODO: Dx11 supports shared constant buffers, so use them
  2376.             // check the match to constant buffers & use rendersystem data hooks to store
  2377.             // for now, just copy
  2378.             params->_copySharedParams();
  2379.         }
  2380.  
  2381.         // Do everything here in Dx11, since deal with via buffers anyway so number of calls
  2382.         // is actually the same whether we categorise the updates or not
  2383.         ID3D11Buffer* pBuffers[1] ;
  2384.         switch(gptype)
  2385.         {
  2386.         case GPT_VERTEX_PROGRAM:
  2387.             {
  2388.                 //  if (params->getAutoConstantCount() > 0)
  2389.                 //{
  2390.                 if (mBoundVertexProgram)
  2391.                 {
  2392.                     pBuffers[0] = mBoundVertexProgram->getConstantBuffer(params, mask);
  2393.                     mDevice.GetImmediateContext()->VSSetConstantBuffers( 0, 1, pBuffers );
  2394.                     if (mDevice.isError())
  2395.                     {
  2396.                         String errorDescription = mDevice.getErrorDescription();
  2397.                         OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2398.                             "D3D11 device cannot set vertex shader constant buffers\nError Description:" + errorDescription,
  2399.                             "D3D11RenderSystem::bindGpuProgramParameters");
  2400.                     }      
  2401.  
  2402.                 }
  2403.             }
  2404.             break;
  2405.         case GPT_FRAGMENT_PROGRAM:
  2406.             {
  2407.                 //if (params->getAutoConstantCount() > 0)
  2408.                 //{
  2409.                 if (mBoundFragmentProgram)
  2410.                 {
  2411.                     pBuffers[0] = mBoundFragmentProgram->getConstantBuffer(params, mask);
  2412.                     mDevice.GetImmediateContext()->PSSetConstantBuffers( 0, 1, pBuffers );
  2413.                     if (mDevice.isError())
  2414.                     {
  2415.                         String errorDescription = mDevice.getErrorDescription();
  2416.                         OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2417.                             "D3D11 device cannot set fragment shader constant buffers\nError Description:" + errorDescription,
  2418.                             "D3D11RenderSystem::bindGpuProgramParameters");
  2419.                     }      
  2420.  
  2421.                 }
  2422.             }
  2423.             break;
  2424.         case GPT_GEOMETRY_PROGRAM:
  2425.             {
  2426.                 if (mBoundGeometryProgram)
  2427.                 {
  2428.                     pBuffers[0] = mBoundGeometryProgram->getConstantBuffer(params, mask);
  2429.                     mDevice.GetImmediateContext()->GSSetConstantBuffers( 0, 1, pBuffers );
  2430.                     if (mDevice.isError())
  2431.                     {
  2432.                         String errorDescription = mDevice.getErrorDescription();
  2433.                         OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2434.                             "D3D11 device cannot set Geometry shader constant buffers\nError Description:" + errorDescription,
  2435.                             "D3D11RenderSystem::bindGpuProgramParameters");
  2436.                     }      
  2437.  
  2438.                 }
  2439.             }
  2440.             break;
  2441.  
  2442.         };
  2443.     }
  2444.     //---------------------------------------------------------------------
  2445.     void D3D11RenderSystem::bindGpuProgramPassIterationParameters(GpuProgramType gptype)
  2446.     {
  2447.  
  2448.         switch(gptype)
  2449.         {
  2450.         case GPT_VERTEX_PROGRAM:
  2451.             bindGpuProgramParameters(gptype, mActiveVertexGpuProgramParameters, (uint16)GPV_PASS_ITERATION_NUMBER);
  2452.             break;
  2453.  
  2454.         case GPT_FRAGMENT_PROGRAM:
  2455.             bindGpuProgramParameters(gptype, mActiveFragmentGpuProgramParameters, (uint16)GPV_PASS_ITERATION_NUMBER);
  2456.             break;
  2457.         case GPT_GEOMETRY_PROGRAM:
  2458.             bindGpuProgramParameters(gptype, mActiveGeometryGpuProgramParameters, (uint16)GPV_PASS_ITERATION_NUMBER);
  2459.             break;
  2460.  
  2461.         }
  2462.     }
  2463.     //---------------------------------------------------------------------
  2464.     void D3D11RenderSystem::setClipPlanesImpl(const PlaneList& clipPlanes)
  2465.     {
  2466.     }
  2467.     //---------------------------------------------------------------------
  2468.     void D3D11RenderSystem::setScissorTest(bool enabled, size_t left, size_t top, size_t right,
  2469.         size_t bottom)
  2470.     {
  2471.         mRasterizerDesc.ScissorEnable = enabled;
  2472.         mScissorRect.left = static_cast<LONG>(left);
  2473.         mScissorRect.top = static_cast<LONG>(top);
  2474.         mScissorRect.right = static_cast<LONG>(right);
  2475.         mScissorRect.bottom =static_cast<LONG>( bottom);
  2476.  
  2477.         mDevice.GetImmediateContext()->RSSetScissorRects(1, &mScissorRect);
  2478.         if (mDevice.isError())
  2479.         {
  2480.             String errorDescription = mDevice.getErrorDescription();
  2481.             OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  2482.                 "D3D11 device cannot set scissor rects\nError Description:" + errorDescription,
  2483.                 "D3D11RenderSystem::setScissorTest");
  2484.         }  
  2485.     }
  2486.     //---------------------------------------------------------------------
  2487.     void D3D11RenderSystem::clearFrameBuffer(unsigned int buffers,
  2488.         const ColourValue& colour, Real depth, unsigned short stencil)
  2489.     {
  2490.         if (mActiveRenderTarget)
  2491.         {
  2492.             ID3D11RenderTargetView * pRTView[OGRE_MAX_MULTIPLE_RENDER_TARGETS];
  2493.             memset(pRTView, 0, sizeof(pRTView));
  2494.  
  2495.             mActiveRenderTarget->getCustomAttribute( "ID3D11RenderTargetView", &pRTView );
  2496.  
  2497.             uint count = 0;
  2498.             while(pRTView[count] != NULL)
  2499.             {
  2500.                 if (buffers & FBT_COLOUR)
  2501.                 {
  2502.                     float ClearColor[4];
  2503.                     D3D11Mappings::get(colour, ClearColor);
  2504.                     mDevice.GetImmediateContext()->ClearRenderTargetView( pRTView[count], ClearColor );
  2505.                 }
  2506.                 count++;
  2507.             }
  2508.             UINT ClearFlags = 0;
  2509.             if (buffers & FBT_DEPTH)
  2510.             {
  2511.                 ClearFlags |= D3D11_CLEAR_DEPTH;
  2512.             }
  2513.             if (buffers & FBT_STENCIL)
  2514.             {
  2515.                 ClearFlags |= D3D11_CLEAR_STENCIL;
  2516.             }
  2517.  
  2518.             if (ClearFlags)
  2519.             {
  2520.                 D3D11DepthBuffer *depthBuffer = static_cast<D3D11DepthBuffer*>(mActiveRenderTarget->
  2521.                                                                                         getDepthBuffer());
  2522.                 if( depthBuffer )
  2523.                 {
  2524.                     mDevice.GetImmediateContext()->ClearDepthStencilView(
  2525.                                                         depthBuffer->getDepthStencilView(),
  2526.                                                         ClearFlags, depth, static_cast<UINT8>(stencil) );
  2527.                 }
  2528.             }
  2529.         }
  2530.     }
  2531.     //---------------------------------------------------------------------
  2532.     void D3D11RenderSystem::_makeProjectionMatrix(Real left, Real right,
  2533.         Real bottom, Real top, Real nearPlane, Real farPlane, Matrix4& dest,
  2534.         bool forGpuProgram)
  2535.     {
  2536.         // Correct position for off-axis projection matrix
  2537.         if (!forGpuProgram)
  2538.         {
  2539.             Real offsetX = left + right;
  2540.             Real offsetY = top + bottom;
  2541.  
  2542.             left -= offsetX;
  2543.             right -= offsetX;
  2544.             top -= offsetY;
  2545.             bottom -= offsetY;
  2546.         }
  2547.  
  2548.         Real width = right - left;
  2549.         Real height = top - bottom;
  2550.         Real q, qn;
  2551.         if (farPlane == 0)
  2552.         {
  2553.             q = 1 - Frustum::INFINITE_FAR_PLANE_ADJUST;
  2554.             qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 1);
  2555.         }
  2556.         else
  2557.         {
  2558.             q = farPlane / ( farPlane - nearPlane );
  2559.             qn = -q * nearPlane;
  2560.         }
  2561.         dest = Matrix4::ZERO;
  2562.         dest[0][0] = 2 * nearPlane / width;
  2563.         dest[0][2] = (right+left) / width;
  2564.         dest[1][1] = 2 * nearPlane / height;
  2565.         dest[1][2] = (top+bottom) / height;
  2566.         if (forGpuProgram)
  2567.         {
  2568.             dest[2][2] = -q;
  2569.             dest[3][2] = -1.0f;
  2570.         }
  2571.         else
  2572.         {
  2573.             dest[2][2] = q;
  2574.             dest[3][2] = 1.0f;
  2575.         }
  2576.         dest[2][3] = qn;
  2577.     }
  2578.  
  2579.     // ------------------------------------------------------------------
  2580.     void D3D11RenderSystem::setClipPlane (ushort index, Real A, Real B, Real C, Real D)
  2581.     {
  2582.     }
  2583.  
  2584.     // ------------------------------------------------------------------
  2585.     void D3D11RenderSystem::enableClipPlane (ushort index, bool enable)
  2586.     {
  2587.     }
  2588.     //---------------------------------------------------------------------
  2589.     HardwareOcclusionQuery* D3D11RenderSystem::createHardwareOcclusionQuery(void)
  2590.     {
  2591.         D3D11HardwareOcclusionQuery* ret = new D3D11HardwareOcclusionQuery (mDevice);
  2592.         mHwOcclusionQueries.push_back(ret);
  2593.         return ret;
  2594.     }
  2595.     //---------------------------------------------------------------------
  2596.     Real D3D11RenderSystem::getHorizontalTexelOffset(void)
  2597.     {
  2598.         // D3D11 is now like GL
  2599.         return 0.0f;
  2600.     }
  2601.     //---------------------------------------------------------------------
  2602.     Real D3D11RenderSystem::getVerticalTexelOffset(void)
  2603.     {
  2604.         // D3D11 is now like GL
  2605.         return 0.0f;
  2606.     }
  2607.     //---------------------------------------------------------------------
  2608.     void D3D11RenderSystem::_applyObliqueDepthProjection(Matrix4& matrix, const Plane& plane,
  2609.         bool forGpuProgram)
  2610.     {
  2611.         // Thanks to Eric Lenyel for posting this calculation at www.terathon.com
  2612.  
  2613.         // Calculate the clip-space corner point opposite the clipping plane
  2614.         // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
  2615.         // transform it into camera space by multiplying it
  2616.         // by the inverse of the projection matrix
  2617.  
  2618.         /* generalised version
  2619.         Vector4 q = matrix.inverse() *
  2620.             Vector4(Math::Sign(plane.normal.x), Math::Sign(plane.normal.y), 1.0f, 1.0f);
  2621.         */
  2622.         Vector4 q;
  2623.         q.x = Math::Sign(plane.normal.x) / matrix[0][0];
  2624.         q.y = Math::Sign(plane.normal.y) / matrix[1][1];
  2625.         q.z = 1.0F;
  2626.         // flip the next bit from Lengyel since we're right-handed
  2627.         if (forGpuProgram)
  2628.         {
  2629.             q.w = (1.0F - matrix[2][2]) / matrix[2][3];
  2630.         }
  2631.         else
  2632.         {
  2633.             q.w = (1.0F + matrix[2][2]) / matrix[2][3];
  2634.         }
  2635.  
  2636.         // Calculate the scaled plane vector
  2637.         Vector4 clipPlane4d(plane.normal.x, plane.normal.y, plane.normal.z, plane.d);
  2638.         Vector4 c = clipPlane4d * (1.0F / (clipPlane4d.dotProduct(q)));
  2639.  
  2640.         // Replace the third row of the projection matrix
  2641.         matrix[2][0] = c.x;
  2642.         matrix[2][1] = c.y;
  2643.         // flip the next bit from Lengyel since we're right-handed
  2644.         if (forGpuProgram)
  2645.         {
  2646.             matrix[2][2] = c.z;
  2647.         }
  2648.         else
  2649.         {
  2650.             matrix[2][2] = -c.z;
  2651.         }
  2652.         matrix[2][3] = c.w;        
  2653.     }
  2654.     //---------------------------------------------------------------------
  2655.     Real D3D11RenderSystem::getMinimumDepthInputValue(void)
  2656.     {
  2657.         // Range [0.0f, 1.0f]
  2658.         return 0.0f;
  2659.     }
  2660.     //---------------------------------------------------------------------
  2661.     Real D3D11RenderSystem::getMaximumDepthInputValue(void)
  2662.     {
  2663.         // Range [0.0f, 1.0f]
  2664.         // D3D inverts even identity view matrices, so maximum INPUT is -1.0
  2665.         return -1.0f;
  2666.     }
  2667.     //---------------------------------------------------------------------
  2668.     void D3D11RenderSystem::registerThread()
  2669.     {
  2670.         // nothing to do - D3D11 shares rendering context already
  2671.     }
  2672.     //---------------------------------------------------------------------
  2673.     void D3D11RenderSystem::unregisterThread()
  2674.     {
  2675.         // nothing to do - D3D11 shares rendering context already
  2676.     }
  2677.     //---------------------------------------------------------------------
  2678.     void D3D11RenderSystem::preExtraThreadsStarted()
  2679.     {
  2680.         // nothing to do - D3D11 shares rendering context already
  2681.     }
  2682.     //---------------------------------------------------------------------
  2683.     void D3D11RenderSystem::postExtraThreadsStarted()
  2684.     {
  2685.         // nothing to do - D3D11 shares rendering context already
  2686.     }
  2687.     //---------------------------------------------------------------------
  2688.     String D3D11RenderSystem::getErrorDescription( long errorNumber ) const
  2689.     {
  2690.         return mDevice.getErrorDescription(errorNumber);
  2691.     }
  2692.     //---------------------------------------------------------------------
  2693.     void D3D11RenderSystem::determineFSAASettings(uint fsaa, const String& fsaaHint,
  2694.         DXGI_FORMAT format, DXGI_SAMPLE_DESC* outFSAASettings)
  2695.     {
  2696.         bool ok = false;
  2697.         bool qualityHint = fsaaHint.find("Quality") != String::npos;
  2698.         size_t origFSAA = fsaa;
  2699.         bool tryCSAA = false;
  2700.         // NVIDIA, prefer CSAA if available for 8+
  2701.         // it would be tempting to use getCapabilities()->getVendor() == GPU_NVIDIA but
  2702.         // if this is the first window, caps will not be initialised yet
  2703.        
  2704.         if (mActiveD3DDriver->getAdapterIdentifier().VendorId == 0x10DE &&
  2705.             fsaa >= 8)
  2706.         {
  2707.             tryCSAA  = true;
  2708.         }
  2709.  
  2710.         while (!ok)
  2711.         {
  2712.             // Deal with special cases
  2713.             if (tryCSAA)
  2714.             {
  2715.                 // see http://developer.nvidia.com/object/coverage-sampled-aa.html
  2716.                 switch(fsaa)
  2717.                 {
  2718.                 case 8:
  2719.                     if (qualityHint)
  2720.                     {
  2721.                         outFSAASettings->Count = 8;
  2722.                         outFSAASettings->Quality = 8;
  2723.                     }
  2724.                     else
  2725.                     {
  2726.                         outFSAASettings->Count = 4;
  2727.                         outFSAASettings->Quality = 8;
  2728.                     }
  2729.                     break;
  2730.                 case 16:
  2731.                     if (qualityHint)
  2732.                     {
  2733.                         outFSAASettings->Count = 8;
  2734.                         outFSAASettings->Quality = 16;
  2735.                     }
  2736.                     else
  2737.                     {
  2738.                         outFSAASettings->Count = 4;
  2739.                         outFSAASettings->Quality = 16;
  2740.                     }
  2741.                     break;
  2742.                 }
  2743.             }
  2744.             else // !CSAA
  2745.             {
  2746.                 outFSAASettings->Count = fsaa == 0 ? 1 : fsaa;
  2747.                 outFSAASettings->Quality = 0;
  2748.             }
  2749.  
  2750.  
  2751.             HRESULT hr;
  2752.             UINT outQuality;
  2753.             hr = mDevice->CheckMultisampleQualityLevels(
  2754.                 format,
  2755.                 outFSAASettings->Count,
  2756.                 &outQuality);
  2757.  
  2758.             if (SUCCEEDED(hr) &&
  2759.                 (!tryCSAA || outQuality > outFSAASettings->Quality))
  2760.             {
  2761.                 ok = true;
  2762.             }
  2763.             else
  2764.             {
  2765.                 // downgrade
  2766.                 if (tryCSAA && fsaa == 8)
  2767.                 {
  2768.                     // for CSAA, we'll try downgrading with quality mode at all samples.
  2769.                     // then try without quality, then drop CSAA
  2770.                     if (qualityHint)
  2771.                     {
  2772.                         // drop quality first
  2773.                         qualityHint = false;
  2774.                     }
  2775.                     else
  2776.                     {
  2777.                         // drop CSAA entirely
  2778.                         tryCSAA = false;
  2779.                     }
  2780.                     // return to original requested samples
  2781.                     fsaa = static_cast<uint>(origFSAA);
  2782.                 }
  2783.                 else
  2784.                 {
  2785.                     // drop samples
  2786.                     --fsaa;
  2787.  
  2788.                     if (fsaa == 1)
  2789.                     {
  2790.                         // ran out of options, no FSAA
  2791.                         fsaa = 0;
  2792.                         ok = true;
  2793.                     }
  2794.                 }
  2795.             }
  2796.  
  2797.         } // while !ok
  2798.  
  2799.     }
  2800.     //---------------------------------------------------------------------
  2801.     void D3D11RenderSystem::initRenderSystem()
  2802.     {
  2803.         if (mRenderSystemWasInited)
  2804.         {
  2805.             return;
  2806.         }
  2807.  
  2808.         mRenderSystemWasInited = true;
  2809.         // set pointers to NULL
  2810.         mpDXGIFactory = NULL;
  2811.         HRESULT hr;
  2812.         hr = CreateDXGIFactory1( __uuidof(IDXGIFactory1), (void**)&mpDXGIFactory );
  2813.         if( FAILED(hr) )
  2814.         {
  2815.             OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR,
  2816.                 "Failed to create Direct3D11 DXGIFactory1",
  2817.                 "D3D11RenderSystem::D3D11RenderSystem" );
  2818.         }
  2819.  
  2820.         mDriverList = NULL;
  2821.         mActiveD3DDriver = NULL;
  2822.         mTextureManager = NULL;
  2823.         mHardwareBufferManager = NULL;
  2824.         mGpuProgramManager = NULL;
  2825.         mPrimaryWindow = NULL;
  2826.         mBasicStatesInitialised = false;
  2827.         mUseNVPerfHUD = false;
  2828.         mHLSLProgramFactory = NULL;
  2829.  
  2830.         mBoundVertexProgram = NULL;
  2831.         mBoundFragmentProgram = NULL;
  2832.         mBoundGeometryProgram = NULL;
  2833.  
  2834.         ZeroMemory( &mBlendDesc, sizeof(mBlendDesc));
  2835.  
  2836.         ZeroMemory( &mRasterizerDesc, sizeof(mRasterizerDesc));
  2837.         mRasterizerDesc.FrontCounterClockwise = true;
  2838.         mRasterizerDesc.DepthClipEnable = false;
  2839.         mRasterizerDesc.MultisampleEnable = true;
  2840.  
  2841.  
  2842.         ZeroMemory( &mDepthStencilDesc, sizeof(mDepthStencilDesc));
  2843.  
  2844.         ZeroMemory( &mDepthStencilDesc, sizeof(mDepthStencilDesc));
  2845.         ZeroMemory( &mScissorRect, sizeof(mScissorRect));
  2846.  
  2847.         for(size_t i = 0; i < OGRE_MAX_TEXTURE_LAYERS; ++i)
  2848.         {
  2849.             FilterMinification[i] = FO_NONE;
  2850.             FilterMagnification[i] = FO_NONE;
  2851.             FilterMips[i] = FO_NONE;
  2852.         }
  2853.         mPolygonMode = PM_SOLID;
  2854.  
  2855.         ZeroMemory(mTexStageDesc, OGRE_MAX_TEXTURE_LAYERS * sizeof(sD3DTextureStageDesc));
  2856.  
  2857.         UINT deviceFlags = 0;
  2858.         if (D3D11Device::D3D_NO_EXCEPTION != D3D11Device::getExceptionsErrorLevel() && OGRE_DEBUG_MODE)
  2859.         {
  2860.             deviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
  2861.         }
  2862.         if (!OGRE_THREAD_SUPPORT)
  2863.         {
  2864.             deviceFlags |= D3D11_CREATE_DEVICE_SINGLETHREADED;
  2865.         }
  2866.  
  2867.         ID3D11Device * device;
  2868.         hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE ,0,deviceFlags, NULL, 0, D3D11_SDK_VERSION, &device, 0 , 0);
  2869.  
  2870.         if(FAILED(hr))
  2871.         {
  2872.             std::stringstream error;
  2873.             error<<"Failed to create Direct3D11 object."<<std::endl<<DXGetErrorDescription(hr)<<std::endl;
  2874.  
  2875.             OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR,
  2876.                 "Failed to create Direct3D11 object",
  2877.                 "D3D11RenderSystem::D3D11RenderSystem" );
  2878.         }
  2879.  
  2880.         mDevice = D3D11Device(device) ;
  2881.  
  2882.  
  2883.         // set stages desc. to defaults
  2884.         for (size_t n = 0; n < OGRE_MAX_TEXTURE_LAYERS; n++)
  2885.         {
  2886.             mTexStageDesc[n].autoTexCoordType = TEXCALC_NONE;
  2887.             mTexStageDesc[n].coordIndex = 0;
  2888.             mTexStageDesc[n].pTex = 0;
  2889.         }
  2890.  
  2891.         mLastVertexSourceCount = 0;
  2892.     }
  2893.     //---------------------------------------------------------------------
  2894.     bool D3D11RenderSystem::_getDepthBufferCheckEnabled( void )
  2895.     {
  2896.         return mDepthStencilDesc.DepthEnable == TRUE;
  2897.     }
  2898.     //---------------------------------------------------------------------
  2899.     D3D11HLSLProgram* D3D11RenderSystem::_getBoundVertexProgram() const
  2900.     {
  2901.         return mBoundVertexProgram;
  2902.     }
  2903.     //---------------------------------------------------------------------
  2904.     D3D11HLSLProgram* D3D11RenderSystem::_getBoundFragmentProgram() const
  2905.     {
  2906.         return mBoundFragmentProgram;
  2907.     }
  2908.     //---------------------------------------------------------------------
  2909.     D3D11HLSLProgram* D3D11RenderSystem::_getBoundGeometryProgram() const
  2910.     {
  2911.         return mBoundGeometryProgram;
  2912.     }
  2913. }
  2914.  
  2915.