Advertisement

Slight Modifications to the Multithreaded Renderer in the DX11 SDK?

Started by July 18, 2017 06:19 AM
3 comments, last by 21st Century Moose 7 years, 6 months ago

My ultimate goal is to decouple the whole thing from the DXUT library...

What I see in this test app is a patch of flashy blue object, could be the mesh itself.

Could anyone please shed some lights on this?

Thanks

Jack


	 enum DEVICECONTEXT_TYPE
	{
    DEVICECONTEXT_IMMEDIATE,                // Traditional rendering, one thread, immediate device context
    DEVICECONTEXT_ST_DEFERRED_PER_SCENE,    // One thread, multiple deferred device contexts, one per scene
    DEVICECONTEXT_MT_DEFERRED_PER_SCENE,    // Multiple threads, one per scene, each with one deferred device context
    DEVICECONTEXT_ST_DEFERRED_PER_CHUNK,    // One thread, multiple deferred device contexts, one per physical processor
    DEVICECONTEXT_MT_DEFERRED_PER_CHUNK,    // Multiple threads, one per physical processor, each with one deferred device context
};
	DEVICECONTEXT_TYPE          g_iDeviceContextType = DEVICECONTEXT_IMMEDIATE;
	// The vertex for a corner of the mirror quad.  Only the Position is used.  
// The others are so we can use the same vertex shader as the main scene
struct MirrorVertex
{
    D3DXVECTOR3 Position;
    D3DXVECTOR3 Normal;
    D3DXVECTOR2 Texcoord;
    D3DXVECTOR3 Tangent;
};
typedef MirrorVertex MirrorRect[4];
	// By convention, the first n lights are shadow casting, and the rest just illuminate.
const int   g_iNumLights = 4;
const int   g_iNumShadows = 1;
const int   g_iNumMirrors = 4;
	// The different types of job in the per-chunk work queues
enum WorkQueueEntryType
{
    WORK_QUEUE_ENTRY_TYPE_SETUP,
    WORK_QUEUE_ENTRY_TYPE_CHUNK,
    WORK_QUEUE_ENTRY_TYPE_FINALIZE,
	    WORK_QUEUE_ENTRY_TYPE_COUNT
};
	// The contents of the work queues depend on the job type...
struct WorkQueueEntryBase
{
    WorkQueueEntryType          m_iType;
};
	// Work item params for scene setup
struct WorkQueueEntrySetup : public WorkQueueEntryBase
{
    const SceneParamsStatic*    m_pSceneParamsStatic;
    SceneParamsDynamic          m_SceneParamsDynamic;
};
	// Work item params for chunk render
struct WorkQueueEntryChunk : public WorkQueueEntryBase
{
    int                         m_iMesh;
};
	// Work item params for scene finalize
struct WorkQueueEntryFinalize : public WorkQueueEntryBase
{
};
	
// The work item queue for each per-chunk worker thread
const int                   g_iSceneQueueSizeInBytes = 16 * 1024;
typedef BYTE                ChunkQueue[g_iSceneQueueSizeInBytes];
	//--------------------------------------------------------------------------------------
// Constant buffers
//--------------------------------------------------------------------------------------
struct CB_VS_PER_OBJECT
{
    D3DXMATRIX m_mWorld;
};
UINT                        g_iCBVSPerObjectBind = 0;
	struct CB_VS_PER_SCENE
{
    D3DXMATRIX m_mViewProj;
};
UINT                        g_iCBVSPerSceneBind = 1;
	struct CB_PS_PER_OBJECT
{
    D3DXVECTOR4 m_vObjectColor;
};
UINT                        g_iCBPSPerObjectBind = 0;
	struct CB_PS_PER_LIGHT
{
    struct LightDataStruct
    {
        D3DXMATRIX  m_mLightViewProj;
        D3DXVECTOR4 m_vLightPos;
        D3DXVECTOR4 m_vLightDir;
        D3DXVECTOR4 m_vLightColor;
        D3DXVECTOR4 m_vFalloffs;    // x = dist end, y = dist range, z = cos angle end, w = cos range
    } m_LightData[g_iNumLights];
};
UINT                        g_iCBPSPerLightBind = 1;
	struct CB_PS_PER_SCENE
{
    D3DXPLANE m_vMirrorPlane;
    D3DXVECTOR4 m_vAmbientColor;
    D3DXVECTOR4 m_vTintColor;
};
UINT                        g_iCBPSPerSceneBind = 2;
	ID3D11Buffer*               g_pcbVSPerObject = NULL;
ID3D11Buffer*               g_pcbVSPerScene = NULL;
ID3D11Buffer*               g_pcbPSPerObject = NULL;
ID3D11Buffer*               g_pcbPSPerLight = NULL;
ID3D11Buffer*               g_pcbPSPerScene = NULL;
	 
	bool                        g_bClearStateUponBeginCommandList = false;
bool                        g_bClearStateUponFinishCommandList = false;
bool                        g_bClearStateUponExecuteCommandList = false;
 
unsigned int WINAPI         _PerSceneRenderDeferredProc( LPVOID lpParameter );
const int                   g_iNumPerSceneRenderThreads = 1;
HANDLE                      g_hPerSceneRenderDeferredThread[g_iNumPerSceneRenderThreads];
HANDLE                      g_hBeginPerSceneRenderDeferredEvent[g_iNumPerSceneRenderThreads];
HANDLE                      g_hEndPerSceneRenderDeferredEvent[g_iNumPerSceneRenderThreads];
ID3D11DeviceContext*        g_pd3dPerSceneDeferredContext[g_iNumPerSceneRenderThreads] = {NULL};
ID3D11CommandList*          g_pd3dPerSceneCommandList[g_iNumPerSceneRenderThreads] = {NULL};
int                         g_iPerSceneThreadInstanceData[g_iNumPerSceneRenderThreads];
	unsigned int WINAPI         _PerChunkRenderDeferredProc( LPVOID lpParameter );
const int                   g_iMaxPerChunkRenderThreads = 32;   // For true scalability, this should not be fixed at compile-time
const int                   g_iMaxPendingQueueEntries = 1024;     // Max value of g_hBeginPerChunkRenderDeferredSemaphore
int                         g_iNumPerChunkRenderThreads;    // One thread per physical processor, minus the main thread
HANDLE                      g_hPerChunkRenderDeferredThread[g_iMaxPerChunkRenderThreads];
HANDLE                      g_hBeginPerChunkRenderDeferredSemaphore[g_iMaxPerChunkRenderThreads];
HANDLE                      g_hEndPerChunkRenderDeferredEvent[g_iMaxPerChunkRenderThreads];
ID3D11DeviceContext*        g_pd3dPerChunkDeferredContext[g_iMaxPerChunkRenderThreads] = {NULL};
ID3D11CommandList*          g_pd3dPerChunkCommandList[g_iMaxPerChunkRenderThreads] = {NULL};
int                         g_iPerChunkThreadInstanceData[g_iMaxPerChunkRenderThreads];
ChunkQueue                  g_ChunkQueue[g_iMaxPerChunkRenderThreads];
int                         g_iPerChunkQueueOffset[g_iMaxPerChunkRenderThreads]; // next free portion of the queue to add an entry to
	bool                        g_bWireFrame = false;
	//--------------------------------------------------------------------------------------
// Default view parameters
//--------------------------------------------------------------------------------------
CModelViewerCamera          g_Camera;               // A model viewing camera
D3DXVECTOR3                 g_vDefaultEye           ( 30.0f, 150.0f, -150.0f );
D3DXVECTOR3                 g_vDefaultLookAt        ( 0.0f, 60.0f, 0.0f );
D3DXVECTOR3                 g_vUp                   ( 0.0f, 1.0f, 0.0f );
D3DXVECTOR3                 g_vDown                 = -g_vUp;
FLOAT                       g_fNearPlane            = 2.0f;
FLOAT                       g_fFarPlane             = 4000.0f;
FLOAT                       g_fFOV                  = D3DX_PI / 4.0f;
D3DXVECTOR3                 g_vSceneCenter          ( 0.0f, 350.0f, 0.0f );
FLOAT                       g_fSceneRadius          = 600.0f;
FLOAT                       g_fDefaultCameraRadius  = 300.0f;
FLOAT                       g_fMinCameraRadius      = 150.0f;
FLOAT                       g_fMaxCameraRadius      = 450.0f;
#ifdef RENDER_SCENE_LIGHT_POV
bool                        g_bRenderSceneLightPOV  = false;
#endif
	//--------------------------------------------------------------------------------------
// Lighting params (to be read from content when the pipeline supports it)
//--------------------------------------------------------------------------------------
D3DXVECTOR4                 g_vAmbientColor         ( 0.04f * 0.760f, 0.04f * 0.793f, 0.04f * 0.822f, 1.000f );
D3DXVECTOR4                 g_vMirrorTint           ( 0.3f, 0.5f, 1.0f, 1.0f );
D3DXVECTOR4                 g_vLightColor[g_iNumLights];
D3DXVECTOR3                 g_vLightPos[g_iNumLights];
D3DXVECTOR3                 g_vLightDir[g_iNumLights];
FLOAT                       g_fLightFalloffDistEnd[g_iNumLights];
FLOAT                       g_fLightFalloffDistRange[g_iNumLights];
FLOAT                       g_fLightFalloffCosAngleEnd[g_iNumLights];
FLOAT                       g_fLightFalloffCosAngleRange[g_iNumLights];
FLOAT                       g_fLightFOV[g_iNumLights];
FLOAT                       g_fLightAspect[g_iNumLights];
FLOAT                       g_fLightNearPlane[g_iNumLights];
FLOAT                       g_fLightFarPlane[g_iNumLights];
	// The scene data
CMultiDeviceContextDXUTMesh g_Mesh11;
	
//--------------------------------------------------------------------------------------
// Rendering interfaces
//--------------------------------------------------------------------------------------
ID3D11InputLayout*          g_pVertexLayout11 = NULL;
ID3D11VertexShader*         g_pVertexShader = NULL;
ID3D11PixelShader*          g_pPixelShader = NULL;
ID3D11SamplerState*         g_pSamPointClamp = NULL;
ID3D11SamplerState*         g_pSamLinearWrap = NULL;
ID3D11RasterizerState*      g_pRasterizerStateNoCull = NULL;
ID3D11RasterizerState*      g_pRasterizerStateBackfaceCull = NULL;
ID3D11RasterizerState*      g_pRasterizerStateFrontfaceCull = NULL;
ID3D11RasterizerState*      g_pRasterizerStateNoCullWireFrame = NULL;
ID3D11DepthStencilState*    g_pDepthStencilStateNoStencil = NULL;
	//--------------------------------------------------------------------------------------
// Mirror data and interfaces
//--------------------------------------------------------------------------------------
D3DXVECTOR3                 g_vMirrorCenter[g_iNumMirrors];
D3DXVECTOR3                 g_vMirrorNormal[g_iNumMirrors];
D3DXPLANE                   g_vMirrorPlane[g_iNumMirrors];
FLOAT                       g_fMirrorWidth[g_iNumMirrors];
FLOAT                       g_fMirrorHeight[g_iNumMirrors];
FLOAT                       g_fMirrorResolutionX[g_iNumMirrors];
FLOAT                       g_fMirrorResolutionY[g_iNumMirrors];
D3DXVECTOR3                 g_vMirrorCorner[4];
MirrorRect                  g_MirrorRect[g_iNumMirrors];
const UINT8                 g_iStencilMask = 0x01;
const UINT8                 g_iStencilRef = 0x01;
ID3D11DepthStencilState*    g_pMirrorDepthStencilStateDepthTestStencilOverwrite = NULL;
ID3D11DepthStencilState*    g_pMirrorDepthStencilStateDepthOverwriteStencilTest = NULL;
ID3D11DepthStencilState*    g_pMirrorDepthStencilStateDepthWriteStencilTest = NULL;
ID3D11DepthStencilState*    g_pMirrorDepthStencilStateDepthOverwriteStencilClear = NULL;
ID3D11Buffer*               g_pMirrorVertexBuffer = NULL;
ID3D11InputLayout*          g_pMirrorVertexLayout11 = NULL;
	
//--------------------------------------------------------------------------------------
// Shadow map data and interface
//--------------------------------------------------------------------------------------
ID3D11Texture2D*            g_pShadowTexture[g_iNumShadows] = { NULL };
ID3D11ShaderResourceView*   g_pShadowResourceView[g_iNumShadows] = { NULL };
ID3D11DepthStencilView*     g_pShadowDepthStencilView[g_iNumShadows] = { NULL };
D3D11_VIEWPORT              g_ShadowViewport[g_iNumShadows] = { 0 };
FLOAT                       g_fShadowResolutionX[g_iNumShadows];
FLOAT                       g_fShadowResolutionY[g_iNumShadows];
	//CCamera g_Camera;
	SceneParamsStatic           g_StaticParamsDirect;
SceneParamsStatic           g_StaticParamsShadow[g_iNumShadows];
SceneParamsStatic           g_StaticParamsMirror[g_iNumMirrors];
	 
	boost::movelib::unique_ptr<D3D11_Renderer> D3D11_Renderer::m_sInstance;
	//--------------------------------------------------------------------------------------
// Convenient checks for the current render pathway
//--------------------------------------------------------------------------------------
inline bool IsRenderDeferredPerScene()
{
    return g_iDeviceContextType == DEVICECONTEXT_ST_DEFERRED_PER_SCENE
        || g_iDeviceContextType == DEVICECONTEXT_MT_DEFERRED_PER_SCENE;
}
	inline bool IsRenderMultithreadedPerScene()
{
    return g_iDeviceContextType == DEVICECONTEXT_MT_DEFERRED_PER_SCENE;
}
	inline bool IsRenderDeferredPerChunk()
{
    return g_iDeviceContextType == DEVICECONTEXT_ST_DEFERRED_PER_CHUNK
        || g_iDeviceContextType == DEVICECONTEXT_MT_DEFERRED_PER_CHUNK;
}
	inline bool IsRenderMultithreadedPerChunk()
{
    return g_iDeviceContextType == DEVICECONTEXT_MT_DEFERRED_PER_CHUNK;
}
	// Handle updates to the scene.  This is called regardless of which D3D API is used
//--------------------------------------------------------------------------------------
void D3D11_Renderer::OnFrameMove( double fTime, float fElapsedTime, void* pUserContext )
{
    static float fTotalTime = 0.0f;
    fTotalTime += fElapsedTime;
	    m_Time = fTime;
    m_ElaspedTime = fElapsedTime;
	    // Jigger the overhead lights --- these are hard-coded to indices 1,2,3
    // Ideally, we'd attach the lights to the relevant objects in the mesh
    // file and animate those objects.  But for now, just some hard-coded
    // swinging...
    float fCycle1X = 0.0f;
    float fCycle1Z = 0.20f * sinf( 2.0f * ( fTotalTime + 0.0f * D3DX_PI ) );
    g_vLightDir[1] = g_vDown + D3DXVECTOR3( fCycle1X, 0.0f, fCycle1Z );
    D3DXVec3Normalize( &g_vLightDir[1], &g_vLightDir[1] );
	    float fCycle2X = 0.10f * cosf( 1.6f * ( fTotalTime + 0.3f * D3DX_PI ) );
    float fCycle2Z = 0.10f * sinf( 1.6f * ( fTotalTime + 0.0f * D3DX_PI ) );
    g_vLightDir[2] = g_vDown + D3DXVECTOR3( fCycle2X, 0.0f, fCycle2Z );
    D3DXVec3Normalize( &g_vLightDir[2], &g_vLightDir[2] );
	    float fCycle3X = 0.30f * cosf( 2.4f * ( fTotalTime + 0.3f * D3DX_PI ) );
    float fCycle3Z = 0.0f;
    g_vLightDir[3] = g_vDown + D3DXVECTOR3( fCycle3X, 0.0f, fCycle3Z );
    D3DXVec3Normalize( &g_vLightDir[3], &g_vLightDir[3] );
	    // Update the camera's position based on user input
    g_Camera.FrameMove( fElapsedTime );
}
	//--------------------------------------------------------------------------------------
// Figure out the ViewProj matrix from the light's perspective
//--------------------------------------------------------------------------------------
void CalcLightViewProj( D3DXMATRIX* pmLightViewProj, int iLight )
{
    const D3DXVECTOR3& vLightDir = g_vLightDir[iLight];
    const D3DXVECTOR3& vLightPos = g_vLightPos[iLight];
	    D3DXVECTOR3 vLookAt = vLightPos + g_fSceneRadius * vLightDir;
	    D3DXMATRIX mLightView;
    D3DXMatrixLookAtLH( &mLightView, &vLightPos, &vLookAt, &g_vUp );
	    D3DXMATRIX mLightProj;
    D3DXMatrixPerspectiveFovLH( &mLightProj, g_fLightFOV[iLight], g_fLightAspect[iLight],
        g_fLightNearPlane[iLight], g_fLightFarPlane[iLight] );
	    *pmLightViewProj = mLightView * mLightProj;
}
	//--------------------------------------------------------------------------------------
// Find and compile the specified shader
//--------------------------------------------------------------------------------------
HRESULT CompileShaderFromFile( WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut )
{
    HRESULT hr = S_OK;
    
    DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
    // Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders.
    // Setting this flag improves the shader debugging experience, but still allows
    // the shaders to be optimized and to run exactly the way they will run in
    // the release configuration of this program.
    dwShaderFlags |= D3DCOMPILE_DEBUG;
#endif
	    ID3DBlob* pErrorBlob;
    hr = D3DX11CompileFromFileW( szFileName, NULL, NULL, szEntryPoint, szShaderModel,
        dwShaderFlags, 0, NULL, ppBlobOut, &pErrorBlob, NULL );
    if( FAILED(hr) )
    {
        if( pErrorBlob != NULL )
            OutputDebugStringA( (char*)pErrorBlob->GetBufferPointer() );
        SAFE_RELEASE( pErrorBlob );
        return hr;
    }
    SAFE_RELEASE( pErrorBlob );
	    return S_OK;
}
	void InitializeLights()
{
    // Our hand-tuned approximation to the sky light
    //g_vLightColor[0] =                  D3DXVECTOR4( 1.5f * 0.160f, 1.5f * 0.341f, 1.5f * 1.000f, 1.000f );
    g_vLightColor[0] =                  D3DXVECTOR4( 3.0f * 0.160f, 3.0f * 0.341f, 3.0f * 1.000f, 1.000f );
    g_vLightDir[0] =                    D3DXVECTOR3( -0.67f, -0.71f, +0.21f );
    g_vLightPos[0] =                    g_vSceneCenter - g_fSceneRadius * g_vLightDir[0];
    g_fLightFOV[0] =                    D3DX_PI / 4.0f;
	    // The three overhead lamps
    g_vLightColor[1] =                  D3DXVECTOR4( 0.4f * 0.895f, 0.4f * 0.634f, 0.4f * 0.626f, 1.0f );
    g_vLightPos[1] =                    D3DXVECTOR3( 0.0f, 400.0f, -250.0f );
    g_vLightDir[1] =                    D3DXVECTOR3( 0.00f, -1.00f, 0.00f );
    g_fLightFOV[1] =                    65.0f * ( D3DX_PI / 180.0f );
    
    g_vLightColor[2] =                  D3DXVECTOR4( 0.5f * 0.388f, 0.5f * 0.641f, 0.5f * 0.401f, 1.0f );
    g_vLightPos[2] =                    D3DXVECTOR3( 0.0f, 400.0f, 0.0f );
    g_vLightDir[2] =                    D3DXVECTOR3( 0.00f, -1.00f, 0.00f );
    g_fLightFOV[2] =                    65.0f * ( D3DX_PI / 180.0f );
    
    g_vLightColor[3] =                  D3DXVECTOR4( 0.4f * 1.000f, 0.4f * 0.837f, 0.4f * 0.848f, 1.0f );
    g_vLightPos[3] =                    D3DXVECTOR3( 0.0f, 400.0f, 250.0f );
    g_vLightDir[3] =                    D3DXVECTOR3( 0.00f, -1.00f, 0.00f );
    g_fLightFOV[3] =                    65.0f * ( D3DX_PI / 180.0f );
    
    // For the time beings, let's make these params follow the same pattern for all lights
    for ( int iLight = 0; iLight < g_iNumLights; ++iLight )
    {
        g_fLightAspect[iLight] = 1.0f;
        g_fLightNearPlane[iLight] = 100.f;
        g_fLightFarPlane[iLight] = 2.0f * g_fSceneRadius;
	        g_fLightFalloffDistEnd[iLight] = g_fLightFarPlane[iLight];
        g_fLightFalloffDistRange[iLight] = 100.0f;
	        g_fLightFalloffCosAngleEnd[iLight] = cosf( g_fLightFOV[iLight] / 2.0f );
        g_fLightFalloffCosAngleRange[iLight] = 0.1f;
	        D3DXVec3Normalize( &g_vLightDir[iLight], &g_vLightDir[iLight] );
    }
	#ifdef ADJUSTABLE_LIGHT
    // The adjustable light is number 0
    g_LightControl.SetLightDirection( g_vLightDir[0] );
#endif
}
	//--------------------------------------------------------------------------------------
// Create D3D11 resources for the shadows
//--------------------------------------------------------------------------------------
HRESULT InitializeShadows( ID3D11Device* pd3dDevice )
{
    HRESULT hr = S_OK;
	    for ( int iShadow = 0; iShadow < g_iNumShadows; ++iShadow )
    {
        // constant for now
        g_fShadowResolutionX[iShadow] = 2048.0f;
        g_fShadowResolutionY[iShadow] = 2048.0f;
	        // The shadow map, along with depth-stencil and texture view
        D3D11_TEXTURE2D_DESC ShadowDesc = {
            ( int) g_fShadowResolutionX[iShadow],   // UINT Width;
            ( int) g_fShadowResolutionY[iShadow],   // UINT Height;
            1,                                      // UINT MipLevels;
            1,                                      // UINT ArraySize;
            DXGI_FORMAT_R32_TYPELESS,               // DXGI_FORMAT Format;
            { 1, 0, },                              // DXGI_SAMPLE_DESC SampleDesc;
            D3D11_USAGE_DEFAULT,                    // D3D11_USAGE Usage;
            D3D11_BIND_SHADER_RESOURCE
                | D3D11_BIND_DEPTH_STENCIL,         // UINT BindFlags;
            0,                                      // UINT CPUAccessFlags;
            0,                                      // UINT MiscFlags;
        };
        D3D11_DEPTH_STENCIL_VIEW_DESC ShadowDepthStencilViewDesc = {
            DXGI_FORMAT_D32_FLOAT,                  // DXGI_FORMAT Format;
            D3D11_DSV_DIMENSION_TEXTURE2D,          // D3D11_DSV_DIMENSION ViewDimension;
            0,                                      // UINT ReadOnlyUsage;
            {0, },                                  // D3D11_TEX2D_RTV Texture2D;
        };
        D3D11_SHADER_RESOURCE_VIEW_DESC ShadowResourceViewDesc = {
            DXGI_FORMAT_R32_FLOAT,                  // DXGI_FORMAT Format;
            D3D11_SRV_DIMENSION_TEXTURE2D,          // D3D11_SRV_DIMENSION ViewDimension;
            {0, 1, },                               // D3D11_TEX2D_SRV Texture2D;
        };
        pd3dDevice->CreateTexture2D( &ShadowDesc, NULL, &g_pShadowTexture[iShadow] ) ;
        DXUT_SetDebugName( g_pShadowTexture[iShadow], "Shadow" );
	        pd3dDevice->CreateDepthStencilView( g_pShadowTexture[iShadow], &ShadowDepthStencilViewDesc,
            &g_pShadowDepthStencilView[iShadow] ) ;
        DXUT_SetDebugName( g_pShadowDepthStencilView[iShadow], "Shadow DSV" );
	        pd3dDevice->CreateShaderResourceView( g_pShadowTexture[iShadow], &ShadowResourceViewDesc,
            &g_pShadowResourceView[iShadow] ) ;
        DXUT_SetDebugName( g_pShadowResourceView[iShadow] , "Shadow RSV" );
	        g_ShadowViewport[iShadow].Width = g_fShadowResolutionX[iShadow];
        g_ShadowViewport[iShadow].Height = g_fShadowResolutionY[iShadow];
        g_ShadowViewport[iShadow].MinDepth = 0;
        g_ShadowViewport[iShadow].MaxDepth = 1;
        g_ShadowViewport[iShadow].TopLeftX = 0;
        g_ShadowViewport[iShadow].TopLeftY = 0;
	        // The parameters to pass to per-chunk threads for the shadow scenes
        g_StaticParamsShadow[iShadow].m_pDepthStencilState = g_pDepthStencilStateNoStencil;
        g_StaticParamsShadow[iShadow].m_iStencilRef = 0;
        g_StaticParamsShadow[iShadow].m_pRasterizerState = g_pRasterizerStateFrontfaceCull;
        g_StaticParamsShadow[iShadow].m_vMirrorPlane = D3DXPLANE( 0.0f, 0.0f, 0.0f, 0.0f );
        g_StaticParamsShadow[iShadow].m_vTintColor = D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f );
        g_StaticParamsShadow[iShadow].m_pDepthStencilView = g_pShadowDepthStencilView[iShadow];
        g_StaticParamsShadow[iShadow].m_pViewport = &g_ShadowViewport[iShadow];
    }
	    return hr;
}
	//--------------------------------------------------------------------------------------
// Create D3D11 resources for the mirrors
//--------------------------------------------------------------------------------------
HRESULT InitializeMirrors( ID3D11Device* pd3dDevice )
{
    HRESULT hr = S_OK;
	    // The stencil method for the mirror rendering requires several different
    // depth-stencil states...
	    // Write stencil if the depth test passes
    D3D11_DEPTH_STENCIL_DESC DepthStencilDescDepthTestStencilOverwrite = {
        TRUE,                           // BOOL DepthEnable;
        D3D11_DEPTH_WRITE_MASK_ZERO,    // D3D11_DEPTH_WRITE_MASK DepthWriteMask;
        D3D11_COMPARISON_LESS_EQUAL,    // D3D11_COMPARISON_FUNC DepthFunc;
        TRUE,                           // BOOL StencilEnable;
        0,                              // UINT8 StencilReadMask;
        g_iStencilMask,                 // UINT8 StencilWriteMask;
        {                               // D3D11_DEPTH_STENCILOP_DESC FrontFace;
            D3D11_STENCIL_OP_REPLACE,   // D3D11_STENCIL_OP StencilFailOp;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilDepthFailOp;
            D3D11_STENCIL_OP_REPLACE,   // D3D11_STENCIL_OP StencilPassOp;
            D3D11_COMPARISON_ALWAYS,    // D3D11_COMPARISON_FUNC StencilFunc;
        },
        {                               // D3D11_DEPTH_STENCILOP_DESC BackFace;
            D3D11_STENCIL_OP_REPLACE,   // D3D11_STENCIL_OP StencilFailOp;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilDepthFailOp;
            D3D11_STENCIL_OP_REPLACE,   // D3D11_STENCIL_OP StencilPassOp;
            D3D11_COMPARISON_ALWAYS,    // D3D11_COMPARISON_FUNC StencilFunc;
        },
    };
    pd3dDevice->CreateDepthStencilState(
        &DepthStencilDescDepthTestStencilOverwrite,
        &g_pMirrorDepthStencilStateDepthTestStencilOverwrite ) ;
    DXUT_SetDebugName( g_pMirrorDepthStencilStateDepthTestStencilOverwrite, "Mirror SO" );
	    // Overwrite depth and if stencil test passes
    D3D11_DEPTH_STENCIL_DESC DepthStencilDescDepthOverwriteStencilTest = {
        TRUE,                           // BOOL DepthEnable;
        D3D11_DEPTH_WRITE_MASK_ALL,     // D3D11_DEPTH_WRITE_MASK DepthWriteMask;
        D3D11_COMPARISON_ALWAYS,        // D3D11_COMPARISON_FUNC DepthFunc;
        TRUE,                           // BOOL StencilEnable;
        g_iStencilMask,                 // UINT8 StencilReadMask;
        0,                              // UINT8 StencilWriteMask;
        {                               // D3D11_DEPTH_STENCILOP_DESC FrontFace;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilFailOp;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilDepthFailOp;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilPassOp;
            D3D11_COMPARISON_EQUAL,     // D3D11_COMPARISON_FUNC StencilFunc;
        },
        {                               // D3D11_DEPTH_STENCILOP_DESC BackFace;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilFailOp;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilDepthFailOp;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilPassOp;
            D3D11_COMPARISON_EQUAL,     // D3D11_COMPARISON_FUNC StencilFunc;
        },
    };
    pd3dDevice->CreateDepthStencilState(
        &DepthStencilDescDepthOverwriteStencilTest,
        &g_pMirrorDepthStencilStateDepthOverwriteStencilTest ) ;
    DXUT_SetDebugName( g_pMirrorDepthStencilStateDepthOverwriteStencilTest, "Mirror DO" );
	    // Perform normal depth test/write if the stencil test passes
    D3D11_DEPTH_STENCIL_DESC DepthStencilDescDepthWriteStencilTest = {
        TRUE,                           // BOOL DepthEnable;
        D3D11_DEPTH_WRITE_MASK_ALL,     // D3D11_DEPTH_WRITE_MASK DepthWriteMask;
        D3D11_COMPARISON_LESS_EQUAL,    // D3D11_COMPARISON_FUNC DepthFunc;
        TRUE,                           // BOOL StencilEnable;
        g_iStencilMask,                 // UINT8 StencilReadMask;
        0,                              // UINT8 StencilWriteMask;
        {                               // D3D11_DEPTH_STENCILOP_DESC FrontFace;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilFailOp;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilDepthFailOp;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilPassOp;
            D3D11_COMPARISON_EQUAL,     // D3D11_COMPARISON_FUNC StencilFunc;
        },
        {                               // D3D11_DEPTH_STENCILOP_DESC BackFace;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilFailOp;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilDepthFailOp;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilPassOp;
            D3D11_COMPARISON_EQUAL,     // D3D11_COMPARISON_FUNC StencilFunc;
        },
    };
    pd3dDevice->CreateDepthStencilState(
        &DepthStencilDescDepthWriteStencilTest,
        &g_pMirrorDepthStencilStateDepthWriteStencilTest ) ;
    DXUT_SetDebugName( g_pMirrorDepthStencilStateDepthWriteStencilTest, "Mirror Normal" );
	    // Overwrite depth and clear stencil if stencil test passes
    D3D11_DEPTH_STENCIL_DESC DepthStencilDescDepthOverwriteStencilClear = {
        TRUE,                           // BOOL DepthEnable;
        D3D11_DEPTH_WRITE_MASK_ALL,     // D3D11_DEPTH_WRITE_MASK DepthWriteMask;
        D3D11_COMPARISON_ALWAYS,        // D3D11_COMPARISON_FUNC DepthFunc;
        TRUE,                           // BOOL StencilEnable;
        g_iStencilMask,                 // UINT8 StencilReadMask;
        g_iStencilMask,                 // UINT8 StencilWriteMask;
        {                               // D3D11_DEPTH_STENCILOP_DESC FrontFace;
            D3D11_STENCIL_OP_ZERO,      // D3D11_STENCIL_OP StencilFailOp;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilDepthFailOp;
            D3D11_STENCIL_OP_ZERO,      // D3D11_STENCIL_OP StencilPassOp;
            D3D11_COMPARISON_EQUAL,     // D3D11_COMPARISON_FUNC StencilFunc;
        },
        {                               // D3D11_DEPTH_STENCILOP_DESC BackFace;
            D3D11_STENCIL_OP_ZERO,      // D3D11_STENCIL_OP StencilFailOp;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilDepthFailOp;
            D3D11_STENCIL_OP_ZERO,      // D3D11_STENCIL_OP StencilPassOp;
            D3D11_COMPARISON_EQUAL,     // D3D11_COMPARISON_FUNC StencilFunc;
        },
    };
    pd3dDevice->CreateDepthStencilState(
        &DepthStencilDescDepthOverwriteStencilClear,
        &g_pMirrorDepthStencilStateDepthOverwriteStencilClear ) ;
    DXUT_SetDebugName( g_pMirrorDepthStencilStateDepthOverwriteStencilClear, "Mirror Clear" );
	    // These values are hard-coded based on the sdkmesh contents, plus some
    // hand-fiddling, pending a better solution in the pipeline.
    g_vMirrorCenter[0].x =  -35.1688f;
    g_vMirrorCenter[0].y =   89.279683f;
    g_vMirrorCenter[0].z =  -0.7488765f;
    g_vMirrorCenter[1].x =   41.2174f;
    g_vMirrorCenter[1].y =   89.279683f;
    g_vMirrorCenter[1].z =  -0.7488745f;
    g_vMirrorCenter[2].x =   3.024275f;
    g_vMirrorCenter[2].y =   89.279683f;
    g_vMirrorCenter[2].z =  -54.344299f;
    g_vMirrorCenter[3].x =   3.02427475f;
    g_vMirrorCenter[3].y =   89.279683f;
    g_vMirrorCenter[3].z =   52.8466f;
	    g_fMirrorWidth [0]   =   104.190895f;
    g_fMirrorHeight[0]   =   92.19922656f;
    g_fMirrorWidth [1]   =   104.190899f;
    g_fMirrorHeight[1]   =   92.19923178f;
    g_fMirrorWidth [2]   =   76.3862f;
    g_fMirrorHeight[2]   =   92.3427325f;
    g_fMirrorWidth [3]   =   76.386196f;
    g_fMirrorHeight[3]   =   92.34274043f;
	    g_vMirrorNormal[0].x =  -0.998638464f;
    g_vMirrorNormal[0].y =  -0.052165297f;
    g_vMirrorNormal[0].z =   0.0f;
    g_vMirrorNormal[1].x =   0.998638407f;
    g_vMirrorNormal[1].y =  -0.052166381f;
    g_vMirrorNormal[1].z =   3.15017E-08f;
    g_vMirrorNormal[2].x =   0.0f;
    g_vMirrorNormal[2].y =  -0.076278878f;
    g_vMirrorNormal[2].z =  -0.997086522f;
    g_vMirrorNormal[3].x =  -5.22129E-08f;
    g_vMirrorNormal[3].y =  -0.076279957f;
    g_vMirrorNormal[3].z =   0.99708644f;
	    g_fMirrorResolutionX[0] = 320.0f;
    g_fMirrorResolutionY[0] = ( g_fMirrorResolutionX[0] * g_fMirrorHeight[0] / g_fMirrorWidth[0] );
    g_fMirrorResolutionX[1] = 320.0f;
    g_fMirrorResolutionY[1] = ( g_fMirrorResolutionX[1] * g_fMirrorHeight[1] / g_fMirrorWidth[1] );
    g_fMirrorResolutionX[2] = 320.0f;
    g_fMirrorResolutionY[2] = ( g_fMirrorResolutionX[2] * g_fMirrorHeight[2] / g_fMirrorWidth[2] );
    g_fMirrorResolutionX[3] = 320.0f;
    g_fMirrorResolutionY[3] = ( g_fMirrorResolutionX[3] * g_fMirrorHeight[3] / g_fMirrorWidth[3] );
	    g_vMirrorCorner[0].x = -1.0f;
    g_vMirrorCorner[0].y = -1.0f;
    g_vMirrorCorner[0].z =  0.0f;
    g_vMirrorCorner[1].x =  1.0f;
    g_vMirrorCorner[1].y = -1.0f;
    g_vMirrorCorner[1].z =  0.0f;
    g_vMirrorCorner[2].x = -1.0f;
    g_vMirrorCorner[2].y =  1.0f;
    g_vMirrorCorner[2].z =  0.0f;
    g_vMirrorCorner[3].x =  1.0f;
    g_vMirrorCorner[3].y =  1.0f;
    g_vMirrorCorner[3].z =  0.0f;
	    D3D11_BUFFER_DESC BufDesc;
    BufDesc.ByteWidth = sizeof( MirrorRect );
    BufDesc.Usage = D3D11_USAGE_DYNAMIC;
    BufDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    BufDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    BufDesc.MiscFlags = 0;
    pd3dDevice->CreateBuffer( &BufDesc, NULL, &g_pMirrorVertexBuffer );
    DXUT_SetDebugName( g_pMirrorVertexBuffer, "Mirror VB" );
	    for ( int iMirror = 0; iMirror < g_iNumMirrors; ++iMirror )
    {
        D3DXPlaneFromPointNormal( &g_vMirrorPlane[iMirror],
            &g_vMirrorCenter[iMirror], &g_vMirrorNormal[iMirror] );
	        // The vertex buffer contents for the mirror quad, in local space.
        for ( UINT iCorner = 0; iCorner < 4; ++ iCorner )
        {
            g_MirrorRect[iMirror][iCorner].Position.x = 0.5f * g_fMirrorWidth [iMirror] * g_vMirrorCorner[iCorner].x;
            g_MirrorRect[iMirror][iCorner].Position.y = 0.5f * g_fMirrorHeight[iMirror] * g_vMirrorCorner[iCorner].y;
            g_MirrorRect[iMirror][iCorner].Position.z =                                   g_vMirrorCorner[iCorner].z;
	            g_MirrorRect[iMirror][iCorner].Normal.x =
            g_MirrorRect[iMirror][iCorner].Normal.y =
            g_MirrorRect[iMirror][iCorner].Normal.z = 0.0f;
	            g_MirrorRect[iMirror][iCorner].Texcoord.x =
            g_MirrorRect[iMirror][iCorner].Texcoord.y = 0.0f;
	            g_MirrorRect[iMirror][iCorner].Tangent.x =
            g_MirrorRect[iMirror][iCorner].Tangent.y =
            g_MirrorRect[iMirror][iCorner].Tangent.z = 0.0f;
        }
	        // The parameters to pass to per-chunk threads for the mirror scenes
        g_StaticParamsMirror[iMirror].m_pDepthStencilState = g_pMirrorDepthStencilStateDepthWriteStencilTest;
        g_StaticParamsMirror[iMirror].m_iStencilRef = g_iStencilRef;
        g_StaticParamsMirror[iMirror].m_pRasterizerState = g_pRasterizerStateBackfaceCull;
        g_StaticParamsMirror[iMirror].m_vMirrorPlane = g_vMirrorPlane[iMirror];
        g_StaticParamsMirror[iMirror].m_vTintColor = g_vMirrorTint;
        g_StaticParamsMirror[iMirror].m_pDepthStencilView = NULL;
        g_StaticParamsMirror[iMirror].m_pViewport = NULL;
    }
	    return S_OK;
}
	 
	 
D3D11_Renderer::D3D11_Renderer(const std::string& l_name) : m_name(l_name)
{
    
}
	void D3D11_Renderer::CreateDevice()
{
    DXGI_SWAP_CHAIN_DESC sd;
    ZeroMemory( &sd, sizeof( sd ) );
    sd.BufferCount = 1;
    sd.BufferDesc.Width = 640;
    sd.BufferDesc.Height = 480;
    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.BufferDesc.RefreshRate.Numerator = 60;
    sd.BufferDesc.RefreshRate.Denominator = 1;
    sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    sd.OutputWindow = CSimApplication::m_pSimApp->GetHwnd();
    sd.SampleDesc.Count = 1;
    sd.SampleDesc.Quality = 0;
    sd.Windowed = TRUE;
	 
	    D3D_FEATURE_LEVEL  FeatureLevelsRequested = D3D_FEATURE_LEVEL_11_0;
    UINT               numLevelsRequested = 1;
    D3D_FEATURE_LEVEL  FeatureLevelsSupported;
	    auto result =
        D3D11CreateDeviceAndSwapChain(
            nullptr,
            D3D_DRIVER_TYPE_HARDWARE,
            nullptr,
            0,
            nullptr,
            0,
            D3D11_SDK_VERSION,
            &sd,
            &m_swapChain,
            &m_pDevice,
            nullptr,
            &m_pDeviceContext
            );
	
    
    if (result != S_OK)
    {
        MessageBoxA(0, "Error Creating DX11 Device", "Error", 0);
        exit(0);
     }
	    // Compile the shaders
    ID3DBlob* pVertexShaderBuffer = NULL;
    CompileShaderFromFile( L"MultithreadedRendering11_VS.hlsl", "VSMain", "vs_4_0", &pVertexShaderBuffer );
	    ID3DBlob* pPixelShaderBuffer = NULL;
    CompileShaderFromFile( L"MultithreadedRendering11_PS.hlsl", "PSMain", "ps_4_0", &pPixelShaderBuffer ) ;
	    // Create the shaders
    m_pDevice->CreateVertexShader( pVertexShaderBuffer->GetBufferPointer(),
                                              pVertexShaderBuffer->GetBufferSize(), NULL, &g_pVertexShader ) ;
    m_pDevice->CreatePixelShader( pPixelShaderBuffer->GetBufferPointer(),
                                             pPixelShaderBuffer->GetBufferSize(), NULL, &g_pPixelShader ) ;
	    DXUT_SetDebugName( g_pVertexShader, "VSMain" );
    DXUT_SetDebugName( g_pPixelShader, "PSMain" );
	    // Create our vertex input layout
    // The content exporter supports either compressed or uncompressed formats for
    // normal/tangent/binormal.  Unfortunately the relevant compressed formats are
    // deprecated for DX10+.  So they required special handling in the vertex shader.
    // If we use uncompressed data here, need to also #define UNCOMPRESSED_VERTEX_DATA
    // in the HLSL file.
    const D3D11_INPUT_ELEMENT_DESC UncompressedLayout[] =
    {
        { "POSITION",  0, DXGI_FORMAT_R32G32B32_FLOAT,   0, 0,  D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "NORMAL",    0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD",  0, DXGI_FORMAT_R32G32_FLOAT,      0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "TANGENT",   0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };
    const D3D11_INPUT_ELEMENT_DESC CompressedLayout[] =
    {
        { "POSITION",  0, DXGI_FORMAT_R32G32B32_FLOAT,   0, 0,  D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "NORMAL",    0, DXGI_FORMAT_R10G10B10A2_UNORM, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD",  0, DXGI_FORMAT_R16G16_FLOAT,      0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "TANGENT",   0, DXGI_FORMAT_R10G10B10A2_UNORM, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };
	#ifdef UNCOMPRESSED_VERTEX_DATA
    V_RETURN( pd3dDevice->CreateInputLayout( UncompressedLayout,
        ARRAYSIZE( UncompressedLayout ),
        pVertexShaderBuffer->GetBufferPointer(),
        pVertexShaderBuffer->GetBufferSize(),
        &g_pVertexLayout11 ) );
    DXUT_SetDebugName(g_pVertexLayout11, "Uncompressed" );
#else
    m_pDevice->CreateInputLayout( CompressedLayout,
        ARRAYSIZE( CompressedLayout ),
        pVertexShaderBuffer->GetBufferPointer(),
        pVertexShaderBuffer->GetBufferSize(),
        &g_pVertexLayout11 ) ;
	    DXUT_SetDebugName(g_pVertexLayout11, "Compressed" );
#endif
	    m_pDevice->CreateInputLayout( UncompressedLayout,
        ARRAYSIZE( UncompressedLayout ),
        pVertexShaderBuffer->GetBufferPointer(),
        pVertexShaderBuffer->GetBufferSize(),
        &g_pMirrorVertexLayout11 ) ;
    DXUT_SetDebugName( g_pMirrorVertexLayout11, "Mirror" );
    
    SAFE_RELEASE( pVertexShaderBuffer );
    SAFE_RELEASE( pPixelShaderBuffer );
	    // The standard depth-stencil state
    D3D11_DEPTH_STENCIL_DESC DepthStencilDescNoStencil = {
        TRUE,                           // BOOL DepthEnable;
        D3D11_DEPTH_WRITE_MASK_ALL,     // D3D11_DEPTH_WRITE_MASK DepthWriteMask;
        D3D11_COMPARISON_LESS_EQUAL,    // D3D11_COMPARISON_FUNC DepthFunc;
        FALSE,                          // BOOL StencilEnable;
        0,                              // UINT8 StencilReadMask;
        0,                              // UINT8 StencilWriteMask;
        {                               // D3D11_DEPTH_STENCILOP_DESC FrontFace;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilFailOp;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilDepthFailOp;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilPassOp;
            D3D11_COMPARISON_NEVER,     // D3D11_COMPARISON_FUNC StencilFunc;
        },
        {                               // D3D11_DEPTH_STENCILOP_DESC BackFace;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilFailOp;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilDepthFailOp;
            D3D11_STENCIL_OP_KEEP,      // D3D11_STENCIL_OP StencilPassOp;
            D3D11_COMPARISON_NEVER,     // D3D11_COMPARISON_FUNC StencilFunc;
        },
    };
    m_pDevice->CreateDepthStencilState(
        &DepthStencilDescNoStencil,
        &g_pDepthStencilStateNoStencil ) ;
    DXUT_SetDebugName( g_pDepthStencilStateNoStencil, "No Stencil" );
	    // Provide the intercept callback for CMultiDeviceContextDXUTMesh, which allows
    // us to farm out different mesh chunks to different device contexts
    void RenderMesh( CMultiDeviceContextDXUTMesh* pMesh,
        UINT iMesh,
        bool bAdjacent,
        ID3D11DeviceContext* pd3dDeviceContext,
        UINT iDiffuseSlot,
        UINT iNormalSlot,
        UINT iSpecularSlot );
    MDC_SDKMESH_CALLBACKS11 MeshCallbacks;
    ZeroMemory( &MeshCallbacks, sizeof(MeshCallbacks) );
    MeshCallbacks.pRenderMesh = RenderMesh;
	    // Load the mesh
    g_Mesh11.Create( m_pDevice, L"SquidRoom\\SquidRoom.sdkmesh", true, &MeshCallbacks ) ;
	    // Create sampler states for point/clamp (shadow map) and linear/wrap (everything else)
    D3D11_SAMPLER_DESC SamDesc;
    SamDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
    SamDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
    SamDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
    SamDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
    SamDesc.MipLODBias = 0.0f;
    SamDesc.MaxAnisotropy = 1;
    SamDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
    SamDesc.BorderColor[0] = SamDesc.BorderColor[1] = SamDesc.BorderColor[2] = SamDesc.BorderColor[3] = 0;
    SamDesc.MinLOD = 0;
    SamDesc.MaxLOD = D3D11_FLOAT32_MAX;
    m_pDevice->CreateSamplerState( &SamDesc, &g_pSamPointClamp ) ;
    DXUT_SetDebugName( g_pSamPointClamp, "PointClamp" );
	    SamDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
    SamDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
    SamDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
    SamDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
    m_pDevice->CreateSamplerState( &SamDesc, &g_pSamLinearWrap ) ;
    DXUT_SetDebugName( g_pSamLinearWrap, "LinearWrap" );
	    // Setup constant buffers
    D3D11_BUFFER_DESC Desc;
    Desc.Usage = D3D11_USAGE_DYNAMIC;
    Desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    Desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    Desc.MiscFlags = 0;
	    Desc.ByteWidth = sizeof( CB_VS_PER_SCENE );
    m_pDevice->CreateBuffer( &Desc, NULL, &g_pcbVSPerScene ) ;
    DXUT_SetDebugName( g_pcbVSPerScene, "CB_VS_PER_SCENE" );
	    Desc.ByteWidth = sizeof( CB_VS_PER_OBJECT );
    m_pDevice->CreateBuffer( &Desc, NULL, &g_pcbVSPerObject ) ;
    DXUT_SetDebugName( g_pcbVSPerObject, "CB_VS_PER_OBJECT" );
	    Desc.ByteWidth = sizeof( CB_PS_PER_SCENE );
    m_pDevice->CreateBuffer( &Desc, NULL, &g_pcbPSPerScene ) ;
    DXUT_SetDebugName( g_pcbPSPerScene, "CB_PS_PER_SCENE" );
	    Desc.ByteWidth = sizeof( CB_PS_PER_OBJECT );
    m_pDevice->CreateBuffer( &Desc, NULL, &g_pcbPSPerObject ) ;
    DXUT_SetDebugName( g_pcbPSPerObject, "CB_PS_PER_OBJECT" );
	    Desc.ByteWidth = sizeof( CB_PS_PER_LIGHT );
    m_pDevice->CreateBuffer( &Desc, NULL, &g_pcbPSPerLight ) ;
    DXUT_SetDebugName( g_pcbPSPerLight, "CB_PS_PER_LIGHT" );
	    // Setup the camera's view parameters
    g_Camera.SetViewParams( &g_vDefaultEye, &g_vDefaultLookAt );
    g_Camera.SetRadius( g_fDefaultCameraRadius, g_fMinCameraRadius, g_fMaxCameraRadius );
	    // Setup backface culling states:
    //  1) g_pRasterizerStateNoCull --- no culling (debugging only)
    //  2) g_pRasterizerStateBackfaceCull --- backface cull (mirror quads and the assets
    //      reflected in the mirrors)
    //  3) g_pRasterizerStateFrontfaceCull --- frontface cull (pre-built assets from
    //      the content pipeline)
    D3D11_RASTERIZER_DESC RasterizerDescNoCull = {
        D3D11_FILL_SOLID,   // D3D11_FILL_MODE FillMode;
        D3D11_CULL_NONE,    // D3D11_CULL_MODE CullMode;
        TRUE,               // BOOL FrontCounterClockwise;
        0,                  // INT DepthBias;
        0,                  // FLOAT DepthBiasClamp;
        0,                  // FLOAT SlopeScaledDepthBias;
        FALSE,              // BOOL DepthClipEnable;
        FALSE,              // BOOL ScissorEnable;
        TRUE,               // BOOL MultisampleEnable;
        FALSE,              // BOOL AntialiasedLineEnable;
    };
	    m_pDevice->CreateRasterizerState( &RasterizerDescNoCull, &g_pRasterizerStateNoCull ) ;
    DXUT_SetDebugName( g_pRasterizerStateNoCull, "NoCull" );
	    RasterizerDescNoCull.FillMode = D3D11_FILL_WIREFRAME;
    m_pDevice->CreateRasterizerState( &RasterizerDescNoCull, &g_pRasterizerStateNoCullWireFrame ) ;
    DXUT_SetDebugName( g_pRasterizerStateNoCullWireFrame, "Wireframe" );
	    D3D11_RASTERIZER_DESC RasterizerDescBackfaceCull = {
        D3D11_FILL_SOLID,   // D3D11_FILL_MODE FillMode;
        D3D11_CULL_BACK,    // D3D11_CULL_MODE CullMode;
        TRUE,               // BOOL FrontCounterClockwise;
        0,                  // INT DepthBias;
        0,                  // FLOAT DepthBiasClamp;
        0,                  // FLOAT SlopeScaledDepthBias;
        FALSE,              // BOOL DepthClipEnable;
        FALSE,              // BOOL ScissorEnable;
        TRUE,               // BOOL MultisampleEnable;
        FALSE,              // BOOL AntialiasedLineEnable;
    };
    m_pDevice->CreateRasterizerState( &RasterizerDescBackfaceCull, &g_pRasterizerStateBackfaceCull ) ;
    DXUT_SetDebugName( g_pRasterizerStateBackfaceCull, "BackfaceCull" );
	    D3D11_RASTERIZER_DESC RasterizerDescFrontfaceCull = {
        D3D11_FILL_SOLID,   // D3D11_FILL_MODE FillMode;
        D3D11_CULL_FRONT,   // D3D11_CULL_MODE CullMode;
        TRUE,               // BOOL FrontCounterClockwise;
        0,                  // INT DepthBias;
        0,                  // FLOAT DepthBiasClamp;
        0,                  // FLOAT SlopeScaledDepthBias;
        FALSE,              // BOOL DepthClipEnable;
        FALSE,              // BOOL ScissorEnable;
        TRUE,               // BOOL MultisampleEnable;
        FALSE,              // BOOL AntialiasedLineEnable;
    };
    m_pDevice->CreateRasterizerState( &RasterizerDescFrontfaceCull, &g_pRasterizerStateFrontfaceCull ) ;
    DXUT_SetDebugName( g_pRasterizerStateFrontfaceCull, "FrontfaceCull" );
	    // The parameters to pass to per-chunk threads for the main scene
    g_StaticParamsDirect.m_pDepthStencilState = g_pDepthStencilStateNoStencil;
    g_StaticParamsDirect.m_iStencilRef = 0;
    g_StaticParamsDirect.m_pRasterizerState = g_pRasterizerStateFrontfaceCull;
    g_StaticParamsDirect.m_vMirrorPlane = D3DXPLANE( 0.0f, 0.0f, 0.0f, 0.0f );
    g_StaticParamsDirect.m_vTintColor = D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f );
    g_StaticParamsDirect.m_pDepthStencilView = NULL;
    g_StaticParamsDirect.m_pViewport = NULL;
	#ifdef DEBUG
    // These checks are important for avoiding implicit assumptions of D3D state carry-over
    // across device contexts.  A very common source of error in multithreaded rendering  
    // is setting some state in one context and inadvertently relying on that state in
    // another context.  Setting all these flags to true should expose all such errors
    // (at non-trivial performance cost).
    //
    // The names mean a bit more than they say.  The flags force that state be cleared when:
    //
    //  1) We actually perform the action in question (e.g. call FinishCommandList)
    //  2) We reach any point in the frame when the action could have been
    // performed (e.g. we are using DEVICECONTEXT_IMMEDIATE but would otherwise
    // have called FinishCommandList)
    //
    // This usage guarantees consistent behavior across the different pathways.
    //
    g_bClearStateUponBeginCommandList = true;
    g_bClearStateUponFinishCommandList = true;
    g_bClearStateUponExecuteCommandList = true;
#endif
	    InitializeLights();
	    InitializeShadows( m_pDevice ) ;
	    InitializeMirrors( m_pDevice ) ;
	     
    // Add additional worker threads for rendering
    InitializeWorkerThreads(m_pDevice);
	    OnD3D11ResizedSwapChain(m_pDevice, m_swapChain, nullptr, nullptr);
         
}
	 
	void D3D11_Renderer::CreateRenderTarget()
{
    CComPtr<ID3D11Texture2D> backBuffer;
    m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backBuffer);
    m_pDevice->CreateRenderTargetView(backBuffer, nullptr, &m_renderTargetView);
    backBuffer->GetDesc(&m_backBufferDesc);
	    // Create a depth stencil view.
    CD3D11_TEXTURE2D_DESC depthStencilDesc(
        DXGI_FORMAT_D24_UNORM_S8_UINT,
        static_cast<UINT>(m_backBufferDesc.Width),
        static_cast<UINT>(m_backBufferDesc.Height),
        1,
        1,
        D3D11_BIND_DEPTH_STENCIL
        );
	    CComPtr<ID3D11Texture2D> depthStencil;
    
    m_pDevice->CreateTexture2D(
            &depthStencilDesc,
            nullptr,
            &depthStencil
            );
        
	    CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D);
    // FIXME
    //m_pDevice->CreateDepthStencilView(depthStencil, &depthStencilViewDesc, &m_depthStencilView);
	}
	//--------------------------------------------------------------------------------------
// Create per-worker-thread resources
//--------------------------------------------------------------------------------------
HRESULT InitializeWorkerThreads( ID3D11Device* pd3dDevice )
{
    HRESULT hr;
	    // Per-scene data init
    for ( int iInstance = 0; iInstance < g_iNumPerSceneRenderThreads; ++iInstance )
    {
        g_iPerSceneThreadInstanceData[iInstance] = iInstance;
	        g_hBeginPerSceneRenderDeferredEvent[iInstance] = CreateEvent( NULL, FALSE, FALSE, NULL );
        g_hEndPerSceneRenderDeferredEvent[iInstance] = CreateEvent( NULL, FALSE, FALSE, NULL );
	        pd3dDevice->CreateDeferredContext( 0 /*Reserved for future use*/,
            &g_pd3dPerSceneDeferredContext[iInstance] ) ;
	        g_hPerSceneRenderDeferredThread[iInstance] = ( HANDLE )_beginthreadex(
            NULL,
            0,
            _PerSceneRenderDeferredProc,
            &g_iPerSceneThreadInstanceData[iInstance],
            CREATE_SUSPENDED,
            NULL );
	#if defined(PROFILE) || defined(DEBUG)
        char threadid[ 16 ];
        sprintf_s( threadid, sizeof(threadid), "PS %d", iInstance );
        DXUT_SetDebugName( g_pd3dPerSceneDeferredContext[iInstance], threadid );
#endif
	        ResumeThread( g_hPerSceneRenderDeferredThread[iInstance] );
    }
	    // Per-chunk data init
	    // Reserve one core for the main thread if possible
    g_iNumPerChunkRenderThreads = 2;
	    // Restrict to the max static allocation --- can be easily relaxed if need be
    g_iNumPerChunkRenderThreads = min( g_iNumPerChunkRenderThreads, g_iMaxPerChunkRenderThreads );
	    // Need at least on worker thread, even on a single-core machine
    g_iNumPerChunkRenderThreads = max( g_iNumPerChunkRenderThreads, 1 );
	    // uncomment to force exactly one worker context (and therefore predictable render order)
    //g_iNumPerChunkRenderThreads = 1;
	    for ( int iInstance = 0; iInstance < g_iNumPerChunkRenderThreads; ++iInstance )
    {
        g_iPerChunkThreadInstanceData[iInstance] = iInstance;
	        g_hBeginPerChunkRenderDeferredSemaphore[iInstance] = CreateSemaphore( NULL, 0,
            g_iMaxPendingQueueEntries, NULL );
        g_hEndPerChunkRenderDeferredEvent[iInstance] = CreateEvent( NULL, FALSE, FALSE, NULL );
	        pd3dDevice->CreateDeferredContext( 0 /*Reserved for future use*/,
            &g_pd3dPerChunkDeferredContext[iInstance] ) ;
	        g_hPerChunkRenderDeferredThread[iInstance] = ( HANDLE )_beginthreadex( NULL,
            0,
            _PerChunkRenderDeferredProc,
            &g_iPerChunkThreadInstanceData[iInstance],
            CREATE_SUSPENDED,
            NULL );
	#if defined(PROFILE) || defined(DEBUG)
        char threadid[ 16 ];
        sprintf_s( threadid, sizeof(threadid), "PC %d", iInstance );
        DXUT_SetDebugName( g_pd3dPerChunkDeferredContext[iInstance], threadid );
#endif
	        ResumeThread( g_hPerChunkRenderDeferredThread[iInstance] );
    }
	    return S_OK;
}
	
// There are a couple of threads participating the rendering
// 1) main thread
// 2) worker threads
 
void D3D11_Renderer::Render()
{
    //ID3D11DeviceContext* pImmediateContext = NULL;
    //m_pDevice->CreateDeferredContext(0, &pImmediateContext);
    Render(m_pDevice, m_pDeviceContext, m_Time, m_ElaspedTime, nullptr);
}
	
// main thread that participates in rendering
void D3D11_Renderer::Render
    (
    ID3D11Device* pd3dDevice,
    ID3D11DeviceContext* pd3dImmediateContext,
    double fTime,
    float fElapsedTime,
    void* pUserContext
    )
{  
    HRESULT hr;
	//#ifdef ADJUSTABLE_LIGHT
//    g_vLightDir[0] = g_LightControl.GetLightDirection();
//    g_vLightPos[0] = g_vSceneCenter - g_fSceneRadius * g_vLightDir[0];
//#endif
	    if ( g_bClearStateUponBeginCommandList )
    {
        pd3dImmediateContext->ClearState();
        DXUTSetupD3D11Views( pd3dImmediateContext ) ;
    }
	    // Clear the render target
    float ClearColor[4] = { 0.0f, 0.25f, 0.25f, 0.55f };
    pd3dImmediateContext->ClearRenderTargetView( m_renderTargetView, ClearColor );
    pd3dImmediateContext->ClearDepthStencilView( m_depthStencilView,  
        D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0, 0 );
	    // 1) Render into the context and renders as a batch
        
    // Three possible render pathways:
    if ( IsRenderMultithreadedPerScene() )
    {
        // Signal all worker threads, then wait for completion
        for ( int iInstance = 0; iInstance < g_iNumPerSceneRenderThreads; ++iInstance )
        {
            // signal ready for scene kickoff
            SetEvent( g_hBeginPerSceneRenderDeferredEvent[iInstance] );
        }
	        // wait for completion
        WaitForMultipleObjects( g_iNumPerSceneRenderThreads,
            g_hEndPerSceneRenderDeferredEvent,
            TRUE,
            INFINITE );
    }
    else if ( IsRenderDeferredPerScene() )
    {
        // Perform the same tasks, serialized on the main thread but using deferred contexts
        for ( int iShadow = 0; iShadow < g_iNumShadows; ++iShadow )
        {
            // Render into a context
            RenderShadow( iShadow, g_pd3dPerSceneDeferredContext[iShadow] );
            g_pd3dPerSceneDeferredContext[iShadow]->FinishCommandList(
                !g_bClearStateUponFinishCommandList,
                &g_pd3dPerSceneCommandList[iShadow] ) ;
        }
	        for ( int iMirror = 0; iMirror < g_iNumMirrors; ++iMirror )
        {
            RenderMirror( iMirror, g_pd3dPerSceneDeferredContext[iMirror] );
            g_pd3dPerSceneDeferredContext[iMirror]->FinishCommandList(
                !g_bClearStateUponFinishCommandList,
                &g_pd3dPerSceneCommandList[g_iNumShadows + iMirror] ) ;
        }
	        RenderSceneDirect( g_pd3dPerSceneDeferredContext[g_iNumMirrors] );
        g_pd3dPerSceneDeferredContext[g_iNumMirrors]->FinishCommandList(
            !g_bClearStateUponFinishCommandList,
            &g_pd3dPerSceneCommandList[g_iNumShadows + g_iNumMirrors] );
    }
    else
    {
        // Perform the same tasks, serialized on the main thread using the immediate context
        for ( int iShadow = 0; iShadow < g_iNumShadows; ++iShadow )
        {
            RenderShadow( iShadow, pd3dImmediateContext );
        }
	        for ( int iMirror = 0; iMirror < g_iNumMirrors; ++iMirror )
        {
            RenderMirror( iMirror, pd3dImmediateContext );
        }
        
	        RenderSceneDirect( pd3dImmediateContext );
    }
	
    /// These are executed by worker threads off-line
	    // If we are doing ST_DEFERRED_PER_SCENE or MT_DEFERRED_PER_SCENE, we have generated a
    // bunch of command lists.  Execute those lists now.
    if ( IsRenderDeferredPerScene() )
    {
        for ( int iInstance = 0; iInstance < g_iNumPerSceneRenderThreads; ++iInstance )
        {
            pd3dImmediateContext->ExecuteCommandList( g_pd3dPerSceneCommandList[iInstance],
                !g_bClearStateUponExecuteCommandList );
            SAFE_RELEASE( g_pd3dPerSceneCommandList[iInstance] );
        }
    }
    else
    {
        // If we rendered directly, optionally clear state for consistent behavior with
        // the other render pathways.
        if ( g_bClearStateUponFinishCommandList || g_bClearStateUponExecuteCommandList )
        {
            pd3dImmediateContext->ClearState();
        }
    }
	    DXUTSetupD3D11Views( pd3dImmediateContext ) ;
	       
}
	HRESULT OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, IDXGISwapChain* pSwapChain,
                                          const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    HRESULT hr;
	   // V_RETURN( g_DialogResourceManager.OnD3D11ResizedSwapChain( pd3dDevice, pBackBufferSurfaceDesc ) );
   // V_RETURN( g_D3DSettingsDlg.OnD3D11ResizedSwapChain( pd3dDevice, pBackBufferSurfaceDesc ) );
	    // Setup the camera's projection parameters
    //float fAspectRatio = pBackBufferSurfaceDesc->Width / ( FLOAT )pBackBufferSurfaceDesc->Height;
    float fAspectRatio = 800.0f / 600.0f;
    g_Camera.SetProjParams( g_fFOV, fAspectRatio, g_fNearPlane, g_fFarPlane );
    g_Camera.SetWindow( 800.0f, 600.0f );
   // g_Camera.SetButtonMasks( MOUSE_MIDDLE_BUTTON, MOUSE_WHEEL, MOUSE_LEFT_BUTTON );
	    //g_HUD.SetLocation( pBackBufferSurfaceDesc->Width - 170, 0 );
    //g_HUD.SetSize( 170, 170 );
    //g_SampleUI.SetLocation( pBackBufferSurfaceDesc->Width - 170, pBackBufferSurfaceDesc->Height - 300 );
    //g_SampleUI.SetSize( 170, 300 );
	    return S_OK;
}
	
 
	// 2 additional threads participating in rendering
//--------------------------------------------------------------------------------------
// The per-scene worker thread entry point.  Loops infinitely, rendering either a
// shadow scene or a mirror scene or the main scene into a command list.
//--------------------------------------------------------------------------------------
unsigned int WINAPI _PerSceneRenderDeferredProc( LPVOID lpParameter )
{
    HRESULT hr;
	    // thread local data
    const int iInstance = *( int*)lpParameter;
    ID3D11DeviceContext* pd3dDeferredContext = g_pd3dPerSceneDeferredContext[iInstance];
    ID3D11CommandList*& pd3dCommandList = g_pd3dPerSceneCommandList[iInstance];
	    for (;;)
    {
        // Wait for main thread to signal ready
        WaitForSingleObject( g_hBeginPerSceneRenderDeferredEvent[iInstance], INFINITE );
	        if ( g_bClearStateUponBeginCommandList )
        {
            pd3dDeferredContext->ClearState();
        }
	        if ( iInstance < g_iNumShadows )
        {
            RenderShadow( iInstance, pd3dDeferredContext );
        }
        else if ( iInstance < g_iNumShadows + g_iNumMirrors )
        {
            RenderMirror( iInstance - g_iNumShadows, pd3dDeferredContext );
        }
        else
        {
            RenderSceneDirect( pd3dDeferredContext );
        }
	        pd3dDeferredContext->FinishCommandList( !g_bClearStateUponFinishCommandList, &pd3dCommandList ) ;
	        // Tell main thread command list is finished
        SetEvent( g_hEndPerSceneRenderDeferredEvent[iInstance] );
    }
}
	 
	// 2 additional threads participating in rendering
//--------------------------------------------------------------------------------------
// The per-chunk worker thread entry point.  Loops infinitely, rendering an arbitrary
// set of objects, from an arbitrary type of scene, into a command list.
//--------------------------------------------------------------------------------------
unsigned int WINAPI _PerChunkRenderDeferredProc( LPVOID lpParameter )
{
    HRESULT hr;
	    // thread local data
    const int iInstance = *( int*)lpParameter;
    ID3D11DeviceContext* pd3dDeferredContext = g_pd3dPerChunkDeferredContext[iInstance];
    ID3D11CommandList*& pd3dCommandList = g_pd3dPerChunkCommandList[iInstance];
    const ChunkQueue& LocalQueue = g_ChunkQueue[iInstance];
	    // The next queue entry to be read.  Since we wait for the semaphore signal count to be greater
    // than zero, this index doesn't require explicit synchronization.
    int iQueueOffset = 0;
	    for (;;)
    {
        // Wait for a work queue entry
        WaitForSingleObject( g_hBeginPerChunkRenderDeferredSemaphore[iInstance], INFINITE );
	        assert( iQueueOffset < g_iSceneQueueSizeInBytes );
        const WorkQueueEntryBase* pEntry = (WorkQueueEntryBase*) &LocalQueue[iQueueOffset];
	        switch ( pEntry->m_iType )
        {
        // Begin the scene by setting all required state
        case WORK_QUEUE_ENTRY_TYPE_SETUP:
            {
                const WorkQueueEntrySetup* pSetupEntry = (WorkQueueEntrySetup*) pEntry;
	                if ( g_bClearStateUponBeginCommandList )
                {
                    pd3dDeferredContext->ClearState();
                }
	                RenderSceneSetup( pd3dDeferredContext, pSetupEntry->m_pSceneParamsStatic,
                    &pSetupEntry->m_SceneParamsDynamic ) ;
	                iQueueOffset += sizeof(WorkQueueEntrySetup);
                break;
            }
	        // Submit a single chunk to the deferred context
        case WORK_QUEUE_ENTRY_TYPE_CHUNK:
            {
                const WorkQueueEntryChunk* pChunkEntry = (WorkQueueEntryChunk*) pEntry;
	                // Submit work to deferred context
                RenderMeshDirect( pd3dDeferredContext, pChunkEntry->m_iMesh );
	                iQueueOffset += sizeof(WorkQueueEntryChunk);
                break;
            }
	        // Finalize scene rendering
        case WORK_QUEUE_ENTRY_TYPE_FINALIZE:
            {
                // Finalize preceding work
                pd3dDeferredContext->FinishCommandList( !g_bClearStateUponFinishCommandList, &pd3dCommandList ) ;
	                // Tell main thread command list is finished
                SetEvent( g_hEndPerChunkRenderDeferredEvent[iInstance] );
	                iQueueOffset += sizeof(WorkQueueEntryFinalize); // unnecessary currently as this is the last item
	                // Reset queue
                iQueueOffset = 0;
                break;
            }
	        // Error --- unrecognized entry type
        default:
            assert( false );
            break;
        }
    }
}
	
//--------------------------------------------------------------------------------------
// Render the shadow map
//--------------------------------------------------------------------------------------
VOID RenderShadow( int iShadow, ID3D11DeviceContext* pd3dContext )
{
    HRESULT hr;
	    SceneParamsDynamic DynamicParams;   
    CalcLightViewProj( &DynamicParams.m_mViewProj, iShadow );
	    RenderScene( pd3dContext, &g_StaticParamsShadow[iShadow], &DynamicParams ) ;
}
	
//--------------------------------------------------------------------------------------
// Render the mirror quad into the stencil buffer, and then render the world into
// the stenciled area, using the mirrored projection matrix
//--------------------------------------------------------------------------------------
VOID RenderMirror( int iMirror, ID3D11DeviceContext* pd3dContext )
{
    HRESULT hr;
    D3D11_MAPPED_SUBRESOURCE MappedResource;
	    D3DXVECTOR3 vEyePoint;
    D3DXMATRIX mViewProj;
	#ifdef RENDER_SCENE_LIGHT_POV
    if ( g_bRenderSceneLightPOV )
    {
        vEyePoint = g_vLightPos[0];
        CalcLightViewProj( &mViewProj, 0 );
    }
    else
#endif
    {
        // Find the right view matrix for the mirror.  
        vEyePoint = *g_Camera.GetEyePt();
        mViewProj = *g_Camera.GetViewMatrix() * *g_Camera.GetProjMatrix();
    }
	    // Test for back-facing mirror (from whichever pov we are using)
    if ( D3DXPlaneDotCoord( &g_vMirrorPlane[iMirror], &vEyePoint ) < 0.0f )
    {
        return;
    }
	    D3DXMATRIX mReflect;
    D3DXMatrixReflect( &mReflect, &g_vMirrorPlane[iMirror] );
	    // Set up the mirror local-to-world matrix (could be done at initialize time)
    D3DXVECTOR3 vMirrorPointAt;
    D3DXVec3Add( &vMirrorPointAt, &g_vMirrorNormal[iMirror], &g_vMirrorCenter[iMirror] );
    D3DXMATRIX mMirrorWorld;
    D3DXMatrixLookAtLH( &mMirrorWorld, &vMirrorPointAt, &g_vMirrorCenter[iMirror], &g_vUp );
    D3DXMatrixTranspose( &mMirrorWorld, &mMirrorWorld );
    mMirrorWorld._41 = g_vMirrorCenter[iMirror].x;
    mMirrorWorld._42 = g_vMirrorCenter[iMirror].y;
    mMirrorWorld._43 = g_vMirrorCenter[iMirror].z;
    mMirrorWorld._14 = 0;
    mMirrorWorld._24 = 0;
    mMirrorWorld._34 = 0;
    mMirrorWorld._44 = 1;
	    if ( g_bClearStateUponBeginCommandList )
    {
        pd3dContext->ClearState();
    }
	    // Restore the main view
    DXUTSetupD3D11Views( pd3dContext );
	    //--------------------------------------------------------------------------------------
    // Draw the mirror quad into the stencil buffer, setting the stencil ref value
    //--------------------------------------------------------------------------------------
	    // Set the depth-stencil state
    pd3dContext->OMSetDepthStencilState( g_pMirrorDepthStencilStateDepthTestStencilOverwrite,
        g_iStencilRef );
	    // Set the cull state
    pd3dContext->RSSetState( g_pRasterizerStateBackfaceCull );
	    // Set inputs for the mirror shader
    pd3dContext->IASetInputLayout( g_pMirrorVertexLayout11 );
    pd3dContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP );
    ID3D11Buffer* pVB[1] = { g_pMirrorVertexBuffer };
    UINT pStride[1] = { sizeof(MirrorVertex) };
    UINT pOffset[1] = { 0 };
    pd3dContext->IASetVertexBuffers( 0, 1, pVB, pStride, pOffset );
	    pd3dContext->VSSetShader( g_pVertexShader, NULL, 0 );
    pd3dContext->PSSetShader( NULL, NULL, 0 );
	    // Set the corners of the mirror vertex buffer.  The UVs aren't used here
    pd3dContext->Map( g_pMirrorVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ;
    memcpy( MappedResource.pData, g_MirrorRect[iMirror], sizeof(g_MirrorRect[iMirror]) );
    pd3dContext->Unmap( g_pMirrorVertexBuffer, 0 );
	    // Set up the transform matrices in the constant buffer
    pd3dContext->Map( g_pcbVSPerObject, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ;
    CB_VS_PER_OBJECT* pVSPerObject = ( CB_VS_PER_OBJECT* )MappedResource.pData;
    D3DXMatrixTranspose( &pVSPerObject->m_mWorld, &mMirrorWorld );
    pd3dContext->Unmap( g_pcbVSPerObject, 0 );
	    pd3dContext->VSSetConstantBuffers( g_iCBVSPerObjectBind, 1, &g_pcbVSPerObject );
	    pd3dContext->Map( g_pcbVSPerScene, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ;
    CB_VS_PER_SCENE* pVSPerScene = ( CB_VS_PER_SCENE* )MappedResource.pData;
    D3DXMatrixTranspose( &pVSPerScene->m_mViewProj, &mViewProj );
    pd3dContext->Unmap( g_pcbVSPerScene, 0 );
	    pd3dContext->VSSetConstantBuffers( g_iCBVSPerSceneBind, 1, &g_pcbVSPerScene );
	    pd3dContext->Draw( 4, 0 );
	    //--------------------------------------------------------------------------------------
    // Clear depth, only within the stencilled area
    //--------------------------------------------------------------------------------------
	    // Set the depth-stencil state
    pd3dContext->OMSetDepthStencilState( g_pMirrorDepthStencilStateDepthOverwriteStencilTest,
        g_iStencilRef );
	    // Set up the transform matrices to alway output depth equal to the far plane (z = w of output)
    pd3dContext->Map( g_pcbVSPerScene, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ;
    pVSPerScene = ( CB_VS_PER_SCENE* )MappedResource.pData;
    D3DXMatrixTranspose( &pVSPerScene->m_mViewProj, &mViewProj );
    pVSPerScene->m_mViewProj._31 = mViewProj._14;
    pVSPerScene->m_mViewProj._32 = mViewProj._24;
    pVSPerScene->m_mViewProj._33 = mViewProj._34;
    pVSPerScene->m_mViewProj._34 = mViewProj._44;
    pd3dContext->Unmap( g_pcbVSPerScene, 0 );
	    pd3dContext->Draw( 4, 0 );
	    //--------------------------------------------------------------------------------------
    // Draw the mirrored world into the stencilled area
    //--------------------------------------------------------------------------------------
	    SceneParamsDynamic DynamicParams;
    DynamicParams.m_mViewProj = mReflect * mViewProj;
	    RenderScene( pd3dContext, &g_StaticParamsMirror[iMirror], &DynamicParams ) ;
	    //--------------------------------------------------------------------------------------
    // Clear the stencil bit to 0 over the mirror quad.
    // At the same time, set the depth buffer to the depth value of the mirror.
    //--------------------------------------------------------------------------------------
	    // Assume this context is completely from scratch, since we've just come back from
    // scene rendering
    DXUTSetupD3D11Views( pd3dContext ) ;
	    // Set the depth-stencil state
    pd3dContext->OMSetDepthStencilState( g_pMirrorDepthStencilStateDepthOverwriteStencilClear,
        g_iStencilRef );
	    // Set the cull state
    pd3dContext->RSSetState( g_pRasterizerStateBackfaceCull );
	    // Set inputs for the mirror shader
    pd3dContext->IASetInputLayout( g_pMirrorVertexLayout11 );
    pd3dContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP );
    pd3dContext->IASetVertexBuffers( 0, 1, pVB, pStride, pOffset );
	    pd3dContext->VSSetShader( g_pVertexShader, NULL, 0 );
    pd3dContext->PSSetShader( NULL, NULL, 0 );
	    // Set up the transform matrices
    pd3dContext->Map( g_pcbVSPerObject, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ;
    pVSPerObject = ( CB_VS_PER_OBJECT* )MappedResource.pData;
    D3DXMatrixTranspose( &pVSPerObject->m_mWorld, &mMirrorWorld );
    pd3dContext->Unmap( g_pcbVSPerObject, 0 );
	    pd3dContext->VSSetConstantBuffers( g_iCBVSPerObjectBind, 1, &g_pcbVSPerObject );
	    pd3dContext->Map( g_pcbVSPerScene, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ;
    pVSPerScene = ( CB_VS_PER_SCENE* )MappedResource.pData;
    D3DXMatrixTranspose( &pVSPerScene->m_mViewProj, &mViewProj );
    pd3dContext->Unmap( g_pcbVSPerScene, 0 );
	    pd3dContext->VSSetConstantBuffers( g_iCBVSPerSceneBind, 1, &g_pcbVSPerScene );
	    pd3dContext->Draw( 4, 0 );
}
	 
	// Called by Threads themselves
//--------------------------------------------------------------------------------------
// Perform per-scene d3d context set-up.  This should be enough setup that you can
// start with a completely new device context, and then successfully call RenderMesh
// afterwards.
//--------------------------------------------------------------------------------------
HRESULT RenderSceneSetup( ID3D11DeviceContext* pd3dContext, const SceneParamsStatic* pStaticParams,
                         const SceneParamsDynamic* pDynamicParams )
{
    HRESULT hr = E_FAIL;
    D3D11_MAPPED_SUBRESOURCE MappedResource;
	    BOOL bShadow = ( pStaticParams->m_pDepthStencilView != NULL );
	    // Use all shadow maps as textures, or else one shadow map as depth-stencil
    if ( bShadow )
    {
        // No shadow maps as textures
        ID3D11ShaderResourceView* ppNullResources[g_iNumShadows] = { NULL };
        pd3dContext->PSSetShaderResources( 2, g_iNumShadows, ppNullResources );
	        // Given shadow map as depth-stencil, no render target
        pd3dContext->RSSetViewports( 1, pStaticParams->m_pViewport );
        pd3dContext->OMSetRenderTargets( 0, NULL, pStaticParams->m_pDepthStencilView );
    }
    else
    {
        // Standard DXUT render target and depth-stencil
        DXUTSetupD3D11Views( pd3dContext ) ;
	        // All shadow maps as textures
        pd3dContext->PSSetShaderResources( 2, g_iNumShadows, g_pShadowResourceView );
    }
	    // Set the depth-stencil state
    pd3dContext->OMSetDepthStencilState( pStaticParams->m_pDepthStencilState, pStaticParams->m_iStencilRef );
	    // Set the rasterizer state
    pd3dContext->RSSetState( g_bWireFrame ? g_pRasterizerStateNoCullWireFrame: pStaticParams->m_pRasterizerState );
	    // Set the shaders
    pd3dContext->VSSetShader( g_pVertexShader, NULL, 0 );
	    // Set the vertex buffer format
    pd3dContext->IASetInputLayout( g_pVertexLayout11 );
    
    // Set the VS per-scene constant data
    pd3dContext->Map( g_pcbVSPerScene, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ;
    CB_VS_PER_SCENE* pVSPerScene = ( CB_VS_PER_SCENE* )MappedResource.pData;
    D3DXMatrixTranspose( &pVSPerScene->m_mViewProj, &pDynamicParams->m_mViewProj );
    pd3dContext->Unmap( g_pcbVSPerScene, 0 );
	    pd3dContext->VSSetConstantBuffers( g_iCBVSPerSceneBind, 1, &g_pcbVSPerScene );
	    if ( bShadow )
    {
        pd3dContext->PSSetShader( NULL, NULL, 0 );
    }
    else
    {
        pd3dContext->PSSetShader( g_pPixelShader, NULL, 0 );
	        ID3D11SamplerState* ppSamplerStates[2] = { g_pSamPointClamp, g_pSamLinearWrap };
        pd3dContext->PSSetSamplers( 0, 2, ppSamplerStates );
	        // Set the PS per-scene constant data
        // A user clip plane prevents drawing things into the mirror which are behind the mirror plane
        pd3dContext->Map( g_pcbPSPerScene, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ;
        CB_PS_PER_SCENE* pPSPerScene = ( CB_PS_PER_SCENE* )MappedResource.pData;
        pPSPerScene->m_vMirrorPlane = pStaticParams->m_vMirrorPlane;
        pPSPerScene->m_vAmbientColor = g_vAmbientColor;
        pPSPerScene->m_vTintColor = pStaticParams->m_vTintColor;
        pd3dContext->Unmap( g_pcbPSPerScene, 0 );
	        pd3dContext->PSSetConstantBuffers( g_iCBPSPerSceneBind, 1, &g_pcbPSPerScene );
	        // Set the PS per-light constant data
        pd3dContext->Map( g_pcbPSPerLight, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ;
        CB_PS_PER_LIGHT* pPSPerLight = ( CB_PS_PER_LIGHT* )MappedResource.pData;
        for ( int iLight = 0; iLight < g_iNumLights; ++iLight )
        {
            D3DXVECTOR4 vLightPos = D3DXVECTOR4( g_vLightPos[iLight].x, g_vLightPos[iLight].y, g_vLightPos[iLight].z, 1.0f );
            D3DXVECTOR4 vLightDir = D3DXVECTOR4( g_vLightDir[iLight].x, g_vLightDir[iLight].y, g_vLightDir[iLight].z, 0.0f );
            D3DXMATRIX mLightViewProj;
	            CalcLightViewProj( &mLightViewProj, iLight );
            
            pPSPerLight->m_LightData[iLight].m_vLightColor = g_vLightColor[iLight];
            pPSPerLight->m_LightData[iLight].m_vLightPos = vLightPos;
            pPSPerLight->m_LightData[iLight].m_vLightDir = vLightDir;
            D3DXMatrixTranspose( &pPSPerLight->m_LightData[iLight].m_mLightViewProj,
                &mLightViewProj );
            pPSPerLight->m_LightData[iLight].m_vFalloffs = D3DXVECTOR4(
                g_fLightFalloffDistEnd[iLight],
                g_fLightFalloffDistRange[iLight],
                g_fLightFalloffCosAngleEnd[iLight],
                g_fLightFalloffCosAngleRange[iLight]);
        }
        pd3dContext->Unmap( g_pcbPSPerLight, 0 );
	        pd3dContext->PSSetConstantBuffers( g_iCBPSPerLightBind, 1, &g_pcbPSPerLight );
    }
	    return hr;
}
	// Called by threads themselves
// 1)
// threads -> RenderSceneDirect -> RenderScene
//--------------------------------------------------------------------------------------
// Render the scene into the world (not into a mirror or a shadow map)
//--------------------------------------------------------------------------------------
VOID RenderSceneDirect( ID3D11DeviceContext* pd3dContext )
{
    HRESULT hr;
    SceneParamsDynamic DynamicParams;
    DynamicParams.m_mViewProj = *g_Camera.GetViewMatrix() * *g_Camera.GetProjMatrix();
	#ifdef RENDER_SCENE_LIGHT_POV
    if ( g_bRenderSceneLightPOV )
    {
        CalcLightViewProj( &DynamicParams.m_mViewProj, 0 );
    }
#endif
    // Call gMesh11.Render();
    RenderScene( pd3dContext, &g_StaticParamsDirect, &DynamicParams );
}
	
// 2
// threads -> RenderSceneDirect -> RenderScene -> gMesh11.Render...  
//--------------------------------------------------------------------------------------
// Render the scene from either:
//      - The immediate context in main thread, or
//      - A deferred context in the main thread, or
//      - A deferred context in a worker thread
//      - Several deferred contexts in the main thread, handling objects alternately
//      - Several deferred contexts in worker threads, handling objects alternately
// The scene can be either the main scene, a mirror scene, or a shadow map scene
//--------------------------------------------------------------------------------------
HRESULT RenderScene( ID3D11DeviceContext* pd3dContext, const SceneParamsStatic *pStaticParams,
                    const SceneParamsDynamic *pDynamicParams )
{
    HRESULT hr = S_OK;
	    // Make sure we're not relying on any state being inherited
    if ( g_bClearStateUponBeginCommandList )
    {
        pd3dContext->ClearState();
    }
	    // Clear the shadow buffer
    if ( pStaticParams->m_pDepthStencilView != NULL )
    {
        pd3dContext->ClearDepthStencilView( pStaticParams->m_pDepthStencilView,
            D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0, 0 );
    }
	    // Perform scene setup on every d3d context we will use
    if ( IsRenderMultithreadedPerChunk() )
    {
        for ( int iInstance = 0; iInstance < g_iNumPerChunkRenderThreads; ++iInstance )
        {
            // Reset count
            g_iPerChunkQueueOffset[iInstance] = 0;
	            // Create and submit a worker queue entry
            ChunkQueue& WorkerQueue = g_ChunkQueue[iInstance];
            int iQueueOffset = g_iPerChunkQueueOffset[iInstance];
            HANDLE hSemaphore = g_hBeginPerChunkRenderDeferredSemaphore[iInstance];
	            g_iPerChunkQueueOffset[iInstance] += sizeof(WorkQueueEntrySetup);
            assert( g_iPerChunkQueueOffset[iInstance] < g_iSceneQueueSizeInBytes );
	            WorkQueueEntrySetup* pEntry = (WorkQueueEntrySetup*) &WorkerQueue[iQueueOffset];
            pEntry->m_iType = WORK_QUEUE_ENTRY_TYPE_SETUP;
            pEntry->m_pSceneParamsStatic = pStaticParams;    // shallow copy, mmm
            pEntry->m_SceneParamsDynamic = *pDynamicParams; // deep copy, gulp
	            ReleaseSemaphore( hSemaphore, 1, NULL );
        }
    }
    else if ( IsRenderDeferredPerChunk() )
    {
        for ( int iInstance = 0; iInstance < g_iNumPerChunkRenderThreads; ++iInstance )
        {
            ID3D11DeviceContext* pd3dDeferredContext = g_pd3dPerChunkDeferredContext[iInstance];
            RenderSceneSetup( pd3dDeferredContext, pStaticParams, pDynamicParams ) ;
        }
    }
    else
    {
        RenderSceneSetup( pd3dContext, pStaticParams, pDynamicParams ) ;
    }
	    //Render / Eventually will call RenderMesh
    g_Mesh11.Render( pd3dContext, 0, 1 );
	    // If we are doing ST_DEFERRED_PER_CHUNK or MT_DEFERRED_PER_CHUNK, generate and execute command lists now.
    if ( IsRenderDeferredPerChunk() )
    {
        if ( IsRenderMultithreadedPerChunk() )
        {
            // Signal all worker threads to finalize their command lists
            for ( int iInstance = 0; iInstance < g_iNumPerChunkRenderThreads; ++iInstance )
            {
                // Create and submit a worker queue entry
                ChunkQueue& WorkerQueue = g_ChunkQueue[iInstance];
                int iQueueOffset = g_iPerChunkQueueOffset[iInstance];
                HANDLE hSemaphore = g_hBeginPerChunkRenderDeferredSemaphore[iInstance];
	                g_iPerChunkQueueOffset[iInstance] += sizeof(WorkQueueEntryFinalize);
                assert( g_iPerChunkQueueOffset[iInstance] < g_iSceneQueueSizeInBytes );
	                WorkQueueEntryFinalize* pEntry = (WorkQueueEntryFinalize*) &WorkerQueue[iQueueOffset];
                pEntry->m_iType = WORK_QUEUE_ENTRY_TYPE_FINALIZE;
	                ReleaseSemaphore( hSemaphore, 1, NULL );
            }
	            // Wait until all worker threads signal that their command lists are finalized
            WaitForMultipleObjects( g_iNumPerChunkRenderThreads,
                g_hEndPerChunkRenderDeferredEvent, TRUE, INFINITE );
        }
        else
        {
            // Directly finalize all command lists
            for ( int iInstance = 0; iInstance < g_iNumPerChunkRenderThreads; ++iInstance )
            {
                g_pd3dPerChunkDeferredContext[iInstance]->FinishCommandList(
                    !g_bClearStateUponFinishCommandList, &g_pd3dPerChunkCommandList[iInstance] ) ;
            }
        }
	        // Execute all command lists.  Note these now produce a scattered render order.
        for ( int iInstance = 0; iInstance < g_iNumPerChunkRenderThreads; ++iInstance )
        {
            pd3dContext->ExecuteCommandList( g_pd3dPerChunkCommandList[iInstance],
                !g_bClearStateUponExecuteCommandList );
            SAFE_RELEASE( g_pd3dPerChunkCommandList[iInstance] );
        }
    }
    else
    {
        // If we rendered directly, optionally clear state for consistent behavior with
        // the other render pathways.
        if ( g_bClearStateUponFinishCommandList || g_bClearStateUponExecuteCommandList )
        {
            pd3dContext->ClearState();
        }
    }
	    return hr;
}
	
// 3
// Called Back by MultiDeviceContextDXUTMesh
	//
//--------------------------------------------------------------------------------------
// The RenderMesh version which may redirect to another device context and/or thread.  
// This function gets called from the main thread or a per-scene thread, but not from
// a per-chunk worker thread.
//
// There are three cases to consider:
//
//  1) If we are not using per-chunk deferred contexts, the call gets routed straight
// back to DXUT with the given device context.
//  2) If we are using singlethreaded per-chunk deferred contexts, the call gets added
// to the next deferred context, and the draw submission occurs inline here.
//  3) If we are using multithreaded per-chunk deferred contexts, the call gets recorded
// in the next per-chunk work queue, and the corresponding semaphore gets incremented.  
// The appropriate worker thread detects the semaphore signal, grabs the work queue
// entry, and submits the draw call from its deferred context.
//
// We ignore most of the arguments to this function, because they are constant for this
// sample.
//--------------------------------------------------------------------------------------
void RenderMesh( CMultiDeviceContextDXUTMesh* pMesh,
                UINT iMesh,
                bool bAdjacent,
                ID3D11DeviceContext* pd3dDeviceContext,
                UINT iDiffuseSlot,
                UINT iNormalSlot,
                UINT iSpecularSlot )
{
    static int iNextAvailableChunkQueue = 0;   // next per-chunk deferred context to assign to
	    if ( IsRenderMultithreadedPerChunk() )
    {
        // Create and submit a worker queue entry
        ChunkQueue& WorkerQueue = g_ChunkQueue[iNextAvailableChunkQueue];
        int iQueueOffset = g_iPerChunkQueueOffset[iNextAvailableChunkQueue];
        HANDLE hSemaphore = g_hBeginPerChunkRenderDeferredSemaphore[iNextAvailableChunkQueue];
	        g_iPerChunkQueueOffset[iNextAvailableChunkQueue] += sizeof(WorkQueueEntryChunk);
        assert( g_iPerChunkQueueOffset[iNextAvailableChunkQueue] < g_iSceneQueueSizeInBytes );
	        WorkQueueEntryChunk* pEntry = (WorkQueueEntryChunk*) &WorkerQueue[iQueueOffset];
        pEntry->m_iType = WORK_QUEUE_ENTRY_TYPE_CHUNK;
        pEntry->m_iMesh = iMesh;
	        ReleaseSemaphore( hSemaphore, 1, NULL );
	    }
    else if ( IsRenderDeferredPerChunk() )
    {
        // Replace the incoming device context by a deferred context
        ID3D11DeviceContext* pd3dDeferredContext = g_pd3dPerChunkDeferredContext[iNextAvailableChunkQueue];
        RenderMeshDirect( pd3dDeferredContext, iMesh );
    }
    else
    {
        // Draw as normal
        RenderMeshDirect( pd3dDeviceContext, iMesh );
    }
	    iNextAvailableChunkQueue = ++iNextAvailableChunkQueue % g_iNumPerChunkRenderThreads;
}
	 
	 
	// Called by either Per Chunk Renderer
// Or by Per Scene Renderer / mainthread in some convoluted way
 
// threads -> RenderScene -> gMesh11.Render -> RenderMesh -> RenderMeshDirect -> gMesh11.RenderMesh
// 4
//--------------------------------------------------------------------------------------
// The RenderMesh version which always calls the regular DXUT pathway.
// Here we set up the per-object constant buffers.
//--------------------------------------------------------------------------------------
void RenderMeshDirect( ID3D11DeviceContext* pd3dContext,
                      UINT iMesh )
{
    HRESULT hr = S_OK;
    D3D11_MAPPED_SUBRESOURCE MappedResource;
	    // Set the VS per-object constant data
    // This should eventually differ per object
    D3DXMATRIX mWorld;
    D3DXMatrixIdentity(&mWorld);    // should actually vary per-object
	    pd3dContext->Map( g_pcbVSPerObject, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource );
    CB_VS_PER_OBJECT* pVSPerObject = ( CB_VS_PER_OBJECT* )MappedResource.pData;
    D3DXMatrixTranspose( &pVSPerObject->m_mWorld, &mWorld );
    pd3dContext->Unmap( g_pcbVSPerObject, 0 );
	    pd3dContext->VSSetConstantBuffers( g_iCBVSPerObjectBind, 1, &g_pcbVSPerObject );
	    // Set the PS per-object constant data
    // This should eventually differ per object
    pd3dContext->Map( g_pcbPSPerObject, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource );
    CB_PS_PER_OBJECT* pPSPerObject = ( CB_PS_PER_OBJECT* )MappedResource.pData;
    pPSPerObject->m_vObjectColor = D3DXVECTOR4( 1, 1, 1, 1 );
    pd3dContext->Unmap( g_pcbPSPerObject, 0 );
	    pd3dContext->PSSetConstantBuffers( g_iCBPSPerObjectBind, 1, &g_pcbPSPerObject );
	    g_Mesh11.RenderMesh( iMesh,
        false,
        pd3dContext,
        0,
        1,
        INVALID_SAMPLER_SLOT );
}
	
void D3D11_Renderer::Present()
{
    m_swapChain->Present(2,0);
}
	


 

Oh... My Bad, I was presenting the scene using a DX9 device....

Sorry, it works now, thanks

Advertisement

If you saw a post like your own, would you be able/willing to read through that much code?

BTW: Don't use D3DX together with DX11 (it's slow and obsolete), use DirectXMath instead!

.:vinterberg:.

49 minutes ago, vinterberg said:

If you saw a post like your own, would you be able/willing to read through that much code?

BTW: Don't use D3DX together with DX11 (it's slow and obsolete), use DirectXMath instead!

Best of luck calling D3DX11CompileFromFileW with DirectXMath.

I'm only being half-facetious here; there is a tendency to say "don't use D3DX, use DirectXMath" which totally overlooks the fact that D3DX contained a lot of other functionality too.

It's far more useful to the OP to point them at this page instead: https://blogs.msdn.microsoft.com/chuckw/2013/08/20/living-without-d3dx/

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

This topic is closed to new replies.

Advertisement